summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRaghavendra Bhat <raghavendrabhat@gluster.com>2011-09-06 19:38:00 +0530
committerRaghavendra Bhat <raghavendrabhat@gluster.com>2011-09-06 19:38:00 +0530
commitb1f10e01c5db3cba20144e43ad9d68b5e22b02d2 (patch)
tree2790e7ce882f30f80fa10b9379d27090d34d0d79
parentb7a8d9a42edd69b757f2f763d24571600a3c19a9 (diff)
Revert "some changes for the regression framework and regression testcases for some bugs"
This reverts commit b7a8d9a42edd69b757f2f763d24571600a3c19a9.
-rwxr-xr-xdvm/2010/testcase2
-rwxr-xr-xdvm/2033/testcase2
-rwxr-xr-xdvm/2099/testcase2
-rwxr-xr-xdvm/2140/testcase2
-rwxr-xr-xdvm/2145/testcase2
-rwxr-xr-xdvm/2154/testcase2
-rwxr-xr-xdvm/2294/testcase2
-rwxr-xr-xdvm/2369/testcase2
-rwxr-xr-xdvm/2426/testcase2
-rwxr-xr-xdvm/2483/testcase2
-rwxr-xr-xdvm/2501/testcase2
-rwxr-xr-xdvm/2623/testcase2
-rwxr-xr-xdvm/2742/testcase2
-rw-r--r--regression_helpers9
-rwxr-xr-xrun.sh5
15 files changed, 18 insertions, 22 deletions
diff --git a/dvm/2010/testcase b/dvm/2010/testcase
index e3052b7..d14f338 100755
--- a/dvm/2010/testcase
+++ b/dvm/2010/testcase
@@ -1,6 +1,6 @@
#!/bin/bash
-source $cw$cwd/regression_helpers
+source ./regression_helpers
$GLUSTERFSDIR/gluster volume create $global_bug_id $(hostname):$EXPORT_DIR/$global_bug_id/export1 2>/dev/null 1>/dev/null;
diff --git a/dvm/2033/testcase b/dvm/2033/testcase
index a888928..03d0879 100755
--- a/dvm/2033/testcase
+++ b/dvm/2033/testcase
@@ -1,6 +1,6 @@
#!/bin/bash
-source $cwd/regression_helpers
+source ./regression_helpers
$GLUSTERFSDIR/gluster volume create $global_bug_id $(hostname):$EXPORT_DIR/$global_bug_id/export1 2>/dev/null 1>/dev/null;
diff --git a/dvm/2099/testcase b/dvm/2099/testcase
index 08c84e4..c7f5d82 100755
--- a/dvm/2099/testcase
+++ b/dvm/2099/testcase
@@ -1,6 +1,6 @@
#!/bin/bash
-source $cwd/regression_helpers
+source ./regression_helpers
VOLNAME="volley"
diff --git a/dvm/2140/testcase b/dvm/2140/testcase
index 28deb0c..34b7d5e 100755
--- a/dvm/2140/testcase
+++ b/dvm/2140/testcase
@@ -1,6 +1,6 @@
#!/bin/bash
-source $cwd/regression_helpers
+source ./regression_helpers
$GLUSTERFSDIR/gluster volume delete $global_bug_id --mode=script | grep -i "exist" 2>/dev/null 1>/dev/null
exit $?;
diff --git a/dvm/2145/testcase b/dvm/2145/testcase
index 969c522..afeee55 100755
--- a/dvm/2145/testcase
+++ b/dvm/2145/testcase
@@ -1,6 +1,6 @@
#!/bin/bash
-source $cwd/regression_helpers
+source ./regression_helpers
VOLNAME="vol$global_bug_id";
diff --git a/dvm/2154/testcase b/dvm/2154/testcase
index a3f8730..50b58c0 100755
--- a/dvm/2154/testcase
+++ b/dvm/2154/testcase
@@ -1,6 +1,6 @@
#!/bin/bash
-source $cwd/regression_helpers
+source ./regression_helpers
$GLUSTERFSDIR/gluster volume create $global_bug_id $(hostname):$EXPORT_DIR/$global_bug_id/export1 2>/dev/null 1>/dev/null
diff --git a/dvm/2294/testcase b/dvm/2294/testcase
index 2f984cf..b0d8674 100755
--- a/dvm/2294/testcase
+++ b/dvm/2294/testcase
@@ -1,6 +1,6 @@
#!/bin/bash
-source $cwd/regression_helpers
+source ./regression_helpers
$GLUSTERFSDIR/gluster volume create $global_bug_id transport tcp,rdma $(hostname):$EXPORT_DIR/$global_bug_id/export1 2>/dev/null 1>/dev/null
exit $?;
diff --git a/dvm/2369/testcase b/dvm/2369/testcase
index 2ad2557..f25af14 100755
--- a/dvm/2369/testcase
+++ b/dvm/2369/testcase
@@ -1,6 +1,6 @@
#!/bin/bash
-source $cwd/regression_helpers
+source ./regression_helpers
$GLUSTERFSDIR/gluster volume create $global_bug_id $(hostname):$EXPORT_DIR/$global_bug_id/export1 2>/dev/null 1>/dev/null;
diff --git a/dvm/2426/testcase b/dvm/2426/testcase
index 1c9e750..4c5dda9 100755
--- a/dvm/2426/testcase
+++ b/dvm/2426/testcase
@@ -1,6 +1,6 @@
#!/bin/bash
-source $cwd/regression_helpers
+source ./regression_helpers
$GLUSTERFSDIR/gluster volume create $global_bug_id $(hostname):$EXPORT_DIR/$global_bug_id/brick1 $(hostname):$EXPORT_DIR/$global_bug_id/brick2 2>/dev/null 1>/dev/null
diff --git a/dvm/2483/testcase b/dvm/2483/testcase
index a0a85d2..ba62402 100755
--- a/dvm/2483/testcase
+++ b/dvm/2483/testcase
@@ -1,6 +1,6 @@
#!/bin/bash
-source $cwd/regression_helpers
+source ./regression_helpers
VOLNAME="vol$global_bug_id"
diff --git a/dvm/2501/testcase b/dvm/2501/testcase
index 4702b00..63561c5 100755
--- a/dvm/2501/testcase
+++ b/dvm/2501/testcase
@@ -1,6 +1,6 @@
#!/bin/bash
-source $cwd/regression_helpers
+source ./regression_helpers
VOLNAME="vol$global_bug_id";
diff --git a/dvm/2623/testcase b/dvm/2623/testcase
index b90c3eb..48b209a 100755
--- a/dvm/2623/testcase
+++ b/dvm/2623/testcase
@@ -1,6 +1,6 @@
#!/bin/bash
-source $cwd/regression_helpers
+source ./regression_helpers
$GLUSTERFSDIR/gluster volume create $global_bug_id $(hostname):$EXPORT_DIR/$global_bug_id/export1 2>/dev/null 1>/dev/null;
diff --git a/dvm/2742/testcase b/dvm/2742/testcase
index 800924e..062c144 100755
--- a/dvm/2742/testcase
+++ b/dvm/2742/testcase
@@ -1,6 +1,6 @@
#!/bin/bash
-source $cwd/regression_helpers
+source ./regression_helpers
VOLNAME="vol$global_bug_id";
diff --git a/regression_helpers b/regression_helpers
index b373d1b..cf0e343 100644
--- a/regression_helpers
+++ b/regression_helpers
@@ -106,11 +106,11 @@ run_testcase ()
export FUSE_MOUNT=$EXPORT_DIR/$global_bug_id/fuse;
export NFS_MOUNT=$EXPORT_DIR/$global_bug_id/nfs;
- if [ -f $cwd/dvm/$id/testcase ]; then
+ if [ -f ./dvm/$id/testcase ]; then
create_directory $FUSE_MOUNT;
create_directory $NFS_MOUNT;
- $cwd/dvm/$id/testcase $GLUSTERD;
+ ./dvm/$id/testcase $GLUSTERD;
if [ $? -ne 0 ]; then
echo -n "$global_bug_id: "
not_ok;
@@ -125,11 +125,10 @@ run_testcase ()
return 0;
fi
- for i in $(ls $cwd/dvm/ | grep "^[0-9]*$" | sort -n)
+ for i in $(ls dvm/ | grep "^[0-9]*$" | sort -n)
do
- if [ -f $cwd/dvm/$i/testcase ]; then
+ if [ -f ./dvm/$i/testcase ]; then
run_testcase $i;
- sleep 1;
fi
done
}
diff --git a/run.sh b/run.sh
index ddce608..0801999 100755
--- a/run.sh
+++ b/run.sh
@@ -29,10 +29,8 @@ _init ()
exit;
}
- export cwd=$(dirname $0);
- source $cwd/regression_helpers
+ source ./regression_helpers
export GLUSTERD=$1
-
bug_id=;
if [ $# -eq 2 ]; then
bug_id=$2;
@@ -41,7 +39,6 @@ _init ()
export glusterd_conf="/etc/glusterd";
export GLUSTERFSDIR=$(dirname $GLUSTERD);
- export GLUSTERDIR=$(dirname $GLUSTERFSDIR);
export VERSION_STR=$($GLUSTERD --version) 2>&1 1>/dev/null
export VERSION=$(echo $VERSION_STR|cut -d " " -f 2)
ass='rem' style='width: 5.9%;'/> -rw-r--r--xlators/cluster/afr/src/pump.c2474
-rw-r--r--xlators/cluster/afr/src/pump.h81
-rw-r--r--xlators/cluster/dht/src/Makefile.am29
-rw-r--r--xlators/cluster/dht/src/dht-common.c7384
-rw-r--r--xlators/cluster/dht/src/dht-common.h958
-rw-r--r--xlators/cluster/dht/src/dht-diskusage.c528
-rw-r--r--xlators/cluster/dht/src/dht-hashfn.c142
-rw-r--r--xlators/cluster/dht/src/dht-helper.c1753
-rw-r--r--xlators/cluster/dht/src/dht-helper.h19
-rw-r--r--xlators/cluster/dht/src/dht-inode-read.c1140
-rw-r--r--xlators/cluster/dht/src/dht-inode-write.c1017
-rw-r--r--xlators/cluster/dht/src/dht-layout.c980
-rw-r--r--xlators/cluster/dht/src/dht-linkfile.c453
-rw-r--r--xlators/cluster/dht/src/dht-mem-types.h35
-rw-r--r--xlators/cluster/dht/src/dht-messages.h452
-rw-r--r--xlators/cluster/dht/src/dht-rebalance.c2145
-rw-r--r--xlators/cluster/dht/src/dht-rename.c1593
-rw-r--r--xlators/cluster/dht/src/dht-selfheal.c1606
-rw-r--r--xlators/cluster/dht/src/dht-shared.c840
-rw-r--r--xlators/cluster/dht/src/dht.c472
-rw-r--r--xlators/cluster/dht/src/nufa.c952
-rw-r--r--xlators/cluster/dht/src/switch.c1078
-rw-r--r--xlators/cluster/dht/src/unittest/dht_layout_mock.c63
-rw-r--r--xlators/cluster/dht/src/unittest/dht_layout_unittest.c124
-rw-r--r--xlators/cluster/ec/src/Makefile.am49
-rw-r--r--xlators/cluster/ec/src/ec-combine.c872
-rw-r--r--xlators/cluster/ec/src/ec-combine.h34
-rw-r--r--xlators/cluster/ec/src/ec-common.c1516
-rw-r--r--xlators/cluster/ec/src/ec-common.h102
-rw-r--r--xlators/cluster/ec/src/ec-data.c250
-rw-r--r--xlators/cluster/ec/src/ec-data.h295
-rw-r--r--xlators/cluster/ec/src/ec-dir-read.c635
-rw-r--r--xlators/cluster/ec/src/ec-dir-write.c2247
-rw-r--r--xlators/cluster/ec/src/ec-fops.h201
-rw-r--r--xlators/cluster/ec/src/ec-generic.c1711
-rw-r--r--xlators/cluster/ec/src/ec-gf.c11635
-rw-r--r--xlators/cluster/ec/src/ec-gf.h23
-rw-r--r--xlators/cluster/ec/src/ec-heal.c1597
-rw-r--r--xlators/cluster/ec/src/ec-helpers.c722
-rw-r--r--xlators/cluster/ec/src/ec-helpers.h60
-rw-r--r--xlators/cluster/ec/src/ec-inode-read.c1865
-rw-r--r--xlators/cluster/ec/src/ec-inode-write.c2225
-rw-r--r--xlators/cluster/ec/src/ec-locks.c1212
-rw-r--r--xlators/cluster/ec/src/ec-mem-types.h26
-rw-r--r--xlators/cluster/ec/src/ec-method.c159
-rw-r--r--xlators/cluster/ec/src/ec-method.h32
-rw-r--r--xlators/cluster/ec/src/ec.c1029
-rw-r--r--xlators/cluster/ec/src/ec.h50
-rw-r--r--xlators/cluster/ha/src/Makefile.am7
-rw-r--r--xlators/cluster/ha/src/ha-helpers.c35
-rw-r--r--xlators/cluster/ha/src/ha-mem-types.h26
-rw-r--r--xlators/cluster/ha/src/ha.c318
-rw-r--r--xlators/cluster/ha/src/ha.h32
-rw-r--r--xlators/cluster/map/src/Makefile.am7
-rw-r--r--xlators/cluster/map/src/map-helper.c29
-rw-r--r--xlators/cluster/map/src/map-mem-types.h24
-rw-r--r--xlators/cluster/map/src/map.c215
-rw-r--r--xlators/cluster/map/src/map.h25
-rw-r--r--xlators/cluster/stripe/src/Makefile.am15
-rw-r--r--xlators/cluster/stripe/src/stripe-helpers.c677
-rw-r--r--xlators/cluster/stripe/src/stripe-mem-types.h31
-rw-r--r--xlators/cluster/stripe/src/stripe.c5365
-rw-r--r--xlators/cluster/stripe/src/stripe.h187
-rw-r--r--xlators/cluster/unify/Makefile.am (renamed from xlators/cluster/ec/Makefile.am)0
-rw-r--r--xlators/cluster/unify/src/Makefile.am16
-rw-r--r--xlators/cluster/unify/src/unify-self-heal.c1227
-rw-r--r--xlators/cluster/unify/src/unify.c4552
-rw-r--r--xlators/cluster/unify/src/unify.h145
-rw-r--r--xlators/debug/error-gen/src/Makefile.am9
-rw-r--r--xlators/debug/error-gen/src/error-gen-mem-types.h20
-rw-r--r--xlators/debug/error-gen/src/error-gen.c1471
-rw-r--r--xlators/debug/error-gen/src/error-gen.h81
-rw-r--r--xlators/debug/io-stats/src/Makefile.am11
-rw-r--r--xlators/debug/io-stats/src/io-stats-mem-types.h24
-rw-r--r--xlators/debug/io-stats/src/io-stats.c2464
-rw-r--r--xlators/debug/trace/src/Makefile.am8
-rw-r--r--xlators/debug/trace/src/trace-mem-types.h21
-rw-r--r--xlators/debug/trace/src/trace.c3412
-rw-r--r--xlators/debug/trace/src/trace.h61
-rw-r--r--xlators/encryption/Makefile.am2
-rw-r--r--xlators/encryption/crypt/src/Makefile.am24
-rw-r--r--xlators/encryption/crypt/src/atom.c962
-rw-r--r--xlators/encryption/crypt/src/crypt-common.h141
-rw-r--r--xlators/encryption/crypt/src/crypt-mem-types.h44
-rw-r--r--xlators/encryption/crypt/src/crypt.c4526
-rw-r--r--xlators/encryption/crypt/src/crypt.h904
-rw-r--r--xlators/encryption/crypt/src/data.c769
-rw-r--r--xlators/encryption/crypt/src/keys.c302
-rw-r--r--xlators/encryption/crypt/src/metadata.c619
-rw-r--r--xlators/encryption/crypt/src/metadata.h74
-rw-r--r--xlators/encryption/rot-13/src/Makefile.am7
-rw-r--r--xlators/encryption/rot-13/src/rot-13.c97
-rw-r--r--xlators/encryption/rot-13/src/rot-13.h20
-rw-r--r--xlators/features/Makefile.am5
-rw-r--r--xlators/features/barrier/Makefile.am3
-rw-r--r--xlators/features/barrier/src/Makefile.am16
-rw-r--r--xlators/features/barrier/src/barrier-mem-types.h20
-rw-r--r--xlators/features/barrier/src/barrier.c664
-rw-r--r--xlators/features/barrier/src/barrier.h91
-rw-r--r--xlators/features/changelog/Makefile.am3
-rw-r--r--xlators/features/changelog/lib/Makefile.am3
-rw-r--r--xlators/features/changelog/lib/examples/c/get-changes.c87
-rw-r--r--xlators/features/changelog/lib/examples/c/get-history.c109
-rw-r--r--xlators/features/changelog/lib/examples/python/changes.py32
-rw-r--r--xlators/features/changelog/lib/examples/python/libgfchangelog.py64
-rw-r--r--xlators/features/changelog/lib/src/Makefile.am37
-rw-r--r--xlators/features/changelog/lib/src/changelog.h31
-rw-r--r--xlators/features/changelog/lib/src/gf-changelog-helpers.c180
-rw-r--r--xlators/features/changelog/lib/src/gf-changelog-helpers.h146
-rw-r--r--xlators/features/changelog/lib/src/gf-changelog-process.c657
-rw-r--r--xlators/features/changelog/lib/src/gf-changelog.c584
-rw-r--r--xlators/features/changelog/lib/src/gf-history-changelog.c930
-rw-r--r--xlators/features/changelog/src/Makefile.am20
-rw-r--r--xlators/features/changelog/src/changelog-barrier.c129
-rw-r--r--xlators/features/changelog/src/changelog-encoders.c197
-rw-r--r--xlators/features/changelog/src/changelog-encoders.h48
-rw-r--r--xlators/features/changelog/src/changelog-helpers.c1339
-rw-r--r--xlators/features/changelog/src/changelog-helpers.h608
-rw-r--r--xlators/features/changelog/src/changelog-mem-types.h30
-rw-r--r--xlators/features/changelog/src/changelog-misc.h114
-rw-r--r--xlators/features/changelog/src/changelog-notifier.c314
-rw-r--r--xlators/features/changelog/src/changelog-notifier.h19
-rw-r--r--xlators/features/changelog/src/changelog-rt.c72
-rw-r--r--xlators/features/changelog/src/changelog-rt.h33
-rw-r--r--xlators/features/changelog/src/changelog.c2502
-rw-r--r--xlators/features/compress/Makefile.am3
-rw-r--r--xlators/features/compress/src/Makefile.am17
-rw-r--r--xlators/features/compress/src/cdc-helper.c547
-rw-r--r--xlators/features/compress/src/cdc-mem-types.h23
-rw-r--r--xlators/features/compress/src/cdc.c361
-rw-r--r--xlators/features/compress/src/cdc.h107
-rw-r--r--xlators/features/filter/src/Makefile.am9
-rw-r--r--xlators/features/filter/src/filter-mem-types.h20
-rw-r--r--xlators/features/filter/src/filter.c193
-rw-r--r--xlators/features/gfid-access/src/Makefile.am15
-rw-r--r--xlators/features/gfid-access/src/gfid-access-mem-types.h23
-rw-r--r--xlators/features/gfid-access/src/gfid-access.c1413
-rw-r--r--xlators/features/gfid-access/src/gfid-access.h108
-rw-r--r--xlators/features/glupy/Makefile.am3
-rw-r--r--xlators/features/glupy/doc/README.md44
-rw-r--r--xlators/features/glupy/doc/TESTING9
-rw-r--r--xlators/features/glupy/doc/test.vol10
-rw-r--r--xlators/features/glupy/examples/Makefile.am5
-rw-r--r--xlators/features/glupy/examples/debug-trace.py775
-rw-r--r--xlators/features/glupy/examples/helloworld.py19
-rw-r--r--xlators/features/glupy/examples/negative.py91
-rw-r--r--xlators/features/glupy/src/Makefile.am24
-rw-r--r--xlators/features/glupy/src/__init__.py.in0
-rw-r--r--xlators/features/glupy/src/glupy.c2501
-rw-r--r--xlators/features/glupy/src/glupy.h60
-rw-r--r--xlators/features/glupy/src/glupy/Makefile.am5
-rw-r--r--xlators/features/glupy/src/glupy/__init__.py852
-rw-r--r--xlators/features/glupy/src/setup.py.in24
-rw-r--r--xlators/features/index/Makefile.am3
-rw-r--r--xlators/features/index/src/Makefile.am17
-rw-r--r--xlators/features/index/src/index-mem-types.h22
-rw-r--r--xlators/features/index/src/index.c1348
-rw-r--r--xlators/features/index/src/index.h60
-rw-r--r--xlators/features/locks/src/Makefile.am17
-rw-r--r--xlators/features/locks/src/clear.c423
-rw-r--r--xlators/features/locks/src/clear.h76
-rw-r--r--xlators/features/locks/src/common.c597
-rw-r--r--xlators/features/locks/src/common.h95
-rw-r--r--xlators/features/locks/src/entrylk.c907
-rw-r--r--xlators/features/locks/src/inodelk.c923
-rw-r--r--xlators/features/locks/src/locks-mem-types.h29
-rw-r--r--xlators/features/locks/src/locks.h122
-rw-r--r--xlators/features/locks/src/posix.c2075
-rw-r--r--xlators/features/locks/src/reservelk.c443
-rw-r--r--xlators/features/locks/tests/unit-test.c22
-rw-r--r--xlators/features/mac-compat/Makefile.am3
-rw-r--r--xlators/features/mac-compat/src/Makefile.am15
-rw-r--r--xlators/features/mac-compat/src/mac-compat.c349
-rw-r--r--xlators/features/mac-compat/src/mac-compat.h41
-rw-r--r--xlators/features/marker/Makefile.am3
-rw-r--r--xlators/features/marker/src/Makefile.am17
-rw-r--r--xlators/features/marker/src/marker-common.c69
-rw-r--r--xlators/features/marker/src/marker-common.h27
-rw-r--r--xlators/features/marker/src/marker-mem-types.h25
-rw-r--r--xlators/features/marker/src/marker-quota-helper.c429
-rw-r--r--xlators/features/marker/src/marker-quota-helper.h76
-rw-r--r--xlators/features/marker/src/marker-quota.c2716
-rw-r--r--xlators/features/marker/src/marker-quota.h135
-rw-r--r--xlators/features/marker/src/marker.c3197
-rw-r--r--xlators/features/marker/src/marker.h139
-rw-r--r--xlators/features/path-convertor/src/Makefile.am7
-rw-r--r--xlators/features/path-convertor/src/path-mem-types.h22
-rw-r--r--xlators/features/path-convertor/src/path.c184
-rw-r--r--xlators/features/protect/Makefile.am3
-rw-r--r--xlators/features/protect/src/Makefile.am21
-rw-r--r--xlators/features/protect/src/prot_client.c219
-rw-r--r--xlators/features/protect/src/prot_dht.c168
-rw-r--r--xlators/features/protect/src/prot_server.c51
-rw-r--r--xlators/features/qemu-block/src/Makefile.am155
-rw-r--r--xlators/features/qemu-block/src/bdrv-xlator.c389
-rw-r--r--xlators/features/qemu-block/src/bh-syncop.c48
-rw-r--r--xlators/features/qemu-block/src/clock-timer.c60
-rw-r--r--xlators/features/qemu-block/src/coroutine-synctask.c116
-rw-r--r--xlators/features/qemu-block/src/monitor-logging.c50
-rw-r--r--xlators/features/qemu-block/src/qb-coroutines.c667
-rw-r--r--xlators/features/qemu-block/src/qb-coroutines.h30
-rw-r--r--xlators/features/qemu-block/src/qemu-block-memory-types.h25
-rw-r--r--xlators/features/qemu-block/src/qemu-block.c1140
-rw-r--r--xlators/features/qemu-block/src/qemu-block.h109
-rw-r--r--xlators/features/quiesce/Makefile.am3
-rw-r--r--xlators/features/quiesce/src/Makefile.am15
-rw-r--r--xlators/features/quiesce/src/quiesce-mem-types.h20
-rw-r--r--xlators/features/quiesce/src/quiesce.c2610
-rw-r--r--xlators/features/quiesce/src/quiesce.h51
-rw-r--r--xlators/features/quota/src/Makefile.am23
-rw-r--r--xlators/features/quota/src/quota-enforcer-client.c405
-rw-r--r--xlators/features/quota/src/quota-mem-types.h30
-rw-r--r--xlators/features/quota/src/quota.c5093
-rw-r--r--xlators/features/quota/src/quota.h245
-rw-r--r--xlators/features/quota/src/quotad-aggregator.c419
-rw-r--r--xlators/features/quota/src/quotad-aggregator.h37
-rw-r--r--xlators/features/quota/src/quotad-helpers.c107
-rw-r--r--xlators/features/quota/src/quotad-helpers.h24
-rw-r--r--xlators/features/quota/src/quotad.c210
-rw-r--r--xlators/features/read-only/Makefile.am3
-rw-r--r--xlators/features/read-only/src/Makefile.am22
-rw-r--r--xlators/features/read-only/src/read-only-common.c239
-rw-r--r--xlators/features/read-only/src/read-only-common.h115
-rw-r--r--xlators/features/read-only/src/read-only.c77
-rw-r--r--xlators/features/read-only/src/worm.c89
-rw-r--r--xlators/features/snapview-client/Makefile.am1
-rw-r--r--xlators/features/snapview-client/src/Makefile.am15
-rw-r--r--xlators/features/snapview-client/src/snapview-client-mem-types.h24
-rw-r--r--xlators/features/snapview-client/src/snapview-client.c2356
-rw-r--r--xlators/features/snapview-client/src/snapview-client.h126
-rw-r--r--xlators/features/snapview-server/Makefile.am1
-rw-r--r--xlators/features/snapview-server/src/Makefile.am22
-rw-r--r--xlators/features/snapview-server/src/snapview-server-helpers.c594
-rw-r--r--xlators/features/snapview-server/src/snapview-server-mem-types.h26
-rw-r--r--xlators/features/snapview-server/src/snapview-server-mgmt.c480
-rw-r--r--xlators/features/snapview-server/src/snapview-server.c2246
-rw-r--r--xlators/features/snapview-server/src/snapview-server.h226
-rw-r--r--xlators/features/trash/src/Makefile.am9
-rw-r--r--xlators/features/trash/src/trash-mem-types.h22
-rw-r--r--xlators/features/trash/src/trash.c378
-rw-r--r--xlators/features/trash/src/trash.h30
-rw-r--r--xlators/lib/src/libxlator.c527
-rw-r--r--xlators/lib/src/libxlator.h157
-rw-r--r--xlators/meta/src/Makefile.am47
-rw-r--r--xlators/meta/src/active-link.c44
-rw-r--r--xlators/meta/src/cmdline-file.c48
-rw-r--r--xlators/meta/src/frames-file.c122
-rw-r--r--xlators/meta/src/graph-dir.c106
-rw-r--r--xlators/meta/src/graphs-dir.c79
-rw-r--r--xlators/meta/src/history-file.c52
-rw-r--r--xlators/meta/src/logfile-link.c44
-rw-r--r--xlators/meta/src/logging-dir.c51
-rw-r--r--xlators/meta/src/loglevel-file.c59
-rw-r--r--xlators/meta/src/mallinfo-file.c44
-rw-r--r--xlators/meta/src/measure-file.c57
-rw-r--r--xlators/meta/src/meminfo-file.c52
-rw-r--r--xlators/meta/src/meta-defaults.c641
-rw-r--r--xlators/meta/src/meta-helpers.c370
-rw-r--r--xlators/meta/src/meta-hooks.h46
-rw-r--r--xlators/meta/src/meta-mem-types.h26
-rw-r--r--xlators/meta/src/meta.c1309
-rw-r--r--xlators/meta/src/meta.h138
-rw-r--r--xlators/meta/src/misc.c67
-rw-r--r--xlators/meta/src/misc.h31
-rw-r--r--xlators/meta/src/name-file.c53
-rw-r--r--xlators/meta/src/option-file.c56
-rw-r--r--xlators/meta/src/options-dir.c76
-rw-r--r--xlators/meta/src/private-file.c52
-rw-r--r--xlators/meta/src/process_uuid-file.c46
-rw-r--r--xlators/meta/src/profile-file.c52
-rw-r--r--xlators/meta/src/root-dir.c79
-rw-r--r--xlators/meta/src/subvolume-link.c66
-rw-r--r--xlators/meta/src/subvolumes-dir.c72
-rw-r--r--xlators/meta/src/top-link.c50
-rw-r--r--xlators/meta/src/tree.c176
-rw-r--r--xlators/meta/src/tree.h35
-rw-r--r--xlators/meta/src/type-file.c53
-rw-r--r--xlators/meta/src/version-file.c47
-rw-r--r--xlators/meta/src/view-dir.c45
-rw-r--r--xlators/meta/src/view.c258
-rw-r--r--xlators/meta/src/view.h32
-rw-r--r--xlators/meta/src/volfile-file.c91
-rw-r--r--xlators/meta/src/xlator-dir.c100
-rw-r--r--xlators/mgmt/Makefile.am3
-rw-r--r--xlators/mgmt/glusterd/Makefile.am3
-rw-r--r--xlators/mgmt/glusterd/src/Makefile.am49
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-brick-ops.c2191
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-geo-rep.c5359
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-handler.c4578
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-handshake.c2015
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-hooks.c568
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-hooks.h89
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-locks.c672
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-locks.h51
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-log-ops.c271
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-mem-types.h77
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-messages.h221
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-mgmt-handler.c930
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-mgmt.c2011
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-mgmt.h51
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-mountbroker.c693
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-mountbroker.h42
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-op-sm.c6775
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-op-sm.h317
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-peer-utils.c902
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-peer-utils.h87
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-pmap.c500
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-pmap.h54
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-quota.c1473
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-rebalance.c825
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-replace-brick.c2066
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-rpc-ops.c2172
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-sm.c1156
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-sm.h217
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-snapshot.c8371
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-store.c4429
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-store.h184
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-syncop.c1729
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-syncop.h74
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-utils.c13832
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-utils.h932
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-volgen.c4820
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-volgen.h181
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-volume-ops.c2533
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-volume-set.c1676
-rw-r--r--xlators/mgmt/glusterd/src/glusterd.c1713
-rw-r--r--xlators/mgmt/glusterd/src/glusterd.h1047
-rw-r--r--xlators/mount/fuse/src/Makefile.am41
-rw-r--r--xlators/mount/fuse/src/fuse-bridge.c5240
-rw-r--r--xlators/mount/fuse/src/fuse-bridge.h412
-rw-r--r--xlators/mount/fuse/src/fuse-helpers.c610
-rw-r--r--xlators/mount/fuse/src/fuse-mem-types.h28
-rw-r--r--xlators/mount/fuse/src/fuse-resolve.c718
-rw-r--r--xlators/mount/fuse/utils/Makefile.am9
-rwxr-xr-xxlators/mount/fuse/utils/mount.glusterfs.in721
-rwxr-xr-xxlators/mount/fuse/utils/mount_glusterfs.in612
-rw-r--r--xlators/nfs/Makefile.am3
-rw-r--r--xlators/nfs/server/Makefile.am3
-rw-r--r--xlators/nfs/server/src/Makefile.am24
-rw-r--r--xlators/nfs/server/src/acl3.c920
-rw-r--r--xlators/nfs/server/src/acl3.h42
-rw-r--r--xlators/nfs/server/src/mount3.c2813
-rw-r--r--xlators/nfs/server/src/mount3.h131
-rw-r--r--xlators/nfs/server/src/mount3udp_svc.c198
-rw-r--r--xlators/nfs/server/src/nfs-common.c465
-rw-r--r--xlators/nfs/server/src/nfs-common.h81
-rw-r--r--xlators/nfs/server/src/nfs-fops.c1697
-rw-r--r--xlators/nfs/server/src/nfs-fops.h248
-rw-r--r--xlators/nfs/server/src/nfs-generics.c345
-rw-r--r--xlators/nfs/server/src/nfs-generics.h168
-rw-r--r--xlators/nfs/server/src/nfs-inodes.c608
-rw-r--r--xlators/nfs/server/src/nfs-inodes.h76
-rw-r--r--xlators/nfs/server/src/nfs-mem-types.h53
-rw-r--r--xlators/nfs/server/src/nfs.c1924
-rw-r--r--xlators/nfs/server/src/nfs.h137
-rw-r--r--xlators/nfs/server/src/nfs3-fh.c188
-rw-r--r--xlators/nfs/server/src/nfs3-fh.h103
-rw-r--r--xlators/nfs/server/src/nfs3-helpers.c3881
-rw-r--r--xlators/nfs/server/src/nfs3-helpers.h340
-rw-r--r--xlators/nfs/server/src/nfs3.c5633
-rw-r--r--xlators/nfs/server/src/nfs3.h287
-rw-r--r--xlators/nfs/server/src/nlm4.c2546
-rw-r--r--xlators/nfs/server/src/nlm4.h112
-rw-r--r--xlators/nfs/server/src/nlmcbk_svc.c116
-rw-r--r--xlators/performance/Makefile.am2
-rw-r--r--xlators/performance/io-cache/src/Makefile.am10
-rw-r--r--xlators/performance/io-cache/src/io-cache.c2376
-rw-r--r--xlators/performance/io-cache/src/io-cache.h317
-rw-r--r--xlators/performance/io-cache/src/ioc-inode.c295
-rw-r--r--xlators/performance/io-cache/src/ioc-mem-types.h29
-rw-r--r--xlators/performance/io-cache/src/page.c1303
-rw-r--r--xlators/performance/io-threads/src/Makefile.am9
-rw-r--r--xlators/performance/io-threads/src/io-threads.c3166
-rw-r--r--xlators/performance/io-threads/src/io-threads.h181
-rw-r--r--xlators/performance/io-threads/src/iot-mem-types.h22
-rw-r--r--xlators/performance/md-cache/Makefile.am1
-rw-r--r--xlators/performance/md-cache/src/Makefile.am25
-rw-r--r--xlators/performance/md-cache/src/md-cache-mem-types.h24
-rw-r--r--xlators/performance/md-cache/src/md-cache.c2323
-rw-r--r--xlators/performance/open-behind/Makefile.am1
-rw-r--r--xlators/performance/open-behind/src/Makefile.am15
-rw-r--r--xlators/performance/open-behind/src/open-behind-mem-types.h21
-rw-r--r--xlators/performance/open-behind/src/open-behind.c1020
-rw-r--r--xlators/performance/quick-read/src/Makefile.am9
-rw-r--r--xlators/performance/quick-read/src/quick-read-mem-types.h27
-rw-r--r--xlators/performance/quick-read/src/quick-read.c2886
-rw-r--r--xlators/performance/quick-read/src/quick-read.h64
-rw-r--r--xlators/performance/read-ahead/src/Makefile.am9
-rw-r--r--xlators/performance/read-ahead/src/page.c689
-rw-r--r--xlators/performance/read-ahead/src/read-ahead-mem-types.h26
-rw-r--r--xlators/performance/read-ahead/src/read-ahead.c1587
-rw-r--r--xlators/performance/read-ahead/src/read-ahead.h148
-rw-r--r--xlators/performance/readdir-ahead/Makefile.am3
-rw-r--r--xlators/performance/readdir-ahead/src/Makefile.am15
-rw-r--r--xlators/performance/readdir-ahead/src/readdir-ahead-mem-types.h24
-rw-r--r--xlators/performance/readdir-ahead/src/readdir-ahead.c567
-rw-r--r--xlators/performance/readdir-ahead/src/readdir-ahead.h46
-rw-r--r--xlators/performance/stat-prefetch/Makefile.am (renamed from xlators/features/qemu-block/Makefile.am)0
-rw-r--r--xlators/performance/stat-prefetch/src/Makefile.am14
-rw-r--r--xlators/performance/stat-prefetch/src/stat-prefetch.c3895
-rw-r--r--xlators/performance/stat-prefetch/src/stat-prefetch.h104
-rw-r--r--xlators/performance/symlink-cache/src/Makefile.am7
-rw-r--r--xlators/performance/symlink-cache/src/symlink-cache.c76
-rw-r--r--xlators/performance/write-behind/src/Makefile.am9
-rw-r--r--xlators/performance/write-behind/src/write-behind-mem-types.h26
-rw-r--r--xlators/performance/write-behind/src/write-behind.c3723
-rw-r--r--xlators/playground/Makefile.am2
-rw-r--r--xlators/playground/template/Makefile.am2
-rw-r--r--xlators/playground/template/src/Makefile.am16
-rw-r--r--xlators/playground/template/src/template.c49
-rw-r--r--xlators/playground/template/src/template.h24
-rw-r--r--xlators/protocol/Makefile.am4
-rw-r--r--xlators/protocol/auth/Makefile.am1
-rw-r--r--xlators/protocol/auth/addr/Makefile.am1
-rw-r--r--xlators/protocol/auth/addr/src/Makefile.am14
-rw-r--r--xlators/protocol/auth/addr/src/addr.c230
-rw-r--r--xlators/protocol/auth/login/Makefile.am1
-rw-r--r--xlators/protocol/auth/login/src/Makefile.am12
-rw-r--r--xlators/protocol/auth/login/src/login.c148
-rw-r--r--xlators/protocol/client/Makefile.am2
-rw-r--r--xlators/protocol/client/src/Makefile.am18
-rw-r--r--xlators/protocol/client/src/client-callback.c56
-rw-r--r--xlators/protocol/client/src/client-handshake.c1703
-rw-r--r--xlators/protocol/client/src/client-helpers.c349
-rw-r--r--xlators/protocol/client/src/client-lk.c573
-rw-r--r--xlators/protocol/client/src/client-mem-types.h25
-rw-r--r--xlators/protocol/client/src/client-protocol.c7244
-rw-r--r--xlators/protocol/client/src/client-protocol.h178
-rw-r--r--xlators/protocol/client/src/client-rpc-fops.c6210
-rw-r--r--xlators/protocol/client/src/client.c2930
-rw-r--r--xlators/protocol/client/src/client.h260
-rw-r--r--xlators/protocol/client/src/saved-frames.c191
-rw-r--r--xlators/protocol/client/src/saved-frames.h79
-rw-r--r--xlators/protocol/server/Makefile.am2
-rw-r--r--xlators/protocol/server/src/Makefile.am28
-rw-r--r--xlators/protocol/server/src/authenticate.c253
-rw-r--r--xlators/protocol/server/src/authenticate.h51
-rw-r--r--xlators/protocol/server/src/server-handshake.c792
-rw-r--r--xlators/protocol/server/src/server-helpers.c1626
-rw-r--r--xlators/protocol/server/src/server-helpers.h84
-rw-r--r--xlators/protocol/server/src/server-mem-types.h30
-rw-r--r--xlators/protocol/server/src/server-protocol.c6907
-rw-r--r--xlators/protocol/server/src/server-protocol.h196
-rw-r--r--xlators/protocol/server/src/server-resolve.c490
-rw-r--r--xlators/protocol/server/src/server-rpc-fops.c6168
-rw-r--r--xlators/protocol/server/src/server.c1198
-rw-r--r--xlators/protocol/server/src/server.h170
-rw-r--r--xlators/storage/Makefile.am6
-rw-r--r--xlators/storage/bd/Makefile.am3
-rw-r--r--xlators/storage/bd/src/Makefile.am20
-rw-r--r--xlators/storage/bd/src/bd-aio.c528
-rw-r--r--xlators/storage/bd/src/bd-aio.h41
-rw-r--r--xlators/storage/bd/src/bd-helper.c1021
-rw-r--r--xlators/storage/bd/src/bd-mem-types.h27
-rw-r--r--xlators/storage/bd/src/bd.c2450
-rw-r--r--xlators/storage/bd/src/bd.h173
-rw-r--r--xlators/storage/bdb/Makefile.am (renamed from xlators/encryption/crypt/Makefile.am)0
-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.c1460
-rw-r--r--xlators/storage/bdb/src/bdb.c3585
-rw-r--r--xlators/storage/bdb/src/bdb.h530
-rw-r--r--xlators/storage/posix/src/Makefile.am18
-rw-r--r--xlators/storage/posix/src/posix-aio.c569
-rw-r--r--xlators/storage/posix/src/posix-aio.h39
-rw-r--r--xlators/storage/posix/src/posix-handle.c882
-rw-r--r--xlators/storage/posix/src/posix-handle.h273
-rw-r--r--xlators/storage/posix/src/posix-helpers.c1755
-rw-r--r--xlators/storage/posix/src/posix-mem-types.h27
-rw-r--r--xlators/storage/posix/src/posix.c6530
-rw-r--r--xlators/storage/posix/src/posix.h181
-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.am23
-rw-r--r--xlators/system/posix-acl/src/posix-acl-mem-types.h24
-rw-r--r--xlators/system/posix-acl/src/posix-acl-xattr.c180
-rw-r--r--xlators/system/posix-acl/src/posix-acl-xattr.h26
-rw-r--r--xlators/system/posix-acl/src/posix-acl.c2206
-rw-r--r--xlators/system/posix-acl/src/posix-acl.h30
519 files changed, 77480 insertions, 293153 deletions
diff --git a/xlators/Makefile.am b/xlators/Makefile.am
index 2a03f905b6d..2abb5219488 100644
--- a/xlators/Makefile.am
+++ b/xlators/Makefile.am
@@ -1,4 +1,3 @@
-SUBDIRS = cluster storage protocol performance debug features encryption mount nfs mgmt system \
- playground meta
+SUBDIRS = cluster storage protocol performance debug features encryption mount
-CLEANFILES =
+CLEANFILES =
diff --git a/xlators/bindings/Makefile.am b/xlators/bindings/Makefile.am
new file mode 100644
index 00000000000..f7766580257
--- /dev/null
+++ b/xlators/bindings/Makefile.am
@@ -0,0 +1 @@
+SUBDIRS = $(BINDINGS_SUBDIRS)
diff --git a/xlators/features/gfid-access/Makefile.am b/xlators/bindings/python/Makefile.am
index af437a64d6d..af437a64d6d 100644
--- a/xlators/features/gfid-access/Makefile.am
+++ b/xlators/bindings/python/Makefile.am
diff --git a/xlators/bindings/python/src/Makefile.am b/xlators/bindings/python/src/Makefile.am
new file mode 100644
index 00000000000..c0b9141c667
--- /dev/null
+++ b/xlators/bindings/python/src/Makefile.am
@@ -0,0 +1,19 @@
+
+xlator_PROGRAMS = python.so
+
+xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/bindings
+
+python_PYTHON = gluster.py glustertypes.py glusterstack.py
+
+pythondir = $(xlatordir)/python
+
+python_so_SOURCES = python.c
+
+AM_CFLAGS = -fPIC -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -Wall \
+ -I$(top_srcdir)/libglusterfs/src -shared -nostartfiles \
+ $(PYTHON_CPPLAGS) -DGLUSTER_PYTHON_PATH=\"$(pythondir)\"
+
+AM_LDFLAGS = $(PYTHON_LDFLAGS)
+
+CLEANFILES =
+
diff --git a/xlators/bindings/python/src/gluster.py b/xlators/bindings/python/src/gluster.py
new file mode 100644
index 00000000000..ee0eb131011
--- /dev/null
+++ b/xlators/bindings/python/src/gluster.py
@@ -0,0 +1,47 @@
+# Copyright (c) 2007 Chris AtLee <chris@atlee.ca>
+# 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/>.
+from ctypes import *
+from glustertypes import *
+from glusterstack import *
+import sys
+import inspect
+
+libglusterfs = CDLL("libglusterfs.so")
+_gf_log = libglusterfs._gf_log
+_gf_log.restype = c_int32
+_gf_log.argtypes = [c_char_p, c_char_p, c_char_p, c_int32, c_int, c_char_p]
+
+gf_log_loglevel = c_int.in_dll(libglusterfs, "gf_log_loglevel")
+
+GF_LOG_NONE = 0
+GF_LOG_CRITICAL = 1
+GF_LOG_ERROR = 2
+GF_LOG_WARNING = 3
+GF_LOG_DEBUG = 4
+
+def gf_log(module, level, fmt, *params):
+ if level <= gf_log_loglevel:
+ frame = sys._getframe(1)
+ _gf_log(module, frame.f_code.co_filename, frame.f_code.co_name,
+ frame.f_lineno, level, fmt, *params)
+
+class ComplexTranslator(object):
+ def __init__(self, xlator):
+ self.xlator = xlator_t.from_address(xlator)
+
+ def __getattr__(self, item):
+ return getattr(self.xlator, item)
diff --git a/xlators/bindings/python/src/glusterstack.py b/xlators/bindings/python/src/glusterstack.py
new file mode 100644
index 00000000000..ba24c81652e
--- /dev/null
+++ b/xlators/bindings/python/src/glusterstack.py
@@ -0,0 +1,55 @@
+# Copyright (c) 2007 Chris AtLee <chris@atlee.ca>
+# 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/>.
+from ctypes import *
+from glustertypes import *
+
+libc = CDLL("libc.so.6")
+calloc = libc.calloc
+calloc.argtypes = [c_int, c_int]
+calloc.restype = c_void_p
+
+# TODO: Can these be done in C somehow?
+def stack_wind(frame, rfn, obj, fn, *params):
+ """Frame is a frame object"""
+ _new = cast(calloc(1, sizeof(call_frame_t)), POINTER(call_frame_t))
+ _new[0].root = frame.root
+ _new[0].next = frame.root[0].frames.next
+ _new[0].prev = pointer(frame.root[0].frames)
+ if frame.root[0].frames.next:
+ frame.root[0].frames.next[0].prev = _new
+ frame.root[0].frames.next = _new
+ _new[0].this = obj
+ # TODO: Type checking like tmp_cbk?
+ _new[0].ret = rfn
+ _new[0].parent = pointer(frame)
+ _new[0].cookie = cast(_new, c_void_p)
+ # TODO: Initialize lock
+ #_new.lock.init()
+ frame.ref_count += 1
+ fn(_new, obj, *params)
+
+def stack_unwind(frame, *params):
+ """Frame is a frame object"""
+ fn = frame[0].ret
+ parent = frame[0].parent[0]
+ parent.ref_count -= 1
+
+ op_ret = params[0]
+ op_err = params[1]
+ params = params[2:]
+ fn(parent, call_frame_t.from_address(frame[0].cookie), parent.this,
+ op_ret, op_err, *params)
diff --git a/xlators/bindings/python/src/glustertypes.py b/xlators/bindings/python/src/glustertypes.py
new file mode 100644
index 00000000000..e9069d07c72
--- /dev/null
+++ b/xlators/bindings/python/src/glustertypes.py
@@ -0,0 +1,167 @@
+# Copyright (c) 2007 Chris AtLee <chris@atlee.ca>
+# 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/>.
+from ctypes import *
+import collections
+
+#
+# Forward declaration of some gluster types
+#
+class call_frame_t(Structure):
+ pass
+
+class call_ctx_t(Structure):
+ pass
+
+class call_pool_t(Structure):
+ pass
+
+class xlator_t(Structure):
+ def _getFirstChild(self):
+ return self.children[0].xlator
+ firstChild = property(_getFirstChild)
+
+class xlator_list_t(Structure):
+ pass
+
+class xlator_fops(Structure):
+ pass
+
+class xlator_mops(Structure):
+ pass
+
+class glusterfs_ctx_t(Structure):
+ pass
+
+class list_head(Structure):
+ pass
+
+class dict_t(Structure):
+ pass
+
+class inode_table_t(Structure):
+ pass
+
+class fd_t(Structure):
+ pass
+
+class iovec(Structure):
+ _fields_ = [
+ ("iov_base", c_void_p),
+ ("iov_len", c_size_t),
+ ]
+
+ def __init__(self, s):
+ self.iov_base = cast(c_char_p(s), c_void_p)
+ self.iov_len = len(s)
+
+ def getBytes(self):
+ return string_at(self.iov_base, self.iov_len)
+
+# This is a pthread_spinlock_t
+# TODO: what happens to volatile-ness?
+gf_lock_t = c_int
+
+uid_t = c_uint32
+gid_t = c_uint32
+pid_t = c_int32
+
+off_t = c_int64
+
+#
+# Function pointer types
+#
+ret_fn_t = CFUNCTYPE(c_int32, POINTER(call_frame_t), POINTER(call_frame_t),
+ POINTER(xlator_t), c_int32, c_int32)
+
+fini_fn_t = CFUNCTYPE(None, POINTER(xlator_t))
+init_fn_t = CFUNCTYPE(c_int32, POINTER(xlator_t))
+event_notify_fn_t = CFUNCTYPE(c_int32, POINTER(xlator_t), c_int32, c_void_p)
+
+list_head._fields_ = [
+ ("next", POINTER(list_head)),
+ ("prev", POINTER(list_head)),
+ ]
+
+call_frame_t._fields_ = [
+ ("root", POINTER(call_ctx_t)),
+ ("parent", POINTER(call_frame_t)),
+ ("next", POINTER(call_frame_t)),
+ ("prev", POINTER(call_frame_t)),
+ ("local", c_void_p),
+ ("this", POINTER(xlator_t)),
+ ("ret", ret_fn_t),
+ ("ref_count", c_int32),
+ ("lock", gf_lock_t),
+ ("cookie", c_void_p),
+ ("op", c_int32),
+ ("type", c_int8),
+ ]
+
+call_ctx_t._fields_ = [
+ ("all_frames", list_head),
+ ("trans", c_void_p),
+ ("pool", call_pool_t),
+ ("unique", c_uint64),
+ ("state", c_void_p),
+ ("uid", uid_t),
+ ("gid", gid_t),
+ ("pid", pid_t),
+ ("frames", call_frame_t),
+ ("req_refs", POINTER(dict_t)),
+ ("rsp_refs", POINTER(dict_t)),
+ ]
+
+xlator_t._fields_ = [
+ ("name", c_char_p),
+ ("type", c_char_p),
+ ("next", POINTER(xlator_t)),
+ ("prev", POINTER(xlator_t)),
+ ("parent", POINTER(xlator_t)),
+ ("children", POINTER(xlator_list_t)),
+ ("fops", POINTER(xlator_fops)),
+ ("mops", POINTER(xlator_mops)),
+ ("fini", fini_fn_t),
+ ("init", init_fn_t),
+ ("notify", event_notify_fn_t),
+ ("options", POINTER(dict_t)),
+ ("ctx", POINTER(glusterfs_ctx_t)),
+ ("itable", POINTER(inode_table_t)),
+ ("ready", c_char),
+ ("private", c_void_p),
+ ]
+
+xlator_list_t._fields_ = [
+ ("xlator", POINTER(xlator_t)),
+ ("next", POINTER(xlator_list_t)),
+ ]
+
+fop_functions = collections.defaultdict(lambda: c_void_p)
+fop_function_names = ['lookup', 'forget', 'stat', 'fstat', 'chmod', 'fchmod',
+ 'chown', 'fchown', 'truncate', 'ftruncate', 'utimens', 'access',
+ 'readlink', 'mknod', 'mkdir', 'unlink', 'rmdir', 'symlink',
+ 'rename', 'link', 'create', 'open', 'readv', 'writev', 'flush',
+ 'close', 'fsync', 'opendir', 'readdir', 'closedir', 'fsyncdir',
+ 'statfs', 'setxattr', 'getxattr', 'removexattr', 'lk', 'writedir',
+ # TODO: Call backs?
+ ]
+
+fop_writev_t = CFUNCTYPE(c_int32, POINTER(call_frame_t), POINTER(xlator_t),
+ POINTER(fd_t), POINTER(iovec), c_int32,
+ off_t)
+
+fop_functions['writev'] = fop_writev_t
+xlator_fops._fields_ = [(f, fop_functions[f]) for f in fop_function_names]
diff --git a/xlators/bindings/python/src/python.c b/xlators/bindings/python/src/python.c
new file mode 100644
index 00000000000..7f32d7f2997
--- /dev/null
+++ b/xlators/bindings/python/src/python.c
@@ -0,0 +1,235 @@
+/*
+ Copyright (c) 2007-2009 Chris AtLee <chris@atlee.ca>
+ 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 <Python.h>
+
+#ifndef _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+#include "glusterfs.h"
+#include "xlator.h"
+#include "logging.h"
+#include "defaults.h"
+
+typedef struct
+{
+ char *scriptname;
+ PyObject *pXlator;
+ PyObject *pScriptModule;
+ PyObject *pGlusterModule;
+ PyThreadState *pInterp;
+
+ PyObject *pFrameType, *pVectorType, *pFdType;
+} python_private_t;
+
+int32_t
+python_writev (call_frame_t *frame,
+ xlator_t *this,
+ fd_t *fd,
+ struct iovec *vector,
+ int32_t count,
+ off_t offset)
+{
+ python_private_t *priv = (python_private_t *)this->private;
+ gf_log("python", GF_LOG_DEBUG, "In writev");
+ if (PyObject_HasAttrString(priv->pXlator, "writev"))
+ {
+
+ PyObject *retval = PyObject_CallMethod(priv->pXlator, "writev",
+ "O O O i l",
+ PyObject_CallMethod(priv->pFrameType, "from_address", "O&", PyLong_FromVoidPtr, frame),
+ PyObject_CallMethod(priv->pFdType, "from_address", "O&", PyLong_FromVoidPtr, fd),
+ PyObject_CallMethod(priv->pVectorType, "from_address", "O&", PyLong_FromVoidPtr, vector),
+ count,
+ offset);
+ if (PyErr_Occurred())
+ {
+ PyErr_Print();
+ }
+ Py_XDECREF(retval);
+ }
+ else
+ {
+ return default_writev(frame, this, fd, vector, count, offset);
+ }
+ return 0;
+}
+
+struct xlator_fops fops = {
+ .writev = python_writev
+};
+
+struct xlator_mops mops = {
+};
+
+static PyObject *
+AnonModule_FromFile (const char* fname)
+{
+ // Get the builtins
+ PyThreadState* pThread = PyThreadState_Get();
+ PyObject *pBuiltins = pThread->interp->builtins;
+
+ if (PyErr_Occurred())
+ {
+ PyErr_Print();
+ return NULL;
+ }
+
+ // Create a new dictionary for running code in
+ PyObject *pModuleDict = PyDict_New();
+ PyDict_SetItemString(pModuleDict, "__builtins__", pBuiltins);
+ Py_INCREF(pBuiltins);
+
+ // Run the file in the new context
+ FILE* fp = fopen(fname, "r");
+ PyRun_File(fp, fname, Py_file_input, pModuleDict, pModuleDict);
+ fclose(fp);
+ if (PyErr_Occurred())
+ {
+ PyErr_Print();
+ Py_DECREF(pModuleDict);
+ Py_DECREF(pBuiltins);
+ return NULL;
+ }
+
+ // Create an object to hold the new context
+ PyRun_String("class ModuleWrapper(object):\n\tpass\n", Py_single_input, pModuleDict, pModuleDict);
+ if (PyErr_Occurred())
+ {
+ PyErr_Print();
+ Py_DECREF(pModuleDict);
+ Py_DECREF(pBuiltins);
+ return NULL;
+ }
+ PyObject *pModule = PyRun_String("ModuleWrapper()", Py_eval_input, pModuleDict, pModuleDict);
+ if (PyErr_Occurred())
+ {
+ PyErr_Print();
+ Py_DECREF(pModuleDict);
+ Py_DECREF(pBuiltins);
+ Py_XDECREF(pModule);
+ return NULL;
+ }
+
+ // Set the new context's dictionary to the one we used to run the code
+ // inside
+ PyObject_SetAttrString(pModule, "__dict__", pModuleDict);
+ if (PyErr_Occurred())
+ {
+ PyErr_Print();
+ Py_DECREF(pModuleDict);
+ Py_DECREF(pBuiltins);
+ Py_DECREF(pModule);
+ return NULL;
+ }
+
+ return pModule;
+}
+
+int32_t
+init (xlator_t *this)
+{
+ // This is ok to call more than once per process
+ Py_InitializeEx(0);
+
+ if (!this->children) {
+ gf_log ("python", GF_LOG_ERROR,
+ "FATAL: python should have exactly one child");
+ return -1;
+ }
+
+ python_private_t *priv = CALLOC (sizeof (python_private_t), 1);
+ ERR_ABORT (priv);
+
+ data_t *scriptname = dict_get (this->options, "scriptname");
+ if (scriptname) {
+ priv->scriptname = data_to_str(scriptname);
+ } else {
+ gf_log("python", GF_LOG_ERROR,
+ "FATAL: python requires the scriptname parameter");
+ return -1;
+ }
+
+ priv->pInterp = Py_NewInterpreter();
+
+ // Adjust python's path
+ PyObject *syspath = PySys_GetObject("path");
+ PyObject *path = PyString_FromString(GLUSTER_PYTHON_PATH);
+ PyList_Append(syspath, path);
+ Py_DECREF(path);
+
+ gf_log("python", GF_LOG_DEBUG,
+ "Loading gluster module");
+
+ priv->pGlusterModule = PyImport_ImportModule("gluster");
+ if (PyErr_Occurred())
+ {
+ PyErr_Print();
+ return -1;
+ }
+
+ priv->pFrameType = PyObject_GetAttrString(priv->pGlusterModule, "call_frame_t");
+ priv->pFdType = PyObject_GetAttrString(priv->pGlusterModule, "fd_t");
+ priv->pVectorType = PyObject_GetAttrString(priv->pGlusterModule, "iovec");
+
+ gf_log("python", GF_LOG_DEBUG, "Loading script...%s", priv->scriptname);
+
+ priv->pScriptModule = AnonModule_FromFile(priv->scriptname);
+ if (!priv->pScriptModule || PyErr_Occurred())
+ {
+ gf_log("python", GF_LOG_ERROR, "Error loading %s", priv->scriptname);
+ PyErr_Print();
+ return -1;
+ }
+
+ if (!PyObject_HasAttrString(priv->pScriptModule, "xlator"))
+ {
+ gf_log("python", GF_LOG_ERROR, "%s does not have a xlator attribute", priv->scriptname);
+ return -1;
+ }
+ gf_log("python", GF_LOG_DEBUG, "Instantiating translator");
+ priv->pXlator = PyObject_CallMethod(priv->pScriptModule, "xlator", "O&",
+ PyLong_FromVoidPtr, this);
+ if (PyErr_Occurred() || !priv->pXlator)
+ {
+ PyErr_Print();
+ return -1;
+ }
+
+ this->private = priv;
+
+ gf_log ("python", GF_LOG_DEBUG, "python xlator loaded");
+ return 0;
+}
+
+void
+fini (xlator_t *this)
+{
+ python_private_t *priv = (python_private_t*)(this->private);
+ Py_DECREF(priv->pXlator);
+ Py_DECREF(priv->pScriptModule);
+ Py_DECREF(priv->pGlusterModule);
+ Py_DECREF(priv->pFrameType);
+ Py_DECREF(priv->pFdType);
+ Py_DECREF(priv->pVectorType);
+ Py_EndInterpreter(priv->pInterp);
+ return;
+}
diff --git a/xlators/bindings/python/src/testxlator.py b/xlators/bindings/python/src/testxlator.py
new file mode 100644
index 00000000000..507455c856a
--- /dev/null
+++ b/xlators/bindings/python/src/testxlator.py
@@ -0,0 +1,56 @@
+# Copyright (c) 2007 Chris AtLee <chris@atlee.ca>
+# 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/>.
+
+"""
+This is a test translator written in python.
+
+Important things to note:
+ This file must be import-able from glusterfsd. This probably means
+ setting PYTHONPATH to where this file is located.
+
+ This file must have a top-level xlator class object that will be
+ used to instantiate individual translators.
+"""
+from gluster import *
+
+class MyXlator(ComplexTranslator):
+ name = "MyXlator"
+ def writev_cbk(self, frame, cookie, op_ret, op_errno, buf):
+ stack_unwind(frame, op_ret, op_errno, buf)
+ return 0
+
+ def writev(self, frame, fd, vector, count, offset):
+ gf_log(self.name, GF_LOG_WARNING, "writev %i bytes", vector.iov_len)
+ # TODO: Use cookie to pass this to writev_cbk
+ old_count = vector.iov_len
+
+ data = vector.getBytes().encode("zlib")
+
+ vector = iovec(data)
+ gf_log(self.name, GF_LOG_WARNING, "writev %i bytes", vector.iov_len)
+
+ @ret_fn_t
+ def rfn(frame, prev, this, op_ret, op_errno, *params):
+ if len(params) == 0:
+ params = [0]
+ return self.writev_cbk(frame, prev, old_count, op_errno, *params)
+
+ stack_wind(frame, rfn, self.firstChild,
+ self.firstChild[0].fops[0].writev, fd, vector, count, offset)
+ return 0
+
+xlator = MyXlator
diff --git a/xlators/cluster/Makefile.am b/xlators/cluster/Makefile.am
index 0662b11acfe..a6ddb3564a9 100644
--- a/xlators/cluster/Makefile.am
+++ b/xlators/cluster/Makefile.am
@@ -1,3 +1,3 @@
-SUBDIRS = stripe afr dht @EC_XLATOR_SUBDIR@
+SUBDIRS = unify stripe afr dht ha map
CLEANFILES =
diff --git a/xlators/cluster/afr/src/Makefile.am b/xlators/cluster/afr/src/Makefile.am
index ac66bf3bb11..1a8ddadb798 100644
--- a/xlators/cluster/afr/src/Makefile.am
+++ b/xlators/cluster/afr/src/Makefile.am
@@ -1,38 +1,20 @@
-xlator_LTLIBRARIES = afr.la pump.la
+xlator_LTLIBRARIES = afr.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-lk-common.c \
- afr-read-txn.c \
- $(top_builddir)/xlators/lib/src/libxlator.c
+afr_la_LDFLAGS = -module -avoidversion
-AFR_SELFHEAL_SOURCES = afr-self-heal-common.c afr-self-heal-data.c \
- afr-self-heal-entry.c afr-self-heal-metadata.c afr-self-heald.c \
- afr-self-heal-name.c
-
-afr_la_LDFLAGS = -module -avoid-version
-afr_la_SOURCES = $(afr_common_source) $(AFR_SELFHEAL_SOURCES) afr.c
+afr_la_SOURCES = afr.c 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_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la
-pump_la_LDFLAGS = -module -avoid-version
-pump_la_SOURCES = $(afr_common_source) $(AFR_SELFHEAL_SOURCES) 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-mem-types.h \
- afr-common.c afr-self-heald.h pump.h \
- $(top_builddir)/xlators/lib/src/libxlator.h afr-messages.h
-
-AM_CPPFLAGS = $(GF_CPPFLAGS) \
- -I$(top_srcdir)/libglusterfs/src -I$(top_srcdir)/xlators/lib/src \
- -I$(top_srcdir)/rpc/rpc-lib/src
+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
-AM_CFLAGS = -Wall $(GF_CFLAGS)
+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 =
+CLEANFILES =
uninstall-local:
rm -f $(DESTDIR)$(xlatordir)/replicate.so
install-data-hook:
- ln -sf afr.so $(DESTDIR)$(xlatordir)/replicate.so
+ ln -sf afr.so $(DESTDIR)$(xlatordir)/replicate.so \ No newline at end of file
diff --git a/xlators/cluster/afr/src/afr-common.c b/xlators/cluster/afr/src/afr-common.c
deleted file mode 100644
index 5de6b52b274..00000000000
--- a/xlators/cluster/afr/src/afr-common.c
+++ /dev/null
@@ -1,4493 +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 <libgen.h>
-#include <unistd.h>
-#include <fnmatch.h>
-#include <sys/time.h>
-#include <stdlib.h>
-#include <signal.h>
-
-#ifndef _CONFIG_H
-#define _CONFIG_H
-#include "config.h"
-#endif
-
-#include "glusterfs.h"
-#include "afr.h"
-#include "dict.h"
-#include "xlator.h"
-#include "hashfn.h"
-#include "logging.h"
-#include "stack.h"
-#include "list.h"
-#include "call-stub.h"
-#include "defaults.h"
-#include "common-utils.h"
-#include "compat-errno.h"
-#include "compat.h"
-#include "byte-order.h"
-#include "statedump.h"
-#include "inode.h"
-
-#include "fd.h"
-
-#include "afr-inode-read.h"
-#include "afr-inode-write.h"
-#include "afr-dir-read.h"
-#include "afr-dir-write.h"
-#include "afr-transaction.h"
-#include "afr-self-heal.h"
-#include "afr-self-heald.h"
-#include "afr-messages.h"
-
-call_frame_t *
-afr_copy_frame (call_frame_t *base)
-{
- afr_local_t *local = NULL;
- call_frame_t *frame = NULL;
- int op_errno = 0;
-
- frame = copy_frame (base);
- if (!frame)
- return NULL;
- local = AFR_FRAME_INIT (frame, op_errno);
- if (!local) {
- AFR_STACK_DESTROY (frame);
- return NULL;
- }
-
- return frame;
-}
-
-/*
- * INODE CTX 64-bit VALUE FORMAT FOR SMALL (<= 16) SUBVOL COUNTS:
- *
- * |<---------- 64bit ------------>|
- * 63 32 31 16 15 0
- * | EVENT_GEN | DATA | METADATA |
- *
- *
- * METADATA (bit-0 .. bit-15): bitmap representing subvolumes from which
- * metadata can be attempted to be read.
- *
- * bit-0 => priv->subvolumes[0]
- * bit-1 => priv->subvolumes[1]
- * ... etc. till bit-15
- *
- * DATA (bit-16 .. bit-31): bitmap representing subvolumes from which data
- * can be attempted to be read.
- *
- * bit-16 => priv->subvolumes[0]
- * bit-17 => priv->subvolumes[1]
- * ... etc. till bit-31
- *
- * EVENT_GEN (bit-32 .. bit-63): event generation (i.e priv->event_generation)
- * when DATA and METADATA was last updated.
- *
- * If EVENT_GEN is < priv->event_generation,
- * or is 0, it means afr_inode_refresh() needs
- * to be called to recalculate the bitmaps.
- */
-
-int
-__afr_inode_read_subvol_get_small (inode_t *inode, xlator_t *this,
- unsigned char *data, unsigned char *metadata,
- int *event_p)
-{
- afr_private_t *priv = NULL;
- int ret = -1;
- uint16_t datamap = 0;
- uint16_t metadatamap = 0;
- uint32_t event = 0;
- uint64_t val = 0;
- int i = 0;
-
- priv = this->private;
-
- ret = __inode_ctx_get (inode, this, &val);
- if (ret < 0)
- return ret;
-
- metadatamap = (val & 0x000000000000ffff);
- datamap = (val & 0x00000000ffff0000) >> 16;
- event = (val & 0xffffffff00000000) >> 32;
-
- for (i = 0; i < priv->child_count; i++) {
- if (metadata)
- metadata[i] = (metadatamap >> i) & 1;
- if (data)
- data[i] = (datamap >> i) & 1;
- }
-
- if (event_p)
- *event_p = event;
- return ret;
-}
-
-
-int
-__afr_inode_read_subvol_set_small (inode_t *inode, xlator_t *this,
- unsigned char *data, unsigned char *metadata,
- int event)
-{
- afr_private_t *priv = NULL;
- uint16_t datamap = 0;
- uint16_t metadatamap = 0;
- uint64_t val = 0;
- int i = 0;
-
- priv = this->private;
-
- for (i = 0; i < priv->child_count; i++) {
- if (data[i])
- datamap |= (1 << i);
- if (metadata[i])
- metadatamap |= (1 << i);
- }
-
- val = ((uint64_t) metadatamap) |
- (((uint64_t) datamap) << 16) |
- (((uint64_t) event) << 32);
-
- return __inode_ctx_set (inode, this, &val);
-}
-
-
-int
-__afr_inode_read_subvol_reset_small (inode_t *inode, xlator_t *this)
-{
- int ret = -1;
- uint16_t datamap = 0;
- uint16_t metadatamap = 0;
- uint32_t event = 0;
- uint64_t val = 0;
-
- ret = __inode_ctx_get (inode, this, &val);
- (void) ret;
-
- metadatamap = (val & 0x000000000000ffff) >> 0;
- datamap = (val & 0x00000000ffff0000) >> 16;
- event = 0;
-
- val = ((uint64_t) metadatamap) |
- (((uint64_t) datamap) << 16) |
- (((uint64_t) event) << 32);
-
- return __inode_ctx_set (inode, this, &val);
-}
-
-
-int
-__afr_inode_read_subvol_get (inode_t *inode, xlator_t *this,
- unsigned char *data, unsigned char *metadata,
- int *event_p)
-{
- afr_private_t *priv = NULL;
- int ret = -1;
-
- priv = this->private;
-
- if (priv->child_count <= 16)
- ret = __afr_inode_read_subvol_get_small (inode, this, data,
- metadata, event_p);
- else
- /* TBD: allocate structure with array and read from it */
- ret = -1;
-
- return ret;
-}
-
-
-int
-__afr_inode_read_subvol_set (inode_t *inode, xlator_t *this, unsigned char *data,
- unsigned char *metadata, int event)
-{
- afr_private_t *priv = NULL;
- int ret = -1;
-
- priv = this->private;
-
- if (priv->child_count <= 16)
- ret = __afr_inode_read_subvol_set_small (inode, this, data,
- metadata, event);
- else
- ret = -1;
-
- return ret;
-}
-
-
-int
-__afr_inode_read_subvol_reset (inode_t *inode, xlator_t *this)
-{
- afr_private_t *priv = NULL;
- int ret = -1;
-
- priv = this->private;
-
- if (priv->child_count <= 16)
- ret = __afr_inode_read_subvol_reset_small (inode, this);
- else
- ret = -1;
-
- return ret;
-}
-
-
-int
-afr_inode_read_subvol_get (inode_t *inode, xlator_t *this, unsigned char *data,
- unsigned char *metadata, int *event_p)
-{
- int ret = -1;
-
- LOCK(&inode->lock);
- {
- ret = __afr_inode_read_subvol_get (inode, this, data,
- metadata, event_p);
- }
- UNLOCK(&inode->lock);
-
- return ret;
-}
-
-
-int
-afr_inode_read_subvol_set (inode_t *inode, xlator_t *this, unsigned char *data,
- unsigned char *metadata, int event)
-{
- int ret = -1;
-
- LOCK(&inode->lock);
- {
- ret = __afr_inode_read_subvol_set (inode, this, data, metadata,
- event);
- }
- UNLOCK(&inode->lock);
-
- return ret;
-}
-
-
-int
-afr_inode_read_subvol_reset (inode_t *inode, xlator_t *this)
-{
- int ret = -1;
-
- LOCK(&inode->lock);
- {
- ret = __afr_inode_read_subvol_reset (inode, this);
- }
- UNLOCK(&inode->lock);
-
- return ret;
-}
-
-
-int
-afr_accused_fill (xlator_t *this, dict_t *xdata, unsigned char *accused,
- afr_transaction_type type)
-{
- afr_private_t *priv = NULL;
- int i = 0;
- int idx = afr_index_for_transaction_type (type);
- void *pending_raw = NULL;
- int pending[3];
- int ret = 0;
-
- priv = this->private;
-
- for (i = 0; i < priv->child_count; i++) {
- ret = dict_get_ptr (xdata, priv->pending_key[i],
- &pending_raw);
- if (ret) /* no pending flags */
- continue;
- memcpy (pending, pending_raw, sizeof(pending));
-
- if (ntoh32 (pending[idx]))
- accused[i] = 1;
- }
-
- return 0;
-}
-
-
-int
-afr_accuse_smallfiles (xlator_t *this, struct afr_reply *replies,
- unsigned char *data_accused)
-{
- int i = 0;
- afr_private_t *priv = NULL;
- uint64_t maxsize = 0;
-
- priv = this->private;
-
- for (i = 0; i < priv->child_count; i++) {
- if (data_accused[i])
- continue;
- if (replies[i].poststat.ia_size > maxsize)
- maxsize = replies[i].poststat.ia_size;
- }
-
- for (i = 0; i < priv->child_count; i++) {
- if (data_accused[i])
- continue;
- if (replies[i].poststat.ia_size < maxsize)
- data_accused[i] = 1;
- }
-
- return 0;
-}
-
-
-int
-afr_replies_interpret (call_frame_t *frame, xlator_t *this, inode_t *inode)
-{
- afr_local_t *local = NULL;
- afr_private_t *priv = NULL;
- struct afr_reply *replies = NULL;
- int event_generation = 0;
- int i = 0;
- unsigned char *data_accused = NULL;
- unsigned char *metadata_accused = NULL;
- unsigned char *data_readable = NULL;
- unsigned char *metadata_readable = NULL;
- int ret = 0;
-
- local = frame->local;
- priv = this->private;
- replies = local->replies;
- event_generation = local->event_generation;
-
- data_accused = alloca0 (priv->child_count);
- data_readable = alloca0 (priv->child_count);
- metadata_accused = alloca0 (priv->child_count);
- metadata_readable = alloca0 (priv->child_count);
-
- for (i = 0; i < priv->child_count; i++) {
- data_readable[i] = 1;
- metadata_readable[i] = 1;
- }
-
- for (i = 0; i < priv->child_count; i++) {
- if (!replies[i].valid) {
- data_readable[i] = 0;
- metadata_readable[i] = 0;
- continue;
- }
-
- if (replies[i].op_ret == -1) {
- data_readable[i] = 0;
- metadata_readable[i] = 0;
- continue;
- }
-
- afr_accused_fill (this, replies[i].xdata, data_accused,
- (replies[i].poststat.ia_type == IA_IFDIR) ?
- AFR_ENTRY_TRANSACTION : AFR_DATA_TRANSACTION);
-
- afr_accused_fill (this, replies[i].xdata,
- metadata_accused, AFR_METADATA_TRANSACTION);
-
- }
-
- if (inode->ia_type != IA_IFDIR)
- afr_accuse_smallfiles (this, replies, data_accused);
-
- for (i = 0; i < priv->child_count; i++) {
- if (data_accused[i]) {
- data_readable[i] = 0;
- ret = 1;
- }
- if (metadata_accused[i]) {
- metadata_readable[i] = 0;
- ret = 1;
- }
- }
-
- afr_inode_read_subvol_set (inode, this, data_readable,
- metadata_readable, event_generation);
- return ret;
-}
-
-
-
-int
-afr_refresh_selfheal_done (int ret, call_frame_t *heal, void *opaque)
-{
- if (heal)
- STACK_DESTROY (heal->root);
- return 0;
-}
-
-int
-afr_inode_refresh_err (call_frame_t *frame, xlator_t *this)
-{
- afr_local_t *local = NULL;
- afr_private_t *priv = NULL;
- int i = 0;
- int err = 0;
-
- local = frame->local;
- priv = this->private;
-
- for (i = 0; i < priv->child_count; i++) {
- if (local->replies[i].valid && !local->replies[i].op_ret) {
- err = 0;
- goto ret;
- }
- }
-
- err = afr_final_errno (local, priv);
-ret:
- return -err;
-}
-
-
-int
-afr_refresh_selfheal_wrap (void *opaque)
-{
- call_frame_t *frame = opaque;
- afr_local_t *local = NULL;
- xlator_t *this = NULL;
- int err = 0;
-
- local = frame->local;
- this = frame->this;
-
- afr_selfheal (frame->this, local->refreshinode->gfid);
-
- afr_selfheal_unlocked_discover (frame, local->refreshinode,
- local->refreshinode->gfid,
- local->replies);
-
- afr_replies_interpret (frame, this, local->refreshinode);
-
- err = afr_inode_refresh_err (frame, this);
-
- afr_local_replies_wipe (local, this->private);
-
- local->refreshfn (frame, this, err);
-
- return 0;
-}
-
-
-gf_boolean_t
-afr_selfheal_enabled (xlator_t *this)
-{
- afr_private_t *priv = NULL;
- gf_boolean_t data = _gf_false;
-
- priv = this->private;
-
- gf_string2boolean (priv->data_self_heal, &data);
-
- return data || priv->metadata_self_heal || priv->entry_self_heal;
-}
-
-
-int
-afr_inode_refresh_done (call_frame_t *frame, xlator_t *this)
-{
- call_frame_t *heal = NULL;
- afr_local_t *local = NULL;
- int ret = 0;
- int err = 0;
-
- local = frame->local;
-
- ret = afr_replies_interpret (frame, this, local->refreshinode);
-
- err = afr_inode_refresh_err (frame, this);
-
- afr_local_replies_wipe (local, this->private);
-
- if (ret && afr_selfheal_enabled (this)) {
- heal = copy_frame (frame);
- if (heal)
- heal->root->pid = GF_CLIENT_PID_AFR_SELF_HEALD;
- ret = synctask_new (this->ctx->env, afr_refresh_selfheal_wrap,
- afr_refresh_selfheal_done, heal, frame);
- if (ret)
- goto refresh_done;
- } else {
- refresh_done:
- local->refreshfn (frame, this, err);
- }
-
- return 0;
-}
-
-
-int
-afr_inode_refresh_subvol_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 *par)
-{
- afr_local_t *local = NULL;
- int call_child = (long) cookie;
- int call_count = 0;
-
- local = frame->local;
-
- local->replies[call_child].valid = 1;
- local->replies[call_child].op_ret = op_ret;
- local->replies[call_child].op_errno = op_errno;
- if (op_ret != -1) {
- local->replies[call_child].poststat = *buf;
- local->replies[call_child].postparent = *par;
- local->replies[call_child].xdata = dict_ref (xdata);
- }
-
- call_count = afr_frame_return (frame);
-
- if (call_count == 0)
- afr_inode_refresh_done (frame, this);
-
- return 0;
-}
-
-
-int
-afr_inode_refresh_subvol (call_frame_t *frame, xlator_t *this, int i,
- inode_t *inode, dict_t *xdata)
-{
- loc_t loc = {0, };
- afr_private_t *priv = NULL;
-
- priv = this->private;
-
- loc.inode = inode;
- uuid_copy (loc.gfid, inode->gfid);
-
- STACK_WIND_COOKIE (frame, afr_inode_refresh_subvol_cbk,
- (void *) (long) i, priv->children[i],
- priv->children[i]->fops->lookup, &loc, xdata);
- return 0;
-}
-
-
-int
-afr_inode_refresh_do (call_frame_t *frame, xlator_t *this)
-{
- afr_local_t *local = NULL;
- afr_private_t *priv = NULL;
- int call_count = 0;
- int i = 0;
- dict_t *xdata = NULL;
-
- priv = this->private;
- local = frame->local;
-
- afr_local_replies_wipe (local, priv);
-
- xdata = dict_new ();
- if (!xdata) {
- afr_inode_refresh_done (frame, this);
- return 0;
- }
-
- if (afr_xattr_req_prepare (this, xdata) != 0) {
- dict_unref (xdata);
- afr_inode_refresh_done (frame, this);
- return 0;
- }
-
- local->call_count = AFR_COUNT (local->child_up, priv->child_count);
-
- call_count = local->call_count;
- for (i = 0; i < priv->child_count; i++) {
- if (!local->child_up[i])
- continue;
-
- afr_inode_refresh_subvol (frame, this, i, local->refreshinode,
- xdata);
-
- if (!--call_count)
- break;
- }
-
- dict_unref (xdata);
-
- return 0;
-}
-
-
-int
-afr_inode_refresh (call_frame_t *frame, xlator_t *this, inode_t *inode,
- afr_inode_refresh_cbk_t refreshfn)
-{
- afr_local_t *local = NULL;
-
- local = frame->local;
-
- local->refreshfn = refreshfn;
-
- if (local->refreshinode) {
- inode_unref (local->refreshinode);
- local->refreshinode = NULL;
- }
-
- local->refreshinode = inode_ref (inode);
-
- afr_inode_refresh_do (frame, this);
-
- return 0;
-}
-
-
-int
-afr_xattr_req_prepare (xlator_t *this, dict_t *xattr_req)
-{
- 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],
- AFR_NUM_CHANGE_LOGS * sizeof(int));
- if (ret < 0)
- gf_log (this->name, GF_LOG_WARNING,
- "Unable to set dict value for %s",
- priv->pending_key[i]);
- /* 3 = data+metadata+entry */
- }
- ret = dict_set_uint64 (xattr_req, AFR_DIRTY,
- AFR_NUM_CHANGE_LOGS * sizeof(int));
- if (ret) {
- gf_log (this->name, GF_LOG_DEBUG, "failed to set dirty "
- "query flag");
- }
-
- ret = dict_set_int32 (xattr_req, "list-xattr", 1);
- if (ret) {
- gf_log (this->name, GF_LOG_DEBUG,
- "Unable to set list-xattr in dict ");
- }
-
- return ret;
-}
-
-int
-afr_lookup_xattr_req_prepare (afr_local_t *local, xlator_t *this,
- dict_t *xattr_req, loc_t *loc)
-{
- int ret = -ENOMEM;
-
- if (!local->xattr_req)
- local->xattr_req = dict_new ();
-
- if (!local->xattr_req)
- goto out;
-
- if (xattr_req != local->xattr_req)
- dict_copy (xattr_req, local->xattr_req);
-
- ret = afr_xattr_req_prepare (this, local->xattr_req);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_WARNING,
- "%s: Unable to prepare 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 = 0;
-out:
- return ret;
-}
-
-
-int
-afr_hash_child (afr_read_subvol_args_t *args, int32_t child_count, int hashmode)
-{
- uuid_t gfid_copy = {0,};
- pid_t pid;
-
- if (!hashmode) {
- return -1;
- }
-
- uuid_copy (gfid_copy, args->gfid);
-
- if ((hashmode > 1) && (args->ia_type != IA_IFDIR)) {
- /*
- * 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 = getpid();
- memcpy (gfid_copy, &pid, sizeof(pid));
- }
-
- return SuperFastHash((char *)gfid_copy,
- sizeof(gfid_copy)) % child_count;
-}
-
-
-int
-afr_read_subvol_select_by_policy (inode_t *inode, xlator_t *this,
- unsigned char *readable,
- afr_read_subvol_args_t *args)
-{
- int i = 0;
- int read_subvol = -1;
- afr_private_t *priv = NULL;
- afr_read_subvol_args_t local_args = {0,};
-
- priv = this->private;
-
- /* first preference - explicitly specified or local subvolume */
- if (priv->read_child >= 0 && readable[priv->read_child])
- return priv->read_child;
-
- if (inode_is_linked (inode)) {
- uuid_copy (local_args.gfid, inode->gfid);
- local_args.ia_type = inode->ia_type;
- } else if (args) {
- local_args = *args;
- }
-
- /* second preference - use hashed mode */
- read_subvol = afr_hash_child (&local_args, priv->child_count,
- priv->hash_mode);
- if (read_subvol >= 0 && readable[read_subvol])
- return read_subvol;
-
- for (i = 0; i < priv->child_count; i++) {
- if (readable[i])
- return i;
- }
-
- /* no readable subvolumes, either split brain or all subvols down */
-
- return -1;
-}
-
-
-int
-afr_inode_read_subvol_type_get (inode_t *inode, xlator_t *this,
- unsigned char *readable, int *event_p,
- int type)
-{
- int ret = -1;
-
- if (type == AFR_METADATA_TRANSACTION)
- ret = afr_inode_read_subvol_get (inode, this, 0, readable,
- event_p);
- else
- ret = afr_inode_read_subvol_get (inode, this, readable, 0,
- event_p);
- return ret;
-}
-
-
-int
-afr_read_subvol_get (inode_t *inode, xlator_t *this, int *subvol_p,
- int *event_p, afr_transaction_type type,
- afr_read_subvol_args_t *args)
-{
- afr_private_t *priv = NULL;
- unsigned char *data_readable = NULL;
- unsigned char *metadata_readable = NULL;
- unsigned char *readable = NULL;
- unsigned char *intersection = NULL;
- int subvol = -1;
- int event = 0;
-
- priv = this->private;
-
- readable = alloca0 (priv->child_count);
- data_readable = alloca0 (priv->child_count);
- metadata_readable = alloca0 (priv->child_count);
- intersection = alloca0 (priv->child_count);
-
- afr_inode_read_subvol_type_get (inode, this, readable, &event, type);
-
- afr_inode_read_subvol_get (inode, this, data_readable, metadata_readable,
- &event);
-
- AFR_INTERSECT (intersection, data_readable, metadata_readable,
- priv->child_count);
-
- if (AFR_COUNT (intersection, priv->child_count) > 0)
- subvol = afr_read_subvol_select_by_policy (inode, this,
- intersection, args);
- else
- subvol = afr_read_subvol_select_by_policy (inode, this,
- readable, args);
- if (subvol_p)
- *subvol_p = subvol;
- if (event_p)
- *event_p = event;
- return subvol;
-}
-
-
-void
-afr_local_transaction_cleanup (afr_local_t *local, xlator_t *this)
-{
- afr_private_t *priv = NULL;
- int i = 0;
-
- priv = this->private;
-
- afr_matrix_cleanup (local->pending, priv->child_count);
-
- GF_FREE (local->internal_lock.locked_nodes);
-
- for (i = 0; local->internal_lock.inodelk[i].domain; i++) {
- GF_FREE (local->internal_lock.inodelk[i].locked_nodes);
- }
-
- GF_FREE (local->internal_lock.lower_locked_nodes);
-
- afr_entry_lockee_cleanup (&local->internal_lock);
-
- GF_FREE (local->transaction.pre_op);
- GF_FREE (local->transaction.eager_lock);
- GF_FREE (local->transaction.fop_subvols);
- GF_FREE (local->transaction.failed_subvols);
-
- GF_FREE (local->transaction.basename);
- GF_FREE (local->transaction.new_basename);
-
- loc_wipe (&local->transaction.parent_loc);
- loc_wipe (&local->transaction.new_parent_loc);
-
-}
-
-
-void
-afr_replies_wipe (struct afr_reply *replies, int count)
-{
- int i = 0;
-
- for (i = 0; i < count; i++) {
- if (replies[i].xdata) {
- dict_unref (replies[i].xdata);
- replies[i].xdata = NULL;
- }
- }
-}
-
-void
-afr_local_replies_wipe (afr_local_t *local, afr_private_t *priv)
-{
-
- if (!local->replies)
- return;
-
- afr_replies_wipe (local->replies, priv->child_count);
-
- memset (local->replies, 0, sizeof(*local->replies) * priv->child_count);
-}
-
-void
-afr_remove_eager_lock_stub (afr_local_t *local)
-{
- LOCK (&local->fd->lock);
- {
- list_del_init (&local->transaction.eager_locked);
- }
- UNLOCK (&local->fd->lock);
-}
-
-void
-afr_local_cleanup (afr_local_t *local, xlator_t *this)
-{
- afr_private_t * priv = NULL;
-
- if (!local)
- return;
-
- syncbarrier_destroy (&local->barrier);
-
- if (local->transaction.eager_lock_on &&
- !list_empty (&local->transaction.eager_locked))
- afr_remove_eager_lock_stub (local);
-
- afr_local_transaction_cleanup (local, this);
-
- priv = this->private;
-
- loc_wipe (&local->loc);
- loc_wipe (&local->newloc);
-
- if (local->fd)
- fd_unref (local->fd);
-
- if (local->xattr_req)
- dict_unref (local->xattr_req);
-
- if (local->dict)
- dict_unref (local->dict);
-
- afr_local_replies_wipe (local, priv);
- GF_FREE(local->replies);
-
- GF_FREE (local->child_up);
-
- GF_FREE (local->read_attempted);
-
- GF_FREE (local->readable);
-
- if (local->inode)
- inode_unref (local->inode);
-
- if (local->parent)
- inode_unref (local->parent);
-
- if (local->parent2)
- inode_unref (local->parent2);
-
- if (local->refreshinode)
- inode_unref (local->refreshinode);
-
- { /* getxattr */
- GF_FREE (local->cont.getxattr.name);
- }
-
- { /* lk */
- GF_FREE (local->cont.lk.locked_nodes);
- }
-
- { /* create */
- if (local->cont.create.fd)
- fd_unref (local->cont.create.fd);
- if (local->cont.create.params)
- dict_unref (local->cont.create.params);
- }
-
- { /* mknod */
- if (local->cont.mknod.params)
- dict_unref (local->cont.mknod.params);
- }
-
- { /* mkdir */
- if (local->cont.mkdir.params)
- dict_unref (local->cont.mkdir.params);
- }
-
- { /* symlink */
- if (local->cont.symlink.params)
- dict_unref (local->cont.symlink.params);
- }
-
- { /* writev */
- GF_FREE (local->cont.writev.vector);
- if (local->cont.writev.iobref)
- iobref_unref (local->cont.writev.iobref);
- }
-
- { /* setxattr */
- if (local->cont.setxattr.dict)
- 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);
- }
-
- { /* readdirp */
- if (local->cont.readdir.dict)
- dict_unref (local->cont.readdir.dict);
- }
-
- { /* inodelk */
- GF_FREE (local->cont.inodelk.volume);
- }
-
- if (local->xdata_req)
- dict_unref (local->xdata_req);
-
- if (local->xdata_rsp)
- dict_unref (local->xdata_rsp);
-}
-
-
-int
-afr_frame_return (call_frame_t *frame)
-{
- afr_local_t *local = NULL;
- int call_count = 0;
-
- local = frame->local;
-
- LOCK (&frame->lock);
- {
- call_count = --local->call_count;
- }
- UNLOCK (&frame->lock);
-
- return call_count;
-}
-
-
-gf_boolean_t
-afr_is_entry_possibly_under_txn (afr_local_t *local, xlator_t *this)
-{
- int i = 0;
- int tmp = 0;
- afr_private_t *priv = NULL;
-
- priv = this->private;
-
- for (i = 0; i < priv->child_count; i++) {
- if (!local->replies[i].xdata)
- continue;
- if (dict_get_int32 (local->replies[i].xdata,
- GLUSTERFS_PARENT_ENTRYLK,
- &tmp) == 0)
- if (tmp)
- return _gf_true;
- }
-
- return _gf_false;
-}
-
-
-static char *afr_ignore_xattrs[] = {
- GLUSTERFS_OPEN_FD_COUNT,
- GLUSTERFS_PARENT_ENTRYLK,
- GLUSTERFS_ENTRYLK_COUNT,
- GLUSTERFS_INODELK_COUNT,
- GF_SELINUX_XATTR_KEY,
- QUOTA_SIZE_KEY,
- NULL
-};
-
-gf_boolean_t
-afr_is_xattr_ignorable (char *key)
-{
- int i = 0;
-
- if (!strncmp (key, AFR_XATTR_PREFIX, strlen(AFR_XATTR_PREFIX)))
- return _gf_true;
- for (i = 0; afr_ignore_xattrs[i]; i++) {
- if (!strcmp (key, afr_ignore_xattrs[i]))
- return _gf_true;
- }
- return _gf_false;
-}
-
-int
-xattr_is_equal (dict_t *this, char *key1, data_t *value1, void *data)
-{
- dict_t *xattr2 = (dict_t *)data;
- data_t *value2 = NULL;
-
- if (afr_is_xattr_ignorable (key1))
- return 0;
-
- value2 = dict_get (xattr2, key1);
- if (!value2)
- return -1;
-
- if (value1->len != value2->len)
- return -1;
- if(memcmp(value1->data, value2->data, value1->len))
- return -1;
- else
- return 0;
-
-}
-
-/* To conclude that both dicts are equal, we need to check if
- * 1) For every key-val pair in dict1, a match is present in dict2
- * 2) For every key-val pair in dict2, a match is present in dict1
- * We need to do both because ignoring glusterfs' internal xattrs
- * happens only in xattr_is_equal().
- */
-gf_boolean_t
-afr_xattrs_are_equal (dict_t *dict1, dict_t *dict2)
-{
- int ret = 0;
-
- ret = dict_foreach (dict1, xattr_is_equal, dict2);
- if (ret == -1)
- return _gf_false;
-
- ret = dict_foreach (dict2, xattr_is_equal, dict1);
- if (ret == -1)
- return _gf_false;
-
- return _gf_true;
-}
-
-static int
-afr_get_parent_read_subvol (xlator_t *this, inode_t *parent,
- struct afr_reply *replies, unsigned char *readable)
-{
- int i = 0;
- int par_read_subvol = -1;
- int par_read_subvol_iter = -1;
- afr_private_t *priv = NULL;
-
- priv = this->private;
-
- if (parent)
- par_read_subvol = afr_data_subvol_get (parent, this, 0, 0,
- NULL);
-
- for (i = 0; i < priv->child_count; i++) {
- if (!replies[i].valid)
- continue;
-
- if (replies[i].op_ret < 0)
- continue;
-
- if (par_read_subvol_iter == -1) {
- par_read_subvol_iter = i;
- continue;
- }
-
- if ((par_read_subvol_iter != par_read_subvol) && readable[i])
- par_read_subvol_iter = i;
-
- if (i == par_read_subvol)
- par_read_subvol_iter = i;
- }
- /* At the end of the for-loop, the only reason why @par_read_subvol_iter
- * could be -1 is when this LOOKUP has failed on all sub-volumes.
- * So it is okay to send an arbitrary subvolume (0 in this case)
- * as parent read subvol.
- */
- if (par_read_subvol_iter == -1)
- par_read_subvol_iter = 0;
-
- return par_read_subvol_iter;
-
-}
-
-static void
-afr_lookup_done (call_frame_t *frame, xlator_t *this)
-{
- afr_private_t *priv = NULL;
- afr_local_t *local = NULL;
- int i = -1;
- int op_errno = 0;
- int read_subvol = 0;
- int par_read_subvol = 0;
- unsigned char *readable = NULL;
- int event = 0;
- struct afr_reply *replies = NULL;
- uuid_t read_gfid = {0, };
- gf_boolean_t locked_entry = _gf_false;
- gf_boolean_t can_interpret = _gf_true;
- inode_t *parent = NULL;
- ia_type_t ia_type = IA_INVAL;
- afr_read_subvol_args_t args = {0,};
-
- priv = this->private;
- local = frame->local;
- replies = local->replies;
- parent = local->loc.parent;
-
- locked_entry = afr_is_entry_possibly_under_txn (local, this);
-
- readable = alloca0 (priv->child_count);
-
- afr_inode_read_subvol_get (parent, this, readable, NULL, &event);
-
- /* First, check if we have a gfid-change from somewhere,
- If so, propagate that so that a fresh lookup can be
- issued
- */
- if (local->cont.lookup.needs_fresh_lookup) {
- local->op_ret = -1;
- local->op_errno = ESTALE;
- goto unwind;
- }
-
- op_errno = afr_final_errno (frame->local, this->private);
- local->op_errno = op_errno;
-
- read_subvol = -1;
- for (i = 0; i < priv->child_count; i++) {
- if (!replies[i].valid)
- continue;
-
- if (locked_entry && replies[i].op_ret == -1 &&
- replies[i].op_errno == ENOENT) {
- /* Second, check entry is still
- "underway" in creation */
- local->op_ret = -1;
- local->op_errno = ENOENT;
- goto unwind;
- }
-
- if (replies[i].op_ret == -1)
- continue;
-
- if (read_subvol == -1 || !readable[read_subvol]) {
- read_subvol = i;
- uuid_copy (read_gfid, replies[i].poststat.ia_gfid);
- ia_type = replies[i].poststat.ia_type;
- local->op_ret = 0;
- }
- }
-
- if (read_subvol == -1)
- goto unwind;
- /* We now have a read_subvol, which is readable[] (if there
- were any). Next we look for GFID mismatches. We don't
- consider a GFID mismatch as an error if read_subvol is
- readable[] but the mismatching GFID subvol is not.
- */
- for (i = 0; i < priv->child_count; i++) {
- if (!replies[i].valid || replies[i].op_ret == -1) {
- if (priv->child_up[i])
- can_interpret = _gf_false;
- continue;
- }
-
- if (!uuid_compare (replies[i].poststat.ia_gfid, read_gfid))
- continue;
-
- can_interpret = _gf_false;
-
- if (locked_entry)
- continue;
-
- /* Now GFIDs mismatch. It's OK as long as this subvol
- is not readable[] but read_subvol is */
- if (readable[read_subvol] && !readable[i])
- continue;
-
- /* LOG ERROR */
- local->op_ret = -1;
- local->op_errno = EIO;
- goto unwind;
- }
-
- /* Forth, for the finalized GFID, pick the best subvolume
- to return stats from.
- */
- if (can_interpret) {
- /* It is safe to call afr_replies_interpret() because we have
- a response from all the UP subvolumes and all of them resolved
- to the same GFID
- */
- uuid_copy (args.gfid, read_gfid);
- args.ia_type = ia_type;
- if (afr_replies_interpret (frame, this, local->inode)) {
- read_subvol = afr_data_subvol_get (local->inode, this,
- 0, 0, &args);
- afr_inode_read_subvol_reset (local->inode, this);
- goto cant_interpret;
- } else {
- read_subvol = afr_data_subvol_get (local->inode, this,
- 0, 0, &args);
- }
- } else {
- cant_interpret:
- if (read_subvol == -1)
- dict_del (replies[0].xdata, GF_CONTENT_KEY);
- else
- dict_del (replies[read_subvol].xdata, GF_CONTENT_KEY);
- }
-
- afr_handle_quota_size (frame, this);
-
-unwind:
- if (read_subvol == -1)
- read_subvol = 0;
-
- par_read_subvol = afr_get_parent_read_subvol (this, parent, replies,
- readable);
-
- AFR_STACK_UNWIND (lookup, frame, local->op_ret, local->op_errno,
- local->inode, &local->replies[read_subvol].poststat,
- local->replies[read_subvol].xdata,
- &local->replies[par_read_subvol].postparent);
-}
-
-/*
- * During a lookup, some errors are more "important" than
- * others in that they must be given higher priority while
- * returning to the user.
- *
- * The hierarchy is ENODATA > ENOENT > ESTALE > others
- */
-
-int
-afr_higher_errno (int32_t old_errno, int32_t new_errno)
-{
- if (old_errno == ENODATA || new_errno == ENODATA)
- return ENODATA;
- if (old_errno == ENOENT || new_errno == ENOENT)
- return ENOENT;
- if (old_errno == ESTALE || new_errno == ESTALE)
- return ESTALE;
-
- return new_errno;
-}
-
-
-int
-afr_final_errno (afr_local_t *local, afr_private_t *priv)
-{
- int i = 0;
- int op_errno = 0;
- int tmp_errno = 0;
-
- for (i = 0; i < priv->child_count; i++) {
- if (!local->replies[i].valid)
- continue;
- if (local->replies[i].op_ret >= 0)
- continue;
- tmp_errno = local->replies[i].op_errno;
- op_errno = afr_higher_errno (op_errno, tmp_errno);
- }
-
- return op_errno;
-}
-
-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
-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;
-}
-
-static int32_t
-afr_local_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;
-
- if (op_ret != 0) {
- goto out;
- }
-
- priv = this->private;
- child_index = (int32_t)(long)cookie;
-
- ret = dict_get_str (dict, GF_XATTR_PATHINFO_KEY, &pathinfo);
- if (ret != 0) {
- goto out;
- }
-
- ret = afr_local_pathinfo (pathinfo, &is_local);
- if (ret) {
- goto out;
- }
-
- /*
- * 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) {
- gf_log (this->name, GF_LOG_INFO,
- "selecting local read_child %s",
- priv->children[child_index]->name);
- priv->read_child = child_index;
- }
-out:
- STACK_DESTROY(frame->root);
- return 0;
-}
-
-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;
-
- newframe = create_frame(this,this->ctx->pool);
- if (!newframe) {
- return;
- }
-
- tmploc.gfid[sizeof(tmploc.gfid)-1] = 1;
- STACK_WIND_COOKIE (newframe, afr_local_discovery_cbk,
- (void *)(long)child_index,
- priv->children[child_index],
- priv->children[child_index]->fops->getxattr,
- &tmploc, GF_XATTR_PATHINFO_KEY, NULL);
-}
-
-int
-afr_lookup_sh_metadata_wrap (void *opaque)
-{
- call_frame_t *frame = opaque;
- afr_local_t *local = NULL;
- xlator_t *this = NULL;
- inode_t *inode = NULL;
- afr_private_t *priv = NULL;
- struct afr_reply *replies = NULL;
- int i= 0, first = -1;
-
- local = frame->local;
- this = frame->this;
- priv = this->private;
- replies = local->replies;
-
- for (i =0; i < priv->child_count; i++) {
- if(!replies[i].valid || replies[i].op_ret == -1)
- continue;
- first = i;
- break;
- }
- if (first == -1)
- goto out;
-
- inode = afr_inode_link (local->inode,&replies[first].poststat);
- if(!inode)
- goto out;
-
- afr_selfheal_metadata (frame, this, inode);
- inode_forget (inode, 1);
- inode_unref (inode);
-
- afr_local_replies_wipe (local, this->private);
- inode = afr_selfheal_unlocked_lookup_on (frame, local->loc.parent,
- local->loc.name, local->replies,
- local->child_up, NULL);
- if (inode)
- inode_unref (inode);
-out:
- afr_lookup_done (frame, this);
-
- return 0;
-}
-
-static gf_boolean_t
-afr_can_start_metadata_self_heal(call_frame_t *frame, xlator_t *this)
-{
- afr_local_t *local = NULL;
- afr_private_t *priv = NULL;
- struct afr_reply *replies = NULL;
- int i = 0, first = -1;
- gf_boolean_t start = _gf_false;
- struct iatt stbuf = {0, };
-
- local = frame->local;
- replies = local->replies;
- priv = this->private;
-
- if (!priv->metadata_self_heal)
- return _gf_false;
-
- for (i = 0; i < priv->child_count; i++) {
- if(!replies[i].valid || replies[i].op_ret == -1)
- continue;
- if (first == -1) {
- first = i;
- stbuf = replies[i].poststat;
- continue;
- }
-
- if (uuid_compare (stbuf.ia_gfid, replies[i].poststat.ia_gfid)) {
- start = _gf_false;
- break;
- }
- if (!IA_EQUAL (stbuf, replies[i].poststat, type)) {
- start = _gf_false;
- break;
- }
-
- /*Check if iattrs need heal*/
- if ((!IA_EQUAL (stbuf, replies[i].poststat, uid)) ||
- (!IA_EQUAL (stbuf, replies[i].poststat, gid)) ||
- (!IA_EQUAL (stbuf, replies[i].poststat, prot))) {
- start = _gf_true;
- continue;
- }
-
- /*Check if xattrs need heal*/
- if (!afr_xattrs_are_equal (replies[first].xdata,
- replies[i].xdata))
- start = _gf_true;
- }
-
- return start;
-}
-
-int
-afr_lookup_metadata_heal_check (call_frame_t *frame, xlator_t *this)
-
-{
- call_frame_t *heal = NULL;
- int ret = 0;
-
- if (!afr_can_start_metadata_self_heal (frame, this))
- goto out;
-
- heal = copy_frame (frame);
- if (heal)
- heal->root->pid = GF_CLIENT_PID_AFR_SELF_HEALD;
- ret = synctask_new (this->ctx->env, afr_lookup_sh_metadata_wrap,
- afr_refresh_selfheal_done, heal, frame);
- if(ret)
- goto out;
- return ret;
-out:
- afr_lookup_done (frame, this);
- return ret;
-}
-
-int
-afr_lookup_selfheal_wrap (void *opaque)
-{
- int ret = 0;
- call_frame_t *frame = opaque;
- afr_local_t *local = NULL;
- xlator_t *this = NULL;
- inode_t *inode = NULL;
-
- local = frame->local;
- this = frame->this;
-
- ret = afr_selfheal_name (frame->this, local->loc.pargfid,
- local->loc.name, &local->cont.lookup.gfid_req);
- if (ret == -EIO)
- goto unwind;
-
- afr_local_replies_wipe (local, this->private);
-
- inode = afr_selfheal_unlocked_lookup_on (frame, local->loc.parent,
- local->loc.name, local->replies,
- local->child_up, NULL);
- if (inode)
- inode_unref (inode);
-
- afr_lookup_metadata_heal_check(frame, this);
- return 0;
-
-unwind:
- AFR_STACK_UNWIND (lookup, frame, -1, EIO, NULL, NULL, NULL, NULL);
- return 0;
-}
-
-
-int
-afr_lookup_entry_heal (call_frame_t *frame, xlator_t *this)
-{
- afr_local_t *local = NULL;
- afr_private_t *priv = NULL;
- call_frame_t *heal = NULL;
- int i = 0, first = -1;
- gf_boolean_t need_heal = _gf_false;
- struct afr_reply *replies = NULL;
- int ret = 0;
-
- local = frame->local;
- replies = local->replies;
- priv = this->private;
-
- for (i = 0; i < priv->child_count; i++) {
- if (!replies[i].valid)
- continue;
-
- if ((replies[i].op_ret == -1) &&
- (replies[i].op_errno == ENODATA))
- need_heal = _gf_true;
-
- if (first == -1) {
- first = i;
- continue;
- }
-
- if (replies[i].op_ret != replies[first].op_ret) {
- need_heal = _gf_true;
- break;
- }
-
- if (uuid_compare (replies[i].poststat.ia_gfid,
- replies[first].poststat.ia_gfid)) {
- need_heal = _gf_true;
- break;
- }
- }
-
- if (need_heal) {
- heal = copy_frame (frame);
- if (heal)
- heal->root->pid = GF_CLIENT_PID_AFR_SELF_HEALD;
- ret = synctask_new (this->ctx->env, afr_lookup_selfheal_wrap,
- afr_refresh_selfheal_done, heal, frame);
- if (ret)
- goto metadata_heal;
- return ret;
- }
-metadata_heal:
- ret = afr_lookup_metadata_heal_check (frame, this);
-
- return ret;
-}
-
-
-int
-afr_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, struct iatt *postparent)
-{
- afr_local_t * local = NULL;
- int call_count = -1;
- int child_index = -1;
-
- child_index = (long) cookie;
-
- local = frame->local;
-
- local->replies[child_index].valid = 1;
- local->replies[child_index].op_ret = op_ret;
- local->replies[child_index].op_errno = op_errno;
- /*
- * On revalidate lookup if the gfid-changed, afr should unwind the fop
- * with ESTALE so that a fresh lookup will be sent by the top xlator.
- * So remember it.
- */
- if (xdata && dict_get (xdata, "gfid-changed"))
- local->cont.lookup.needs_fresh_lookup = _gf_true;
-
- if (op_ret != -1) {
- local->replies[child_index].poststat = *buf;
- local->replies[child_index].postparent = *postparent;
- if (xdata)
- local->replies[child_index].xdata = dict_ref (xdata);
- }
-
- call_count = afr_frame_return (frame);
- if (call_count == 0) {
- afr_lookup_entry_heal (frame, this);
- }
-
- return 0;
-}
-
-
-
-static void
-afr_discover_done (call_frame_t *frame, xlator_t *this)
-{
- afr_private_t *priv = NULL;
- afr_local_t *local = NULL;
- int i = -1;
- int op_errno = 0;
- int read_subvol = 0;
-
- priv = this->private;
- local = frame->local;
-
- for (i = 0; i < priv->child_count; i++) {
- if (!local->replies[i].valid)
- continue;
- if (local->replies[i].op_ret == 0)
- local->op_ret = 0;
- }
-
- op_errno = afr_final_errno (frame->local, this->private);
-
- if (local->op_ret < 0) {
- local->op_errno = op_errno;
- local->op_ret = -1;
- goto unwind;
- }
-
- afr_replies_interpret (frame, this, local->inode);
-
- read_subvol = afr_data_subvol_get (local->inode, this, 0, 0, NULL);
- if (read_subvol == -1) {
- gf_log (this->name, GF_LOG_WARNING, "no read subvols for %s",
- local->loc.path);
-
- for (i = 0; i < priv->child_count; i++) {
- if (!local->replies[i].valid ||
- local->replies[i].op_ret == -1)
- continue;
- read_subvol = i;
- break;
- }
- }
-
-unwind:
- if (read_subvol == -1)
- read_subvol = 0;
-
- AFR_STACK_UNWIND (lookup, frame, local->op_ret, local->op_errno,
- local->inode, &local->replies[read_subvol].poststat,
- local->replies[read_subvol].xdata,
- &local->replies[read_subvol].postparent);
-}
-
-
-int
-afr_discover_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)
-{
- afr_local_t * local = NULL;
- int call_count = -1;
- int child_index = -1;
-
- child_index = (long) cookie;
-
- local = frame->local;
-
- local->replies[child_index].valid = 1;
- local->replies[child_index].op_ret = op_ret;
- local->replies[child_index].op_errno = op_errno;
- if (op_ret != -1) {
- local->replies[child_index].poststat = *buf;
- local->replies[child_index].postparent = *postparent;
- if (xdata)
- local->replies[child_index].xdata = dict_ref (xdata);
- }
-
- if (local->do_discovery && (op_ret == 0))
- afr_attempt_local_discovery (this, child_index);
-
- call_count = afr_frame_return (frame);
- if (call_count == 0) {
- afr_discover_done (frame, this);
- }
-
- return 0;
-}
-
-
-int
-afr_discover_do (call_frame_t *frame, xlator_t *this, int err)
-{
- int ret = 0;
- int i = 0;
- afr_local_t *local = NULL;
- afr_private_t *priv = NULL;
- int call_count = 0;
-
- local = frame->local;
- priv = this->private;
-
- if (err) {
- local->op_errno = -err;
- ret = -1;
- goto out;
- }
-
- call_count = local->call_count = AFR_COUNT (local->child_up,
- priv->child_count);
-
- ret = afr_lookup_xattr_req_prepare (local, this, local->xattr_req,
- &local->loc);
- if (ret) {
- local->op_errno = -ret;
- ret = -1;
- goto out;
- }
-
- for (i = 0; i < priv->child_count; i++) {
- if (local->child_up[i]) {
- STACK_WIND_COOKIE (frame, afr_discover_cbk,
- (void *) (long) i,
- priv->children[i],
- priv->children[i]->fops->lookup,
- &local->loc, local->xattr_req);
- if (!--call_count)
- break;
- }
- }
-
- return 0;
-out:
- AFR_STACK_UNWIND (lookup, frame, -1, local->op_errno, 0, 0, 0, 0);
- return 0;
-}
-
-
-int
-afr_discover (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xattr_req)
-{
- int op_errno = ENOMEM;
- afr_private_t *priv = NULL;
- afr_local_t *local = NULL;
- int event = 0;
-
- priv = this->private;
-
- local = AFR_FRAME_INIT (frame, op_errno);
- if (!local)
- goto out;
-
- if (!local->call_count) {
- op_errno = ENOTCONN;
- goto out;
- }
-
- if (__is_root_gfid (loc->inode->gfid)) {
- if (!this->itable)
- this->itable = loc->inode->table;
- if (!priv->root_inode)
- priv->root_inode = inode_ref (loc->inode);
-
- if (priv->choose_local && !priv->did_discovery) {
- /* Logic to detect which subvolumes of AFR are
- local, in order to prefer them for reads
- */
- local->do_discovery = _gf_true;
- priv->did_discovery = _gf_true;
- }
- }
-
- local->op = GF_FOP_LOOKUP;
-
- loc_copy (&local->loc, loc);
-
- local->inode = inode_ref (loc->inode);
-
- if (xattr_req)
- /* If xattr_req was null, afr_lookup_xattr_req_prepare() will
- allocate one for us */
- local->xattr_req = dict_ref (xattr_req);
-
- if (uuid_is_null (loc->inode->gfid)) {
- afr_discover_do (frame, this, 0);
- return 0;
- }
-
- afr_read_subvol_get (loc->inode, this, NULL, &event,
- AFR_DATA_TRANSACTION, NULL);
-
- if (event != local->event_generation)
- afr_inode_refresh (frame, this, loc->inode, afr_discover_do);
- else
- afr_discover_do (frame, this, 0);
-
- return 0;
-out:
- AFR_STACK_UNWIND (lookup, frame, -1, op_errno, NULL, NULL, NULL, NULL);
- return 0;
-}
-
-
-int
-afr_lookup_do (call_frame_t *frame, xlator_t *this, int err)
-{
- int ret = 0;
- int i = 0;
- afr_local_t *local = NULL;
- afr_private_t *priv = NULL;
- int call_count = 0;
-
- local = frame->local;
- priv = this->private;
-
- if (err < 0) {
- local->op_errno = -err;
- ret = -1;
- goto out;
- }
-
- call_count = local->call_count = AFR_COUNT (local->child_up,
- priv->child_count);
-
- ret = afr_lookup_xattr_req_prepare (local, this, local->xattr_req,
- &local->loc);
- if (ret) {
- local->op_errno = -ret;
- ret = -1;
- goto out;
- }
-
- for (i = 0; i < priv->child_count; i++) {
- if (local->child_up[i]) {
- STACK_WIND_COOKIE (frame, afr_lookup_cbk,
- (void *) (long) i,
- priv->children[i],
- priv->children[i]->fops->lookup,
- &local->loc, local->xattr_req);
- if (!--call_count)
- break;
- }
- }
- return 0;
-out:
- AFR_STACK_UNWIND (lookup, frame, -1, local->op_errno, 0, 0, 0, 0);
- return 0;
-}
-
-/*
- * afr_lookup()
- *
- * The goal here is to figure out what the element getting looked up is.
- * i.e what is the GFID, inode type and a conservative estimate of the
- * inode attributes are.
- *
- * As we lookup, operations may be underway on the entry name and the
- * inode. In lookup() we are primarily concerned only with the entry
- * operations. If the entry is getting unlinked or renamed, we detect
- * what operation is underway by querying for on-going transactions and
- * pending self-healing on the entry through xdata.
- *
- * If the entry is a file/dir, it may need self-heal and/or in a
- * split-brain condition. Lookup is not the place to worry about these
- * conditions. Outcast marking will naturally handle them in the read
- * paths.
- *
- * Here is a brief goal of what we are trying to achieve:
- *
- * - LOOKUP on all subvolumes concurrently, querying on-going transaction
- * and pending self-heal info from the servers.
- *
- * - If all servers reply the same inode type and GFID, the overall call
- * MUST be a success.
- *
- * - If inode types or GFIDs mismatch, and there IS either an on-going
- * transaction or pending self-heal, inspect what the nature of the
- * transaction or pending heal is, and select the appropriate subvolume's
- * reply as the winner.
- *
- * - If inode types or GFIDs mismatch, and there are no on-going transactions
- * or pending self-heal on the entry name on any of the servers, fail the
- * lookup with EIO. Something has gone wrong beyond reasonable action.
- */
-
-int
-afr_lookup (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xattr_req)
-{
- afr_local_t *local = NULL;
- int32_t op_errno = 0;
- int event = 0;
- void *gfid_req = NULL;
- int ret = 0;
-
- if (!loc->parent && uuid_is_null (loc->pargfid)) {
- if (xattr_req)
- dict_del (xattr_req, "gfid-req");
- afr_discover (frame, this, loc, xattr_req);
- return 0;
- }
-
- if (__is_root_gfid (loc->parent->gfid)) {
- if (!strcmp (loc->name, GF_REPLICATE_TRASH_DIR)) {
- op_errno = EPERM;
- goto out;
- }
- }
-
- local = AFR_FRAME_INIT (frame, op_errno);
- if (!local)
- goto out;
-
- if (!local->call_count) {
- op_errno = ENOTCONN;
- goto out;
- }
-
- local->op = GF_FOP_LOOKUP;
-
- loc_copy (&local->loc, loc);
-
- local->inode = inode_ref (loc->inode);
-
- if (xattr_req) {
- /* If xattr_req was null, afr_lookup_xattr_req_prepare() will
- allocate one for us */
- ret = dict_get_ptr (xattr_req, "gfid-req", &gfid_req);
- if (ret == 0) {
- uuid_copy (local->cont.lookup.gfid_req, gfid_req);
- dict_del (xattr_req, "gfid-req");
- }
- local->xattr_req = dict_ref (xattr_req);
- }
-
- afr_read_subvol_get (loc->parent, this, NULL, &event,
- AFR_DATA_TRANSACTION, NULL);
-
- if (event != local->event_generation)
- afr_inode_refresh (frame, this, loc->parent, afr_lookup_do);
- else
- afr_lookup_do (frame, this, 0);
-
- return 0;
-out:
- AFR_STACK_UNWIND (lookup, frame, -1, op_errno, NULL, NULL, NULL, NULL);
-
- return 0;
-}
-
-
-/* {{{ open */
-
-afr_fd_ctx_t *
-__afr_fd_ctx_get (fd_t *fd, xlator_t *this)
-{
- uint64_t ctx = 0;
- int ret = 0;
- afr_fd_ctx_t *fd_ctx = NULL;
-
- ret = __fd_ctx_get (fd, this, &ctx);
-
- if (ret < 0) {
- ret = __afr_fd_ctx_set (this, fd);
- if (ret < 0)
- goto out;
-
- ret = __fd_ctx_get (fd, this, &ctx);
- 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);
-
- return fd_ctx;
-}
-
-
-int
-__afr_fd_ctx_set (xlator_t *this, fd_t *fd)
-{
- afr_private_t * priv = NULL;
- int ret = -1;
- uint64_t ctx = 0;
- afr_fd_ctx_t * fd_ctx = NULL;
- int i = 0;
-
- VALIDATE_OR_GOTO (this->private, out);
- VALIDATE_OR_GOTO (fd, out);
-
- 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;
- }
-
- for (i = 0; i < AFR_NUM_CHANGE_LOGS; i++) {
- fd_ctx->pre_op_done[i] = GF_CALLOC (sizeof (*fd_ctx->pre_op_done[i]),
- priv->child_count,
- gf_afr_mt_int32_t);
- if (!fd_ctx->pre_op_done[i]) {
- 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;
- }
-
- for (i = 0; i < priv->child_count; i++) {
- if (fd_is_anonymous (fd))
- fd_ctx->opened_on[i] = AFR_FD_OPENED;
- else
- fd_ctx->opened_on[i] = AFR_FD_NOT_OPENED;
- }
-
- 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;
- }
-
- 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->readdir_subvol = -1;
-
- pthread_mutex_init (&fd_ctx->delay_lock, NULL);
-
- INIT_LIST_HEAD (&fd_ctx->eager_locked);
-
- 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;
-}
-
-
-int
-afr_fd_ctx_set (xlator_t *this, fd_t *fd)
-{
- int ret = -1;
-
- LOCK (&fd->lock);
- {
- ret = __afr_fd_ctx_set (this, fd);
- }
- UNLOCK (&fd->lock);
-
- return ret;
-}
-
-/* {{{ flush */
-
-int
-afr_flush_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;
- int call_count = -1;
-
- local = frame->local;
-
- LOCK (&frame->lock);
- {
- if (op_ret != -1) {
- local->op_ret = op_ret;
- if (!local->xdata_rsp && xdata)
- local->xdata_rsp = dict_ref (xdata);
- } else {
- local->op_errno = op_errno;
- }
- }
- UNLOCK (&frame->lock);
-
- call_count = afr_frame_return (frame);
-
- if (call_count == 0)
- AFR_STACK_UNWIND (flush, frame, local->op_ret,
- local->op_errno, local->xdata_rsp);
-
- return 0;
-}
-
-static int
-afr_flush_wrapper (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
-{
- int i = 0;
- afr_local_t *local = NULL;
- afr_private_t *priv = NULL;
- int call_count = -1;
-
- priv = this->private;
- local = frame->local;
- call_count = local->call_count;
-
- for (i = 0; i < priv->child_count; i++) {
- if (local->child_up[i]) {
- STACK_WIND_COOKIE (frame, afr_flush_cbk,
- (void *) (long) i,
- priv->children[i],
- priv->children[i]->fops->flush,
- local->fd, xdata);
- if (!--call_count)
- break;
-
- }
- }
-
- return 0;
-}
-
-int
-afr_flush (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
-{
- afr_local_t *local = NULL;
- call_stub_t *stub = NULL;
- int op_errno = ENOMEM;
-
- local = AFR_FRAME_INIT (frame, op_errno);
- if (!local)
- goto out;
-
- if (!local->call_count) {
- op_errno = ENOTCONN;
- goto out;
- }
-
- local->fd = fd_ref(fd);
-
- stub = fop_flush_stub (frame, afr_flush_wrapper, fd, xdata);
- if (!stub)
- goto out;
-
- afr_delayed_changelog_wake_resume (this, fd, stub);
-
- return 0;
-out:
- AFR_STACK_UNWIND (flush, frame, -1, op_errno, NULL);
- return 0;
-}
-
-/* }}} */
-
-
-int
-afr_cleanup_fd_ctx (xlator_t *this, fd_t *fd)
-{
- uint64_t ctx = 0;
- afr_fd_ctx_t *fd_ctx = NULL;
- int ret = 0;
- int i = 0;
-
- ret = fd_ctx_get (fd, this, &ctx);
- if (ret < 0)
- goto out;
-
- fd_ctx = (afr_fd_ctx_t *)(long) ctx;
-
- if (fd_ctx) {
- //no need to take any locks
- if (!list_empty (&fd_ctx->eager_locked))
- gf_log (this->name, GF_LOG_WARNING, "%s: Stale "
- "Eager-lock stubs found",
- uuid_utoa (fd->inode->gfid));
-
- for (i = 0; i < AFR_NUM_CHANGE_LOGS; i++)
- GF_FREE (fd_ctx->pre_op_done[i]);
-
- GF_FREE (fd_ctx->opened_on);
-
- GF_FREE (fd_ctx->lock_piggyback);
-
- GF_FREE (fd_ctx->lock_acquired);
-
- pthread_mutex_destroy (&fd_ctx->delay_lock);
-
- GF_FREE (fd_ctx);
- }
-
-out:
- return 0;
-}
-
-
-int
-afr_release (xlator_t *this, fd_t *fd)
-{
- afr_cleanup_fd_ctx (this, fd);
-
- return 0;
-}
-
-
-/* {{{ fsync */
-
-int
-afr_fsync_unwind_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)
-{
- AFR_STACK_UNWIND (fsync, frame, op_ret, op_errno, prebuf, postbuf,
- xdata);
- return 0;
-}
-
-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)
-{
- afr_local_t *local = NULL;
- int call_count = -1;
- int child_index = (long) cookie;
- int read_subvol = 0;
- call_stub_t *stub = NULL;
-
- local = frame->local;
-
- read_subvol = afr_data_subvol_get (local->inode, this, 0, 0, NULL);
-
- LOCK (&frame->lock);
- {
- if (op_ret == 0) {
- if (local->op_ret == -1) {
- local->op_ret = 0;
-
- local->cont.inode_wfop.prebuf = *prebuf;
- local->cont.inode_wfop.postbuf = *postbuf;
-
- if (xdata)
- local->xdata_rsp = dict_ref (xdata);
- }
-
- if (child_index == read_subvol) {
- local->cont.inode_wfop.prebuf = *prebuf;
- local->cont.inode_wfop.postbuf = *postbuf;
- if (xdata) {
- if (local->xdata_rsp)
- dict_unref (local->xdata_rsp);
- local->xdata_rsp = dict_ref (xdata);
- }
- }
- } else {
- local->op_errno = op_errno;
- }
- }
- UNLOCK (&frame->lock);
-
- call_count = afr_frame_return (frame);
-
- if (call_count == 0) {
- /* Make a stub out of the frame, and register it
- with the waking up post-op. When the call-stub resumes,
- we are guaranteed that there was no post-op pending
- (i.e changelogs were unset in the server). This is an
- essential "guarantee", that fsync() returns only after
- completely finishing EVERYTHING, including the delayed
- post-op. This guarantee is expected by FUSE graph switching
- for example.
- */
- stub = fop_fsync_cbk_stub (frame, afr_fsync_unwind_cbk,
- local->op_ret, local->op_errno,
- &local->cont.inode_wfop.prebuf,
- &local->cont.inode_wfop.postbuf,
- local->xdata_rsp);
- if (!stub) {
- AFR_STACK_UNWIND (fsync, frame, -1, ENOMEM, 0, 0, 0);
- return 0;
- }
-
- /* If no new unstable writes happened between the
- time we cleared the unstable write witness flag in afr_fsync
- and now, calling afr_delayed_changelog_wake_up() should
- wake up and skip over the fsync phase and go straight to
- afr_changelog_post_op_now()
- */
- afr_delayed_changelog_wake_resume (this, local->fd, stub);
- }
-
- return 0;
-}
-
-
-int
-afr_fsync (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t datasync,
- dict_t *xdata)
-{
- afr_private_t *priv = NULL;
- afr_local_t *local = NULL;
- int i = 0;
- int32_t call_count = 0;
- int32_t op_errno = ENOMEM;
-
- priv = this->private;
-
- local = AFR_FRAME_INIT (frame, op_errno);
- if (!local)
- goto out;
-
- call_count = local->call_count;
- if (!call_count) {
- op_errno = ENOTCONN;
- goto out;
- }
-
- local->fd = fd_ref (fd);
-
- if (afr_fd_has_witnessed_unstable_write (this, fd)) {
- /* don't care. we only wanted to CLEAR the bit */
- }
-
- local->inode = inode_ref (fd->inode);
-
- for (i = 0; i < priv->child_count; i++) {
- if (local->child_up[i]) {
- STACK_WIND_COOKIE (frame, afr_fsync_cbk,
- (void *) (long) i,
- priv->children[i],
- priv->children[i]->fops->fsync,
- fd, datasync, xdata);
- if (!--call_count)
- break;
- }
- }
-
- return 0;
-out:
- AFR_STACK_UNWIND (fsync, frame, -1, op_errno, NULL, NULL, NULL);
-
- return 0;
-}
-
-/* }}} */
-
-/* {{{ fsync */
-
-int
-afr_fsyncdir_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;
- int call_count = -1;
-
- local = frame->local;
-
- LOCK (&frame->lock);
- {
- if (op_ret == 0) {
- local->op_ret = 0;
- if (!local->xdata_rsp && xdata)
- local->xdata_rsp = dict_ref (xdata);
- } else {
- local->op_errno = op_errno;
- }
- }
- UNLOCK (&frame->lock);
-
- call_count = afr_frame_return (frame);
-
- if (call_count == 0)
- AFR_STACK_UNWIND (fsyncdir, frame, local->op_ret,
- local->op_errno, local->xdata_rsp);
-
- return 0;
-}
-
-
-int
-afr_fsyncdir (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t datasync,
- dict_t *xdata)
-{
- afr_private_t *priv = NULL;
- afr_local_t *local = NULL;
- int i = 0;
- int32_t call_count = 0;
- int32_t op_errno = ENOMEM;
-
- priv = this->private;
-
- local = AFR_FRAME_INIT (frame, op_errno);
- if (!local)
- goto out;
-
- call_count = local->call_count;
- if (!call_count) {
- op_errno = ENOTCONN;
- goto out;
- }
-
- 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);
- if (!--call_count)
- break;
- }
- }
-
- return 0;
-out:
- AFR_STACK_UNWIND (fsyncdir, frame, -1, op_errno, NULL);
-
- return 0;
-}
-
-/* }}} */
-
-/* {{{ xattrop */
-
-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)
-{
- afr_local_t *local = NULL;
- int call_count = -1;
-
- local = frame->local;
-
- LOCK (&frame->lock);
- {
- if (op_ret == 0) {
- if (!local->cont.xattrop.xattr)
- local->cont.xattrop.xattr = dict_ref (xattr);
-
- if (!local->xdata_rsp && xdata)
- local->xdata_rsp = dict_ref (xdata);
-
- local->op_ret = 0;
- }
-
- local->op_errno = op_errno;
- }
- UNLOCK (&frame->lock);
-
- call_count = afr_frame_return (frame);
-
- if (call_count == 0)
- AFR_STACK_UNWIND (xattrop, frame, local->op_ret, local->op_errno,
- local->cont.xattrop.xattr, local->xdata_rsp);
-
- return 0;
-}
-
-
-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)
-{
- afr_private_t *priv = NULL;
- afr_local_t *local = NULL;
- int i = 0;
- int32_t call_count = 0;
- int32_t op_errno = ENOMEM;
-
- priv = this->private;
-
- local = AFR_FRAME_INIT (frame, op_errno);
- if (!local)
- goto out;
-
- call_count = local->call_count;
- if (!call_count) {
- op_errno = ENOTCONN;
- goto out;
- }
-
- 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);
- if (!--call_count)
- break;
- }
- }
-
- return 0;
-out:
- AFR_STACK_UNWIND (xattrop, frame, -1, op_errno, NULL, NULL);
-
- return 0;
-}
-
-/* }}} */
-
-/* {{{ fxattrop */
-
-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)
-{
- afr_local_t *local = NULL;
-
- int call_count = -1;
-
- local = frame->local;
-
- LOCK (&frame->lock);
- {
- if (op_ret == 0) {
- if (!local->cont.fxattrop.xattr)
- local->cont.fxattrop.xattr = dict_ref (xattr);
-
- if (!local->xdata_rsp && xdata)
- local->xdata_rsp = dict_ref (xdata);
- local->op_ret = 0;
- }
-
- local->op_errno = op_errno;
- }
- UNLOCK (&frame->lock);
-
- call_count = afr_frame_return (frame);
-
- if (call_count == 0)
- AFR_STACK_UNWIND (fxattrop, frame, local->op_ret, local->op_errno,
- local->cont.fxattrop.xattr, local->xdata_rsp);
-
- return 0;
-}
-
-
-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)
-{
- afr_private_t *priv = NULL;
- afr_local_t *local = NULL;
- int i = 0;
- int32_t call_count = 0;
- int32_t op_errno = 0;
-
- priv = this->private;
-
- local = AFR_FRAME_INIT (frame, op_errno);
- if (!local)
- goto out;
-
- call_count = local->call_count;
- if (!call_count) {
- op_errno = ENOTCONN;
- goto out;
- }
-
- 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);
- if (!--call_count)
- break;
- }
- }
-
- return 0;
-out:
- AFR_STACK_UNWIND (fxattrop, frame, -1, op_errno, NULL, NULL);
-
- return 0;
-}
-
-/* }}} */
-
-int32_t
-afr_unlock_partial_inodelk_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 child_index = (long)cookie;
- uuid_t gfid = {0};
-
- local = frame->local;
- priv = this->private;
-
- if (op_ret < 0 && op_errno != ENOTCONN) {
- loc_gfid (&local->loc, gfid);
- gf_log (this->name, GF_LOG_ERROR, "%s: Failed to unlock %s "
- "with lk_owner: %s (%s)", uuid_utoa (gfid),
- priv->children[child_index]->name,
- lkowner_utoa (&frame->root->lk_owner),
- strerror (op_errno));
- }
-
- call_count = afr_frame_return (frame);
- if (call_count == 0) {
- AFR_STACK_UNWIND (inodelk, frame, local->op_ret,
- local->op_errno, local->xdata_rsp);
- }
-
- return 0;
-}
-
-int32_t
-afr_unlock_inodelks_and_unwind (call_frame_t *frame, xlator_t *this,
- int call_count)
-{
- int i = 0;
- afr_private_t *priv = NULL;
- afr_local_t *local = NULL;
-
- local = frame->local;
- priv = this->private;
- local->call_count = call_count;
- local->cont.inodelk.flock.l_type = F_UNLCK;
-
- for (i = 0; i < priv->child_count; i++) {
- if (!local->replies[i].valid)
- continue;
-
- if (local->replies[i].op_ret == -1)
- continue;
-
- STACK_WIND_COOKIE (frame, afr_unlock_partial_inodelk_cbk,
- (void*) (long) i,
- priv->children[i],
- priv->children[i]->fops->inodelk,
- local->cont.inodelk.volume,
- &local->loc, local->cont.inodelk.cmd,
- &local->cont.inodelk.flock, 0);
-
- if (!--call_count)
- break;
- }
-
- return 0;
-}
-
-int32_t
-afr_inodelk_done (call_frame_t *frame, xlator_t *this)
-{
- int i = 0;
- int lock_count = 0;
-
- afr_local_t *local = NULL;
- afr_private_t *priv = NULL;
-
- local = frame->local;
- priv = this->private;
-
- for (i = 0; i < priv->child_count; i++) {
- if (!local->replies[i].valid)
- continue;
-
- if (local->replies[i].op_ret == 0)
- lock_count++;
-
- if (local->op_ret == -1 && local->op_errno == EAGAIN)
- continue;
-
- if ((local->replies[i].op_ret == -1) &&
- (local->replies[i].op_errno == EAGAIN)) {
- local->op_ret = -1;
- local->op_errno = EAGAIN;
- continue;
- }
-
- if (local->replies[i].op_ret == 0)
- local->op_ret = 0;
-
- local->op_errno = local->replies[i].op_errno;
- }
-
- if (lock_count && local->cont.inodelk.flock.l_type != F_UNLCK &&
- (local->op_ret == -1 && local->op_errno == EAGAIN)) {
- afr_unlock_inodelks_and_unwind (frame, this,
- lock_count);
- } else {
- AFR_STACK_UNWIND (inodelk, frame, local->op_ret,
- local->op_errno, local->xdata_rsp);
- }
-
- return 0;
-}
-
-int
-afr_common_inodelk_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;
- int child_index = (long)cookie;
-
- local = frame->local;
-
- local->replies[child_index].valid = 1;
- local->replies[child_index].op_ret = op_ret;
- local->replies[child_index].op_errno = op_errno;
- if (op_ret == 0 && xdata) {
- local->replies[child_index].xdata = dict_ref (xdata);
- LOCK (&frame->lock);
- {
- if (!local->xdata_rsp)
- local->xdata_rsp = dict_ref (xdata);
- }
- UNLOCK (&frame->lock);
- }
- return 0;
-}
-
-static int32_t
-afr_parallel_inodelk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
-
-{
- int call_count = 0;
-
- afr_common_inodelk_cbk (frame, cookie, this, op_ret, op_errno, xdata);
-
- call_count = afr_frame_return (frame);
- if (call_count == 0)
- afr_inodelk_done (frame, this);
-
- return 0;
-}
-
-static inline gf_boolean_t
-afr_is_conflicting_lock_present (int32_t op_ret, int32_t op_errno)
-{
- if (op_ret == -1 && op_errno == EAGAIN)
- return _gf_true;
- return _gf_false;
-}
-
-static int32_t
-afr_serialized_inodelk_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 child_index = (long)cookie;
- int next_child = 0;
-
- local = frame->local;
- priv = this->private;
-
- afr_common_inodelk_cbk (frame, cookie, this, op_ret, op_errno, xdata);
-
- for (next_child = child_index + 1; next_child < priv->child_count;
- next_child++) {
- if (local->child_up[next_child])
- break;
- }
-
- if (afr_is_conflicting_lock_present (op_ret, op_errno) ||
- (next_child == priv->child_count)) {
- afr_inodelk_done (frame, this);
- } else {
- STACK_WIND_COOKIE (frame, afr_serialized_inodelk_cbk,
- (void *) (long) next_child,
- priv->children[next_child],
- priv->children[next_child]->fops->inodelk,
- (const char *)local->cont.inodelk.volume,
- &local->loc, local->cont.inodelk.cmd,
- &local->cont.inodelk.flock,
- local->xdata_req);
- }
-
- return 0;
-}
-
-static int
-afr_parallel_inodelk_wind (call_frame_t *frame, xlator_t *this)
-{
- afr_private_t *priv = NULL;
- afr_local_t *local = NULL;
- int call_count = 0;
- int i = 0;
-
- priv = this->private;
- local = frame->local;
- call_count = local->call_count;
-
- for (i = 0; i < priv->child_count; i++) {
- if (!local->child_up[i])
- continue;
- STACK_WIND_COOKIE (frame, afr_parallel_inodelk_cbk,
- (void *) (long) i,
- priv->children[i],
- priv->children[i]->fops->inodelk,
- (const char *)local->cont.inodelk.volume,
- &local->loc, local->cont.inodelk.cmd,
- &local->cont.inodelk.flock,
- local->xdata_req);
- if (!--call_count)
- break;
- }
- return 0;
-}
-
-static int
-afr_serialized_inodelk_wind (call_frame_t *frame, xlator_t *this)
-{
- afr_private_t *priv = NULL;
- afr_local_t *local = NULL;
- int i = 0;
-
- priv = this->private;
- local = frame->local;
-
- for (i = 0; i < priv->child_count; i++) {
- if (local->child_up[i]) {
- STACK_WIND_COOKIE (frame, afr_serialized_inodelk_cbk,
- (void *) (long) i,
- priv->children[i],
- priv->children[i]->fops->inodelk,
- (const char *)local->cont.inodelk.volume,
- &local->loc, local->cont.inodelk.cmd,
- &local->cont.inodelk.flock,
- local->xdata_req);
- break;
- }
- }
- return 0;
-}
-
-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)
-{
- afr_local_t *local = NULL;
- int32_t op_errno = ENOMEM;
-
- local = AFR_FRAME_INIT (frame, op_errno);
- if (!local)
- goto out;
-
- loc_copy (&local->loc, loc);
- local->cont.inodelk.volume = gf_strdup (volume);
- if (!local->cont.inodelk.volume) {
- op_errno = ENOMEM;
- goto out;
- }
-
- local->cont.inodelk.cmd = cmd;
- local->cont.inodelk.flock = *flock;
- if (xdata)
- local->xdata_req = dict_ref (xdata);
-
- /* At least one child is up */
- /*
- * Non-blocking locks also need to be serialized. Otherwise there is
- * a chance that both the mounts which issued same non-blocking inodelk
- * may endup not acquiring the lock on any-brick.
- * Ex: Mount1 and Mount2
- * request for full length lock on file f1. Mount1 afr may acquire the
- * partial lock on brick-1 and may not acquire the lock on brick-2
- * because Mount2 already got the lock on brick-2, vice versa. Since
- * both the mounts only got partial locks, afr treats them as failure in
- * gaining the locks and unwinds with EAGAIN errno.
- */
- if (flock->l_type == F_UNLCK) {
- afr_parallel_inodelk_wind (frame, this);
- } else {
- afr_serialized_inodelk_wind (frame, this);
- }
-
- return 0;
-out:
- AFR_STACK_UNWIND (inodelk, frame, -1, op_errno, NULL);
-
- 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)
-
-{
- afr_local_t *local = NULL;
- int call_count = -1;
-
- local = frame->local;
-
- LOCK (&frame->lock);
- {
- if (op_ret == 0)
- local->op_ret = 0;
-
- local->op_errno = op_errno;
- }
- UNLOCK (&frame->lock);
-
- call_count = afr_frame_return (frame);
-
- if (call_count == 0)
- AFR_STACK_UNWIND (finodelk, frame, local->op_ret,
- local->op_errno, xdata);
-
- return 0;
-}
-
-
-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)
-{
- afr_private_t *priv = NULL;
- afr_local_t *local = NULL;
- int i = 0;
- int32_t call_count = 0;
- int32_t op_errno = ENOMEM;
-
- priv = this->private;
-
- local = AFR_FRAME_INIT (frame, op_errno);
- if (!local)
- goto out;
-
- call_count = local->call_count;
- if (!call_count) {
- op_errno = ENOTCONN;
- goto out;
- }
-
- 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);
-
- if (!--call_count)
- break;
- }
- }
-
- return 0;
-out:
- AFR_STACK_UNWIND (finodelk, frame, -1, op_errno, NULL);
-
- 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_local_t *local = NULL;
- int call_count = -1;
-
- local = frame->local;
-
- LOCK (&frame->lock);
- {
- if (op_ret == 0)
- local->op_ret = 0;
-
- local->op_errno = op_errno;
- }
- UNLOCK (&frame->lock);
-
- call_count = afr_frame_return (frame);
-
- if (call_count == 0)
- AFR_STACK_UNWIND (entrylk, frame, local->op_ret,
- local->op_errno, xdata);
-
- return 0;
-}
-
-
-int
-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)
-{
- afr_private_t *priv = NULL;
- afr_local_t *local = NULL;
- int i = 0;
- int32_t call_count = 0;
- int32_t op_errno = 0;
-
- priv = this->private;
-
- local = AFR_FRAME_INIT (frame, op_errno);
- if (!local)
- goto out;
-
- call_count = local->call_count;
- if (!call_count) {
- op_errno = ENOTCONN;
- goto out;
- }
-
- 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);
-
- if (!--call_count)
- break;
- }
- }
-
- return 0;
-out:
- AFR_STACK_UNWIND (entrylk, frame, -1, op_errno, NULL);
-
- return 0;
-}
-
-
-
-int
-afr_fentrylk_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;
- int call_count = -1;
-
- local = frame->local;
-
- LOCK (&frame->lock);
- {
- if (op_ret == 0)
- local->op_ret = 0;
-
- local->op_errno = op_errno;
- }
- UNLOCK (&frame->lock);
-
- call_count = afr_frame_return (frame);
-
- if (call_count == 0)
- AFR_STACK_UNWIND (fentrylk, frame, local->op_ret,
- local->op_errno, xdata);
-
- return 0;
-}
-
-
-int
-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)
-{
- afr_private_t *priv = NULL;
- afr_local_t *local = NULL;
- int i = 0;
- int32_t call_count = 0;
- int32_t op_errno = ENOMEM;
-
- priv = this->private;
-
- local = AFR_FRAME_INIT (frame, op_errno);
- if (!local)
- goto out;
-
- call_count = local->call_count;
- if (!call_count) {
- op_errno = ENOTCONN;
- goto out;
- }
-
- 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);
-
- if (!--call_count)
- break;
- }
- }
-
- return 0;
-out:
- AFR_STACK_UNWIND (fentrylk, frame, -1, op_errno, NULL);
-
- return 0;
-}
-
-
-int
-afr_statfs_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int op_ret,
- int op_errno, struct statvfs *statvfs, dict_t *xdata)
-{
- afr_local_t *local = NULL;
- int call_count = 0;
- struct statvfs *buf = NULL;
-
- LOCK (&frame->lock);
- {
- local = frame->local;
-
- if (op_ret != 0) {
- local->op_errno = op_errno;
- goto unlock;
- }
-
- local->op_ret = op_ret;
-
- buf = &local->cont.statfs.buf;
- if (local->cont.statfs.buf_set) {
- if (statvfs->f_bavail < buf->f_bavail) {
- *buf = *statvfs;
- if (xdata) {
- if (local->xdata_rsp)
- dict_unref (local->xdata_rsp);
- local->xdata_rsp = dict_ref (xdata);
- }
- }
- } else {
- *buf = *statvfs;
- local->cont.statfs.buf_set = 1;
- if (xdata)
- local->xdata_rsp = dict_ref (xdata);
- }
- }
-unlock:
- UNLOCK (&frame->lock);
-
- call_count = afr_frame_return (frame);
-
- if (call_count == 0)
- AFR_STACK_UNWIND (statfs, frame, local->op_ret, local->op_errno,
- &local->cont.statfs.buf, local->xdata_rsp);
-
- return 0;
-}
-
-
-int
-afr_statfs (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
-{
- afr_local_t * local = NULL;
- afr_private_t *priv = NULL;
- int i = 0;
- int call_count = 0;
- int32_t op_errno = ENOMEM;
-
- priv = this->private;
-
- local = AFR_FRAME_INIT (frame, op_errno);
- if (!local)
- goto out;
-
- call_count = local->call_count;
- if (!call_count) {
- op_errno = ENOTCONN;
- goto out;
- }
-
- for (i = 0; i < priv->child_count; i++) {
- if (local->child_up[i]) {
- STACK_WIND (frame, afr_statfs_cbk,
- priv->children[i],
- priv->children[i]->fops->statfs,
- loc, xdata);
- if (!--call_count)
- break;
- }
- }
-
- return 0;
-out:
- AFR_STACK_UNWIND (statfs, frame, -1, op_errno, NULL, 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)
-{
- afr_local_t * local = NULL;
- int call_count = -1;
-
- local = frame->local;
- call_count = afr_frame_return (frame);
-
- if (call_count == 0)
- AFR_STACK_UNWIND (lk, frame, local->op_ret, local->op_errno,
- lock, xdata);
-
- return 0;
-}
-
-
-int32_t
-afr_lk_unlock (call_frame_t *frame, xlator_t *this)
-{
- afr_local_t * local = NULL;
- afr_private_t * priv = NULL;
- int i = 0;
- int call_count = 0;
-
- local = frame->local;
- priv = this->private;
-
- call_count = afr_locked_nodes_count (local->cont.lk.locked_nodes,
- priv->child_count);
-
- if (call_count == 0) {
- AFR_STACK_UNWIND (lk, frame, local->op_ret, local->op_errno,
- &local->cont.lk.ret_flock, NULL);
- return 0;
- }
-
- local->call_count = call_count;
-
- local->cont.lk.user_flock.l_type = F_UNLCK;
-
- for (i = 0; i < priv->child_count; i++) {
- if (local->cont.lk.locked_nodes[i]) {
- STACK_WIND (frame, afr_lk_unlock_cbk,
- priv->children[i],
- priv->children[i]->fops->lk,
- local->fd, F_SETLK,
- &local->cont.lk.user_flock, NULL);
-
- if (!--call_count)
- break;
- }
- }
-
- return 0;
-}
-
-
-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)
-{
- afr_local_t *local = NULL;
- afr_private_t *priv = NULL;
- int child_index = -1;
-/* int ret = 0; */
-
-
- local = frame->local;
- priv = this->private;
-
- child_index = (long) cookie;
-
- if (!child_went_down (op_ret, op_errno) && (op_ret == -1)) {
- local->op_ret = -1;
- local->op_errno = op_errno;
-
- afr_lk_unlock (frame, this);
- return 0;
- }
-
- if (op_ret == 0) {
- local->op_ret = 0;
- local->op_errno = 0;
- local->cont.lk.locked_nodes[child_index] = 1;
- local->cont.lk.ret_flock = *lock;
- }
-
- child_index++;
-
- if (child_index < priv->child_count) {
- STACK_WIND_COOKIE (frame, afr_lk_cbk, (void *) (long) child_index,
- priv->children[child_index],
- priv->children[child_index]->fops->lk,
- local->fd, local->cont.lk.cmd,
- &local->cont.lk.user_flock, xdata);
- } else if (local->op_ret == -1) {
- /* all nodes have gone down */
-
- AFR_STACK_UNWIND (lk, frame, -1, ENOTCONN,
- &local->cont.lk.ret_flock, NULL);
- } else {
- AFR_STACK_UNWIND (lk, frame, local->op_ret, local->op_errno,
- &local->cont.lk.ret_flock, NULL);
- }
-
- return 0;
-}
-
-
-int
-afr_lk (call_frame_t *frame, xlator_t *this,
- fd_t *fd, int32_t cmd, struct gf_flock *flock, dict_t *xdata)
-{
- afr_private_t *priv = NULL;
- afr_local_t *local = NULL;
- int i = 0;
- int32_t op_errno = ENOMEM;
-
- priv = this->private;
-
- local = AFR_FRAME_INIT (frame, op_errno);
- if (!local)
- goto out;
-
- local->cont.lk.locked_nodes = GF_CALLOC (priv->child_count,
- sizeof (*local->cont.lk.locked_nodes),
- gf_afr_mt_char);
-
- if (!local->cont.lk.locked_nodes) {
- op_errno = ENOMEM;
- goto out;
- }
-
- local->fd = fd_ref (fd);
- local->cont.lk.cmd = cmd;
- local->cont.lk.user_flock = *flock;
- local->cont.lk.ret_flock = *flock;
-
- STACK_WIND_COOKIE (frame, afr_lk_cbk, (void *) (long) 0,
- priv->children[i],
- priv->children[i]->fops->lk,
- fd, cmd, flock, xdata);
-
- return 0;
-out:
- AFR_STACK_UNWIND (lk, frame, -1, op_errno, NULL, NULL);
-
- return 0;
-}
-
-int
-afr_forget (xlator_t *this, inode_t *inode)
-{
- return 0;
-}
-
-int
-afr_priv_dump (xlator_t *this)
-{
- afr_private_t *priv = NULL;
- char key_prefix[GF_DUMP_MAX_BUF_LEN];
- char key[GF_DUMP_MAX_BUF_LEN];
- int i = 0;
-
-
- GF_ASSERT (this);
- priv = this->private;
-
- 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);
- for (i = 0; i < priv->child_count; i++) {
- sprintf (key, "child_up[%d]", i);
- gf_proc_dump_write(key, "%d", priv->child_up[i]);
- sprintf (key, "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);
-
- return 0;
-}
-
-
-/**
- * find_child_index - find the child's index in the array of subvolumes
- * @this: AFR
- * @child: child
- */
-
-static int
-find_child_index (xlator_t *this, xlator_t *child)
-{
- afr_private_t *priv = NULL;
- int i = -1;
-
- priv = this->private;
-
- for (i = 0; i < priv->child_count; i++) {
- if ((xlator_t *) child == priv->children[i])
- break;
- }
-
- return i;
-}
-
-int32_t
-afr_notify (xlator_t *this, int32_t event,
- void *data, void *data2)
-{
- 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 = -1;
- dict_t *input = NULL;
- dict_t *output = NULL;
- gf_boolean_t had_quorum = _gf_false;
- gf_boolean_t has_quorum = _gf_false;
-
- 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_msg (this->name, GF_LOG_ERROR, 0, AFR_MSG_INVALID_CHILD_UP,
- "Received child_up from invalid subvolume");
- goto out;
- }
-
- had_quorum = priv->quorum_count && afr_has_quorum (priv->child_up,
- this);
- 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->event_generation++;
- }
- 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_msg (this->name, GF_LOG_INFO, 0,
- AFR_MSG_SUBVOL_UP,
- "Subvolume '%s' came back up; "
- "going online.", ((xlator_t *)data)->name);
- } else {
- event = GF_EVENT_CHILD_MODIFIED;
- }
-
- priv->last_event[idx] = event;
- }
- UNLOCK (&priv->lock);
-
- break;
-
- 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->event_generation++;
- }
- 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_msg (this->name, GF_LOG_ERROR, 0,
- AFR_MSG_ALL_SUBVOLS_DOWN,
- "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;
- }
- UNLOCK (&priv->lock);
-
- break;
-
- case GF_EVENT_CHILD_CONNECTING:
- LOCK (&priv->lock);
- {
- priv->last_event[idx] = event;
- }
- UNLOCK (&priv->lock);
-
- break;
-
- case GF_EVENT_TRANSLATOR_OP:
- input = data;
- output = data2;
- if (!had_heard_from_all) {
- ret = -1;
- goto out;
- }
- ret = afr_xl_op (this, input, output);
- goto out;
- break;
-
- default:
- propagate = 1;
- break;
- }
-
- if (priv->quorum_count) {
- has_quorum = afr_has_quorum (priv->child_up, this);
- if (!had_quorum && has_quorum)
- gf_msg (this->name, GF_LOG_INFO, 0, AFR_MSG_QUORUM_MET,
- "Client-quorum is met");
- if (had_quorum && !has_quorum)
- gf_msg (this->name, GF_LOG_WARNING, 0,
- AFR_MSG_QUORUM_FAIL,
- "Client-quorum is not met");
- }
-
- /* 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;
-
- 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;
-
- LOCK (&priv->lock);
- {
- up_children = AFR_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 */
- }
- }
- }
- UNLOCK (&priv->lock);
- }
-
- ret = 0;
- if (propagate)
- ret = default_notify (this, event, data);
-
- if (!had_heard_from_all && have_heard_from_all && priv->shd.iamshd) {
- /*
- * Since self-heal is supposed to be launched only after
- * the responses from all the bricks are collected,
- * launch self-heals now on all up subvols.
- */
- for (i = 0; i < priv->child_count; i++)
- if (priv->child_up[i])
- afr_selfheal_childup (this, i);
- } else if (have_heard_from_all && call_psh && priv->shd.iamshd) {
- /*
- * Already heard from everyone. Just launch heal on now up
- * subvolume.
- */
- afr_selfheal_childup (this, up_child);
- }
-out:
- return ret;
-}
-
-
-int
-afr_local_init (afr_local_t *local, afr_private_t *priv, int32_t *op_errno)
-{
- local->op_ret = -1;
- local->op_errno = EUCLEAN;
-
- syncbarrier_init (&local->barrier);
-
- 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_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->event_generation = priv->event_generation;
-
- local->read_attempted = GF_CALLOC (priv->child_count, sizeof (char),
- gf_afr_mt_char);
- if (!local->read_attempted) {
- if (op_errno)
- *op_errno = ENOMEM;
- goto out;
- }
-
- local->readable = GF_CALLOC (priv->child_count, sizeof (char),
- gf_afr_mt_char);
- if (!local->readable) {
- if (op_errno)
- *op_errno = ENOMEM;
- goto out;
- }
-
- local->replies = GF_CALLOC(priv->child_count, sizeof(*local->replies),
- gf_afr_mt_reply_t);
- if (!local->replies) {
- if (op_errno)
- *op_errno = ENOMEM;
- goto out;
- }
-
- return 0;
-out:
- return -1;
-}
-
-int
-afr_internal_lock_init (afr_internal_lock_t *lk, size_t child_count,
- transaction_lk_type_t lk_type)
-{
- int ret = -ENOMEM;
-
- 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_inodelk_init (afr_inodelk_t *lk, char *dom, size_t child_count)
-{
- int ret = -ENOMEM;
-
- lk->domain = dom;
- lk->locked_nodes = GF_CALLOC (sizeof (*lk->locked_nodes),
- child_count, gf_afr_mt_char);
- if (NULL == lk->locked_nodes)
- goto out;
- ret = 0;
-out:
- return ret;
-}
-
-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;
-
- if ((local->transaction.type == AFR_DATA_TRANSACTION) ||
- (local->transaction.type == AFR_METADATA_TRANSACTION)) {
- ret = afr_inodelk_init (&local->internal_lock.inodelk[0],
- this->name, priv->child_count);
- if (ret < 0)
- goto out;
- }
-
- ret = -ENOMEM;
- child_up_count = AFR_COUNT (local->child_up, priv->child_count);
- if (priv->optimistic_change_log && child_up_count == priv->child_count)
- local->optimistic_change_log = 1;
-
- local->pre_op_compat = priv->pre_op_compat;
-
- 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->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->transaction.fop_subvols = GF_CALLOC (sizeof (*local->transaction.fop_subvols),
- priv->child_count,
- gf_afr_mt_char);
- if (!local->transaction.fop_subvols)
- goto out;
-
- local->transaction.failed_subvols = GF_CALLOC (sizeof (*local->transaction.failed_subvols),
- priv->child_count,
- gf_afr_mt_char);
- if (!local->transaction.failed_subvols)
- goto out;
-
- local->pending = afr_matrix_create (priv->child_count,
- AFR_NUM_CHANGE_LOGS);
- if (!local->pending)
- goto out;
-
- INIT_LIST_HEAD (&local->transaction.eager_locked);
-
- ret = 0;
-out:
- return ret;
-}
-
-
-void
-afr_set_low_priority (call_frame_t *frame)
-{
- frame->root->pid = LOW_PRIO_PROC_PID;
-}
-
-
-gf_boolean_t
-afr_have_quorum (char *logname, afr_private_t *priv)
-{
- unsigned int quorum = 0;
-
- GF_VALIDATE_OR_GOTO(logname,priv,out);
-
- quorum = priv->quorum_count;
- if (quorum != AFR_QUORUM_AUTO) {
- return (priv->up_count >= (priv->down_count + quorum));
- }
-
- quorum = priv->child_count / 2 + 1;
- if (priv->up_count >= (priv->down_count + quorum)) {
- return _gf_true;
- }
-
- /*
- * 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;
- }
- }
- }
-
-out:
- return _gf_false;
-}
-
-void
-afr_priv_destroy (afr_private_t *priv)
-{
- int i = 0;
-
- if (!priv)
- goto out;
- inode_unref (priv->root_inode);
- GF_FREE (priv->last_event);
- if (priv->pending_key) {
- for (i = 0; i < priv->child_count; i++)
- GF_FREE (priv->pending_key[i]);
- }
- GF_FREE (priv->pending_key);
- GF_FREE (priv->children);
- GF_FREE (priv->child_up);
- LOCK_DESTROY (&priv->lock);
-
- GF_FREE (priv);
-out:
- return;
-}
-
-int
-xlator_subvolume_count (xlator_t *this)
-{
- int i = 0;
- xlator_list_t *list = NULL;
-
- for (list = this->children; list; list = list->next)
- i++;
- return i;
-}
-
-
-void
-afr_handle_open_fd_count (call_frame_t *frame, xlator_t *this)
-{
- afr_local_t *local = NULL;
- afr_fd_ctx_t *fd_ctx = NULL;
-
- local = frame->local;
-
- if (!local->fd)
- return;
-
- fd_ctx = afr_fd_ctx_get (local->fd, this);
- if (!fd_ctx)
- return;
-
- fd_ctx->open_fd_count = local->open_fd_count;
-}
-
-int**
-afr_mark_pending_changelog (afr_private_t *priv, unsigned char *pending,
- dict_t *xattr, ia_type_t iat)
-{
- int i = 0;
- int **changelog = NULL;
- int idx = -1;
- int m_idx = 0;
- int ret = 0;
-
- m_idx = afr_index_for_transaction_type (AFR_METADATA_TRANSACTION);
-
- idx = afr_index_from_ia_type (iat);
-
- changelog = afr_matrix_create (priv->child_count, AFR_NUM_CHANGE_LOGS);
- if (!changelog)
- goto out;
-
- for (i = 0; i < priv->child_count; i++) {
- if (!pending[i])
- continue;
-
- changelog[i][m_idx] = hton32(1);
- if (idx != -1)
- changelog[i][idx] = hton32(1);
- }
- ret = afr_set_pending_dict (priv, xattr, changelog);
- if (ret < 0) {
- afr_matrix_cleanup (changelog, priv->child_count);
- return NULL;
- }
-out:
- return changelog;
-}
-
-gf_boolean_t
-afr_decide_heal_info (afr_private_t *priv, unsigned char *sources, int ret)
-{
- int sources_count = 0;
-
- if (ret)
- goto out;
-
- sources_count = AFR_COUNT (sources, priv->child_count);
- if (sources_count == priv->child_count)
- return _gf_false;
-out:
- return _gf_true;
-}
-
-int
-afr_selfheal_locked_metadata_inspect (call_frame_t *frame, xlator_t *this,
- inode_t *inode, gf_boolean_t *msh)
-{
- int ret = -1;
- unsigned char *locked_on = NULL;
- unsigned char *sources = NULL;
- unsigned char *sinks = NULL;
- unsigned char *healed_sinks = NULL;
- struct afr_reply *locked_replies = NULL;
-
- afr_private_t *priv = this->private;
-
- locked_on = alloca0 (priv->child_count);
- sources = alloca0 (priv->child_count);
- sinks = alloca0 (priv->child_count);
- healed_sinks = alloca0 (priv->child_count);
-
- locked_replies = alloca0 (sizeof (*locked_replies) * priv->child_count);
-
- ret = afr_selfheal_inodelk (frame, this, inode, this->name,
- LLONG_MAX - 1, 0, locked_on);
- {
- if (ret == 0) {
- /* Not a single lock */
- ret = -afr_final_errno (frame->local, priv);
- if (ret == 0)
- ret = -ENOTCONN;/* all invalid responses */
- goto out;
- }
- ret = __afr_selfheal_metadata_prepare (frame, this, inode,
- locked_on, sources,
- sinks, healed_sinks,
- locked_replies);
- *msh = afr_decide_heal_info (priv, sources, ret);
- }
- afr_selfheal_uninodelk (frame, this, inode, this->name,
- LLONG_MAX - 1, 0, locked_on);
-out:
- if (locked_replies)
- afr_replies_wipe (locked_replies, priv->child_count);
- return ret;
-}
-
-int
-afr_selfheal_locked_data_inspect (call_frame_t *frame, xlator_t *this,
- inode_t *inode, gf_boolean_t *dsh)
-{
- int ret = -1;
- afr_private_t *priv = NULL;
- unsigned char *locked_on = NULL;
- unsigned char *data_lock = NULL;
- unsigned char *sources = NULL;
- unsigned char *sinks = NULL;
- unsigned char *healed_sinks = NULL;
- struct afr_reply *locked_replies = NULL;
-
- priv = this->private;
- locked_on = alloca0 (priv->child_count);
- data_lock = alloca0 (priv->child_count);
- sources = alloca0 (priv->child_count);
- sinks = alloca0 (priv->child_count);
- healed_sinks = alloca0 (priv->child_count);
-
- locked_replies = alloca0 (sizeof (*locked_replies) * priv->child_count);
-
- ret = afr_selfheal_tryinodelk (frame, this, inode, priv->sh_domain,
- 0, 0, locked_on);
- {
- if (ret == 0) {
- ret = -afr_final_errno (frame->local, priv);
- if (ret == 0)
- ret = -ENOTCONN;/* all invalid responses */
- goto out;
- }
- ret = afr_selfheal_inodelk (frame, this, inode, this->name,
- 0, 0, data_lock);
- {
- if (ret == 0) {
- ret = -afr_final_errno (frame->local, priv);
- if (ret == 0)
- ret = -ENOTCONN;
- /* all invalid responses */
- goto unlock;
- }
- ret = __afr_selfheal_data_prepare (frame, this, inode,
- data_lock, sources,
- sinks, healed_sinks,
- locked_replies);
- *dsh = afr_decide_heal_info (priv, sources, ret);
- }
- afr_selfheal_uninodelk (frame, this, inode, this->name, 0, 0,
- data_lock);
- }
-unlock:
- afr_selfheal_uninodelk (frame, this, inode, priv->sh_domain, 0, 0,
- locked_on);
-out:
- if (locked_replies)
- afr_replies_wipe (locked_replies, priv->child_count);
- return ret;
-}
-
-int
-afr_selfheal_locked_entry_inspect (call_frame_t *frame, xlator_t *this,
- inode_t *inode,
- gf_boolean_t *esh)
-{
- int ret = -1;
- int source = -1;
- afr_private_t *priv = NULL;
- unsigned char *locked_on = NULL;
- unsigned char *data_lock = NULL;
- unsigned char *sources = NULL;
- unsigned char *sinks = NULL;
- unsigned char *healed_sinks = NULL;
- struct afr_reply *locked_replies = NULL;
-
- priv = this->private;
- locked_on = alloca0 (priv->child_count);
- data_lock = alloca0 (priv->child_count);
- sources = alloca0 (priv->child_count);
- sinks = alloca0 (priv->child_count);
- healed_sinks = alloca0 (priv->child_count);
-
- locked_replies = alloca0 (sizeof (*locked_replies) * priv->child_count);
-
- ret = afr_selfheal_tryentrylk (frame, this, inode, priv->sh_domain,
- NULL, locked_on);
- {
- if (ret == 0) {
- ret = -afr_final_errno (frame->local, priv);
- if (ret == 0)
- ret = -ENOTCONN;/* all invalid responses */
- goto out;
- }
-
- ret = afr_selfheal_entrylk (frame, this, inode, this->name,
- NULL, data_lock);
- {
- if (ret == 0) {
- ret = -afr_final_errno (frame->local, priv);
- if (ret == 0)
- ret = -ENOTCONN;
- /* all invalid responses */
- goto unlock;
- }
- ret = __afr_selfheal_entry_prepare (frame, this, inode,
- data_lock, sources,
- sinks, healed_sinks,
- locked_replies,
- &source);
- if ((ret == 0) && source < 0)
- ret = -EIO;
- *esh = afr_decide_heal_info (priv, sources, ret);
- }
- afr_selfheal_unentrylk (frame, this, inode, this->name, NULL,
- data_lock);
- }
-unlock:
- afr_selfheal_unentrylk (frame, this, inode, priv->sh_domain, NULL,
- locked_on);
-out:
- if (locked_replies)
- afr_replies_wipe (locked_replies, priv->child_count);
- return ret;
-}
-
-int
-afr_selfheal_locked_inspect (call_frame_t *frame, xlator_t *this, uuid_t gfid,
- inode_t **inode,
- gf_boolean_t *entry_selfheal,
- gf_boolean_t *data_selfheal,
- gf_boolean_t *metadata_selfheal)
-
-{
- int ret = -1;
- gf_boolean_t dsh = _gf_false;
- gf_boolean_t msh = _gf_false;
- gf_boolean_t esh = _gf_false;
-
- ret = afr_selfheal_unlocked_inspect (frame, this, gfid, inode,
- &dsh, &msh, &esh);
- if (ret)
- goto out;
-
- /* For every heal type hold locks and check if it indeed needs heal */
-
- if (msh) {
- ret = afr_selfheal_locked_metadata_inspect (frame, this,
- *inode, &msh);
- if (ret == -EIO)
- goto out;
- }
-
- if (dsh) {
- ret = afr_selfheal_locked_data_inspect (frame, this, *inode,
- &dsh);
- if (ret == -EIO || (ret == -EAGAIN))
- goto out;
- }
-
- if (esh) {
- ret = afr_selfheal_locked_entry_inspect (frame, this, *inode,
- &esh);
- }
-
-out:
- *data_selfheal = dsh;
- *entry_selfheal = esh;
- *metadata_selfheal = msh;
- return ret;
-}
-
-dict_t*
-afr_set_heal_info (char *status)
-{
- dict_t *dict = NULL;
- int ret = -1;
-
- dict = dict_new ();
- if (!dict) {
- ret = -ENOMEM;
- goto out;
- }
-
- if (!strcmp (status, "heal")) {
- ret = dict_set_str (dict, "heal-info", "heal");
- if (ret)
- gf_log ("", GF_LOG_WARNING,
- "Failed to set heal-info key to"
- "heal");
- } else if (!strcmp (status, "split-brain")) {
- ret = dict_set_str (dict, "heal-info", "split-brain");
- if (ret)
- gf_log ("", GF_LOG_WARNING,
- "Failed to set heal-info key to"
- "split-brain");
- } else if (!strcmp (status, "possibly-healing")) {
- ret = dict_set_str (dict, "heal-info", "possibly-healing");
- if (ret)
- gf_log ("", GF_LOG_WARNING,
- "Failed to set heal-info key to"
- "possibly-healing");
- }
-out:
- return dict;
-}
-
-int
-afr_get_heal_info (call_frame_t *frame, xlator_t *this, loc_t *loc,
- dict_t *xdata)
-{
- gf_boolean_t data_selfheal = _gf_false;
- gf_boolean_t metadata_selfheal = _gf_false;
- gf_boolean_t entry_selfheal = _gf_false;
- dict_t *dict = NULL;
- int ret = -1;
- int op_errno = 0;
- inode_t *inode = NULL;
-
- ret = afr_selfheal_locked_inspect (frame, this, loc->gfid, &inode,
- &entry_selfheal,
- &data_selfheal, &metadata_selfheal);
-
- if (ret == -ENOMEM) {
- op_errno = -ret;
- ret = -1;
- goto out;
- }
-
- if (ret == -EIO) {
- dict = afr_set_heal_info ("split-brain");
- } else if (ret == -EAGAIN) {
- dict = afr_set_heal_info ("possibly-healing");
- } else if (ret >= 0) {
- /* value of ret = source index
- * so ret >= 0 and at least one of the 3 booleans set to
- * true means a source is identified; heal is required.
- */
-
- if (!data_selfheal && !entry_selfheal &&
- !metadata_selfheal) {
- dict = afr_set_heal_info ("no-heal");
- } else {
- dict = afr_set_heal_info ("heal");
- }
- } else if (ret < 0) {
- /* Apart from above checked -ve ret values, there are other
- * possible ret values like ENOTCONN (returned when number of
- * valid replies received are less than 2) in which case heal is
- * required when one of the selfheal booleans is set.
- */
- if (data_selfheal || entry_selfheal ||
- metadata_selfheal) {
- dict = afr_set_heal_info ("heal");
- }
- }
- ret = 0;
-
-out:
- AFR_STACK_UNWIND (getxattr, frame, ret, op_errno, dict, NULL);
- if (dict)
- dict_unref (dict);
- if (inode) {
- inode_forget (inode, 1);
- inode_unref (inode);
- }
- return ret;
-}
diff --git a/xlators/cluster/afr/src/afr-dir-read.c b/xlators/cluster/afr/src/afr-dir-read.c
index 11f583e42f1..4fac4775465 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>
- 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-2009 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/>.
*/
@@ -37,310 +46,790 @@
#include "checksum.h"
#include "afr.h"
-#include "afr-transaction.h"
+#include "afr-self-heal.h"
+
+
+int
+afr_examine_dir_sh_unwind (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;
+
+ afr_set_opendir_done (this, local->fd->inode);
+
+ AFR_STACK_UNWIND (opendir, frame, local->op_ret,
+ local->op_errno, local->fd);
+
+ return 0;
+}
+
+
+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;
+
+ cksum = checksum[0];
+
+ for (i = 0; i < child_count; i++) {
+ if (!child_up[i])
+ continue;
+
+ if (cksum != checksum[i]) {
+ ret = _gf_true;
+ break;
+ }
+
+ cksum = checksum[i];
+ }
+
+ return ret;
+}
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)
+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)
{
- afr_local_t *local = NULL;
- int call_count = -1;
- int32_t child_index = 0;
- afr_fd_ctx_t *fd_ctx = NULL;
+ 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;
+
+ int child_index = 0;
+
+ uint32_t entry_cksum;
+
+ int call_count = 0;
+ off_t last_offset = 0;
+
+ priv = this->private;
local = frame->local;
- fd_ctx = local->fd_ctx;
+ sh = &local->self_heal;
+
child_index = (long) cookie;
- LOCK (&frame->lock);
- {
- if (op_ret == -1) {
- local->op_errno = op_errno;
- fd_ctx->opened_on[child_index] = AFR_FD_NOT_OPENED;
- } else {
- local->op_ret = op_ret;
- fd_ctx->opened_on[child_index] = AFR_FD_OPENED;
- if (!local->xdata_rsp && xdata)
- local->xdata_rsp = dict_ref (xdata);
- }
+ if (op_ret == -1) {
+ local->op_ret = -1;
+ local->op_ret = op_errno;
+ goto out;
}
- UNLOCK (&frame->lock);
- call_count = afr_frame_return (frame);
+ if (op_ret == 0)
+ goto out;
+
+ list_for_each_entry_safe (entry, tmp, &entries->list, list) {
+ entry_cksum = gf_rsync_weak_checksum (entry->d_name,
+ strlen (entry->d_name));
+ local->cont.opendir.checksum[child_index] ^= entry_cksum;
+ }
+
+ list_for_each_entry (entry, &entries->list, list) {
+ last_offset = entry->d_off;
+ }
+
+ /* read more entries */
+
+ STACK_WIND_COOKIE (frame, afr_examine_dir_readdir_cbk,
+ (void *) (long) child_index,
+ priv->children[child_index],
+ priv->children[child_index]->fops->readdir,
+ local->fd, 131072, last_offset);
+
+out:
+ if ((op_ret == 0) || (op_ret == -1)) {
+ call_count = afr_frame_return (frame);
+
+ if (call_count == 0) {
+ if (__checksums_differ (local->cont.opendir.checksum,
+ priv->child_count,
+ local->child_up)) {
+
+ sh->need_entry_self_heal = _gf_true;
+ sh->forced_merge = _gf_true;
+ sh->mode = local->fd->inode->st_mode;
+ sh->background = _gf_false;
+ sh->unwind = afr_examine_dir_sh_unwind;
+
+ gf_log (this->name, GF_LOG_DEBUG,
+ "checksums of directory %s differ,"
+ " triggering forced merge",
+ local->loc.path);
+
+ afr_self_heal (frame, this);
+ } else {
+ afr_set_opendir_done (this, local->fd->inode);
+
+ AFR_STACK_UNWIND (opendir, frame, local->op_ret,
+ local->op_errno, local->fd);
+ }
+ }
+ }
- if (call_count == 0)
- AFR_STACK_UNWIND (opendir, frame, local->op_ret,
- local->op_errno, local->fd, NULL);
return 0;
}
int
-afr_opendir (call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd)
+afr_examine_dir (call_frame_t *frame, xlator_t *this)
{
- afr_private_t * priv = NULL;
- afr_local_t * local = NULL;
- int i = 0;
- int call_count = -1;
- int32_t op_errno = ENOMEM;
- afr_fd_ctx_t *fd_ctx = NULL;
-
- priv = this->private;
+ afr_private_t * priv = NULL;
+ afr_local_t * local = NULL;
- local = AFR_FRAME_INIT (frame, op_errno);
- if (!local)
- goto out;
+ int i;
+ int call_count = 0;
- fd_ctx = afr_fd_ctx_get (fd, this);
- if (!fd_ctx)
- goto out;
+ local = frame->local;
+ priv = this->private;
- loc_copy (&local->loc, loc);
+ local->cont.opendir.checksum = CALLOC (priv->child_count,
+ sizeof (*local->cont.opendir.checksum));
- local->fd = fd_ref (fd);
- local->fd_ctx = fd_ctx;
+ call_count = afr_up_children_count (priv->child_count, local->child_up);
- call_count = local->call_count;
+ local->call_count = call_count;
for (i = 0; i < priv->child_count; i++) {
if (local->child_up[i]) {
- STACK_WIND_COOKIE (frame, afr_opendir_cbk,
- (void*) (long) i,
+ STACK_WIND_COOKIE (frame, afr_examine_dir_readdir_cbk,
+ (void *) (long) i,
priv->children[i],
- priv->children[i]->fops->opendir,
- loc, fd, NULL);
+ priv->children[i]->fops->readdir,
+ local->fd, 131072, 0);
if (!--call_count)
break;
}
}
- return 0;
-out:
- AFR_STACK_UNWIND (opendir, frame, -1, op_errno, fd, NULL);
return 0;
}
-static int
-afr_validate_read_subvol (inode_t *inode, xlator_t *this, int par_read_subvol)
+
+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)
{
- int gen = 0;
- int entry_read_subvol = 0;
- unsigned char *data_readable = NULL;
- unsigned char *metadata_readable = NULL;
- afr_private_t *priv = NULL;
-
- priv = this->private;
- data_readable = alloca0 (priv->child_count);
- metadata_readable = alloca0 (priv->child_count);
-
- afr_inode_read_subvol_get (inode, this, data_readable,
- metadata_readable, &gen);
-
- if (gen != priv->event_generation ||
- !data_readable[par_read_subvol] ||
- !metadata_readable[par_read_subvol])
- return -1;
-
- /* Once the control reaches the following statement, it means that the
- * parent's read subvol is perfectly readable. So calling
- * either afr_data_subvol_get() or afr_metadata_subvol_get() would
- * yield the same result. Hence, choosing afr_data_subvol_get() below.
- */
-
- if (!priv->consistent_metadata)
- return 0;
-
- /* For an inode fetched through readdirp which is yet to be linked,
- * inode ctx would not be initialised (yet). So this function returns
- * -1 above due to gen being 0, which is why it is OK to pass NULL for
- * read_subvol_args here.
- */
- entry_read_subvol = afr_data_subvol_get (inode, this, 0, 0, NULL);
- if (entry_read_subvol != par_read_subvol)
- return -1;
+ afr_local_t * local = NULL;
- return 0;
+ int call_count = -1;
+ int ret = 0;
+
+ LOCK (&frame->lock);
+ {
+ local = frame->local;
+
+ if (op_ret >= 0)
+ local->op_ret = op_ret;
+
+ local->op_errno = op_errno;
+ }
+ UNLOCK (&frame->lock);
+
+ call_count = afr_frame_return (frame);
+
+ if (call_count == 0) {
+ if (local->op_ret == 0) {
+ ret = afr_fd_ctx_set (this, local->fd);
+
+ if (!afr_is_opendir_done (this, local->fd->inode)) {
+ /*
+ * This is the first opendir on this inode. We need
+ * to check if the directory's entries are the same
+ * on all subvolumes. This is needed in addition
+ * 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 anamolies).
+ */
+
+ gf_log (this->name, GF_LOG_TRACE,
+ "reading contents of directory %s looking for mismatch",
+ local->loc.path);
+
+ afr_examine_dir (frame, this);
+
+ } else {
+ AFR_STACK_UNWIND (opendir, frame, local->op_ret,
+ local->op_errno, local->fd);
+ }
+ } else {
+ AFR_STACK_UNWIND (opendir, frame, local->op_ret,
+ local->op_errno, local->fd);
+ }
+ }
+
+ return 0;
}
-static void
-afr_readdir_transform_entries (gf_dirent_t *subvol_entries, int subvol,
- gf_dirent_t *entries, fd_t *fd)
+
+int32_t
+afr_opendir (call_frame_t *frame, xlator_t *this,
+ loc_t *loc, fd_t *fd)
{
- int ret = -1;
- gf_dirent_t *entry = NULL;
- gf_dirent_t *tmp = NULL;
- xlator_t *this = NULL;
+ afr_private_t * priv = NULL;
+ afr_local_t * local = NULL;
- this = THIS;
+ int child_count = 0;
+ int i = 0;
- list_for_each_entry_safe (entry, tmp, &subvol_entries->list, list) {
- if (__is_root_gfid (fd->inode->gfid) &&
- !strcmp (entry->d_name, GF_REPLICATE_TRASH_DIR)) {
- continue;
- }
+ int ret = -1;
+ int call_count = -1;
- list_del_init (&entry->list);
- list_add_tail (&entry->list, &entries->list);
+ int32_t op_ret = -1;
+ int32_t op_errno = 0;
- if (entry->inode) {
- ret = afr_validate_read_subvol (entry->inode, this,
- subvol);
- if (ret == -1) {
- inode_unref (entry->inode);
- entry->inode = NULL;
- continue;
- }
+ VALIDATE_OR_GOTO (frame, out);
+ VALIDATE_OR_GOTO (this, out);
+ VALIDATE_OR_GOTO (this->private, out);
+
+ priv = this->private;
+
+ child_count = priv->child_count;
+
+ 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 (frame, afr_opendir_cbk,
+ priv->children[i],
+ priv->children[i]->fops->opendir,
+ loc, fd);
+
+ if (!--call_count)
+ break;
}
+ }
+
+ op_ret = 0;
+out:
+ if (op_ret == -1) {
+ AFR_STACK_UNWIND (opendir, frame, op_ret, op_errno, fd);
+ }
+
+ return 0;
+}
+
+
+/**
+ * Common algorithm for directory read calls:
+ *
+ * - Try the fop on the first child that is up
+ * - if we have failed due to ENOTCONN:
+ * try the next child
+ *
+ * Applicable to: readdir
+ */
+
+
+struct entry_name {
+ char *name;
+ struct list_head list;
+};
+
+
+static gf_boolean_t
+remembered_name (const char *name, struct list_head *entries)
+{
+ struct entry_name *e;
+ gf_boolean_t ret = _gf_false;
+
+ list_for_each_entry (e, entries, list) {
+ if (!strcmp (name, e->name)) {
+ ret = _gf_true;
+ goto out;
+ }
}
+
+out:
+ return ret;
}
-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 *subvol_entries,
- dict_t *xdata)
+static void
+afr_remember_entries (gf_dirent_t *entries, fd_t *fd)
{
- afr_local_t *local = NULL;
- gf_dirent_t entries;
+ struct entry_name *n = NULL;
+ gf_dirent_t * entry = NULL;
- INIT_LIST_HEAD (&entries.list);
+ int ret = 0;
- local = frame->local;
+ uint64_t ctx;
+ afr_fd_ctx_t *fd_ctx;
- if (op_ret < 0 && !local->cont.readdir.offset) {
- /* failover only if this was first readdir, detected
- by offset == 0 */
- local->op_ret = op_ret;
- local->op_errno = op_errno;
+ ret = fd_ctx_get (fd, THIS, &ctx);
+ if (ret < 0) {
+ gf_log (THIS->name, GF_LOG_DEBUG,
+ "could not get fd ctx for fd=%p", fd);
+ return;
+ }
+
+ fd_ctx = (afr_fd_ctx_t *)(long) ctx;
+
+ list_for_each_entry (entry, &entries->list, list) {
+ n = CALLOC (1, sizeof (*n));
+ n->name = strdup (entry->d_name);
+ INIT_LIST_HEAD (&n->list);
- afr_read_txn_continue (frame, this, (long) cookie);
- return 0;
+ list_add (&n->list, &fd_ctx->entries);
}
+}
+
- if (op_ret >= 0)
- afr_readdir_transform_entries (subvol_entries, (long) cookie,
- &entries, local->fd);
+static off_t
+afr_filter_entries (gf_dirent_t *entries, fd_t *fd)
+{
+ gf_dirent_t *entry, *tmp;
+ int ret = 0;
- AFR_STACK_UNWIND (readdir, frame, op_ret, op_errno, &entries, xdata);
+ uint64_t ctx;
+ afr_fd_ctx_t *fd_ctx;
- gf_dirent_free (&entries);
+ off_t offset = 0;
- return 0;
+ ret = fd_ctx_get (fd, THIS, &ctx);
+ if (ret < 0) {
+ gf_log (THIS->name, GF_LOG_DEBUG,
+ "could not get fd ctx for fd=%p", fd);
+ return -1;
+ }
+
+ fd_ctx = (afr_fd_ctx_t *)(long) ctx;
+
+ list_for_each_entry_safe (entry, tmp, &entries->list, list) {
+ offset = entry->d_off;
+
+ if (remembered_name (entry->d_name, &fd_ctx->entries)) {
+ list_del (&entry->list);
+ FREE (entry);
+ }
+ }
+
+ return offset;
}
-int
-afr_readdir_wind (call_frame_t *frame, xlator_t *this, int subvol)
+static void
+afr_forget_entries (fd_t *fd)
{
- afr_local_t *local = NULL;
- afr_private_t *priv = NULL;
- afr_fd_ctx_t *fd_ctx = NULL;
+ struct entry_name *entry, *tmp;
+ int ret = 0;
- priv = this->private;
- local = frame->local;
- fd_ctx = afr_fd_ctx_get (local->fd, this);
+ uint64_t ctx;
+ afr_fd_ctx_t *fd_ctx;
- if (subvol == -1) {
- AFR_STACK_UNWIND (readdir, frame, local->op_ret,
- local->op_errno, 0, 0);
- return 0;
+ ret = fd_ctx_get (fd, THIS, &ctx);
+ if (ret < 0) {
+ gf_log (THIS->name, GF_LOG_DEBUG,
+ "could not get fd ctx for fd=%p", fd);
+ return;
}
- fd_ctx->readdir_subvol = subvol;
+ fd_ctx = (afr_fd_ctx_t *)(long) ctx;
+
+ list_for_each_entry_safe (entry, tmp, &fd_ctx->entries, list) {
+ FREE (entry->name);
+ list_del (&entry->list);
+ FREE (entry);
+ }
+}
+
+
+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)
+{
+ afr_private_t * priv = NULL;
+ afr_local_t * local = NULL;
+ xlator_t ** children = NULL;
+
+ gf_dirent_t * entry = NULL;
+ gf_dirent_t * tmp = NULL;
+
+ int child_index = -1;
+
+ priv = this->private;
+ children = priv->children;
+
+ local = frame->local;
+
+ child_index = (long) cookie;
+
+ if (op_ret != -1) {
+ 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);
+ FREE (entry);
+ }
+ }
+ }
+
+ AFR_STACK_UNWIND (readdir, frame, op_ret, op_errno, entries);
- if (local->op == GF_FOP_READDIR)
- STACK_WIND_COOKIE (frame, afr_readdir_cbk,
- (void *) (long) subvol,
- priv->children[subvol],
- priv->children[subvol]->fops->readdir,
- local->fd, local->cont.readdir.size,
- local->cont.readdir.offset,
- local->xdata_req);
- else
- STACK_WIND_COOKIE (frame, afr_readdir_cbk,
- (void *) (long) subvol,
- priv->children[subvol],
- priv->children[subvol]->fops->readdirp,
- local->fd, local->cont.readdir.size,
- local->cont.readdir.offset,
- local->xdata_req);
return 0;
}
-int
-afr_do_readdir (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
- off_t offset, int whichop, dict_t *dict)
+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)
{
- afr_local_t *local = NULL;
- int32_t op_errno = 0;
- int subvol = -1;
- afr_fd_ctx_t *fd_ctx = NULL;
+ 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;
+ afr_fd_ctx_t *fd_ctx = NULL;
+
+ off_t offset = 0;
+
+ priv = this->private;
+ children = priv->children;
+
+ local = frame->local;
+
+ child_index = (long) cookie;
+
+ if (priv->strict_readdir) {
+ ret = fd_ctx_get (local->fd, this, &ctx);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "could not get fd ctx for fd=%p", local->fd);
+ op_ret = -1;
+ op_errno = -ret;
+ goto out;
+ }
+
+ fd_ctx = (afr_fd_ctx_t *)(long) ctx;
+
+ if (child_went_down (op_ret, op_errno)) {
+ if (all_tried (child_index, priv->child_count)) {
+ goto out;
+ }
+
+ call_child = ++child_index;
+
+ gf_log (this->name, GF_LOG_TRACE,
+ "starting readdir afresh on child %d, offset %"PRId64,
+ call_child, (uint64_t) 0);
+
+ fd_ctx->failed_over = _gf_true;
+
+ STACK_WIND_COOKIE (frame, afr_readdirp_cbk,
+ (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.st_ino,
+ priv->child_count, child_index);
+ entry->d_stat.st_ino = inum;
+
+ if ((local->fd->inode == local->fd->inode->table->root)
+ && !strcmp (entry->d_name, GF_REPLICATE_TRASH_DIR)) {
+ list_del_init (&entry->list);
+ FREE (entry);
+ }
+ }
+ }
+
+ if (priv->strict_readdir) {
+ if (fd_ctx->failed_over) {
+ if (list_empty (&entries->list)) {
+ goto out;
+ }
+
+ offset = afr_filter_entries (entries, local->fd);
+
+ afr_remember_entries (entries, local->fd);
+
+ if (list_empty (&entries->list)) {
+ /* All the entries we got were duplicate. We
+ shouldn't send an empty list now, because
+ 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[child_index]->name);
+
+ STACK_WIND_COOKIE (frame, afr_readdirp_cbk,
+ (void *) (long) child_index,
+ children[child_index],
+ children[child_index]->fops->readdirp,
+ local->fd, local->cont.readdir.size, offset);
+ return 0;
+ }
+ } else {
+ afr_remember_entries (entries, local->fd);
+ }
+ }
+
+out:
+ 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)
+{
+ afr_private_t * priv = NULL;
+ xlator_t ** children = NULL;
+ int call_child = 0;
+ afr_local_t *local = NULL;
+
+ uint64_t ctx;
+ afr_fd_ctx_t *fd_ctx;
+
+ int ret = -1;
+
+ int32_t op_ret = -1;
+ int32_t op_errno = 0;
+
+ VALIDATE_OR_GOTO (frame, out);
+ VALIDATE_OR_GOTO (this, out);
+ VALIDATE_OR_GOTO (this->private, out);
- local = AFR_FRAME_INIT (frame, op_errno);
- if (!local)
+ priv = this->private;
+ children = priv->children;
+
+ ALLOC_OR_GOTO (local, afr_local_t, out);
+ ret = AFR_LOCAL_INIT (local, priv);
+ if (ret < 0) {
+ op_errno = -ret;
goto out;
+ }
- fd_ctx = afr_fd_ctx_get (fd, this);
- if (!fd_ctx) {
- op_errno = EINVAL;
+ frame->local = local;
+
+ 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->fd = fd_ref (fd);
+ local->cont.readdir.size = size;
+
+ if (priv->strict_readdir) {
+ ret = fd_ctx_get (fd, this, &ctx);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "could not get fd ctx for fd=%p", fd);
+ op_errno = -ret;
+ goto out;
+ }
- local->op = whichop;
- local->fd = fd_ref (fd);
- local->cont.readdir.size = size;
- local->cont.readdir.offset = offset;
- local->xdata_req = (dict)? dict_ref (dict) : NULL;
-
- subvol = fd_ctx->readdir_subvol;
-
- if (offset == 0 || subvol == -1) {
- /* First readdir has option of failing over and selecting
- an appropriate read subvolume */
- afr_read_txn (frame, this, fd->inode, afr_readdir_wind,
- AFR_DATA_TRANSACTION);
- } else {
- /* But continued readdirs MUST stick to the same subvolume
- without an option to failover */
- afr_readdir_wind (frame, this, subvol);
+ fd_ctx = (afr_fd_ctx_t *)(long) ctx;
+
+ if (fd_ctx->last_tried != call_child) {
+ gf_log (this->name, GF_LOG_TRACE,
+ "first up child has changed from %d to %d, restarting readdir from offset 0",
+ fd_ctx->last_tried, call_child);
+
+ fd_ctx->failed_over = _gf_true;
+ offset = 0;
+ }
+
+ fd_ctx->last_tried = call_child;
}
- return 0;
+ if (whichop == GF_FOP_READDIR)
+ STACK_WIND_COOKIE (frame, afr_readdir_cbk,
+ (void *) (long) call_child,
+ children[call_child],
+ children[call_child]->fops->readdir, fd,
+ 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);
+
+ op_ret = 0;
out:
- AFR_STACK_UNWIND (readdir, frame, -1, op_errno, NULL, NULL);
- return 0;
+ 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;
}
+int32_t
+afr_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)
+{
+ 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;
+
+ priv = this->private;
+ children = priv->children;
+
+ local = frame->local;
+
+ if (op_ret == -1) {
+ last_tried = local->cont.getdents.last_tried;
+
+ if (all_tried (last_tried, priv->child_count)) {
+ goto out;
+ }
+
+ this_try = ++local->cont.getdents.last_tried;
+ unwind = 0;
+
+ STACK_WIND (frame, afr_getdents_cbk,
+ children[this_try],
+ children[this_try]->fops->getdents,
+ local->fd, local->cont.getdents.size,
+ local->cont.getdents.offset, local->cont.getdents.flag);
+ }
+
+out:
+ if (unwind) {
+ AFR_STACK_UNWIND (getdents, frame, op_ret, op_errno,
+ entry, count);
+ }
+
+ return 0;
+}
+
int32_t
afr_releasedir (xlator_t *this, fd_t *fd)
{
+ afr_forget_entries (fd);
afr_cleanup_fd_ctx (this, fd);
+ return 0;
+}
- return 0;
+
+int32_t
+afr_getdents (call_frame_t *frame, xlator_t *this,
+ fd_t *fd, size_t size, off_t offset, int32_t flag)
+{
+ 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;
+
+ VALIDATE_OR_GOTO (frame, out);
+ VALIDATE_OR_GOTO (this, out);
+ VALIDATE_OR_GOTO (this->private, out);
+
+ priv = this->private;
+ children = priv->children;
+
+ ALLOC_OR_GOTO (local, afr_local_t, out);
+
+ 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.getdents.last_tried = call_child;
+
+ local->fd = fd_ref (fd);
+
+ local->cont.getdents.size = size;
+ local->cont.getdents.offset = offset;
+ local->cont.getdents.flag = flag;
+
+ frame->local = local;
+
+ STACK_WIND (frame, afr_getdents_cbk,
+ children[call_child], children[call_child]->fops->getdents,
+ fd, size, offset, flag);
+
+ op_ret = 0;
+out:
+ if (op_ret == -1) {
+ AFR_STACK_UNWIND (getdents, frame, op_ret, op_errno,
+ NULL, 0);
+ }
+
+ return 0;
}
+
+
diff --git a/xlators/cluster/afr/src/afr-dir-read.h b/xlators/cluster/afr/src/afr-dir-read.h
index 09456d15949..abde2534de9 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-2009 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 __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 8bd7d47f89c..1d7d3f19557 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-2009 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 General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that 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/>.
*/
@@ -34,743 +43,817 @@
#include "common-utils.h"
#include "compat-errno.h"
#include "compat.h"
-#include "byte-order.h"
#include "afr.h"
#include "afr-transaction.h"
+
void
-afr_mark_entry_pending_changelog (call_frame_t *frame, xlator_t *this);
+afr_build_parent_loc (loc_t *parent, loc_t *child)
+{
+ char *tmp = NULL;
+
+ if (!child->parent) {
+ loc_copy (parent, child);
+ return;
+ }
+
+ tmp = strdup (child->path);
+ parent->path = strdup (dirname (tmp));
+ FREE (tmp);
+
+ parent->name = strrchr (parent->path, '/');
+ if (parent->name)
+ parent->name++;
+
+ parent->inode = inode_ref (child->parent);
+ parent->parent = inode_parent (parent->inode, 0, NULL);
+ parent->ino = parent->inode->ino;
+}
+
+/* {{{ create */
int
-afr_build_parent_loc (loc_t *parent, loc_t *child, int32_t *op_errno)
+afr_create_unwind (call_frame_t *frame, xlator_t *this)
{
- int ret = -1;
- char *child_path = NULL;
+ call_frame_t *main_frame = NULL;
+ afr_private_t * priv = NULL;
+ afr_local_t *local = NULL;
+ struct stat *unwind_buf = NULL;
- if (!child->parent) {
- if (op_errno)
- *op_errno = EINVAL;
- goto out;
- }
+ priv = this->private;
+ local = frame->local;
- child_path = gf_strdup (child->path);
- if (!child_path) {
- if (op_errno)
- *op_errno = ENOMEM;
- goto out;
- }
+ LOCK (&frame->lock);
+ {
+ if (local->transaction.main_frame) {
+ main_frame = local->transaction.main_frame;
+ }
+ local->transaction.main_frame = NULL;
+ }
+ UNLOCK (&frame->lock);
- parent->path = gf_strdup (dirname (child_path));
- if (!parent->path) {
- if (op_errno)
- *op_errno = ENOMEM;
- goto out;
+ if (main_frame) {
+ if (local->cont.create.read_child_buf.st_ino) {
+ unwind_buf = &local->cont.create.read_child_buf;
+ } else {
+ unwind_buf = &local->cont.create.buf;
+ }
+
+ unwind_buf->st_ino = local->cont.create.ino;
+ unwind_buf->st_dev = local->cont.create.gen;
+
+ local->cont.create.preparent.st_ino = local->cont.create.parent_ino;
+ local->cont.create.postparent.st_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);
}
+
+ return 0;
+}
- parent->inode = inode_ref (child->parent);
- uuid_copy (parent->gfid, child->pargfid);
- ret = 0;
-out:
- GF_FREE (child_path);
+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 stat *buf,
+ struct stat *preparent, struct stat *postparent)
+{
+ afr_local_t * local = NULL;
+ afr_private_t * priv = NULL;
+
+ uint64_t ctx;
+ afr_fd_ctx_t *fd_ctx;
+
+ int ret = 0;
+
+ int call_count = -1;
+ int child_index = -1;
+
+ local = frame->local;
+ priv = this->private;
+
+ child_index = (long) cookie;
+
+ LOCK (&frame->lock);
+ {
+ if (afr_fop_failed (op_ret, op_errno))
+ afr_transaction_fop_failed (frame, this, child_index);
+
+ if (op_ret != -1) {
+ local->op_ret = op_ret;
+
+ ret = afr_fd_ctx_set (this, fd);
+
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "could not set ctx on fd=%p", fd);
+
+ local->op_ret = -1;
+ local->op_errno = -ret;
+ }
+
+ ret = fd_ctx_get (fd, this, &ctx);
+
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "could not get fd ctx for fd=%p", fd);
+ local->op_ret = -1;
+ local->op_errno = -ret;
+ }
+
+ fd_ctx = (afr_fd_ctx_t *)(long) ctx;
+
+ fd_ctx->opened_on[child_index] = 1;
+ fd_ctx->flags = local->cont.create.flags;
+
+ if (local->success_count == 0) {
+ local->cont.create.buf = *buf;
+
+ local->cont.create.ino =
+ afr_itransform (buf->st_ino,
+ priv->child_count,
+ child_index);
+ local->cont.create.gen = buf->st_dev;
+
+ 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->st_ino,
+ priv->child_count,
+ local->first_up_child);
+ local->cont.create.gen = buf->st_dev;
+ }
+
+ if (child_index == local->read_child_index) {
+ local->cont.create.read_child_buf = *buf;
+ local->cont.create.preparent = *preparent;
+ local->cont.create.postparent = *postparent;
+ }
+
+ local->cont.create.inode = inode;
+
+ local->success_count++;
+ }
+
+ local->op_errno = op_errno;
+ }
+ UNLOCK (&frame->lock);
- return ret;
+ call_count = afr_frame_return (frame);
+
+ if (call_count == 0) {
+ local->transaction.unwind (frame, this);
+
+ local->transaction.resume (frame, this);
+ }
+
+ return 0;
}
-static void
-__afr_dir_write_finalize (call_frame_t *frame, xlator_t *this)
+int
+afr_create_wind (call_frame_t *frame, xlator_t *this)
{
afr_local_t *local = NULL;
afr_private_t *priv = NULL;
- int inode_read_subvol = -1;
- int parent_read_subvol = -1;
- int parent2_read_subvol = -1;
+
+ int call_count = -1;
int i = 0;
local = frame->local;
priv = this->private;
- if (local->inode) {
- afr_replies_interpret (frame, this, local->inode);
- inode_read_subvol = afr_data_subvol_get (local->inode, this,
- NULL, NULL, NULL);
- }
- if (local->parent)
- parent_read_subvol = afr_data_subvol_get (local->parent, this,
- NULL, NULL, NULL);
- if (local->parent2)
- parent2_read_subvol = afr_data_subvol_get (local->parent2, this,
- NULL, NULL, NULL);
-
- local->op_ret = -1;
- local->op_errno = afr_final_errno (local, priv);
-
- for (i = 0; i < priv->child_count; i++) {
- if (!local->replies[i].valid)
- continue;
- if (local->replies[i].op_ret < 0) {
- if (local->inode)
- afr_inode_read_subvol_reset (local->inode,
- this);
- if (local->parent)
- afr_inode_read_subvol_reset (local->parent,
- this);
- if (local->parent2)
- afr_inode_read_subvol_reset (local->parent2,
- this);
- continue;
- }
-
- if (local->op_ret == -1) {
- local->op_ret = local->replies[i].op_ret;
- local->op_errno = local->replies[i].op_errno;
-
- local->cont.dir_fop.buf =
- local->replies[i].poststat;
- local->cont.dir_fop.preparent =
- local->replies[i].preparent;
- local->cont.dir_fop.postparent =
- local->replies[i].postparent;
- local->cont.dir_fop.prenewparent =
- local->replies[i].preparent2;
- local->cont.dir_fop.postnewparent =
- local->replies[i].postparent2;
- if (local->replies[i].xdata)
- local->xdata_rsp =
- dict_ref (local->replies[i].xdata);
- continue;
- }
-
- if (i == inode_read_subvol) {
- local->cont.dir_fop.buf =
- local->replies[i].poststat;
- if (local->replies[i].xdata) {
- if (local->xdata_rsp)
- dict_unref (local->xdata_rsp);
- local->xdata_rsp =
- dict_ref (local->replies[i].xdata);
- }
- }
+ call_count = afr_up_children_count (priv->child_count, local->child_up);
- if (i == parent_read_subvol) {
- local->cont.dir_fop.preparent =
- local->replies[i].preparent;
- local->cont.dir_fop.postparent =
- local->replies[i].postparent;
- }
+ if (call_count == 0) {
+ local->transaction.resume (frame, this);
+ return 0;
+ }
- if (i == parent2_read_subvol) {
- local->cont.dir_fop.prenewparent =
- local->replies[i].preparent2;
- local->cont.dir_fop.postnewparent =
- local->replies[i].postparent2;
+ local->call_count = call_count;
+
+ for (i = 0; i < priv->child_count; i++) {
+ if (local->child_up[i]) {
+ STACK_WIND_COOKIE (frame, afr_create_wind_cbk,
+ (void *) (long) i,
+ priv->children[i],
+ priv->children[i]->fops->create,
+ &local->loc,
+ local->cont.create.flags,
+ local->cont.create.mode,
+ local->cont.create.fd);
+ if (!--call_count)
+ break;
}
}
+
+ return 0;
}
-static void
-__afr_dir_write_fill (call_frame_t *frame, xlator_t *this, int child_index,
- int op_ret, int op_errno, struct iatt *poststat,
- struct iatt *preparent, struct iatt *postparent,
- struct iatt *preparent2, struct iatt *postparent2,
- dict_t *xdata)
+int
+afr_create_done (call_frame_t *frame, xlator_t *this)
{
- afr_local_t *local = NULL;
- afr_fd_ctx_t *fd_ctx = NULL;
-
- local = frame->local;
- fd_ctx = local->fd_ctx;
-
- local->replies[child_index].valid = 1;
- local->replies[child_index].op_ret = op_ret;
- local->replies[child_index].op_errno = op_errno;
-
- if (op_ret >= 0) {
- if (poststat)
- local->replies[child_index].poststat = *poststat;
- if (preparent)
- local->replies[child_index].preparent = *preparent;
- if (postparent)
- local->replies[child_index].postparent = *postparent;
- if (preparent2)
- local->replies[child_index].preparent2 = *preparent2;
- if (postparent2)
- local->replies[child_index].postparent2 = *postparent2;
- if (xdata)
- local->replies[child_index].xdata = dict_ref (xdata);
-
- if (fd_ctx)
- fd_ctx->opened_on[child_index] = AFR_FD_OPENED;
- } else {
- if (op_errno != ENOTEMPTY)
- afr_transaction_fop_failed (frame, this, child_index);
- if (fd_ctx)
- fd_ctx->opened_on[child_index] = AFR_FD_NOT_OPENED;
- }
+ afr_local_t * local = NULL;
+
+ local = frame->local;
+
+ local->transaction.unwind (frame, this);
- return;
+ AFR_STACK_DESTROY (frame);
+
+ return 0;
}
-static int
-__afr_dir_write_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int op_ret, int op_errno, struct iatt *buf,
- struct iatt *preparent, struct iatt *postparent,
- struct iatt *preparent2, struct iatt *postparent2,
- dict_t *xdata)
+int
+afr_create (call_frame_t *frame, xlator_t *this,
+ loc_t *loc, int32_t flags, mode_t mode, fd_t *fd)
{
- afr_local_t *local = NULL;
- int child_index = (long) cookie;
- int call_count = -1;
+ afr_private_t * priv = NULL;
+ afr_local_t * local = NULL;
+ call_frame_t * transaction_frame = NULL;
- local = frame->local;
+ int ret = -1;
- LOCK (&frame->lock);
- {
- __afr_dir_write_fill (frame, this, child_index, op_ret,
- op_errno, buf, preparent, postparent,
- preparent2, postparent2, xdata);
+ 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;
+
+ transaction_frame = copy_frame (frame);
+ if (!transaction_frame) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory.");
+ goto out;
}
- UNLOCK (&frame->lock);
- call_count = afr_frame_return (frame);
- if (call_count == 0) {
- __afr_dir_write_finalize (frame, this);
+ ALLOC_OR_GOTO (local, afr_local_t, out);
- if (afr_txn_nothing_failed (frame, this))
- local->transaction.unwind (frame, this);
+ ret = AFR_LOCAL_INIT (local, priv);
+ if (ret < 0) {
+ op_errno = -ret;
+ goto out;
+ }
- afr_mark_entry_pending_changelog (frame, this);
+ transaction_frame->local = local;
- local->transaction.resume (frame, this);
+ loc_copy (&local->loc, loc);
+
+ LOCK (&priv->read_child_lock);
+ {
+ local->read_child_index = (++priv->read_child_rr)
+ % (priv->child_count);
}
+ UNLOCK (&priv->read_child_lock);
- return 0;
-}
+ local->cont.create.flags = flags;
+ local->cont.create.mode = mode;
+ local->cont.create.fd = fd_ref (fd);
+ if (loc->parent)
+ local->cont.create.parent_ino = loc->parent->ino;
-int
-afr_mark_new_entry_changelog_cbk (call_frame_t *frame, void *cookie,
- xlator_t *this, int op_ret, int op_errno,
- dict_t *xattr, dict_t *xdata)
-{
- int call_count = 0;
+ local->transaction.fop = afr_create_wind;
+ local->transaction.done = afr_create_done;
+ local->transaction.unwind = afr_create_unwind;
+
+ afr_build_parent_loc (&local->transaction.parent_loc, loc);
- call_count = afr_frame_return (frame);
+ local->transaction.main_frame = frame;
+ local->transaction.basename = AFR_BASENAME (loc->path);
- if (call_count == 0)
- AFR_STACK_DESTROY (frame);
+ afr_transaction (transaction_frame, this, AFR_ENTRY_TRANSACTION);
- return 0;
+ op_ret = 0;
+out:
+ if (op_ret == -1) {
+ if (transaction_frame)
+ AFR_STACK_DESTROY (transaction_frame);
+ AFR_STACK_UNWIND (create, frame, op_ret, op_errno,
+ NULL, NULL, NULL, NULL, NULL);
+ }
+
+ return 0;
}
+/* }}} */
+
+/* {{{ mknod */
-void
-afr_mark_new_entry_changelog (call_frame_t *frame, xlator_t *this)
+int
+afr_mknod_unwind (call_frame_t *frame, xlator_t *this)
{
- call_frame_t *new_frame = NULL;
- afr_local_t *local = NULL;
- afr_local_t *new_local = NULL;
- afr_private_t *priv = NULL;
- dict_t *xattr = NULL;
- int32_t **changelog = NULL;
- int i = 0;
- int op_errno = ENOMEM;
- unsigned char *pending = NULL;
- int call_count = 0;
-
- local = frame->local;
- priv = this->private;
-
- new_frame = copy_frame (frame);
- if (!new_frame)
- goto out;
-
- new_local = AFR_FRAME_INIT (new_frame, op_errno);
- if (!new_local)
- goto out;
+ call_frame_t *main_frame = NULL;
+ afr_local_t *local = NULL;
- xattr = dict_new ();
- if (!xattr)
- goto out;
+ struct stat *unwind_buf = NULL;
- pending = alloca0 (priv->child_count);
+ local = frame->local;
- for (i = 0; i < priv->child_count; i++) {
- if (local->transaction.pre_op[i] &&
- !local->transaction.failed_subvols[i]) {
- call_count ++;
- continue;
+ LOCK (&frame->lock);
+ {
+ if (local->transaction.main_frame) {
+ main_frame = local->transaction.main_frame;
}
- pending[i] = 1;
+ local->transaction.main_frame = NULL;
}
+ UNLOCK (&frame->lock);
- changelog = afr_mark_pending_changelog (priv, pending, xattr,
- local->cont.dir_fop.buf.ia_type);
- if (!changelog)
- goto out;
-
- new_local->pending = changelog;
- changelog = NULL;
- uuid_copy (new_local->loc.gfid, local->cont.dir_fop.buf.ia_gfid);
- new_local->loc.inode = inode_ref (local->inode);
+ if (main_frame) {
+ if (local->cont.mknod.read_child_buf.st_ino) {
+ unwind_buf = &local->cont.mknod.read_child_buf;
+ } else {
+ unwind_buf = &local->cont.mknod.buf;
+ }
- new_local->call_count = call_count;
+ unwind_buf->st_ino = local->cont.mknod.ino;
+ unwind_buf->st_dev = local->cont.mknod.gen;
- for (i = 0; i < priv->child_count; i++) {
- if (pending[i])
- continue;
+ local->cont.mknod.preparent.st_ino = local->cont.mknod.parent_ino;
+ local->cont.mknod.postparent.st_ino = local->cont.mknod.parent_ino;
- STACK_WIND_COOKIE (new_frame, afr_mark_new_entry_changelog_cbk,
- (void *) (long) i, priv->children[i],
- priv->children[i]->fops->xattrop,
- &new_local->loc, GF_XATTROP_ADD_ARRAY,
- xattr, NULL);
- if (!--call_count)
- break;
+ 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);
}
- new_frame = NULL;
-out:
- if (changelog)
- afr_matrix_cleanup (changelog, priv->child_count);
- if (new_frame)
- AFR_STACK_DESTROY (new_frame);
- if (xattr)
- dict_unref (xattr);
- return;
+ return 0;
}
-void
-afr_mark_entry_pending_changelog (call_frame_t *frame, xlator_t *this)
+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 stat *buf, struct stat *preparent,
+ struct stat *postparent)
{
- afr_local_t *local = NULL;
- afr_private_t *priv = NULL;
- int pre_op_count = 0;
- int failed_count = 0;
+ afr_local_t * local = NULL;
+ afr_private_t * priv = NULL;
- local = frame->local;
- priv = this->private;
+ int call_count = -1;
+ int child_index = -1;
- if (local->op_ret < 0)
- return;
+ local = frame->local;
+ priv = this->private;
- if (local->op != GF_FOP_CREATE && local->op != GF_FOP_MKNOD)
- return;
+ child_index = (long) cookie;
- pre_op_count = AFR_COUNT (local->transaction.pre_op, priv->child_count);
- failed_count = AFR_COUNT (local->transaction.failed_subvols,
- priv->child_count);
+ LOCK (&frame->lock);
+ {
+ if (afr_fop_failed (op_ret, op_errno))
+ afr_transaction_fop_failed (frame, this, child_index);
+
+ if (op_ret != -1) {
+ local->op_ret = op_ret;
+
+ if (local->success_count == 0){
+ local->cont.mknod.buf = *buf;
+ local->cont.mknod.ino =
+ afr_itransform (buf->st_ino,
+ priv->child_count,
+ child_index);
+ local->cont.mknod.gen = buf->st_dev;
+
+ 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 (pre_op_count == priv->child_count && !failed_count)
- return;
+ if (child_index == local->first_up_child) {
+ local->cont.mknod.ino =
+ afr_itransform (buf->st_ino,
+ priv->child_count,
+ local->first_up_child);
+ local->cont.mknod.gen = buf->st_dev;
+ }
+
+ if (child_index == local->read_child_index) {
+ local->cont.mknod.read_child_buf = *buf;
+ local->cont.mknod.preparent = *preparent;
+ local->cont.mknod.postparent = *postparent;
+ }
+
+ local->cont.mknod.inode = inode;
+
+ local->success_count++;
+ }
- afr_mark_new_entry_changelog (frame, this);
+ local->op_errno = op_errno;
+ }
+ UNLOCK (&frame->lock);
- return;
-}
+ call_count = afr_frame_return (frame);
+ if (call_count == 0) {
+ local->transaction.unwind (frame, this);
-/* {{{ create */
+ local->transaction.resume (frame, this);
+ }
+
+ return 0;
+}
-int
-afr_create_unwind (call_frame_t *frame, xlator_t *this)
+
+int32_t
+afr_mknod_wind (call_frame_t *frame, xlator_t *this)
{
- call_frame_t *main_frame = NULL;
- afr_local_t *local = NULL;
+ afr_local_t *local = NULL;
+ afr_private_t *priv = NULL;
+
+ int call_count = -1;
+ int i = 0;
- local = frame->local;
+ local = frame->local;
+ priv = this->private;
- main_frame = afr_transaction_detach_fop_frame (frame);
+ call_count = afr_up_children_count (priv->child_count, local->child_up);
- if (!main_frame)
+ if (call_count == 0) {
+ local->transaction.resume (frame, this);
return 0;
+ }
- AFR_STACK_UNWIND (create, main_frame, local->op_ret, local->op_errno,
- local->cont.create.fd, local->inode,
- &local->cont.dir_fop.buf,
- &local->cont.dir_fop.preparent,
- &local->cont.dir_fop.postparent, local->xdata_rsp);
- return 0;
+ local->call_count = call_count;
+
+ for (i = 0; i < priv->child_count; 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);
+ if (!--call_count)
+ break;
+ }
+ }
+
+ return 0;
}
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)
+afr_mknod_done (call_frame_t *frame, xlator_t *this)
{
- return __afr_dir_write_cbk (frame, cookie, this, op_ret, op_errno, buf,
- preparent, postparent, NULL, NULL, xdata);
-}
+ afr_local_t * local = NULL;
+ local = frame->local;
-int
-afr_create_wind (call_frame_t *frame, xlator_t *this, int subvol)
-{
- afr_local_t *local = NULL;
- afr_private_t *priv = NULL;
-
- local = frame->local;
- priv = this->private;
-
- STACK_WIND_COOKIE (frame, afr_create_wind_cbk, (void *) (long) subvol,
- priv->children[subvol],
- priv->children[subvol]->fops->create,
- &local->loc, local->cont.create.flags,
- local->cont.create.mode, local->umask,
- local->cont.create.fd, local->xdata_req);
- return 0;
+ local->transaction.unwind (frame, this);
+ AFR_STACK_DESTROY (frame);
+
+ return 0;
}
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 *xdata)
+afr_mknod (call_frame_t *frame, xlator_t *this,
+ loc_t *loc, mode_t mode, dev_t dev)
{
- afr_private_t *priv = NULL;
- afr_local_t *local = NULL;
- afr_internal_lock_t *int_lock = NULL;
- call_frame_t *transaction_frame = NULL;
- int ret = -1;
- int op_errno = ENOMEM;
+ afr_private_t * priv = NULL;
+ afr_local_t * local = NULL;
+ call_frame_t * transaction_frame = NULL;
- priv = this->private;
+ int ret = -1;
- transaction_frame = copy_frame (frame);
- if (!transaction_frame)
- goto out;
+ int op_ret = -1;
+ int op_errno = 0;
- local = AFR_FRAME_INIT (transaction_frame, op_errno);
- if (!local)
- goto out;
+ VALIDATE_OR_GOTO (frame, out);
+ VALIDATE_OR_GOTO (this, out);
+ VALIDATE_OR_GOTO (this->private, out);
- loc_copy (&local->loc, loc);
+ priv = this->private;
- local->fd_ctx = afr_fd_ctx_get (fd, this);
- if (!local->fd_ctx)
+ transaction_frame = copy_frame (frame);
+ if (!transaction_frame) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory.");
goto out;
+ }
- local->inode = inode_ref (loc->inode);
- local->parent = inode_ref (loc->parent);
+ ALLOC_OR_GOTO (local, afr_local_t, out);
- local->op = GF_FOP_CREATE;
- local->cont.create.flags = flags;
- local->cont.create.mode = mode;
- local->cont.create.fd = fd_ref (fd);
- local->umask = umask;
+ ret = AFR_LOCAL_INIT (local, priv);
+ if (ret < 0) {
+ op_errno = -ret;
+ goto out;
+ }
- if (xdata)
- local->xdata_req = dict_copy_with_ref (xdata, NULL);
- else
- local->xdata_req = dict_new ();
+ transaction_frame->local = local;
- if (!local->xdata_req)
- goto out;
+ loc_copy (&local->loc, loc);
- local->transaction.wind = afr_create_wind;
- local->transaction.fop = __afr_txn_write_fop;
- local->transaction.done = __afr_txn_write_done;
- local->transaction.unwind = afr_create_unwind;
-
- ret = afr_build_parent_loc (&local->transaction.parent_loc, loc,
- &op_errno);
- if (ret)
- goto out;
-
- local->transaction.main_frame = frame;
- local->transaction.basename = AFR_BASENAME (loc->path);
- int_lock = &local->internal_lock;
-
- int_lock->lockee_count = 0;
- ret = afr_init_entry_lockee (&int_lock->lockee[0], local,
- &local->transaction.parent_loc,
- local->transaction.basename,
- priv->child_count);
- if (ret)
- goto out;
-
- int_lock->lockee_count++;
- ret = afr_transaction (transaction_frame, this, AFR_ENTRY_TRANSACTION);
- if (ret < 0) {
- op_errno = -ret;
- goto out;
+ LOCK (&priv->read_child_lock);
+ {
+ local->read_child_index = (++priv->read_child_rr)
+ % (priv->child_count);
}
+ UNLOCK (&priv->read_child_lock);
- return 0;
-out:
- if (transaction_frame)
- AFR_STACK_DESTROY (transaction_frame);
+ local->cont.mknod.mode = mode;
+ local->cont.mknod.dev = dev;
- AFR_STACK_UNWIND (create, frame, -1, op_errno, NULL, NULL, NULL, NULL,
- NULL, NULL);
- return 0;
-}
+ 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;
-/* {{{ mknod */
+ afr_build_parent_loc (&local->transaction.parent_loc, loc);
-int
-afr_mknod_unwind (call_frame_t *frame, xlator_t *this)
-{
- call_frame_t *main_frame = NULL;
- afr_local_t *local = NULL;
+ local->transaction.main_frame = frame;
+ local->transaction.basename = AFR_BASENAME (loc->path);
- local = frame->local;
+ afr_transaction (transaction_frame, this, AFR_ENTRY_TRANSACTION);
- main_frame = afr_transaction_detach_fop_frame (frame);
- if (!main_frame)
- return 0;
+ op_ret = 0;
+out:
+ if (op_ret == -1) {
+ if (transaction_frame)
+ AFR_STACK_DESTROY (transaction_frame);
+ AFR_STACK_UNWIND (mknod, frame, op_ret, op_errno,
+ NULL, NULL, NULL, NULL);
+ }
- AFR_STACK_UNWIND (mknod, main_frame, local->op_ret, local->op_errno,
- local->inode, &local->cont.dir_fop.buf,
- &local->cont.dir_fop.preparent,
- &local->cont.dir_fop.postparent, local->xdata_rsp);
- return 0;
+ return 0;
}
+/* }}} */
-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)
-{
- return __afr_dir_write_cbk (frame, cookie, this, op_ret, op_errno, buf,
- preparent, postparent, NULL, NULL, xdata);
-}
+/* {{{ mkdir */
int
-afr_mknod_wind (call_frame_t *frame, xlator_t *this, int subvol)
+afr_mkdir_unwind (call_frame_t *frame, xlator_t *this)
{
- afr_local_t *local = NULL;
- afr_private_t *priv = NULL;
+ call_frame_t *main_frame = NULL;
+ afr_local_t *local = NULL;
- local = frame->local;
- priv = this->private;
+ struct stat *unwind_buf = 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) {
+ if (local->cont.mkdir.read_child_buf.st_ino) {
+ unwind_buf = &local->cont.mkdir.read_child_buf;
+ } else {
+ unwind_buf = &local->cont.mkdir.buf;
+ }
+
+ unwind_buf->st_ino = local->cont.mkdir.ino;
+ unwind_buf->st_dev = local->cont.mkdir.gen;
+
+ local->cont.mkdir.preparent.st_ino = local->cont.mkdir.parent_ino;
+ local->cont.mkdir.postparent.st_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);
+ }
- STACK_WIND_COOKIE (frame, afr_mknod_wind_cbk, (void *) (long) subvol,
- priv->children[subvol],
- priv->children[subvol]->fops->mknod,
- &local->loc, local->cont.mknod.mode,
- local->cont.mknod.dev, local->umask,
- local->xdata_req);
- return 0;
+ return 0;
}
+
int
-afr_mknod (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
- dev_t dev, mode_t umask, dict_t *xdata)
+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 stat *buf, struct stat *preparent,
+ struct stat *postparent)
{
- afr_private_t *priv = NULL;
- afr_local_t *local = NULL;
- afr_internal_lock_t *int_lock = NULL;
- call_frame_t *transaction_frame = NULL;
- int ret = -1;
- int op_errno = ENOMEM;
+ afr_local_t * local = NULL;
+ afr_private_t * priv = NULL;
- priv = this->private;
+ int call_count = -1;
+ int child_index = -1;
- transaction_frame = copy_frame (frame);
- if (!transaction_frame)
- goto out;
+ local = frame->local;
+ priv = this->private;
- local = AFR_FRAME_INIT (transaction_frame, op_errno);
- if (!local)
- goto out;
+ child_index = (long) cookie;
- loc_copy (&local->loc, loc);
- local->inode = inode_ref (loc->inode);
- local->parent = inode_ref (loc->parent);
+ LOCK (&frame->lock);
+ {
+ if (afr_fop_failed (op_ret, op_errno))
+ afr_transaction_fop_failed (frame, this, child_index);
- local->op = GF_FOP_MKNOD;
- local->cont.mknod.mode = mode;
- local->cont.mknod.dev = dev;
- local->umask = umask;
+ if (op_ret != -1) {
+ local->op_ret = op_ret;
+
+ if (local->success_count == 0) {
+ local->cont.mkdir.buf = *buf;
+
+ local->cont.mkdir.ino =
+ afr_itransform (buf->st_ino,
+ priv->child_count,
+ child_index);
+ local->cont.mkdir.gen = buf->st_dev;
+
+ 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 (xdata)
- local->xdata_req = dict_copy_with_ref (xdata, NULL);
- else
- local->xdata_req = dict_new ();
+ if (child_index == local->first_up_child) {
+ local->cont.mkdir.ino =
+ afr_itransform (buf->st_ino,
+ priv->child_count,
+ local->first_up_child);
+ local->cont.mkdir.gen = buf->st_dev;
+ }
+
+ if (child_index == local->read_child_index) {
+ local->cont.mkdir.read_child_buf = *buf;
+ local->cont.mkdir.preparent = *preparent;
+ local->cont.mkdir.postparent = *postparent;
+ }
+
+ local->cont.mkdir.inode = inode;
+
+ local->success_count++;
+ }
- if (!local->xdata_req)
- goto out;
+ local->op_errno = op_errno;
+ }
+ UNLOCK (&frame->lock);
- local->transaction.wind = afr_mknod_wind;
- local->transaction.fop = __afr_txn_write_fop;
- local->transaction.done = __afr_txn_write_done;
- local->transaction.unwind = afr_mknod_unwind;
-
- ret = afr_build_parent_loc (&local->transaction.parent_loc, loc,
- &op_errno);
- if (ret)
- goto out;
-
- local->transaction.main_frame = frame;
- local->transaction.basename = AFR_BASENAME (loc->path);
- int_lock = &local->internal_lock;
-
- int_lock->lockee_count = 0;
- ret = afr_init_entry_lockee (&int_lock->lockee[0], local,
- &local->transaction.parent_loc,
- local->transaction.basename,
- priv->child_count);
- if (ret)
- goto out;
-
- int_lock->lockee_count++;
- ret = afr_transaction (transaction_frame, this, AFR_ENTRY_TRANSACTION);
- if (ret < 0) {
- op_errno = -ret;
- goto out;
- }
+ call_count = afr_frame_return (frame);
- return 0;
-out:
- if (transaction_frame)
- AFR_STACK_DESTROY (transaction_frame);
+ if (call_count == 0) {
+ local->transaction.unwind (frame, this);
- AFR_STACK_UNWIND (mknod, frame, -1, op_errno, NULL, NULL, NULL, NULL,
- NULL);
- return 0;
+ local->transaction.resume (frame, this);
+ }
+
+ return 0;
}
-/* }}} */
-
-/* {{{ mkdir */
-
int
-afr_mkdir_unwind (call_frame_t *frame, xlator_t *this)
+afr_mkdir_wind (call_frame_t *frame, xlator_t *this)
{
- call_frame_t *main_frame = NULL;
- afr_local_t *local = NULL;
+ afr_local_t *local = NULL;
+ afr_private_t *priv = NULL;
+
+ int call_count = -1;
+ int i = 0;
+
+ local = frame->local;
+ priv = this->private;
- local = frame->local;
+ call_count = afr_up_children_count (priv->child_count, local->child_up);
- main_frame = afr_transaction_detach_fop_frame (frame);
- if (!main_frame)
+ if (call_count == 0) {
+ local->transaction.resume (frame, this);
return 0;
+ }
- AFR_STACK_UNWIND (mkdir, main_frame, local->op_ret, local->op_errno,
- local->inode, &local->cont.dir_fop.buf,
- &local->cont.dir_fop.preparent,
- &local->cont.dir_fop.postparent, local->xdata_rsp);
- return 0;
+ local->call_count = call_count;
+
+ for (i = 0; i < priv->child_count; 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);
+ if (!--call_count)
+ break;
+ }
+ }
+
+ return 0;
}
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)
+afr_mkdir_done (call_frame_t *frame, xlator_t *this)
{
- return __afr_dir_write_cbk (frame, cookie, this, op_ret, op_errno, buf,
- preparent, postparent, NULL, NULL, xdata);
-}
+ afr_local_t * local = NULL;
+ local = frame->local;
-int
-afr_mkdir_wind (call_frame_t *frame, xlator_t *this, int subvol)
-{
- afr_local_t *local = NULL;
- afr_private_t *priv = NULL;
+ local->transaction.unwind (frame, this);
- local = frame->local;
- priv = this->private;
+ AFR_STACK_DESTROY (frame);
- STACK_WIND_COOKIE (frame, afr_mkdir_wind_cbk, (void *) (long) subvol,
- priv->children[subvol],
- priv->children[subvol]->fops->mkdir, &local->loc,
- local->cont.mkdir.mode, local->umask,
- local->xdata_req);
- return 0;
+ return 0;
}
int
-afr_mkdir (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
- mode_t umask, dict_t *xdata)
+afr_mkdir (call_frame_t *frame, xlator_t *this,
+ loc_t *loc, mode_t mode)
{
- afr_private_t *priv = NULL;
- afr_local_t *local = NULL;
- afr_internal_lock_t *int_lock = NULL;
- call_frame_t *transaction_frame = NULL;
- int ret = -1;
- int op_errno = ENOMEM;
-
- priv = this->private;
+ afr_private_t * priv = NULL;
+ afr_local_t * local = NULL;
+ call_frame_t * transaction_frame = NULL;
- transaction_frame = copy_frame (frame);
- if (!transaction_frame)
- goto out;
+ int ret = -1;
- local = AFR_FRAME_INIT (transaction_frame, op_errno);
- if (!local)
- goto out;
-
- loc_copy (&local->loc, loc);
- local->inode = inode_ref (loc->inode);
- local->parent = inode_ref (loc->parent);
+ int op_ret = -1;
+ int op_errno = 0;
- local->cont.mkdir.mode = mode;
- local->umask = umask;
+ VALIDATE_OR_GOTO (frame, out);
+ VALIDATE_OR_GOTO (this, out);
+ VALIDATE_OR_GOTO (this->private, out);
- if (xdata)
- local->xdata_req = dict_copy_with_ref (xdata, NULL);
- else
- local->xdata_req = dict_new ();
+ priv = this->private;
- if (!local->xdata_req)
+ transaction_frame = copy_frame (frame);
+ if (!transaction_frame) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory.");
goto out;
+ }
+
+ ALLOC_OR_GOTO (local, afr_local_t, out);
- local->op = GF_FOP_MKDIR;
- local->transaction.wind = afr_mkdir_wind;
- local->transaction.fop = __afr_txn_write_fop;
- local->transaction.done = __afr_txn_write_done;
- local->transaction.unwind = afr_mkdir_unwind;
-
- ret = afr_build_parent_loc (&local->transaction.parent_loc, loc,
- &op_errno);
- if (ret)
- goto out;
-
- local->transaction.main_frame = frame;
- local->transaction.basename = AFR_BASENAME (loc->path);
- int_lock = &local->internal_lock;
-
- int_lock->lockee_count = 0;
- ret = afr_init_entry_lockee (&int_lock->lockee[0], local,
- &local->transaction.parent_loc,
- local->transaction.basename,
- priv->child_count);
- if (ret)
- goto out;
-
- int_lock->lockee_count++;
- ret = afr_transaction (transaction_frame, this, AFR_ENTRY_TRANSACTION);
- 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);
+
+ LOCK (&priv->read_child_lock);
+ {
+ local->read_child_index = (++priv->read_child_rr)
+ % (priv->child_count);
}
+ UNLOCK (&priv->read_child_lock);
- return 0;
+ local->cont.mkdir.mode = mode;
+
+ 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;
+
+ 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);
+
+ op_ret = 0;
out:
- if (transaction_frame)
- AFR_STACK_DESTROY (transaction_frame);
+ 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);
- return 0;
+ AFR_STACK_UNWIND (mkdir, frame, op_ret, op_errno,
+ NULL, NULL, NULL, NULL);
+ }
+
+ return 0;
}
/* }}} */
@@ -781,125 +864,233 @@ out:
int
afr_link_unwind (call_frame_t *frame, xlator_t *this)
{
- call_frame_t *main_frame = NULL;
- afr_local_t *local = NULL;
+ call_frame_t *main_frame = NULL;
+ afr_local_t *local = NULL;
- local = frame->local;
+ struct stat *unwind_buf = NULL;
- main_frame = afr_transaction_detach_fop_frame (frame);
- if (!main_frame)
- return 0;
+ 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) {
+ if (local->cont.link.read_child_buf.st_ino) {
+ unwind_buf = &local->cont.link.read_child_buf;
+ } else {
+ unwind_buf = &local->cont.link.buf;
+ }
+
+ unwind_buf->st_ino = local->cont.link.ino;
- AFR_STACK_UNWIND (link, main_frame, local->op_ret, local->op_errno,
- local->inode, &local->cont.dir_fop.buf,
- &local->cont.dir_fop.preparent,
- &local->cont.dir_fop.postparent, local->xdata_rsp);
- return 0;
+ local->cont.link.preparent.st_ino = local->cont.link.parent_ino;
+ local->cont.link.postparent.st_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);
+ }
+
+ return 0;
}
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)
+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 stat *buf, struct stat *preparent,
+ struct stat *postparent)
{
- return __afr_dir_write_cbk (frame, cookie, this, op_ret, op_errno, buf,
- preparent, postparent, NULL, NULL, xdata);
+ afr_local_t * local = NULL;
+ afr_private_t * priv = NULL;
+
+ int call_count = -1;
+ int child_index = -1;
+
+ local = frame->local;
+ priv = this->private;
+
+ child_index = (long) cookie;
+
+ LOCK (&frame->lock);
+ {
+ if (afr_fop_failed (op_ret, op_errno))
+ afr_transaction_fop_failed (frame, this, child_index);
+
+ 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) {
+ local->cont.link.read_child_buf = *buf;
+ local->cont.link.preparent = *preparent;
+ local->cont.link.postparent = *postparent;
+ }
+
+ local->cont.link.inode = inode;
+
+ local->success_count++;
+ }
+
+ local->op_errno = op_errno;
+ }
+ UNLOCK (&frame->lock);
+
+ call_count = afr_frame_return (frame);
+
+ if (call_count == 0) {
+ local->transaction.unwind (frame, this);
+
+ local->transaction.resume (frame, this);
+ }
+
+ return 0;
}
int
-afr_link_wind (call_frame_t *frame, xlator_t *this, int subvol)
+afr_link_wind (call_frame_t *frame, xlator_t *this)
{
- afr_local_t *local = NULL;
- afr_private_t *priv = NULL;
+ afr_local_t *local = NULL;
+ afr_private_t *priv = NULL;
- local = frame->local;
- priv = this->private;
+ int call_count = -1;
+ int i = 0;
- STACK_WIND_COOKIE (frame, afr_link_wind_cbk, (void *) (long) subvol,
- priv->children[subvol],
- priv->children[subvol]->fops->link,
- &local->loc, &local->newloc, local->xdata_req);
- return 0;
+ local = frame->local;
+ priv = this->private;
+
+ call_count = afr_up_children_count (priv->child_count, local->child_up);
+
+ 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->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);
+
+ if (!--call_count)
+ break;
+ }
+ }
+
+ return 0;
}
int
-afr_link (call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc,
- dict_t *xdata)
+afr_link_done (call_frame_t *frame, xlator_t *this)
{
- afr_private_t *priv = NULL;
- afr_local_t *local = NULL;
- afr_internal_lock_t *int_lock = NULL;
- call_frame_t *transaction_frame = NULL;
- int ret = -1;
- int op_errno = ENOMEM;
+ afr_local_t * local = frame->local;
- priv = this->private;
+ local->transaction.unwind (frame, this);
- transaction_frame = copy_frame (frame);
- if (!transaction_frame)
- goto out;
+ AFR_STACK_DESTROY (frame);
- local = AFR_FRAME_INIT (transaction_frame, op_errno);
- if (!local)
- goto out;
+ return 0;
+}
+
+
+int
+afr_link (call_frame_t *frame, xlator_t *this,
+ loc_t *oldloc, loc_t *newloc)
+{
+ afr_private_t * priv = NULL;
+ afr_local_t * local = NULL;
+ call_frame_t * transaction_frame = NULL;
- loc_copy (&local->loc, oldloc);
- loc_copy (&local->newloc, newloc);
+ int ret = -1;
- local->inode = inode_ref (oldloc->inode);
- local->parent = inode_ref (newloc->parent);
+ int op_ret = -1;
+ int op_errno = 0;
- if (xdata)
- local->xdata_req = dict_copy_with_ref (xdata, NULL);
- else
- local->xdata_req = dict_new ();
+ VALIDATE_OR_GOTO (frame, out);
+ VALIDATE_OR_GOTO (this, out);
+ VALIDATE_OR_GOTO (this->private, out);
- if (!local->xdata_req)
+ priv = this->private;
+
+ transaction_frame = copy_frame (frame);
+ if (!transaction_frame) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory.");
goto out;
+ }
- local->op = GF_FOP_LINK;
-
- local->transaction.wind = afr_link_wind;
- local->transaction.fop = __afr_txn_write_fop;
- local->transaction.done = __afr_txn_write_done;
- local->transaction.unwind = afr_link_unwind;
-
- ret = afr_build_parent_loc (&local->transaction.parent_loc, newloc,
- &op_errno);
- if (ret)
- goto out;
-
- local->transaction.main_frame = frame;
- local->transaction.basename = AFR_BASENAME (newloc->path);
- int_lock = &local->internal_lock;
-
- int_lock->lockee_count = 0;
- ret = afr_init_entry_lockee (&int_lock->lockee[0], local,
- &local->transaction.parent_loc,
- local->transaction.basename,
- priv->child_count);
- if (ret)
- goto out;
-
- int_lock->lockee_count++;
- ret = afr_transaction (transaction_frame, this, AFR_ENTRY_TRANSACTION);
- 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;
+ }
+
+ transaction_frame->local = local;
+
+ loc_copy (&local->loc, oldloc);
+ loc_copy (&local->newloc, newloc);
+
+ LOCK (&priv->read_child_lock);
+ {
+ local->read_child_index = (++priv->read_child_rr)
+ % (priv->child_count);
}
+ UNLOCK (&priv->read_child_lock);
- return 0;
+ local->cont.link.ino = oldloc->inode->ino;
+
+ if (oldloc->parent)
+ local->cont.link.parent_ino = oldloc->parent->ino;
+
+ local->transaction.fop = afr_link_wind;
+ local->transaction.done = afr_link_done;
+ local->transaction.unwind = afr_link_unwind;
+
+ afr_build_parent_loc (&local->transaction.parent_loc, oldloc);
+
+ local->transaction.main_frame = frame;
+ local->transaction.basename = AFR_BASENAME (oldloc->path);
+ local->transaction.new_basename = AFR_BASENAME (newloc->path);
+
+ afr_transaction (transaction_frame, this, AFR_ENTRY_TRANSACTION);
+
+ op_ret = 0;
out:
- if (transaction_frame)
- AFR_STACK_DESTROY (transaction_frame);
+ if (op_ret == -1) {
+ if (transaction_frame)
+ AFR_STACK_DESTROY (transaction_frame);
+ AFR_STACK_UNWIND (link, frame, op_ret, op_errno,
+ NULL, NULL, NULL, NULL);
+ }
- AFR_STACK_UNWIND (link, frame, -1, op_errno, NULL, NULL, NULL, NULL,
- NULL);
- return 0;
+ return 0;
}
/* }}} */
@@ -910,126 +1101,246 @@ out:
int
afr_symlink_unwind (call_frame_t *frame, xlator_t *this)
{
- call_frame_t *main_frame = NULL;
- afr_local_t *local = NULL;
+ call_frame_t *main_frame = NULL;
+ afr_local_t *local = NULL;
+
+ struct stat *unwind_buf = NULL;
+
+ local = frame->local;
- 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);
- main_frame = afr_transaction_detach_fop_frame (frame);
- if (!main_frame)
- return 0;
+ if (main_frame) {
+ if (local->cont.symlink.read_child_buf.st_ino) {
+ unwind_buf = &local->cont.symlink.read_child_buf;
+ } else {
+ unwind_buf = &local->cont.symlink.buf;
+ }
+
+ unwind_buf->st_ino = local->cont.symlink.ino;
+ unwind_buf->st_dev = local->cont.symlink.gen;
+
+ local->cont.symlink.preparent.st_ino = local->cont.symlink.parent_ino;
+ local->cont.symlink.postparent.st_ino = local->cont.symlink.parent_ino;
- AFR_STACK_UNWIND (symlink, main_frame, local->op_ret, local->op_errno,
- local->inode, &local->cont.dir_fop.buf,
- &local->cont.dir_fop.preparent,
- &local->cont.dir_fop.postparent, local->xdata_rsp);
- return 0;
+ 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);
+ }
+
+ return 0;
}
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)
+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 stat *buf, struct stat *preparent,
+ struct stat *postparent)
{
- return __afr_dir_write_cbk (frame, cookie, this, op_ret, op_errno, buf,
- preparent, postparent, NULL, NULL, xdata);
+ afr_local_t * local = NULL;
+ afr_private_t * priv = NULL;
+
+ int call_count = -1;
+ int child_index = -1;
+
+ local = frame->local;
+ priv = this->private;
+
+ child_index = (long) cookie;
+
+ LOCK (&frame->lock);
+ {
+ if (afr_fop_failed (op_ret, op_errno))
+ afr_transaction_fop_failed (frame, this, child_index);
+
+ if (op_ret != -1) {
+ local->op_ret = op_ret;
+
+ if (local->success_count == 0) {
+ local->cont.symlink.buf = *buf;
+ local->cont.symlink.ino =
+ afr_itransform (buf->st_ino, priv->child_count,
+ child_index);
+ local->cont.symlink.gen = buf->st_dev;
+
+ 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->st_ino,
+ priv->child_count,
+ local->first_up_child);
+ local->cont.symlink.gen = buf->st_dev;
+ }
+
+ if (child_index == local->read_child_index) {
+ local->cont.symlink.read_child_buf = *buf;
+ local->cont.symlink.preparent = *preparent;
+ local->cont.symlink.postparent = *postparent;
+ }
+
+ local->cont.symlink.inode = inode;
+
+ local->success_count++;
+ }
+
+ local->op_errno = op_errno;
+ }
+ UNLOCK (&frame->lock);
+
+ call_count = afr_frame_return (frame);
+
+ if (call_count == 0) {
+ local->transaction.unwind (frame, this);
+
+ local->transaction.resume (frame, this);
+ }
+
+ return 0;
}
int
-afr_symlink_wind (call_frame_t *frame, xlator_t *this, int subvol)
+afr_symlink_wind (call_frame_t *frame, xlator_t *this)
{
- afr_local_t *local = NULL;
- afr_private_t *priv = NULL;
-
- local = frame->local;
- priv = this->private;
-
- STACK_WIND_COOKIE (frame, afr_symlink_wind_cbk, (void *) (long) subvol,
- priv->children[subvol],
- priv->children[subvol]->fops->symlink,
- local->cont.symlink.linkpath, &local->loc,
- local->umask, local->xdata_req);
- return 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_up_children_count (priv->child_count, local->child_up);
+
+ 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->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);
+
+ if (!--call_count)
+ break;
+
+ }
+ }
+
+ return 0;
}
int
-afr_symlink (call_frame_t *frame, xlator_t *this, const char *linkpath,
- loc_t *loc, mode_t umask, dict_t *xdata)
+afr_symlink_done (call_frame_t *frame, xlator_t *this)
{
- afr_private_t *priv = NULL;
- afr_local_t *local = NULL;
- afr_internal_lock_t *int_lock = NULL;
- call_frame_t *transaction_frame = NULL;
- int ret = -1;
- int op_errno = ENOMEM;
+ afr_local_t * local = frame->local;
- priv = this->private;
+ local->transaction.unwind (frame, this);
- transaction_frame = copy_frame (frame);
- if (!transaction_frame)
- goto out;
+ AFR_STACK_DESTROY (frame);
+
+ return 0;
+}
- local = AFR_FRAME_INIT (transaction_frame, op_errno);
- if (!local)
- goto out;
- loc_copy (&local->loc, loc);
- local->inode = inode_ref (loc->inode);
- local->parent = inode_ref (loc->parent);
+int
+afr_symlink (call_frame_t *frame, xlator_t *this,
+ const char *linkpath, loc_t *loc)
+{
+ afr_private_t * priv = NULL;
+ afr_local_t * local = NULL;
+ call_frame_t * transaction_frame = NULL;
+
+ int ret = -1;
- local->cont.symlink.linkpath = gf_strdup (linkpath);
- local->umask = umask;
+ int op_ret = -1;
+ int op_errno = 0;
- if (xdata)
- local->xdata_req = dict_copy_with_ref (xdata, NULL);
- else
- local->xdata_req = dict_new ();
+ VALIDATE_OR_GOTO (frame, out);
+ VALIDATE_OR_GOTO (this, out);
+ VALIDATE_OR_GOTO (this->private, out);
- if (!local->xdata_req)
+ priv = this->private;
+
+ transaction_frame = copy_frame (frame);
+ if (!transaction_frame) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory.");
goto out;
+ }
- local->op = GF_FOP_SYMLINK;
- local->transaction.wind = afr_symlink_wind;
- local->transaction.fop = __afr_txn_write_fop;
- local->transaction.done = __afr_txn_write_done;
- local->transaction.unwind = afr_symlink_unwind;
-
- ret = afr_build_parent_loc (&local->transaction.parent_loc, loc,
- &op_errno);
- if (ret)
- goto out;
-
- local->transaction.main_frame = frame;
- local->transaction.basename = AFR_BASENAME (loc->path);
- int_lock = &local->internal_lock;
-
- int_lock->lockee_count = 0;
- ret = afr_init_entry_lockee (&int_lock->lockee[0], local,
- &local->transaction.parent_loc,
- local->transaction.basename,
- priv->child_count);
- if (ret)
- goto out;
-
- int_lock->lockee_count++;
- ret = afr_transaction (transaction_frame, this, AFR_ENTRY_TRANSACTION);
- 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;
+ }
+
+ transaction_frame->local = local;
+
+ loc_copy (&local->loc, loc);
+
+ LOCK (&priv->read_child_lock);
+ {
+ local->read_child_index = (++priv->read_child_rr)
+ % (priv->child_count);
}
+ UNLOCK (&priv->read_child_lock);
- return 0;
+ local->cont.symlink.linkpath = strdup (linkpath);
+
+ 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;
+
+ 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);
+
+ op_ret = 0;
out:
- if (transaction_frame)
- AFR_STACK_DESTROY (transaction_frame);
+ if (op_ret == -1) {
+ if (transaction_frame)
+ AFR_STACK_DESTROY (transaction_frame);
+ AFR_STACK_UNWIND (symlink, frame, op_ret, op_errno,
+ NULL, NULL, NULL, NULL);
+ }
- AFR_STACK_UNWIND (symlink, frame, -1, op_errno, NULL, NULL, NULL,
- NULL, NULL);
- return 0;
+ return 0;
}
/* }}} */
@@ -1039,157 +1350,231 @@ out:
int
afr_rename_unwind (call_frame_t *frame, xlator_t *this)
{
- call_frame_t *main_frame = NULL;
- afr_local_t *local = NULL;
+ call_frame_t *main_frame = NULL;
+ afr_local_t *local = NULL;
- local = frame->local;
+ struct stat *unwind_buf = NULL;
- main_frame = afr_transaction_detach_fop_frame (frame);
- if (!main_frame)
- return 0;
+ local = frame->local;
- AFR_STACK_UNWIND (rename, main_frame, local->op_ret, local->op_errno,
- &local->cont.dir_fop.buf,
- &local->cont.dir_fop.preparent,
- &local->cont.dir_fop.postparent,
- &local->cont.dir_fop.prenewparent,
- &local->cont.dir_fop.postnewparent, local->xdata_rsp);
- return 0;
+ 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) {
+ if (local->cont.rename.read_child_buf.st_ino) {
+ unwind_buf = &local->cont.rename.read_child_buf;
+ } else {
+ unwind_buf = &local->cont.rename.buf;
+ }
+
+ unwind_buf->st_ino = local->cont.rename.ino;
+
+ local->cont.rename.preoldparent.st_ino = local->cont.rename.oldparent_ino;
+ local->cont.rename.postoldparent.st_ino = local->cont.rename.oldparent_ino;
+ local->cont.rename.prenewparent.st_ino = local->cont.rename.newparent_ino;
+ local->cont.rename.postnewparent.st_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);
+ }
+
+ return 0;
}
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)
+afr_rename_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct stat *buf,
+ struct stat *preoldparent, struct stat *postoldparent,
+ struct stat *prenewparent, struct stat *postnewparent)
{
- return __afr_dir_write_cbk (frame, cookie, this, op_ret, op_errno, buf,
- preoldparent, postoldparent, prenewparent,
- postnewparent, xdata);
+ afr_local_t * local = NULL;
+ afr_private_t * priv = NULL;
+
+ int call_count = -1;
+ int child_index = -1;
+
+ local = frame->local;
+ priv = this->private;
+
+ child_index = (long) cookie;
+
+ LOCK (&frame->lock);
+ {
+ if (afr_fop_failed (op_ret, op_errno))
+ afr_transaction_fop_failed (frame, this, child_index);
+
+ if (op_ret != -1) {
+ if (local->success_count == 0) {
+ local->op_ret = op_ret;
+
+ if (buf) {
+ local->cont.rename.buf = *buf;
+ }
+
+ local->success_count++;
+ }
+
+ if (child_index == local->read_child_index) {
+ local->cont.rename.read_child_buf = *buf;
+
+ local->cont.rename.preoldparent = *preoldparent;
+ local->cont.rename.postoldparent = *postoldparent;
+ local->cont.rename.prenewparent = *prenewparent;
+ local->cont.rename.postnewparent = *postnewparent;
+ }
+ }
+
+ local->op_errno = op_errno;
+ }
+ UNLOCK (&frame->lock);
+
+ call_count = afr_frame_return (frame);
+
+ if (call_count == 0) {
+ local->transaction.unwind (frame, this);
+
+ local->transaction.resume (frame, this);
+ }
+
+ return 0;
}
-int
-afr_rename_wind (call_frame_t *frame, xlator_t *this, int subvol)
+int32_t
+afr_rename_wind (call_frame_t *frame, xlator_t *this)
{
- afr_local_t *local = NULL;
- afr_private_t *priv = NULL;
+ afr_local_t *local = NULL;
+ afr_private_t *priv = NULL;
+
+ int call_count = -1;
+ int i = 0;
local = frame->local;
priv = this->private;
- STACK_WIND_COOKIE (frame, afr_rename_wind_cbk, (void *) (long) subvol,
- priv->children[subvol],
- priv->children[subvol]->fops->rename,
- &local->loc, &local->newloc, local->xdata_req);
- return 0;
+ call_count = afr_up_children_count (priv->child_count, local->child_up);
+
+ 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->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);
+ if (!--call_count)
+ break;
+ }
+ }
+
+ return 0;
+}
+
+
+int
+afr_rename_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_rename (call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc,
- dict_t *xdata)
+afr_rename (call_frame_t *frame, xlator_t *this,
+ loc_t *oldloc, loc_t *newloc)
{
- afr_private_t *priv = NULL;
- afr_local_t *local = NULL;
- afr_internal_lock_t *int_lock = NULL;
- call_frame_t *transaction_frame = NULL;
- int ret = -1;
- int op_errno = ENOMEM;
- int nlockee = 0;
-
- priv = this->private;
-
- transaction_frame = copy_frame (frame);
- if (!transaction_frame)
- op_errno = ENOMEM;
-
- local = AFR_FRAME_INIT (transaction_frame, op_errno);
- if (!local)
- goto out;
+ afr_private_t * priv = NULL;
+ afr_local_t * local = NULL;
+ call_frame_t * transaction_frame = NULL;
- loc_copy (&local->loc, oldloc);
- loc_copy (&local->newloc, newloc);
+ int ret = -1;
- local->inode = inode_ref (oldloc->inode);
- local->parent = inode_ref (oldloc->parent);
- local->parent2 = inode_ref (newloc->parent);
+ int op_ret = -1;
+ int op_errno = 0;
- if (xdata)
- local->xdata_req = dict_copy_with_ref (xdata, NULL);
- else
- local->xdata_req = dict_new ();
+ VALIDATE_OR_GOTO (frame, out);
+ VALIDATE_OR_GOTO (this, out);
+ VALIDATE_OR_GOTO (this->private, out);
- if (!local->xdata_req)
+ priv = this->private;
+
+ transaction_frame = copy_frame (frame);
+ if (!transaction_frame) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory.");
goto out;
+ }
- local->op = GF_FOP_RENAME;
- local->transaction.wind = afr_rename_wind;
- local->transaction.fop = __afr_txn_write_fop;
- local->transaction.done = __afr_txn_write_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;
-
- local->transaction.main_frame = frame;
- local->transaction.basename = AFR_BASENAME (oldloc->path);
- local->transaction.new_basename = AFR_BASENAME (newloc->path);
- int_lock = &local->internal_lock;
-
- int_lock->lockee_count = nlockee = 0;
- ret = afr_init_entry_lockee (&int_lock->lockee[nlockee], local,
- &local->transaction.new_parent_loc,
- local->transaction.new_basename,
- priv->child_count);
- if (ret)
- goto out;
-
- nlockee++;
- ret = afr_init_entry_lockee (&int_lock->lockee[nlockee], local,
- &local->transaction.parent_loc,
- local->transaction.basename,
- priv->child_count);
- if (ret)
- goto out;
-
- nlockee++;
- if (local->newloc.inode && IA_ISDIR (local->newloc.inode->ia_type)) {
- ret = afr_init_entry_lockee (&int_lock->lockee[nlockee], local,
- &local->newloc,
- NULL,
- priv->child_count);
- if (ret)
- goto out;
-
- nlockee++;
- }
- qsort (int_lock->lockee, nlockee, sizeof (*int_lock->lockee),
- afr_entry_lockee_cmp);
- int_lock->lockee_count = nlockee;
+ ALLOC_OR_GOTO (local, afr_local_t, out);
- ret = afr_transaction (transaction_frame, this, AFR_ENTRY_RENAME_TRANSACTION);
- if (ret < 0) {
+ ret = AFR_LOCAL_INIT (local, priv);
+ if (ret < 0) {
op_errno = -ret;
goto out;
- }
+ }
- return 0;
+ transaction_frame->local = local;
+
+ loc_copy (&local->loc, oldloc);
+ loc_copy (&local->newloc, newloc);
+
+ 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;
+
+ 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);
+ local->transaction.new_basename = AFR_BASENAME (newloc->path);
+
+ afr_transaction (transaction_frame, this, AFR_ENTRY_RENAME_TRANSACTION);
+
+ op_ret = 0;
out:
- if (transaction_frame)
- AFR_STACK_DESTROY (transaction_frame);
+ 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);
- return 0;
+ AFR_STACK_UNWIND (rename, frame, op_ret, op_errno,
+ NULL, NULL, NULL, NULL, NULL);
+ }
+
+ return 0;
}
/* }}} */
@@ -1199,121 +1584,210 @@ out:
int
afr_unlink_unwind (call_frame_t *frame, xlator_t *this)
{
- call_frame_t *main_frame = NULL;
- afr_local_t *local = NULL;
+ call_frame_t *main_frame = NULL;
+ afr_local_t *local = NULL;
- local = frame->local;
+ local = frame->local;
- main_frame = afr_transaction_detach_fop_frame (frame);
- if (!main_frame)
- return 0;
+ 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) {
+ local->cont.unlink.preparent.st_ino = local->cont.unlink.parent_ino;
+ local->cont.unlink.postparent.st_ino = local->cont.unlink.parent_ino;
- AFR_STACK_UNWIND (unlink, main_frame, local->op_ret, local->op_errno,
- &local->cont.dir_fop.preparent,
- &local->cont.dir_fop.postparent, local->xdata_rsp);
- return 0;
+ AFR_STACK_UNWIND (unlink, main_frame,
+ local->op_ret, local->op_errno,
+ &local->cont.unlink.preparent,
+ &local->cont.unlink.postparent);
+ }
+
+ return 0;
}
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)
+afr_unlink_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct stat *preparent,
+ struct stat *postparent)
{
- return __afr_dir_write_cbk (frame, cookie, this, op_ret, op_errno, NULL,
- preparent, postparent, NULL, NULL, xdata);
+ afr_local_t * local = NULL;
+ afr_private_t * priv = NULL;
+
+ int call_count = -1;
+ int child_index = (long) cookie;
+ int need_unwind = 0;
+ int read_child = 0;
+
+ local = frame->local;
+ priv = this->private;
+
+ read_child = afr_read_child (this, local->loc.inode);
+
+ LOCK (&frame->lock);
+ {
+ if (child_index == local->read_child_index) {
+ local->read_child_returned = _gf_true;
+ }
+
+ if (afr_fop_failed (op_ret, op_errno))
+ afr_transaction_fop_failed (frame, this, child_index);
+
+ if (op_ret != -1) {
+ if (local->success_count == 0) {
+ local->op_ret = op_ret;
+ local->cont.unlink.preparent = *preparent;
+ local->cont.unlink.postparent = *postparent;
+ }
+
+ if (child_index == local->read_child_index) {
+ local->cont.unlink.preparent = *preparent;
+ local->cont.unlink.postparent = *postparent;
+ }
+
+ local->success_count++;
+
+ if ((local->success_count == priv->wait_count)
+ && local->read_child_returned) {
+ need_unwind = 1;
+ }
+ }
+
+ local->op_errno = op_errno;
+ }
+ UNLOCK (&frame->lock);
+
+ call_count = afr_frame_return (frame);
+
+ if (call_count == 0) {
+ local->transaction.unwind (frame, this);
+
+ local->transaction.resume (frame, this);
+ }
+
+ return 0;
}
-int
-afr_unlink_wind (call_frame_t *frame, xlator_t *this, int subvol)
+int32_t
+afr_unlink_wind (call_frame_t *frame, xlator_t *this)
{
- afr_local_t *local = NULL;
- afr_private_t *priv = NULL;
+ afr_local_t *local = NULL;
+ afr_private_t *priv = NULL;
- local = frame->local;
- priv = this->private;
+ int call_count = -1;
+ int i = 0;
+
+ local = frame->local;
+ priv = this->private;
- STACK_WIND_COOKIE (frame, afr_unlink_wind_cbk, (void *) (long) subvol,
- priv->children[subvol],
- priv->children[subvol]->fops->unlink,
- &local->loc, local->xflag, local->xdata_req);
- return 0;
+ call_count = afr_up_children_count (priv->child_count, local->child_up);
+
+ 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->child_up[i]) {
+ STACK_WIND_COOKIE (frame, afr_unlink_wind_cbk,
+ (void *) (long) i,
+ priv->children[i],
+ priv->children[i]->fops->unlink,
+ &local->loc);
+
+ if (!--call_count)
+ break;
+ }
+ }
+
+ return 0;
}
-int
-afr_unlink (call_frame_t *frame, xlator_t *this, loc_t *loc, int xflag,
- dict_t *xdata)
+int32_t
+afr_unlink_done (call_frame_t *frame, xlator_t *this)
{
- afr_private_t *priv = NULL;
- afr_local_t *local = NULL;
- afr_internal_lock_t *int_lock = NULL;
- call_frame_t *transaction_frame = NULL;
- int ret = -1;
- int op_errno = ENOMEM;
+ afr_local_t * local = frame->local;
- priv = this->private;
+ local->transaction.unwind (frame, this);
- transaction_frame = copy_frame (frame);
- if (!transaction_frame)
- goto out;
+ AFR_STACK_DESTROY (frame);
+
+ return 0;
+}
- local = AFR_FRAME_INIT (transaction_frame, op_errno);
- if (!local)
- goto out;
- loc_copy (&local->loc, loc);
- local->xflag = xflag;
+int32_t
+afr_unlink (call_frame_t *frame, xlator_t *this,
+ loc_t *loc)
+{
+ afr_private_t * priv = NULL;
+ afr_local_t * local = NULL;
+ call_frame_t * transaction_frame = NULL;
+
+ int ret = -1;
- local->inode = inode_ref (loc->inode);
- local->parent = inode_ref (loc->parent);
+ int op_ret = -1;
+ int op_errno = 0;
- if (xdata)
- local->xdata_req = dict_copy_with_ref (xdata, NULL);
- else
- local->xdata_req = dict_new ();
+ VALIDATE_OR_GOTO (frame, out);
+ VALIDATE_OR_GOTO (this, out);
+ VALIDATE_OR_GOTO (this->private, out);
- if (!local->xdata_req)
+ priv = this->private;
+
+ transaction_frame = copy_frame (frame);
+ if (!transaction_frame) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory.");
goto out;
+ }
- local->op = GF_FOP_UNLINK;
- local->transaction.wind = afr_unlink_wind;
- local->transaction.fop = __afr_txn_write_fop;
- local->transaction.done = __afr_txn_write_done;
- local->transaction.unwind = afr_unlink_unwind;
-
- ret = afr_build_parent_loc (&local->transaction.parent_loc, loc,
- &op_errno);
- if (ret)
- goto out;
-
- local->transaction.main_frame = frame;
- local->transaction.basename = AFR_BASENAME (loc->path);
- int_lock = &local->internal_lock;
-
- int_lock->lockee_count = 0;
- ret = afr_init_entry_lockee (&int_lock->lockee[0], local,
- &local->transaction.parent_loc,
- local->transaction.basename,
- priv->child_count);
- if (ret)
- goto out;
-
- int_lock->lockee_count++;
- ret = afr_transaction (transaction_frame, this, AFR_ENTRY_TRANSACTION);
- 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;
- }
+ }
- return 0;
+ transaction_frame->local = local;
+
+ loc_copy (&local->loc, loc);
+
+ 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;
+
+ 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);
+
+ op_ret = 0;
out:
- if (transaction_frame)
- AFR_STACK_DESTROY (transaction_frame);
+ if (op_ret == -1) {
+ if (transaction_frame)
+ AFR_STACK_DESTROY (transaction_frame);
+ AFR_STACK_UNWIND (unlink, frame, op_ret, op_errno,
+ NULL, NULL);
+ }
- AFR_STACK_UNWIND (unlink, frame, -1, op_errno, NULL, NULL, NULL);
- return 0;
+ return 0;
}
/* }}} */
@@ -1325,135 +1799,352 @@ out:
int
afr_rmdir_unwind (call_frame_t *frame, xlator_t *this)
{
- call_frame_t *main_frame = NULL;
- afr_local_t *local = NULL;
+ call_frame_t *main_frame = NULL;
+ afr_local_t *local = NULL;
- local = frame->local;
+ local = frame->local;
- main_frame = afr_transaction_detach_fop_frame (frame);
- if (!main_frame)
- return 0;
+ 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) {
+ local->cont.rmdir.preparent.st_ino = local->cont.rmdir.parent_ino;
+ local->cont.rmdir.postparent.st_ino = local->cont.rmdir.parent_ino;
- AFR_STACK_UNWIND (rmdir, main_frame, local->op_ret, local->op_errno,
- &local->cont.dir_fop.preparent,
- &local->cont.dir_fop.postparent, local->xdata_rsp);
- return 0;
+ AFR_STACK_UNWIND (rmdir, main_frame,
+ local->op_ret, local->op_errno,
+ &local->cont.rmdir.preparent,
+ &local->cont.rmdir.postparent);
+ }
+
+ return 0;
}
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)
+afr_rmdir_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct stat *preparent,
+ struct stat *postparent)
{
- return __afr_dir_write_cbk (frame, cookie, this, op_ret, op_errno, NULL,
- preparent, postparent, NULL, NULL, xdata);
+ afr_local_t * local = NULL;
+ afr_private_t * priv = NULL;
+
+ int call_count = -1;
+ int child_index = (long) cookie;
+ int need_unwind = 0;
+ int read_child = 0;
+
+ local = frame->local;
+ priv = this->private;
+
+ read_child = afr_read_child (this, local->loc.inode);
+
+ LOCK (&frame->lock);
+ {
+ if (child_index == read_child) {
+ local->read_child_returned = _gf_true;
+ }
+
+ if (afr_fop_failed (op_ret, op_errno) && (op_errno != ENOTEMPTY))
+ afr_transaction_fop_failed (frame, this, child_index);
+
+ if (op_ret != -1) {
+ if (local->success_count == 0) {
+ local->op_ret = op_ret;
+ local->cont.rmdir.preparent = *preparent;
+ local->cont.rmdir.postparent = *postparent;
+
+ }
+
+ if (child_index == read_child) {
+ local->cont.rmdir.preparent = *preparent;
+ local->cont.rmdir.postparent = *postparent;
+ }
+
+ local->success_count++;
+
+ if ((local->success_count == priv->wait_count)
+ && local->read_child_returned)
+ need_unwind = 1;
+ }
+
+ local->op_errno = op_errno;
+ }
+ UNLOCK (&frame->lock);
+
+ call_count = afr_frame_return (frame);
+
+ if (call_count == 0) {
+ local->transaction.unwind (frame, this);
+
+ local->transaction.resume (frame, this);
+ }
+
+ return 0;
}
int
-afr_rmdir_wind (call_frame_t *frame, xlator_t *this, int subvol)
+afr_rmdir_wind (call_frame_t *frame, xlator_t *this)
{
- afr_local_t *local = NULL;
- afr_private_t *priv = NULL;
+ afr_local_t *local = NULL;
+ afr_private_t *priv = NULL;
- local = frame->local;
- priv = this->private;
+ int call_count = -1;
+ int i = 0;
+
+ local = frame->local;
+ priv = this->private;
+
+ call_count = afr_up_children_count (priv->child_count, local->child_up);
+
+ 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->child_up[i]) {
+ STACK_WIND_COOKIE (frame, afr_rmdir_wind_cbk,
+ (void *) (long) i,
+ priv->children[i],
+ priv->children[i]->fops->rmdir,
+ &local->loc);
- STACK_WIND_COOKIE (frame, afr_rmdir_wind_cbk, (void *) (long) subvol,
- priv->children[subvol],
- priv->children[subvol]->fops->rmdir,
- &local->loc, local->cont.rmdir.flags, local->xdata_req);
- return 0;
+ if (!--call_count)
+ break;
+ }
+ }
+
+ return 0;
}
int
-afr_rmdir (call_frame_t *frame, xlator_t *this, loc_t *loc, int flags,
- dict_t *xdata)
+afr_rmdir_done (call_frame_t *frame, xlator_t *this)
{
- afr_private_t *priv = NULL;
- afr_local_t *local = NULL;
- afr_internal_lock_t *int_lock = NULL;
- call_frame_t *transaction_frame = NULL;
- int ret = -1;
- int op_errno = ENOMEM;
- int nlockee = 0;
-
- priv = this->private;
-
- transaction_frame = copy_frame (frame);
- if (!transaction_frame)
- goto out;
-
- local = AFR_FRAME_INIT (transaction_frame, op_errno);
- if (!local)
- goto out;
+ afr_local_t * local = frame->local;
+
+ local->transaction.unwind (frame, this);
+ AFR_STACK_DESTROY (frame);
+
+ return 0;
+}
+
+
+int
+afr_rmdir (call_frame_t *frame, xlator_t *this,
+ loc_t *loc)
+{
+ afr_private_t * priv = NULL;
+ afr_local_t * local = NULL;
+ call_frame_t * transaction_frame = NULL;
+
+ int ret = -1;
- loc_copy (&local->loc, loc);
- local->inode = inode_ref (loc->inode);
- local->parent = inode_ref (loc->parent);
+ int op_ret = -1;
+ int op_errno = 0;
- local->cont.rmdir.flags = flags;
+ VALIDATE_OR_GOTO (frame, out);
+ VALIDATE_OR_GOTO (this, out);
+ VALIDATE_OR_GOTO (this->private, out);
- if (xdata)
- local->xdata_req = dict_copy_with_ref (xdata, NULL);
- else
- local->xdata_req = dict_new ();
+ priv = this->private;
- if (!local->xdata_req)
+ transaction_frame = copy_frame (frame);
+ if (!transaction_frame) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory.");
goto out;
+ }
- local->op = GF_FOP_RMDIR;
- local->transaction.wind = afr_rmdir_wind;
- local->transaction.fop = __afr_txn_write_fop;
- local->transaction.done = __afr_txn_write_done;
- local->transaction.unwind = afr_rmdir_unwind;
-
- ret = afr_build_parent_loc (&local->transaction.parent_loc, loc,
- &op_errno);
- if (ret)
- goto out;
-
- local->transaction.main_frame = frame;
- local->transaction.basename = AFR_BASENAME (loc->path);
- int_lock = &local->internal_lock;
-
- int_lock->lockee_count = nlockee = 0;
- ret = afr_init_entry_lockee (&int_lock->lockee[nlockee], local,
- &local->transaction.parent_loc,
- local->transaction.basename,
- priv->child_count);
- if (ret)
- goto out;
-
- nlockee++;
- ret = afr_init_entry_lockee (&int_lock->lockee[nlockee], local,
- &local->loc,
- NULL,
- priv->child_count);
- if (ret)
- goto out;
-
- nlockee++;
- qsort (int_lock->lockee, nlockee, sizeof (*int_lock->lockee),
- afr_entry_lockee_cmp);
- int_lock->lockee_count = nlockee;
-
- ret = afr_transaction (transaction_frame, this, AFR_ENTRY_TRANSACTION);
- 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;
- }
+ }
+
+ transaction_frame->local = local;
+
+ 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;
+
+ 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);
+
+ op_ret = 0;
+out:
+ if (op_ret == -1) {
+ if (transaction_frame)
+ AFR_STACK_DESTROY (transaction_frame);
+ AFR_STACK_UNWIND (rmdir, frame, op_ret, op_errno,
+ NULL, NULL);
+ }
return 0;
+}
+
+/* }}} */
+
+/* {{{ setdents */
+
+int32_t
+afr_setdents_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno)
+{
+ 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);
+ {
+ if (afr_fop_failed (op_ret, op_errno))
+ afr_transaction_fop_failed (frame, this, child_index);
+
+ if ((op_ret != -1) && (local->success_count == 0)) {
+ local->op_ret = op_ret;
+ local->success_count++;
+ }
+
+ local->op_errno = op_errno;
+ }
+ UNLOCK (&frame->lock);
+
+ call_count = afr_frame_return (frame);
+
+ if (call_count == 0) {
+ local->transaction.resume (frame, this);
+ }
+
+ return 0;
+}
+
+
+int32_t
+afr_setdents_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_up_children_count (priv->child_count, local->child_up);
+
+ 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->child_up[i]) {
+ STACK_WIND_COOKIE (frame, afr_setdents_wind_cbk,
+ (void *) (long) i,
+ priv->children[i],
+ priv->children[i]->fops->setdents,
+ local->fd, local->cont.setdents.flags,
+ local->cont.setdents.entries,
+ local->cont.setdents.count);
+
+ if (!--call_count)
+ break;
+ }
+ }
+
+ return 0;
+}
+
+
+int32_t
+afr_setdents_done (call_frame_t *frame, xlator_t *this)
+{
+ afr_local_t * local = frame->local;
+
+ AFR_STACK_UNWIND (setdents, frame, local->op_ret, local->op_errno);
+
+ return 0;
+}
+
+
+int32_t
+afr_setdents (call_frame_t *frame, xlator_t *this,
+ fd_t *fd, int32_t flags, dir_entry_t *entries, int32_t count)
+{
+ afr_private_t * priv = NULL;
+ afr_local_t * local = 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);
+
+ 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;
+ }
+
+ frame->local = local;
+
+ local->fd = fd_ref (fd);
+
+ local->cont.setdents.flags = flags;
+ local->cont.setdents.entries = entries;
+ local->cont.setdents.count = count;
+
+ local->transaction.fop = afr_setdents_wind;
+ local->transaction.done = afr_setdents_done;
+
+ local->transaction.basename = NULL;
+
+ afr_transaction (frame, this, AFR_ENTRY_TRANSACTION);
+
+ op_ret = 0;
out:
- if (transaction_frame)
- AFR_STACK_DESTROY (transaction_frame);
+ if (op_ret == -1) {
+ AFR_STACK_UNWIND (setdents, frame, op_ret, op_errno);
+ }
- AFR_STACK_UNWIND (rmdir, frame, -1, op_errno, NULL, NULL, NULL);
- return 0;
+ return 0;
}
/* }}} */
diff --git a/xlators/cluster/afr/src/afr-dir-write.h b/xlators/cluster/afr/src/afr-dir-write.h
index 02f0a3682d9..4fa618b6575 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-2009 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 __DIR_WRITE_H__
@@ -13,35 +22,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);
+ loc_t *loc, int32_t flags, mode_t mode, fd_t *fd);
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);
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);
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);
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
+int32_t
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);
+
+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 3c178c20fd5..3b89da9abdb 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>
- 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-2009 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/>.
*/
@@ -30,384 +39,258 @@
#include "stack.h"
#include "list.h"
#include "call-stub.h"
-#include "byte-order.h"
#include "defaults.h"
#include "common-utils.h"
#include "compat-errno.h"
#include "compat.h"
-#include "afr-transaction.h"
-
-/*
- * Quota size xattrs are not maintained by afr. There is a
- * possibility that they differ even when both the directory changelog xattrs
- * suggest everything is fine. So if there is at least one 'source' check among
- * the sources which has the maximum quota size. Otherwise check among all the
- * available ones for maximum quota size. This way if there is a source and
- * stale copies it always votes for the 'source'.
- * */
-
-int
-afr_handle_quota_size (call_frame_t *frame, xlator_t *this)
-{
- unsigned char *readable = NULL;
- afr_local_t *local = NULL;
- afr_private_t *priv = NULL;
- struct afr_reply *replies = NULL;
- int i = 0;
- uint64_t size = 0;
- uint64_t max_size = 0;
- int readable_cnt = 0;
- int read_subvol = -1;
-
- local = frame->local;
- priv = this->private;
- replies = local->replies;
-
- readable = alloca0 (priv->child_count);
-
- afr_inode_read_subvol_get (local->inode, this, readable, 0, 0);
-
- readable_cnt = AFR_COUNT (readable, priv->child_count);
-
- for (i = 0; i < priv->child_count; i++) {
- if (!replies[i].valid || replies[i].op_ret == -1)
- continue;
- if (readable_cnt && !readable[i])
- continue;
- if (!replies[i].xdata)
- continue;
- if (dict_get_uint64 (replies[i].xdata, QUOTA_SIZE_KEY, &size))
- continue;
- size = ntoh64 (size);
- if (read_subvol == -1)
- read_subvol = i;
- if (size > max_size) {
- read_subvol = i;
- max_size = size;
- }
- }
-
- if (!max_size)
- return read_subvol;
-
- max_size = hton64 (max_size);
-
- for (i = 0; i < priv->child_count; i++) {
- if (!replies[i].valid || replies[i].op_ret == -1)
- continue;
- if (readable_cnt && !readable[i])
- continue;
- if (!replies[i].xdata)
- continue;
- if (dict_set_uint64 (replies[i].xdata, QUOTA_SIZE_KEY, max_size))
- continue;
- }
+#include "afr.h"
- return read_subvol;
-}
+/**
+ * Common algorithm for inode read calls:
+ *
+ * - Try the fop on the first child that is up
+ * - if we have failed due to ENOTCONN:
+ * try the next child
+ *
+ * Applicable to: access, stat, fstat, readlink, getxattr
+ */
/* {{{ access */
-int
-afr_access_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int op_ret, int op_errno, dict_t *xdata)
+int32_t
+afr_access_cbk (call_frame_t *frame, void *cookie,
+ xlator_t *this, int32_t op_ret, int32_t op_errno)
{
- afr_local_t *local = NULL;
+ afr_private_t * priv = NULL;
+ afr_local_t * local = NULL;
+ xlator_t ** children = NULL;
- local = frame->local;
+ int unwind = 1;
+ int last_tried = -1;
+ int this_try = -1;
+ int read_child = -1;
- if (op_ret < 0) {
- local->op_ret = op_ret;
- local->op_errno = op_errno;
-
- afr_read_txn_continue (frame, this, (long) cookie);
- return 0;
- }
-
- AFR_STACK_UNWIND (access, frame, op_ret, op_errno, xdata);
-
- return 0;
-}
+ priv = this->private;
+ children = priv->children;
-
-int
-afr_access_wind (call_frame_t *frame, xlator_t *this, int subvol)
-{
- afr_private_t *priv = NULL;
- afr_local_t *local = NULL;
-
- priv = this->private;
local = frame->local;
- if (subvol == -1) {
- AFR_STACK_UNWIND (access, frame, local->op_ret,
- local->op_errno, 0);
- return 0;
- }
+ read_child = (long) cookie;
- STACK_WIND_COOKIE (frame, afr_access_cbk, (void *) (long) subvol,
- priv->children[subvol],
- priv->children[subvol]->fops->access,
- &local->loc, local->cont.access.mask,
- local->xdata_req);
- return 0;
-}
+ if (op_ret == -1) {
+ retry:
+ last_tried = local->cont.access.last_tried;
-int
-afr_access (call_frame_t *frame, xlator_t *this, loc_t *loc,
- int mask, dict_t *xdata)
-{
- afr_local_t *local = NULL;
- int op_errno = 0;
+ if (all_tried (last_tried, priv->child_count)) {
+ goto out;
+ }
+ this_try = ++local->cont.access.last_tried;
- local = AFR_FRAME_INIT (frame, op_errno);
- if (!local)
- goto out;
+ if (this_try == read_child) {
+ goto retry;
+ }
- local->op = GF_FOP_ACCESS;
- loc_copy (&local->loc, loc);
- local->cont.access.mask = mask;
- if (xdata)
- local->xdata_req = dict_ref (xdata);
+ unwind = 0;
- afr_read_txn (frame, this, loc->inode, afr_access_wind,
- AFR_METADATA_TRANSACTION);
+ STACK_WIND_COOKIE (frame, afr_access_cbk,
+ (void *) (long) read_child,
+ children[this_try],
+ children[this_try]->fops->access,
+ &local->loc, local->cont.access.mask);
+ }
- return 0;
out:
- AFR_STACK_UNWIND (access, frame, -1, op_errno, NULL);
+ if (unwind) {
+ AFR_STACK_UNWIND (access, frame, op_ret, op_errno);
+ }
- return 0;
+ return 0;
}
-/* }}} */
-
-/* {{{ stat */
-int
-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)
+int32_t
+afr_access (call_frame_t *frame, xlator_t *this,
+ loc_t *loc, int32_t mask)
{
- afr_local_t *local = NULL;
+ afr_private_t * priv = NULL;
+ xlator_t ** children = NULL;
+ int call_child = 0;
+ afr_local_t *local = NULL;
- local = frame->local;
+ int32_t read_child = -1;
- if (op_ret < 0) {
- local->op_ret = op_ret;
- local->op_errno = op_errno;
- afr_read_txn_continue (frame, this, (long) cookie);
- return 0;
- }
+ int32_t op_ret = -1;
+ int32_t op_errno = 0;
- AFR_STACK_UNWIND (stat, frame, op_ret, op_errno, buf, xdata);
+ VALIDATE_OR_GOTO (frame, out);
+ VALIDATE_OR_GOTO (this, out);
+ VALIDATE_OR_GOTO (this->private, out);
- return 0;
-}
+ priv = this->private;
+ VALIDATE_OR_GOTO (priv->children, out);
+ children = priv->children;
-int
-afr_stat_wind (call_frame_t *frame, xlator_t *this, int subvol)
-{
- afr_private_t *priv = NULL;
- afr_local_t *local = NULL;
+ ALLOC_OR_GOTO (local, afr_local_t, out);
- priv = this->private;
- local = frame->local;
+ read_child = afr_read_child (this, loc->inode);
- if (subvol == -1) {
- AFR_STACK_UNWIND (stat, frame, local->op_ret, local->op_errno,
- 0, 0);
- return 0;
- }
+ if (read_child >= 0) {
+ call_child = read_child;
- STACK_WIND_COOKIE (frame, afr_stat_cbk, (void *) (long) subvol,
- priv->children[subvol],
- priv->children[subvol]->fops->stat,
- &local->loc, local->xdata_req);
- return 0;
-}
+ local->cont.access.last_tried = -1;
-int
-afr_stat (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
-{
- afr_local_t *local = NULL;
- int op_errno = 0;
+ } 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 = AFR_FRAME_INIT (frame, op_errno);
- if (!local)
- goto out;
+ local->cont.access.last_tried = call_child;
+ }
- local->op = GF_FOP_STAT;
loc_copy (&local->loc, loc);
- if (xdata)
- local->xdata_req = dict_ref (xdata);
+ local->cont.access.mask = mask;
- afr_read_txn (frame, this, loc->inode, afr_stat_wind,
- AFR_DATA_TRANSACTION);
+ STACK_WIND_COOKIE (frame, afr_access_cbk,
+ (void *) (long) call_child,
+ children[call_child], children[call_child]->fops->access,
+ loc, mask);
- return 0;
+ op_ret = 0;
out:
- AFR_STACK_UNWIND (stat, frame, -1, op_errno, NULL, NULL);
-
- return 0;
+ if (op_ret == -1) {
+ AFR_STACK_UNWIND (access, frame, op_ret, op_errno);
+ }
+ return 0;
}
/* }}} */
-/* {{{ fstat */
+/* {{{ stat */
-int
-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
+afr_stat_cbk (call_frame_t *frame, void *cookie,
+ xlator_t *this, int32_t op_ret, int32_t op_errno,
+ struct stat *buf)
{
- afr_local_t *local = NULL;
+ afr_private_t * priv = NULL;
+ afr_local_t * local = NULL;
+ xlator_t ** children = NULL;
- local = frame->local;
+ int unwind = 1;
+ int last_tried = -1;
+ int this_try = -1;
+ int read_child = -1;
- if (op_ret < 0) {
- local->op_ret = op_ret;
- local->op_errno = op_errno;
+ priv = this->private;
+ children = priv->children;
- afr_read_txn_continue (frame, this, (long) cookie);
- return 0;
- }
+ read_child = (long) cookie;
- AFR_STACK_UNWIND (fstat, frame, op_ret, op_errno, buf, xdata);
+ local = frame->local;
- return 0;
-}
+ if (op_ret == -1) {
+ retry:
+ last_tried = local->cont.stat.last_tried;
+
+ if (all_tried (last_tried, priv->child_count)) {
+ goto out;
+ }
+ this_try = ++local->cont.stat.last_tried;
+ if (this_try == read_child) {
+ goto retry;
+ }
-int
-afr_fstat_wind (call_frame_t *frame, xlator_t *this, int subvol)
-{
- afr_private_t *priv = NULL;
- afr_local_t *local = NULL;
+ unwind = 0;
- priv = this->private;
- local = frame->local;
+ STACK_WIND_COOKIE (frame, afr_stat_cbk,
+ (void *) (long) read_child,
+ children[this_try],
+ children[this_try]->fops->stat,
+ &local->loc);
+ }
- if (subvol == -1) {
- AFR_STACK_UNWIND (fstat, frame, local->op_ret, local->op_errno,
- 0, 0);
- return 0;
+out:
+ if (unwind) {
+ if (buf)
+ buf->st_ino = local->cont.stat.ino;
+
+ AFR_STACK_UNWIND (stat, frame, op_ret, op_errno, buf);
}
- STACK_WIND_COOKIE (frame, afr_fstat_cbk, (void *) (long) subvol,
- priv->children[subvol],
- priv->children[subvol]->fops->fstat,
- local->fd, local->xdata_req);
return 0;
}
int32_t
-afr_fstat (call_frame_t *frame, xlator_t *this,
- fd_t *fd, dict_t *xdata)
+afr_stat (call_frame_t *frame, xlator_t *this,
+ loc_t *loc)
{
- afr_local_t *local = NULL;
- int op_errno = 0;
+ afr_private_t * priv = NULL;
+ afr_local_t * local = NULL;
+ xlator_t ** children = NULL;
- local = AFR_FRAME_INIT (frame, op_errno);
- if (!local)
- goto out;
+ int32_t read_child = -1;
+ int call_child = 0;
- local->op = GF_FOP_FSTAT;
- local->fd = fd_ref (fd);
- if (xdata)
- local->xdata_req = dict_ref (xdata);
+ int32_t op_ret = -1;
+ int32_t op_errno = 0;
- afr_fix_open (fd, this);
+ VALIDATE_OR_GOTO (frame, out);
+ VALIDATE_OR_GOTO (this, out);
+ VALIDATE_OR_GOTO (this->private, out);
- afr_read_txn (frame, this, fd->inode, afr_fstat_wind,
- AFR_DATA_TRANSACTION);
+ priv = this->private;
+ VALIDATE_OR_GOTO (priv->children, out);
- return 0;
-out:
- AFR_STACK_UNWIND (fstat, frame, -1, op_errno, NULL, NULL);
+ children = priv->children;
- return 0;
-}
+ ALLOC_OR_GOTO (local, afr_local_t, out);
-/* }}} */
-
-/* {{{ readlink */
+ frame->local = local;
-int
-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)
-{
- afr_local_t *local = NULL;
-
- local = frame->local;
+ read_child = afr_read_child (this, loc->inode);
- if (op_ret < 0) {
- local->op_ret = -1;
- local->op_errno = op_errno;
+ if (read_child >= 0) {
+ call_child = read_child;
- afr_read_txn_continue (frame, this, (long) cookie);
- return 0;
- }
-
- AFR_STACK_UNWIND (readlink, frame, op_ret, op_errno,
- buf, sbuf, xdata);
- return 0;
-}
-
-int
-afr_readlink_wind (call_frame_t *frame, xlator_t *this, int subvol)
-{
- afr_local_t *local = NULL;
- afr_private_t *priv = NULL;
+ local->cont.stat.last_tried = -1;
- local = frame->local;
- priv = this->private;
+ } 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;
+ }
- if (subvol == -1) {
- AFR_STACK_UNWIND (readlink, frame, local->op_ret,
- local->op_errno, 0, 0, 0);
- return 0;
+ local->cont.stat.last_tried = call_child;
}
- STACK_WIND_COOKIE (frame, afr_readlink_cbk, (void *) (long) subvol,
- priv->children[subvol],
- priv->children[subvol]->fops->readlink,
- &local->loc, local->cont.readlink.size,
- local->xdata_req);
- return 0;
-}
-
-
-int
-afr_readlink (call_frame_t *frame, xlator_t *this,
- loc_t *loc, size_t size, dict_t *xdata)
-{
- afr_local_t * local = NULL;
- int32_t op_errno = 0;
-
- local = AFR_FRAME_INIT (frame, op_errno);
- if (!local)
- goto out;
+ loc_copy (&local->loc, loc);
- local->op = GF_FOP_READLINK;
- loc_copy (&local->loc, loc);
- local->cont.readlink.size = size;
- if (xdata)
- local->xdata_req = dict_ref (xdata);
+ local->cont.stat.ino = loc->inode->ino;
- afr_read_txn (frame, this, loc->inode, afr_readlink_wind,
- AFR_DATA_TRANSACTION);
+ STACK_WIND_COOKIE (frame, afr_stat_cbk, (void *) (long) call_child,
+ children[call_child],
+ children[call_child]->fops->stat,
+ loc);
- return 0;
+ op_ret = 0;
out:
- AFR_STACK_UNWIND(readlink, frame, -1, op_errno, 0, 0, 0);
+ if (op_ret == -1) {
+ AFR_STACK_UNWIND (stat, frame, op_ret, op_errno, NULL);
+ }
return 0;
}
@@ -415,1357 +298,588 @@ out:
/* }}} */
-/* {{{ getxattr */
-
-struct _xattr_key {
- char *key;
- struct list_head list;
-};
-
-
-int
-__gather_xattr_keys (dict_t *dict, char *key, data_t *value,
- void *data)
-{
- struct list_head * list = data;
- struct _xattr_key * xkey = NULL;
-
- if (!strncmp (key, AFR_XATTR_PREFIX,
- strlen (AFR_XATTR_PREFIX))) {
-
- xkey = GF_CALLOC (1, sizeof (*xkey), gf_afr_mt_xattr_key);
- if (!xkey)
- return -1;
-
- xkey->key = key;
- INIT_LIST_HEAD (&xkey->list);
-
- list_add_tail (&xkey->list, list);
- }
- return 0;
-}
-
+/* {{{ fstat */
-void
-afr_filter_xattrs (dict_t *dict)
+int32_t
+afr_fstat_cbk (call_frame_t *frame, void *cookie,
+ xlator_t *this, int32_t op_ret, int32_t op_errno,
+ struct stat *buf)
{
- struct list_head keys = {0,};
- struct _xattr_key *key = NULL;
- struct _xattr_key *tmp = NULL;
+ afr_private_t * priv = NULL;
+ afr_local_t * local = NULL;
+ xlator_t ** children = NULL;
- INIT_LIST_HEAD (&keys);
+ int unwind = 1;
+ int last_tried = -1;
+ int this_try = -1;
+ int read_child = -1;
- dict_foreach (dict, __gather_xattr_keys,
- (void *) &keys);
+ priv = this->private;
+ children = priv->children;
- list_for_each_entry_safe (key, tmp, &keys, list) {
- dict_del (dict, key->key);
+ local = frame->local;
- list_del_init (&key->list);
+ read_child = (long) cookie;
- GF_FREE (key);
- }
-}
+ if (op_ret == -1) {
+ retry:
+ last_tried = local->cont.fstat.last_tried;
+ if (all_tried (last_tried, priv->child_count)) {
+ goto out;
+ }
+ this_try = ++local->cont.fstat.last_tried;
-int
-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)
-{
- afr_local_t *local = NULL;
-
- local = frame->local;
+ if (this_try == read_child) {
+ goto retry;
+ }
- if (op_ret < 0) {
- local->op_ret = op_ret;
- local->op_errno = op_errno;
+ unwind = 0;
- afr_read_txn_continue (frame, this, (long) cookie);
- return 0;
+ STACK_WIND_COOKIE (frame, afr_fstat_cbk,
+ (void *) (long) read_child,
+ children[this_try],
+ children[this_try]->fops->fstat,
+ local->fd);
}
- if (dict)
- afr_filter_xattrs (dict);
-
- AFR_STACK_UNWIND (getxattr, frame, op_ret, op_errno, dict, xdata);
-
- return 0;
-}
-
-
-int
-afr_getxattr_wind (call_frame_t *frame, xlator_t *this, int subvol)
-{
- afr_local_t *local = NULL;
- afr_private_t *priv = NULL;
-
- local = frame->local;
- priv = this->private;
+out:
+ if (unwind) {
+ if (buf)
+ buf->st_ino = local->cont.fstat.ino;
- if (subvol == -1) {
- AFR_STACK_UNWIND (getxattr, frame, local->op_ret,
- local->op_errno, NULL, NULL);
- return 0;
+ AFR_STACK_UNWIND (fstat, frame, op_ret, op_errno, buf);
}
- STACK_WIND_COOKIE (frame, afr_getxattr_cbk, (void *) (long) subvol,
- priv->children[subvol],
- priv->children[subvol]->fops->getxattr,
- &local->loc, local->cont.getxattr.name,
- local->xdata_req);
return 0;
}
int32_t
-afr_getxattr_unwind (call_frame_t *frame, int op_ret, int op_errno,
- dict_t *dict, dict_t *xdata)
-
+afr_fstat (call_frame_t *frame, xlator_t *this,
+ fd_t *fd)
{
- AFR_STACK_UNWIND (getxattr, frame, op_ret, op_errno, dict, xdata);
- return 0;
-}
+ afr_private_t * priv = NULL;
+ afr_local_t * local = NULL;
+ xlator_t ** children = NULL;
-int32_t
-afr_fgetxattr_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->replies[cky].op_errno = 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;
- }
+ int call_child = 0;
+ int32_t read_child = -1;
- unwind:
- // Updating child_errno with more recent 'events'
- op_errno = afr_final_errno (local, priv);
+ int32_t op_ret = -1;
+ int32_t op_errno = 0;
- AFR_STACK_UNWIND (fgetxattr, frame, op_ret, op_errno, xattr,
- xdata);
- if (xattr)
- dict_unref (xattr);
- }
+ VALIDATE_OR_GOTO (frame, out);
+ VALIDATE_OR_GOTO (this, out);
+ VALIDATE_OR_GOTO (fd, out);
+ VALIDATE_OR_GOTO (this->private, out);
- return ret;
-}
+ priv = this->private;
+ VALIDATE_OR_GOTO (priv->children, out);
-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->replies[cky].op_errno = 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;
- }
+ children = priv->children;
- unwind:
- // Updating child_errno with more recent 'events'
- op_errno = afr_final_errno (local, priv);
+ ALLOC_OR_GOTO (local, afr_local_t, out);
- AFR_STACK_UNWIND (getxattr, frame, op_ret, op_errno, xattr, xdata);
+ frame->local = local;
- if (xattr)
- dict_unref (xattr);
- }
+ VALIDATE_OR_GOTO (fd->inode, out);
- return ret;
-}
+ read_child = afr_read_child (this, fd->inode);
-/**
- * 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);
- }
+ if (read_child >= 0) {
+ call_child = read_child;
- unwind:
- if (unwind)
- AFR_STACK_UNWIND (getxattr, frame, op_ret, op_errno, dict,
- NULL);
+ local->cont.fstat.last_tried = -1;
+ } else {
+ call_child = afr_first_up_child (priv);
- return 0;
-}
+ if (call_child == -1) {
+ op_errno = ENOTCONN;
+ gf_log (this->name, GF_LOG_DEBUG,
+ "no child is up");
+ goto out;
+ }
-int32_t
-afr_getxattr_quota_size_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 idx = (long) cookie;
- int call_count = 0;
- afr_local_t *local = frame->local;
- int read_subvol = -1;
-
- local->replies[idx].valid = 1;
- local->replies[idx].op_ret = op_ret;
- local->replies[idx].op_errno = op_errno;
- if (dict)
- local->replies[idx].xdata = dict_ref (dict);
- call_count = afr_frame_return (frame);
- if (call_count == 0) {
- local->inode = inode_ref (local->loc.inode);
- read_subvol = afr_handle_quota_size (frame, this);
- if (read_subvol != -1) {
- op_ret = local->replies[read_subvol].op_ret;
- op_errno = local->replies[read_subvol].op_errno;
- dict = local->replies[read_subvol].xdata;
- }
- AFR_STACK_UNWIND (getxattr, frame, op_ret, op_errno, dict,
- xdata);
+ local->cont.fstat.last_tried = call_child;
}
- return 0;
-}
-
-int32_t
-afr_getxattr_lockinfo_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 call_cnt = 0, len = 0;
- char *lockinfo_buf = NULL;
- dict_t *lockinfo = NULL, *newdict = NULL;
- afr_local_t *local = NULL;
+ local->cont.fstat.ino = fd->inode->ino;
+ local->fd = fd_ref (fd);
- LOCK (&frame->lock);
- {
- local = frame->local;
+ STACK_WIND_COOKIE (frame, afr_fstat_cbk, (void *) (long) call_child,
+ children[call_child],
+ children[call_child]->fops->fstat,
+ fd);
- call_cnt = --local->call_count;
+ op_ret = 0;
+out:
+ if (op_ret == -1) {
+ AFR_STACK_UNWIND (fstat, frame, op_ret, op_errno, NULL);
+ }
- if ((op_ret < 0) || (!dict && !xdata)) {
- goto unlock;
- }
+ return 0;
+}
- if (xdata) {
- if (!local->xdata_rsp) {
- local->xdata_rsp = dict_new ();
- if (!local->xdata_rsp) {
- local->op_ret = -1;
- local->op_errno = ENOMEM;
- goto unlock;
- }
- }
- }
+/* }}} */
- if (!dict) {
- goto unlock;
- }
+/* {{{ readlink */
- op_ret = dict_get_ptr_and_len (dict, GF_XATTR_LOCKINFO_KEY,
- (void **)&lockinfo_buf, &len);
+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 stat *sbuf)
+{
+ afr_private_t * priv = NULL;
+ afr_local_t * local = NULL;
+ xlator_t ** children = NULL;
- if (!lockinfo_buf) {
- goto unlock;
- }
+ int unwind = 1;
+ int last_tried = -1;
+ int this_try = -1;
+ int read_child = -1;
- if (!local->dict) {
- local->dict = dict_new ();
- if (!local->dict) {
- local->op_ret = -1;
- local->op_errno = ENOMEM;
- goto unlock;
- }
- }
- }
-unlock:
- UNLOCK (&frame->lock);
-
- if (lockinfo_buf != NULL) {
- lockinfo = dict_new ();
- if (lockinfo == NULL) {
- local->op_ret = -1;
- local->op_errno = ENOMEM;
- } else {
- op_ret = dict_unserialize (lockinfo_buf, len,
- &lockinfo);
-
- if (lockinfo && local->dict) {
- dict_copy (lockinfo, local->dict);
- }
- }
- }
+ priv = this->private;
+ children = priv->children;
- if (xdata && local->xdata_rsp) {
- dict_copy (xdata, local->xdata_rsp);
- }
+ local = frame->local;
- if (!call_cnt) {
- newdict = dict_new ();
- if (!newdict) {
- local->op_ret = -1;
- local->op_errno = ENOMEM;
- goto unwind;
- }
+ read_child = (long) cookie;
- len = dict_serialized_length (local->dict);
- if (len == 0) {
- goto unwind;
- }
+ if (op_ret == -1) {
+ retry:
+ last_tried = local->cont.readlink.last_tried;
- lockinfo_buf = GF_CALLOC (1, len, gf_common_mt_char);
- if (!lockinfo_buf) {
- local->op_ret = -1;
- local->op_errno = ENOMEM;
- goto unwind;
- }
+ if (all_tried (last_tried, priv->child_count)) {
+ goto out;
+ }
+ this_try = ++local->cont.readlink.last_tried;
- op_ret = dict_serialize (local->dict, lockinfo_buf);
- if (op_ret < 0) {
- local->op_ret = -1;
- local->op_errno = -op_ret;
+ if (this_try == read_child) {
+ goto retry;
}
- op_ret = dict_set_dynptr (newdict, GF_XATTR_LOCKINFO_KEY,
- (void *)lockinfo_buf, len);
- if (op_ret < 0) {
- local->op_ret = -1;
- local->op_errno = -op_ret;
- goto unwind;
- }
+ unwind = 0;
+ STACK_WIND_COOKIE (frame, afr_readlink_cbk,
+ (void *) (long) read_child,
+ children[this_try],
+ children[this_try]->fops->readlink,
+ &local->loc,
+ local->cont.readlink.size);
+ }
- unwind:
- AFR_STACK_UNWIND (getxattr, frame, op_ret,
- op_errno, newdict,
- local->xdata_rsp);
- }
+out:
+ if (unwind) {
+ if (sbuf)
+ sbuf->st_ino = local->cont.readlink.ino;
- dict_unref (lockinfo);
+ AFR_STACK_UNWIND (readlink, frame, op_ret, op_errno, buf, sbuf);
+ }
- return 0;
+ return 0;
}
+
int32_t
-afr_fgetxattr_lockinfo_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_readlink (call_frame_t *frame, xlator_t *this,
+ loc_t *loc, size_t size)
{
- int call_cnt = 0, len = 0;
- char *lockinfo_buf = NULL;
- dict_t *lockinfo = NULL, *newdict = NULL;
- afr_local_t *local = NULL;
+ afr_private_t * priv = NULL;
+ xlator_t ** children = NULL;
+ int call_child = 0;
+ afr_local_t *local = NULL;
- LOCK (&frame->lock);
- {
- local = frame->local;
+ int32_t read_child = -1;
- call_cnt = --local->call_count;
+ int32_t op_ret = -1;
+ int32_t op_errno = 0;
- if ((op_ret < 0) || (!dict && !xdata)) {
- goto unlock;
- }
+ VALIDATE_OR_GOTO (frame, out);
+ VALIDATE_OR_GOTO (this, out);
+ VALIDATE_OR_GOTO (this->private, out);
- if (xdata) {
- if (!local->xdata_rsp) {
- local->xdata_rsp = dict_new ();
- if (!local->xdata_rsp) {
- local->op_ret = -1;
- local->op_errno = ENOMEM;
- goto unlock;
- }
- }
- }
+ priv = this->private;
+ VALIDATE_OR_GOTO (priv->children, out);
- if (!dict) {
- goto unlock;
- }
+ children = priv->children;
- op_ret = dict_get_ptr_and_len (dict, GF_XATTR_LOCKINFO_KEY,
- (void **)&lockinfo_buf, &len);
+ ALLOC_OR_GOTO (local, afr_local_t, out);
- if (!lockinfo_buf) {
- goto unlock;
- }
+ frame->local = local;
- if (!local->dict) {
- local->dict = dict_new ();
- if (!local->dict) {
- local->op_ret = -1;
- local->op_errno = ENOMEM;
- goto unlock;
- }
- }
- }
-unlock:
- UNLOCK (&frame->lock);
-
- if (lockinfo_buf != NULL) {
- lockinfo = dict_new ();
- if (lockinfo == NULL) {
- local->op_ret = -1;
- local->op_errno = ENOMEM;
- } else {
- op_ret = dict_unserialize (lockinfo_buf, len,
- &lockinfo);
-
- if (lockinfo && local->dict) {
- dict_copy (lockinfo, local->dict);
- }
- }
- }
+ read_child = afr_read_child (this, loc->inode);
- if (xdata && local->xdata_rsp) {
- dict_copy (xdata, local->xdata_rsp);
- }
+ if (read_child >= 0) {
+ call_child = read_child;
- if (!call_cnt) {
- newdict = dict_new ();
- if (!newdict) {
- local->op_ret = -1;
- local->op_errno = ENOMEM;
- goto unwind;
- }
+ local->cont.readlink.last_tried = -1;
- len = dict_serialized_length (local->dict);
- if (len <= 0) {
- goto unwind;
- }
+ } else {
+ call_child = afr_first_up_child (priv);
- lockinfo_buf = GF_CALLOC (1, len, gf_common_mt_char);
- if (!lockinfo_buf) {
- local->op_ret = -1;
- local->op_errno = ENOMEM;
- goto unwind;
+ if (call_child == -1) {
+ op_errno = ENOTCONN;
+ gf_log (this->name, GF_LOG_DEBUG,
+ "no child is up");
+ goto out;
}
- op_ret = dict_serialize (local->dict, lockinfo_buf);
- if (op_ret < 0) {
- local->op_ret = -1;
- local->op_errno = -op_ret;
- }
+ local->cont.readlink.last_tried = call_child;
+ }
- op_ret = dict_set_dynptr (newdict, GF_XATTR_LOCKINFO_KEY,
- (void *)lockinfo_buf, len);
- if (op_ret < 0) {
- local->op_ret = -1;
- local->op_errno = -op_ret;
- goto unwind;
- }
+ loc_copy (&local->loc, loc);
- unwind:
- AFR_STACK_UNWIND (fgetxattr, frame, op_ret,
- op_errno, newdict,
- local->xdata_rsp);
- }
+ local->cont.readlink.size = size;
+ local->cont.readlink.ino = loc->inode->ino;
- dict_unref (lockinfo);
+ STACK_WIND_COOKIE (frame, afr_readlink_cbk,
+ (void *) (long) call_child,
+ children[call_child], children[call_child]->fops->readlink,
+ loc, size);
- return 0;
+ op_ret = 0;
+out:
+ if (op_ret == -1) {
+ AFR_STACK_UNWIND (readlink, frame, op_ret, op_errno, NULL, NULL);
+ }
+ return 0;
}
-int32_t
-afr_fgetxattr_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;
+/* {{{ getxattr */
- if (op_ret < 0) {
- local->op_errno = op_errno;
- } else {
- local->op_ret = op_ret;
- if (!local->xdata_rsp && xdata)
- local->xdata_rsp = dict_ref (xdata);
- }
+struct _xattr_key {
+ char *key;
+ struct list_head list;
+};
- 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;
- }
+void
+__gather_xattr_keys (dict_t *dict, char *key, data_t *value,
+ void *data)
+{
+ struct list_head * list = data;
+ struct _xattr_key * xkey = NULL;
- /* closing part */
- *(xattr_serz + padding + tlen) = ')';
- *(xattr_serz + padding + tlen + 1) = '\0';
+ if (!strncmp (key, AFR_XATTR_PREFIX,
+ strlen (AFR_XATTR_PREFIX))) {
- 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");
+ xkey = CALLOC (1, sizeof (*xkey));
+ if (!xkey)
+ return;
- unwind:
- AFR_STACK_UNWIND (fgetxattr, frame, local->op_ret,
- local->op_errno, nxattr, local->xdata_rsp);
+ xkey->key = key;
+ INIT_LIST_HEAD (&xkey->list);
- if (nxattr)
- dict_unref (nxattr);
+ list_add_tail (&xkey->list, list);
}
-
- return ret;
}
-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)
+
+void
+__filter_xattrs (dict_t *dict)
{
- 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;
- }
+ struct list_head keys;
- local = frame->local;
- cky = (long) cookie;
-
- LOCK (&frame->lock);
- {
- callcnt = --local->call_count;
-
- if (op_ret < 0) {
- local->op_errno = op_errno;
- } else {
- local->op_ret = op_ret;
- if (!local->xdata_rsp && xdata)
- local->xdata_rsp = dict_ref (xdata);
- }
-
- 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;
- }
+ struct _xattr_key *key;
+ struct _xattr_key *tmp;
- /* closing part */
- *(xattr_serz + padding + tlen) = ')';
- *(xattr_serz + padding + tlen + 1) = '\0';
+ INIT_LIST_HEAD (&keys);
- 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");
+ dict_foreach (dict, __gather_xattr_keys,
+ (void *) &keys);
- unwind:
- AFR_STACK_UNWIND (getxattr, frame, local->op_ret,
- local->op_errno, nxattr, local->xdata_rsp);
+ list_for_each_entry_safe (key, tmp, &keys, list) {
+ dict_del (dict, key->key);
- if (nxattr)
- dict_unref (nxattr);
- }
+ list_del_init (&key->list);
- return ret;
+ FREE (key);
+ }
}
-static int
-afr_aggregate_stime_xattr (dict_t *this, char *key, data_t *value, void *data)
-{
- int ret = 0;
-
- if (fnmatch (GF_XATTR_STIME_PATTERN, key, FNM_NOESCAPE) == 0)
- ret = gf_get_max_stime (THIS, data, key, value);
- return ret;
-}
int32_t
-afr_common_getxattr_stime_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_getxattr_cbk (call_frame_t *frame, void *cookie,
+ xlator_t *this, int32_t op_ret, int32_t op_errno,
+ dict_t *dict)
{
- afr_local_t *local = NULL;
- int32_t callcnt = 0;
-
- if (!frame || !frame->local || !this) {
- gf_log ("", GF_LOG_ERROR, "possible NULL deref");
- goto out;
- }
+ afr_private_t * priv = NULL;
+ afr_local_t * local = NULL;
+ xlator_t ** children = NULL;
- local = frame->local;
+ int unwind = 1;
+ int last_tried = -1;
+ int this_try = -1;
+ int read_child = -1;
- LOCK (&frame->lock);
- {
- callcnt = --local->call_count;
+ priv = this->private;
+ children = priv->children;
- if (!dict || (op_ret < 0)) {
- local->op_errno = op_errno;
- goto cleanup;
- }
-
- if (!local->dict)
- local->dict = dict_copy_with_ref (dict, NULL);
- else
- dict_foreach (dict, afr_aggregate_stime_xattr,
- local->dict);
- local->op_ret = 0;
- }
+ local = frame->local;
-cleanup:
- UNLOCK (&frame->lock);
+ read_child = (long) cookie;
- if (!callcnt) {
- AFR_STACK_UNWIND (getxattr, frame, local->op_ret,
- local->op_errno, local->dict, xdata);
- }
+ if (op_ret == -1) {
+ retry:
+ last_tried = local->cont.getxattr.last_tried;
-out:
- return 0;
-}
+ if (all_tried (last_tried, priv->child_count)) {
+ goto out;
+ }
+ this_try = ++local->cont.getxattr.last_tried;
+ if (this_try == read_child) {
+ goto retry;
+ }
-static gf_boolean_t
-afr_is_special_xattr (const char *name, fop_getxattr_cbk_t *cbk,
- gf_boolean_t is_fgetxattr)
-{
- gf_boolean_t is_spl = _gf_true;
+ unwind = 0;
+ STACK_WIND_COOKIE (frame, afr_getxattr_cbk,
+ (void *) (long) read_child,
+ children[this_try],
+ children[this_try]->fops->getxattr,
+ &local->loc,
+ local->cont.getxattr.name);
+ }
- GF_ASSERT (cbk);
- if (!cbk || !name) {
- is_spl = _gf_false;
- goto out;
- }
+out:
+ if (unwind) {
+ if (op_ret >= 0 && dict)
+ __filter_xattrs (dict);
- if (!strcmp (name, GF_XATTR_PATHINFO_KEY) ||
- !strcmp (name, GF_XATTR_USER_PATHINFO_KEY)) {
- if (is_fgetxattr) {
- *cbk = afr_fgetxattr_pathinfo_cbk;
- } else {
- *cbk = afr_getxattr_pathinfo_cbk;
- }
- } else if (!strncmp (name, GF_XATTR_CLRLK_CMD,
- strlen (GF_XATTR_CLRLK_CMD))) {
- if (is_fgetxattr) {
- *cbk = afr_fgetxattr_clrlk_cbk;
- } else {
- *cbk = afr_getxattr_clrlk_cbk;
- }
- } else if (!strncmp (name, GF_XATTR_LOCKINFO_KEY,
- strlen (GF_XATTR_LOCKINFO_KEY))) {
- if (is_fgetxattr) {
- *cbk = afr_fgetxattr_lockinfo_cbk;
- } else {
- *cbk = afr_getxattr_lockinfo_cbk;
- }
- } else if (fnmatch (GF_XATTR_STIME_PATTERN, name, FNM_NOESCAPE) == 0) {
- *cbk = afr_common_getxattr_stime_cbk;
- } else if (strcmp (name, QUOTA_SIZE_KEY) == 0) {
- *cbk = afr_getxattr_quota_size_cbk;
- } else {
- is_spl = _gf_false;
- }
+ AFR_STACK_UNWIND (getxattr, frame, op_ret, op_errno, dict);
+ }
-out:
- return is_spl;
+ return 0;
}
-static void
-afr_getxattr_all_subvols (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;
- int i = 0;
- int call_count = 0;
-
- priv = this->private;
-
- local = frame->local;
- //local->call_count set in afr_local_init
- call_count = local->call_count;
-
- //If up-children count is 0, afr_local_init would have failed already
- //and the call would have unwound so not handling it here.
-
- for (i = 0; i < priv->child_count; i++) {
- if (local->child_up[i]) {
- STACK_WIND_COOKIE (frame, cbk,
- (void *) (long) i, priv->children[i],
- priv->children[i]->fops->getxattr,
- loc, name, NULL);
- if (!--call_count)
- break;
- }
- }
- 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;
- afr_local_t *local = NULL;
- xlator_list_t *trav = NULL;
- xlator_t **sub_volumes = NULL;
- int i = 0;
- int32_t op_errno = 0;
- int ret = -1;
- fop_getxattr_cbk_t cbk = NULL;
- int afr_xtime_gauge[MCNT_MAX] = {0,};
-
-
- local = AFR_FRAME_INIT (frame, op_errno);
- if (!local)
- goto out;
-
- priv = this->private;
+ afr_private_t * priv = NULL;
+ xlator_t ** children = NULL;
+ int call_child = 0;
+ afr_local_t * local = NULL;
- children = priv->children;
+ int read_child = -1;
- loc_copy (&local->loc, loc);
+ int32_t op_ret = -1;
+ int32_t op_errno = 0;
- local->op = GF_FOP_GETXATTR;
+ VALIDATE_OR_GOTO (frame, out);
+ VALIDATE_OR_GOTO (this, out);
+ VALIDATE_OR_GOTO (this->private, out);
- if (xdata)
- local->xdata_req = dict_ref (xdata);
+ priv = this->private;
+ VALIDATE_OR_GOTO (priv->children, out);
- if (!name)
- goto no_name;
-
- local->cont.getxattr.name = gf_strdup (name);
-
- if (!local->cont.getxattr.name) {
- op_errno = ENOMEM;
- goto out;
- }
-
- 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)
- && (GF_CLIENT_PID_GSYNCD == frame->root->pid)) {
+ children = priv->children;
- local->marker.call_count = priv->child_count;
+ ALLOC_OR_GOTO (local, afr_local_t, out);
+ frame->local = local;
- 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) {
+ if (!strncmp (name, AFR_XATTR_PREFIX,
+ strlen (AFR_XATTR_PREFIX))) {
- if (cluster_getmarkerattr (frame, this, loc, name,
- local, afr_getxattr_unwind,
- sub_volumes,
- priv->child_count,
- MARKER_UUID_TYPE,
- marker_uuid_default_gauge,
- priv->vol_uuid)) {
-
- gf_log (this->name, GF_LOG_INFO,
- "%s: failed to get marker attr (%s)",
- loc->path, name);
- op_errno = EINVAL;
+ op_errno = ENODATA;
goto out;
}
-
- return 0;
}
- if (!strcmp (name, GF_AFR_HEAL_INFO)) {
- afr_get_heal_info (frame, this, loc, xdata);
- return 0;
- }
+ read_child = afr_read_child (this, loc->inode);
- /*
- * Special xattrs which need responses from all subvols
- */
- if (afr_is_special_xattr (name, &cbk, 0)) {
- afr_getxattr_all_subvols (this, frame, name, loc, cbk);
- return 0;
- }
+ if (read_child >= 0) {
+ call_child = read_child;
- 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;
- }
+ local->cont.getxattr.last_tried = -1;
+ } else {
+ call_child = afr_first_up_child (priv);
- if (*priv->vol_uuid) {
- if ((match_uuid_local (name, priv->vol_uuid) == 0)
- && (GF_CLIENT_PID_GSYNCD == 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;
-
- }
-
- /* don't err out on getting ENOTCONN (brick down)
- * from a subset of the bricks
- */
- memcpy (afr_xtime_gauge, marker_xtime_default_gauge,
- sizeof (afr_xtime_gauge));
- afr_xtime_gauge[MCNT_NOTFOUND] = 0;
- afr_xtime_gauge[MCNT_ENOTCONN] = 0;
- if (cluster_getmarkerattr (frame, this, loc,
- name, local,
- afr_getxattr_unwind,
- sub_volumes,
- priv->child_count,
- MARKER_XTIME_TYPE,
- afr_xtime_gauge,
- 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;
- }
-
- return 0;
+ 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;
}
-no_name:
+ loc_copy (&local->loc, loc);
+ if (name)
+ local->cont.getxattr.name = strdup (name);
- afr_read_txn (frame, this, local->loc.inode, afr_getxattr_wind,
- AFR_METADATA_TRANSACTION);
+ STACK_WIND_COOKIE (frame, afr_getxattr_cbk,
+ (void *) (long) call_child,
+ children[call_child], children[call_child]->fops->getxattr,
+ loc, name);
- ret = 0;
+ op_ret = 0;
out:
- if (ret < 0)
- AFR_STACK_UNWIND (getxattr, frame, -1, op_errno, NULL, NULL);
- return 0;
+ if (op_ret == -1) {
+ AFR_STACK_UNWIND (getxattr, frame, op_ret, op_errno, NULL);
+ }
+ return 0;
}
-/* {{{ fgetxattr */
+/* }}} */
-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_local_t *local = NULL;
-
- local = frame->local;
-
- if (op_ret < 0) {
- local->op_ret = -1;
- local->op_errno = op_errno;
-
- afr_read_txn_continue (frame, this, (long) cookie);
- return 0;
- }
-
- if (dict)
- afr_filter_xattrs (dict);
-
- AFR_STACK_UNWIND (fgetxattr, frame, op_ret, op_errno, dict, xdata);
+/* {{{ readv */
- return 0;
-}
+/**
+ * read algorithm:
+ *
+ * if the user has specified a read subvolume, use it
+ * otherwise -
+ * use the inode number to hash it to one of the subvolumes, and
+ * read from there (to balance read load)
+ *
+ * if any of the above read's fail, try the children in sequence
+ * beginning at the beginning
+ */
-int
-afr_fgetxattr_wind (call_frame_t *frame, xlator_t *this, int subvol)
+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 stat *buf,
+ struct iobref *iobref)
{
- afr_local_t *local = NULL;
- afr_private_t *priv = NULL;
+ afr_private_t * priv = NULL;
+ afr_local_t * local = NULL;
+ xlator_t ** children = NULL;
- local = frame->local;
- priv = this->private;
+ int unwind = 1;
+ int last_tried = -1;
+ int this_try = -1;
+ int read_child = -1;
- if (subvol == -1) {
- AFR_STACK_UNWIND (fgetxattr, frame, local->op_ret,
- local->op_errno, NULL, NULL);
- return 0;
- }
-
- STACK_WIND_COOKIE (frame, afr_fgetxattr_cbk, (void *) (long) subvol,
- priv->children[subvol],
- priv->children[subvol]->fops->fgetxattr,
- local->fd, local->cont.getxattr.name,
- local->xdata_req);
- return 0;
-}
+ 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);
-static void
-afr_fgetxattr_all_subvols (xlator_t *this, call_frame_t *frame,
- fop_fgetxattr_cbk_t cbk)
-{
- afr_private_t *priv = NULL;
- afr_local_t *local = NULL;
- int i = 0;
- int call_count = 0;
-
- priv = this->private;
-
- local = frame->local;
- //local->call_count set in afr_local_init
- call_count = local->call_count;
-
- //If up-children count is 0, afr_local_init would have failed already
- //and the call would have unwound so not handling it here.
-
- for (i = 0; i < priv->child_count; i++) {
- if (local->child_up[i]) {
- STACK_WIND_COOKIE (frame, cbk,
- (void *) (long) i,
- priv->children[i],
- priv->children[i]->fops->fgetxattr,
- local->fd, local->cont.getxattr.name,
- NULL);
- if (!--call_count)
- break;
- }
- }
-
- return;
-}
+ children = priv->children;
+ local = frame->local;
-int
-afr_fgetxattr (call_frame_t *frame, xlator_t *this,
- fd_t *fd, const char *name, dict_t *xdata)
-{
- afr_local_t *local = NULL;
- int32_t op_errno = 0;
- fop_fgetxattr_cbk_t cbk = NULL;
+ read_child = (long) cookie;
- local = AFR_FRAME_INIT (frame, op_errno);
- if (!local)
- goto out;
+ if (op_ret == -1) {
+ retry:
+ last_tried = local->cont.readv.last_tried;
- local->op = GF_FOP_FGETXATTR;
- local->fd = fd_ref (fd);
- if (name) {
- local->cont.getxattr.name = gf_strdup (name);
- if (!local->cont.getxattr.name) {
- op_errno = ENOMEM;
+ if (all_tried (last_tried, priv->child_count)) {
goto out;
}
- }
- if (xdata)
- local->xdata_req = dict_ref (xdata);
-
- /* pathinfo gets handled only in getxattr(), but we need to handle
- * lockinfo.
- * If we are doing fgetxattr with lockinfo as the key then we
- * collect information from all children.
- */
- if (afr_is_special_xattr (name, &cbk, 1)) {
- afr_fgetxattr_all_subvols (this, frame, cbk);
- return 0;
- }
+ 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;
+ }
- afr_fix_open (fd, this);
+ unwind = 0;
- afr_read_txn (frame, this, fd->inode, afr_fgetxattr_wind,
- AFR_METADATA_TRANSACTION);
+ STACK_WIND_COOKIE (frame, afr_readv_cbk,
+ (void *) (long) read_child,
+ children[this_try],
+ children[this_try]->fops->readv,
+ local->fd, local->cont.readv.size,
+ local->cont.readv.offset);
+ }
- return 0;
out:
- AFR_STACK_UNWIND (fgetxattr, frame, -1, op_errno, NULL, NULL);
-
- return 0;
-}
+ if (unwind) {
+ if (buf)
+ buf->st_ino = local->cont.readv.ino;
+ AFR_STACK_UNWIND (readv, frame, op_ret, op_errno,
+ vector, count, buf, iobref);
+ }
-/* }}} */
+ return 0;
+}
-/* {{{ readv */
-int
-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)
+int32_t
+afr_readv (call_frame_t *frame, xlator_t *this,
+ fd_t *fd, size_t size, off_t offset)
{
- afr_local_t *local = NULL;
+ afr_private_t * priv = NULL;
+ afr_local_t * local = NULL;
+ xlator_t ** children = NULL;
- local = frame->local;
+ int32_t read_child = -1;
+ int call_child = 0;
- if (op_ret < 0) {
- local->op_ret = -1;
- local->op_errno = op_errno;
+ int32_t op_ret = -1;
+ int32_t op_errno = 0;
- afr_read_txn_continue (frame, this, (long) cookie);
- return 0;
- }
+ VALIDATE_OR_GOTO (frame, out);
+ VALIDATE_OR_GOTO (this, out);
+ VALIDATE_OR_GOTO (this->private, out);
+ VALIDATE_OR_GOTO (fd, out);
- AFR_STACK_UNWIND (readv, frame, op_ret, op_errno,
- vector, count, buf, iobref, xdata);
- return 0;
-}
+ priv = this->private;
+ children = priv->children;
+ ALLOC_OR_GOTO (local, afr_local_t, out);
-int
-afr_readv_wind (call_frame_t *frame, xlator_t *this, int subvol)
-{
- afr_local_t *local = NULL;
- afr_private_t *priv = NULL;
+ frame->local = local;
- local = frame->local;
- priv = this->private;
+ read_child = afr_read_child (this, fd->inode);
- if (subvol == -1) {
- AFR_STACK_UNWIND (readv, frame, local->op_ret, local->op_errno,
- 0, 0, 0, 0, 0);
- return 0;
- }
-
- STACK_WIND_COOKIE (frame, afr_readv_cbk, (void *) (long) subvol,
- priv->children[subvol],
- priv->children[subvol]->fops->readv,
- local->fd, local->cont.readv.size,
- local->cont.readv.offset, local->cont.readv.flags,
- local->xdata_req);
- return 0;
-}
+ if (read_child >= 0) {
+ 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;
-int
-afr_readv (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
- off_t offset, uint32_t flags, dict_t *xdata)
-{
- afr_local_t * local = NULL;
- int32_t op_errno = 0;
+ } 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 = AFR_FRAME_INIT (frame, op_errno);
- if (!local)
- goto out;
+ local->cont.readv.last_tried = call_child;
+ }
- local->op = GF_FOP_READ;
- local->fd = fd_ref (fd);
- local->cont.readv.size = size;
- local->cont.readv.offset = offset;
- local->cont.readv.flags = flags;
- if (xdata)
- local->xdata_req = dict_ref (xdata);
+ local->fd = fd_ref (fd);
- afr_fix_open (fd, this);
+ local->cont.readv.ino = fd->inode->ino;
+ local->cont.readv.size = size;
+ local->cont.readv.offset = offset;
- afr_read_txn (frame, this, fd->inode, afr_readv_wind,
- AFR_DATA_TRANSACTION);
+ STACK_WIND_COOKIE (frame, afr_readv_cbk,
+ (void *) (long) call_child,
+ children[call_child],
+ children[call_child]->fops->readv,
+ fd, size, offset);
- return 0;
+ op_ret = 0;
out:
- AFR_STACK_UNWIND(readv, frame, -1, op_errno, 0, 0, 0, 0, 0);
-
+ 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 d128134ef2a..2b22131db1a 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-2009 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 __INODE_READ_H__
@@ -13,33 +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);
-int
-afr_handle_quota_size (call_frame_t *frame, xlator_t *this);
#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 d2c7ecc4740..8ebba6d4ad2 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>
- 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-2009 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/>.
*/
@@ -39,426 +48,278 @@
#include "afr-transaction.h"
-static void
-__afr_inode_write_finalize (call_frame_t *frame, xlator_t *this)
+/* {{{ writev */
+
+int
+afr_writev_unwind (call_frame_t *frame, xlator_t *this)
{
- afr_local_t *local = NULL;
- afr_private_t *priv = NULL;
- int read_subvol = 0;
- int i = 0;
+ afr_local_t * local = NULL;
+ afr_private_t * priv = NULL;
+ call_frame_t *main_frame = NULL;
local = frame->local;
- priv = this->private;
+ priv = this->private;
- if (local->inode) {
- if (local->transaction.type == AFR_METADATA_TRANSACTION)
- read_subvol = afr_metadata_subvol_get (local->inode, this,
- NULL, NULL,
- NULL);
- else
- read_subvol = afr_data_subvol_get (local->inode, this,
- NULL, NULL, NULL);
+ LOCK (&frame->lock);
+ {
+ if (local->transaction.main_frame)
+ main_frame = local->transaction.main_frame;
+ local->transaction.main_frame = NULL;
}
+ UNLOCK (&frame->lock);
- local->op_ret = -1;
- local->op_errno = afr_final_errno (local, priv);
-
- for (i = 0; i < priv->child_count; i++) {
- if (!local->replies[i].valid)
- continue;
- if (local->replies[i].op_ret < 0) {
- afr_inode_read_subvol_reset (local->inode, this);
- continue;
- }
+ if (main_frame) {
+ local->cont.writev.prebuf.st_ino = local->cont.writev.ino;
+ local->cont.writev.postbuf.st_ino = local->cont.writev.ino;
- /* Order of checks in the compound conditional
- below is important.
-
- - Highest precedence: largest op_ret
- - Next precendence: if all op_rets are equal, read subvol
- - Least precedence: any succeeded subvol
- */
- if ((local->op_ret < local->replies[i].op_ret) ||
- ((local->op_ret == local->replies[i].op_ret) &&
- (i == read_subvol))) {
-
- local->op_ret = local->replies[i].op_ret;
- local->op_errno = local->replies[i].op_errno;
-
- local->cont.inode_wfop.prebuf =
- local->replies[i].prestat;
- local->cont.inode_wfop.postbuf =
- local->replies[i].poststat;
-
- if (local->replies[i].xdata) {
- if (local->xdata_rsp)
- dict_unref (local->xdata_rsp);
- local->xdata_rsp =
- dict_ref (local->replies[i].xdata);
- }
- }
+ AFR_STACK_UNWIND (writev, main_frame,
+ local->op_ret, local->op_errno,
+ &local->cont.writev.prebuf,
+ &local->cont.writev.postbuf);
}
+ return 0;
}
-static void
-__afr_inode_write_fill (call_frame_t *frame, xlator_t *this, int child_index,
- int op_ret, int op_errno,
- struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata)
+int
+afr_writev_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct stat *prebuf,
+ struct stat *postbuf)
{
- afr_local_t *local = NULL;
-
- local = frame->local;
-
- local->replies[child_index].valid = 1;
- local->replies[child_index].op_ret = op_ret;
- local->replies[child_index].op_errno = op_errno;
-
- if (op_ret >= 0) {
- if (prebuf)
- local->replies[child_index].prestat = *prebuf;
- if (postbuf)
- local->replies[child_index].poststat = *postbuf;
- if (xdata)
- local->replies[child_index].xdata = dict_ref (xdata);
- } else {
- afr_transaction_fop_failed (frame, this, child_index);
- }
+ afr_local_t * local = NULL;
+ afr_private_t * priv = NULL;
- return;
-}
+ int child_index = (long) cookie;
+ int call_count = -1;
+ int need_unwind = 0;
+ int read_child = 0;
+ local = frame->local;
+ priv = this->private;
-static int
-__afr_inode_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)
-{
- afr_local_t *local = NULL;
- int child_index = (long) cookie;
- int call_count = -1;
-
- local = frame->local;
+ read_child = afr_read_child (this, local->fd->inode);
- LOCK (&frame->lock);
- {
- __afr_inode_write_fill (frame, this, child_index, op_ret,
- op_errno, prebuf, postbuf, xdata);
- }
- UNLOCK (&frame->lock);
+ LOCK (&frame->lock);
+ {
+ if (child_index == read_child) {
+ local->read_child_returned = _gf_true;
+ }
- call_count = afr_frame_return (frame);
+ if (afr_fop_failed (op_ret, op_errno))
+ afr_transaction_fop_failed (frame, this, child_index);
- if (call_count == 0) {
- __afr_inode_write_finalize (frame, this);
+ if (op_ret != -1) {
+ if (local->success_count == 0) {
+ local->op_ret = op_ret;
+ local->cont.writev.prebuf = *prebuf;
+ local->cont.writev.postbuf = *postbuf;
+ }
- if (afr_txn_nothing_failed (frame, this))
- local->transaction.unwind (frame, this);
+ if (child_index == read_child) {
+ local->cont.writev.prebuf = *prebuf;
+ local->cont.writev.postbuf = *postbuf;
+ }
- local->transaction.resume (frame, this);
- }
+ local->success_count++;
- return 0;
-}
+ if ((local->success_count >= priv->wait_count)
+ && local->read_child_returned) {
+ need_unwind = 1;
+ }
+ }
-/* {{{ writev */
+ local->op_errno = op_errno;
+ }
+ UNLOCK (&frame->lock);
-void
-afr_writev_copy_outvars (call_frame_t *src_frame, call_frame_t *dst_frame)
-{
- afr_local_t *src_local = NULL;
- afr_local_t *dst_local = NULL;
-
- src_local = src_frame->local;
- dst_local = dst_frame->local;
-
- dst_local->op_ret = src_local->op_ret;
- dst_local->op_errno = src_local->op_errno;
- dst_local->cont.inode_wfop.prebuf = src_local->cont.inode_wfop.prebuf;
- dst_local->cont.inode_wfop.postbuf = src_local->cont.inode_wfop.postbuf;
- if (src_local->xdata_rsp)
- dst_local->xdata_rsp = dict_ref (src_local->xdata_rsp);
-}
+ call_count = afr_frame_return (frame);
-void
-afr_writev_unwind (call_frame_t *frame, xlator_t *this)
-{
- afr_local_t * local = NULL;
- local = frame->local;
+ if (call_count == 0) {
+ local->transaction.unwind (frame, this);
- AFR_STACK_UNWIND (writev, frame,
- local->op_ret, local->op_errno,
- &local->cont.inode_wfop.prebuf,
- &local->cont.inode_wfop.postbuf,
- local->xdata_rsp);
+ local->transaction.resume (frame, this);
+ }
+
+ return 0;
}
int
-afr_transaction_writev_unwind (call_frame_t *frame, xlator_t *this)
+afr_writev_wind (call_frame_t *frame, xlator_t *this)
{
- call_frame_t *fop_frame = NULL;
+ afr_local_t *local = NULL;
+ afr_private_t *priv = NULL;
+
+ int i = 0;
+ int call_count = -1;
- fop_frame = afr_transaction_detach_fop_frame (frame);
+ local = frame->local;
+ priv = this->private;
- if (fop_frame) {
- afr_writev_copy_outvars (frame, fop_frame);
- afr_writev_unwind (fop_frame, this);
- }
- return 0;
-}
+ call_count = afr_up_children_count (priv->child_count, local->child_up);
-static void
-afr_writev_handle_short_writes (call_frame_t *frame, xlator_t *this)
-{
- afr_local_t *local = NULL;
- afr_private_t *priv = NULL;
- int i = 0;
+ if (call_count == 0) {
+ local->transaction.resume (frame, this);
+ return 0;
+ }
- local = frame->local;
- priv = this->private;
- /*
- * We already have the best case result of the writev calls staged
- * as the return value. Any writev that returns some value less
- * than the best case is now out of sync, so mark the fop as
- * failed. Note that fops that have returned with errors have
- * already been marked as failed.
- */
- for (i = 0; i < priv->child_count; i++) {
- if ((!local->replies[i].valid) ||
- (local->replies[i].op_ret == -1))
- continue;
-
- if (local->replies[i].op_ret < local->op_ret)
- afr_transaction_fop_failed (frame, this, i);
- }
+ local->call_count = call_count;
+
+ for (i = 0; i < priv->child_count; i++) {
+ if (local->child_up[i]) {
+ STACK_WIND_COOKIE (frame, afr_writev_wind_cbk,
+ (void *) (long) i,
+ priv->children[i],
+ priv->children[i]->fops->writev,
+ local->fd,
+ local->cont.writev.vector,
+ local->cont.writev.count,
+ local->cont.writev.offset,
+ local->cont.writev.iobref);
+
+ if (!--call_count)
+ break;
+ }
+ }
+
+ return 0;
}
+
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)
+afr_writev_done (call_frame_t *frame, xlator_t *this)
{
- afr_local_t * local = NULL;
- call_frame_t *fop_frame = NULL;
- int child_index = (long) cookie;
- int call_count = -1;
- int ret = 0;
- uint32_t open_fd_count = 0;
- uint32_t write_is_append = 0;
+ afr_local_t *local = NULL;
- local = frame->local;
+ local = frame->local;
- LOCK (&frame->lock);
- {
- __afr_inode_write_fill (frame, this, child_index, op_ret,
- op_errno, prebuf, postbuf, xdata);
- if (op_ret == -1 || !xdata)
- goto unlock;
-
- write_is_append = 0;
- ret = dict_get_uint32 (xdata, GLUSTERFS_WRITE_IS_APPEND,
- &write_is_append);
- if (ret || !write_is_append)
- local->append_write = _gf_false;
-
- ret = dict_get_uint32 (xdata, GLUSTERFS_OPEN_FD_COUNT,
- &open_fd_count);
- if (ret == -1)
- goto unlock;
- if ((open_fd_count > local->open_fd_count)) {
- local->open_fd_count = open_fd_count;
- local->update_open_fd_count = _gf_true;
- }
- }
-unlock:
- UNLOCK (&frame->lock);
-
- call_count = afr_frame_return (frame);
-
- if (call_count == 0) {
- if (!local->stable_write && !local->append_write)
- /* An appended write removes the necessity to
- fsync() the file. This is because self-heal
- has the logic to check for larger file when
- the xattrs are not reliably pointing at
- a stale file.
- */
- afr_fd_report_unstable_write (this, local->fd);
-
- __afr_inode_write_finalize (frame, this);
-
- afr_writev_handle_short_writes (frame, this);
-
- if (local->update_open_fd_count)
- afr_handle_open_fd_count (frame, this);
-
- if (!afr_txn_nothing_failed (frame, this)) {
- //Don't unwind until post-op is complete
- local->transaction.resume (frame, this);
- } else {
- /*
- * Generally inode-write fops do transaction.unwind then
- * transaction.resume, but writev needs to make sure that
- * delayed post-op frame is placed in fdctx before unwind
- * happens. This prevents the race of flush doing the
- * changelog wakeup first in fuse thread and then this
- * writev placing its delayed post-op frame in fdctx.
- * This helps flush make sure all the delayed post-ops are
- * completed.
- */
-
- fop_frame = afr_transaction_detach_fop_frame (frame);
- afr_writev_copy_outvars (frame, fop_frame);
- local->transaction.resume (frame, this);
- afr_writev_unwind (fop_frame, this);
- }
- }
- return 0;
-}
+ iobref_unref (local->cont.writev.iobref);
+ local->cont.writev.iobref = NULL;
+ local->transaction.unwind (frame, this);
-int
-afr_writev_wind (call_frame_t *frame, xlator_t *this, int subvol)
-{
- afr_local_t *local = NULL;
- afr_private_t *priv = NULL;
+ AFR_STACK_DESTROY (frame);
- local = frame->local;
- priv = this->private;
-
- STACK_WIND_COOKIE (frame, afr_writev_wind_cbk, (void *) (long) subvol,
- priv->children[subvol],
- priv->children[subvol]->fops->writev,
- local->fd, local->cont.writev.vector,
- local->cont.writev.count, local->cont.writev.offset,
- local->cont.writev.flags, local->cont.writev.iobref,
- local->xdata_req);
- return 0;
+ return 0;
}
int
afr_do_writev (call_frame_t *frame, xlator_t *this)
{
- call_frame_t *transaction_frame = NULL;
- afr_local_t *local = NULL;
- int ret = -1;
- int op_errno = ENOMEM;
+ call_frame_t * transaction_frame = NULL;
+ afr_local_t * local = NULL;
- transaction_frame = copy_frame (frame);
- if (!transaction_frame)
- goto out;
+ int op_ret = -1;
+ int op_errno = 0;
local = frame->local;
- transaction_frame->local = local;
- frame->local = NULL;
- if (!AFR_FRAME_INIT (frame, op_errno))
+ transaction_frame = copy_frame (frame);
+ if (!transaction_frame) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory.");
+ op_errno = ENOMEM;
goto out;
+ }
- local->op = GF_FOP_WRITE;
-
- local->transaction.wind = afr_writev_wind;
- local->transaction.fop = __afr_txn_write_fop;
- local->transaction.done = __afr_txn_write_done;
- local->transaction.unwind = afr_transaction_writev_unwind;
-
- local->transaction.main_frame = frame;
-
- if (local->fd->flags & O_APPEND) {
- /*
- * Backend vfs ignores the 'offset' for append mode fd so
- * locking just the region provided for the writev does not
- * give consistency gurantee. The actual write may happen at a
- * completely different range than the one provided by the
- * offset, len in the fop. So lock the entire file.
- */
- local->transaction.start = 0;
- local->transaction.len = 0;
- } else {
- local->transaction.start = local->cont.writev.offset;
- local->transaction.len = iov_length (local->cont.writev.vector,
+ transaction_frame->local = local;
+ frame->local = NULL;
+
+ local->op = GF_FOP_WRITE;
+
+ local->success_count = 0;
+
+ local->transaction.fop = afr_writev_wind;
+ local->transaction.done = afr_writev_done;
+ local->transaction.unwind = afr_writev_unwind;
+
+ local->transaction.main_frame = frame;
+ if (local->fd->flags & O_APPEND) {
+ local->transaction.start = 0;
+ local->transaction.len = 0;
+ } else {
+ local->transaction.start = local->cont.writev.offset;
+ local->transaction.len = iov_length (local->cont.writev.vector,
local->cont.writev.count);
- }
+ }
- ret = afr_transaction (transaction_frame, this, AFR_DATA_TRANSACTION);
- if (ret < 0) {
- op_errno = -ret;
- goto out;
- }
+ afr_transaction (transaction_frame, this, AFR_DATA_TRANSACTION);
- return 0;
+ op_ret = 0;
out:
- if (transaction_frame)
- AFR_STACK_DESTROY (transaction_frame);
+ if (op_ret == -1) {
+ if (transaction_frame)
+ AFR_STACK_DESTROY (transaction_frame);
+ AFR_STACK_UNWIND (writev, frame, op_ret, op_errno, NULL, NULL);
+ }
- AFR_STACK_UNWIND (writev, frame, -1, op_errno, NULL, NULL, NULL);
return 0;
}
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)
+afr_writev (call_frame_t *frame, xlator_t *this, fd_t *fd,
+ struct iovec *vector, int32_t count, off_t offset,
+ struct iobref *iobref)
{
- afr_local_t *local = NULL;
- int op_errno = ENOMEM;
+ afr_private_t * priv = NULL;
+ afr_local_t * local = NULL;
- local = AFR_FRAME_INIT (frame, op_errno);
- if (!local)
- goto out;
+ int ret = -1;
- local->cont.writev.vector = iov_dup (vector, count);
- if (!local->cont.writev.vector)
- goto out;
- local->cont.writev.count = count;
- local->cont.writev.offset = offset;
- local->cont.writev.flags = flags;
- local->cont.writev.iobref = iobref_ref (iobref);
+ int op_ret = -1;
+ int op_errno = 0;
- if (xdata)
- local->xdata_req = dict_copy_with_ref (xdata, NULL);
- else
- local->xdata_req = dict_new ();
+ uint64_t ctx;
+ afr_fd_ctx_t *fd_ctx = NULL;
- if (!local->xdata_req)
- goto out;
+ VALIDATE_OR_GOTO (frame, out);
+ VALIDATE_OR_GOTO (this, out);
+ VALIDATE_OR_GOTO (this->private, out);
- local->fd = fd_ref (fd);
- local->inode = inode_ref (fd->inode);
+ priv = this->private;
- if (dict_set_uint32 (local->xdata_req, GLUSTERFS_OPEN_FD_COUNT, 4)) {
- op_errno = ENOMEM;
- goto out;
- }
+ ALLOC_OR_GOTO (local, afr_local_t, out);
- if (dict_set_uint32 (local->xdata_req, GLUSTERFS_WRITE_IS_APPEND, 4)) {
- op_errno = ENOMEM;
+ ret = AFR_LOCAL_INIT (local, priv);
+ if (ret < 0) {
+ op_errno = -ret;
goto out;
}
- /* Set append_write to be true speculatively. If on any
- server it turns not be true, we unset it in the
- callback.
- */
- local->append_write = _gf_true;
+ frame->local = local;
+
+ local->cont.writev.vector = iov_dup (vector, count);
+ local->cont.writev.count = count;
+ local->cont.writev.offset = offset;
+ local->cont.writev.ino = fd->inode->ino;
+ local->cont.writev.iobref = iobref_ref (iobref);
- /* detect here, but set it in writev_wind_cbk *after* the unstable
- write is performed
- */
- local->stable_write = !!((fd->flags|flags)&(O_SYNC|O_DSYNC));
+ local->fd = fd_ref (fd);
+
+ ret = fd_ctx_get (fd, this, &ctx);
+ if (ret < 0) {
+ goto out;
+ }
- afr_fix_open (fd, this);
+ fd_ctx = (afr_fd_ctx_t *)(long) ctx;
- afr_do_writev (frame, this);
+ if (fd_ctx->up_count < priv->up_count) {
+ local->openfd_flush_cbk = afr_do_writev;
+ afr_openfd_flush (frame, this, fd);
- return 0;
+ } else {
+ afr_do_writev (frame, this);
+ }
+
+ op_ret = 0;
out:
- 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;
+ return 0;
}
@@ -469,114 +330,214 @@ out:
int
afr_truncate_unwind (call_frame_t *frame, xlator_t *this)
{
- afr_local_t * local = NULL;
- call_frame_t *main_frame = NULL;
+ afr_local_t * local = NULL;
+ afr_private_t * priv = NULL;
+ call_frame_t *main_frame = NULL;
- local = frame->local;
+ local = frame->local;
+ priv = this->private;
- main_frame = afr_transaction_detach_fop_frame (frame);
- if (!main_frame)
- return 0;
+ LOCK (&frame->lock);
+ {
+ if (local->transaction.main_frame)
+ main_frame = local->transaction.main_frame;
+ local->transaction.main_frame = NULL;
+ }
+ UNLOCK (&frame->lock);
- AFR_STACK_UNWIND (truncate, main_frame, local->op_ret, local->op_errno,
- &local->cont.inode_wfop.prebuf,
- &local->cont.inode_wfop.postbuf, local->xdata_rsp);
- return 0;
+ if (main_frame) {
+ local->cont.truncate.prebuf.st_ino = local->cont.truncate.ino;
+ local->cont.truncate.postbuf.st_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);
+ }
+
+ return 0;
}
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)
+afr_truncate_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct stat *prebuf,
+ struct stat *postbuf)
+{
+ afr_local_t * local = NULL;
+ afr_private_t * priv = NULL;
+
+ int child_index = (long) cookie;
+ int read_child = 0;
+ int call_count = -1;
+ int need_unwind = 0;
+
+ local = frame->local;
+ priv = this->private;
+
+ read_child = afr_read_child (this, local->loc.inode);
+
+ LOCK (&frame->lock);
+ {
+ if (child_index == read_child) {
+ local->read_child_returned = _gf_true;
+ }
+
+ if (afr_fop_failed (op_ret, op_errno))
+ afr_transaction_fop_failed (frame, this, child_index);
+
+ if (op_ret != -1) {
+ if (local->success_count == 0) {
+ local->op_ret = op_ret;
+ local->cont.truncate.prebuf = *prebuf;
+ local->cont.truncate.postbuf = *postbuf;
+ }
+
+ if (child_index == read_child) {
+ local->cont.truncate.prebuf = *prebuf;
+ local->cont.truncate.postbuf = *postbuf;
+ }
+
+ local->success_count++;
+
+ if ((local->success_count >= priv->wait_count)
+ && local->read_child_returned) {
+ 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_truncate_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;
- if (op_ret == 0 && prebuf->ia_size != postbuf->ia_size)
- local->stable_write = _gf_false;
+ call_count = afr_up_children_count (priv->child_count, local->child_up);
- return __afr_inode_write_cbk (frame, cookie, this, op_ret, op_errno,
- prebuf, postbuf, xdata);
+ 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->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);
+
+ if (!--call_count)
+ break;
+ }
+ }
+
+ return 0;
}
int
-afr_truncate_wind (call_frame_t *frame, xlator_t *this, int subvol)
+afr_truncate_done (call_frame_t *frame, xlator_t *this)
{
- afr_local_t *local = NULL;
- afr_private_t *priv = NULL;
+ afr_local_t *local = NULL;
- local = frame->local;
- priv = this->private;
+ local = frame->local;
- STACK_WIND_COOKIE (frame, afr_truncate_wind_cbk, (void *) (long) subvol,
- priv->children[subvol],
- priv->children[subvol]->fops->truncate,
- &local->loc, local->cont.truncate.offset,
- local->xdata_req);
- return 0;
+ local->transaction.unwind (frame, this);
+
+ AFR_STACK_DESTROY (frame);
+
+ return 0;
}
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_local_t * local = NULL;
- call_frame_t *transaction_frame = NULL;
+ afr_private_t * priv = NULL;
+ afr_local_t * local = NULL;
+ call_frame_t *transaction_frame = NULL;
+
int ret = -1;
- int op_errno = ENOMEM;
- transaction_frame = copy_frame (frame);
- if (!transaction_frame)
- goto out;
+ 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;
- local = AFR_FRAME_INIT (transaction_frame, op_errno);
- if (!local)
+ transaction_frame = copy_frame (frame);
+ if (!transaction_frame) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory.");
goto out;
+ }
- local->cont.truncate.offset = offset;
- if (xdata)
- local->xdata_req = dict_copy_with_ref (xdata, NULL);
- else
- local->xdata_req = dict_new ();
+ ALLOC_OR_GOTO (local, afr_local_t, out);
- if (!local->xdata_req)
+ ret = AFR_LOCAL_INIT (local, priv);
+ if (ret < 0) {
+ op_errno = -ret;
goto out;
+ }
- local->transaction.wind = afr_truncate_wind;
- local->transaction.fop = __afr_txn_write_fop;
- local->transaction.done = __afr_txn_write_done;
- local->transaction.unwind = afr_truncate_unwind;
+ transaction_frame->local = local;
- loc_copy (&local->loc, loc);
- local->inode = inode_ref (loc->inode);
+ local->op_ret = -1;
- local->op = GF_FOP_TRUNCATE;
+ local->cont.truncate.offset = offset;
+ local->cont.truncate.ino = loc->inode->ino;
- local->transaction.main_frame = frame;
- local->transaction.start = offset;
- local->transaction.len = 0;
+ local->transaction.fop = afr_truncate_wind;
+ local->transaction.done = afr_truncate_done;
+ local->transaction.unwind = afr_truncate_unwind;
- /* Set it true speculatively, will get reset in afr_truncate_wind_cbk
- if truncate was not a NOP */
- local->stable_write = _gf_true;
+ loc_copy (&local->loc, loc);
- ret = afr_transaction (transaction_frame, this, AFR_DATA_TRANSACTION);
- if (ret < 0) {
- op_errno = -ret;
- goto out;
- }
+ local->transaction.main_frame = frame;
+ local->transaction.start = 0;
+ local->transaction.len = offset;
- return 0;
+ afr_transaction (transaction_frame, this, AFR_DATA_TRANSACTION);
+
+ op_ret = 0;
out:
- if (transaction_frame)
- AFR_STACK_DESTROY (transaction_frame);
+ if (op_ret == -1) {
+ if (transaction_frame)
+ AFR_STACK_DESTROY (transaction_frame);
+ AFR_STACK_UNWIND (truncate, frame, op_ret, op_errno, NULL, NULL);
+ }
- AFR_STACK_UNWIND (truncate, frame, -1, op_errno, NULL, NULL, NULL);
- return 0;
+ return 0;
}
@@ -588,1105 +549,1074 @@ out:
int
afr_ftruncate_unwind (call_frame_t *frame, xlator_t *this)
{
- afr_local_t * local = NULL;
- call_frame_t *main_frame = NULL;
+ afr_local_t * local = NULL;
+ afr_private_t * priv = NULL;
+ call_frame_t *main_frame = NULL;
- local = frame->local;
+ local = frame->local;
+ priv = this->private;
- main_frame = afr_transaction_detach_fop_frame (frame);
- if (!main_frame)
- return 0;
+ LOCK (&frame->lock);
+ {
+ if (local->transaction.main_frame)
+ main_frame = local->transaction.main_frame;
+ local->transaction.main_frame = NULL;
+ }
+ UNLOCK (&frame->lock);
- AFR_STACK_UNWIND (ftruncate, main_frame, local->op_ret, local->op_errno,
- &local->cont.inode_wfop.prebuf,
- &local->cont.inode_wfop.postbuf, local->xdata_rsp);
- return 0;
+ if (main_frame) {
+ local->cont.ftruncate.prebuf.st_ino = local->cont.ftruncate.ino;
+ local->cont.ftruncate.postbuf.st_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);
+ }
+ return 0;
}
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)
+afr_ftruncate_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct stat *prebuf,
+ struct stat *postbuf)
{
- afr_local_t *local = NULL;
+ afr_local_t * local = NULL;
+ afr_private_t * priv = NULL;
+
+ int child_index = (long) cookie;
+ int call_count = -1;
+ int need_unwind = 0;
+ int read_child = 0;
local = frame->local;
+ priv = this->private;
- if (op_ret == 0 && prebuf->ia_size != postbuf->ia_size)
- local->stable_write = _gf_false;
+ read_child = afr_read_child (this, local->fd->inode);
- return __afr_inode_write_cbk (frame, cookie, this, op_ret, op_errno,
- prebuf, postbuf, xdata);
-}
+ LOCK (&frame->lock);
+ {
+ if (child_index == read_child) {
+ local->read_child_returned = _gf_true;
+ }
+ if (afr_fop_failed (op_ret, op_errno))
+ afr_transaction_fop_failed (frame, this, child_index);
-int
-afr_ftruncate_wind (call_frame_t *frame, xlator_t *this, int subvol)
-{
- afr_local_t *local = NULL;
- afr_private_t *priv = NULL;
+ if (op_ret != -1) {
+ if (local->success_count == 0) {
+ local->op_ret = op_ret;
+ local->cont.ftruncate.prebuf = *prebuf;
+ local->cont.ftruncate.postbuf = *postbuf;
+ }
- local = frame->local;
- priv = this->private;
+ if (child_index == read_child) {
+ local->cont.ftruncate.prebuf = *prebuf;
+ local->cont.ftruncate.postbuf = *postbuf;
+ }
- STACK_WIND_COOKIE (frame, afr_ftruncate_wind_cbk, (void *) (long) subvol,
- priv->children[subvol],
- priv->children[subvol]->fops->ftruncate,
- local->fd, local->cont.ftruncate.offset,
- local->xdata_req);
- return 0;
+ local->success_count++;
+
+ if ((local->success_count >= priv->wait_count)
+ && local->read_child_returned) {
+ 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_ftruncate (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
- dict_t *xdata)
+afr_ftruncate_wind (call_frame_t *frame, xlator_t *this)
{
- afr_local_t *local = NULL;
- call_frame_t *transaction_frame = NULL;
- int ret = -1;
- int op_errno = ENOMEM;
-
- transaction_frame = copy_frame (frame);
- if (!frame)
- goto out;
+ afr_local_t *local = NULL;
+ afr_private_t *priv = NULL;
+
+ int call_count = -1;
+ int i = 0;
- local = AFR_FRAME_INIT (transaction_frame, op_errno);
- if (!local)
- goto out;
+ local = frame->local;
+ priv = this->private;
- local->cont.ftruncate.offset = offset;
- if (xdata)
- local->xdata_req = dict_copy_with_ref (xdata, NULL);
- else
- local->xdata_req = dict_new ();
+ call_count = afr_up_children_count (priv->child_count, local->child_up);
- if (!local->xdata_req)
- goto out;
+ if (call_count == 0) {
+ local->transaction.resume (frame, this);
+ return 0;
+ }
- local->fd = fd_ref (fd);
- local->inode = inode_ref (fd->inode);
+ local->call_count = call_count;
- local->op = GF_FOP_FTRUNCATE;
+ for (i = 0; i < priv->child_count; 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);
- local->transaction.wind = afr_ftruncate_wind;
- local->transaction.fop = __afr_txn_write_fop;
- local->transaction.done = __afr_txn_write_done;
- local->transaction.unwind = afr_ftruncate_unwind;
+ if (!--call_count)
+ break;
+ }
+ }
+
+ return 0;
+}
- local->transaction.main_frame = frame;
- local->transaction.start = local->cont.ftruncate.offset;
- local->transaction.len = 0;
+int
+afr_ftruncate_done (call_frame_t *frame, xlator_t *this)
+{
+ afr_local_t *local = NULL;
- afr_fix_open (fd, this);
+ local = frame->local;
- /* Set it true speculatively, will get reset in afr_ftruncate_wind_cbk
- if truncate was not a NOP */
- local->stable_write = _gf_true;
+ local->transaction.unwind (frame, this);
- ret = afr_transaction (transaction_frame, this, AFR_DATA_TRANSACTION);
- if (ret < 0) {
- op_errno = -ret;
- goto out;
- }
+ AFR_STACK_DESTROY (frame);
return 0;
-out:
- AFR_STACK_UNWIND (ftruncate, frame, -1, op_errno, NULL, NULL, NULL);
-
- return 0;
}
-/* }}} */
-
-/* {{{ setattr */
int
-afr_setattr_unwind (call_frame_t *frame, xlator_t *this)
+afr_do_ftruncate (call_frame_t *frame, xlator_t *this)
{
- afr_local_t *local = NULL;
- call_frame_t *main_frame = NULL;
+ call_frame_t * transaction_frame = NULL;
+ afr_local_t * local = NULL;
+
+ int op_ret = -1;
+ int op_errno = 0;
local = frame->local;
- main_frame = afr_transaction_detach_fop_frame (frame);
- if (!main_frame)
- return 0;
+ transaction_frame = copy_frame (frame);
+ if (!transaction_frame) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory.");
+ goto out;
+ }
- AFR_STACK_UNWIND (setattr, main_frame, local->op_ret, local->op_errno,
- &local->cont.inode_wfop.prebuf,
- &local->cont.inode_wfop.postbuf,
- local->xdata_rsp);
- return 0;
-}
+ transaction_frame->local = local;
+ frame->local = NULL;
+ local->op = GF_FOP_FTRUNCATE;
-int
-afr_setattr_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int op_ret, int op_errno,
- struct iatt *preop, struct iatt *postop, dict_t *xdata)
-{
- return __afr_inode_write_cbk (frame, cookie, this, op_ret, op_errno,
- preop, postop, xdata);
-}
+ local->transaction.fop = afr_ftruncate_wind;
+ local->transaction.done = afr_ftruncate_done;
+ local->transaction.unwind = afr_ftruncate_unwind;
+ local->transaction.main_frame = frame;
-int
-afr_setattr_wind (call_frame_t *frame, xlator_t *this, int subvol)
-{
- afr_local_t *local = NULL;
- afr_private_t *priv = NULL;
+ local->transaction.start = 0;
+ local->transaction.len = local->cont.ftruncate.offset;
- local = frame->local;
- priv = this->private;
+ afr_transaction (transaction_frame, this, AFR_DATA_TRANSACTION);
+
+ op_ret = 0;
+out:
+ if (op_ret == -1) {
+ if (transaction_frame)
+ AFR_STACK_DESTROY (transaction_frame);
+ AFR_STACK_UNWIND (ftruncate, frame, op_ret, op_errno, NULL, NULL);
+ }
- STACK_WIND_COOKIE (frame, afr_setattr_wind_cbk, (void *) (long) subvol,
- priv->children[subvol],
- priv->children[subvol]->fops->setattr,
- &local->loc, &local->cont.setattr.in_buf,
- local->cont.setattr.valid, local->xdata_req);
return 0;
}
int
-afr_setattr (call_frame_t *frame, xlator_t *this, loc_t *loc, struct iatt *buf,
- int32_t valid, dict_t *xdata)
+afr_ftruncate (call_frame_t *frame, xlator_t *this,
+ fd_t *fd, off_t offset)
{
- afr_local_t *local = NULL;
- call_frame_t *transaction_frame = NULL;
- int ret = -1;
- int op_errno = ENOMEM;
+ afr_private_t * priv = NULL;
+ afr_local_t * local = NULL;
+ call_frame_t *transaction_frame = NULL;
- transaction_frame = copy_frame (frame);
- if (!transaction_frame)
- goto out;
+ int ret = -1;
- local = AFR_FRAME_INIT (transaction_frame, op_errno);
- if (!local)
- goto out;
+ int op_ret = -1;
+ int op_errno = 0;
- local->cont.setattr.in_buf = *buf;
- local->cont.setattr.valid = valid;
- if (xdata)
- local->xdata_req = dict_copy_with_ref (xdata, NULL);
- else
- local->xdata_req = dict_new ();
+ uint64_t ctx;
+ afr_fd_ctx_t *fd_ctx = NULL;
- if (!local->xdata_req)
- goto out;
+ VALIDATE_OR_GOTO (frame, out);
+ VALIDATE_OR_GOTO (this, out);
+ VALIDATE_OR_GOTO (this->private, out);
+
+ priv = this->private;
+
+ ALLOC_OR_GOTO (local, afr_local_t, out);
- local->transaction.wind = afr_setattr_wind;
- local->transaction.fop = __afr_txn_write_fop;
- local->transaction.done = __afr_txn_write_done;
- local->transaction.unwind = afr_setattr_unwind;
+ ret = AFR_LOCAL_INIT (local, priv);
+ if (ret < 0) {
+ op_errno = -ret;
+ goto out;
+ }
- loc_copy (&local->loc, loc);
- local->inode = inode_ref (loc->inode);
+ frame->local = local;
- local->op = GF_FOP_SETATTR;
+ local->cont.ftruncate.offset = offset;
+ local->cont.ftruncate.ino = fd->inode->ino;
- local->transaction.main_frame = frame;
- local->transaction.start = LLONG_MAX - 1;
- local->transaction.len = 0;
+ local->fd = fd_ref (fd);
- ret = afr_transaction (transaction_frame, this, AFR_METADATA_TRANSACTION);
+ ret = fd_ctx_get (fd, this, &ctx);
if (ret < 0) {
- op_errno = -ret;
- goto out;
+ goto out;
}
- return 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 (transaction_frame)
- AFR_STACK_DESTROY (transaction_frame);
+ if (op_ret == -1) {
+ if (transaction_frame)
+ AFR_STACK_DESTROY (transaction_frame);
+ AFR_STACK_UNWIND (ftruncate, frame, op_ret, op_errno, NULL, NULL);
+ }
- AFR_STACK_UNWIND (setattr, frame, -1, op_errno, NULL, NULL, NULL);
- return 0;
+ return 0;
}
-/* {{{ fsetattr */
+/* }}} */
+
+/* {{{ setattr */
int
-afr_fsetattr_unwind (call_frame_t *frame, xlator_t *this)
+afr_setattr_unwind (call_frame_t *frame, xlator_t *this)
{
- afr_local_t * local = NULL;
- call_frame_t *main_frame = NULL;
+ afr_local_t * local = NULL;
+ afr_private_t * priv = NULL;
+ call_frame_t *main_frame = NULL;
- local = frame->local;
+ local = frame->local;
+ priv = this->private;
- main_frame = afr_transaction_detach_fop_frame (frame);
- if (!main_frame)
- return 0;
+ LOCK (&frame->lock);
+ {
+ if (local->transaction.main_frame)
+ main_frame = local->transaction.main_frame;
+ local->transaction.main_frame = NULL;
+ }
+ UNLOCK (&frame->lock);
- AFR_STACK_UNWIND (fsetattr, main_frame, local->op_ret, local->op_errno,
- &local->cont.inode_wfop.prebuf,
- &local->cont.inode_wfop.postbuf, local->xdata_rsp);
- return 0;
-}
+ if (main_frame) {
+ local->cont.setattr.preop_buf.st_ino = local->cont.setattr.ino;
+ local->cont.setattr.postop_buf.st_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);
+ }
-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)
-{
- return __afr_inode_write_cbk (frame, cookie, this, op_ret, op_errno,
- preop, postop, xdata);
+ return 0;
}
int
-afr_fsetattr_wind (call_frame_t *frame, xlator_t *this, int subvol)
+afr_setattr_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno,
+ struct stat *preop, struct stat *postop)
{
- afr_local_t *local = NULL;
- afr_private_t *priv = NULL;
-
- local = frame->local;
- priv = this->private;
-
- STACK_WIND_COOKIE (frame, afr_fsetattr_wind_cbk, (void *) (long) subvol,
- priv->children[subvol],
- priv->children[subvol]->fops->fsetattr,
- local->fd, &local->cont.fsetattr.in_buf,
- local->cont.fsetattr.valid, local->xdata_req);
- return 0;
-}
+ afr_local_t * local = NULL;
+ afr_private_t * priv = NULL;
+ int child_index = (long) cookie;
+ int read_child = 0;
+ int call_count = -1;
+ int need_unwind = 0;
-int
-afr_fsetattr (call_frame_t *frame, xlator_t *this,
- fd_t *fd, struct iatt *buf, int32_t valid, dict_t *xdata)
-{
- afr_local_t *local = NULL;
- call_frame_t *transaction_frame = NULL;
- int ret = -1;
- int op_errno = ENOMEM;
+ local = frame->local;
+ priv = this->private;
- transaction_frame = copy_frame (frame);
- if (!transaction_frame)
- goto out;
+ read_child = afr_read_child (this, local->loc.inode);
- local = AFR_FRAME_INIT (transaction_frame, op_errno);
- if (!local)
- goto out;
+ LOCK (&frame->lock);
+ {
+ if (child_index == read_child) {
+ local->read_child_returned = _gf_true;
+ }
- local->cont.fsetattr.in_buf = *buf;
- local->cont.fsetattr.valid = valid;
- if (xdata)
- local->xdata_req = dict_copy_with_ref (xdata, NULL);
- else
- local->xdata_req = dict_new ();
+ if (afr_fop_failed (op_ret, op_errno))
+ afr_transaction_fop_failed (frame, this, child_index);
- if (!local->xdata_req)
- goto out;
+ if (op_ret != -1) {
+ if (local->success_count == 0) {
+ local->op_ret = op_ret;
+ local->cont.setattr.preop_buf = *preop;
+ local->cont.setattr.postop_buf = *postop;
+ }
- local->transaction.wind = afr_fsetattr_wind;
- local->transaction.fop = __afr_txn_write_fop;
- local->transaction.done = __afr_txn_write_done;
- local->transaction.unwind = afr_fsetattr_unwind;
+ if (child_index == read_child) {
+ local->cont.setattr.preop_buf = *preop;
+ local->cont.setattr.postop_buf = *postop;
+ }
- local->fd = fd_ref (fd);
- local->inode = inode_ref (fd->inode);
+ local->success_count++;
- local->op = GF_FOP_FSETATTR;
+ if ((local->success_count >= priv->wait_count)
+ && local->read_child_returned) {
+ need_unwind = 1;
+ }
+ }
+ local->op_errno = op_errno;
+ }
+ UNLOCK (&frame->lock);
- afr_fix_open (fd, this);
+ if (need_unwind)
+ local->transaction.unwind (frame, this);
- local->transaction.main_frame = frame;
- local->transaction.start = LLONG_MAX - 1;
- local->transaction.len = 0;
+ call_count = afr_frame_return (frame);
- ret = afr_transaction (transaction_frame, this, AFR_METADATA_TRANSACTION);
- if (ret < 0) {
- op_errno = -ret;
- goto out;
- }
+ if (call_count == 0) {
+ local->transaction.resume (frame, this);
+ }
return 0;
-out:
- if (transaction_frame)
- AFR_STACK_DESTROY (transaction_frame);
-
- AFR_STACK_UNWIND (fsetattr, frame, -1, op_errno, NULL, NULL, NULL);
- return 0;
}
-/* {{{ setxattr */
+int32_t
+afr_setattr_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;
-int
-afr_setxattr_unwind (call_frame_t *frame, xlator_t *this)
-{
- afr_local_t * local = NULL;
- call_frame_t *main_frame = NULL;
+ local = frame->local;
+ priv = this->private;
- local = frame->local;
+ call_count = afr_up_children_count (priv->child_count, local->child_up);
- main_frame = afr_transaction_detach_fop_frame (frame);
- if (!main_frame)
+ if (call_count == 0) {
+ local->transaction.resume (frame, this);
return 0;
+ }
- AFR_STACK_UNWIND (setxattr, main_frame, local->op_ret, local->op_errno,
- local->xdata_rsp);
- return 0;
-}
+ local->call_count = call_count;
+ for (i = 0; i < priv->child_count; 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);
+
+ if (!--call_count)
+ break;
+ }
+ }
-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)
-{
- return __afr_inode_write_cbk (frame, cookie, this, op_ret, op_errno,
- NULL, NULL, xdata);
+ return 0;
}
int
-afr_setxattr_wind (call_frame_t *frame, xlator_t *this, int subvol)
+afr_setattr_done (call_frame_t *frame, xlator_t *this)
{
- afr_local_t *local = NULL;
- afr_private_t *priv = NULL;
+ afr_local_t *local = NULL;
- local = frame->local;
- priv = this->private;
+ local = frame->local;
- STACK_WIND_COOKIE (frame, afr_setxattr_wind_cbk, (void *) (long) subvol,
- priv->children[subvol],
- priv->children[subvol]->fops->setxattr,
- &local->loc, local->cont.setxattr.dict,
- local->cont.setxattr.flags, local->xdata_req);
- return 0;
+ local->transaction.unwind (frame, this);
+
+ AFR_STACK_DESTROY (frame);
+
+ return 0;
}
int
-afr_setxattr (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *dict,
- int32_t flags, dict_t *xdata)
+afr_setattr (call_frame_t *frame, xlator_t *this,
+ loc_t *loc, struct stat *buf, int32_t valid)
{
- afr_local_t *local = NULL;
- call_frame_t *transaction_frame = NULL;
- int ret = -1;
- int op_errno = EINVAL;
-
- GF_IF_INTERNAL_XATTR_GOTO ("trusted.afr.*", dict,
- op_errno, out);
+ afr_private_t * priv = NULL;
+ afr_local_t * local = NULL;
+ call_frame_t *transaction_frame = NULL;
- GF_IF_INTERNAL_XATTR_GOTO ("trusted.glusterfs.afr.*", dict,
- op_errno, out);
+ int ret = -1;
- transaction_frame = copy_frame (frame);
- if (!transaction_frame)
- goto out;
+ int op_ret = -1;
+ int op_errno = 0;
- local = AFR_FRAME_INIT (transaction_frame, op_errno);
- if (!local)
- goto out;
+ VALIDATE_OR_GOTO (frame, out);
+ VALIDATE_OR_GOTO (this, out);
+ VALIDATE_OR_GOTO (this->private, out);
- local->cont.setxattr.dict = dict_ref (dict);
- local->cont.setxattr.flags = flags;
- if (xdata)
- local->xdata_req = dict_copy_with_ref (xdata, NULL);
- else
- local->xdata_req = dict_new ();
+ priv = this->private;
- if (!local->xdata_req)
+ transaction_frame = copy_frame (frame);
+ if (!transaction_frame) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory.");
goto out;
+ }
- local->transaction.wind = afr_setxattr_wind;
- local->transaction.fop = __afr_txn_write_fop;
- local->transaction.done = __afr_txn_write_done;
- local->transaction.unwind = afr_setxattr_unwind;
-
- loc_copy (&local->loc, loc);
- local->inode = inode_ref (loc->inode);
-
- local->transaction.main_frame = frame;
- local->transaction.start = LLONG_MAX - 1;
- local->transaction.len = 0;
-
- local->op = GF_FOP_SETXATTR;
+ ALLOC_OR_GOTO (local, afr_local_t, out);
- ret = afr_transaction (transaction_frame, this, AFR_METADATA_TRANSACTION);
- if (ret < 0) {
+ ret = AFR_LOCAL_INIT (local, priv);
+ if (ret < 0) {
op_errno = -ret;
goto out;
- }
-
- return 0;
-out:
- if (transaction_frame)
- AFR_STACK_DESTROY (transaction_frame);
+ }
- AFR_STACK_UNWIND (setxattr, frame, -1, op_errno, NULL);
+ transaction_frame->local = local;
- return 0;
-}
+ local->op_ret = -1;
-/* {{{ fsetxattr */
+ local->cont.setattr.ino = loc->inode->ino;
+ local->cont.setattr.in_buf = *buf;
+ local->cont.setattr.valid = valid;
-int
-afr_fsetxattr_unwind (call_frame_t *frame, xlator_t *this)
-{
- afr_local_t *local = NULL;
- call_frame_t *main_frame = NULL;
+ local->transaction.fop = afr_setattr_wind;
+ local->transaction.done = afr_setattr_done;
+ local->transaction.unwind = afr_setattr_unwind;
- local = frame->local;
+ loc_copy (&local->loc, loc);
- main_frame = afr_transaction_detach_fop_frame (frame);
- if (!main_frame)
- return 0;
+ local->transaction.main_frame = frame;
+ local->transaction.start = LLONG_MAX - 1;
+ local->transaction.len = 0;
- AFR_STACK_UNWIND (fsetxattr, main_frame, local->op_ret, local->op_errno,
- local->xdata_rsp);
- return 0;
-}
+ afr_transaction (transaction_frame, this, AFR_METADATA_TRANSACTION);
+ op_ret = 0;
+out:
+ if (op_ret == -1) {
+ if (transaction_frame)
+ AFR_STACK_DESTROY (transaction_frame);
+ AFR_STACK_UNWIND (setattr, frame, op_ret, op_errno, NULL, NULL);
+ }
-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)
-{
- return __afr_inode_write_cbk (frame, cookie, this, op_ret, op_errno,
- NULL, NULL, xdata);
+ return 0;
}
+/* {{{ fsetattr */
int
-afr_fsetxattr_wind (call_frame_t *frame, xlator_t *this, int subvol)
+afr_fsetattr_unwind (call_frame_t *frame, xlator_t *this)
{
- afr_local_t *local = NULL;
- afr_private_t *priv = NULL;
+ afr_local_t * local = NULL;
+ afr_private_t * priv = NULL;
+ call_frame_t *main_frame = NULL;
- local = frame->local;
- priv = this->private;
+ local = frame->local;
+ priv = this->private;
- STACK_WIND_COOKIE (frame, afr_fsetxattr_wind_cbk, (void *) (long) subvol,
- priv->children[subvol],
- priv->children[subvol]->fops->fsetxattr,
- local->fd, local->cont.fsetxattr.dict,
- local->cont.fsetxattr.flags, local->xdata_req);
- return 0;
+ 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) {
+ local->cont.fsetattr.preop_buf.st_ino =
+ local->cont.fsetattr.ino;
+ local->cont.fsetattr.postop_buf.st_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);
+ }
+
+ 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_fsetattr_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno,
+ struct stat *preop, struct stat *postop)
{
- afr_local_t *local = NULL;
- call_frame_t *transaction_frame = NULL;
- int ret = -1;
- int op_errno = ENOMEM;
+ afr_local_t * local = NULL;
+ afr_private_t * priv = NULL;
- GF_IF_INTERNAL_XATTR_GOTO ("trusted.afr.*", dict,
- op_errno, out);
+ int child_index = (long) cookie;
+ int read_child = 0;
+ int call_count = -1;
+ int need_unwind = 0;
- GF_IF_INTERNAL_XATTR_GOTO ("trusted.glusterfs.afr.*", dict,
- op_errno, out);
+ local = frame->local;
+ priv = this->private;
- transaction_frame = copy_frame (frame);
- if (!transaction_frame)
- goto out;
+ read_child = afr_read_child (this, local->fd->inode);
- local = AFR_FRAME_INIT (transaction_frame, op_errno);
- if (!local)
- goto out;
+ LOCK (&frame->lock);
+ {
+ if (child_index == read_child) {
+ local->read_child_returned = _gf_true;
+ }
- local->cont.fsetxattr.dict = dict_ref (dict);
- local->cont.fsetxattr.flags = flags;
+ if (afr_fop_failed (op_ret, op_errno))
+ afr_transaction_fop_failed (frame, this, child_index);
- if (xdata)
- local->xdata_req = dict_copy_with_ref (xdata, NULL);
- else
- local->xdata_req = dict_new ();
+ if (op_ret != -1) {
+ if (local->success_count == 0) {
+ local->op_ret = op_ret;
+ local->cont.fsetattr.preop_buf = *preop;
+ local->cont.fsetattr.postop_buf = *postop;
+ }
- if (!local->xdata_req)
- goto out;
+ if (child_index == read_child) {
+ local->cont.fsetattr.preop_buf = *preop;
+ local->cont.fsetattr.postop_buf = *postop;
+ }
- local->transaction.wind = afr_fsetxattr_wind;
- local->transaction.fop = __afr_txn_write_fop;
- local->transaction.done = __afr_txn_write_done;
- local->transaction.unwind = afr_fsetxattr_unwind;
+ local->success_count++;
- local->fd = fd_ref (fd);
- local->inode = inode_ref (fd->inode);
+ if ((local->success_count >= priv->wait_count)
+ && local->read_child_returned) {
+ need_unwind = 1;
+ }
+ }
+ local->op_errno = op_errno;
+ }
+ UNLOCK (&frame->lock);
- local->op = GF_FOP_FSETXATTR;
+ if (need_unwind)
+ local->transaction.unwind (frame, this);
- local->transaction.main_frame = frame;
- local->transaction.start = LLONG_MAX - 1;
- local->transaction.len = 0;
+ call_count = afr_frame_return (frame);
- ret = afr_transaction (transaction_frame, this, AFR_METADATA_TRANSACTION);
- if (ret < 0) {
- op_errno = -ret;
- goto out;
- }
+ if (call_count == 0) {
+ local->transaction.resume (frame, this);
+ }
return 0;
-out:
- if (transaction_frame)
- AFR_STACK_DESTROY (transaction_frame);
-
- AFR_STACK_UNWIND (fsetxattr, frame, -1, op_errno, NULL);
- return 0;
}
-/* }}} */
+int32_t
+afr_fsetattr_wind (call_frame_t *frame, xlator_t *this)
+{
+ afr_local_t *local = NULL;
+ afr_private_t *priv = NULL;
-/* {{{ removexattr */
-
+ int call_count = -1;
+ int i = 0;
-int
-afr_removexattr_unwind (call_frame_t *frame, xlator_t *this)
-{
- afr_local_t * local = NULL;
- call_frame_t *main_frame = NULL;
+ local = frame->local;
+ priv = this->private;
- local = frame->local;
+ call_count = afr_up_children_count (priv->child_count, local->child_up);
- main_frame = afr_transaction_detach_fop_frame (frame);
- if (!main_frame)
+ if (call_count == 0) {
+ local->transaction.resume (frame, this);
return 0;
+ }
- AFR_STACK_UNWIND (removexattr, main_frame, local->op_ret, local->op_errno,
- local->xdata_rsp);
- return 0;
-}
+ local->call_count = call_count;
+ for (i = 0; i < priv->child_count; 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);
+
+ if (!--call_count)
+ break;
+ }
+ }
-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)
-{
- return __afr_inode_write_cbk (frame, cookie, this, op_ret, op_errno,
- NULL, NULL, xdata);
+ return 0;
}
int
-afr_removexattr_wind (call_frame_t *frame, xlator_t *this, int subvol)
+afr_fsetattr_done (call_frame_t *frame, xlator_t *this)
{
- afr_local_t *local = NULL;
- afr_private_t *priv = NULL;
+ afr_local_t *local = NULL;
local = frame->local;
- priv = this->private;
- STACK_WIND_COOKIE (frame, afr_removexattr_wind_cbk, (void *) (long) subvol,
- priv->children[subvol],
- priv->children[subvol]->fops->removexattr,
- &local->loc, local->cont.removexattr.name,
- local->xdata_req);
- return 0;
+ local->transaction.unwind (frame, this);
+
+ AFR_STACK_DESTROY (frame);
+
+ return 0;
}
int
-afr_removexattr (call_frame_t *frame, xlator_t *this,
- loc_t *loc, const char *name, dict_t *xdata)
+afr_fsetattr (call_frame_t *frame, xlator_t *this,
+ fd_t *fd, struct stat *buf, int32_t valid)
{
- afr_local_t *local = NULL;
- call_frame_t *transaction_frame = NULL;
- int ret = -1;
- int op_errno = ENOMEM;
+ afr_private_t * priv = NULL;
+ afr_local_t * local = NULL;
+ call_frame_t *transaction_frame = NULL;
- GF_IF_NATIVE_XATTR_GOTO ("trusted.afr.*",
- name, op_errno, out);
+ int ret = -1;
- GF_IF_NATIVE_XATTR_GOTO ("trusted.glusterfs.afr.*",
- name, op_errno, out);
+ int op_ret = -1;
+ int op_errno = 0;
- transaction_frame = copy_frame (frame);
- if (!transaction_frame)
- goto out;
+ VALIDATE_OR_GOTO (frame, out);
+ VALIDATE_OR_GOTO (this, out);
+ VALIDATE_OR_GOTO (this->private, out);
- local = AFR_FRAME_INIT (transaction_frame, op_errno);
- if (!local)
- goto out;
+ priv = this->private;
- local->cont.removexattr.name = gf_strdup (name);
+ transaction_frame = copy_frame (frame);
+ if (!transaction_frame) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory.");
+ goto out;
+ }
- if (xdata)
- local->xdata_req = dict_copy_with_ref (xdata, NULL);
- else
- local->xdata_req = dict_new ();
+ ALLOC_OR_GOTO (local, afr_local_t, out);
- if (!local->xdata_req)
+ ret = AFR_LOCAL_INIT (local, priv);
+ if (ret < 0) {
+ op_errno = -ret;
goto out;
+ }
- local->transaction.wind = afr_removexattr_wind;
- local->transaction.fop = __afr_txn_write_fop;
- local->transaction.done = __afr_txn_write_done;
- local->transaction.unwind = afr_removexattr_unwind;
-
- loc_copy (&local->loc, loc);
- local->inode = inode_ref (loc->inode);
+ transaction_frame->local = local;
- local->op = GF_FOP_REMOVEXATTR;
+ local->op_ret = -1;
- local->transaction.main_frame = frame;
- local->transaction.start = LLONG_MAX - 1;
- local->transaction.len = 0;
+ local->cont.fsetattr.ino = fd->inode->ino;
- ret = afr_transaction (transaction_frame, this, AFR_METADATA_TRANSACTION);
- if (ret < 0) {
- op_errno = -ret;
- goto out;
- }
+ local->cont.fsetattr.in_buf = *buf;
+ local->cont.fsetattr.valid = valid;
- return 0;
-out:
- if (transaction_frame)
- AFR_STACK_DESTROY (transaction_frame);
+ local->transaction.fop = afr_fsetattr_wind;
+ local->transaction.done = afr_fsetattr_done;
+ local->transaction.unwind = afr_fsetattr_unwind;
- AFR_STACK_UNWIND (removexattr, frame, -1, op_errno, NULL);
- return 0;
-}
+ local->fd = fd_ref (fd);
-/* ffremovexattr */
-int
-afr_fremovexattr_unwind (call_frame_t *frame, xlator_t *this)
-{
- afr_local_t * local = NULL;
- call_frame_t *main_frame = NULL;
+ local->transaction.main_frame = frame;
+ local->transaction.start = LLONG_MAX - 1;
+ local->transaction.len = 0;
- local = frame->local;
+ afr_transaction (transaction_frame, this, AFR_METADATA_TRANSACTION);
- main_frame = afr_transaction_detach_fop_frame (frame);
- if (!main_frame)
- return 0;
+ op_ret = 0;
+out:
+ if (op_ret == -1) {
+ if (transaction_frame)
+ AFR_STACK_DESTROY (transaction_frame);
+ AFR_STACK_UNWIND (fsetattr, frame, op_ret, op_errno, NULL, NULL);
+ }
- AFR_STACK_UNWIND (fremovexattr, main_frame, local->op_ret, local->op_errno,
- local->xdata_rsp);
- return 0;
+ 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)
-{
- return __afr_inode_write_cbk (frame, cookie, this, op_ret, op_errno,
- NULL, NULL, xdata);
-}
+/* {{{ setxattr */
int
-afr_fremovexattr_wind (call_frame_t *frame, xlator_t *this, int subvol)
+afr_setxattr_unwind (call_frame_t *frame, xlator_t *this)
{
- afr_local_t *local = NULL;
- afr_private_t *priv = NULL;
+ afr_local_t * local = NULL;
+ afr_private_t * priv = NULL;
+ call_frame_t *main_frame = NULL;
- local = frame->local;
- priv = this->private;
+ local = frame->local;
+ priv = this->private;
- STACK_WIND_COOKIE (frame, afr_fremovexattr_wind_cbk, (void *) (long) subvol,
- priv->children[subvol],
- priv->children[subvol]->fops->fremovexattr,
- local->fd, local->cont.removexattr.name,
- local->xdata_req);
- return 0;
+ 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 (setxattr, main_frame,
+ local->op_ret, local->op_errno)
+ }
+ return 0;
}
int
-afr_fremovexattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
- const char *name, dict_t *xdata)
+afr_setxattr_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno)
{
- afr_local_t *local = NULL;
- call_frame_t *transaction_frame = NULL;
- int ret = -1;
- int op_errno = ENOMEM;
-
- GF_IF_NATIVE_XATTR_GOTO ("trusted.afr.*",
- name, op_errno, out);
+ afr_local_t * local = NULL;
+ afr_private_t * priv = NULL;
- GF_IF_NATIVE_XATTR_GOTO ("trusted.glusterfs.afr.*",
- name, op_errno, out);
+ int call_count = -1;
+ int need_unwind = 0;
- transaction_frame = copy_frame (frame);
- if (!transaction_frame)
- goto out;
-
- local = AFR_FRAME_INIT (transaction_frame, op_errno);
- if (!local)
- goto out;
-
- local->cont.removexattr.name = gf_strdup (name);
- if (xdata)
- local->xdata_req = dict_copy_with_ref (xdata, NULL);
- else
- local->xdata_req = dict_new ();
-
- if (!local->xdata_req)
- goto out;
+ local = frame->local;
+ priv = this->private;
- local->transaction.wind = afr_fremovexattr_wind;
- local->transaction.fop = __afr_txn_write_fop;
- local->transaction.done = __afr_txn_write_done;
- local->transaction.unwind = afr_fremovexattr_unwind;
+ LOCK (&frame->lock);
+ {
+ if (op_ret != -1) {
+ if (local->success_count == 0) {
+ local->op_ret = op_ret;
+ }
+ local->success_count++;
- local->fd = fd_ref (fd);
- local->inode = inode_ref (fd->inode);
+ if (local->success_count == priv->wait_count) {
+ need_unwind = 1;
+ }
+ }
- local->op = GF_FOP_FREMOVEXATTR;
+ local->op_errno = op_errno;
+ }
+ UNLOCK (&frame->lock);
- local->transaction.main_frame = frame;
- local->transaction.start = LLONG_MAX - 1;
- local->transaction.len = 0;
+ if (need_unwind)
+ local->transaction.unwind (frame, this);
- ret = afr_transaction (transaction_frame, this, AFR_METADATA_TRANSACTION);
- if (ret < 0) {
- op_errno = -ret;
- goto out;
- }
+ call_count = afr_frame_return (frame);
+ if (call_count == 0) {
+ local->transaction.resume (frame, this);
+ }
+
return 0;
-out:
- if (transaction_frame)
- AFR_STACK_DESTROY (transaction_frame);
-
- AFR_STACK_UNWIND (fremovexattr, frame, -1, op_errno, NULL);
-
- return 0;
}
int
-afr_fallocate_unwind (call_frame_t *frame, xlator_t *this)
+afr_setxattr_wind (call_frame_t *frame, xlator_t *this)
{
- afr_local_t * local = NULL;
- call_frame_t *main_frame = NULL;
+ afr_local_t *local = NULL;
+ afr_private_t *priv = NULL;
- local = frame->local;
+ int call_count = -1;
+ int i = 0;
- main_frame = afr_transaction_detach_fop_frame (frame);
- if (!main_frame)
+ local = frame->local;
+ priv = this->private;
+
+ call_count = afr_up_children_count (priv->child_count, local->child_up);
+
+ if (call_count == 0) {
+ local->transaction.resume (frame, this);
return 0;
+ }
- AFR_STACK_UNWIND (fallocate, main_frame, local->op_ret, local->op_errno,
- &local->cont.inode_wfop.prebuf,
- &local->cont.inode_wfop.postbuf, local->xdata_rsp);
- return 0;
-}
+ local->call_count = call_count;
+ for (i = 0; i < priv->child_count; 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);
-int
-afr_fallocate_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)
-{
- return __afr_inode_write_cbk (frame, cookie, this, op_ret, op_errno,
- prebuf, postbuf, xdata);
+ if (!--call_count)
+ break;
+ }
+ }
+
+ return 0;
}
int
-afr_fallocate_wind (call_frame_t *frame, xlator_t *this, int subvol)
+afr_setxattr_done (call_frame_t *frame, xlator_t *this)
{
- afr_local_t *local = NULL;
- afr_private_t *priv = NULL;
+ afr_local_t * local = frame->local;
- local = frame->local;
- priv = this->private;
-
- STACK_WIND_COOKIE (frame, afr_fallocate_wind_cbk, (void *) (long) subvol,
- priv->children[subvol],
- priv->children[subvol]->fops->fallocate,
- local->fd, local->cont.fallocate.mode,
- local->cont.fallocate.offset,
- local->cont.fallocate.len, local->xdata_req);
- return 0;
+ local->transaction.unwind (frame, this);
+
+ AFR_STACK_DESTROY (frame);
+
+ return 0;
}
int
-afr_fallocate (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t mode,
- off_t offset, size_t len, dict_t *xdata)
+afr_setxattr (call_frame_t *frame, xlator_t *this,
+ loc_t *loc, dict_t *dict, int32_t flags)
{
- call_frame_t *transaction_frame = NULL;
- afr_local_t *local = NULL;
- int ret = -1;
- int op_errno = ENOMEM;
+ afr_private_t * priv = NULL;
+ afr_local_t * local = NULL;
+ call_frame_t *transaction_frame = NULL;
- transaction_frame = copy_frame (frame);
- if (!transaction_frame)
- goto out;
+ int ret = -1;
- local = AFR_FRAME_INIT (transaction_frame, op_errno);
- if (!local)
- goto out;
+ int op_ret = -1;
+ int op_errno = 0;
+
+ VALIDATE_OR_GOTO (frame, out);
+ VALIDATE_OR_GOTO (this, out);
+ VALIDATE_OR_GOTO (this->private, out);
- local->cont.fallocate.mode = mode;
- local->cont.fallocate.offset = offset;
- local->cont.fallocate.len = len;
+ priv = this->private;
- local->fd = fd_ref (fd);
- local->inode = inode_ref (fd->inode);
+ transaction_frame = copy_frame (frame);
+ if (!transaction_frame) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory.");
+ goto out;
+ }
- if (xdata)
- local->xdata_req = dict_copy_with_ref (xdata, NULL);
- else
- local->xdata_req = dict_new ();
+ ALLOC_OR_GOTO (local, afr_local_t, out);
- if (!local->xdata_req)
+ ret = AFR_LOCAL_INIT (local, priv);
+ if (ret < 0) {
+ op_errno = -ret;
goto out;
+ }
- local->op = GF_FOP_FALLOCATE;
+ transaction_frame->local = local;
- local->transaction.wind = afr_fallocate_wind;
- local->transaction.fop = __afr_txn_write_fop;
- local->transaction.done = __afr_txn_write_done;
- local->transaction.unwind = afr_fallocate_unwind;
+ local->op_ret = -1;
- local->transaction.main_frame = frame;
+ local->cont.setxattr.dict = dict_ref (dict);
+ local->cont.setxattr.flags = flags;
- local->transaction.start = local->cont.fallocate.offset;
- local->transaction.len = 0;
+ local->transaction.fop = afr_setxattr_wind;
+ local->transaction.done = afr_setxattr_done;
+ local->transaction.unwind = afr_setxattr_unwind;
- afr_fix_open (fd, this);
+ loc_copy (&local->loc, loc);
- ret = afr_transaction (transaction_frame, this, AFR_DATA_TRANSACTION);
- if (ret < 0) {
- op_errno = -ret;
- goto out;
- }
+ local->transaction.main_frame = frame;
+ local->transaction.start = LLONG_MAX - 1;
+ local->transaction.len = 0;
- return 0;
+ afr_transaction (transaction_frame, this, AFR_METADATA_TRANSACTION);
+
+ op_ret = 0;
out:
- if (transaction_frame)
- AFR_STACK_DESTROY (transaction_frame);
+ if (op_ret == -1) {
+ if (transaction_frame)
+ AFR_STACK_DESTROY (transaction_frame);
+ AFR_STACK_UNWIND (setxattr, frame, op_ret, op_errno);
+ }
- AFR_STACK_UNWIND (fallocate, frame, -1, op_errno, NULL, NULL, NULL);
- return 0;
+ return 0;
}
-
/* }}} */
-/* {{{ discard */
+/* {{{ removexattr */
+
int
-afr_discard_unwind (call_frame_t *frame, xlator_t *this)
+afr_removexattr_unwind (call_frame_t *frame, xlator_t *this)
{
- afr_local_t * local = NULL;
- call_frame_t *main_frame = NULL;
+ afr_local_t * local = NULL;
+ afr_private_t * priv = NULL;
+ call_frame_t *main_frame = NULL;
- local = frame->local;
-
- main_frame = afr_transaction_detach_fop_frame (frame);
- if (!main_frame)
- return 0;
-
- AFR_STACK_UNWIND (discard, main_frame, local->op_ret, local->op_errno,
- &local->cont.inode_wfop.prebuf,
- &local->cont.inode_wfop.postbuf, local->xdata_rsp);
- return 0;
-}
+ local = frame->local;
+ priv = this->private;
+ LOCK (&frame->lock);
+ {
+ if (local->transaction.main_frame)
+ main_frame = local->transaction.main_frame;
+ local->transaction.main_frame = NULL;
+ }
+ UNLOCK (&frame->lock);
-int
-afr_discard_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)
-{
- return __afr_inode_write_cbk (frame, cookie, this, op_ret, op_errno,
- prebuf, postbuf, xdata);
+ if (main_frame) {
+ AFR_STACK_UNWIND (removexattr, main_frame,
+ local->op_ret, local->op_errno)
+ }
+ return 0;
}
int
-afr_discard_wind (call_frame_t *frame, xlator_t *this, int subvol)
+afr_removexattr_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno)
{
- afr_local_t *local = NULL;
- afr_private_t *priv = NULL;
+ afr_local_t * local = NULL;
+ afr_private_t * priv = NULL;
- local = frame->local;
- priv = this->private;
+ int call_count = -1;
+ int need_unwind = 0;
- STACK_WIND_COOKIE (frame, afr_discard_wind_cbk, (void *) (long) subvol,
- priv->children[subvol],
- priv->children[subvol]->fops->discard,
- local->fd, local->cont.discard.offset,
- local->cont.discard.len, local->xdata_req);
- return 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++;
-int
-afr_discard (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
- size_t len, dict_t *xdata)
-{
- afr_local_t *local = NULL;
- call_frame_t *transaction_frame = NULL;
- int ret = -1;
- int op_errno = ENOMEM;
+ if (local->success_count == priv->wait_count) {
+ need_unwind = 1;
+ }
+ }
- transaction_frame = copy_frame (frame);
- if (!transaction_frame)
- goto out;
+ local->op_errno = op_errno;
+ }
+ UNLOCK (&frame->lock);
- local = AFR_FRAME_INIT (transaction_frame, op_errno);
- if (!local)
- goto out;
+ if (need_unwind)
+ local->transaction.unwind (frame, this);
- local->cont.discard.offset = offset;
- local->cont.discard.len = len;
+ call_count = afr_frame_return (frame);
- local->fd = fd_ref (fd);
- local->inode = inode_ref (fd->inode);
+ if (call_count == 0) {
+ local->transaction.resume (frame, this);
+ }
+
+ return 0;
+}
- if (xdata)
- local->xdata_req = dict_copy_with_ref (xdata, NULL);
- else
- local->xdata_req = dict_new ();
- if (!local->xdata_req)
- goto out;
+int32_t
+afr_removexattr_wind (call_frame_t *frame, xlator_t *this)
+{
+ afr_local_t *local = NULL;
+ afr_private_t *priv = NULL;
- local->op = GF_FOP_DISCARD;
+ int call_count = -1;
+ int i = 0;
- local->transaction.wind = afr_discard_wind;
- local->transaction.fop = __afr_txn_write_fop;
- local->transaction.done = __afr_txn_write_done;
- local->transaction.unwind = afr_discard_unwind;
+ local = frame->local;
+ priv = this->private;
- local->transaction.main_frame = frame;
+ call_count = afr_up_children_count (priv->child_count, local->child_up);
- local->transaction.start = local->cont.discard.offset;
- local->transaction.len = 0;
+ if (call_count == 0) {
+ local->transaction.resume (frame, this);
+ return 0;
+ }
- afr_fix_open (fd, this);
+ local->call_count = call_count;
- ret = afr_transaction (transaction_frame, this, AFR_DATA_TRANSACTION);
- if (ret < 0) {
- op_errno = -ret;
- goto out;
- }
+ for (i = 0; i < priv->child_count; 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);
+ if (!--call_count)
+ break;
+ }
+ }
+
return 0;
-out:
- if (transaction_frame)
- AFR_STACK_DESTROY (transaction_frame);
-
- AFR_STACK_UNWIND (discard, frame, -1, op_errno, NULL, NULL, NULL);
- return 0;
}
-/* {{{ zerofill */
-
int
-afr_zerofill_unwind (call_frame_t *frame, xlator_t *this)
+afr_removexattr_done (call_frame_t *frame, xlator_t *this)
{
- afr_local_t * local = NULL;
- call_frame_t *main_frame = NULL;
-
- local = frame->local;
+ afr_local_t * local = frame->local;
- main_frame = afr_transaction_detach_fop_frame (frame);
- if (!main_frame)
- return 0;
+ local->transaction.unwind (frame, this);
- AFR_STACK_UNWIND (discard, main_frame, local->op_ret, local->op_errno,
- &local->cont.inode_wfop.prebuf,
- &local->cont.inode_wfop.postbuf, local->xdata_rsp);
- return 0;
+ AFR_STACK_DESTROY (frame);
+
+ return 0;
}
int
-afr_zerofill_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)
+afr_removexattr (call_frame_t *frame, xlator_t *this,
+ loc_t *loc, const char *name)
{
- return __afr_inode_write_cbk (frame, cookie, this, op_ret, op_errno,
- prebuf, postbuf, xdata);
-}
+ afr_private_t * priv = NULL;
+ afr_local_t * local = NULL;
+ call_frame_t *transaction_frame = NULL;
+ int ret = -1;
-int
-afr_zerofill_wind (call_frame_t *frame, xlator_t *this, int subvol)
-{
- afr_local_t *local = NULL;
- afr_private_t *priv = NULL;
-
- local = frame->local;
- priv = this->private;
+ int op_ret = -1;
+ int op_errno = 0;
- STACK_WIND_COOKIE (frame, afr_zerofill_wind_cbk, (void *) (long) subvol,
- priv->children[subvol],
- priv->children[subvol]->fops->zerofill,
- local->fd, local->cont.zerofill.offset,
- local->cont.zerofill.len, local->xdata_req);
- return 0;
-}
+ VALIDATE_OR_GOTO (frame, out);
+ VALIDATE_OR_GOTO (this, out);
+ VALIDATE_OR_GOTO (this->private, out);
+ VALIDATE_OR_GOTO (loc, out);
-int
-afr_zerofill (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
- size_t len, dict_t *xdata)
-{
- afr_local_t *local = NULL;
- call_frame_t *transaction_frame = NULL;
- int ret = -1;
- int op_errno = ENOMEM;
+ priv = this->private;
transaction_frame = copy_frame (frame);
- if (!transaction_frame)
+ if (!transaction_frame) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory.");
goto out;
+ }
- local = AFR_FRAME_INIT (transaction_frame, op_errno);
- if (!local)
- goto out;
-
- local->cont.zerofill.offset = offset;
- local->cont.zerofill.len = len;
-
- local->fd = fd_ref (fd);
- local->inode = inode_ref (fd->inode);
-
- if (xdata)
- local->xdata_req = dict_copy_with_ref (xdata, NULL);
- else
- local->xdata_req = dict_new ();
+ ALLOC_OR_GOTO (local, afr_local_t, out);
- if (!local->xdata_req)
+ ret = AFR_LOCAL_INIT (local, priv);
+ if (ret < 0) {
+ op_errno = -ret;
goto out;
+ }
- local->op = GF_FOP_ZEROFILL;
+ transaction_frame->local = local;
- local->transaction.wind = afr_zerofill_wind;
- local->transaction.fop = __afr_txn_write_fop;
- local->transaction.done = __afr_txn_write_done;
- local->transaction.unwind = afr_zerofill_unwind;
+ local->op_ret = -1;
- local->transaction.main_frame = frame;
+ local->cont.removexattr.name = strdup (name);
- local->transaction.start = local->cont.discard.offset;
- local->transaction.len = len;
+ local->transaction.fop = afr_removexattr_wind;
+ local->transaction.done = afr_removexattr_done;
+ local->transaction.unwind = afr_removexattr_unwind;
- afr_fix_open (fd, this);
+ loc_copy (&local->loc, loc);
- ret = afr_transaction (transaction_frame, this, AFR_DATA_TRANSACTION);
- if (ret < 0) {
- op_errno = -ret;
- goto out;
- }
+ local->transaction.main_frame = frame;
+ local->transaction.start = LLONG_MAX - 1;
+ local->transaction.len = 0;
- return 0;
+ afr_transaction (transaction_frame, this, AFR_METADATA_TRANSACTION);
+
+ op_ret = 0;
out:
- if (transaction_frame)
- AFR_STACK_DESTROY (transaction_frame);
+ if (op_ret == -1) {
+ if (transaction_frame)
+ AFR_STACK_DESTROY (transaction_frame);
+ AFR_STACK_UNWIND (removexattr, frame, op_ret, op_errno);
+ }
- AFR_STACK_UNWIND (zerofill, frame, -1, op_errno, NULL, NULL, NULL);
- return 0;
+ return 0;
}
-
-/* }}} */
diff --git a/xlators/cluster/afr/src/afr-inode-write.h b/xlators/cluster/afr/src/afr-inode-write.h
index 7b1fc552880..66da777b622 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-2009 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 __INODE_WRITE_H__
@@ -13,70 +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 stat *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 stat *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);
-int
-afr_discard (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
- size_t len, dict_t *xdata);
-
-int
-afr_fallocate (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t mode,
- off_t offset, size_t len, dict_t *xdata);
-
-int
-afr_zerofill(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
- off_t len, dict_t *xdata);
#endif /* __INODE_WRITE_H__ */
diff --git a/xlators/cluster/afr/src/afr-lk-common.c b/xlators/cluster/afr/src/afr-lk-common.c
deleted file mode 100644
index e3e70007706..00000000000
--- a/xlators/cluster/afr/src/afr-lk-common.c
+++ /dev/null
@@ -1,1669 +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 "dict.h"
-#include "byte-order.h"
-#include "common-utils.h"
-
-#include "afr.h"
-#include "afr-transaction.h"
-
-#include <signal.h>
-
-
-#define LOCKED_NO 0x0 /* no lock held */
-#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_entry_lockee_cmp (const void *l1, const void *l2)
-{
- const afr_entry_lockee_t *r1 = l1;
- const afr_entry_lockee_t *r2 = l2;
- int ret = 0;
- uuid_t gfid1 = {0};
- uuid_t gfid2 = {0};
-
- loc_gfid ((loc_t*)&r1->loc, gfid1);
- loc_gfid ((loc_t*)&r2->loc, gfid2);
- ret = uuid_compare (gfid1, gfid2);
- /*Entrylks with NULL basename are the 'smallest'*/
- if (ret == 0) {
- if (!r1->basename)
- return -1;
- if (!r2->basename)
- return 1;
- ret = strcmp (r1->basename, r2->basename);
- }
-
- if (ret <= 0)
- return -1;
- else
- return 1;
-}
-
-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
-get_afr_lock_number ()
-{
- return (++afr_lock_number);
-}
-
-int
-afr_set_lock_number (call_frame_t *frame, xlator_t *this)
-{
- afr_local_t *local = NULL;
- afr_internal_lock_t *int_lock = NULL;
-
- local = frame->local;
- int_lock = &local->internal_lock;
-
- int_lock->lock_number = get_afr_lock_number ();
-
- return 0;
-}
-
-void
-afr_set_lk_owner (call_frame_t *frame, xlator_t *this, void *lk_owner)
-{
- 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);
-}
-
-static int
-is_afr_lock_selfheal (afr_local_t *local)
-{
- afr_internal_lock_t *int_lock = NULL;
- int ret = -1;
-
- int_lock = &local->internal_lock;
-
- switch (int_lock->selfheal_lk_type) {
- case AFR_DATA_SELF_HEAL_LK:
- case AFR_METADATA_SELF_HEAL_LK:
- ret = 1;
- break;
- case AFR_ENTRY_SELF_HEAL_LK:
- ret = 0;
- break;
- }
-
- return ret;
-
-}
-
-int32_t
-internal_lock_count (call_frame_t *frame, xlator_t *this)
-{
- afr_local_t *local = NULL;
- afr_private_t *priv = NULL;
- int32_t call_count = 0;
- int i = 0;
-
- local = frame->local;
- priv = this->private;
-
- for (i = 0; i < priv->child_count; i++) {
- if (local->child_up[i])
- ++call_count;
- }
-
- return call_count;
-}
-
-static void
-afr_print_inodelk (char *str, int size, int cmd,
- struct gf_flock *flock, gf_lkowner_t *owner)
-{
- char *cmd_str = NULL;
- char *type_str = NULL;
-
- switch (cmd) {
-#if F_GETLK != F_GETLK64
- case F_GETLK64:
-#endif
- case F_GETLK:
- cmd_str = "GETLK";
- break;
-
-#if F_SETLK != F_SETLK64
- case F_SETLK64:
-#endif
- case F_SETLK:
- cmd_str = "SETLK";
- break;
-
-#if F_SETLKW != F_SETLKW64
- case F_SETLKW64:
-#endif
- case F_SETLKW:
- cmd_str = "SETLKW";
- break;
-
- default:
- cmd_str = "<null>";
- break;
- }
-
- switch (flock->l_type) {
- case F_RDLCK:
- type_str = "READ";
- break;
- case F_WRLCK:
- type_str = "WRITE";
- break;
- case F_UNLCK:
- type_str = "UNLOCK";
- break;
- default:
- type_str = "UNKNOWN";
- break;
- }
-
- snprintf (str, size, "lock=INODELK, cmd=%s, type=%s, "
- "start=%llu, len=%llu, pid=%llu, lk-owner=%s",
- 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));
-
-}
-
-static void
-afr_print_lockee (char *str, int size, loc_t *loc, fd_t *fd,
- int child_index)
-{
- snprintf (str, size, "path=%s, fd=%p, child=%d",
- loc->path ? loc->path : "<nul>",
- fd ? fd : NULL,
- child_index);
-}
-
-void
-afr_print_entrylk (char *str, int size, const char *basename,
- gf_lkowner_t *owner)
-{
- snprintf (str, size, "Basename=%s, lk-owner=%s",
- basename ? basename : "<nul>",
- lkowner_utoa (owner));
-}
-
-static void
-afr_print_verdict (int op_ret, int op_errno, char *str)
-{
- if (op_ret < 0) {
- if (op_errno == EAGAIN)
- strcpy (str, "EAGAIN");
- else
- strcpy (str, "FAILED");
- }
- else
- strcpy (str, "GRANTED");
-}
-
-static void
-afr_set_lock_call_type (afr_lock_call_type_t lock_call_type,
- char *lock_call_type_str,
- afr_internal_lock_t *int_lock)
-{
- switch (lock_call_type) {
- case AFR_INODELK_TRANSACTION:
- if (int_lock->transaction_lk_type == AFR_TRANSACTION_LK)
- strcpy (lock_call_type_str, "AFR_INODELK_TRANSACTION");
- else
- strcpy (lock_call_type_str, "AFR_INODELK_SELFHEAL");
- break;
- case AFR_INODELK_NB_TRANSACTION:
- if (int_lock->transaction_lk_type == AFR_TRANSACTION_LK)
- strcpy (lock_call_type_str, "AFR_INODELK_NB_TRANSACTION");
- else
- strcpy (lock_call_type_str, "AFR_INODELK_NB_SELFHEAL");
- break;
- case AFR_ENTRYLK_TRANSACTION:
- if (int_lock->transaction_lk_type == AFR_TRANSACTION_LK)
- strcpy (lock_call_type_str, "AFR_ENTRYLK_TRANSACTION");
- else
- strcpy (lock_call_type_str, "AFR_ENTRYLK_SELFHEAL");
- break;
- case AFR_ENTRYLK_NB_TRANSACTION:
- if (int_lock->transaction_lk_type == AFR_TRANSACTION_LK)
- strcpy (lock_call_type_str, "AFR_ENTRYLK_NB_TRANSACTION");
- else
- strcpy (lock_call_type_str, "AFR_ENTRYLK_NB_SELFHEAL");
- break;
- default:
- strcpy (lock_call_type_str, "UNKNOWN");
- break;
- }
-
-}
-
-static void
-afr_trace_inodelk_out (call_frame_t *frame, xlator_t *this,
- 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)
-{
- afr_internal_lock_t *int_lock = NULL;
- afr_local_t *local = NULL;
-
- char lockee[256];
- char lock_call_type_str[256];
- char verdict[16];
-
- local = frame->local;
- int_lock = &local->internal_lock;
-
- 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);
-
- 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}",
- lock_call_type_str,
- lk_op_type == AFR_LOCK_OP ? "LOCK REPLY" : "UNLOCK REPLY",
- verdict, lkowner_utoa (&frame->root->lk_owner), 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_lock_op_type_t lk_op_type, struct gf_flock *flock,
- int32_t cmd, int32_t child_index)
-{
- afr_local_t *local = NULL;
- afr_internal_lock_t *int_lock = NULL;
-
- char lock[256];
- char lockee[256];
- char lock_call_type_str[256];
-
- local = frame->local;
- int_lock = &local->internal_lock;
-
- 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);
-
- gf_log (this->name, GF_LOG_INFO,
- "[%s %s] Lock={%s} Lockee={%s} Number={%llu}",
- lock_call_type_str,
- lk_op_type == AFR_LOCK_OP ? "LOCK REQUEST" : "UNLOCK REQUEST",
- lock, lockee,
- (unsigned long long) int_lock->lock_number);
-
-}
-
-static void
-afr_trace_entrylk_in (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,
- int32_t cookie)
-{
- afr_local_t *local = NULL;
- afr_internal_lock_t *int_lock = NULL;
- afr_private_t *priv = NULL;
- int child_index = 0;
- int lockee_no = 0;
-
- char lock[256];
- char lockee[256];
- char lock_call_type_str[256];
-
- local = frame->local;
- int_lock = &local->internal_lock;
- priv = this->private;
-
- if (!priv->entrylk_trace) {
- return;
- }
- lockee_no = cookie / priv->child_count;
- child_index = cookie % priv->child_count;
-
- afr_print_entrylk (lock, 256, basename, &frame->root->lk_owner);
- afr_print_lockee (lockee, 256, &int_lock->lockee[lockee_no].loc, local->fd,
- child_index);
-
- afr_set_lock_call_type (lock_call_type, lock_call_type_str, int_lock);
-
- gf_log (this->name, GF_LOG_INFO,
- "[%s %s] Lock={%s} Lockee={%s} Number={%llu}, Cookie={%d}",
- lock_call_type_str,
- lk_op_type == AFR_LOCK_OP ? "LOCK REQUEST" : "UNLOCK REQUEST",
- lock, lockee,
- (unsigned long long) int_lock->lock_number,
- cookie);
-}
-
-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 cookie)
-{
- afr_internal_lock_t *int_lock = NULL;
- afr_local_t *local = NULL;
- afr_private_t *priv = NULL;
- int lockee_no = 0;
- int child_index = 0;
-
- char lock[256];
- char lockee[256];
- char lock_call_type_str[256];
- char verdict[16];
-
- local = frame->local;
- int_lock = &local->internal_lock;
- priv = this->private;
-
- if (!priv->entrylk_trace) {
- return;
- }
- lockee_no = cookie / priv->child_count;
- child_index = cookie % priv->child_count;
-
- afr_print_entrylk (lock, 256, basename, &frame->root->lk_owner);
- afr_print_lockee (lockee, 256, &int_lock->lockee[lockee_no].loc, local->fd,
- child_index);
-
- afr_set_lock_call_type (lock_call_type, lock_call_type_str, int_lock);
-
- afr_print_verdict (op_ret, op_errno, verdict);
-
- gf_log (this->name, GF_LOG_INFO,
- "[%s %s] [%s] Lock={%s} Lockee={%s} Number={%llu} Cookie={%d}",
- lock_call_type_str,
- lk_op_type == AFR_LOCK_OP ? "LOCK REPLY" : "UNLOCK REPLY",
- verdict,
- lock, lockee,
- (unsigned long long) int_lock->lock_number,
- cookie);
-
-}
-
-static int
-transaction_lk_op (afr_local_t *local)
-{
- afr_internal_lock_t *int_lock = NULL;
- int ret = -1;
-
- int_lock = &local->internal_lock;
-
- if (int_lock->transaction_lk_type == AFR_TRANSACTION_LK) {
- gf_log (THIS->name, GF_LOG_DEBUG,
- "lk op is for a transaction");
- ret = 1;
- }
- else if (int_lock->transaction_lk_type == AFR_SELFHEAL_LK) {
- gf_log (THIS->name, GF_LOG_DEBUG,
- "lk op is for a self heal");
-
- ret = 0;
- }
-
- if (ret == -1)
- gf_log (THIS->name, GF_LOG_DEBUG,
- "lk op is not set");
-
- return ret;
-
-}
-
-static int
-is_afr_lock_transaction (afr_local_t *local)
-{
- int ret = 0;
-
- switch (local->transaction.type) {
- case AFR_DATA_TRANSACTION:
- case AFR_METADATA_TRANSACTION:
- ret = 1;
- break;
-
- case AFR_ENTRY_RENAME_TRANSACTION:
- case AFR_ENTRY_TRANSACTION:
- ret = 0;
- break;
-
- }
-
- return ret;
-}
-
-int
-afr_init_entry_lockee (afr_entry_lockee_t *lockee, afr_local_t *local,
- loc_t *loc, char *basename, int child_count)
-{
- int ret = -1;
-
- loc_copy (&lockee->loc, loc);
- lockee->basename = (basename)? gf_strdup (basename): NULL;
- if (basename && !lockee->basename)
- goto out;
-
- lockee->locked_count = 0;
- lockee->locked_nodes = GF_CALLOC (child_count,
- sizeof (*lockee->locked_nodes),
- gf_afr_mt_afr_node_character);
-
- if (!lockee->locked_nodes)
- goto out;
-
- ret = 0;
-out:
- return ret;
-
-}
-
-void
-afr_entry_lockee_cleanup (afr_internal_lock_t *int_lock)
-{
- int i = 0;
-
- for (i = 0; i < int_lock->lockee_count; i++) {
- loc_wipe (&int_lock->lockee[i].loc);
- if (int_lock->lockee[i].basename)
- GF_FREE (int_lock->lockee[i].basename);
- if (int_lock->lockee[i].locked_nodes)
- GF_FREE (int_lock->lockee[i].locked_nodes);
- }
-
- return;
-}
-
-static int
-initialize_entrylk_variables (call_frame_t *frame, xlator_t *this)
-{
- afr_local_t *local = NULL;
- afr_internal_lock_t *int_lock = NULL;
- afr_private_t *priv = NULL;
-
- int i = 0;
-
- priv = this->private;
- local = frame->local;
- int_lock = &local->internal_lock;
-
- int_lock->entrylk_lock_count = 0;
- int_lock->lock_op_ret = -1;
- int_lock->lock_op_errno = 0;
-
- for (i = 0; i < AFR_LOCKEE_COUNT_MAX; i++) {
- if (!int_lock->lockee[i].locked_nodes)
- break;
- int_lock->lockee[i].locked_count = 0;
- memset (int_lock->lockee[i].locked_nodes, 0,
- sizeof (*int_lock->lockee[i].locked_nodes) *
- priv->child_count);
- }
-
- return 0;
-}
-
-static int
-initialize_inodelk_variables (call_frame_t *frame, xlator_t *this)
-{
- afr_local_t *local = NULL;
- afr_internal_lock_t *int_lock = NULL;
- afr_private_t *priv = NULL;
- afr_inodelk_t *inodelk = NULL;
-
- priv = this->private;
- local = frame->local;
- int_lock = &local->internal_lock;
-
- inodelk = afr_get_inodelk (int_lock, int_lock->domain);
-
- inodelk->lock_count = 0;
- int_lock->lk_attempted_count = 0;
- int_lock->lock_op_ret = -1;
- int_lock->lock_op_errno = 0;
-
- memset (inodelk->locked_nodes, 0,
- sizeof (*inodelk->locked_nodes) * priv->child_count);
- memset (int_lock->locked_nodes, 0,
- sizeof (*int_lock->locked_nodes) * priv->child_count);
-
- return 0;
-}
-
-int
-afr_lockee_locked_nodes_count (afr_internal_lock_t *int_lock)
-{
- int call_count = 0;
- int i = 0;
-
- for (i = 0; i < int_lock->lockee_count; i++)
- call_count += int_lock->lockee[i].locked_count;
-
- return call_count;
-}
-
-int
-afr_locked_nodes_count (unsigned char *locked_nodes, int child_count)
-
-{
- int i = 0;
- int call_count = 0;
-
- for (i = 0; i < child_count; i++) {
- if (locked_nodes[i] & LOCKED_YES)
- call_count++;
- }
-
- return call_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)
-{
- afr_local_t *local = NULL;
- afr_internal_lock_t *int_lock = NULL;
- int call_count = 0;
-
- local = frame->local;
- int_lock = &local->internal_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,
- "All internal locks unlocked");
- int_lock->lock_cbk (frame, this);
- }
-
- return 0;
-}
-
-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)
-{
- afr_local_t *local = NULL;
- afr_internal_lock_t *int_lock = NULL;
- afr_inodelk_t *inodelk = NULL;
- int32_t child_index = (long)cookie;
- afr_private_t *priv = NULL;
-
- local = frame->local;
- int_lock = &local->internal_lock;
-
- AFR_TRACE_INODELK_OUT (frame, this, AFR_INODELK_TRANSACTION,
- AFR_UNLOCK_OP, NULL, op_ret,
- op_errno, child_index);
-
- priv = this->private;
-
- if (op_ret < 0 && op_errno != ENOTCONN && op_errno != EBADFD) {
- gf_msg (this->name, GF_LOG_INFO, op_errno,
- AFR_MSG_ENTRY_UNLOCK_FAIL,
- "%s: unlock failed on subvolume %s "
- "with lock owner %s", local->loc.path,
- priv->children[child_index]->name,
- lkowner_utoa (&frame->root->lk_owner));
- }
-
-
- inodelk = afr_get_inodelk (int_lock, int_lock->domain);
- inodelk->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);
-
- return 0;
-
-}
-
-static int
-afr_unlock_inodelk (call_frame_t *frame, xlator_t *this)
-{
- afr_internal_lock_t *int_lock = NULL;
- afr_inodelk_t *inodelk = NULL;
- 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;
- priv = this->private;
-
- inodelk = afr_get_inodelk (int_lock, int_lock->domain);
-
- flock.l_start = inodelk->flock.l_start;
- flock.l_len = inodelk->flock.l_len;
- flock.l_type = F_UNLCK;
-
- full_flock.l_type = F_UNLCK;
- call_count = afr_locked_nodes_count (inodelk->locked_nodes,
- priv->child_count);
-
- int_lock->lk_call_count = call_count;
-
- if (!call_count) {
- gf_log (this->name, GF_LOG_TRACE,
- "No internal locks unlocked");
- int_lock->lock_cbk (frame, this);
- goto out;
- }
-
- if (local->fd)
- fd_ctx = afr_fd_ctx_get (local->fd, this);
-
- for (i = 0; i < priv->child_count; i++) {
- if ((inodelk->locked_nodes[i] & LOCKED_YES) != LOCKED_YES)
- continue;
-
- 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);
-
- 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,
- int_lock->domain, local->fd,
- F_SETLK, flock_use, NULL);
-
- if (!--call_count)
- break;
-
- } else {
- AFR_TRACE_INODELK_IN (frame, this,
- AFR_INODELK_TRANSACTION,
- AFR_UNLOCK_OP, &flock, F_SETLK, i);
-
- STACK_WIND_COOKIE (frame, afr_unlock_inodelk_cbk,
- (void *) (long)i,
- priv->children[i],
- priv->children[i]->fops->inodelk,
- int_lock->domain, &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)
-{
- afr_local_t *local = NULL;
- afr_private_t *priv = NULL;
- afr_internal_lock_t *int_lock = NULL;
- int32_t child_index = 0;
- int lockee_no = 0;
-
- priv = this->private;
- lockee_no = (int)((long) cookie) / priv->child_count;
- child_index = (int) ((long) cookie) % priv->child_count;
-
- local = frame->local;
- int_lock = &local->internal_lock;
-
- AFR_TRACE_ENTRYLK_OUT (frame, this, AFR_ENTRYLK_TRANSACTION,
- AFR_UNLOCK_OP,
- int_lock->lockee[lockee_no].basename, op_ret,
- op_errno, (int) ((long)cookie));
-
- 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));
- }
-
- int_lock->lockee[lockee_no].locked_nodes[child_index] &= LOCKED_NO;
- afr_unlock_common_cbk (frame, cookie, this, op_ret, op_errno, NULL);
-
- return 0;
-}
-
-static int
-afr_unlock_entrylk (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 call_count = 0;
- int index = 0;
- int lockee_no = 0;
- int copies = 0;
- int i = -1;
-
- local = frame->local;
- int_lock = &local->internal_lock;
- priv = this->private;
- copies = priv->child_count;
-
- call_count = afr_lockee_locked_nodes_count (int_lock);
-
- int_lock->lk_call_count = call_count;
-
- if (!call_count){
- gf_log (this->name, GF_LOG_TRACE,
- "No internal locks unlocked");
- int_lock->lock_cbk (frame, this);
- goto out;
- }
-
- for (i = 0; i < int_lock->lockee_count * priv->child_count; i++) {
- lockee_no = i / copies;
- index = i % copies;
- if (int_lock->lockee[lockee_no].locked_nodes[index] & LOCKED_YES) {
- AFR_TRACE_ENTRYLK_IN (frame, this, AFR_ENTRYLK_NB_TRANSACTION,
- AFR_UNLOCK_OP,
- int_lock->lockee[lockee_no].basename,
- i);
-
- STACK_WIND_COOKIE (frame, afr_unlock_entrylk_cbk,
- (void *) (long) i,
- priv->children[index],
- priv->children[index]->fops->entrylk,
- int_lock->domain,
- &int_lock->lockee[lockee_no].loc,
- int_lock->lockee[lockee_no].basename,
- ENTRYLK_UNLOCK, ENTRYLK_WRLCK, NULL);
-
- if (!--call_count)
- break;
- }
- }
-
-out:
- return 0;
-
-}
-
-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)
-{
- afr_internal_lock_t *int_lock = NULL;
- afr_local_t *local = NULL;
- afr_private_t *priv = NULL;
- int cky = (long) cookie;
- int child_index = 0;
- int lockee_no = 0;
-
- priv = this->private;
- local = frame->local;
- int_lock = &local->internal_lock;
-
- child_index = ((int)cky) % priv->child_count;
- lockee_no = ((int)cky) / priv->child_count;
-
- LOCK (&frame->lock);
- {
- if (op_ret == -1) {
- if (op_errno == ENOSYS) {
- /* return ENOTSUP */
- gf_log (this->name, GF_LOG_ERROR,
- "subvolume does not support locking. "
- "please load features/locks xlator on server");
- local->op_ret = op_ret;
- int_lock->lock_op_ret = op_ret;
- }
-
- local->op_errno = op_errno;
- int_lock->lock_op_errno = op_errno;
- }
-
- int_lock->lk_attempted_count++;
- }
- UNLOCK (&frame->lock);
-
- if ((op_ret == -1) &&
- (op_errno == ENOSYS)) {
- afr_unlock (frame, this);
- } else {
- if (op_ret == 0) {
- if (local->transaction.type == AFR_ENTRY_TRANSACTION ||
- local->transaction.type == AFR_ENTRY_RENAME_TRANSACTION) {
- int_lock->lockee[lockee_no].locked_nodes[child_index] |= LOCKED_YES;
- int_lock->lockee[lockee_no].locked_count++;
- int_lock->entrylk_lock_count++;
- } else {
- int_lock->locked_nodes[child_index] |= LOCKED_YES;
- int_lock->lock_count++;
- }
- }
- afr_lock_blocking (frame, this, cky + 1);
- }
-
- return 0;
-}
-
-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)
-{
- AFR_TRACE_INODELK_OUT (frame, this, AFR_INODELK_TRANSACTION,
- AFR_LOCK_OP, NULL, op_ret,
- op_errno, (long) cookie);
-
- afr_lock_cbk (frame, cookie, this, op_ret, op_errno, xdata);
- return 0;
-
-}
-
-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)
-{
- AFR_TRACE_ENTRYLK_OUT (frame, this, AFR_ENTRYLK_TRANSACTION,
- AFR_LOCK_OP, NULL, op_ret,
- op_errno, (long)cookie);
-
- afr_lock_cbk (frame, cookie, this, op_ret, op_errno, xdata);
- return 0;
-}
-
-static int
-afr_copy_locked_nodes (call_frame_t *frame, xlator_t *this)
-{
- afr_internal_lock_t *int_lock = NULL;
- afr_inodelk_t *inodelk = NULL;
- afr_local_t *local = NULL;
- afr_private_t *priv = NULL;
-
- priv = this->private;
- local = frame->local;
- int_lock = &local->internal_lock;
-
- switch (local->transaction.type) {
- case AFR_DATA_TRANSACTION:
- case AFR_METADATA_TRANSACTION:
- inodelk = afr_get_inodelk (int_lock, int_lock->domain);
- memcpy (inodelk->locked_nodes, int_lock->locked_nodes,
- sizeof (*inodelk->locked_nodes) * priv->child_count);
- inodelk->lock_count = int_lock->lock_count;
- break;
-
- case AFR_ENTRY_RENAME_TRANSACTION:
- case AFR_ENTRY_TRANSACTION:
- /*entrylk_count is being used in both non-blocking and blocking
- * modes */
- break;
- }
-
- return 0;
-
-}
-
-static inline gf_boolean_t
-afr_is_entrylk (afr_internal_lock_t *int_lock,
- afr_transaction_type trans_type)
-{
- gf_boolean_t is_entrylk = _gf_false;
-
- if ((int_lock->transaction_lk_type == AFR_SELFHEAL_LK) &&
- int_lock->selfheal_lk_type == AFR_ENTRY_SELF_HEAL_LK) {
-
- is_entrylk = _gf_true;
-
- } else if ((int_lock->transaction_lk_type == AFR_TRANSACTION_LK) &&
- (trans_type == AFR_ENTRY_TRANSACTION ||
- trans_type == AFR_ENTRY_RENAME_TRANSACTION)) {
-
- is_entrylk = _gf_true;
-
- } else {
- is_entrylk = _gf_false;
- }
-
- return is_entrylk;
-}
-
-static gf_boolean_t
-_is_lock_wind_needed (afr_local_t *local, int child_index)
-{
- if (!local->child_up[child_index])
- return _gf_false;
-
- return _gf_true;
-}
-
-int
-afr_lock_blocking (call_frame_t *frame, xlator_t *this, int cookie)
-{
- afr_internal_lock_t *int_lock = NULL;
- afr_inodelk_t *inodelk = NULL;
- afr_local_t *local = NULL;
- afr_private_t *priv = NULL;
- struct gf_flock flock = {0,};
- uint64_t ctx = 0;
- int ret = 0;
- int child_index = 0;
- int lockee_no = 0;
- gf_boolean_t is_entrylk = _gf_false;
-
- local = frame->local;
- int_lock = &local->internal_lock;
- priv = this->private;
- child_index = cookie % priv->child_count;
- lockee_no = cookie / priv->child_count;
- is_entrylk = afr_is_entrylk (int_lock, local->transaction.type);
-
-
- if (!is_entrylk) {
- inodelk = afr_get_inodelk (int_lock, int_lock->domain);
- flock.l_start = inodelk->flock.l_start;
- flock.l_len = inodelk->flock.l_len;
- flock.l_type = inodelk->flock.l_type;
- }
-
- if (local->fd) {
- 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);
-
- local->op_ret = -1;
- int_lock->lock_op_ret = -1;
-
- afr_copy_locked_nodes (frame, this);
-
- afr_unlock (frame, this);
-
- return 0;
- }
- }
-
- if (int_lock->lk_expected_count == int_lock->lk_attempted_count) {
- if ((is_entrylk && int_lock->entrylk_lock_count == 0) ||
- (!is_entrylk && int_lock->lock_count == 0)) {
- gf_log (this->name, GF_LOG_INFO,
- "unable to lock on even one child");
-
- local->op_ret = -1;
- int_lock->lock_op_ret = -1;
-
- afr_copy_locked_nodes (frame, this);
-
- afr_unlock(frame, this);
-
- return 0;
- }
- }
-
- if (int_lock->lk_expected_count == int_lock->lk_attempted_count) {
- /* we're done locking */
-
- gf_log (this->name, GF_LOG_DEBUG,
- "we're done locking");
-
- afr_copy_locked_nodes (frame, this);
-
- int_lock->lock_op_ret = 0;
- int_lock->lock_cbk (frame, this);
- return 0;
- }
-
- if (!_is_lock_wind_needed (local, child_index)) {
- afr_lock_blocking (frame, this, cookie + 1);
- return 0;
- }
-
- switch (local->transaction.type) {
- case AFR_DATA_TRANSACTION:
- case AFR_METADATA_TRANSACTION:
-
- if (local->fd) {
- AFR_TRACE_INODELK_IN (frame, this,
- AFR_INODELK_TRANSACTION,
- AFR_LOCK_OP, &flock, F_SETLKW,
- child_index);
-
- STACK_WIND_COOKIE (frame, afr_blocking_inodelk_cbk,
- (void *) (long) child_index,
- priv->children[child_index],
- priv->children[child_index]->fops->finodelk,
- int_lock->domain, local->fd,
- F_SETLKW, &flock, NULL);
-
- } else {
- AFR_TRACE_INODELK_IN (frame, this,
- AFR_INODELK_TRANSACTION,
- AFR_LOCK_OP, &flock, F_SETLKW,
- child_index);
-
- STACK_WIND_COOKIE (frame, afr_blocking_inodelk_cbk,
- (void *) (long) child_index,
- priv->children[child_index],
- priv->children[child_index]->fops->inodelk,
- int_lock->domain, &local->loc,
- F_SETLKW, &flock, NULL);
- }
-
- break;
-
- case AFR_ENTRY_RENAME_TRANSACTION:
- case AFR_ENTRY_TRANSACTION:
- /*Accounting for child_index increments on 'down'
- *and 'fd-less' children */
-
- if (local->fd) {
- AFR_TRACE_ENTRYLK_IN (frame, this, AFR_ENTRYLK_TRANSACTION,
- AFR_LOCK_OP,
- int_lock->lockee[lockee_no].basename,
- cookie);
-
- STACK_WIND_COOKIE (frame, afr_blocking_entrylk_cbk,
- (void *) (long) cookie,
- priv->children[child_index],
- priv->children[child_index]->fops->fentrylk,
- int_lock->domain, local->fd,
- int_lock->lockee[lockee_no].basename,
- ENTRYLK_LOCK, ENTRYLK_WRLCK, NULL);
- } else {
- AFR_TRACE_ENTRYLK_IN (frame, this,
- AFR_ENTRYLK_TRANSACTION,
- AFR_LOCK_OP, local->transaction.basename,
- child_index);
-
- STACK_WIND_COOKIE (frame, afr_blocking_entrylk_cbk,
- (void *) (long) cookie,
- priv->children[child_index],
- priv->children[child_index]->fops->entrylk,
- int_lock->domain,
- &int_lock->lockee[lockee_no].loc,
- int_lock->lockee[lockee_no].basename,
- ENTRYLK_LOCK, ENTRYLK_WRLCK, NULL);
- }
-
- break;
- }
-
- return 0;
-}
-
-int32_t
-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;
- int_lock = &local->internal_lock;
-
- switch (local->transaction.type) {
- case AFR_DATA_TRANSACTION:
- case AFR_METADATA_TRANSACTION:
- initialize_inodelk_variables (frame, this);
- break;
-
- case AFR_ENTRY_RENAME_TRANSACTION:
- case AFR_ENTRY_TRANSACTION:
- up_count = AFR_COUNT (local->child_up, priv->child_count);
- int_lock->lk_call_count = int_lock->lk_expected_count
- = (int_lock->lockee_count *
- up_count);
- initialize_entrylk_variables (frame, this);
- break;
- }
-
- afr_lock_blocking (frame, this, 0);
-
- return 0;
-}
-
-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)
-{
- afr_internal_lock_t *int_lock = NULL;
- afr_local_t *local = NULL;
- int call_count = 0;
- int child_index = (long) cookie;
- int copies = 0;
- int index = 0;
- int lockee_no = 0;
- afr_private_t *priv = NULL;
-
- priv = this->private;
-
- copies = priv->child_count;
- index = child_index % copies;
- lockee_no = child_index / copies;
-
- local = frame->local;
- int_lock = &local->internal_lock;
-
- AFR_TRACE_ENTRYLK_OUT (frame, this, AFR_ENTRYLK_TRANSACTION,
- AFR_LOCK_OP,
- int_lock->lockee[lockee_no].basename, op_ret,
- op_errno, (long) cookie);
-
- LOCK (&frame->lock);
- {
- if (op_ret < 0 ) {
- if (op_errno == ENOSYS) {
- /* return ENOTSUP */
- gf_log (this->name, GF_LOG_ERROR,
- "subvolume does not support locking. "
- "please load features/locks xlator on server");
- local->op_ret = op_ret;
- int_lock->lock_op_ret = op_ret;
-
- int_lock->lock_op_errno = op_errno;
- local->op_errno = op_errno;
- }
- } else if (op_ret == 0) {
- int_lock->lockee[lockee_no].locked_nodes[index] |= \
- LOCKED_YES;
- int_lock->lockee[lockee_no].locked_count++;
- int_lock->entrylk_lock_count++;
- }
-
- 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 */
- if (int_lock->entrylk_lock_count ==
- int_lock->lk_expected_count) {
- 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
- again, this time with serially blocking locks */
- else {
- gf_log (this->name, GF_LOG_TRACE,
- "%d servers locked. Trying again with blocking calls",
- int_lock->lock_count);
-
- afr_unlock(frame, this);
- }
- }
-
- return 0;
-}
-
-int
-afr_nonblocking_entrylk (call_frame_t *frame, xlator_t *this)
-{
- afr_internal_lock_t *int_lock = NULL;
- afr_local_t *local = NULL;
- afr_private_t *priv = NULL;
- afr_fd_ctx_t *fd_ctx = NULL;
- int copies = 0;
- int index = 0;
- int lockee_no = 0;
- int32_t call_count = 0;
- int i = 0;
-
- local = frame->local;
- int_lock = &local->internal_lock;
- priv = this->private;
-
- copies = priv->child_count;
- initialize_entrylk_variables (frame, this);
-
- if (local->fd) {
- fd_ctx = afr_fd_ctx_get (local->fd, this);
- if (!fd_ctx) {
- gf_log (this->name, GF_LOG_INFO,
- "unable to get fd ctx for fd=%p",
- local->fd);
-
- local->op_ret = -1;
- int_lock->lock_op_ret = -1;
- local->op_errno = EINVAL;
- int_lock->lock_op_errno = EINVAL;
-
- afr_unlock (frame, this);
- return -1;
- }
-
- call_count = int_lock->lockee_count * internal_lock_count (frame, this);
- int_lock->lk_call_count = call_count;
- int_lock->lk_expected_count = call_count;
-
- if (!call_count) {
- gf_log (this->name, GF_LOG_INFO,
- "fd not open on any subvolumes. aborting.");
- afr_unlock (frame, this);
- goto out;
- }
-
- /* Send non-blocking entrylk calls only on up children
- and where the fd has been opened */
- for (i = 0; i < int_lock->lockee_count*priv->child_count; i++) {
- index = i%copies;
- lockee_no = i/copies;
- if (local->child_up[index]) {
- AFR_TRACE_ENTRYLK_IN (frame, this, AFR_ENTRYLK_NB_TRANSACTION,
- AFR_LOCK_OP,
- int_lock->lockee[lockee_no].basename,
- i);
-
- STACK_WIND_COOKIE (frame, afr_nonblocking_entrylk_cbk,
- (void *) (long) i,
- priv->children[index],
- priv->children[index]->fops->fentrylk,
- this->name, local->fd,
- int_lock->lockee[lockee_no].basename,
- ENTRYLK_LOCK_NB, ENTRYLK_WRLCK,
- NULL);
- if (!--call_count)
- break;
- }
- }
- } else {
- call_count = int_lock->lockee_count * internal_lock_count (frame, this);
- int_lock->lk_call_count = call_count;
- int_lock->lk_expected_count = call_count;
-
- for (i = 0; i < int_lock->lockee_count*priv->child_count; i++) {
- index = i%copies;
- lockee_no = i/copies;
- if (local->child_up[index]) {
- AFR_TRACE_ENTRYLK_IN (frame, this, AFR_ENTRYLK_NB_TRANSACTION,
- AFR_LOCK_OP,
- int_lock->lockee[lockee_no].basename,
- i);
-
- STACK_WIND_COOKIE (frame, afr_nonblocking_entrylk_cbk,
- (void *) (long) i,
- priv->children[index],
- priv->children[index]->fops->entrylk,
- this->name, &int_lock->lockee[lockee_no].loc,
- int_lock->lockee[lockee_no].basename,
- ENTRYLK_LOCK_NB, ENTRYLK_WRLCK,
- NULL);
-
- if (!--call_count)
- break;
- }
- }
- }
-out:
- return 0;
-}
-
-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)
-{
- afr_internal_lock_t *int_lock = NULL;
- afr_inodelk_t *inodelk = NULL;
- afr_local_t *local = 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;
- inodelk = afr_get_inodelk (int_lock, int_lock->domain);
-
- AFR_TRACE_INODELK_OUT (frame, this, AFR_INODELK_NB_TRANSACTION,
- AFR_LOCK_OP, NULL, op_ret,
- op_errno, (long) cookie);
-
- if (local->fd)
- fd_ctx = afr_fd_ctx_get (local->fd, this);
-
- LOCK (&frame->lock);
- {
- if (op_ret < 0) {
- if (op_errno == ENOSYS) {
- /* return ENOTSUP */
- gf_log (this->name, GF_LOG_ERROR,
- "subvolume does not support locking. "
- "please load features/locks xlator on "
- "server");
- local->op_ret = op_ret;
- int_lock->lock_op_ret = op_ret;
- 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 {
- inodelk->locked_nodes[child_index] |= LOCKED_YES;
- inodelk->lock_count++;
-
- if (local->transaction.eager_lock &&
- local->transaction.eager_lock[child_index] &&
- local->fd) {
- /* piggybacked */
- if (op_ret == 1) {
- /* piggybacked */
- } else if (op_ret == 0) {
- /* lock acquired from server */
- fd_ctx->lock_acquired[child_index]++;
- }
- }
- }
-
- 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 */
- if (inodelk->lock_count == int_lock->lk_expected_count) {
- 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
- again, this time with serially blocking locks */
- else {
- gf_log (this->name, GF_LOG_TRACE,
- "%d servers locked. Trying again with blocking calls",
- int_lock->lock_count);
-
- afr_unlock(frame, this);
- }
- }
-
- return 0;
-}
-
-int
-afr_nonblocking_inodelk (call_frame_t *frame, xlator_t *this)
-{
- afr_internal_lock_t *int_lock = NULL;
- afr_inodelk_t *inodelk = NULL;
- 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;
-
- local = frame->local;
- int_lock = &local->internal_lock;
- priv = this->private;
-
- inodelk = afr_get_inodelk (int_lock, int_lock->domain);
-
- flock.l_start = inodelk->flock.l_start;
- flock.l_len = inodelk->flock.l_len;
- flock.l_type = inodelk->flock.l_type;
-
- full_flock.l_type = inodelk->flock.l_type;
-
- initialize_inodelk_variables (frame, this);
-
- if (local->fd) {
- fd_ctx = afr_fd_ctx_get (local->fd, this);
- if (!fd_ctx) {
- gf_log (this->name, GF_LOG_INFO,
- "unable to get fd ctx for fd=%p",
- local->fd);
-
- local->op_ret = -1;
- int_lock->lock_op_ret = -1;
- local->op_errno = EINVAL;
- int_lock->lock_op_errno = EINVAL;
-
- afr_unlock (frame, this);
- ret = -1;
- goto out;
- }
-
- call_count = internal_lock_count (frame, this);
- int_lock->lk_call_count = call_count;
- int_lock->lk_expected_count = call_count;
-
- if (!call_count) {
- gf_log (this->name, GF_LOG_INFO,
- "fd not open on any subvolumes. aborting.");
- afr_unlock (frame, this);
- goto out;
- }
-
- /* 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])
- continue;
-
- flock_use = &flock;
- if (!local->transaction.eager_lock_on) {
- goto wind;
- }
-
- piggyback = 0;
- local->transaction.eager_lock[i] = 1;
-
- 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);
-
- 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,
- int_lock->domain, local->fd,
- F_SETLK, flock_use, NULL);
-
- if (!--call_count)
- break;
- }
- } else {
- call_count = internal_lock_count (frame, this);
- 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);
-
- STACK_WIND_COOKIE (frame, afr_nonblocking_inodelk_cbk,
- (void *) (long) i,
- priv->children[i],
- priv->children[i]->fops->inodelk,
- int_lock->domain, &local->loc,
- F_SETLK, &flock, NULL);
-
- if (!--call_count)
- break;
- }
- }
-out:
- return ret;
-}
-
-int32_t
-afr_unlock (call_frame_t *frame, xlator_t *this)
-{
- afr_local_t *local = NULL;
-
- local = frame->local;
-
- if (transaction_lk_op (local)) {
- if (is_afr_lock_transaction (local))
- afr_unlock_inodelk (frame, this);
- else
- afr_unlock_entrylk (frame, this);
-
- } else {
- if (is_afr_lock_selfheal (local))
- afr_unlock_inodelk (frame, this);
- else
- afr_unlock_entrylk (frame, this);
- }
-
- return 0;
-}
-
-int
-afr_lk_transfer_datalock (call_frame_t *dst, call_frame_t *src, char *dom,
- 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;
- afr_inodelk_t *dst_inodelk = NULL;
- afr_inodelk_t *src_inodelk = NULL;
- int ret = -1;
-
- src_local = src->local;
- src_lock = &src_local->internal_lock;
- src_inodelk = afr_get_inodelk (src_lock, dom);
- dst_local = dst->local;
- dst_lock = &dst_local->internal_lock;
- dst_inodelk = afr_get_inodelk (dst_lock, dom);
- if (!dst_inodelk || !src_inodelk)
- goto out;
- if (src_inodelk->locked_nodes) {
- memcpy (dst_inodelk->locked_nodes, src_inodelk->locked_nodes,
- sizeof (*dst_inodelk->locked_nodes) * child_count);
- memset (src_inodelk->locked_nodes, 0,
- sizeof (*src_inodelk->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_inodelk->lock_count = src_inodelk->lock_count;
- src_inodelk->lock_count = 0;
- ret = 0;
-out:
- return ret;
-}
diff --git a/xlators/cluster/afr/src/afr-mem-types.h b/xlators/cluster/afr/src/afr-mem-types.h
deleted file mode 100644
index 05df90cc0ee..00000000000
--- a/xlators/cluster/afr/src/afr-mem-types.h
+++ /dev/null
@@ -1,49 +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_MEM_TYPES_H__
-#define __AFR_MEM_TYPES_H__
-
-#include "mem-types.h"
-
-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_private_t,
- gf_afr_mt_int32_t,
- gf_afr_mt_char,
- gf_afr_mt_xattr_key,
- gf_afr_mt_dict_t,
- gf_afr_mt_xlator_t,
- gf_afr_mt_iatt,
- gf_afr_mt_int,
- gf_afr_mt_afr_node_character,
- gf_afr_mt_sh_diff_loop_state,
- gf_afr_mt_uint8_t,
- gf_afr_mt_loc_t,
- 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_reply_t,
- gf_afr_mt_subvol_healer_t,
- gf_afr_mt_end
-};
-#endif
-
diff --git a/xlators/cluster/afr/src/afr-messages.h b/xlators/cluster/afr/src/afr-messages.h
deleted file mode 100644
index 1c9f6bcc358..00000000000
--- a/xlators/cluster/afr/src/afr-messages.h
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- Copyright (c) 2014 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_MESSAGES_H_
-#define _AFR_MESSAGES_H_
-
-#ifndef _CONFIG_H
-#define _CONFIG_H
-#include "config.h"
-#endif
-
-#include "glfs-message-id.h"
-
-/*! \file afr-messages.h
- * \brief AFR log-message IDs and their descriptions.
- */
-
-/* NOTE: Rules for message additions
- * 1) Each instance of a message is _better_ left with a unique message ID, even
- * if the message format is the same. Reasoning is that, if the message
- * format needs to change in one instance, the other instances are not
- * impacted or the new change does not change the ID of the instance being
- * modified.
- * 2) Addition of a message,
- * - Should increment the GLFS_NUM_MESSAGES
- * - Append to the list of messages defined, towards the end
- * - Retain macro naming as glfs_msg_X (for redability across developers)
- * NOTE: Rules for message format modifications
- * 3) Check acorss the code if the message ID macro in question is reused
- * anywhere. If reused then then the modifications should ensure correctness
- * everywhere, or needs a new message ID as (1) above was not adhered to. If
- * not used anywhere, proceed with the required modification.
- * NOTE: Rules for message deletion
- * 4) Check (3) and if used anywhere else, then cannot be deleted. If not used
- * anywhere, then can be deleted, but will leave a hole by design, as
- * addition rules specify modification to the end of the list and not filling
- * holes.
- */
-
-#define GLFS_COMP_BASE_AFR GLFS_MSGID_COMP_AFR
-#define GLFS_NUM_MESSAGES 9
-#define GLFS_MSGID_END (GLFS_COMP_BASE_AFR + GLFS_NUM_MESSAGES + 1)
-
-#define glfs_msg_start_x GLFS_COMP_BASE_AFR, "Invalid: Start of messages"
-
-/*!
- * @messageid 108001
- * @diagnosis Client quorum is not met due to which file modification
- * operations are disallowed.
- * @recommendedaction Some brick processes are down/ not visible from the
- * client. Ensure that the bricks are up/ network traffic is not blocked.
- */
-#define AFR_MSG_QUORUM_FAIL (GLFS_COMP_BASE_AFR + 1)
-
-
-/*!
- * @messageid 108002
- * @diagnosis The bricks that were down are now up and quorum is restored.
- * @recommendedaction Possibly check why the bricks went down to begin with.
- */
-#define AFR_MSG_QUORUM_MET (GLFS_COMP_BASE_AFR + 2)
-
-
-/*!
- * @messageid 108003
- * @diagnosis Client quorum-type was set to auto due to which the quorum-count
- * option is no longer valid.
- * @recommendedaction None.
- */
-#define AFR_MSG_QUORUM_OVERRIDE (GLFS_COMP_BASE_AFR + 3)
-
-
-/*!
- * @messageid 108004
- * @diagnosis Replication sub volume witnessed a connection notification
- * from a brick which does not belong to its replica set.
- * @recommendedaction None. This is a safety check in code.
- */
-#define AFR_MSG_INVALID_CHILD_UP (GLFS_COMP_BASE_AFR + 4)
-
-
-/*!
- * @messageid 108005
- * @diagnosis A replica set that was inaccessible because all its bricks were
- * down is now accessible because at least one of its bricks came back up.
- * @recommendedaction Possibly check why all the bricks of that replica set
- * went down to begin with.
- */
-#define AFR_MSG_SUBVOL_UP (GLFS_COMP_BASE_AFR + 5)
-
-
-/*!
- * @messageid 108006
- * @diagnosis All bricks of a replica set are down. Data residing in that
- * replica cannot be accessed until one of the bricks come back up.
- * @recommendedaction Ensure that the bricks are up.
- */
-#define AFR_MSG_ALL_SUBVOLS_DOWN (GLFS_COMP_BASE_AFR + 6)
-
-
-/*!
- * @messageid 108007
- * @diagnosis Entry unlocks failed on a brick.
- * @recommendedaction Error number in the log should give the reason why it
- * failed. Also observe brick logs for more information.
-*/
-#define AFR_MSG_ENTRY_UNLOCK_FAIL (GLFS_COMP_BASE_AFR + 7)
-
-
-/*!
- * @messageid 108008
- * @diagnosis There is an inconsistency in the file's data/metadata/gfid
- * amongst the bricks of a replica set.
- * @recommendedaction Resolve the split brain by clearing the AFR changelog
- * attributes from the appropriate brick and trigger self-heal.
- */
-#define AFR_MSG_SPLIT_BRAIN (GLFS_COMP_BASE_AFR + 8)
-
-
-/*!
- * @messageid 108009
- * @diagnosis open/opendir failed on a brick.
- * @recommendedaction Error number in the log should give the reason why it
- * failed. Also observe brick logs for more information.
- */
-#define AFR_MSG_OPEN_FAIL (GLFS_COMP_BASE_AFR + 9)
-
-
-#define glfs_msg_end_x GLFS_MSGID_END, "Invalid: End of messages"
-
-#endif /* !_AFR_MESSAGES_H_ */
diff --git a/xlators/cluster/afr/src/afr-open.c b/xlators/cluster/afr/src/afr-open.c
index f8ad8544e10..00958438a4c 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>
- 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-2009 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 <libgen.h>
@@ -44,291 +53,426 @@
#include "afr-dir-write.h"
#include "afr-transaction.h"
+#include "afr-self-heal.h"
+
-gf_boolean_t
-afr_is_fd_fixable (fd_t *fd)
+int
+afr_open_ftruncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct stat *prebuf,
+ struct stat *postbuf)
{
- if (!fd || !fd->inode)
- return _gf_false;
- else if (fd_is_anonymous (fd))
- return _gf_false;
- else if (uuid_is_null (fd->inode->gfid))
- return _gf_false;
-
- return _gf_true;
+ afr_local_t * local = frame->local;
+
+ AFR_STACK_UNWIND (open, frame, local->op_ret, local->op_errno,
+ local->fd);
+ return 0;
}
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)
+afr_open_cbk (call_frame_t *frame, void *cookie,
+ xlator_t *this, int32_t op_ret, int32_t op_errno,
+ fd_t *fd)
{
- afr_local_t * local = frame->local;
+ afr_local_t * local = NULL;
+ afr_private_t * priv = NULL;
- AFR_STACK_UNWIND (open, frame, local->op_ret, local->op_errno,
- local->fd, xdata);
- return 0;
+ int child_index = (long) cookie;
+
+ uint64_t ctx;
+ afr_fd_ctx_t *fd_ctx;
+
+ int ret = 0;
+
+ int call_count = -1;
+
+ priv = this->private;
+ local = frame->local;
+
+ LOCK (&frame->lock);
+ {
+ if (op_ret == -1) {
+ local->op_errno = op_errno;
+ }
+
+ if (op_ret >= 0) {
+ local->op_ret = op_ret;
+ local->success_count++;
+
+ ret = afr_fd_ctx_set (this, fd);
+
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "could not set fd ctx for fd=%p",
+ fd);
+
+ local->op_ret = -1;
+ local->op_errno = -ret;
+ }
+
+ ret = fd_ctx_get (fd, this, &ctx);
+
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "could not get fd ctx for fd=%p", fd);
+ local->op_ret = -1;
+ local->op_errno = -ret;
+ }
+
+ 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 (&frame->lock);
+
+ call_count = afr_frame_return (frame);
+
+ if (call_count == 0) {
+ if ((local->cont.open.flags & O_TRUNC)
+ && (local->op_ret >= 0)) {
+ STACK_WIND (frame, afr_open_ftruncate_cbk,
+ this, this->fops->ftruncate,
+ fd, 0);
+ } else {
+ AFR_STACK_UNWIND (open, frame, local->op_ret,
+ local->op_errno, local->fd);
+ }
+ }
+
+ return 0;
}
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)
+afr_open (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
+ fd_t *fd, int32_t wbflags)
{
- afr_local_t * local = NULL;
- int call_count = -1;
- int child_index = (long) cookie;
- afr_fd_ctx_t *fd_ctx = NULL;
+ 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);
+
+ VALIDATE_OR_GOTO (frame, out);
+ VALIDATE_OR_GOTO (this, out);
+ VALIDATE_OR_GOTO (this->private, out);
+ VALIDATE_OR_GOTO (loc, out);
+
+ priv = this->private;
+
+ if (afr_is_split_brain (this, loc->inode)) {
+ /* self-heal failed */
+ op_errno = EIO;
+ goto out;
+ }
+
+ ALLOC_OR_GOTO (local, afr_local_t, out);
+ 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);
+
+ for (i = 0; i < priv->child_count; i++) {
+ if (local->child_up[i]) {
+ STACK_WIND_COOKIE (frame, afr_open_cbk, (void *) (long) i,
+ priv->children[i],
+ priv->children[i]->fops->open,
+ loc, wind_flags, fd, wbflags);
+
+ if (!--call_count)
+ break;
+ }
+ }
+
+ op_ret = 0;
+out:
+ if (op_ret == -1) {
+ AFR_STACK_UNWIND (open, frame, op_ret, op_errno, fd);
+ }
+
+ return 0;
+}
+
+
+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_local_t *local = NULL;
+ afr_private_t *priv = NULL;
+
+ int ret = 0;
+
+ uint64_t ctx;
+ afr_fd_ctx_t *fd_ctx;
+
+ int call_count = 0;
+ int child_index = (long) cookie;
+
+ priv = this->private;
local = frame->local;
- fd_ctx = local->fd_ctx;
LOCK (&frame->lock);
{
- if (op_ret == -1) {
- local->op_errno = op_errno;
- fd_ctx->opened_on[child_index] = AFR_FD_NOT_OPENED;
- } else {
- local->op_ret = op_ret;
- fd_ctx->opened_on[child_index] = AFR_FD_OPENED;
- if (!local->xdata_rsp && xdata)
- local->xdata_rsp = dict_ref (xdata);
+ if (op_ret >= 0) {
+ ret = fd_ctx_get (fd, this, &ctx);
+
+ if (ret < 0) {
+ 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) {
- if ((fd_ctx->flags & O_TRUNC) && (local->op_ret >= 0)) {
- STACK_WIND (frame, afr_open_ftruncate_cbk,
- this, this->fops->ftruncate,
- fd, 0, NULL);
- } else {
- AFR_STACK_UNWIND (open, frame, local->op_ret,
- local->op_errno, local->fd,
- local->xdata_rsp);
- }
+ local->transaction.resume (frame, this);
}
return 0;
}
+
+static int
+__unopened_count (int child_count, unsigned int *opened_on, unsigned char *child_up)
+{
+ int i;
+ int count = 0;
+
+ for (i = 0; i < child_count; i++) {
+ if (!opened_on[i] && child_up[i])
+ count++;
+ }
+
+ return count;
+}
+
+
int
-afr_open (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
- fd_t *fd, dict_t *xdata)
+afr_openfd_sh_unwind (call_frame_t *frame, xlator_t *this)
{
- afr_private_t * priv = NULL;
- afr_local_t * local = NULL;
- int i = 0;
- int32_t call_count = 0;
- int32_t op_errno = 0;
- afr_fd_ctx_t *fd_ctx = NULL;
+ afr_local_t *local = NULL;
+ afr_private_t *priv = NULL;
- //We can't let truncation to happen outside transaction.
+ uint64_t ctx;
+ afr_fd_ctx_t *fd_ctx;
- priv = this->private;
+ int abandon = 0;
+ int ret = 0;
+ int i;
+ int call_count = 0;
- local = AFR_FRAME_INIT (frame, op_errno);
- if (!local)
- goto out;
+ priv = this->private;
+ local = frame->local;
- fd_ctx = afr_fd_ctx_get (fd, this);
- if (!fd_ctx) {
- op_errno = ENOMEM;
- 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.
+ */
+
+ ret = fd_ctx_get (local->fd, this, &ctx);
+
+ if (ret < 0) {
+ abandon = 1;
+ goto out;
+ }
- local->fd = fd_ref (fd);
- local->fd_ctx = fd_ctx;
- fd_ctx->flags = flags;
+ 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);
+ for (i = 0; i < priv->child_count; i++) {
+ fd_ctx->pre_op_done[i] = 0;
+ fd_ctx->pre_op_piggyback[i] = 0;
+ }
+ }
+ UNLOCK (&local->fd->lock);
+
+ if (call_count == 0) {
+ abandon = 1;
+ goto out;
+ }
- call_count = local->call_count;
+ local->call_count = call_count;
- local->cont.open.flags = flags;
+ if (!local->loc.path) {
+ abandon = 1;
+ goto out;
+ }
for (i = 0; i < priv->child_count; i++) {
- if (local->child_up[i]) {
- STACK_WIND_COOKIE (frame, afr_open_cbk, (void *) (long) 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,
- loc, (flags & ~O_TRUNC), fd, xdata);
+ &local->loc, fd_ctx->flags, local->fd,
+ fd_ctx->wbflags);
+
if (!--call_count)
break;
}
}
- return 0;
out:
- AFR_STACK_UNWIND (open, frame, -1, op_errno, fd, NULL);
+ if (abandon)
+ local->transaction.resume (frame, this);
return 0;
}
+
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 (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;
-
- priv = this->private;
- local = frame->local;
-
- if (op_ret >= 0) {
- gf_log (this->name, GF_LOG_DEBUG, "fd for %s opened "
- "successfully on subvolume %s", local->loc.path,
- priv->children[child_index]->name);
- } else {
- gf_msg (this->name, fop_log_level (GF_FOP_OPEN, op_errno),
- op_errno, AFR_MSG_OPEN_FAIL, "Failed to open %s on "
- "subvolume %s", local->loc.path,
- priv->children[child_index]->name);
- }
+ afr_private_t *priv = NULL;
+ afr_local_t *local = NULL;
+ afr_self_heal_t *sh = NULL;
- fd_ctx = local->fd_ctx;
+ int ret = -1;
- 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;
- }
+ priv = this->private;
+ local = frame->local;
+ sh = &local->self_heal;
+
+ ret = inode_path (local->fd->inode, NULL, (char **)&local->loc.path);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_TRACE,
+ "Inode path failed. Possible open-unlink-write detected");
+ afr_openfd_sh_unwind (frame, this);
+
+ return 0;
}
- UNLOCK (&local->fd->lock);
+ local->loc.name = strrchr (local->loc.path, '/');
+ local->loc.inode = inode_ref (local->fd->inode);
+ local->loc.parent = inode_parent (local->fd->inode, 0, NULL);
- call_count = afr_frame_return (frame);
- if (call_count == 0)
- AFR_STACK_DESTROY (frame);
+ /* 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->mode = local->fd->inode->st_mode;
+ sh->background = _gf_false;
+ sh->unwind = afr_openfd_sh_unwind;
+
+ afr_self_heal (frame, this);
return 0;
}
-static int
-afr_fd_ctx_need_open (fd_t *fd, xlator_t *this, unsigned char *need_open)
+int
+afr_openfd_flush_done (call_frame_t *frame, xlator_t *this)
{
- afr_fd_ctx_t *fd_ctx = NULL;
- afr_private_t *priv = NULL;
- int i = 0;
- int count = 0;
+ afr_private_t *priv = NULL;
+ afr_local_t *local = NULL;
- priv = this->private;
+ uint64_t ctx;
+ afr_fd_ctx_t * fd_ctx = NULL;
- fd_ctx = afr_fd_ctx_get (fd, this);
- if (!fd_ctx)
- return 0;
+ int _ret = -1;
- LOCK (&fd->lock);
- {
- for (i = 0; i < priv->child_count; i++) {
- if (fd_ctx->opened_on[i] == AFR_FD_NOT_OPENED &&
- priv->child_up[i]) {
- fd_ctx->opened_on[i] = AFR_FD_OPENING;
- need_open[i] = 1;
- count++;
- } else {
- need_open[i] = 0;
- }
- }
- }
- UNLOCK (&fd->lock);
+ priv = this->private;
+ local = frame->local;
- return count;
-}
+ LOCK (&local->fd->lock);
+ {
+ _ret = __fd_ctx_get (local->fd, this, &ctx);
+ if (_ret < 0) {
+ goto out;
+ }
-void
-afr_fix_open (fd_t *fd, xlator_t *this)
-{
- afr_private_t *priv = NULL;
- int i = 0;
- call_frame_t *frame = NULL;
- afr_local_t *local = NULL;
- int ret = -1;
- int32_t op_errno = 0;
- afr_fd_ctx_t *fd_ctx = NULL;
- unsigned char *need_open = NULL;
- int call_count = 0;
+ fd_ctx = (afr_fd_ctx_t *)(long) ctx;
- priv = this->private;
+ fd_ctx->down_count = priv->down_count;
+ fd_ctx->up_count = priv->up_count;
+ }
+out:
+ UNLOCK (&local->fd->lock);
- if (!afr_is_fd_fixable (fd))
- goto out;
+ afr_local_transaction_cleanup (local, this);
- fd_ctx = afr_fd_ctx_get (fd, this);
- if (!fd_ctx)
- goto out;
+ local->openfd_flush_cbk (frame, this);
- need_open = alloca0 (priv->child_count);
+ return 0;
+}
- call_count = afr_fd_ctx_need_open (fd, this, need_open);
- if (!call_count)
- goto out;
- frame = create_frame (this, this->ctx->pool);
- if (!frame)
- goto out;
+int
+afr_openfd_flush (call_frame_t *frame, xlator_t *this, fd_t *fd)
+{
+ afr_private_t * priv = NULL;
+ afr_local_t * local = NULL;
- local = AFR_FRAME_INIT (frame, op_errno);
- if (!local)
- goto out;
+ int op_ret = -1;
- local->loc.inode = inode_ref (fd->inode);
- ret = loc_path (&local->loc, NULL);
- if (ret < 0)
- goto out;
+ VALIDATE_OR_GOTO (frame, out);
+ VALIDATE_OR_GOTO (this, out);
+ VALIDATE_OR_GOTO (this->private, out);
- local->fd = fd_ref (fd);
- local->fd_ctx = fd_ctx;
+ priv = this->private;
- local->call_count = call_count;
+ local = frame->local;
- gf_log (this->name, GF_LOG_DEBUG, "need open count: %d",
- call_count);
+ local->op = GF_FOP_FLUSH;
- for (i = 0; i < priv->child_count; i++) {
- if (!need_open[i])
- continue;
+// local->fd = fd_ref (local->fd);
- if (IA_IFDIR == fd->inode->ia_type) {
- gf_log (this->name, GF_LOG_DEBUG,
- "opening fd for dir %s on subvolume %s",
- local->loc.path, priv->children[i]->name);
+ local->transaction.fop = afr_openfd_sh;
+ local->transaction.done = afr_openfd_flush_done;
- STACK_WIND_COOKIE (frame, afr_openfd_fix_open_cbk,
- (void*) (long) i,
- priv->children[i],
- priv->children[i]->fops->opendir,
- &local->loc, local->fd,
- NULL);
- } else {
- gf_log (this->name, GF_LOG_DEBUG,
- "opening fd for file %s on subvolume %s",
- local->loc.path, priv->children[i]->name);
+ local->transaction.start = 0;
+ local->transaction.len = 0;
- STACK_WIND_COOKIE (frame, afr_openfd_fix_open_cbk,
- (void *)(long) i,
- priv->children[i],
- priv->children[i]->fops->open,
- &local->loc,
- fd_ctx->flags & (~O_TRUNC),
- local->fd, NULL);
- }
+ gf_log (this->name, GF_LOG_TRACE,
+ "doing up/down flush on fd=%p",
+ fd);
- if (!--call_count)
- break;
- }
+ afr_transaction (frame, this, AFR_DATA_TRANSACTION);
- return;
+ op_ret = 0;
out:
- if (frame)
- AFR_STACK_DESTROY (frame);
+ return 0;
}
diff --git a/xlators/cluster/afr/src/afr-read-txn.c b/xlators/cluster/afr/src/afr-read-txn.c
deleted file mode 100644
index 4efadb3f1d4..00000000000
--- a/xlators/cluster/afr/src/afr-read-txn.c
+++ /dev/null
@@ -1,247 +0,0 @@
-/*
- Copyright (c) 2013 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 "afr.h"
-#include "afr-transaction.h"
-
-int
-afr_read_txn_next_subvol (call_frame_t *frame, xlator_t *this)
-{
- afr_local_t *local = NULL;
- afr_private_t *priv = NULL;
- int i = 0;
- int subvol = -1;
-
- local = frame->local;
- priv = this->private;
-
-
- for (i = 0; i < priv->child_count; i++) {
- if (!local->readable[i]) {
- /* don't even bother trying here.
- just mark as attempted and move on. */
- local->read_attempted[i] = 1;
- continue;
- }
-
- if (!local->read_attempted[i]) {
- subvol = i;
- break;
- }
- }
-
- /* If no more subvols were available for reading, we leave
- @subvol as -1, which is an indication we have run out of
- readable subvols. */
- if (subvol != -1)
- local->read_attempted[subvol] = 1;
- local->readfn (frame, this, subvol);
-
- return 0;
-}
-
-#define AFR_READ_TXN_SET_ERROR_AND_GOTO(ret, errnum, index, label) \
- do { \
- local->op_ret = ret; \
- local->op_errno = errnum; \
- read_subvol = index; \
- goto label; \
- } while (0)
-
-int
-afr_read_txn_refresh_done (call_frame_t *frame, xlator_t *this, int err)
-{
- afr_local_t *local = NULL;
- afr_private_t *priv = NULL;
- int read_subvol = 0;
- int event_generation = 0;
- inode_t *inode = NULL;
- int ret = -1;
-
- local = frame->local;
- inode = local->inode;
- priv = frame->this->private;
-
- if (err)
- AFR_READ_TXN_SET_ERROR_AND_GOTO (-1, -err, -1, readfn);
-
- ret = afr_inode_read_subvol_type_get (inode, this, local->readable,
- &event_generation,
- local->transaction.type);
-
- if (ret == -1 || !event_generation)
- /* Even after refresh, we don't have a good
- read subvolume. Time to bail */
- AFR_READ_TXN_SET_ERROR_AND_GOTO (-1, EIO, -1, readfn);
-
- /* For directories in split-brain, we need to allow all fops
- * except (f)getxattr and access. */
- if (!AFR_COUNT(local->readable, priv->child_count) &&
- local->transaction.type == AFR_DATA_TRANSACTION &&
- inode->ia_type == IA_IFDIR)
- memcpy (local->readable, local->child_up, priv->child_count);
-
- read_subvol = afr_read_subvol_select_by_policy (inode, this,
- local->readable, NULL);
- if (read_subvol == -1)
- AFR_READ_TXN_SET_ERROR_AND_GOTO (-1, EIO, -1, readfn);
-
- if (local->read_attempted[read_subvol]) {
- afr_read_txn_next_subvol (frame, this);
- return 0;
- }
-
- local->read_attempted[read_subvol] = 1;
-readfn:
- local->readfn (frame, this, read_subvol);
-
- return 0;
-}
-
-
-int
-afr_read_txn_continue (call_frame_t *frame, xlator_t *this, int subvol)
-{
- afr_local_t *local = NULL;
-
- local = frame->local;
-
- if (!local->refreshed) {
- local->refreshed = _gf_true;
- afr_inode_refresh (frame, this, local->inode,
- afr_read_txn_refresh_done);
- } else {
- afr_read_txn_next_subvol (frame, this);
- }
-
- return 0;
-}
-
-
-/* afr_read_txn_wipe:
-
- clean internal variables in @local in order to make
- it possible to call afr_read_txn() multiple times from
- the same frame
-*/
-
-void
-afr_read_txn_wipe (call_frame_t *frame, xlator_t *this)
-{
- afr_local_t *local = NULL;
- afr_private_t *priv = NULL;
- int i = 0;
-
- local = frame->local;
- priv = this->private;
-
- local->readfn = NULL;
-
- if (local->inode)
- inode_unref (local->inode);
-
- for (i = 0; i < priv->child_count; i++) {
- local->read_attempted[i] = 0;
- local->readable[i] = 0;
- }
-}
-
-
-/*
- afr_read_txn:
-
- This is the read transaction function. The way it works:
-
- - Determine read-subvolume from inode ctx.
-
- - If read-subvolume's generation was stale, refresh ctx once by
- calling afr_inode_refresh()
-
- Else make an attempt to read on read-subvolume.
-
- - If attempted read on read-subvolume fails, refresh ctx once
- by calling afr_inode_refresh()
-
- - After ctx refresh, query read-subvolume freshly and attempt
- read once.
-
- - If read fails, try every other readable[] subvolume before
- finally giving up. readable[] elements are set by afr_inode_refresh()
- based on dirty and pending flags.
-
- - If file is in split brain in the backend, generation will be
- kept 0 by afr_inode_refresh() and readable[] will be set 0 for
- all elements. Therefore reads always fail.
-*/
-
-int
-afr_read_txn (call_frame_t *frame, xlator_t *this, inode_t *inode,
- afr_read_txn_wind_t readfn, afr_transaction_type type)
-{
- afr_local_t *local = NULL;
- afr_private_t *priv = NULL;
- int read_subvol = -1;
- int event_generation = 0;
- int ret = -1;
-
- priv = this->private;
- local = frame->local;
-
- afr_read_txn_wipe (frame, this);
-
- local->readfn = readfn;
- local->inode = inode_ref (inode);
-
- local->transaction.type = type;
- ret = afr_inode_read_subvol_type_get (inode, this, local->readable,
- &event_generation, type);
- if (ret == -1)
- /* very first transaction on this inode */
- goto refresh;
-
- gf_log (this->name, GF_LOG_DEBUG, "%s: generation now vs cached: %d, "
- "%d", uuid_utoa (inode->gfid), local->event_generation,
- event_generation);
- if (local->event_generation != event_generation)
- /* servers have disconnected / reconnected, and possibly
- rebooted, very likely changing the state of freshness
- of copies */
- goto refresh;
-
- read_subvol = afr_read_subvol_select_by_policy (inode, this,
- local->readable, NULL);
-
- if (read_subvol < 0 || read_subvol > priv->child_count) {
- gf_msg (this->name, GF_LOG_WARNING, 0, AFR_MSG_SPLIT_BRAIN,
- "Unreadable subvolume %d found with event generation "
- "%d. (Possible split-brain)",
- read_subvol, event_generation);
- goto refresh;
- }
-
- if (!local->child_up[read_subvol]) {
- /* should never happen, just in case */
- gf_log (this->name, GF_LOG_WARNING, "subvolume %d is the "
- "read subvolume in this generation, but is not up",
- read_subvol);
- goto refresh;
- }
-
- local->read_attempted[read_subvol] = 1;
-
- local->readfn (frame, this, read_subvol);
-
- return 0;
-
-refresh:
- afr_inode_refresh (frame, this, inode, afr_read_txn_refresh_done);
-
- return 0;
-}
diff --git a/xlators/cluster/afr/src/afr-self-heal-algorithm.c b/xlators/cluster/afr/src/afr-self-heal-algorithm.c
new file mode 100644
index 00000000000..8261858d094
--- /dev/null
+++ b/xlators/cluster/afr/src/afr-self-heal-algorithm.c
@@ -0,0 +1,1071 @@
+/*
+ Copyright (c) 2009 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 "glusterfs.h"
+#include "afr.h"
+#include "xlator.h"
+#include "dict.h"
+#include "xlator.h"
+#include "hashfn.h"
+#include "logging.h"
+#include "stack.h"
+#include "list.h"
+#include "call-stub.h"
+#include "defaults.h"
+#include "common-utils.h"
+#include "compat-errno.h"
+#include "compat.h"
+#include "byte-order.h"
+#include "md5.h"
+
+#include "afr-transaction.h"
+#include "afr-self-heal.h"
+#include "afr-self-heal-common.h"
+#include "afr-self-heal-algorithm.h"
+
+/*
+ This file contains the various self-heal algorithms
+*/
+
+
+/*
+ The "full" algorithm. Copies the entire file from
+ source to sinks.
+*/
+
+
+static void
+sh_full_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_full_private_t *sh_priv = NULL;
+
+ priv = this->private;
+ local = frame->local;
+ sh = &local->self_heal;
+
+ sh_priv = sh->private;
+
+ if (sh_priv)
+ FREE (sh_priv);
+}
+
+
+static int
+sh_full_loop_driver (call_frame_t *frame, xlator_t *this);
+
+static int
+sh_full_loop_return (call_frame_t *rw_frame, xlator_t *this, off_t offset)
+{
+ 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_full_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;
+
+ LOCK (&sh_priv->lock);
+ {
+ sh_priv->loops_running--;
+ }
+ UNLOCK (&sh_priv->lock);
+
+ gf_log (this->name, GF_LOG_TRACE,
+ "loop for offset %"PRId64" returned", offset);
+
+ AFR_STACK_DESTROY (rw_frame);
+
+ sh_full_loop_driver (sh_frame, this);
+
+ return 0;
+}
+
+
+static int
+sh_full_write_cbk (call_frame_t *rw_frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct stat *prebuf,
+ struct stat *postbuf)
+{
+ 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;
+
+ 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;
+
+ 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_DEBUG,
+ "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);
+ }
+
+ return 0;
+}
+
+
+static int
+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 stat *buf,
+ struct iobref *iobref)
+{
+ 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) {
+ 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
+ */
+
+ 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_full_read_write (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 *rw_sh = NULL;
+ afr_self_heal_t *sh = NULL;
+
+ call_frame_t *rw_frame = NULL;
+
+ int32_t op_errno = 0;
+
+ priv = this->private;
+ local = frame->local;
+ sh = &local->self_heal;
+
+ 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;
+
+ 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;
+
+ sh_full_loop_driver (frame, this);
+
+ return 0;
+}
+
+
+static int
+sh_full_loop_driver (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_full_private_t *sh_priv = NULL;
+
+ int loop = 0;
+ int recurse = 0;
+
+ off_t offset = 0;
+
+ priv = this->private;
+ local = frame->local;
+ sh = &local->self_heal;
+ sh_priv = sh->private;
+
+ if (sh->op_failed) {
+ if (sh_priv->loops_running == 0) {
+ gf_log (this->name, GF_LOG_TRACE,
+ "full self-heal aborting on %s",
+ local->loc.path);
+
+ sh_full_private_cleanup (frame, this);
+ local->self_heal.algo_abort_cbk (frame, this);
+ }
+
+ goto out;
+ }
+
+ if (sh_priv->offset >= sh->file_size) {
+ if (sh_priv->loops_running == 0) {
+
+ gf_log (this->name, GF_LOG_TRACE,
+ "full self-heal completed on %s",
+ local->loc.path);
+
+ sh_full_private_cleanup (frame, this);
+ local->self_heal.algo_completion_cbk (frame, this);
+ }
+
+ goto out;
+ }
+
+spawn:
+ loop = 0;
+ recurse = 0;
+
+ LOCK (&sh_priv->lock);
+ {
+ if ((sh_priv->loops_running < priv->data_self_heal_window_size)
+ && (sh_priv->offset < sh->file_size)) {
+
+ gf_log (this->name, GF_LOG_TRACE,
+ "spawning a loop for offset %"PRId64,
+ sh_priv->offset);
+
+ offset = sh_priv->offset;
+ sh_priv->offset += sh->block_size;
+
+ sh_priv->loops_running++;
+
+ loop = 1;
+
+ if (sh_priv->offset < sh->file_size)
+ recurse = 1;
+ }
+ }
+ UNLOCK (&sh_priv->lock);
+
+ if (loop) {
+ sh_full_read_write (frame, this, offset);
+ if (recurse)
+ goto spawn;
+ }
+
+out:
+ return 0;
+}
+
+
+int
+afr_sh_algo_full (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_full_private_t *sh_priv = NULL;
+
+ priv = this->private;
+ local = frame->local;
+ sh = &local->self_heal;
+
+ sh_priv = CALLOC (1, sizeof (*sh_priv));
+
+ LOCK_INIT (&sh_priv->lock);
+
+ sh->private = sh_priv;
+
+ local->call_count = 0;
+
+ sh_full_loop_driver (frame, this);
+ 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;
+
+ 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)
+ FREE (sh_priv->loops[i]->write_needed);
+
+ if (sh_priv->loops[i]->checksum)
+ FREE (sh_priv->loops[i]->checksum);
+
+ FREE (sh_priv->loops[i]);
+ }
+ }
+
+ if (sh_priv) {
+ if (sh_priv->loops)
+ FREE (sh_priv->loops);
+
+ 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;
+
+ for (i = 0; i < child_count; i++) {
+ if (write_needed[i])
+ writes++;
+ }
+
+ return writes;
+}
+
+
+static int
+sh_diff_loop_driver (call_frame_t *frame, xlator_t *this);
+
+
+static int
+sh_diff_loop_return (call_frame_t *rw_frame, xlator_t *this,
+ struct sh_diff_loop_state *loop_state)
+{
+ 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;
+
+ gf_log (this->name, GF_LOG_TRACE,
+ "loop for offset %"PRId64" returned", loop_state->offset);
+
+ LOCK (&sh_priv->lock);
+ {
+ sh_priv->loops_running--;
+ sh_diff_loop_state_reset (loop_state, priv->child_count);
+ }
+ UNLOCK (&sh_priv->lock);
+
+ AFR_STACK_DESTROY (rw_frame);
+
+ sh_diff_loop_driver (sh_frame, this);
+
+ return 0;
+}
+
+
+static int
+sh_diff_write_cbk (call_frame_t *rw_frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct stat *buf,
+ struct stat *postbuf)
+{
+ 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;
+ struct sh_diff_loop_state *loop_state;
+
+ int call_count = 0;
+ int child_index = 0;
+ int loop_index = 0;
+
+ 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;
+
+ 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_state->offset);
+
+ LOCK (&sh_frame->lock);
+ {
+ if (op_ret == -1) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "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_diff_loop_return (rw_frame, this, loop_state);
+ }
+
+ return 0;
+}
+
+
+static int
+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 stat *buf,
+ struct iobref *iobref)
+{
+ 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;
+
+ call_frame_t *sh_frame = NULL;
+ afr_local_t * sh_local = NULL;
+ afr_self_heal_t *sh = NULL;
+
+ int loop_index;
+ struct sh_diff_loop_state *loop_state;
+
+ uint32_t wcookie;
+
+ int i = 0;
+ int call_count = 0;
+
+ 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;
+
+ 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, sh_local->loc.path, sh->offset);
+
+ if ((op_ret <= 0) ||
+ (call_count == 0)) {
+ sh_diff_loop_return (rw_frame, this, loop_state);
+
+ return 0;
+ }
+
+ if (sh->file_has_holes) {
+ if (iov_0filled (vector, count) == 0) {
+
+ sh_diff_loop_return (rw_frame, this, loop_state);
+ goto out;
+ }
+ }
+
+ for (i = 0; i < priv->child_count; i++) {
+ if (loop_state->write_needed[i]) {
+ wcookie = __make_cookie (loop_index, i);
+
+ 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:
+ return 0;
+}
+
+
+static int
+sh_diff_read (call_frame_t *rw_frame, xlator_t *this,
+ int loop_index)
+{
+ 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;
+
+ call_frame_t *sh_frame = NULL;
+ afr_local_t * sh_local = NULL;
+ afr_self_heal_t *sh = NULL;
+
+ uint32_t 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;
+ 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 *rw_frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno,
+ uint32_t weak_checksum, uint8_t *strong_checksum)
+{
+ 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;
+
+ int call_count = 0;
+ int i = 0;
+ int write_needed = 0;
+
+ 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;
+
+ 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_state->checksum + child_index * MD5_DIGEST_LEN,
+ strong_checksum,
+ MD5_DIGEST_LEN);
+ }
+
+ 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_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
+ */
+
+ gf_log (this->name, GF_LOG_TRACE,
+ "checksum on subvolume %s at offset %"
+ PRId64" differs from that on source",
+ priv->children[i]->name, loop_state->offset);
+
+ write_needed = loop_state->write_needed[i] = 1;
+ }
+ }
+
+ LOCK (&sh_priv->lock);
+ {
+ sh_priv->total_blocks++;
+ if (write_needed)
+ sh_priv->diff_blocks++;
+ }
+ UNLOCK (&sh_priv->lock);
+
+ if (write_needed && !sh->op_failed) {
+ sh_diff_read (rw_frame, this, loop_index);
+ } else {
+ sh->offset += sh_priv->block_size;
+
+ sh_diff_loop_return (rw_frame, this, loop_state);
+ }
+ }
+
+ return 0;
+}
+
+
+static int
+sh_diff_find_unused_loop (afr_sh_algo_diff_private_t *sh_priv, int max)
+{
+ int i;
+
+ 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);
+
+ 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");
+ }
+
+ return i;
+}
+
+
+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;
+ 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 (sh->sources[i] || !local->child_up[i])
+ continue;
+
+ 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,
+ 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);
+
+ return 0;
+}
+
+
+static int
+sh_diff_loop_driver (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 loop = 0;
+ int recurse = 0;
+
+ off_t offset = 0;
+
+ priv = this->private;
+ local = frame->local;
+ sh = &local->self_heal;
+ sh_priv = sh->private;
+
+ if (sh->op_failed) {
+ if (sh_priv->loops_running == 0) {
+ gf_log (this->name, GF_LOG_TRACE,
+ "diff self-heal aborting on %s",
+ local->loc.path);
+
+ sh_diff_private_cleanup (frame, this);
+ local->self_heal.algo_abort_cbk (frame, this);
+ }
+
+ goto out;
+ }
+
+ if (sh_priv->offset >= sh->file_size) {
+ if (sh_priv->loops_running == 0) {
+ gf_log (this->name, GF_LOG_TRACE,
+ "diff self-heal completed on %s",
+ local->loc.path);
+
+
+ gf_log (this->name, GF_LOG_DEBUG,
+ "diff self-heal on %s: %d blocks of %d were different (%.2f%%)",
+ local->loc.path, sh_priv->diff_blocks,
+ sh_priv->total_blocks,
+ ((sh_priv->diff_blocks * 1.0)/sh_priv->total_blocks) * 100);
+
+ sh_diff_private_cleanup (frame, this);
+ local->self_heal.algo_completion_cbk (frame, this);
+ }
+
+ goto out;
+ }
+
+spawn:
+ loop = 0;
+ recurse = 0;
+
+ LOCK (&sh_priv->lock);
+ {
+ if ((sh_priv->loops_running < priv->data_self_heal_window_size)
+ && (sh_priv->offset < sh->file_size)) {
+
+ gf_log (this->name, GF_LOG_TRACE,
+ "spawning a loop for offset %"PRId64,
+ sh_priv->offset);
+
+ offset = sh_priv->offset;
+ sh_priv->offset += sh_priv->block_size;
+
+ sh_priv->loops_running++;
+
+ loop = 1;
+
+ if (sh_priv->offset < sh->file_size)
+ recurse = 1;
+ }
+ }
+ UNLOCK (&sh_priv->lock);
+
+ if (loop) {
+ sh_diff_checksum (frame, this, offset);
+ if (recurse)
+ goto spawn;
+ }
+
+out:
+ return 0;
+}
+
+
+int
+afr_sh_algo_diff (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;
+
+ priv = this->private;
+ local = frame->local;
+ sh = &local->self_heal;
+
+ sh_priv = CALLOC (1, sizeof (*sh_priv));
+
+ sh_priv->block_size = this->ctx->page_size;
+
+ sh->private = sh_priv;
+
+ LOCK_INIT (&sh_priv->lock);
+
+ local->call_count = 0;
+
+ sh_priv->loops = CALLOC (priv->data_self_heal_window_size,
+ sizeof (*sh_priv->loops));
+
+ for (i = 0; i < priv->data_self_heal_window_size; i++) {
+ sh_priv->loops[i] = CALLOC (1, sizeof (*sh_priv->loops[i]));
+
+ sh_priv->loops[i]->checksum = CALLOC (priv->child_count,
+ MD5_DIGEST_LEN);
+ sh_priv->loops[i]->write_needed = CALLOC (priv->child_count,
+ sizeof (*sh_priv->loops[i]->write_needed));
+ }
+
+ sh_diff_loop_driver (frame, this);
+
+ return 0;
+}
+
+
+struct afr_sh_algorithm afr_self_heal_algorithms[] = {
+ {.name = "full", .fn = afr_sh_algo_full},
+ {.name = "diff", .fn = afr_sh_algo_diff},
+ {0, 0},
+};
diff --git a/xlators/cluster/afr/src/afr-self-heal-algorithm.h b/xlators/cluster/afr/src/afr-self-heal-algorithm.h
new file mode 100644
index 00000000000..0bdae3aa77f
--- /dev/null
+++ b/xlators/cluster/afr/src/afr-self-heal-algorithm.h
@@ -0,0 +1,60 @@
+/*
+ Copyright (c) 2009 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 __AFR_SELF_HEAL_ALGORITHM_H__
+#define __AFR_SELF_HEAL_ALGORITHM_H__
+
+
+typedef int (*afr_sh_algo_fn) (call_frame_t *frame,
+ xlator_t *this);
+
+struct afr_sh_algorithm {
+ const char *name;
+ afr_sh_algo_fn fn;
+};
+
+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;
+
+ 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 b3194724e51..967173146fd 100644
--- a/xlators/cluster/afr/src/afr-self-heal-common.c
+++ b/xlators/cluster/afr/src/afr-self-heal-common.c
@@ -1,1206 +1,1603 @@
/*
- Copyright (c) 2013 Red Hat, Inc. <http://www.redhat.com>
+ Copyright (c) 2008-2009 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 General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+ GlusterFS is distributed in the hope that 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.
-#ifndef _CONFIG_H
-#define _CONFIG_H
-#include "config.h"
-#endif
+ 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 "glusterfs.h"
+#include "xlator.h"
+#include "byte-order.h"
#include "afr.h"
+#include "afr-transaction.h"
+#include "afr-self-heal-common.h"
#include "afr-self-heal.h"
-#include "byte-order.h"
+/**
+ * select_source - select a source and return it
+ */
+
int
-afr_selfheal_post_op_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int op_ret, int op_errno, dict_t *xattr, dict_t *xdata)
+afr_sh_select_source (int sources[], int child_count)
{
- afr_local_t *local = NULL;
+ int i;
+ for (i = 0; i < child_count; i++)
+ if (sources[i])
+ return i;
- local = frame->local;
-
- syncbarrier_wake (&local->barrier);
-
- return 0;
+ return -1;
}
+/**
+ * sink_count - return number of sinks in sources array
+ */
+
int
-afr_selfheal_post_op (call_frame_t *frame, xlator_t *this, inode_t *inode,
- int subvol, dict_t *xattr)
+afr_sh_sink_count (int sources[], int child_count)
{
- afr_private_t *priv = NULL;
- afr_local_t *local = NULL;
- loc_t loc = {0, };
+ int i;
+ int sinks = 0;
+ for (i = 0; i < child_count; i++)
+ if (!sources[i])
+ sinks++;
+ return sinks;
+}
- priv = this->private;
- local = frame->local;
+int
+afr_sh_source_count (int sources[], int child_count)
+{
+ int i;
+ int nsource = 0;
- loc.inode = inode_ref (inode);
- uuid_copy (loc.gfid, inode->gfid);
+ for (i = 0; i < child_count; i++)
+ if (sources[i])
+ nsource++;
+ return nsource;
+}
- STACK_WIND (frame, afr_selfheal_post_op_cbk, priv->children[subvol],
- priv->children[subvol]->fops->xattrop, &loc,
- GF_XATTROP_ADD_ARRAY, xattr, NULL);
- syncbarrier_wait (&local->barrier, 1);
+int
+afr_sh_supress_errenous_children (int sources[], int child_errno[],
+ int child_count)
+{
+ int i = 0;
- loc_wipe (&loc);
+ for (i = 0; i < child_count; i++) {
+ if (child_errno[i] && sources[i]) {
+ sources[i] = 0;
+ }
+ }
return 0;
}
-dict_t *
-afr_selfheal_output_xattr (xlator_t *this, afr_transaction_type type,
- int *output_dirty, int **output_matrix, int subvol)
+void
+afr_sh_print_pending_matrix (int32_t *pending_matrix[], xlator_t *this)
{
- dict_t *xattr = NULL;
- afr_private_t *priv = NULL;
- int j = 0;
- int idx = 0;
- int ret = 0;
- int *raw = 0;
+ afr_private_t * priv = this->private;
- priv = this->private;
- idx = afr_index_for_transaction_type (type);
-
- xattr = dict_new ();
- if (!xattr)
- return NULL;
-
- /* clear dirty */
- raw = GF_CALLOC (sizeof(int), AFR_NUM_CHANGE_LOGS, gf_afr_mt_int32_t);
- if (!raw)
- goto err;
-
- raw[idx] = hton32 (output_dirty[subvol]);
- ret = dict_set_bin (xattr, AFR_DIRTY, raw,
- sizeof(int) * AFR_NUM_CHANGE_LOGS);
- if (ret)
- goto err;
-
- /* clear/set pending */
- for (j = 0; j < priv->child_count; j++) {
- raw = GF_CALLOC (sizeof(int), AFR_NUM_CHANGE_LOGS,
- gf_afr_mt_int32_t);
- if (!raw)
- goto err;
-
- raw[idx] = hton32 (output_matrix[subvol][j]);
-
- ret = dict_set_bin (xattr, priv->pending_key[j],
- raw, sizeof(int) * AFR_NUM_CHANGE_LOGS);
- if (ret)
- goto err;
+ char *buf = NULL;
+ char *ptr = NULL;
+
+ int i, j;
+
+ /* 10 digits per entry + 1 space + '[' and ']' */
+ buf = MALLOC (priv->child_count * 11 + 8);
+
+ for (i = 0; i < priv->child_count; i++) {
+ ptr = buf;
+ ptr += sprintf (ptr, "[ ");
+ for (j = 0; j < priv->child_count; j++) {
+ ptr += sprintf (ptr, "%d ", pending_matrix[i][j]);
+ }
+ ptr += sprintf (ptr, "]");
+ gf_log (this->name, GF_LOG_TRACE,
+ "pending_matrix: %s", buf);
}
- return xattr;
-err:
- if (xattr)
- dict_unref (xattr);
- return NULL;
+ FREE (buf);
}
-int
-afr_selfheal_undo_pending (call_frame_t *frame, xlator_t *this, inode_t *inode,
- unsigned char *sources, unsigned char *sinks,
- unsigned char *healed_sinks, afr_transaction_type type,
- struct afr_reply *replies, unsigned char *locked_on)
+void
+afr_sh_build_pending_matrix (afr_private_t *priv,
+ int32_t *pending_matrix[], dict_t *xattr[],
+ int child_count, afr_transaction_type type)
{
- afr_private_t *priv = NULL;
- int i = 0;
- int j = 0;
- unsigned char *pending = NULL;
- int *input_dirty = NULL;
- int **input_matrix = NULL;
- int *output_dirty = NULL;
- int **output_matrix = NULL;
- dict_t *xattr = NULL;
-
- priv = this->private;
-
- pending = alloca0 (priv->child_count);
+ int i, j, k;
- input_dirty = alloca0 (priv->child_count * sizeof (int));
- input_matrix = ALLOC_MATRIX (priv->child_count, int);
- output_dirty = alloca0 (priv->child_count * sizeof (int));
- output_matrix = ALLOC_MATRIX (priv->child_count, int);
+ int32_t *pending = NULL;
+ int ret = -1;
- afr_selfheal_extract_xattr (this, replies, type, input_dirty,
- input_matrix);
+ unsigned char *ignorant_subvols = NULL;
- for (i = 0; i < priv->child_count; i++)
- if (sinks[i] && !healed_sinks[i])
- pending[i] = 1;
+ ignorant_subvols = CALLOC (sizeof (*ignorant_subvols), child_count);
- for (i = 0; i < priv->child_count; i++) {
- for (j = 0; j < priv->child_count; j++) {
- if (pending[j])
- output_matrix[i][j] = 1;
- else
- output_matrix[i][j] = -input_matrix[i][j];
+ /* 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 < priv->child_count; i++) {
- if (!pending[i])
- output_dirty[i] = -input_dirty[i];
+ for (i = 0; i < child_count; i++) {
+ pending = NULL;
+
+ for (j = 0; j < child_count; j++) {
+ ret = dict_get_ptr (xattr[i], priv->pending_key[j],
+ VOID(&pending));
+
+ if (ret != 0) {
+ /*
+ * There is no xattr present. This means this
+ * subvolume should be considered an 'ignorant'
+ * subvolume.
+ */
+
+ ignorant_subvols[i] = 1;
+ continue;
+ }
+
+ k = afr_index_for_transaction_type (type);
+
+ pending_matrix[i][j] = ntoh32 (pending[k]);
+ }
}
- for (i = 0; i < priv->child_count; i++) {
- if (!locked_on[i])
- /* perform post-op only on subvols we had locked
- and inspected on.
- */
- continue;
+ /*
+ * Make all non-ignorant subvols point towards the ignorant
+ * subvolumes.
+ */
- xattr = afr_selfheal_output_xattr (this, type, output_dirty,
- output_matrix, i);
- if (!xattr) {
- gf_log (this->name, GF_LOG_ERROR,
- "unable to allocate xdata for subvol %d", i);
- continue;
- }
+ 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;
+ }
+ }
+ }
+
+ FREE (ignorant_subvols);
+}
- afr_selfheal_post_op (frame, this, inode, i, xattr);
- dict_unref (xattr);
- }
+/**
+ * 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.
+ */
- return 0;
-}
+typedef enum {
+ AFR_NODE_INNOCENT,
+ AFR_NODE_FOOL,
+ AFR_NODE_WISE
+} afr_node_type;
+typedef struct {
+ afr_node_type type;
+ int wisdom;
+} afr_node_character;
-void
-afr_replies_copy (struct afr_reply *dst, struct afr_reply *src, int count)
+
+static int
+afr_sh_is_innocent (int32_t *array, int child_count)
{
- int i = 0;
- dict_t *xdata = NULL;
-
- if (dst == src)
- return;
-
- for (i = 0; i < count; i++) {
- dst[i].valid = src[i].valid;
- dst[i].op_ret = src[i].op_ret;
- dst[i].op_errno = src[i].op_errno;
- dst[i].prestat = src[i].prestat;
- dst[i].poststat = src[i].poststat;
- dst[i].preparent = src[i].preparent;
- dst[i].postparent = src[i].postparent;
- dst[i].preparent2 = src[i].preparent2;
- dst[i].postparent2 = src[i].postparent2;
- if (src[i].xdata)
- xdata = dict_ref (src[i].xdata);
- else
- xdata = NULL;
- if (dst[i].xdata)
- dict_unref (dst[i].xdata);
- dst[i].xdata = xdata;
- memcpy (dst[i].checksum, src[i].checksum,
- MD5_DIGEST_LENGTH);
- }
+ int i = 0;
+ int ret = 1; /* innocent until proven guilty */
+
+ for (i = 0; i < child_count; i++) {
+ if (array[i]) {
+ ret = 0;
+ break;
+ }
+ }
+
+ return ret;
}
-int
-afr_selfheal_fill_dirty (xlator_t *this, int *dirty, int subvol,
- int idx, dict_t *xdata)
+static int
+afr_sh_is_fool (int32_t *array, int i, int child_count)
{
- void *pending_raw = NULL;
- int pending[3] = {0, };
+ return array[i]; /* fool if accuses itself */
+}
- if (dict_get_ptr (xdata, AFR_DIRTY, &pending_raw))
- return -1;
- if (!pending_raw)
- return -1;
+static int
+afr_sh_is_wise (int32_t *array, int i, int child_count)
+{
+ return !array[i]; /* wise if does not accuse itself */
+}
+
- memcpy (pending, pending_raw, sizeof(pending));
+static int
+afr_sh_all_nodes_innocent (afr_node_character *characters,
+ int child_count)
+{
+ int i = 0;
+ int ret = 1;
- dirty[subvol] = ntoh32 (pending[idx]);
+ for (i = 0; i < child_count; i++) {
+ if (characters[i].type != AFR_NODE_INNOCENT) {
+ ret = 0;
+ break;
+ }
+ }
- return 0;
+ return ret;
}
-int
-afr_selfheal_fill_matrix (xlator_t *this, int **matrix, int subvol,
- int idx, dict_t *xdata)
+static int
+afr_sh_wise_nodes_exist (afr_node_character *characters, int child_count)
{
- int i = 0;
- void *pending_raw = NULL;
- int pending[3] = {0, };
- afr_private_t *priv = NULL;
+ int i = 0;
+ int ret = 0;
- priv = this->private;
+ for (i = 0; i < child_count; i++) {
+ if (characters[i].type == AFR_NODE_WISE) {
+ ret = 1;
+ break;
+ }
+ }
- for (i = 0; i < priv->child_count; i++) {
- if (dict_get_ptr (xdata, priv->pending_key[i], &pending_raw))
- continue;
+ return ret;
+}
- if (!pending_raw)
- continue;
- memcpy (pending, pending_raw, sizeof(pending));
+/*
+ * The 'wisdom' of a wise node is 0 if any other wise node accuses it.
+ * 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 occured.
+ */
- matrix[subvol][i] = ntoh32 (pending[idx]);
- }
+static void
+afr_sh_compute_wisdom (int32_t *pending_matrix[],
+ afr_node_character characters[], int child_count)
+{
+ int i = 0;
+ int j = 0;
- return 0;
+ for (i = 0; i < child_count; i++) {
+ if (characters[i].type == AFR_NODE_WISE) {
+ characters[i].wisdom = 1;
+
+ for (j = 0; j < child_count; j++) {
+ if ((characters[j].type == AFR_NODE_WISE)
+ && pending_matrix[j][i]) {
+
+ characters[i].wisdom = 0;
+ }
+ }
+ }
+ }
}
-int
-afr_selfheal_extract_xattr (xlator_t *this, struct afr_reply *replies,
- afr_transaction_type type, int *dirty, int **matrix)
+static int
+afr_sh_wise_nodes_conflict (afr_node_character *characters,
+ int child_count)
{
- afr_private_t *priv = NULL;
- int i = 0;
- dict_t *xdata = NULL;
- int idx = -1;
+ int i = 0;
+ int ret = 1;
- idx = afr_index_for_transaction_type (type);
+ for (i = 0; i < child_count; i++) {
+ if ((characters[i].type == AFR_NODE_WISE)
+ && characters[i].wisdom == 1) {
- priv = this->private;
+ /* There is atleast one bona-fide wise node */
+ ret = 0;
+ break;
+ }
+ }
- for (i = 0; i < priv->child_count; i++) {
- if (!replies[i].xdata)
- continue;
+ return ret;
+}
- xdata = replies[i].xdata;
- afr_selfheal_fill_dirty (this, dirty, i, idx, xdata);
- afr_selfheal_fill_matrix (this, matrix, i, idx, xdata);
- }
+static int
+afr_sh_mark_wisest_as_sources (int sources[],
+ afr_node_character *characters,
+ int child_count)
+{
+ int nsources = 0;
+
+ int i = 0;
- return 0;
+ for (i = 0; i < child_count; i++) {
+ if (characters[i].wisdom == 1) {
+ sources[i] = 1;
+ nsources++;
+ }
+ }
+
+ return nsources;
}
-void
-afr_mark_active_sinks (xlator_t *this, unsigned char *sources,
- unsigned char *locked_on, unsigned char *sinks)
+
+static int
+afr_sh_mark_if_size_differs (afr_self_heal_t *sh, int child_count)
{
- int i = 0;
- afr_private_t *priv = NULL;
+ int32_t ** pending_matrix;
+ int i, j;
- priv = this->private;
+ int size_differs = 0;
- memset (sinks, 0, sizeof (*sinks) * priv->child_count);
- for (i = 0; i < priv->child_count; i++) {
- if (!sources[i] && locked_on[i])
- sinks[i] = 1;
+ pending_matrix = sh->pending_matrix;
+
+ for (i = 0; i < child_count; i++) {
+ for (j = 0; j < child_count; j++) {
+ if (!sh->buf)
+ break;
+
+ if (SIZE_DIFFERS (&sh->buf[i], &sh->buf[j])
+ && (pending_matrix[i][j] == 0)
+ && (pending_matrix[j][i] == 0)) {
+
+ pending_matrix[i][j] = 1;
+ pending_matrix[j][i] = 1;
+
+ size_differs = 1;
+ }
+ }
}
+
+ return size_differs;
}
-gf_boolean_t
-afr_does_witness_exist (xlator_t *this, uint64_t *witness)
+
+static int
+afr_sh_mark_biggest_fool_as_source (afr_self_heal_t *sh,
+ afr_node_character *characters,
+ int child_count)
{
int i = 0;
- afr_private_t *priv = NULL;
+ int biggest = 0;
- priv = this->private;
+ for (i = 0; i < child_count; i++) {
+ if (characters[i].type == AFR_NODE_FOOL) {
+ biggest = i;
+ break;
+ }
+ }
- for (i = 0; i < priv->child_count; i++) {
- if (witness[i])
- return _gf_true;
+ for (i = 0; i < child_count; i++) {
+ if (characters[i].type != AFR_NODE_FOOL)
+ continue;
+
+ if (!sh->buf)
+ break;
+
+ if (SIZE_GREATER (&sh->buf[i], &sh->buf[biggest])) {
+ biggest = i;
+ }
}
- return _gf_false;
+
+ sh->sources[biggest] = 1;
+
+ return 1;
}
-/*
- * This function determines if a self-heal is required for a given inode,
- * and if needed, in what direction.
- *
- * locked_on[] is the array representing servers which have been locked and
- * from which xattrs have been fetched for analysis.
- *
- * The output of the function is by filling the arrays sources[] and sinks[].
- *
- * sources[i] is set if i'th server is an eligible source for a selfheal.
- *
- * sinks[i] is set if i'th server needs to be healed.
- *
- * if sources[0..N] are all set, there is no need for a selfheal.
- *
- * if sinks[0..N] are all set, the inode is in split brain.
- *
- */
-int
-afr_selfheal_find_direction (call_frame_t *frame, xlator_t *this,
- struct afr_reply *replies,
- afr_transaction_type type,
- unsigned char *locked_on, unsigned char *sources,
- unsigned char *sinks, uint64_t *witness)
+static int
+afr_sh_mark_biggest_as_source (afr_self_heal_t *sh, int child_count)
{
- afr_private_t *priv = NULL;
- int i = 0;
- int j = 0;
- int *dirty = NULL; /* Denotes if dirty xattr is set */
- int **matrix = NULL;/* Changelog matrix */
- char *accused = NULL;/* Accused others without any self-accusal */
- char *pending = NULL;/* Have pending operations on others */
- char *self_accused = NULL; /* Accused itself */
+ int biggest = 0;
+ int i;
- priv = this->private;
+ for (i = 0; i < child_count; i++) {
+ if (!sh->buf)
+ break;
- dirty = alloca0 (priv->child_count * sizeof (int));
- accused = alloca0 (priv->child_count);
- pending = alloca0 (priv->child_count);
- self_accused = alloca0 (priv->child_count);
- matrix = ALLOC_MATRIX(priv->child_count, int);
- memset (witness, 0, sizeof (*witness) * priv->child_count);
-
- if (afr_success_count (replies,
- priv->child_count) < AFR_SH_MIN_PARTICIPANTS) {
- /* Treat this just like locks not being acquired */
- return -ENOTCONN;
+ if (SIZE_GREATER (&sh->buf[i], &sh->buf[biggest])) {
+ biggest = i;
+ }
}
- /* First construct the pending matrix for further analysis */
- afr_selfheal_extract_xattr (this, replies, type, dirty, matrix);
+ sh->sources[biggest] = 1;
- /* short list all self-accused */
- for (i = 0; i < priv->child_count; i++) {
- if (matrix[i][i])
- self_accused[i] = 1;
- }
+ return 1;
+}
- /* Next short list all accused to exclude them from being sources */
- /* Self-accused can't accuse others as they are FOOLs */
- for (i = 0; i < priv->child_count; i++) {
- for (j = 0; j < priv->child_count; j++) {
- if (matrix[i][j]) {
- if (!self_accused[i])
- accused[j] = 1;
- if (i != j)
- pending[i] = 1;
- }
- }
- }
+static int
+afr_sh_mark_lowest_uid_as_source (afr_self_heal_t *sh, int child_count)
+{
+ uid_t smallest = 0;
+ int i;
- /* Short list all non-accused as sources */
- memset (sources, 0, priv->child_count);
- for (i = 0; i < priv->child_count; i++) {
- if (!accused[i] && locked_on[i])
- sources[i] = 1;
- }
+ for (i = 0; i < child_count; i++) {
+ if (!sh->buf)
+ break;
- /* Everyone accused by non-self-accused sources are sinks */
- memset (sinks, 0, priv->child_count);
- for (i = 0; i < priv->child_count; i++) {
- if (!sources[i])
- continue;
- if (self_accused[i])
- continue;
- for (j = 0; j < priv->child_count; j++) {
- if (matrix[i][j])
- sinks[j] = 1;
+ if (sh->buf[i].st_uid < sh->buf[smallest].st_uid) {
+ smallest = i;
}
}
- /* For breaking ties provide with number of fops they witnessed */
+ sh->sources[smallest] = 1;
- /*
- * count the pending fops witnessed from itself to others when it is
- * self-accused
- */
- for (i = 0; i < priv->child_count; i++) {
- if (!self_accused[i])
- continue;
- for (j = 0; j < priv->child_count; j++) {
- if (i == j)
- continue;
- witness[i] += matrix[i][j];
+ return 1;
+}
+
+
+int
+afr_sh_mark_sources (afr_self_heal_t *sh, int child_count,
+ afr_self_heal_type type)
+{
+ int i = 0;
+
+ int32_t ** pending_matrix;
+ int * sources;
+
+ int size_differs = 0;
+
+ pending_matrix = sh->pending_matrix;
+ sources = sh->sources;
+
+ int nsources = 0;
+
+ /* stores the 'characters' (innocent, fool, wise) of the nodes */
+ afr_node_character *
+ characters = CALLOC (sizeof (afr_node_character),
+ child_count);
+
+ /* start clean */
+ for (i = 0; i < child_count; i++) {
+ sources[i] = 0;
+ }
+
+ for (i = 0; i < child_count; i++) {
+ if (afr_sh_is_innocent (pending_matrix[i], child_count)) {
+ characters[i].type = AFR_NODE_INNOCENT;
+
+ } else if (afr_sh_is_fool (pending_matrix[i], i, child_count)) {
+ characters[i].type = AFR_NODE_FOOL;
+
+ } else if (afr_sh_is_wise (pending_matrix[i], i, child_count)) {
+ characters[i].type = AFR_NODE_WISE;
+
+ } else {
+ gf_log ("[module:replicate]", GF_LOG_ERROR,
+ "Could not determine the state of subvolume %d!"
+ " (This message should never appear."
+ " Please file a bug report to "
+ "<gluster-devel@nongnu.org>.)", i);
}
}
- /* In afr-v1 if a file is self-accused but didn't have any pending
- * operations on others then it is similar to 'dirty' in afr-v2.
- * Consider such cases as witness.
- */
- for (i = 0; i < priv->child_count; i++) {
- if (self_accused[i] && !pending[i])
- witness[i] += matrix[i][i];
+ if (type == AFR_SELF_HEAL_DATA) {
+ size_differs = afr_sh_mark_if_size_differs (sh, child_count);
}
- /* count the number of dirty fops witnessed */
- for (i = 0; i < priv->child_count; i++)
- witness[i] += dirty[i];
+ if ((type == AFR_SELF_HEAL_METADATA)
+ && afr_sh_all_nodes_innocent (characters, child_count)) {
- return 0;
-}
+ nsources = afr_sh_mark_lowest_uid_as_source (sh, child_count);
+ goto out;
+ }
-void
-afr_log_selfheal (uuid_t gfid, xlator_t *this, int ret, char *type,
- int source, unsigned char *healed_sinks)
-{
- char *status = NULL;
- char *sinks_str = NULL;
- char *p = NULL;
- afr_private_t *priv = NULL;
- gf_loglevel_t loglevel = GF_LOG_NONE;
- int i = 0;
+ if (afr_sh_all_nodes_innocent (characters, child_count)) {
+ if (size_differs) {
+ nsources = afr_sh_mark_biggest_as_source (sh,
+ child_count);
+ }
- priv = this->private;
- sinks_str = alloca0 (priv->child_count * 8);
- p = sinks_str;
- for (i = 0; i < priv->child_count; i++) {
- if (!healed_sinks[i])
- continue;
- p += sprintf (p, "%d ", i);
- }
+ } 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)) {
+ /* split-brain */
+
+ nsources = -1;
+ goto out;
- if (ret < 0) {
- status = "Failed";
- loglevel = GF_LOG_DEBUG;
+ } else {
+ nsources = afr_sh_mark_wisest_as_sources (sources,
+ characters,
+ child_count);
+ }
} else {
- status = "Completed";
- loglevel = GF_LOG_INFO;
+ nsources = afr_sh_mark_biggest_fool_as_source (sh, characters,
+ child_count);
}
- gf_log (this->name, loglevel, "%s %s selfheal on %s. "
- "source=%d sinks=%s", status, type, uuid_utoa (gfid),
- source, sinks_str);
+out:
+ FREE (characters);
+
+ return nsources;
}
-int
-afr_selfheal_discover_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 *parbuf)
+
+void
+afr_sh_pending_to_delta (afr_private_t *priv, dict_t **xattr,
+ int32_t *delta_matrix[], int success[],
+ int child_count, afr_transaction_type type)
{
- afr_local_t *local = NULL;
- int i = -1;
+ int i = 0;
+ int j = 0;
+ int k = 0;
- local = frame->local;
- i = (long) cookie;
+ int32_t * pending = NULL;
+ int ret = 0;
- local->replies[i].valid = 1;
- local->replies[i].op_ret = op_ret;
- local->replies[i].op_errno = op_errno;
- if (buf)
- local->replies[i].poststat = *buf;
- if (parbuf)
- local->replies[i].postparent = *parbuf;
- if (xdata)
- local->replies[i].xdata = dict_ref (xdata);
+ /* start clean */
+ for (i = 0; i < child_count; i++) {
+ for (j = 0; j < child_count; j++) {
+ delta_matrix[i][j] = 0;
+ }
+ }
- syncbarrier_wake (&local->barrier);
+ for (i = 0; i < child_count; i++) {
+ pending = NULL;
- return 0;
-}
+ for (j = 0; j < child_count; j++) {
+ ret = dict_get_ptr (xattr[i], priv->pending_key[j],
+ VOID(&pending));
+
+ if (!success[j])
+ continue;
+ k = afr_index_for_transaction_type (type);
+
+ if (pending) {
+ delta_matrix[i][j] = -(ntoh32 (pending[k]));
+ } else {
+ delta_matrix[i][j] = 0;
+ }
-inode_t *
-afr_selfheal_unlocked_lookup_on (call_frame_t *frame, inode_t *parent,
- const char *name, struct afr_reply *replies,
- unsigned char *lookup_on, dict_t *xattr)
-{
- loc_t loc = {0, };
- dict_t *xattr_req = NULL;
- afr_local_t *local = NULL;
- afr_private_t *priv = NULL;
- inode_t *inode = NULL;
+ }
+ }
+}
- local = frame->local;
- priv = frame->this->private;
- xattr_req = dict_new ();
- if (!xattr_req)
- return NULL;
+int
+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;
- if (xattr)
- dict_copy (xattr, xattr_req);
+ int ret = 0;
- if (afr_xattr_req_prepare (frame->this, xattr_req) != 0) {
- dict_destroy (xattr_req);
- return NULL;
- }
+ int32_t *pending = 0;
- inode = inode_new (parent->table);
- if (!inode) {
- dict_destroy (xattr_req);
- return NULL;
- }
+ for (i = 0; i < child_count; i++) {
+ if (!xattr[i])
+ continue;
- loc.parent = inode_ref (parent);
- uuid_copy (loc.pargfid, parent->gfid);
- loc.name = name;
- loc.inode = inode_ref (inode);
+ for (j = 0; j < child_count; j++) {
+ pending = CALLOC (sizeof (int32_t), 3);
+ /* 3 = data+metadata+entry */
- AFR_ONLIST (lookup_on, frame, afr_selfheal_discover_cbk, lookup, &loc,
- xattr_req);
+ k = afr_index_for_transaction_type (type);
- afr_replies_copy (replies, local->replies, priv->child_count);
+ pending[k] = hton32 (delta_matrix[i][j]);
- loc_wipe (&loc);
- dict_unref (xattr_req);
+ ret = dict_set_bin (xattr[i], priv->pending_key[j],
+ pending,
+ 3 * sizeof (int32_t));
+ }
+ }
- return inode;
+ return 0;
}
+
int
-afr_selfheal_unlocked_discover_on (call_frame_t *frame, inode_t *inode,
- uuid_t gfid, struct afr_reply *replies,
- unsigned char *discover_on)
+afr_sh_has_metadata_pending (dict_t *xattr, int child_count, xlator_t *this)
{
- loc_t loc = {0, };
- dict_t *xattr_req = NULL;
- afr_local_t *local = NULL;
afr_private_t *priv = NULL;
+ int32_t *pending = NULL;
+ void *tmp_pending = NULL; /* This is required to remove 'type-punned' warnings from gcc */
- local = frame->local;
- priv = frame->this->private;
-
- xattr_req = dict_new ();
- if (!xattr_req)
- return -ENOMEM;
+ int ret = -1;
+ int i = 0;
+ int j = 0;
- if (afr_xattr_req_prepare (frame->this, xattr_req) != 0) {
- dict_destroy (xattr_req);
- return -ENOMEM;
- }
+ priv = this->private;
- loc.inode = inode_ref (inode);
- uuid_copy (loc.gfid, gfid);
+ for (i = 0; i < priv->child_count; i++) {
+ ret = dict_get_ptr (xattr, priv->pending_key[i],
+ &tmp_pending);
- AFR_ONLIST (discover_on, frame, afr_selfheal_discover_cbk, lookup, &loc,
- xattr_req);
+ if (ret != 0)
+ return 0;
+
+ pending = tmp_pending;
- afr_replies_copy (replies, local->replies, priv->child_count);
+ j = afr_index_for_transaction_type (AFR_METADATA_TRANSACTION);
- loc_wipe (&loc);
- dict_unref (xattr_req);
+ if (pending[j])
+ return 1;
+ }
return 0;
}
+
int
-afr_selfheal_unlocked_discover (call_frame_t *frame, inode_t *inode,
- uuid_t gfid, struct afr_reply *replies)
+afr_sh_has_data_pending (dict_t *xattr, int child_count, xlator_t *this)
{
afr_private_t *priv = NULL;
+ int32_t *pending = NULL;
+ void *tmp_pending = NULL; /* This is required to remove 'type-punned' warnings from gcc */
- priv = frame->this->private;
+ int ret = -1;
+ int i = 0;
+ int j = 0;
- return afr_selfheal_unlocked_discover_on (frame, inode, gfid, replies,
- priv->child_up);
-}
+ priv = this->private;
-unsigned int
-afr_success_count (struct afr_reply *replies, unsigned int count)
-{
- int i = 0;
- unsigned int success = 0;
+ for (i = 0; i < priv->child_count; i++) {
+ ret = dict_get_ptr (xattr, priv->pending_key[i],
+ &tmp_pending);
+
+ if (ret != 0)
+ return 0;
+
+ pending = tmp_pending;
+
+ j = afr_index_for_transaction_type (AFR_DATA_TRANSACTION);
+
+ if (pending[j])
+ return 1;
+ }
- for (i = 0; i < count; i++)
- if (replies[i].valid && replies[i].op_ret == 0)
- success++;
- return success;
+ return 0;
}
+
int
-afr_selfheal_lock_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int op_ret, int op_errno, dict_t *xdata)
+afr_sh_has_entry_pending (dict_t *xattr, int child_count, xlator_t *this)
{
- afr_local_t *local = NULL;
- int i = 0;
+ afr_private_t *priv = NULL;
+ int32_t *pending = NULL;
+ void *tmp_pending = NULL; /* This is required to remove 'type-punned' warnings from gcc */
- local = frame->local;
- i = (long) cookie;
+ int ret = -1;
+ int i = 0;
+ int j = 0;
+
+ priv = this->private;
- local->replies[i].valid = 1;
- local->replies[i].op_ret = op_ret;
- local->replies[i].op_errno = op_errno;
+ for (i = 0; i < priv->child_count; i++) {
+ ret = dict_get_ptr (xattr, priv->pending_key[i],
+ &tmp_pending);
+
+ if (ret != 0)
+ return 0;
+
+ pending = tmp_pending;
- syncbarrier_wake (&local->barrier);
+ j = afr_index_for_transaction_type (AFR_ENTRY_TRANSACTION);
+
+ if (pending[j])
+ return 1;
+ }
return 0;
}
+/**
+ * is_matrix_zero - return true if pending matrix is all zeroes
+ */
+
int
-afr_selfheal_locked_fill (call_frame_t *frame, xlator_t *this,
- unsigned char *locked_on)
+afr_sh_is_matrix_zero (int32_t *pending_matrix[], int child_count)
{
- int i = 0;
- afr_private_t *priv = NULL;
- afr_local_t *local = NULL;
- int count = 0;
+ int i, j;
+
+ 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;
+// memset (sh->child_errno, 0, sizeof (int) * priv->child_count);
+ memset (sh->buf, 0, sizeof (struct stat) * 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 (local->replies[i].valid && local->replies[i].op_ret == 0) {
- locked_on[i] = 1;
- count++;
- } else {
- locked_on[i] = 0;
- }
+ if (sh->xattr[i])
+ dict_unref (sh->xattr[i]);
+ sh->xattr[i] = NULL;
}
- return count;
+ if (local->govinda_gOvinda) {
+ gf_log (this->name, GF_LOG_TRACE,
+ "aborting selfheal of %s",
+ local->loc.path);
+ sh->completion_cbk (frame, this);
+ } else {
+ gf_log (this->name, GF_LOG_TRACE,
+ "proceeding to metadata check on %s",
+ local->loc.path);
+ afr_self_heal_metadata (frame, this);
+ }
+
+ return 0;
}
int
-afr_selfheal_tryinodelk (call_frame_t *frame, xlator_t *this, inode_t *inode,
- char *dom, off_t off, size_t size,
- unsigned char *locked_on)
+sh_missing_entries_unlck_cbk (call_frame_t *frame, void *cookie,
+ xlator_t *this,
+ int32_t op_ret, int32_t op_errno)
{
- loc_t loc = {0,};
- struct gf_flock flock = {0, };
+ afr_local_t *local = NULL;
+ afr_self_heal_t *sh = NULL;
+ afr_private_t *priv = NULL;
+ int call_count = 0;
- loc.inode = inode_ref (inode);
- uuid_copy (loc.gfid, inode->gfid);
- flock.l_type = F_WRLCK;
- flock.l_start = off;
- flock.l_len = size;
+ local = frame->local;
+ sh = &local->self_heal;
+ priv = this->private;
- AFR_ONALL (frame, afr_selfheal_lock_cbk, inodelk, dom,
- &loc, F_SETLK, &flock, NULL);
+ LOCK (&frame->lock);
+ {
+ }
+ UNLOCK (&frame->lock);
- loc_wipe (&loc);
+ call_count = afr_frame_return (frame);
- return afr_selfheal_locked_fill (frame, this, locked_on);
-}
+ if (call_count == 0) {
+ afr_sh_missing_entries_done (frame, this);
+ }
+ return 0;
+}
+
-int
-afr_selfheal_inodelk (call_frame_t *frame, xlator_t *this, inode_t *inode,
- char *dom, off_t off, size_t size,
- unsigned char *locked_on)
+static int
+sh_missing_entries_finish (call_frame_t *frame, xlator_t *this)
{
- loc_t loc = {0,};
- struct gf_flock flock = {0, };
- afr_local_t *local = NULL;
- int i = 0;
- afr_private_t *priv = NULL;
+ afr_private_t *priv = NULL;
+ afr_local_t *local = NULL;
+ int i = 0;
+ int call_count = 0;
+ afr_self_heal_t *sh = NULL;
+
- priv = this->private;
local = frame->local;
+ sh = &local->self_heal;
+ priv = this->private;
- loc.inode = inode_ref (inode);
- uuid_copy (loc.gfid, inode->gfid);
+ for (i = 0; i < priv->child_count; i++) {
+ if (sh->locked_nodes[i])
+ call_count++;
+ }
- flock.l_type = F_WRLCK;
- flock.l_start = off;
- flock.l_len = size;
+ if (call_count == 0) {
+ afr_sh_missing_entries_done (frame, this);
+ return 0;
+ }
- AFR_ONALL (frame, afr_selfheal_lock_cbk, inodelk, dom,
- &loc, F_SETLK, &flock, NULL);
+ local->call_count = call_count;
for (i = 0; i < priv->child_count; i++) {
- if (local->replies[i].op_ret == -1 &&
- local->replies[i].op_errno == EAGAIN) {
- afr_selfheal_locked_fill (frame, this, locked_on);
- afr_selfheal_uninodelk (frame, this, inode, dom, off,
- size, locked_on);
-
- AFR_SEQ (frame, afr_selfheal_lock_cbk, inodelk, dom,
- &loc, F_SETLKW, &flock, NULL);
- break;
+ if (sh->locked_nodes[i]) {
+ gf_log (this->name, GF_LOG_TRACE,
+ "unlocking %"PRId64"/%s on subvolume %s",
+ sh->parent_loc.inode->ino, local->loc.name,
+ priv->children[i]->name);
+
+ STACK_WIND (frame, sh_missing_entries_unlck_cbk,
+ priv->children[i],
+ priv->children[i]->fops->entrylk,
+ this->name,
+ &sh->parent_loc, local->loc.name,
+ ENTRYLK_UNLOCK, ENTRYLK_WRLCK);
+
+ if (!--call_count)
+ break;
}
}
-
- loc_wipe (&loc);
-
- return afr_selfheal_locked_fill (frame, this, locked_on);
+ return 0;
}
-int
-afr_selfheal_uninodelk (call_frame_t *frame, xlator_t *this, inode_t *inode,
- char *dom, off_t off, size_t size,
- const unsigned char *locked_on)
+static int
+sh_destroy_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int op_errno,
+ struct stat *preop, struct stat *postop)
{
- loc_t loc = {0,};
- struct gf_flock flock = {0, };
+ afr_local_t *local = NULL;
+ loc_t *parent_loc = cookie;
- loc.inode = inode_ref (inode);
- uuid_copy (loc.gfid, inode->gfid);
+ int call_count = 0;
- flock.l_type = F_UNLCK;
- flock.l_start = off;
- flock.l_len = size;
+ local = frame->local;
- AFR_ONLIST (locked_on, frame, afr_selfheal_lock_cbk, inodelk,
- dom, &loc, F_SETLK, &flock, NULL);
+ if (op_ret == -1) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "setattr on %s failed: %s",
+ local->loc.path, strerror (op_errno));
+ }
- loc_wipe (&loc);
+ if (parent_loc) {
+ loc_wipe (parent_loc);
+ FREE (parent_loc);
+ }
+ call_count = afr_frame_return (frame);
+
+ if (call_count == 0) {
+ STACK_DESTROY (frame->root);
+ }
+
return 0;
}
-int
-afr_selfheal_tryentrylk (call_frame_t *frame, xlator_t *this, inode_t *inode,
- char *dom, const char *name, unsigned char *locked_on)
+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 stat *buf,
+ struct stat *preparent,
+ struct stat *postparent)
{
- loc_t loc = {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 stat stbuf;
+ int32_t valid;
+
+ local = frame->local;
+ sh = &local->self_heal;
+ priv = this->private;
+
+ child_index = (long) cookie;
+
+#ifdef HAVE_STRUCT_STAT_ST_ATIM_TV_NSEC
+ stbuf.st_atim = sh->buf[sh->source].st_atim;
+ stbuf.st_mtim = sh->buf[sh->source].st_mtim;
+
+#elif HAVE_STRUCT_STAT_ST_ATIMESPEC_TV_NSEC
+ stbuf.st_atimespec = sh->buf[sh->source].st_atimespec;
+ stbuf.st_mtimespec = sh->buf[sh->source].st_mtimespec;
+#else
+ stbuf.st_atime = sh->buf[sh->source].st_atime;
+ stbuf.st_mtime = sh->buf[sh->source].st_mtime;
+#endif
- loc.inode = inode_ref (inode);
- uuid_copy (loc.gfid, inode->gfid);
+ stbuf.st_uid = sh->buf[sh->source].st_uid;
+ stbuf.st_gid = sh->buf[sh->source].st_gid;
+
+ valid = GF_SET_ATTR_UID | GF_SET_ATTR_GID |
+ GF_SET_ATTR_ATIME | GF_SET_ATTR_MTIME;
+
+ if (op_ret == 0) {
+ setattr_frame = copy_frame (frame);
+
+ setattr_frame->local = CALLOC (1, sizeof (afr_local_t));
+
+ ((afr_local_t *)setattr_frame->local)->call_count = 2;
+
+ gf_log (this->name, GF_LOG_TRACE,
+ "setattr (%s) on subvolume %s",
+ local->loc.path, priv->children[child_index]->name);
+
+ 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);
+
+ valid = GF_SET_ATTR_ATIME | GF_SET_ATTR_MTIME;
+ parent_loc = CALLOC (1, sizeof (*parent_loc));
+ 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);
+ }
- AFR_ONALL (frame, afr_selfheal_lock_cbk, entrylk, dom,
- &loc, name, ENTRYLK_LOCK_NB, ENTRYLK_WRLCK, NULL);
+ call_count = afr_frame_return (frame);
- loc_wipe (&loc);
+ if (call_count == 0) {
+ sh_missing_entries_finish (frame, this);
+ }
- return afr_selfheal_locked_fill (frame, this, locked_on);
+ return 0;
}
-int
-afr_selfheal_entrylk (call_frame_t *frame, xlator_t *this, inode_t *inode,
- char *dom, const char *name, unsigned char *locked_on)
+static int
+sh_missing_entries_mknod (call_frame_t *frame, xlator_t *this)
{
- loc_t loc = {0,};
- afr_local_t *local = NULL;
- int i = 0;
- afr_private_t *priv = NULL;
+ afr_local_t *local = NULL;
+ afr_self_heal_t *sh = NULL;
+ afr_private_t *priv = NULL;
+ int i = 0;
+ int enoent_count = 0;
+ int call_count = 0;
+ mode_t st_mode = 0;
+ dev_t st_dev = 0;
+
- priv = this->private;
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++;
- loc.inode = inode_ref (inode);
- uuid_copy (loc.gfid, inode->gfid);
+ call_count = enoent_count;
+ local->call_count = call_count;
- AFR_ONALL (frame, afr_selfheal_lock_cbk, entrylk, dom, &loc,
- name, ENTRYLK_LOCK_NB, ENTRYLK_WRLCK, NULL);
+ st_mode = sh->buf[sh->source].st_mode;
+ st_dev = sh->buf[sh->source].st_dev;
+
+ gf_log (this->name, GF_LOG_TRACE,
+ "mknod %s mode 0%o on %d subvolumes",
+ local->loc.path, st_mode, enoent_count);
for (i = 0; i < priv->child_count; i++) {
- if (local->replies[i].op_ret == -1 &&
- local->replies[i].op_errno == EAGAIN) {
- afr_selfheal_locked_fill (frame, this, locked_on);
- afr_selfheal_unentrylk (frame, this, inode, dom, name,
- locked_on);
-
- AFR_SEQ (frame, afr_selfheal_lock_cbk, entrylk, dom,
- &loc, name, ENTRYLK_LOCK, ENTRYLK_WRLCK, NULL);
- break;
+ 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_dev);
+ if (!--call_count)
+ break;
}
}
- loc_wipe (&loc);
-
- return afr_selfheal_locked_fill (frame, this, locked_on);
+ return 0;
}
-int
-afr_selfheal_unentrylk (call_frame_t *frame, xlator_t *this, inode_t *inode,
- char *dom, const char *name, unsigned char *locked_on)
+static int
+sh_missing_entries_mkdir (call_frame_t *frame, xlator_t *this)
{
- loc_t loc = {0,};
+ afr_local_t *local = NULL;
+ afr_self_heal_t *sh = NULL;
+ afr_private_t *priv = NULL;
+ int i = 0;
+ int enoent_count = 0;
+ int call_count = 0;
+ mode_t st_mode = 0;
- loc.inode = inode_ref (inode);
- uuid_copy (loc.gfid, inode->gfid);
- AFR_ONLIST (locked_on, frame, afr_selfheal_lock_cbk, entrylk,
- dom, &loc, name, ENTRYLK_UNLOCK, ENTRYLK_WRLCK, NULL);
+ 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++;
- loc_wipe (&loc);
+ call_count = enoent_count;
+ local->call_count = call_count;
+
+ st_mode = sh->buf[sh->source].st_mode;
+
+ gf_log (this->name, GF_LOG_TRACE,
+ "mkdir %s mode 0%o on %d subvolumes",
+ local->loc.path, st_mode, enoent_count);
+
+ 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 "/" */
+
+ sh_missing_entries_finish (frame, this);
+
+ 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);
+ if (!--call_count)
+ break;
+ }
+ }
+ }
return 0;
}
-gf_boolean_t
-afr_is_pending_set (xlator_t *this, dict_t *xdata, int type)
+static int
+sh_missing_entries_symlink (call_frame_t *frame, xlator_t *this,
+ const char *link)
{
- int idx = -1;
- afr_private_t *priv = NULL;
- void *pending_raw = NULL;
- int *pending_int = NULL;
- int i = 0;
+ afr_local_t *local = NULL;
+ afr_self_heal_t *sh = NULL;
+ afr_private_t *priv = NULL;
+ int i = 0;
+ int enoent_count = 0;
+ int call_count = 0;
+
+ local = frame->local;
+ sh = &local->self_heal;
priv = this->private;
- idx = afr_index_for_transaction_type (type);
- if (dict_get_ptr (xdata, AFR_DIRTY, &pending_raw) == 0) {
- if (pending_raw) {
- pending_int = pending_raw;
+ for (i = 0; i < priv->child_count; i++)
+ if (sh->child_errno[i] == ENOENT)
+ enoent_count++;
- if (ntoh32 (pending_int[idx]))
- return _gf_true;
- }
- }
+ call_count = enoent_count;
+ local->call_count = call_count;
- for (i = 0; i < priv->child_count; i++) {
- if (dict_get_ptr (xdata, priv->pending_key[i],
- &pending_raw))
- continue;
- if (!pending_raw)
- continue;
- pending_int = pending_raw;
+ gf_log (this->name, GF_LOG_TRACE,
+ "symlink %s -> %s on %d subvolumes",
+ local->loc.path, link, enoent_count);
- if (ntoh32 (pending_int[idx]))
- return _gf_true;
+ 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);
+ if (!--call_count)
+ break;
+ }
}
- return _gf_false;
+ return 0;
}
-gf_boolean_t
-afr_is_data_set (xlator_t *this, dict_t *xdata)
+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 stat *sbuf)
{
- return afr_is_pending_set (this, xdata, AFR_DATA_TRANSACTION);
-}
+ if (op_ret > 0)
+ sh_missing_entries_symlink (frame, this, link);
+ else
+ sh_missing_entries_finish (frame, this);
-gf_boolean_t
-afr_is_metadata_set (xlator_t *this, dict_t *xdata)
-{
- return afr_is_pending_set (this, xdata, AFR_METADATA_TRANSACTION);
+ return 0;
}
-gf_boolean_t
-afr_is_entry_set (xlator_t *this, dict_t *xdata)
+
+static int
+sh_missing_entries_readlink (call_frame_t *frame, xlator_t *this)
{
- return afr_is_pending_set (this, xdata, AFR_ENTRY_TRANSACTION);
-}
+ afr_local_t *local = NULL;
+ afr_self_heal_t *sh = NULL;
+ afr_private_t *priv = NULL;
-inode_t*
-afr_inode_link (inode_t *inode, struct iatt *iatt)
-{
- inode_t *linked_inode = NULL;
+ local = frame->local;
+ sh = &local->self_heal;
+ priv = this->private;
- linked_inode = inode_link (inode, NULL, NULL, iatt);
+ STACK_WIND (frame, sh_missing_entries_readlink_cbk,
+ priv->children[sh->source],
+ priv->children[sh->source]->fops->readlink,
+ &local->loc, 4096);
- if (linked_inode)
- inode_lookup (linked_inode);
- return linked_inode;
+ return 0;
}
-/*
- * This function inspects the looked up replies (in an unlocked manner)
- * and decides whether a locked verification and possible healing is
- * required or not. It updates the three booleans for each type
- * of healing. If the boolean flag gets set to FALSE, then we are sure
- * no healing is required. If the boolean flag gets set to TRUE then
- * we have to proceed with locked reinspection.
- */
-
-int
-afr_selfheal_unlocked_inspect (call_frame_t *frame, xlator_t *this,
- uuid_t gfid, inode_t **link_inode,
- gf_boolean_t *data_selfheal,
- gf_boolean_t *metadata_selfheal,
- gf_boolean_t *entry_selfheal)
+static int
+sh_missing_entries_create (call_frame_t *frame, xlator_t *this)
{
- afr_private_t *priv = NULL;
- inode_t *inode = NULL;
- int i = 0;
- int valid_cnt = 0;
- struct iatt first = {0, };
- struct afr_reply *replies = NULL;
- int ret = -1;
+ afr_local_t *local = NULL;
+ afr_self_heal_t *sh = NULL;
+ int type = 0;
+ int i = 0;
+ afr_private_t *priv = NULL;
+ int enoent_count = 0;
+ int govinda_gOvinda = 0;
+
+ local = frame->local;
+ sh = &local->self_heal;
priv = this->private;
- inode = afr_inode_find (this, gfid);
- if (!inode)
- goto out;
+ for (i = 0; i < priv->child_count; i++) {
+ if (sh->child_errno[i]) {
+ if (sh->child_errno[i] == ENOENT)
+ enoent_count++;
+ } else {
+ if (type) {
+ if (type != (sh->buf[i].st_mode & S_IFMT)) {
+ gf_log (this->name, GF_LOG_TRACE,
+ "file %s is govinda!",
+ local->loc.path);
+
+ govinda_gOvinda = 1;
+ }
+ } else {
+ sh->source = i;
+ type = sh->buf[i].st_mode & S_IFMT;
+ }
+ }
+ }
- replies = alloca0 (sizeof (*replies) * priv->child_count);
+ if (govinda_gOvinda) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "conflicing filetypes exist for path %s. returning.",
+ local->loc.path);
- ret = afr_selfheal_unlocked_discover (frame, inode, gfid, replies);
- if (ret)
- goto out;
+ local->govinda_gOvinda = 1;
+ sh_missing_entries_finish (frame, this);
+ return 0;
+ }
- for (i = 0; i < priv->child_count; i++) {
- if (!replies[i].valid)
- continue;
- if (replies[i].op_ret == -1)
- continue;
+ 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;
+ }
+
+ if (enoent_count == 0) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "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;
+ }
- if (data_selfheal && afr_is_data_set (this, replies[i].xdata))
- *data_selfheal = _gf_true;
+ switch (type) {
+ case S_IFSOCK:
+ case S_IFREG:
+ case S_IFBLK:
+ case S_IFCHR:
+ case S_IFIFO:
+ sh_missing_entries_mknod (frame, this);
+ break;
+ case S_IFLNK:
+ sh_missing_entries_readlink (frame, this);
+ break;
+ case S_IFDIR:
+ sh_missing_entries_mkdir (frame, this);
+ break;
+ default:
+ gf_log (this->name, GF_LOG_ERROR,
+ "unknown file type: 0%o", type);
+ local->govinda_gOvinda = 1;
+ sh_missing_entries_finish (frame, this);
+ }
- if (metadata_selfheal &&
- afr_is_metadata_set (this, replies[i].xdata))
- *metadata_selfheal = _gf_true;
+ return 0;
+}
- if (entry_selfheal && afr_is_entry_set (this, replies[i].xdata))
- *entry_selfheal = _gf_true;
- valid_cnt ++;
- if (valid_cnt == 1) {
- first = replies[i].poststat;
- continue;
- }
+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 stat *buf, dict_t *xattr,
+ struct stat *postparent)
+{
+ int child_index = 0;
+ afr_local_t *local = NULL;
+ int call_count = 0;
+ afr_self_heal_t *sh = NULL;
+ afr_private_t *priv = NULL;
- if (!IA_EQUAL (first, replies[i].poststat, type)) {
- gf_msg (this->name, GF_LOG_ERROR, 0,
- AFR_MSG_SPLIT_BRAIN,
- "TYPE mismatch %d vs %d on %s for gfid:%s",
- (int) first.ia_type,
- (int) replies[i].poststat.ia_type,
- priv->children[i]->name,
- uuid_utoa (replies[i].poststat.ia_gfid));
- ret = -EIO;
- goto out;
- }
- if (!IA_EQUAL (first, replies[i].poststat, uid)) {
- gf_log (this->name, GF_LOG_DEBUG,
- "UID mismatch %d vs %d on %s for gfid:%s",
- (int) first.ia_uid,
- (int) replies[i].poststat.ia_uid,
- priv->children[i]->name,
- uuid_utoa (replies[i].poststat.ia_gfid));
-
- if (metadata_selfheal)
- *metadata_selfheal = _gf_true;
- }
+ local = frame->local;
+ sh = &local->self_heal;
+ priv = this->private;
- if (!IA_EQUAL (first, replies[i].poststat, gid)) {
- gf_log (this->name, GF_LOG_DEBUG,
- "GID mismatch %d vs %d on %s for gfid:%s",
- (int) first.ia_uid,
- (int) replies[i].poststat.ia_uid,
- priv->children[i]->name,
- uuid_utoa (replies[i].poststat.ia_gfid));
-
- if (metadata_selfheal)
- *metadata_selfheal = _gf_true;
- }
+ child_index = (long) cookie;
- if (!IA_EQUAL (first, replies[i].poststat, prot)) {
- gf_log (this->name, GF_LOG_DEBUG,
- "MODE mismatch %d vs %d on %s for gfid:%s",
- (int) st_mode_from_ia (first.ia_prot, 0),
- (int) st_mode_from_ia (replies[i].poststat.ia_prot, 0),
- priv->children[i]->name,
- uuid_utoa (replies[i].poststat.ia_gfid));
-
- if (metadata_selfheal)
- *metadata_selfheal = _gf_true;
- }
+ 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->st_mode);
- if (IA_ISREG(first.ia_type) &&
- !IA_EQUAL (first, replies[i].poststat, size)) {
- gf_log (this->name, GF_LOG_DEBUG,
- "SIZE mismatch %lld vs %lld on %s for gfid:%s",
- (long long) first.ia_size,
- (long long) replies[i].poststat.ia_size,
- priv->children[i]->name,
- uuid_utoa (replies[i].poststat.ia_gfid));
-
- if (data_selfheal)
- *data_selfheal = _gf_true;
+ local->self_heal.buf[child_index] = *buf;
+ local->self_heal.parentbuf = *postparent;
+ } else {
+ gf_log (this->name, GF_LOG_TRACE,
+ "path %s on subvolume %s => -1 (%s)",
+ local->loc.path,
+ priv->children[child_index]->name,
+ strerror (op_errno));
+
+ local->self_heal.child_errno[child_index] = op_errno;
}
+
}
+ UNLOCK (&frame->lock);
- if (valid_cnt > 0 && link_inode) {
- *link_inode = afr_inode_link (inode, &first);
- if (!*link_inode) {
- ret = -EINVAL;
- goto out;
- }
- } else if (valid_cnt < 2) {
- ret = -ENOTCONN;
- goto out;
- }
+ call_count = afr_frame_return (frame);
- ret = 0;
-out:
- if (inode)
- inode_unref (inode);
- if (replies)
- afr_replies_wipe (replies, priv->child_count);
+ if (call_count == 0) {
+ sh_missing_entries_create (frame, this);
+ }
- return ret;
+ return 0;
}
-inode_t *
-afr_inode_find (xlator_t *this, uuid_t gfid)
+static int
+sh_missing_entries_lookup (call_frame_t *frame, xlator_t *this)
{
- inode_table_t *table = NULL;
- inode_t *inode = NULL;
-
- table = this->itable;
- if (!table)
- return NULL;
-
- inode = inode_find (table, gfid);
- if (inode)
- return inode;
+ afr_local_t *local = NULL;
+ int i = 0;
+ int call_count = 0;
+ afr_private_t *priv = NULL;
+ dict_t *xattr_req = NULL;
+ int ret = -1;
- inode = inode_new (table);
- if (!inode)
- return NULL;
+ 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));
+ }
+ }
- uuid_copy (inode->gfid, gfid);
+ for (i = 0; i < priv->child_count; i++) {
+ if (local->child_up[i]) {
+ gf_log (this->name, GF_LOG_TRACE,
+ "looking up %s on subvolume %s",
+ local->loc.path, priv->children[i]->name);
+
+ STACK_WIND_COOKIE (frame,
+ sh_missing_entries_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 inode;
+ return 0;
}
-call_frame_t *
-afr_frame_create (xlator_t *this)
+static int
+sh_missing_entries_lk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno)
{
- call_frame_t *frame = NULL;
- afr_local_t *local = NULL;
- int op_errno = 0;
- pid_t pid = GF_CLIENT_PID_AFR_SELF_HEALD;
-
- frame = create_frame (this, this->ctx->pool);
- if (!frame)
- return NULL;
-
- local = AFR_FRAME_INIT (frame, op_errno);
- if (!local) {
- STACK_DESTROY (frame->root);
- return NULL;
+ afr_local_t *local = NULL;
+ afr_self_heal_t *sh = NULL;
+ int call_count = 0;
+ int child_index = (long) cookie;
+
+
+ local = frame->local;
+ sh = &local->self_heal;
+
+ LOCK (&frame->lock);
+ {
+ if (op_ret == -1) {
+ sh->op_failed = 1;
+
+ sh->locked_nodes[child_index] = 0;
+ gf_log (this->name, GF_LOG_DEBUG,
+ "locking inode of %s on child %d failed: %s",
+ local->loc.path, child_index,
+ strerror (op_errno));
+ } else {
+ sh->locked_nodes[child_index] = 1;
+ gf_log (this->name, GF_LOG_TRACE,
+ "inode of %s on child %d locked",
+ local->loc.path, child_index);
+ }
}
+ UNLOCK (&frame->lock);
- syncopctx_setfspid (&pid);
+ call_count = afr_frame_return (frame);
- frame->root->pid = pid;
+ if (call_count == 0) {
+ if (sh->op_failed == 1) {
+ sh_missing_entries_finish (frame, this);
+ return 0;
+ }
- afr_set_lk_owner (frame, this, frame->root);
+ sh_missing_entries_lookup (frame, this);
+ }
- return frame;
+ return 0;
}
-int
-afr_selfheal_newentry_mark (call_frame_t *frame, xlator_t *this, inode_t *inode,
- int source, struct afr_reply *replies,
- unsigned char *sources, unsigned char *newentry)
+
+static int
+afr_self_heal_missing_entries (call_frame_t *frame, xlator_t *this)
{
- int ret = 0;
- int i = 0;
- afr_private_t *priv = NULL;
- dict_t *xattr = NULL;
- int **changelog = NULL;
+ afr_local_t *local = NULL;
+ afr_self_heal_t *sh = NULL;
+ afr_private_t *priv = NULL;
+ int i = 0;
+ int call_count = 0;
+
+ local = frame->local;
+ sh = &local->self_heal;
priv = this->private;
- uuid_copy (inode->gfid, replies[source].poststat.ia_gfid);
+ gf_log (this->name, GF_LOG_TRACE,
+ "attempting to recreate missing entries for path=%s",
+ local->loc.path);
- xattr = dict_new();
- if (!xattr)
- return -ENOMEM;
+ afr_build_parent_loc (&sh->parent_loc, &local->loc);
- changelog = afr_mark_pending_changelog (priv, newentry, xattr,
- replies[source].poststat.ia_type);
+ call_count = afr_up_children_count (priv->child_count,
+ local->child_up);
- if (!changelog)
- goto out;
+ local->call_count = call_count;
for (i = 0; i < priv->child_count; i++) {
- if (!sources[i])
- continue;
- afr_selfheal_post_op (frame, this, inode, i, xattr);
- }
-out:
- if (changelog)
- afr_matrix_cleanup (changelog, priv->child_count);
- if (xattr)
- dict_unref (xattr);
- return ret;
+ if (local->child_up[i]) {
+ STACK_WIND_COOKIE (frame, sh_missing_entries_lk_cbk,
+ (void *) (long) i,
+ priv->children[i],
+ priv->children[i]->fops->entrylk,
+ this->name,
+ &sh->parent_loc, local->loc.name,
+ ENTRYLK_LOCK_NB, ENTRYLK_WRLCK);
+ if (!--call_count)
+ break;
+ }
+ }
+
+ return 0;
}
-int
-afr_selfheal_do (call_frame_t *frame, xlator_t *this, uuid_t gfid)
+
+afr_local_t *afr_local_copy (afr_local_t *l, xlator_t *this)
{
- int ret = -1;
- int entry_ret = 1;
- int metadata_ret = 1;
- int data_ret = 1;
- int or_ret = 0;
- inode_t *inode = NULL;
- gf_boolean_t data_selfheal = _gf_false;
- gf_boolean_t metadata_selfheal = _gf_false;
- gf_boolean_t entry_selfheal = _gf_false;
- afr_private_t *priv = NULL;
- gf_boolean_t dataheal_enabled = _gf_false;
+ afr_private_t *priv = NULL;
+ afr_local_t *lc = NULL;
+ afr_self_heal_t *sh = NULL;
+ afr_self_heal_t *shc = NULL;
+
priv = this->private;
- gf_string2boolean (priv->data_self_heal, &dataheal_enabled);
- ret = afr_selfheal_unlocked_inspect (frame, this, gfid, &inode,
- &data_selfheal,
- &metadata_selfheal,
- &entry_selfheal);
- if (ret)
- goto out;
+ sh = &l->self_heal;
- if (!(data_selfheal || metadata_selfheal || entry_selfheal)) {
- ret = 2;
- goto out;
- }
+ lc = CALLOC (1, sizeof (afr_local_t));
+ shc = &lc->self_heal;
- if (data_selfheal && dataheal_enabled)
- data_ret = afr_selfheal_data (frame, this, inode);
+ shc->unwind = sh->unwind;
+ 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->mode = sh->mode;
- if (metadata_selfheal && priv->metadata_self_heal)
- metadata_ret = afr_selfheal_metadata (frame, this, inode);
+ if (l->loc.path)
+ loc_copy (&lc->loc, &l->loc);
- if (entry_selfheal && priv->entry_self_heal)
- entry_ret = afr_selfheal_entry (frame, this, inode);
+ lc->child_up = memdup (l->child_up, priv->child_count);
+ if (l->xattr_req)
+ lc->xattr_req = dict_ref (l->xattr_req);
- or_ret = (data_ret | metadata_ret | entry_ret);
+ if (l->cont.lookup.inode)
+ lc->cont.lookup.inode = inode_ref (l->cont.lookup.inode);
+ if (l->cont.lookup.xattr)
+ lc->cont.lookup.xattr = dict_ref (l->cont.lookup.xattr);
- if (data_ret == -EIO || metadata_ret == -EIO || entry_ret == -EIO)
- ret = -EIO;
- else if (data_ret == 1 && metadata_ret == 1 && entry_ret == 1)
- ret = 1;
- else if (or_ret < 0)
- ret = or_ret;
- else
- ret = 0;
+ return lc;
+}
-out:
- if (inode) {
- inode_forget (inode, 1);
- inode_unref (inode);
+
+int
+afr_self_heal_completion_cbk (call_frame_t *bgsh_frame, xlator_t *this)
+{
+ afr_private_t * priv = NULL;
+ afr_local_t * local = NULL;
+ afr_self_heal_t * sh = NULL;
+
+ priv = this->private;
+ local = bgsh_frame->local;
+ sh = &local->self_heal;
+
+ if (local->govinda_gOvinda) {
+ afr_set_split_brain (this, local->cont.lookup.inode, _gf_true);
+ } else {
+ afr_set_split_brain (this, local->cont.lookup.inode, _gf_false);
+ }
+
+ gf_log (this->name, GF_LOG_TRACE,
+ "background self-heal completed");
+
+ if (!sh->unwound) {
+ sh->unwind (sh->orig_frame, this);
}
- return ret;
+
+ if (sh->background) {
+ LOCK (&priv->lock);
+ {
+ priv->background_self_heals_started--;
+ }
+ UNLOCK (&priv->lock);
+ }
+
+ AFR_STACK_DESTROY (bgsh_frame);
+
+ return 0;
}
-/*
- * This is the entry point for healing a given GFID. The return values for this
- * function are as follows:
- * '0' if the self-heal is successful
- * '1' if the afr-xattrs are non-zero (due to on-going IO) and no heal is needed
- * '2' if the afr-xattrs are all-zero and no heal is needed
- * $errno if the heal on the gfid failed.
- */
+
int
-afr_selfheal (xlator_t *this, uuid_t gfid)
+afr_self_heal (call_frame_t *frame, xlator_t *this)
{
- int ret = -1;
- call_frame_t *frame = NULL;
+ afr_local_t *local = NULL;
+ afr_self_heal_t *sh = NULL;
+ afr_private_t *priv = NULL;
+ int i = 0;
+
+ call_frame_t *sh_frame = NULL;
+ afr_local_t *sh_local = NULL;
+
+ local = frame->local;
+ priv = this->private;
- frame = afr_frame_create (this);
- if (!frame)
- return ret;
+ afr_set_lk_owner (frame, this);
- ret = afr_selfheal_do (frame, this, gfid);
+ 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);
+ }
- if (frame)
- AFR_STACK_DESTROY (frame);
+ gf_log (this->name, GF_LOG_TRACE,
+ "performing self heal on %s (metadata=%d data=%d entry=%d)",
+ local->loc.path,
+ local->self_heal.need_metadata_self_heal,
+ local->self_heal.need_data_self_heal,
+ local->self_heal.need_entry_self_heal);
- return ret;
+ sh_frame = copy_frame (frame);
+ sh_local = afr_local_copy (local, this);
+ sh_frame->local = sh_local;
+ sh = &sh_local->self_heal;
+
+ sh->orig_frame = frame;
+
+ sh->completion_cbk = afr_self_heal_completion_cbk;
+
+
+ sh->buf = CALLOC (priv->child_count, sizeof (struct stat));
+ sh->child_errno = CALLOC (priv->child_count, sizeof (int));
+ sh->success = CALLOC (priv->child_count, sizeof (int));
+ sh->xattr = CALLOC (priv->child_count, sizeof (dict_t *));
+ sh->sources = CALLOC (priv->child_count, sizeof (*sh->sources));
+ sh->locked_nodes = CALLOC (priv->child_count, sizeof (*sh->locked_nodes));
+
+ sh->pending_matrix = CALLOC (sizeof (int32_t *), priv->child_count);
+ for (i = 0; i < priv->child_count; i++) {
+ sh->pending_matrix[i] = CALLOC (sizeof (int32_t),
+ priv->child_count);
+ }
+
+ sh->delta_matrix = CALLOC (sizeof (int32_t *), priv->child_count);
+ for (i = 0; i < priv->child_count; i++) {
+ sh->delta_matrix[i] = CALLOC (sizeof (int32_t),
+ priv->child_count);
+ }
+
+ if (local->success_count && local->enoent_count) {
+ afr_self_heal_missing_entries (sh_frame, this);
+ } else {
+ gf_log (this->name, GF_LOG_TRACE,
+ "proceeding to metadata check on %s",
+ local->loc.path);
+
+ afr_sh_missing_entries_done (sh_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
new file mode 100644
index 00000000000..be556a3c77e
--- /dev/null
+++ b/xlators/cluster/afr/src/afr-self-heal-common.h
@@ -0,0 +1,70 @@
+/*
+ Copyright (c) 2008-2009 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 __AFR_SELF_HEAL_COMMON_H__
+#define __AFR_SELF_HEAL_COMMON_H__
+
+#define FILE_HAS_HOLES(buf) (((buf)->st_size) > ((buf)->st_blocks * 512))
+
+typedef enum {
+ AFR_SELF_HEAL_ENTRY,
+ AFR_SELF_HEAL_METADATA,
+ AFR_SELF_HEAL_DATA,
+} afr_self_heal_type;
+
+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);
+
+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[], int success[],
+ int child_count, afr_transaction_type type);
+
+int
+afr_sh_mark_sources (afr_self_heal_t *sh, int child_count,
+ afr_self_heal_type type);
+
+int
+afr_sh_delta_to_xattr (afr_private_t *priv,
+ int32_t *delta_matrix[], dict_t *xattr[],
+ int child_count, afr_transaction_type type);
+
+int
+afr_sh_is_matrix_zero (int32_t *pending_matrix[], int child_count);
+
+
+#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 28abe2b87a0..225dd07b881 100644
--- a/xlators/cluster/afr/src/afr-self-heal-data.c
+++ b/xlators/cluster/afr/src/afr-self-heal-data.c
@@ -1,830 +1,1215 @@
/*
- Copyright (c) 2013 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-2009 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 <libgen.h>
+#include <unistd.h>
+#include <fnmatch.h>
+#include <sys/time.h>
+#include <stdlib.h>
+#include <signal.h>
#ifndef _CONFIG_H
#define _CONFIG_H
#include "config.h"
#endif
+#include "glusterfs.h"
#include "afr.h"
-#include "afr-self-heal.h"
+#include "dict.h"
+#include "xlator.h"
+#include "hashfn.h"
+#include "logging.h"
+#include "stack.h"
+#include "list.h"
+#include "call-stub.h"
+#include "defaults.h"
+#include "common-utils.h"
+#include "compat-errno.h"
+#include "compat.h"
#include "byte-order.h"
-enum {
- AFR_SELFHEAL_DATA_FULL = 0,
- AFR_SELFHEAL_DATA_DIFF,
-};
+#include "afr-transaction.h"
+#include "afr-self-heal.h"
+#include "afr-self-heal-common.h"
+#include "afr-self-heal-algorithm.h"
-#define HAS_HOLES(i) ((i->ia_blocks * 512) < (i->ia_size))
-static int
-__checksum_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int op_ret, int op_errno, uint32_t weak, uint8_t *strong,
- dict_t *xdata)
+int
+afr_sh_data_done (call_frame_t *frame, xlator_t *this)
{
- afr_local_t *local = NULL;
- int i = (long) cookie;
+ 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;
+
+ /*
+ 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);
- local->replies[i].valid = 1;
- local->replies[i].op_ret = op_ret;
- local->replies[i].op_errno = op_errno;
- if (strong)
- memcpy (local->replies[i].checksum, strong, MD5_DIGEST_LENGTH);
+ sh->completion_cbk (frame, this);
- syncbarrier_wake (&local->barrier);
return 0;
}
-static int
-attr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int op_ret, int op_errno, struct iatt *pre, struct iatt *post,
- dict_t *xdata)
+int
+afr_sh_data_flush_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno)
{
- int i = (long) cookie;
- afr_local_t *local = NULL;
+ afr_local_t *local = NULL;
+ afr_private_t *priv = NULL;
+ afr_self_heal_t *sh = NULL;
+ int call_count = 0;
+
+ int child_index = (long) cookie;
local = frame->local;
+ sh = &local->self_heal;
+ priv = this->private;
- local->replies[i].valid = 1;
- local->replies[i].op_ret = op_ret;
- local->replies[i].op_errno = op_errno;
- if (pre)
- local->replies[i].prestat = *pre;
- if (post)
- local->replies[i].poststat = *post;
- if (xdata)
- local->replies[i].xdata = dict_ref (xdata);
+ LOCK (&frame->lock);
+ {
+ if (op_ret == -1) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "flush or 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);
- syncbarrier_wake (&local->barrier);
+ if (call_count == 0) {
+ afr_sh_data_done (frame, this);
+ }
return 0;
}
-static gf_boolean_t
-__afr_selfheal_data_checksums_match (call_frame_t *frame, xlator_t *this,
- fd_t *fd, int source,
- unsigned char *healed_sinks,
- off_t offset, size_t size)
+int
+afr_sh_data_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct stat *statpre, struct stat *statpost)
{
- afr_private_t *priv = NULL;
- afr_local_t *local = NULL;
- unsigned char *wind_subvols = NULL;
- int i = 0;
+ afr_sh_data_flush_cbk (frame, cookie, this, op_ret, op_errno);
- priv = this->private;
- local = frame->local;
+ return 0;
+}
- wind_subvols = alloca0 (priv->child_count);
- for (i = 0; i < priv->child_count; i++) {
- if (i == source || healed_sinks[i])
- wind_subvols[i] = 1;
+
+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;
+ int source = 0;
+ int active_sinks = 0;
+ int32_t valid = 0;
+
+ struct stat stbuf = {0,};
+
+ local = frame->local;
+ sh = &local->self_heal;
+ priv = this->private;
+
+ source = sh->source;
+ active_sinks = sh->active_sinks;
+
+ valid |= (GF_SET_ATTR_ATIME | GF_SET_ATTR_MTIME);
+
+#ifdef HAVE_STRUCT_STAT_ST_ATIM_TV_NSEC
+ stbuf.st_atim = sh->buf[source].st_atim;
+ stbuf.st_mtim = sh->buf[source].st_mtim;
+
+#elif HAVE_STRUCT_STAT_ST_ATIMESPEC_TV_NSEC
+ stbuf.st_atimespec = sh->buf[source].st_atimespec;
+ stbuf.st_mtimespec = sh->buf[source].st_mtimespec;
+#else
+ stbuf.st_atime = sh->buf[source].st_atime;
+ stbuf.st_mtime = sh->buf[source].st_mtime;
+#endif
+
+ if (sh->healing_fd_opened) {
+ /* not our job to close the fd */
+
+ afr_sh_data_done (frame, this);
+ return 0;
+ }
+
+ if (!sh->healing_fd) {
+ afr_sh_data_done (frame, this);
+ return 0;
}
- AFR_ONLIST (wind_subvols, frame, __checksum_cbk, rchecksum, fd,
- offset, size, NULL);
+ call_count = (sh->active_sinks + 1) * 2;
+ local->call_count = call_count;
- if (!local->replies[source].valid || local->replies[source].op_ret != 0)
- return _gf_false;
+ /* 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 (i == source)
+ if (sh->sources[i] || !local->child_up[i])
continue;
- if (memcmp (local->replies[source].checksum,
- local->replies[i].checksum,
- MD5_DIGEST_LENGTH))
- return _gf_false;
+
+ 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);
+
+ if (!--call_count)
+ break;
}
- return _gf_true;
+ return 0;
}
-static gf_boolean_t
-__afr_is_sink_zero_filled (xlator_t *this, fd_t *fd, size_t size,
- off_t offset, int sink)
+int
+afr_sh_data_unlck_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno)
{
- afr_private_t *priv = NULL;
- struct iobref *iobref = NULL;
- struct iovec *iovec = NULL;
- int count = 0;
- int ret = 0;
- gf_boolean_t zero_filled = _gf_false;
-
- priv = this->private;
- ret = syncop_readv (priv->children[sink], fd, size, offset, 0, &iovec,
- &count, &iobref);
- if (ret < 0)
- goto out;
- ret = iov_0filled (iovec, count);
- if (!ret)
- zero_filled = _gf_true;
-out:
- if (iovec)
- GF_FREE (iovec);
- if (iobref)
- iobref_unref (iobref);
- return zero_filled;
+ afr_local_t * local = NULL;
+ int call_count = 0;
+ int child_index = (long) cookie;
+
+
+ local = frame->local;
+
+ LOCK (&frame->lock);
+ {
+ if (op_ret == -1) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "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);
+
+ call_count = afr_frame_return (frame);
+
+ if (call_count == 0) {
+ afr_sh_data_close (frame, this);
+ }
+
+ return 0;
}
-static int
-__afr_selfheal_data_read_write (call_frame_t *frame, xlator_t *this, fd_t *fd,
- int source, unsigned char *healed_sinks,
- off_t offset, size_t size,
- struct afr_reply *replies, int type)
+
+int
+afr_sh_data_unlock (call_frame_t *frame, xlator_t *this)
{
- struct iovec *iovec = NULL;
- int count = 0;
- struct iobref *iobref = NULL;
- int ret = 0;
- int i = 0;
- afr_private_t *priv = NULL;
+ struct flock flock;
+ int i = 0;
+ int call_count = 0;
+ 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;
- ret = syncop_readv (priv->children[source], fd, size, offset, 0,
- &iovec, &count, &iobref);
- if (ret <= 0)
- return ret;
+ if (sh->data_lock_held) {
+ /* not our job to unlock, proceed to close */
- for (i = 0; i < priv->child_count; i++) {
- if (!healed_sinks[i])
- continue;
+ afr_sh_data_close (frame, this);
+ return 0;
+ }
- /*
- * TODO: Use fiemap() and discard() to heal holes
- * in the future.
- *
- * For now,
- *
- * - if the source had any holes at all,
- * AND
- * - if we are writing past the original file size
- * of the sink
- * AND
- * - is NOT the last block of the source file. if
- * the block contains EOF, it has to be written
- * in order to set the file size even if the
- * last block is 0-filled.
- * AND
- * - if the read buffer is filled with only 0's
- *
- * then, skip writing to this source. We don't depend
- * on the write to happen to update the size as we
- * have performed an ftruncate() upfront anyways.
- */
-#define is_last_block(o,b,s) ((s >= o) && (s <= (o + b)))
- if (HAS_HOLES ((&replies[source].poststat)) &&
- offset >= replies[i].poststat.ia_size &&
- !is_last_block (offset, size,
- replies[source].poststat.ia_size) &&
- (iov_0filled (iovec, count) == 0))
- continue;
+ for (i = 0; i < priv->child_count; i++) {
+ if (sh->locked_nodes[i])
+ call_count++;
+ }
- /* Avoid filling up sparse regions of the sink with 0-filled
- * writes.*/
- if (type == AFR_SELFHEAL_DATA_FULL &&
- HAS_HOLES ((&replies[source].poststat)) &&
- ((offset + size) <= replies[i].poststat.ia_size) &&
- (iov_0filled (iovec, count) == 0) &&
- __afr_is_sink_zero_filled (this, fd, size, offset, i)) {
- continue;
- }
+ if (call_count == 0) {
+ afr_sh_data_close (frame, this);
+ return 0;
+ }
- ret = syncop_writev (priv->children[i], fd, iovec, count,
- offset, iobref, 0);
- if (ret != iov_length (iovec, count)) {
- /* write() failed on this sink. unset the corresponding
- member in sinks[] (which is healed_sinks[] in the
- caller) so that this server does NOT get considered
- as successfully healed.
- */
- healed_sinks[i] = 0;
+ local->call_count = call_count;
+
+ flock.l_start = 0;
+ flock.l_len = 0;
+ flock.l_type = F_UNLCK;
+
+ for (i = 0; i < priv->child_count; i++) {
+ if (sh->locked_nodes[i]) {
+ gf_log (this->name, GF_LOG_TRACE,
+ "unlocking %s on subvolume %s",
+ local->loc.path, priv->children[i]->name);
+
+ STACK_WIND_COOKIE (frame, afr_sh_data_unlck_cbk,
+ (void *) (long) i,
+ priv->children[i],
+ priv->children[i]->fops->inodelk,
+ this->name,
+ &local->loc, F_SETLK, &flock);
+ if (!--call_count)
+ break;
}
}
- if (iovec)
- GF_FREE (iovec);
- if (iobref)
- iobref_unref (iobref);
- return ret;
+ return 0;
}
-static int
-afr_selfheal_data_block (call_frame_t *frame, xlator_t *this, fd_t *fd,
- int source, unsigned char *healed_sinks, off_t offset,
- size_t size, int type, struct afr_reply *replies)
+int
+afr_sh_data_finish (call_frame_t *frame, xlator_t *this)
{
- int ret = -1;
- int sink_count = 0;
- afr_private_t *priv = NULL;
- unsigned char *data_lock = NULL;
+ afr_local_t *local = NULL;
+
+ local = frame->local;
+
+ gf_log (this->name, GF_LOG_TRACE,
+ "finishing data selfheal of %s", local->loc.path);
+ afr_sh_data_unlock (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)
+{
+ afr_local_t *local = NULL;
+ afr_self_heal_t *sh = NULL;
+ afr_private_t *priv = NULL;
+ int call_count = 0;
+
+ local = frame->local;
+ sh = &local->self_heal;
priv = this->private;
- sink_count = AFR_COUNT (healed_sinks, priv->child_count);
- data_lock = alloca0 (priv->child_count);
- ret = afr_selfheal_inodelk (frame, this, fd->inode, this->name,
- offset, size, data_lock);
+ LOCK (&frame->lock);
{
- if (ret < sink_count) {
- ret = -ENOTCONN;
- goto unlock;
- }
+ }
+ UNLOCK (&frame->lock);
- if (type == AFR_SELFHEAL_DATA_DIFF &&
- __afr_selfheal_data_checksums_match (frame, this, fd, source,
- healed_sinks, offset, size)) {
- ret = 0;
- goto unlock;
+ call_count = afr_frame_return (frame);
+
+ if (call_count == 0)
+ afr_sh_data_finish (frame, this);
+
+ return 0;
+}
+
+
+int
+afr_sh_data_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;
+
+
+ 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_DATA_TRANSACTION);
+
+ erase_xattr = CALLOC (sizeof (*erase_xattr), priv->child_count);
+
+ 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]);
}
+ }
- ret = __afr_selfheal_data_read_write (frame, this, fd, source,
- healed_sinks, offset, size,
- replies, type);
+ 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;
+
+ 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_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;
}
-unlock:
- afr_selfheal_uninodelk (frame, this, fd->inode, this->name,
- offset, size, data_lock);
- return ret;
-}
+ for (i = 0; i < priv->child_count; i++) {
+ if (erase_xattr[i]) {
+ dict_unref (erase_xattr[i]);
+ }
+ }
+ FREE (erase_xattr);
+ return 0;
+}
-static int
-afr_selfheal_data_fsync (call_frame_t *frame, xlator_t *this, fd_t *fd,
- unsigned char *healed_sinks)
+
+int
+afr_sh_data_trim_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct stat *prebuf,
+ struct stat *postbuf)
{
- afr_local_t *local = NULL;
- afr_private_t *priv = NULL;
- int i = 0;
+ afr_private_t * priv = NULL;
+ afr_local_t * local = NULL;
+ afr_self_heal_t *sh = NULL;
+ int call_count = 0;
+ int child_index = 0;
- local = frame->local;
priv = this->private;
+ local = frame->local;
+ sh = &local->self_heal;
- AFR_ONLIST (healed_sinks, frame, attr_cbk, fsync, fd, 0, NULL);
+ child_index = (long) cookie;
+
+ LOCK (&frame->lock);
+ {
+ if (op_ret == -1)
+ gf_log (this->name, GF_LOG_DEBUG,
+ "ftruncate of %s on subvolume %s failed (%s)",
+ local->loc.path,
+ priv->children[child_index]->name,
+ strerror (op_errno));
+ 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) {
+ afr_sh_data_erase_pending (frame, this);
+ }
- for (i = 0; i < priv->child_count; i++)
- if (healed_sinks[i] && local->replies[i].op_ret != 0)
- /* fsync() failed. Do NOT consider this server
- as successfully healed. Mark it so.
- */
- healed_sinks[i] = 0;
return 0;
}
-static int
-afr_selfheal_data_restore_time (call_frame_t *frame, xlator_t *this,
- inode_t *inode, int source,
- unsigned char *healed_sinks,
- struct afr_reply *replies)
+int
+afr_sh_data_trim_sinks (call_frame_t *frame, xlator_t *this)
{
- loc_t loc = {0, };
+ afr_private_t * priv = NULL;
+ afr_local_t * local = NULL;
+ afr_self_heal_t *sh = NULL;
+ int *sources = NULL;
+ int call_count = 0;
+ int i = 0;
+
+
+ priv = this->private;
+ local = frame->local;
+ sh = &local->self_heal;
- loc.inode = inode_ref (inode);
- uuid_copy (loc.gfid, inode->gfid);
+ sources = sh->sources;
+ call_count = sh->active_sinks;
- AFR_ONLIST (healed_sinks, frame, attr_cbk, setattr, &loc,
- &replies[source].poststat,
- (GF_SET_ATTR_ATIME|GF_SET_ATTR_MTIME), NULL);
+ local->call_count = call_count;
- loc_wipe (&loc);
+ for (i = 0; i < priv->child_count; i++) {
+ if (sources[i] || !local->child_up[i])
+ continue;
+
+ STACK_WIND_COOKIE (frame, afr_sh_data_trim_cbk,
+ (void *) (long) i,
+ priv->children[i],
+ priv->children[i]->fops->ftruncate,
+ sh->healing_fd, sh->file_size);
+
+ if (!--call_count)
+ break;
+ }
return 0;
}
-static int
-afr_data_self_heal_type_get (afr_private_t *priv, unsigned char *healed_sinks,
- int source, struct afr_reply *replies)
+
+static struct afr_sh_algorithm *
+sh_algo_from_name (xlator_t *this, char *name)
{
- int type = AFR_SELFHEAL_DATA_FULL;
int i = 0;
- if (priv->data_self_heal_algorithm == NULL) {
- type = AFR_SELFHEAL_DATA_FULL;
- for (i = 0; i < priv->child_count; i++) {
- if (!healed_sinks[i] && i != source)
- continue;
- if (replies[i].poststat.ia_size) {
- type = AFR_SELFHEAL_DATA_DIFF;
- break;
- }
+ while (afr_self_heal_algorithms[i].name) {
+ if (!strcmp (name, afr_self_heal_algorithms[i].name)) {
+ return &afr_self_heal_algorithms[i];
}
- } else if (strcmp (priv->data_self_heal_algorithm, "full") == 0) {
- type = AFR_SELFHEAL_DATA_FULL;
- } else if (strcmp (priv->data_self_heal_algorithm, "diff") == 0) {
- type = AFR_SELFHEAL_DATA_DIFF;
+
+ i++;
}
- return type;
+
+ return NULL;
}
+
static int
-afr_selfheal_data_do (call_frame_t *frame, xlator_t *this, fd_t *fd,
- int source, unsigned char *healed_sinks,
- struct afr_reply *replies)
+sh_zero_byte_files_exist (afr_self_heal_t *sh, int child_count)
{
- afr_private_t *priv = NULL;
- off_t off = 0;
- size_t block = 128 * 1024;
- int type = AFR_SELFHEAL_DATA_FULL;
- int ret = -1;
- call_frame_t *iter_frame = NULL;
+ int i;
+ int ret = 0;
- priv = this->private;
-
- type = afr_data_self_heal_type_get (priv, healed_sinks, source,
- replies);
-
- iter_frame = afr_copy_frame (frame);
- if (!iter_frame)
- return -ENOMEM;
-
- for (off = 0; off < replies[source].poststat.ia_size; off += block) {
- if (AFR_COUNT (healed_sinks, priv->child_count) == 0) {
- ret = -ENOTCONN;
- goto out;
+ for (i = 0; i < child_count; i++) {
+ if (sh->buf[i].st_size == 0) {
+ ret = 1;
+ break;
}
+ }
- ret = afr_selfheal_data_block (iter_frame, this, fd, source,
- healed_sinks, off, block, type,
- replies);
- if (ret < 0)
- goto out;
-
- AFR_STACK_RESET (iter_frame);
- }
+ return ret;
+}
- afr_selfheal_data_restore_time (frame, this, fd->inode, source,
- healed_sinks, replies);
- ret = afr_selfheal_data_fsync (frame, this, fd, healed_sinks);
+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 ((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");
+ }
+ }
-out:
- if (iter_frame)
- AFR_STACK_DESTROY (iter_frame);
- return ret;
+ return algo;
}
-static int
-__afr_selfheal_truncate_sinks (call_frame_t *frame, xlator_t *this,
- fd_t *fd, unsigned char *healed_sinks,
- struct afr_reply *replies, uint64_t size)
+int
+afr_sh_data_sync_prepare (call_frame_t *frame, xlator_t *this)
{
- afr_local_t *local = NULL;
- afr_private_t *priv = NULL;
- unsigned char *larger_sinks = 0;
- int i = 0;
+ 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;
- larger_sinks = alloca0 (priv->child_count);
+ source = sh->source;
+
for (i = 0; i < priv->child_count; i++) {
- if (healed_sinks[i] && replies[i].poststat.ia_size > size)
- larger_sinks[i] = 1;
+ 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_TRACE,
+ "no active sinks for performing self-heal on file %s",
+ local->loc.path);
+ afr_sh_data_finish (frame, this);
+ 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[source]->name, active_sinks);
+
+ sh->algo_completion_cbk = afr_sh_data_trim_sinks;
+ sh->algo_abort_cbk = afr_sh_data_finish;
- AFR_ONLIST (larger_sinks, frame, attr_cbk, ftruncate, fd, size, NULL);
+ sh_algo = afr_sh_data_pick_algo (frame, this);
+
+ sh_algo->fn (frame, this);
- for (i = 0; i < priv->child_count; i++)
- if (healed_sinks[i] && local->replies[i].op_ret == -1)
- /* truncate() failed. Do NOT consider this server
- as successfully healed. Mark it so.
- */
- healed_sinks[i] = 0;
return 0;
}
-gf_boolean_t
-afr_has_source_witnesses (xlator_t *this, unsigned char *sources,
- uint64_t *witness)
+
+int
+afr_sh_data_fix (call_frame_t *frame, xlator_t *this)
{
- int i = 0;
- afr_private_t *priv = NULL;
+ afr_local_t *local = NULL;
+ afr_local_t * orig_local = NULL;
- priv = this->private;
+ afr_self_heal_t *sh = NULL;
+ afr_private_t *priv = NULL;
+ int nsources = 0;
+ int source = 0;
+ int i = 0;
- for (i = 0; i < priv->child_count; i++) {
- if (sources[i] && witness[i])
- return _gf_true;
+ local = frame->local;
+ sh = &local->self_heal;
+ priv = this->private;
+
+ 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;
}
- return _gf_false;
-}
-static gf_boolean_t
-afr_does_size_mismatch (xlator_t *this, unsigned char *sources,
- struct afr_reply *replies)
-{
- int i = 0;
- afr_private_t *priv = NULL;
- struct iatt *min = NULL;
- struct iatt *max = NULL;
+ if ((nsources == -1)
+ && (priv->favorite_child != -1)
+ && (sh->child_errno[priv->favorite_child] == 0)) {
- priv = this->private;
+ gf_log (this->name, GF_LOG_DEBUG,
+ "Picking favorite child %s as authentic source to resolve conflicting data of %s",
+ priv->children[priv->favorite_child]->name,
+ local->loc.path);
- for (i = 0; i < priv->child_count; i++) {
- if (!replies[i].valid)
- continue;
+ sh->sources[priv->favorite_child] = 1;
+
+ nsources = afr_sh_source_count (sh->sources,
+ priv->child_count);
+ }
- if (replies[i].op_ret < 0)
- continue;
+ if (nsources == -1) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Unable to self-heal contents of '%s' (possible split-brain). "
+ "Please delete the file from all but the preferred "
+ "subvolume.", local->loc.path);
- if (!min)
- min = &replies[i].poststat;
+ local->govinda_gOvinda = 1;
- if (!max)
- max = &replies[i].poststat;
+ afr_sh_data_finish (frame, this);
+ return 0;
+ }
- if (min->ia_size > replies[i].poststat.ia_size)
- min = &replies[i].poststat;
+ source = afr_sh_select_source (sh->sources, priv->child_count);
+
+ if (source == -1) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "No active sources found.");
- if (max->ia_size < replies[i].poststat.ia_size)
- max = &replies[i].poststat;
+ afr_sh_data_finish (frame, this);
+ return 0;
}
- if (min && max) {
- if (min->ia_size != max->ia_size)
- return _gf_true;
+ sh->source = source;
+ sh->block_size = 65536;
+ sh->file_size = sh->buf[source].st_size;
+
+ if (FILE_HAS_HOLES (&sh->buf[source]))
+ sh->file_has_holes = 1;
+
+ orig_local = sh->orig_frame->local;
+ orig_local->cont.lookup.buf.st_size = sh->buf[source].st_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;
}
- return _gf_false;
+ afr_sh_data_sync_prepare (frame, this);
+
+ return 0;
}
-/*
- * If by chance there are multiple sources with differing sizes, select
- * the largest file as the source.
- *
- * This can happen if data was directly modified in the backend or for snapshots
- */
-
-static void
-afr_mark_largest_file_as_source (xlator_t *this, unsigned char *sources,
- struct afr_reply *replies)
+
+
+int
+afr_self_heal_get_source (xlator_t *this, afr_local_t *local, dict_t **xattr)
{
- int i = 0;
- afr_private_t *priv = NULL;
- uint64_t size = 0;
+ afr_self_heal_t *sh = NULL;
+ afr_private_t *priv = NULL;
- /* Find source with biggest file size */
- priv = this->private;
- for (i = 0; i < priv->child_count; i++) {
- if (!sources[i])
- continue;
- if (size <= replies[i].poststat.ia_size) {
- size = replies[i].poststat.ia_size;
- }
- }
+ int nsources = 0;
+ int source = 0;
+ int i = 0;
- /* Mark sources with less size as not source */
- for (i = 0; i < priv->child_count; i++) {
- if (!sources[i])
- continue;
- if (size > replies[i].poststat.ia_size)
- sources[i] = 0;
- }
+ sh = &local->self_heal;
+ priv = this->private;
+
+ sh->pending_matrix = CALLOC (sizeof (int32_t *), priv->child_count);
+ for (i = 0; i < priv->child_count; i++) {
+ sh->pending_matrix[i] = CALLOC (sizeof (int32_t),
+ priv->child_count);
+ }
+
+ sh->sources = CALLOC (priv->child_count, sizeof (*sh->sources));
+
+ afr_sh_build_pending_matrix (priv, sh->pending_matrix, xattr,
+ priv->child_count, AFR_DATA_TRANSACTION);
+
+ nsources = afr_sh_mark_sources (sh, priv->child_count,
+ AFR_SELF_HEAL_DATA);
- return;
+ source = afr_sh_select_source (sh->sources, priv->child_count);
+
+ return source;
}
-static void
-afr_mark_biggest_witness_as_source (xlator_t *this, unsigned char *sources,
- uint64_t *witness)
+
+int
+afr_sh_data_fstat_cbk (call_frame_t *frame, void *cookie,
+ xlator_t *this, int32_t op_ret, int32_t op_errno,
+ struct stat *buf)
{
- int i = 0;
- afr_private_t *priv = NULL;
- uint64_t biggest_witness = 0;
+ afr_private_t *priv = NULL;
+ afr_local_t *local = NULL;
+ afr_self_heal_t *sh = NULL;
- priv = this->private;
- /* Find source with biggest witness count */
- for (i = 0; i < priv->child_count; i++) {
- if (!sources[i])
- continue;
- if (biggest_witness < witness[i])
- biggest_witness = witness[i];
- }
+ int call_count = -1;
+ int child_index = (long) cookie;
- /* Mark files with less witness count as not source */
- for (i = 0; i < priv->child_count; i++) {
- if (!sources[i])
- continue;
- if (witness[i] < biggest_witness)
- sources[i] = 0;
- }
+ local = frame->local;
+ sh = &local->self_heal;
+ priv = this->private;
- return;
+ LOCK (&frame->lock);
+ {
+ if (op_ret != -1) {
+ gf_log (this->name, GF_LOG_TRACE,
+ "fstat of %s on %s succeeded",
+ local->loc.path,
+ priv->children[child_index]->name);
+
+ sh->buf[child_index] = *buf;
+ }
+ }
+ UNLOCK (&frame->lock);
+
+ call_count = afr_frame_return (frame);
+
+ if (call_count == 0) {
+ afr_sh_data_fix (frame, this);
+ }
+
+ return 0;
}
-/* This is a tie breaker function. Only one source be assigned here */
-static void
-afr_mark_newest_file_as_source (xlator_t *this, unsigned char *sources,
- struct afr_reply *replies)
+
+int
+afr_sh_data_fstat (call_frame_t *frame, xlator_t *this)
{
- int i = 0;
- afr_private_t *priv = NULL;
- int source = -1;
- uint32_t max_ctime = 0;
+ afr_self_heal_t *sh = NULL;
+ afr_local_t *local = NULL;
+ afr_private_t *priv = NULL;
- priv = this->private;
- /* Find source with latest ctime */
- for (i = 0; i < priv->child_count; i++) {
- if (!sources[i])
- continue;
+ int call_count = 0;
+ int i = 0;
- if (max_ctime <= replies[i].poststat.ia_ctime) {
- source = i;
- max_ctime = replies[i].poststat.ia_ctime;
- }
- }
+ priv = this->private;
+ local = frame->local;
+ sh = &local->self_heal;
+
+ call_count = afr_up_children_count (priv->child_count,
+ local->child_up);
+
+ local->call_count = call_count;
+
+ for (i = 0; i < priv->child_count; i++) {
+ 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;
+ }
+ }
- /* Only mark one of the files as source to break ties */
- memset (sources, 0, sizeof (*sources) * priv->child_count);
- sources[source] = 1;
+ return 0;
}
-static int
-__afr_selfheal_data_finalize_source (xlator_t *this, unsigned char *sources,
- unsigned char *healed_sinks,
- unsigned char *locked_on,
- struct afr_reply *replies,
- uint64_t *witness)
+
+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)
{
- int i = 0;
- afr_private_t *priv = NULL;
- int source = -1;
- int sources_count = 0;
+ 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;
+ sh = &local->self_heal;
priv = this->private;
- sources_count = AFR_COUNT (sources, priv->child_count);
+ LOCK (&frame->lock);
+ {
+ if (op_ret != -1) {
+ gf_log (this->name, GF_LOG_TRACE,
+ "fxattrop of %s on %s succeeded",
+ local->loc.path,
+ priv->children[child_index]->name);
- if ((AFR_CMP (locked_on, healed_sinks, priv->child_count) == 0)
- || !sources_count) {
- /* split brain */
- return -EIO;
+ sh->xattr[child_index] = dict_ref (xattr);
+ }
}
+ UNLOCK (&frame->lock);
- /* If there are no witnesses/size-mismatches on sources we are done*/
- if (!afr_does_size_mismatch (this, sources, replies) &&
- !afr_has_source_witnesses (this, sources, witness))
- goto out;
+ call_count = afr_frame_return (frame);
- afr_mark_largest_file_as_source (this, sources, replies);
- afr_mark_biggest_witness_as_source (this, sources, witness);
- afr_mark_newest_file_as_source (this, sources, replies);
+ if (call_count == 0) {
+ afr_sh_data_fstat (frame, this);
+ }
-out:
- afr_mark_active_sinks (this, sources, locked_on, healed_sinks);
+ return 0;
+}
- for (i = 0; i < priv->child_count; i++) {
- if (sources[i]) {
- source = i;
- break;
+
+int
+afr_sh_data_fxattrop (call_frame_t *frame, xlator_t *this)
+{
+ afr_self_heal_t *sh = NULL;
+ afr_local_t *local = NULL;
+ afr_private_t *priv = NULL;
+ dict_t *xattr_req = NULL;
+
+ int32_t zero_pending[3] = {0, 0, 0};
+
+ int call_count = 0;
+ int i = 0;
+ int ret = 0;
+
+ priv = this->private;
+ local = frame->local;
+ sh = &local->self_heal;
+
+ 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_static_bin (xattr_req, priv->pending_key[i],
+ zero_pending, 3 * sizeof(int32_t));
}
}
- return source;
+
+ for (i = 0; i < priv->child_count; i++) {
+ if (local->child_up[i]) {
+ STACK_WIND_COOKIE (frame, afr_sh_data_fxattrop_cbk,
+ (void *) (long) i,
+ priv->children[i],
+ priv->children[i]->fops->fxattrop,
+ sh->healing_fd, GF_XATTROP_ADD_ARRAY,
+ xattr_req);
+
+ if (!--call_count)
+ break;
+ }
+ }
+
+ if (xattr_req)
+ dict_unref (xattr_req);
+
+ return 0;
}
-/*
- * __afr_selfheal_data_prepare:
- *
- * This function inspects the on-disk xattrs and determines which subvols
- * are sources and sinks.
- *
- * The return value is the index of the subvolume to be used as the source
- * for self-healing, or -1 if no healing is necessary/split brain.
- */
+
int
-__afr_selfheal_data_prepare (call_frame_t *frame, xlator_t *this,
- inode_t *inode, unsigned char *locked_on,
- unsigned char *sources, unsigned char *sinks,
- unsigned char *healed_sinks,
- struct afr_reply *replies)
+afr_sh_data_lock_rec (call_frame_t *frame, xlator_t *this, int child_index);
+
+int
+afr_sh_data_lock_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno)
{
- int ret = -1;
- int source = -1;
- afr_private_t *priv = NULL;
- uint64_t *witness = NULL;
+ afr_local_t *local = NULL;
+ afr_self_heal_t *sh = NULL;
+ int child_index = (long) cookie;
- priv = this->private;
+ /* TODO: what if lock fails? */
+
+ local = frame->local;
+ sh = &local->self_heal;
- ret = afr_selfheal_unlocked_discover (frame, inode, inode->gfid,
- replies);
-
- if (ret)
- return ret;
-
- witness = alloca0(priv->child_count * sizeof (*witness));
- ret = afr_selfheal_find_direction (frame, this, replies,
- AFR_DATA_TRANSACTION,
- locked_on, sources, sinks, witness);
- if (ret)
- return ret;
-
- /* Initialize the healed_sinks[] array optimistically to
- the intersection of to-be-healed (i.e sinks[]) and
- the list of servers which are up (i.e locked_on[]).
- As we encounter failures in the healing process, we
- will unmark the respective servers in the healed_sinks[]
- array.
- */
- AFR_INTERSECT (healed_sinks, sinks, locked_on, priv->child_count);
-
- source = __afr_selfheal_data_finalize_source (this, sources,
- healed_sinks, locked_on,
- replies, witness);
- if (source < 0)
- return -EIO;
+ LOCK (&frame->lock);
+ {
+ if (op_ret == -1) {
+ sh->locked_nodes[child_index] = 0;
+
+ gf_log (this->name, GF_LOG_DEBUG,
+ "locking of %s on child %d failed: %s",
+ local->loc.path, child_index,
+ strerror (op_errno));
+ } else {
+ sh->locked_nodes[child_index] = 1;
+ sh->lock_count++;
+
+ gf_log (this->name, GF_LOG_TRACE,
+ "inode of %s on child %d locked",
+ local->loc.path, child_index);
+ }
+ }
+ UNLOCK (&frame->lock);
- return source;
+ afr_sh_data_lock_rec (frame, this, child_index + 1);
+
+ return 0;
}
-static int
-__afr_selfheal_data (call_frame_t *frame, xlator_t *this, fd_t *fd,
- unsigned char *locked_on)
+int
+afr_sh_data_lock_rec (call_frame_t *frame, xlator_t *this, int child_index)
{
- afr_private_t *priv = NULL;
- int ret = -1;
- unsigned char *sources = NULL;
- unsigned char *sinks = NULL;
- unsigned char *data_lock = NULL;
- unsigned char *healed_sinks = NULL;
- struct afr_reply *locked_replies = NULL;
- int source = -1;
- gf_boolean_t compat = _gf_false;
- gf_boolean_t did_sh = _gf_true;
- unsigned char *compat_lock = NULL;
+ struct flock flock;
+ int i = 0;
+
+ 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;
- sources = alloca0 (priv->child_count);
- sinks = alloca0 (priv->child_count);
- healed_sinks = alloca0 (priv->child_count);
- data_lock = alloca0 (priv->child_count);
- compat_lock = alloca0 (priv->child_count);
+ flock.l_start = 0;
+ flock.l_len = 0;
+ flock.l_type = F_WRLCK;
- locked_replies = alloca0 (sizeof (*locked_replies) * priv->child_count);
+ /* skip over children that are down */
+ while ((child_index < priv->child_count)
+ && !local->child_up[child_index])
+ child_index++;
- ret = afr_selfheal_inodelk (frame, this, fd->inode, this->name, 0, 0,
- data_lock);
- {
- if (ret < AFR_SH_MIN_PARTICIPANTS) {
- gf_log (this->name, GF_LOG_DEBUG, "%s: Skipping "
- "self-heal as only %d number of subvolumes "
- "could be locked", uuid_utoa (fd->inode->gfid),
- ret);
- ret = -ENOTCONN;
- goto unlock;
- }
+ if ((child_index == priv->child_count) &&
+ sh->lock_count == 0) {
- ret = __afr_selfheal_data_prepare (frame, this, fd->inode,
- data_lock, sources, sinks,
- healed_sinks,
- locked_replies);
- if (ret < 0)
- goto unlock;
+ gf_log (this->name, GF_LOG_DEBUG,
+ "unable to lock on even one child");
- if (AFR_COUNT(healed_sinks, priv->child_count) == 0) {
- did_sh = _gf_false;
- goto unlock;
- }
+ afr_sh_data_done (frame, this);
+ return 0;
+ }
+
+ if ((child_index == priv->child_count)
+ || (sh->lock_count == afr_lock_server_count (priv, AFR_DATA_TRANSACTION))) {
+ afr_sh_data_fxattrop (frame, this);
+ return 0;
+ }
- source = ret;
-
- ret = __afr_selfheal_truncate_sinks (frame, this, fd, healed_sinks,
- locked_replies,
- locked_replies[source].poststat.ia_size);
- if (ret < 0)
- goto unlock;
-
- ret = 0;
-
- /* Locking from (LLONG_MAX - 2) to (LLONG_MAX - 1) is for
- compatibility with older self-heal clients which do not
- hold a lock in the @priv->sh_domain domain to guard
- against concurrent ongoing self-heals
- */
- afr_selfheal_inodelk (frame, this, fd->inode, this->name,
- LLONG_MAX - 2, 1, compat_lock);
- compat = _gf_true;
- }
-unlock:
- afr_selfheal_uninodelk (frame, this, fd->inode, this->name, 0, 0,
- data_lock);
- if (ret < 0)
- goto out;
-
- if (!did_sh)
- goto out;
-
- ret = afr_selfheal_data_do (frame, this, fd, source, healed_sinks,
- locked_replies);
- if (ret)
- goto out;
-
- ret = afr_selfheal_undo_pending (frame, this, fd->inode, sources, sinks,
- healed_sinks, AFR_DATA_TRANSACTION,
- locked_replies, data_lock);
-out:
- if (compat)
- afr_selfheal_uninodelk (frame, this, fd->inode, this->name,
- LLONG_MAX - 2, 1, compat_lock);
-
- if (did_sh)
- afr_log_selfheal (fd->inode->gfid, this, ret, "data", source,
- healed_sinks);
- else
- ret = 1;
-
- if (locked_replies)
- afr_replies_wipe (locked_replies, priv->child_count);
-
- return ret;
+ gf_log (this->name, GF_LOG_TRACE,
+ "locking %s on subvolume %s",
+ local->loc.path, priv->children[i]->name);
+
+ STACK_WIND_COOKIE (frame, afr_sh_data_lock_cbk,
+ (void *) (long) child_index,
+ priv->children[i],
+ priv->children[i]->fops->inodelk,
+ this->name,
+ &local->loc, F_SETLKW, &flock);
+
+ return 0;
}
-static fd_t *
-afr_selfheal_data_open (xlator_t *this, inode_t *inode)
+int
+afr_sh_data_lock (call_frame_t *frame, xlator_t *this)
{
- loc_t loc = {0,};
- int ret = 0;
- fd_t *fd = NULL;
+ afr_local_t * local = NULL;
+ afr_private_t * priv = NULL;
+ afr_self_heal_t * sh = NULL;
- fd = fd_create (inode, 0);
- if (!fd)
- return NULL;
+ int i = 0;
- loc.inode = inode_ref (inode);
- uuid_copy (loc.gfid, inode->gfid);
+ local = frame->local;
+ sh = &local->self_heal;
+ priv = this->private;
- ret = syncop_open (this, &loc, O_RDWR|O_LARGEFILE, fd);
- if (ret) {
- fd_unref (fd);
- fd = NULL;
- } else {
- fd_bind (fd);
+ if (sh->data_lock_held) {
+ /* caller has held the lock already,
+ so skip locking */
+
+ afr_sh_data_fxattrop (frame, this);
+ return 0;
+ }
+
+ for (i = 0; i < priv->child_count; i++)
+ sh->locked_nodes[i] = 0;
+
+ return afr_sh_data_lock_rec (frame, this, 0);
+}
+
+
+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)
+{
+ 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;
+
+ /* TODO: some of the open's might fail.
+ In that case, modify cleanup fn to send flush on those
+ fd's which are already open */
+
+ LOCK (&frame->lock);
+ {
+ if (op_ret == -1) {
+ gf_log (this->name, GF_LOG_TRACE,
+ "open of %s failed on child %s (%s)",
+ local->loc.path,
+ priv->children[child_index]->name,
+ strerror (op_errno));
+ sh->op_failed = 1;
+ }
+
+ 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);
+
+ call_count = afr_frame_return (frame);
+
+ if (call_count == 0) {
+ if (sh->op_failed) {
+ afr_sh_data_finish (frame, this);
+ return 0;
+ }
+
+ gf_log (this->name, GF_LOG_TRACE,
+ "fd for %s opened, commencing sync",
+ local->loc.path);
- loc_wipe (&loc);
+ afr_sh_data_lock (frame, this);
+ }
- return fd;
+ return 0;
}
+
int
-afr_selfheal_data (call_frame_t *frame, xlator_t *this, inode_t *inode)
+afr_sh_data_open (call_frame_t *frame, xlator_t *this)
{
- afr_private_t *priv = NULL;
- unsigned char *locked_on = NULL;
- int ret = 0;
+ int i = 0;
+ int call_count = 0;
+
fd_t *fd = NULL;
+ 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;
- fd = afr_selfheal_data_open (this, inode);
- if (!fd) {
- gf_log (this->name, GF_LOG_DEBUG, "%s: Failed to open",
- uuid_utoa (inode->gfid));
- return -EIO;
+ if (sh->healing_fd_opened) {
+ /* caller has opened the fd for us already, so skip open */
+
+ afr_sh_data_lock (frame, this);
+ return 0;
}
- locked_on = alloca0 (priv->child_count);
+ call_count = afr_up_children_count (priv->child_count, local->child_up);
+ local->call_count = call_count;
- ret = afr_selfheal_tryinodelk (frame, this, inode, priv->sh_domain, 0, 0,
- locked_on);
- {
- if (ret < AFR_SH_MIN_PARTICIPANTS) {
- gf_log (this->name, GF_LOG_DEBUG, "%s: Skipping "
- "self-heal as only %d number of subvolumes "
- "could be locked", uuid_utoa (fd->inode->gfid),
- ret);
- /* Either less than two subvols available, or another
- selfheal (from another server) is in progress. Skip
- for now in any case there isn't anything to do.
- */
- ret = -ENOTCONN;
- goto unlock;
- }
+ fd = fd_create (local->loc.inode, frame->root->pid);
+ sh->healing_fd = fd;
+
+ /* open sinks */
+ for (i = 0; i < priv->child_count; i++) {
+ if(!local->child_up[i])
+ continue;
+
+ STACK_WIND_COOKIE (frame, afr_sh_data_open_cbk,
+ (void *) (long) i,
+ priv->children[i],
+ priv->children[i]->fops->open,
+ &local->loc,
+ O_RDWR|O_LARGEFILE, fd, 0);
- ret = __afr_selfheal_data (frame, this, fd, locked_on);
+ if (!--call_count)
+ break;
}
-unlock:
- afr_selfheal_uninodelk (frame, this, inode, priv->sh_domain, 0, 0, locked_on);
- if (fd)
- fd_unref (fd);
+ return 0;
+}
+
- return ret;
+int
+afr_self_heal_data (call_frame_t *frame, xlator_t *this)
+{
+ afr_local_t *local = NULL;
+ afr_self_heal_t *sh = NULL;
+ afr_private_t *priv = this->private;
+
+
+ local = frame->local;
+ sh = &local->self_heal;
+
+ 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",
+ local->loc.path);
+ afr_sh_data_done (frame, this);
+ }
+
+ return 0;
}
+
diff --git a/xlators/cluster/afr/src/afr-self-heal-entry.c b/xlators/cluster/afr/src/afr-self-heal-entry.c
index 7f5095e2ada..73535dddd2a 100644
--- a/xlators/cluster/afr/src/afr-self-heal-entry.c
+++ b/xlators/cluster/afr/src/afr-self-heal-entry.c
@@ -1,765 +1,2557 @@
/*
- Copyright (c) 2013 Red Hat, Inc. <http://www.redhat.com>
+ Copyright (c) 2008-2009 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 General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that 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 <libgen.h>
+#include <unistd.h>
+#include <fnmatch.h>
+#include <sys/time.h>
+#include <stdlib.h>
+#include <signal.h>
#ifndef _CONFIG_H
#define _CONFIG_H
#include "config.h"
#endif
+#include "glusterfs.h"
+#include "inode.h"
#include "afr.h"
-#include "afr-self-heal.h"
+#include "dict.h"
+#include "xlator.h"
+#include "hashfn.h"
+#include "logging.h"
+#include "stack.h"
+#include "list.h"
+#include "call-stub.h"
+#include "defaults.h"
+#include "common-utils.h"
+#include "compat-errno.h"
+#include "compat.h"
#include "byte-order.h"
+
#include "afr-transaction.h"
+#include "afr-self-heal.h"
+#include "afr-self-heal-common.h"
-/* Max file name length is 255 this filename is of length 256. No file with
- * this name can ever come, entry-lock with this name is going to prevent
- * self-heals from older versions while the granular entry-self-heal is going
- * on in newer version.*/
-#define LONG_FILENAME "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"\
- "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"\
- "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"\
- "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"\
- "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-static int
-afr_selfheal_entry_delete (xlator_t *this, inode_t *dir, const char *name,
- inode_t *inode, int child, struct afr_reply *replies)
+
+int
+afr_sh_entry_done (call_frame_t *frame, xlator_t *this)
{
- afr_private_t *priv = NULL;
- xlator_t *subvol = NULL;
- int ret = 0;
- loc_t loc = {0, };
- char g[64];
+ 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;
- subvol = priv->children[child];
+ /*
+ TODO: cleanup sh->*
+ */
- loc.parent = inode_ref (dir);
- uuid_copy (loc.pargfid, dir->gfid);
- loc.name = name;
- loc.inode = inode_ref (inode);
+ if (sh->healing_fd)
+ fd_unref (sh->healing_fd);
+ sh->healing_fd = NULL;
- if (replies[child].valid && replies[child].op_ret == 0) {
- switch (replies[child].poststat.ia_type) {
- case IA_IFDIR:
- gf_log (this->name, GF_LOG_WARNING,
- "expunging dir %s/%s (%s) on %s",
- uuid_utoa (dir->gfid), name,
- uuid_utoa_r (replies[child].poststat.ia_gfid, g),
- subvol->name);
- ret = syncop_rmdir (subvol, &loc, 1);
- break;
- default:
- gf_log (this->name, GF_LOG_WARNING,
- "expunging file %s/%s (%s) on %s",
- uuid_utoa (dir->gfid), name,
- uuid_utoa_r (replies[child].poststat.ia_gfid, g),
- subvol->name);
- ret = syncop_unlink (subvol, &loc);
- break;
+ 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);
+
+ return 0;
+}
+
+
+int
+afr_sh_entry_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 call_count = 0;
+ int child_index = (long) cookie;
+
+ /* TODO: what if lock fails? */
+
+ local = frame->local;
+ sh = &local->self_heal;
+
+ LOCK (&frame->lock);
+ {
+ if (op_ret == -1) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "unlocking inode of %s on child %d failed: %s",
+ local->loc.path, child_index,
+ strerror (op_errno));
+ } else {
+ gf_log (this->name, GF_LOG_TRACE,
+ "unlocked inode of %s on child %d",
+ local->loc.path, child_index);
}
}
+ UNLOCK (&frame->lock);
- loc_wipe (&loc);
+ call_count = afr_frame_return (frame);
- return ret;
+ if (call_count == 0) {
+ afr_sh_entry_done (frame, this);
+ }
+
+ return 0;
}
int
-afr_selfheal_recreate_entry (xlator_t *this, int dst, int source, inode_t *dir,
- const char *name, inode_t *inode,
- struct afr_reply *replies,
- unsigned char *newentry)
+afr_sh_entry_unlock (call_frame_t *frame, xlator_t *this)
{
- int ret = 0;
- loc_t loc = {0,};
- loc_t srcloc = {0,};
- afr_private_t *priv = NULL;
- dict_t *xdata = NULL;
- struct iatt *iatt = NULL;
- char *linkname = NULL;
- mode_t mode = 0;
- struct iatt newent = {0,};
- priv = this->private;
-
- xdata = dict_new();
- if (!xdata)
- return -ENOMEM;
-
- loc.parent = inode_ref (dir);
- uuid_copy (loc.pargfid, dir->gfid);
- loc.name = name;
- loc.inode = inode_ref (inode);
-
- ret = afr_selfheal_entry_delete (this, dir, name, inode, dst, replies);
- if (ret)
- goto out;
+ int i = 0;
+ int call_count = 0;
- ret = dict_set_static_bin (xdata, "gfid-req",
- replies[source].poststat.ia_gfid, 16);
- if (ret)
- goto out;
+ afr_local_t * local = NULL;
+ afr_private_t * priv = NULL;
+ afr_self_heal_t * sh = NULL;
- iatt = &replies[source].poststat;
- srcloc.inode = inode_ref (inode);
- uuid_copy (srcloc.gfid, iatt->ia_gfid);
+ local = frame->local;
+ sh = &local->self_heal;
+ priv = this->private;
- mode = st_mode_from_ia (iatt->ia_prot, iatt->ia_type);
+ for (i = 0; i < priv->child_count; i++) {
+ if (sh->locked_nodes[i])
+ call_count++;
+ }
- switch (iatt->ia_type) {
- case IA_IFDIR:
- ret = syncop_mkdir (priv->children[dst], &loc, mode, xdata, 0);
- if (ret == 0)
- newentry[dst] = 1;
- break;
- case IA_IFLNK:
- ret = syncop_lookup (priv->children[dst], &srcloc, 0, 0, 0, 0);
- if (ret == 0) {
- ret = syncop_link (priv->children[dst], &srcloc, &loc);
- } else {
- ret = syncop_readlink (priv->children[source], &srcloc,
- &linkname, 4096);
- if (ret <= 0)
- goto out;
- ret = syncop_symlink (priv->children[dst], &loc, linkname,
- xdata, NULL);
- if (ret == 0)
- newentry[dst] = 1;
- }
- break;
- default:
- ret = dict_set_int32 (xdata, GLUSTERFS_INTERNAL_FOP_KEY, 1);
- if (ret)
- goto out;
- ret = syncop_mknod (priv->children[dst], &loc, mode,
- iatt->ia_rdev, xdata, &newent);
- if (ret == 0 && newent.ia_nlink == 1) {
- /* New entry created. Mark @dst pending on all sources */
- newentry[dst] = 1;
+ if (call_count == 0) {
+ afr_sh_entry_done (frame, this);
+ return 0;
+ }
+
+ local->call_count = call_count;
+
+ for (i = 0; i < priv->child_count; i++) {
+ if (sh->locked_nodes[i]) {
+ gf_log (this->name, GF_LOG_TRACE,
+ "unlocking %s on subvolume %s",
+ local->loc.path, priv->children[i]->name);
+
+ STACK_WIND_COOKIE (frame, afr_sh_entry_unlck_cbk,
+ (void *) (long) i,
+ priv->children[i],
+ priv->children[i]->fops->entrylk,
+ this->name,
+ &local->loc, NULL,
+ ENTRYLK_UNLOCK, ENTRYLK_WRLCK);
+ if (!--call_count)
+ break;
}
- break;
}
-out:
- if (xdata)
- dict_unref (xdata);
- loc_wipe (&loc);
- loc_wipe (&srcloc);
- return ret;
+ return 0;
}
-static int
-__afr_selfheal_heal_dirent (call_frame_t *frame, xlator_t *this, fd_t *fd,
- char *name, inode_t *inode, int source,
- unsigned char *sources, unsigned char *healed_sinks,
- unsigned char *locked_on, struct afr_reply *replies)
+int
+afr_sh_entry_finish (call_frame_t *frame, xlator_t *this)
{
- int ret = 0;
- afr_private_t *priv = NULL;
- int i = 0;
- unsigned char *newentry = NULL;
+ afr_local_t *local = NULL;
+
+ local = frame->local;
+ gf_log (this->name, GF_LOG_TRACE,
+ "finishing entry selfheal of %s", local->loc.path);
+
+ afr_sh_entry_unlock (frame, this);
+
+ return 0;
+}
+
+
+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)
+{
+ afr_local_t *local = NULL;
+ afr_self_heal_t *sh = NULL;
+ afr_private_t *priv = NULL;
+ int call_count = 0;
+
+ local = frame->local;
+ sh = &local->self_heal;
priv = this->private;
- newentry = alloca0 (priv->child_count);
+ LOCK (&frame->lock);
+ {
+ }
+ UNLOCK (&frame->lock);
+
+ call_count = afr_frame_return (frame);
+
+ if (call_count == 0)
+ afr_sh_entry_finish (frame, this);
+
+ return 0;
+}
+
- if (!replies[source].valid)
- return -EIO;
+int
+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;
- /* Skip healing this entry if the last lookup on it failed for reasons
- * other than ENOENT.
- */
- if ((replies[source].op_ret < 0) &&
- (replies[source].op_errno != ENOENT))
- return -replies[source].op_errno;
+ afr_sh_pending_to_delta (priv, sh->xattr, sh->delta_matrix, sh->success,
+ priv->child_count, AFR_ENTRY_TRANSACTION);
+
+ erase_xattr = CALLOC (sizeof (*erase_xattr), priv->child_count);
for (i = 0; i < priv->child_count; i++) {
- if (!healed_sinks[i])
+ if (sh->xattr[i]) {
+ call_count++;
+
+ erase_xattr[i] = get_new_dict();
+ dict_ref (erase_xattr[i]);
+ }
+ }
+
+ 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;
- if (replies[source].op_ret == -1 &&
- replies[source].op_errno == ENOENT) {
- ret = afr_selfheal_entry_delete (this, fd->inode, name,
- inode, i, replies);
- } else {
- if (!uuid_compare (replies[i].poststat.ia_gfid,
- replies[source].poststat.ia_gfid))
- continue;
- ret = afr_selfheal_recreate_entry (this, i, source,
- fd->inode, name, inode,
- replies, newentry);
- }
- if (ret < 0)
+ 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;
}
- if (AFR_COUNT (newentry, priv->child_count))
- afr_selfheal_newentry_mark (frame, this, inode, source, replies,
- sources, newentry);
- return ret;
+ for (i = 0; i < priv->child_count; i++) {
+ if (erase_xattr[i]) {
+ dict_unref (erase_xattr[i]);
+ }
+ }
+ FREE (erase_xattr);
+
+ if (need_unwind)
+ afr_sh_entry_finish (frame, this);
+
+ return 0;
}
+
+
static int
-afr_selfheal_detect_gfid_and_type_mismatch (xlator_t *this,
- struct afr_reply *replies,
- uuid_t pargfid, char *bname,
- int src_idx)
+next_active_source (call_frame_t *frame, xlator_t *this,
+ int current_active_source)
{
- int i = 0;
- char g1[64] = {0,};
- char g2[64] = {0,};
- afr_private_t *priv = NULL;
+ afr_private_t *priv = NULL;
+ afr_local_t *local = NULL;
+ afr_self_heal_t *sh = NULL;
+ int source = -1;
+ int next_active_source = -1;
+ int i = 0;
- priv = this->private;
+ priv = this->private;
+ local = frame->local;
+ sh = &local->self_heal;
- for (i = 0; i < priv->child_count; i++) {
- if (i == src_idx)
- continue;
-
- if (!replies[i].valid)
- continue;
-
- if (replies[i].op_ret != 0)
- continue;
-
- if (uuid_compare (replies[src_idx].poststat.ia_gfid,
- replies[i].poststat.ia_gfid)) {
- gf_log (this->name, GF_LOG_ERROR, "Gfid mismatch "
- "detected for <%s/%s>, %s on %s and %s on %s. "
- "Skipping conservative merge on the file.",
- uuid_utoa (pargfid), bname,
- uuid_utoa_r (replies[i].poststat.ia_gfid, g1),
- priv->children[i]->name,
- uuid_utoa_r (replies[src_idx].poststat.ia_gfid,
- g2), priv->children[src_idx]->name);
- return -1;
- }
+ source = sh->source;
- if ((replies[src_idx].poststat.ia_type) !=
- (replies[i].poststat.ia_type)) {
- gf_log (this->name, GF_LOG_ERROR, "Type mismatch "
- "detected for <%s/%s>, %d on %s and %d on %s. "
- "Skipping conservative merge on the file.",
- uuid_utoa (pargfid), bname,
- replies[i].poststat.ia_type,
- priv->children[i]->name,
- replies[src_idx].poststat.ia_type,
- priv->children[src_idx]->name);
- return -1;
- }
- }
+ if (source != -1) {
+ if (current_active_source != source)
+ next_active_source = source;
+ goto out;
+ }
- return 0;
+ /*
+ the next active sink becomes the source for the
+ 'conservative decision' of merging all entries
+ */
+
+ for (i = 0; i < priv->child_count; i++) {
+ if ((sh->sources[i] == 0)
+ && (local->child_up[i] == 1)
+ && (i > current_active_source)) {
+
+ next_active_source = i;
+ break;
+ }
+ }
+out:
+ return next_active_source;
}
+
+
static int
-__afr_selfheal_merge_dirent (call_frame_t *frame, xlator_t *this, fd_t *fd,
- char *name, inode_t *inode, unsigned char *sources,
- unsigned char *healed_sinks, unsigned char *locked_on,
- struct afr_reply *replies)
+next_active_sink (call_frame_t *frame, xlator_t *this,
+ int current_active_sink)
{
- int ret = 0;
- int i = 0;
- int source = -1;
- unsigned char *newentry = NULL;
- afr_private_t *priv = NULL;
+ afr_private_t *priv = NULL;
+ afr_local_t *local = NULL;
+ afr_self_heal_t *sh = NULL;
+ int next_active_sink = -1;
+ int i = 0;
priv = this->private;
+ local = frame->local;
+ sh = &local->self_heal;
- newentry = alloca0 (priv->child_count);
+ /*
+ the next active sink becomes the source for the
+ 'conservative decision' of merging all entries
+ */
for (i = 0; i < priv->child_count; i++) {
- if (replies[i].valid && replies[i].op_ret == 0) {
- source = i;
+ if ((sh->sources[i] == 0)
+ && (local->child_up[i] == 1)
+ && (i > current_active_sink)) {
+
+ next_active_sink = i;
break;
}
}
- if (source == -1) {
- /* entry got deleted in the mean time? */
- return 0;
+ 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;
}
- /* In case of a gfid or type mismatch on the entry, return -1.*/
- ret = afr_selfheal_detect_gfid_and_type_mismatch (this, replies,
- fd->inode->gfid,
- name, source);
+ if (strcmp (parent->path, "/") == 0)
+ ret = asprintf ((char **)&child->path, "/%s", name);
+ else
+ ret = asprintf ((char **)&child->path, "%s/%s", parent->path,
+ name);
- if (ret < 0)
- return ret;
+ if (-1 == ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "asprintf failed while setting child path");
+ }
- for (i = 0; i < priv->child_count; i++) {
- if (i == source || !healed_sinks[i])
- continue;
+ if (!child->path) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory.");
+ goto out;
+ }
- if (replies[i].op_errno != ENOENT)
- continue;
+ child->name = strrchr (child->path, '/');
+ if (child->name)
+ child->name++;
- ret = afr_selfheal_recreate_entry (this, i, source, fd->inode,
- name, inode, replies,
- newentry);
+ child->parent = inode_ref (parent->inode);
+ child->inode = inode_new (parent->inode->table);
+
+ if (!child->inode) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory.");
+ goto out;
}
- if (AFR_COUNT (newentry, priv->child_count))
- afr_selfheal_newentry_mark (frame, this, inode, source, replies,
- sources, newentry);
+ ret = 0;
+out:
+ if (ret == -1)
+ loc_wipe (child);
+
return ret;
}
-static int
-__afr_selfheal_entry_dirent (call_frame_t *frame, xlator_t *this, fd_t *fd,
- char *name, inode_t *inode, int source,
- unsigned char *sources, unsigned char *healed_sinks,
- unsigned char *locked_on,
- struct afr_reply *replies)
-{
- int ret = -1;
-
- if (source < 0)
- ret = __afr_selfheal_merge_dirent (frame, this, fd, name, inode,
- sources, healed_sinks,
- locked_on, replies);
- else
- ret = __afr_selfheal_heal_dirent (frame, this, fd, name, inode,
- source, sources, healed_sinks,
- locked_on, replies);
- return ret;
+int
+afr_sh_entry_expunge_all (call_frame_t *frame, xlator_t *this);
+
+int
+afr_sh_entry_expunge_subvol (call_frame_t *frame, xlator_t *this,
+ int active_src);
+
+int
+afr_sh_entry_expunge_entry_done (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;
+ int call_count = 0;
+
+ priv = this->private;
+ local = frame->local;
+ sh = &local->self_heal;
+
+ LOCK (&frame->lock);
+ {
+ }
+ UNLOCK (&frame->lock);
+
+ call_count = afr_frame_return (frame);
+
+ if (call_count == 0)
+ afr_sh_entry_expunge_subvol (frame, this, active_src);
+
+ return 0;
}
-static int
-__afr_selfheal_entry_finalize_source (xlator_t *this, unsigned char *sources,
- unsigned char *healed_sinks,
- unsigned char *locked_on,
- struct afr_reply *replies,
- uint64_t *witness)
+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 stat *preop, struct stat *postop)
{
- int i = 0;
- afr_private_t *priv = NULL;
- int source = -1;
- int sources_count = 0;
+ 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;
+
+ priv = this->private;
+ expunge_local = expunge_frame->local;
+ expunge_sh = &expunge_local->self_heal;
+ frame = expunge_sh->sh_frame;
+
+ if (op_ret != 0) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "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);
+ afr_sh_entry_expunge_entry_done (frame, this, active_src);
+
+ return 0;
+}
+
+
+int
+afr_sh_entry_expunge_rename_cbk (call_frame_t *expunge_frame, void *cookie,
+ xlator_t *this,
+ int32_t op_ret, int32_t op_errno,
+ struct stat *buf,
+ struct stat *preoldparent,
+ struct stat *postoldparent,
+ struct stat *prenewparent,
+ struct stat *postnewparent)
+{
+ 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;
+
+ if (op_ret == 0) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "removed %s on %s",
+ expunge_local->loc.path,
+ priv->children[active_src]->name);
+ } else {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "removing %s on %s failed (%s)",
+ expunge_local->loc.path,
+ priv->children[active_src]->name,
+ strerror (op_errno));
+ }
+
+ 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,
+ priv->children[active_src],
+ priv->children[active_src]->fops->setattr,
+ &expunge_sh->parent_loc,
+ &expunge_sh->parentbuf,
+ valid);
+
+ return 0;
+}
+
+
+static void
+init_trash_loc (loc_t *trash_loc, inode_table_t *table)
+{
+ trash_loc->path = strdup ("/" GF_REPLICATE_TRASH_DIR);
+ trash_loc->name = GF_REPLICATE_TRASH_DIR;
+ trash_loc->parent = table->root;
+ trash_loc->inode = inode_new (table);
+}
+
+
+char *
+make_trash_path (const char *path)
+{
+ char *c = NULL;
+ char *tp = NULL;
+
+ tp = CALLOC (strlen ("/" GF_REPLICATE_TRASH_DIR) + strlen (path) + 1, sizeof (char));
+
+ strcpy (tp, GF_REPLICATE_TRASH_DIR);
+ strcat (tp, path);
+
+ c = strchr (tp, '/') + 1;
+ while (*c++)
+ if (*c == '/')
+ *c = '-';
+
+ return tp;
+}
+
+
+int
+afr_sh_entry_expunge_rename (call_frame_t *expunge_frame, xlator_t *this,
+ int active_src, inode_t *trash_inode)
+{
+ afr_private_t *priv = NULL;
+ afr_local_t *expunge_local = NULL;
+
+ loc_t rename_loc;
+
+ priv = this->private;
+ expunge_local = expunge_frame->local;
+
+ rename_loc.inode = inode_ref (expunge_local->loc.inode);
+ rename_loc.path = make_trash_path (expunge_local->loc.path);
+ rename_loc.name = strrchr (rename_loc.path, '/') + 1;
+ rename_loc.parent = trash_inode;
+
+ gf_log (this->name, GF_LOG_TRACE,
+ "moving file/directory %s on %s to %s",
+ expunge_local->loc.path, priv->children[active_src]->name,
+ rename_loc.path);
+
+ STACK_WIND_COOKIE (expunge_frame, afr_sh_entry_expunge_rename_cbk,
+ (void *) (long) active_src,
+ priv->children[active_src],
+ priv->children[active_src]->fops->rename,
+ &expunge_local->loc, &rename_loc);
+
+ loc_wipe (&rename_loc);
+
+ return 0;
+}
+
+
+int
+afr_sh_entry_expunge_mkdir_cbk (call_frame_t *expunge_frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, inode_t *inode,
+ struct stat *buf, struct stat *preparent,
+ struct stat *postparent)
+{
+ 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;
+
+ inode_t *trash_inode = NULL;
+
+ priv = this->private;
+ expunge_local = expunge_frame->local;
+ expunge_sh = &expunge_local->self_heal;
+ frame = expunge_sh->sh_frame;
+
+ if (op_ret != 0) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "mkdir of /" GF_REPLICATE_TRASH_DIR " failed on %s",
+ priv->children[active_src]->name);
+
+ goto out;
+ }
+
+ /* mkdir successful */
+
+ trash_inode = inode_link (inode, expunge_local->loc.inode->table->root,
+ GF_REPLICATE_TRASH_DIR, buf);
+
+ afr_sh_entry_expunge_rename (expunge_frame, this, active_src,
+ trash_inode);
+ return 0;
+out:
+ AFR_STACK_DESTROY (expunge_frame);
+ afr_sh_entry_expunge_entry_done (frame, this, active_src);
+ return 0;
+}
+
+
+int
+afr_sh_entry_expunge_lookup_trash_cbk (call_frame_t *expunge_frame, void *cookie,
+ xlator_t *this,
+ int32_t op_ret, int32_t op_errno,
+ inode_t *inode, struct stat *buf,
+ dict_t *xattr, struct stat *postparent)
+{
+ 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;
+
+ inode_t *trash_inode;
+ loc_t trash_loc;
+
+ priv = this->private;
+ expunge_local = expunge_frame->local;
+ expunge_sh = &expunge_local->self_heal;
+ frame = expunge_sh->sh_frame;
+
+ if ((op_ret != 0) && (op_errno == ENOENT)) {
+ init_trash_loc (&trash_loc, expunge_local->loc.inode->table);
+
+ gf_log (this->name, GF_LOG_TRACE,
+ "creating directory " GF_REPLICATE_TRASH_DIR " on subvolume %s",
+ priv->children[active_src]->name);
+
+ STACK_WIND_COOKIE (expunge_frame, afr_sh_entry_expunge_mkdir_cbk,
+ (void *) (long) active_src,
+ priv->children[active_src],
+ priv->children[active_src]->fops->mkdir,
+ &trash_loc, 0777);
+
+ loc_wipe (&trash_loc);
+ return 0;
+ }
+
+ if (op_ret != 0) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "lookup of /" GF_REPLICATE_TRASH_DIR " failed on %s",
+ priv->children[active_src]->name);
+ goto out;
+ }
+
+ /* lookup successful */
+
+ trash_inode = inode_link (inode, expunge_local->loc.inode->table->root,
+ GF_REPLICATE_TRASH_DIR, buf);
+
+ afr_sh_entry_expunge_rename (expunge_frame, this, active_src,
+ trash_inode);
+ return 0;
+out:
+ AFR_STACK_DESTROY (expunge_frame);
+ afr_sh_entry_expunge_entry_done (frame, this, active_src);
+ return 0;
+}
+
- sources_count = AFR_COUNT (sources, priv->child_count);
+int
+afr_sh_entry_expunge_lookup_trash (call_frame_t *expunge_frame, xlator_t *this,
+ int active_src)
+{
+ afr_private_t *priv = NULL;
+ afr_local_t *expunge_local = NULL;
+
+ inode_t *root = NULL;
+ inode_t *trash = NULL;
+ loc_t trash_loc;
+
+ priv = this->private;
+ expunge_local = expunge_frame->local;
+
+ root = expunge_local->loc.inode->table->root;
+
+ trash = inode_grep (root->table, root, GF_REPLICATE_TRASH_DIR);
+
+ if (trash) {
+ /* inode is in cache, so no need to mkdir */
+
+ afr_sh_entry_expunge_rename (expunge_frame, this, active_src,
+ trash);
+ return 0;
+ }
+
+ /* Not in cache, so look it up */
+
+ init_trash_loc (&trash_loc, expunge_local->loc.inode->table);
+
+ gf_log (this->name, GF_LOG_TRACE,
+ "looking up /" GF_REPLICATE_TRASH_DIR " on %s",
+ priv->children[active_src]->name);
+
+ STACK_WIND_COOKIE (expunge_frame, afr_sh_entry_expunge_lookup_trash_cbk,
+ (void *) (long) active_src,
+ priv->children[active_src],
+ priv->children[active_src]->fops->lookup,
+ &trash_loc, NULL);
- if ((AFR_CMP (locked_on, healed_sinks, priv->child_count) == 0)
- || !sources_count || afr_does_witness_exist (this, witness)) {
+ loc_wipe (&trash_loc);
- memset (sources, 0, sizeof (*sources) * priv->child_count);
- afr_mark_active_sinks (this, sources, locked_on, healed_sinks);
- return -1;
+ return 0;
+}
+
+
+int
+afr_sh_entry_expunge_remove (call_frame_t *expunge_frame, xlator_t *this,
+ int active_src, struct stat *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;
+
+ priv = this->private;
+ expunge_local = expunge_frame->local;
+ expunge_sh = &expunge_local->self_heal;
+ frame = expunge_sh->sh_frame;
+ source = expunge_sh->source;
+
+ type = (buf->st_mode & S_IFMT);
+
+ switch (type) {
+ case S_IFSOCK:
+ case S_IFREG:
+ case S_IFBLK:
+ case S_IFCHR:
+ case S_IFIFO:
+ case S_IFLNK:
+ case S_IFDIR:
+ afr_sh_entry_expunge_lookup_trash (expunge_frame, this, active_src);
+ break;
+ default:
+ gf_log (this->name, GF_LOG_ERROR,
+ "%s has unknown file type on %s: 0%o",
+ expunge_local->loc.path,
+ priv->children[source]->name, type);
+ goto out;
+ break;
}
- for (i = 0; i < priv->child_count; i++) {
- if (sources[i]) {
- source = i;
- break;
- }
+ return 0;
+out:
+ AFR_STACK_DESTROY (expunge_frame);
+ afr_sh_entry_expunge_entry_done (frame, this, active_src);
+
+ return 0;
+}
+
+
+int
+afr_sh_entry_expunge_lookup_cbk (call_frame_t *expunge_frame, void *cookie,
+ xlator_t *this,
+ int32_t op_ret, int32_t op_errno,
+ inode_t *inode, struct stat *buf, dict_t *x,
+ struct stat *postparent)
+{
+ 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 = 0;
+
+ priv = this->private;
+ expunge_local = expunge_frame->local;
+ expunge_sh = &expunge_local->self_heal;
+ frame = expunge_sh->sh_frame;
+ active_src = (long) cookie;
+
+ if (op_ret == -1) {
+ gf_log (this->name, GF_LOG_TRACE,
+ "lookup of %s on %s failed (%s)",
+ expunge_local->loc.path,
+ priv->children[active_src]->name,
+ strerror (op_errno));
+ goto out;
}
- return source;
+ afr_sh_entry_expunge_remove (expunge_frame, this, active_src, buf);
+
+ return 0;
+out:
+ AFR_STACK_DESTROY (expunge_frame);
+ afr_sh_entry_expunge_entry_done (frame, this, active_src);
+
+ return 0;
}
+
int
-__afr_selfheal_entry_prepare (call_frame_t *frame, xlator_t *this,
- inode_t *inode, unsigned char *locked_on,
- unsigned char *sources, unsigned char *sinks,
- unsigned char *healed_sinks,
- struct afr_reply *replies, int *source_p)
+afr_sh_entry_expunge_purge (call_frame_t *expunge_frame, xlator_t *this,
+ int active_src)
{
- int ret = -1;
- int source = -1;
- afr_private_t *priv = NULL;
- uint64_t *witness = NULL;
+ afr_private_t *priv = NULL;
+ afr_local_t *expunge_local = NULL;
priv = this->private;
+ expunge_local = expunge_frame->local;
+
+ gf_log (this->name, GF_LOG_TRACE,
+ "looking up %s on %s",
+ expunge_local->loc.path, priv->children[active_src]->name);
+
+ STACK_WIND_COOKIE (expunge_frame, afr_sh_entry_expunge_lookup_cbk,
+ (void *) (long) active_src,
+ priv->children[active_src],
+ priv->children[active_src]->fops->lookup,
+ &expunge_local->loc, 0);
+
+ return 0;
+}
- ret = afr_selfheal_unlocked_discover (frame, inode, inode->gfid,
- replies);
- if (ret)
- return ret;
- witness = alloca0 (sizeof (*witness) * priv->child_count);
- ret = afr_selfheal_find_direction (frame, this, replies,
- AFR_ENTRY_TRANSACTION,
- locked_on, sources, sinks, witness);
- if (ret)
- return ret;
+int
+afr_sh_entry_expunge_entry_cbk (call_frame_t *expunge_frame, void *cookie,
+ xlator_t *this,
+ int32_t op_ret, int32_t op_errno,
+ inode_t *inode, struct stat *buf, dict_t *x,
+ struct stat *postparent)
+{
+ 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 active_src = 0;
- /* Initialize the healed_sinks[] array optimistically to
- the intersection of to-be-healed (i.e sinks[]) and
- the list of servers which are up (i.e locked_on[]).
- As we encounter failures in the healing process, we
- will unmark the respective servers in the healed_sinks[]
- array.
- */
- AFR_INTERSECT (healed_sinks, sinks, locked_on, priv->child_count);
+ priv = this->private;
+ expunge_local = expunge_frame->local;
+ expunge_sh = &expunge_local->self_heal;
+ frame = expunge_sh->sh_frame;
+ active_src = expunge_sh->active_source;
+ source = (long) cookie;
- source = __afr_selfheal_entry_finalize_source (this, sources,
- healed_sinks,
- locked_on, replies,
- witness);
+ if (op_ret == -1 && op_errno == ENOENT && postparent) {
- if (source < 0) {
- /* If source is < 0 (typically split-brain), we perform a
- conservative merge of entries rather than erroring out */
+ gf_log (this->name, GF_LOG_TRACE,
+ "missing entry %s on %s",
+ expunge_local->loc.path,
+ priv->children[source]->name);
+
+ expunge_sh->parentbuf = *postparent;
+
+ afr_sh_entry_expunge_purge (expunge_frame, this, active_src);
+
+ return 0;
}
- *source_p = source;
- return ret;
+ if (op_ret == 0) {
+ gf_log (this->name, GF_LOG_TRACE,
+ "%s exists under %s",
+ expunge_local->loc.path,
+ priv->children[source]->name);
+ } else {
+ gf_log (this->name, GF_LOG_TRACE,
+ "looking up %s under %s failed (%s)",
+ expunge_local->loc.path,
+ priv->children[source]->name,
+ strerror (op_errno));
+ }
+
+ AFR_STACK_DESTROY (expunge_frame);
+ afr_sh_entry_expunge_entry_done (frame, this, active_src);
+
+ return 0;
}
-static int
-afr_selfheal_entry_dirent (call_frame_t *frame, xlator_t *this,
- fd_t *fd, char *name)
+
+int
+afr_sh_entry_expunge_entry (call_frame_t *frame, xlator_t *this,
+ char *name)
{
- int ret = 0;
- int source = -1;
- unsigned char *locked_on = NULL;
- unsigned char *sources = NULL;
- unsigned char *sinks = NULL;
- unsigned char *healed_sinks = NULL;
- inode_t *inode = NULL;
- struct afr_reply *replies = NULL;
- struct afr_reply *par_replies = NULL;
- afr_private_t *priv = NULL;
+ afr_private_t *priv = NULL;
+ afr_local_t *local = NULL;
+ afr_self_heal_t *sh = NULL;
+ int ret = -1;
+ call_frame_t *expunge_frame = NULL;
+ afr_local_t *expunge_local = NULL;
+ afr_self_heal_t *expunge_sh = NULL;
+ int active_src = 0;
+ int source = 0;
+ int op_errno = 0;
priv = this->private;
+ local = frame->local;
+ sh = &local->self_heal;
- sources = alloca0 (priv->child_count);
- sinks = alloca0 (priv->child_count);
- healed_sinks = alloca0 (priv->child_count);
- locked_on = alloca0 (priv->child_count);
+ active_src = sh->active_source;
+ source = sh->source;
- replies = alloca0 (priv->child_count * sizeof(*replies));
- par_replies = alloca0 (priv->child_count * sizeof(*par_replies));
+ if ((strcmp (name, ".") == 0)
+ || (strcmp (name, "..") == 0)
+ || ((strcmp (local->loc.path, "/") == 0)
+ && (strcmp (name, GF_REPLICATE_TRASH_DIR) == 0))) {
- ret = afr_selfheal_entrylk (frame, this, fd->inode, this->name, NULL,
- locked_on);
- {
- if (ret < AFR_SH_MIN_PARTICIPANTS) {
- gf_log (this->name, GF_LOG_DEBUG, "%s: Skipping "
- "entry self-heal as only %d sub-volumes could "
- "be locked in %s domain",
- uuid_utoa (fd->inode->gfid), ret, this->name);
- ret = -ENOTCONN;
- goto unlock;
- }
+ gf_log (this->name, GF_LOG_TRACE,
+ "skipping inspection of %s under %s",
+ name, local->loc.path);
+ goto out;
+ }
+
+ gf_log (this->name, GF_LOG_TRACE,
+ "inspecting existance of %s under %s",
+ name, local->loc.path);
+
+ expunge_frame = copy_frame (frame);
+ if (!expunge_frame) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory.");
+ goto 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;
+
+ ret = build_child_loc (this, &expunge_local->loc, &local->loc, name);
+ if (ret != 0) {
+ goto out;
+ }
+
+ gf_log (this->name, GF_LOG_TRACE,
+ "looking up %s on %s", expunge_local->loc.path,
+ priv->children[source]->name);
+
+ STACK_WIND_COOKIE (expunge_frame,
+ afr_sh_entry_expunge_entry_cbk,
+ (void *) (long) source,
+ priv->children[source],
+ priv->children[source]->fops->lookup,
+ &expunge_local->loc, 0);
+
+ ret = 0;
+out:
+ if (ret == -1)
+ afr_sh_entry_expunge_entry_done (frame, this, active_src);
+
+ return 0;
+}
- ret = __afr_selfheal_entry_prepare (frame, this, fd->inode,
- locked_on,
- sources, sinks,
- healed_sinks, par_replies,
- &source);
- if (ret < 0)
- goto unlock;
-
- inode = afr_selfheal_unlocked_lookup_on (frame, fd->inode, name,
- replies, locked_on,
- NULL);
- if (!inode) {
- ret = -ENOMEM;
- goto unlock;
+
+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)
+{
+ afr_private_t *priv = NULL;
+ afr_local_t *local = NULL;
+ afr_self_heal_t *sh = NULL;
+ gf_dirent_t *entry = NULL;
+ off_t last_offset = 0;
+ int active_src = 0;
+ int entry_count = 0;
+
+ priv = this->private;
+ local = frame->local;
+ sh = &local->self_heal;
+
+ active_src = sh->active_source;
+
+ if (op_ret <= 0) {
+ if (op_ret < 0) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "readdir of %s on subvolume %s failed (%s)",
+ local->loc.path,
+ priv->children[active_src]->name,
+ strerror (op_errno));
+ } else {
+ gf_log (this->name, GF_LOG_TRACE,
+ "readdir of %s on subvolume %s complete",
+ local->loc.path,
+ priv->children[active_src]->name);
}
- ret = __afr_selfheal_entry_dirent (frame, this, fd, name, inode,
- source, sources, healed_sinks,
- locked_on, replies);
+ afr_sh_entry_expunge_all (frame, this);
+ return 0;
}
-unlock:
- afr_selfheal_unentrylk (frame, this, fd->inode, this->name, NULL,
- locked_on);
- if (inode)
- inode_unref (inode);
- if (replies)
- afr_replies_wipe (replies, priv->child_count);
- if (par_replies)
- afr_replies_wipe (par_replies, priv->child_count);
- return ret;
+ list_for_each_entry (entry, &entries->list, list) {
+ last_offset = entry->d_off;
+ entry_count++;
+ }
+
+ gf_log (this->name, GF_LOG_TRACE,
+ "readdir'ed %d entries from %s",
+ entry_count, priv->children[active_src]->name);
+
+ sh->offset = last_offset;
+ local->call_count = entry_count;
+
+ list_for_each_entry (entry, &entries->list, list) {
+ afr_sh_entry_expunge_entry (frame, this, entry->d_name);
+ }
+
+ return 0;
}
+int
+afr_sh_entry_expunge_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;
-static int
-afr_selfheal_entry_do_subvol (call_frame_t *frame, xlator_t *this,
- fd_t *fd, int child)
+ priv = this->private;
+ local = frame->local;
+ sh = &local->self_heal;
+
+ STACK_WIND (frame, afr_sh_entry_expunge_readdir_cbk,
+ priv->children[active_src],
+ priv->children[active_src]->fops->readdir,
+ sh->healing_fd, sh->block_size, sh->offset);
+
+ return 0;
+}
+
+
+int
+afr_sh_entry_expunge_all (call_frame_t *frame, xlator_t *this)
{
- int ret = 0;
- gf_dirent_t entries;
- gf_dirent_t *entry = NULL;
- off_t offset = 0;
- call_frame_t *iter_frame = NULL;
- xlator_t *subvol = NULL;
- afr_private_t *priv = NULL;
+ afr_private_t *priv = NULL;
+ afr_local_t *local = NULL;
+ afr_self_heal_t *sh = NULL;
+ int active_src = -1;
priv = this->private;
- subvol = priv->children[child];
+ local = frame->local;
+ sh = &local->self_heal;
+
+ sh->offset = 0;
- INIT_LIST_HEAD (&entries.list);
+ if (sh->source == -1) {
+ gf_log (this->name, GF_LOG_TRACE,
+ "no active sources for %s to expunge entries",
+ local->loc.path);
+ goto out;
+ }
- iter_frame = afr_copy_frame (frame);
- if (!iter_frame)
- return -ENOMEM;
+ active_src = next_active_sink (frame, this, sh->active_source);
+ sh->active_source = active_src;
- while ((ret = syncop_readdir (subvol, fd, 131072, offset, &entries))) {
- if (ret > 0)
- ret = 0;
- list_for_each_entry (entry, &entries.list, list) {
- offset = entry->d_off;
+ if (sh->op_failed) {
+ goto out;
+ }
- if (!strcmp (entry->d_name, ".") ||
- !strcmp (entry->d_name, ".."))
- continue;
+ if (active_src == -1) {
+ /* completed creating missing files on all subvolumes */
+ goto out;
+ }
- if (__is_root_gfid (fd->inode->gfid) &&
- !strcmp (entry->d_name, GF_REPLICATE_TRASH_DIR))
- continue;
+ gf_log (this->name, GF_LOG_TRACE,
+ "expunging entries of %s on %s to other sinks",
+ local->loc.path, priv->children[active_src]->name);
- ret = afr_selfheal_entry_dirent (iter_frame, this, fd,
- entry->d_name);
- AFR_STACK_RESET (iter_frame);
+ afr_sh_entry_expunge_subvol (frame, this, active_src);
- if (ret)
- break;
- }
+ return 0;
+out:
+ afr_sh_entry_erase_pending (frame, this);
+ return 0;
- gf_dirent_free (&entries);
- if (ret)
- break;
+}
+
+
+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,
+ int active_src);
+
+int
+afr_sh_entry_impunge_entry_done (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;
+ int call_count = 0;
+
+ priv = this->private;
+ local = frame->local;
+ sh = &local->self_heal;
+
+ LOCK (&frame->lock);
+ {
}
+ UNLOCK (&frame->lock);
- AFR_STACK_DESTROY (iter_frame);
- return ret;
+ call_count = afr_frame_return (frame);
+
+ if (call_count == 0)
+ afr_sh_entry_impunge_subvol (frame, this, active_src);
+
+ return 0;
}
-static int
-afr_selfheal_entry_do (call_frame_t *frame, xlator_t *this, fd_t *fd,
- int source, unsigned char *sources,
- unsigned char *healed_sinks)
+
+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 stat *preop, struct stat *postop)
{
- int i = 0;
- afr_private_t *priv = NULL;
- int ret = 0;
+ 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_TRACE,
+ "setattr done for %s on %s",
+ impunge_local->loc.path,
+ priv->children[child_index]->name);
+ } else {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "setattr (%s) on %s failed (%s)",
+ impunge_local->loc.path,
+ priv->children[child_index]->name,
+ strerror (op_errno));
+ }
- gf_log (this->name, GF_LOG_INFO, "performing entry selfheal on %s",
- uuid_utoa (fd->inode->gfid));
+ LOCK (&impunge_frame->lock);
+ {
+ call_count = --impunge_local->call_count;
+ }
+ UNLOCK (&impunge_frame->lock);
- for (i = 0; i < priv->child_count; i++) {
- if (i != source && !healed_sinks[i])
- continue;
- ret = afr_selfheal_entry_do_subvol (frame, this, fd, i);
- if (ret)
- break;
+ if (call_count == 0) {
+ AFR_STACK_DESTROY (impunge_frame);
+ afr_sh_entry_impunge_entry_done (frame, this, active_src);
}
- return ret;
+
+ 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)
+{
+ afr_private_t *priv = NULL;
+ afr_local_t *impunge_local = NULL;
+ afr_self_heal_t *impunge_sh = NULL;
+ call_frame_t *frame = NULL;
+ int child_index = 0;
+
+ struct stat stbuf;
+ int32_t valid = 0;
+
+ priv = this->private;
+ impunge_local = impunge_frame->local;
+ impunge_sh = &impunge_local->self_heal;
+ frame = impunge_sh->sh_frame;
+
+ child_index = (long) cookie;
+
+ 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.st_uid,
+ impunge_local->cont.lookup.buf.st_gid);
+
+#ifdef HAVE_STRUCT_STAT_ST_ATIM_TV_NSEC
+ stbuf.st_atim = impunge_local->cont.lookup.buf.st_atim;
+ stbuf.st_mtim = impunge_local->cont.lookup.buf.st_mtim;
+
+#elif HAVE_STRUCT_STAT_ST_ATIMESPEC_TV_NSEC
+ stbuf.st_atimespec = impunge_local->cont.lookup.buf.st_atimespec;
+ stbuf.st_mtimespec = impunge_local->cont.lookup.buf.st_mtimespec;
+#else
+ stbuf.st_atime = impunge_local->cont.lookup.buf.st_atime;
+ stbuf.st_mtime = impunge_local->cont.lookup.buf.st_mtime;
+#endif
-static int
-__afr_selfheal_entry (call_frame_t *frame, xlator_t *this, fd_t *fd,
- unsigned char *locked_on)
+ stbuf.st_uid = impunge_local->cont.lookup.buf.st_uid;
+ stbuf.st_gid = impunge_local->cont.lookup.buf.st_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_parent_setattr_cbk (call_frame_t *setattr_frame,
+ void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno,
+ struct stat *preop, struct stat *postop)
{
- int ret = -1;
- int source = -1;
- unsigned char *sources = NULL;
- unsigned char *sinks = NULL;
- unsigned char *data_lock = NULL;
- unsigned char *postop_lock = NULL;
- unsigned char *healed_sinks = NULL;
- struct afr_reply *locked_replies = NULL;
- afr_private_t *priv = NULL;
- gf_boolean_t did_sh = _gf_true;
+ loc_t *parent_loc = cookie;
+
+ if (op_ret != 0) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "setattr on parent directory failed: %s",
+ strerror (op_errno));
+ }
+
+ loc_wipe (parent_loc);
+
+ FREE (parent_loc);
+
+ 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 stat *stbuf,
+ struct stat *preparent,
+ struct stat *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 stat parentbuf;
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) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "creation of %s on %s failed (%s)",
+ impunge_local->loc.path,
+ priv->children[child_index]->name,
+ strerror (op_errno));
+ goto out;
+ }
- sources = alloca0 (priv->child_count);
- sinks = alloca0 (priv->child_count);
- healed_sinks = alloca0 (priv->child_count);
- data_lock = alloca0 (priv->child_count);
- postop_lock = alloca0 (priv->child_count);
+ inode->st_mode = stbuf->st_mode;
- locked_replies = alloca0 (sizeof (*locked_replies) * priv->child_count);
+ xattr = get_new_dict ();
+ dict_ref (xattr);
- ret = afr_selfheal_entrylk (frame, this, fd->inode, this->name, NULL,
- data_lock);
+ idx = afr_index_for_transaction_type (AFR_METADATA_TRANSACTION);
+ pending_array[idx] = hton32 (1);
+ if (S_ISDIR (stbuf->st_mode))
+ idx = afr_index_for_transaction_type (AFR_ENTRY_TRANSACTION);
+ else
+ idx = afr_index_for_transaction_type (AFR_DATA_TRANSACTION);
+ pending_array[idx] = hton32 (1);
+
+ ret = dict_set_static_bin (xattr, priv->pending_key[child_index],
+ pending_array, sizeof (pending_array));
+
+ valid = GF_SET_ATTR_ATIME | GF_SET_ATTR_MTIME;
+ parentbuf = impunge_sh->parentbuf;
+ setattr_frame = copy_frame (impunge_frame);
+
+ parent_loc = CALLOC (1, sizeof (*parent_loc));
+ afr_build_parent_loc (parent_loc, &impunge_local->loc);
+
+ 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->setattr,
+ parent_loc, &parentbuf, valid);
+
+ dict_unref (xattr);
+
+ return 0;
+
+out:
+ LOCK (&impunge_frame->lock);
{
- if (ret < AFR_SH_MIN_PARTICIPANTS) {
- gf_log (this->name, GF_LOG_DEBUG, "%s: Skipping "
- "entry self-heal as only %d sub-volumes could "
- "be locked in %s domain",
- uuid_utoa (fd->inode->gfid), ret,
- this->name);
- ret = -ENOTCONN;
- goto unlock;
- }
+ call_count = --impunge_local->call_count;
+ }
+ UNLOCK (&impunge_frame->lock);
- ret = __afr_selfheal_entry_prepare (frame, this, fd->inode,
- data_lock, sources, sinks,
- healed_sinks,
- locked_replies, &source);
- if (AFR_COUNT(healed_sinks, priv->child_count) == 0) {
- did_sh = _gf_false;
- goto unlock;
- }
+ if (call_count == 0) {
+ AFR_STACK_DESTROY (impunge_frame);
+ afr_sh_entry_impunge_entry_done (frame, this, active_src);
}
-unlock:
- afr_selfheal_unentrylk (frame, this, fd->inode, this->name, NULL,
- data_lock);
- if (ret < 0)
+
+ return 0;
+}
+
+
+int
+afr_sh_entry_impunge_mknod (call_frame_t *impunge_frame, xlator_t *this,
+ int child_index, struct stat *stbuf)
+{
+ afr_private_t *priv = NULL;
+ afr_local_t *impunge_local = NULL;
+ afr_self_heal_t *impunge_sh = NULL;
+
+
+ priv = this->private;
+ impunge_local = impunge_frame->local;
+ impunge_sh = &impunge_local->self_heal;
+
+ gf_log (this->name, GF_LOG_DEBUG,
+ "creating missing file %s on %s",
+ impunge_local->loc.path,
+ priv->children[child_index]->name);
+
+ STACK_WIND_COOKIE (impunge_frame, afr_sh_entry_impunge_newfile_cbk,
+ (void *) (long) child_index,
+ priv->children[child_index],
+ priv->children[child_index]->fops->mknod,
+ &impunge_local->loc,
+ stbuf->st_mode, stbuf->st_rdev);
+
+ return 0;
+}
+
+
+
+int
+afr_sh_entry_impunge_mkdir (call_frame_t *impunge_frame, xlator_t *this,
+ int child_index, struct stat *stbuf)
+{
+ afr_private_t *priv = NULL;
+ afr_local_t *impunge_local = NULL;
+ afr_self_heal_t *impunge_sh = NULL;
+
+
+ priv = this->private;
+ impunge_local = impunge_frame->local;
+ impunge_sh = &impunge_local->self_heal;
+
+ gf_log (this->name, GF_LOG_DEBUG,
+ "creating missing directory %s on %s",
+ impunge_local->loc.path,
+ priv->children[child_index]->name);
+
+ STACK_WIND_COOKIE (impunge_frame, afr_sh_entry_impunge_newfile_cbk,
+ (void *) (long) child_index,
+ priv->children[child_index],
+ priv->children[child_index]->fops->mkdir,
+ &impunge_local->loc, stbuf->st_mode);
+
+ return 0;
+}
+
+
+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;
+ afr_self_heal_t *impunge_sh = NULL;
+
+
+ priv = this->private;
+ impunge_local = impunge_frame->local;
+ impunge_sh = &impunge_local->self_heal;
+
+ gf_log (this->name, GF_LOG_DEBUG,
+ "creating missing symlink %s -> %s on %s",
+ impunge_local->loc.path, linkname,
+ priv->children[child_index]->name);
+
+ STACK_WIND_COOKIE (impunge_frame, afr_sh_entry_impunge_newfile_cbk,
+ (void *) (long) child_index,
+ priv->children[child_index],
+ priv->children[child_index]->fops->symlink,
+ linkname, &impunge_local->loc);
+
+ return 0;
+}
+
+
+int
+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 stat *preparent,
+ struct stat *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;
+
+ if (op_ret == -1) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "unlink of %s on %s failed (%s)",
+ impunge_local->loc.path,
+ priv->children[child_index]->name,
+ strerror (op_errno));
goto out;
+ }
- if (!did_sh)
- goto out;
+ afr_sh_entry_impunge_symlink (impunge_frame, this, child_index,
+ impunge_sh->linkname);
+
+ return 0;
+out:
+ LOCK (&impunge_frame->lock);
+ {
+ call_count = --impunge_local->call_count;
+ }
+ 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_symlink_unlink (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;
- ret = afr_selfheal_entry_do (frame, this, fd, source, sources,
- healed_sinks);
- if (ret)
+ priv = this->private;
+ impunge_local = impunge_frame->local;
+ impunge_sh = &impunge_local->self_heal;
+
+ gf_log (this->name, GF_LOG_DEBUG,
+ "unlinking symlink %s with wrong target on %s",
+ impunge_local->loc.path,
+ priv->children[child_index]->name);
+
+ STACK_WIND_COOKIE (impunge_frame, afr_sh_entry_impunge_symlink_unlink_cbk,
+ (void *) (long) child_index,
+ priv->children[child_index],
+ priv->children[child_index]->fops->unlink,
+ &impunge_local->loc);
+
+ return 0;
+}
+
+
+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 stat *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;
+
+ if ((op_ret == -1) && (op_errno != ENOENT)) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "readlink of %s on %s failed (%s)",
+ impunge_local->loc.path,
+ priv->children[active_src]->name,
+ strerror (op_errno));
goto out;
+ }
- /* Take entrylks in xlator domain before doing post-op (undo-pending) in
- * entry self-heal. This is to prevent a parallel name self-heal on
- * an entry under @fd->inode from reading pending xattrs while it is
- * being modified by SHD after entry sh below, given that
- * name self-heal takes locks ONLY in xlator domain and is free to read
- * pending changelog in the absence of the following locking.
- */
- ret = afr_selfheal_entrylk (frame, this, fd->inode, this->name, NULL,
- postop_lock);
- {
- if (AFR_CMP (data_lock, postop_lock, priv->child_count) != 0) {
- gf_log (this->name, GF_LOG_DEBUG, "%s: Skipping "
- "post-op after entry self-heal as %d "
- "sub-volumes, as opposed to %d, could be locked"
- " in %s domain", uuid_utoa (fd->inode->gfid),
- ret, AFR_COUNT (data_lock, priv->child_count),
- this->name);
- ret = -ENOTCONN;
- goto postop_unlock;
- }
+ /* symlink doesn't exist on the sink */
+
+ if ((op_ret == -1) && (op_errno == ENOENT)) {
+ afr_sh_entry_impunge_symlink (impunge_frame, this,
+ child_index, impunge_sh->linkname);
+ return 0;
+ }
- ret = afr_selfheal_undo_pending (frame, this, fd->inode,
- sources, sinks, healed_sinks,
- AFR_ENTRY_TRANSACTION,
- locked_replies, postop_lock);
+
+ /* symlink exists on the sink, so check if targets match */
+
+ if (strcmp (linkname, impunge_sh->linkname) == 0) {
+ /* targets match, nothing to do */
+
+ goto out;
+ } else {
+ /*
+ * Hah! Sneaky wolf in sheep's clothing!
+ */
+
+ afr_sh_entry_impunge_symlink_unlink (impunge_frame, this,
+ child_index);
+ return 0;
}
-postop_unlock:
- afr_selfheal_unentrylk (frame, this, fd->inode, this->name, NULL,
- postop_lock);
+
out:
- if (did_sh)
- afr_log_selfheal (fd->inode->gfid, this, ret, "entry", source,
- healed_sinks);
- else
- ret = 1;
+ LOCK (&impunge_frame->lock);
+ {
+ call_count = --impunge_local->call_count;
+ }
+ UNLOCK (&impunge_frame->lock);
- if (locked_replies)
- afr_replies_wipe (locked_replies, priv->child_count);
- return ret;
+ if (call_count == 0) {
+ AFR_STACK_DESTROY (impunge_frame);
+ afr_sh_entry_impunge_entry_done (frame, this, active_src);
+ }
+
+ return 0;
}
-static fd_t *
-afr_selfheal_data_opendir (xlator_t *this, inode_t *inode)
+int
+afr_sh_entry_impunge_readlink_sink (call_frame_t *impunge_frame, xlator_t *this,
+ int child_index)
{
- loc_t loc = {0,};
- int ret = 0;
- fd_t *fd = NULL;
+ afr_private_t *priv = NULL;
+ afr_local_t *impunge_local = NULL;
+ afr_self_heal_t *impunge_sh = NULL;
+
+
+ priv = this->private;
+ impunge_local = impunge_frame->local;
+ impunge_sh = &impunge_local->self_heal;
+
+ gf_log (this->name, GF_LOG_DEBUG,
+ "checking symlink target of %s on %s",
+ impunge_local->loc.path, priv->children[child_index]->name);
+
+ STACK_WIND_COOKIE (impunge_frame, afr_sh_entry_impunge_readlink_sink_cbk,
+ (void *) (long) child_index,
+ priv->children[child_index],
+ priv->children[child_index]->fops->readlink,
+ &impunge_local->loc, 4096);
+
+ return 0;
+}
+
+
+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 stat *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;
+
+ if (op_ret == -1) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "readlink of %s on %s failed (%s)",
+ impunge_local->loc.path,
+ priv->children[active_src]->name,
+ strerror (op_errno));
+ goto out;
+ }
+
+ impunge_sh->linkname = strdup (linkname);
+
+ afr_sh_entry_impunge_readlink_sink (impunge_frame, this, child_index);
+
+ return 0;
+
+out:
+ LOCK (&impunge_frame->lock);
+ {
+ call_count = --impunge_local->call_count;
+ }
+ 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_readlink (call_frame_t *impunge_frame, xlator_t *this,
+ int child_index, struct stat *stbuf)
+{
+ afr_private_t *priv = NULL;
+ afr_local_t *impunge_local = NULL;
+ afr_self_heal_t *impunge_sh = NULL;
+ int active_src = -1;
+
+ priv = this->private;
+ impunge_local = impunge_frame->local;
+ impunge_sh = &impunge_local->self_heal;
+ active_src = impunge_sh->active_source;
+
+ STACK_WIND_COOKIE (impunge_frame, afr_sh_entry_impunge_readlink_cbk,
+ (void *) (long) child_index,
+ priv->children[active_src],
+ priv->children[active_src]->fops->readlink,
+ &impunge_local->loc, 4096);
+
+ return 0;
+}
+
+
+int
+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 stat *buf,
+ dict_t *xattr,struct stat *postparent)
+{
+ afr_private_t *priv = 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;
+
+ 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) {
+ gf_log (this->name, GF_LOG_TRACE,
+ "looking up %s on %s (for %s) failed (%s)",
+ impunge_local->loc.path,
+ priv->children[active_src]->name,
+ priv->children[child_index]->name,
+ strerror (op_errno));
+ goto out;
+ }
+
+ impunge_sh->parentbuf = *postparent;
+
+ impunge_local->cont.lookup.buf = *buf;
+ type = (buf->st_mode & S_IFMT);
+
+ switch (type) {
+ case S_IFSOCK:
+ case S_IFREG:
+ case S_IFBLK:
+ case S_IFCHR:
+ case S_IFIFO:
+ afr_sh_entry_impunge_mknod (impunge_frame, this,
+ child_index, buf);
+ break;
+ case S_IFLNK:
+ afr_sh_entry_impunge_readlink (impunge_frame, this,
+ child_index, buf);
+ break;
+ case S_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);
+ goto out;
+ break;
+ }
+
+ return 0;
+
+out:
+ LOCK (&impunge_frame->lock);
+ {
+ call_count = --impunge_local->call_count;
+ }
+ 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;
+}
- fd = fd_create (inode, 0);
- if (!fd)
- return NULL;
- loc.inode = inode_ref (inode);
- uuid_copy (loc.gfid, inode->gfid);
+int
+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;
+ int active_src = 0;
+
+
+ priv = this->private;
+ impunge_local = impunge_frame->local;
+ impunge_sh = &impunge_local->self_heal;
- ret = syncop_opendir (this, &loc, fd);
- if (ret) {
- fd_unref (fd);
- fd = NULL;
+ active_src = impunge_sh->active_source;
+
+ 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;
+}
+
+
+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 stat *buf, dict_t *x,
+ struct stat *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;
+ int active_src = 0;
+
+ 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 == -1 && op_errno == ENOENT)
+ || (S_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 {
- fd_bind (fd);
+ gf_log (this->name, GF_LOG_TRACE,
+ "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;
+ }
+ UNLOCK (&impunge_frame->lock);
+
+ if (call_count == 0) {
+ AFR_STACK_DESTROY (impunge_frame);
+ afr_sh_entry_impunge_entry_done (frame, this, active_src);
}
- loc_wipe (&loc);
- return fd;
+ return 0;
}
int
-afr_selfheal_entry (call_frame_t *frame, xlator_t *this, inode_t *inode)
+afr_sh_entry_impunge_entry (call_frame_t *frame, xlator_t *this,
+ gf_dirent_t *entry)
{
- afr_private_t *priv = NULL;
- unsigned char *locked_on = NULL;
- unsigned char *long_name_locked = NULL;
+ afr_private_t *priv = NULL;
+ afr_local_t *local = NULL;
+ afr_self_heal_t *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;
+
+ priv = this->private;
+ local = frame->local;
+ sh = &local->self_heal;
+
+ active_src = sh->active_source;
+
+ if ((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);
+ goto out;
+ }
+
+ gf_log (this->name, GF_LOG_TRACE,
+ "inspecting existance of %s under %s",
+ entry->d_name, local->loc.path);
+
+ impunge_frame = copy_frame (frame);
+ if (!impunge_frame) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory.");
+ goto out;
+ }
+
+ ALLOC_OR_GOTO (impunge_local, afr_local_t, out);
+
+ impunge_frame->local = impunge_local;
+ impunge_sh = &impunge_local->self_heal;
+ impunge_sh->sh_frame = frame;
+ impunge_sh->active_source = active_src;
+
+ impunge_sh->impunging_entry_mode = entry->d_stat.st_mode;
+
+ ret = build_child_loc (this, &impunge_local->loc, &local->loc, entry->d_name);
+ if (ret != 0) {
+ goto out;
+ }
+
+ 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++;
+ }
+
+ 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;
+}
+
+
+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)
+{
+ afr_private_t *priv = NULL;
+ afr_local_t *local = NULL;
+ afr_self_heal_t *sh = NULL;
+ gf_dirent_t *entry = NULL;
+ off_t last_offset = 0;
+ int active_src = 0;
+ int entry_count = 0;
+
+ priv = this->private;
+ local = frame->local;
+ sh = &local->self_heal;
+
+ active_src = sh->active_source;
+
+ if (op_ret <= 0) {
+ if (op_ret < 0) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "readdir of %s on subvolume %s failed (%s)",
+ local->loc.path,
+ priv->children[active_src]->name,
+ strerror (op_errno));
+ } else {
+ gf_log (this->name, GF_LOG_TRACE,
+ "readdir of %s on subvolume %s complete",
+ local->loc.path,
+ priv->children[active_src]->name);
+ }
+
+ afr_sh_entry_impunge_all (frame, this);
+ return 0;
+ }
+
+ list_for_each_entry (entry, &entries->list, list) {
+ last_offset = entry->d_off;
+ entry_count++;
+ }
+
+ gf_log (this->name, GF_LOG_TRACE,
+ "readdir'ed %d entries from %s",
+ entry_count, priv->children[active_src]->name);
+
+ sh->offset = last_offset;
+ local->call_count = entry_count;
+
+ list_for_each_entry (entry, &entries->list, list) {
+ afr_sh_entry_impunge_entry (frame, this, entry);
+ }
+
+ return 0;
+}
+
+
+int
+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;
+
+ priv = this->private;
+ local = frame->local;
+ sh = &local->self_heal;
+
+ 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);
+
+ return 0;
+}
+
+
+int
+afr_sh_entry_impunge_all (call_frame_t *frame, xlator_t *this)
+{
+ afr_private_t *priv = NULL;
+ afr_local_t *local = NULL;
+ afr_self_heal_t *sh = NULL;
+ int active_src = -1;
+
+ priv = this->private;
+ local = frame->local;
+ sh = &local->self_heal;
+
+ sh->offset = 0;
+
+ active_src = next_active_source (frame, this, sh->active_source);
+ sh->active_source = active_src;
+
+ if (sh->op_failed) {
+ afr_sh_entry_finish (frame, this);
+ return 0;
+ }
+
+ if (active_src == -1) {
+ /* completed creating missing files on all subvolumes */
+ afr_sh_entry_expunge_all (frame, this);
+ return 0;
+ }
+
+ gf_log (this->name, GF_LOG_TRACE,
+ "impunging entries of %s on %s to other sinks",
+ local->loc.path, priv->children[active_src]->name);
+
+ afr_sh_entry_impunge_subvol (frame, this, active_src);
+
+ return 0;
+}
+
+
+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)
+{
+ 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;
+
+ /* TODO: some of the open's might fail.
+ In that case, modify cleanup fn to send flush on those
+ fd's which are already open */
+
+ LOCK (&frame->lock);
+ {
+ if (op_ret == -1) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "opendir of %s failed on child %s (%s)",
+ local->loc.path,
+ priv->children[child_index]->name,
+ strerror (op_errno));
+ sh->op_failed = 1;
+ }
+ }
+ UNLOCK (&frame->lock);
+
+ call_count = afr_frame_return (frame);
+
+ if (call_count == 0) {
+ if (sh->op_failed) {
+ afr_sh_entry_finish (frame, this);
+ return 0;
+ }
+ gf_log (this->name, GF_LOG_TRACE,
+ "fd for %s opened, commencing sync",
+ local->loc.path);
+
+ sh->active_source = -1;
+ afr_sh_entry_impunge_all (frame, this);
+ }
+
+ return 0;
+}
+
+
+int
+afr_sh_entry_open (call_frame_t *frame, xlator_t *this)
+{
+ int i = 0;
+ int call_count = 0;
+
+ int source = -1;
+ int *sources = NULL;
+
fd_t *fd = NULL;
- int ret = 0;
+ 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;
- fd = afr_selfheal_data_opendir (this, inode);
- if (!fd)
- return -EIO;
+ source = local->self_heal.source;
+ sources = local->self_heal.sources;
+
+ sh->block_size = 131072;
+ sh->offset = 0;
+
+ call_count = sh->active_sinks;
+ if (source != -1)
+ call_count++;
- locked_on = alloca0 (priv->child_count);
- long_name_locked = alloca0 (priv->child_count);
+ local->call_count = call_count;
- ret = afr_selfheal_tryentrylk (frame, this, inode, priv->sh_domain, NULL,
- locked_on);
+ fd = fd_create (local->loc.inode, frame->root->pid);
+ sh->healing_fd = fd;
+
+ if (source != -1) {
+ gf_log (this->name, GF_LOG_TRACE,
+ "opening directory %s on subvolume %s (source)",
+ local->loc.path, priv->children[source]->name);
+
+ /* open source */
+ STACK_WIND_COOKIE (frame, afr_sh_entry_opendir_cbk,
+ (void *) (long) source,
+ priv->children[source],
+ priv->children[source]->fops->opendir,
+ &local->loc, fd);
+ call_count--;
+ }
+
+ /* open sinks */
+ for (i = 0; i < priv->child_count; i++) {
+ if (sources[i] || !local->child_up[i])
+ continue;
+
+ gf_log (this->name, GF_LOG_TRACE,
+ "opening directory %s on subvolume %s (sink)",
+ local->loc.path, priv->children[i]->name);
+
+ STACK_WIND_COOKIE (frame, afr_sh_entry_opendir_cbk,
+ (void *) (long) i,
+ priv->children[i],
+ priv->children[i]->fops->opendir,
+ &local->loc, fd);
+
+ if (!--call_count)
+ break;
+ }
+
+ return 0;
+}
+
+
+int
+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;
+ priv = this->private;
+
+ source = sh->source;
+
+ 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 (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 && 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,
+ active_sinks);
+ else
+ gf_log (this->name, GF_LOG_DEBUG,
+ "no active sources for %s found. "
+ "merging all entries as a conservative decision",
+ local->loc.path);
+
+ afr_sh_entry_open (frame, this);
+
+ return 0;
+}
+
+
+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;
+
+ local = frame->local;
+ sh = &local->self_heal;
+ priv = this->private;
+
+ if (sh->forced_merge) {
+ sh->source = -1;
+ goto heal;
+ }
+
+ 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 0;
+ }
+
+ afr_sh_supress_errenous_children (sh->sources, sh->child_errno,
+ priv->child_count);
+
+ source = afr_sh_select_source (sh->sources, priv->child_count);
+
+ sh->source = source;
+
+heal:
+ afr_sh_entry_sync_prepare (frame, this);
+
+ 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 stat *buf, dict_t *xattr,
+ struct stat *postparent)
+{
+ 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;
+ sh = &local->self_heal;
+ priv = this->private;
+
+ LOCK (&frame->lock);
{
- if (ret < AFR_SH_MIN_PARTICIPANTS) {
- gf_log (this->name, GF_LOG_DEBUG, "%s: Skipping "
- "entry self-heal as only %d sub-volumes could "
- "be locked in %s domain",
- uuid_utoa (fd->inode->gfid), ret,
- priv->sh_domain);
- /* Either less than two subvols available, or another
- selfheal (from another server) is in progress. Skip
- for now in any case there isn't anything to do.
- */
- ret = -ENOTCONN;
- goto unlock;
+ 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);
- ret = afr_selfheal_tryentrylk (frame, this, inode, this->name,
- LONG_FILENAME, long_name_locked);
- {
- if (ret < 1) {
- gf_log (this->name, GF_LOG_DEBUG, "%s: Skipping"
- " entry self-heal as only %d "
- "sub-volumes could be locked in "
- "special-filename domain",
- uuid_utoa (fd->inode->gfid),
- ret);
- ret = -ENOTCONN;
- goto unlock;
- }
- ret = __afr_selfheal_entry (frame, this, fd, locked_on);
+ 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_self_heal_t * sh = NULL;
+ 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;
+ sh = &local->self_heal;
+
+ 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));
}
- afr_selfheal_unentrylk (frame, this, inode, this->name,
- LONG_FILENAME, long_name_locked);
+ }
+
+ 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;
+ }
}
-unlock:
- afr_selfheal_unentrylk (frame, this, inode, priv->sh_domain, NULL, locked_on);
+
+ if (xattr_req)
+ dict_unref (xattr_req);
- if (fd)
- fd_unref (fd);
+ return 0;
+}
- return ret;
+
+
+int
+afr_sh_entry_lock_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 call_count = 0;
+ int child_index = (long) cookie;
+
+ /* TODO: what if lock fails? */
+
+ local = frame->local;
+ sh = &local->self_heal;
+
+ LOCK (&frame->lock);
+ {
+ if (op_ret == -1) {
+ sh->op_failed = 1;
+
+ sh->locked_nodes[child_index] = 0;
+ gf_log (this->name, GF_LOG_DEBUG,
+ "locking inode of %s on child %d failed: %s",
+ local->loc.path, child_index,
+ strerror (op_errno));
+ } else {
+ sh->locked_nodes[child_index] = 1;
+ gf_log (this->name, GF_LOG_TRACE,
+ "inode of %s on child %d locked",
+ local->loc.path, child_index);
+ }
+ }
+ UNLOCK (&frame->lock);
+
+ call_count = afr_frame_return (frame);
+
+ if (call_count == 0) {
+ if (sh->op_failed == 1) {
+ afr_sh_entry_finish (frame, this);
+ return 0;
+ }
+
+ afr_sh_entry_lookup (frame, this);
+ }
+
+ return 0;
}
+
+
+int
+afr_sh_entry_lock (call_frame_t *frame, xlator_t *this)
+{
+ int i = 0;
+ int call_count = 0;
+
+ 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;
+
+ call_count = afr_up_children_count (priv->child_count,
+ local->child_up);
+
+ local->call_count = call_count;
+
+ for (i = 0; i < priv->child_count; i++) {
+ if (local->child_up[i]) {
+ gf_log (this->name, GF_LOG_TRACE,
+ "locking %s on subvolume %s",
+ local->loc.path, priv->children[i]->name);
+
+ STACK_WIND_COOKIE (frame, afr_sh_entry_lock_cbk,
+ (void *) (long) i,
+ priv->children[i],
+ priv->children[i]->fops->entrylk,
+ this->name,
+ &local->loc, NULL,
+ ENTRYLK_LOCK_NB, ENTRYLK_WRLCK);
+ if (!--call_count)
+ break;
+ }
+ }
+
+ return 0;
+}
+
+
+int
+afr_self_heal_entry (call_frame_t *frame, xlator_t *this)
+{
+ afr_local_t *local = NULL;
+ afr_self_heal_t *sh = NULL;
+ afr_private_t *priv = NULL;
+
+
+ priv = this->private;
+ local = frame->local;
+ sh = &local->self_heal;
+
+ 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",
+ local->loc.path);
+ afr_sh_entry_done (frame, this);
+ }
+
+ return 0;
+}
+
diff --git a/xlators/cluster/afr/src/afr-self-heal-metadata.c b/xlators/cluster/afr/src/afr-self-heal-metadata.c
index 8cc9b30d3e4..bddccf6821d 100644
--- a/xlators/cluster/afr/src/afr-self-heal-metadata.c
+++ b/xlators/cluster/afr/src/afr-self-heal-metadata.c
@@ -1,429 +1,822 @@
/*
- Copyright (c) 2013 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-2009 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 <libgen.h>
+#include <unistd.h>
+#include <fnmatch.h>
+#include <sys/time.h>
+#include <stdlib.h>
+#include <signal.h>
#ifndef _CONFIG_H
#define _CONFIG_H
#include "config.h"
#endif
+#include "glusterfs.h"
#include "afr.h"
-#include "afr-self-heal.h"
+#include "dict.h"
+#include "xlator.h"
+#include "hashfn.h"
+#include "logging.h"
+#include "stack.h"
+#include "list.h"
+#include "call-stub.h"
+#include "defaults.h"
+#include "common-utils.h"
+#include "compat-errno.h"
+#include "compat.h"
#include "byte-order.h"
-#define AFR_HEAL_ATTR (GF_SET_ATTR_UID|GF_SET_ATTR_GID|GF_SET_ATTR_MODE)
+#include "afr-transaction.h"
+#include "afr-self-heal.h"
+#include "afr-self-heal-common.h"
+
-static gf_boolean_t
-_afr_ignorable_key_match (dict_t *d, char *k, data_t *val, void *mdata)
+int
+afr_sh_metadata_done (call_frame_t *frame, xlator_t *this)
{
- return afr_is_xattr_ignorable (k);
+ 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 stat) * priv->child_count);
+ memset (sh->success, 0, sizeof (int) * priv->child_count);
+
+ 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_DEBUG,
+ "aborting selfheal of %s",
+ local->loc.path);
+ sh->completion_cbk (frame, this);
+ } else {
+ if (S_ISREG (sh->mode)) {
+ gf_log (this->name, GF_LOG_TRACE,
+ "proceeding to data check on %s",
+ local->loc.path);
+ afr_self_heal_data (frame, this);
+ return 0;
+ }
+
+ if (S_ISDIR (sh->mode)) {
+ gf_log (this->name, GF_LOG_TRACE,
+ "proceeding to entry check on %s",
+ local->loc.path);
+ afr_self_heal_entry (frame, this);
+ return 0;
+ }
+ gf_log (this->name, GF_LOG_DEBUG,
+ "completed self heal of %s",
+ local->loc.path);
+
+ sh->completion_cbk (frame, this);
+ }
+
+ return 0;
}
-void
-afr_delete_ignorable_xattrs (dict_t *xattr)
+
+int
+afr_sh_metadata_unlck_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno)
{
- dict_foreach_match (xattr, _afr_ignorable_key_match, NULL,
- dict_remove_foreach_fn, NULL);
+ afr_local_t *local = NULL;
+ int call_count = 0;
+
+
+ local = frame->local;
+
+ call_count = afr_frame_return (frame);
+
+ if (call_count == 0)
+ afr_sh_metadata_done (frame, this);
+
+ return 0;
}
+
int
-__afr_selfheal_metadata_do (call_frame_t *frame, xlator_t *this, inode_t *inode,
- int source, unsigned char *healed_sinks,
- struct afr_reply *locked_replies)
+afr_sh_metadata_finish (call_frame_t *frame, xlator_t *this)
{
- int ret = -1;
- loc_t loc = {0,};
- dict_t *xattr = NULL;
- dict_t *old_xattr = NULL;
- afr_private_t *priv = NULL;
- int i = 0;
+ afr_local_t *local = NULL;
+ afr_self_heal_t *sh = NULL;
+ afr_private_t *priv = NULL;
+ int i = 0;
+ int call_count = 0;
+ struct flock flock = {0, };
+
+ local = frame->local;
+ sh = &local->self_heal;
priv = this->private;
- loc.inode = inode_ref (inode);
- uuid_copy (loc.gfid, inode->gfid);
+ for (i = 0; i < priv->child_count; i++) {
+ if (sh->locked_nodes[i])
+ call_count++;
+ }
+
+ if (call_count == 0) {
+ afr_sh_metadata_done (frame, this);
+ return 0;
+ }
+
+ local->call_count = call_count;
+
+ for (i = 0; i < priv->child_count; i++) {
+ flock.l_start = 0;
+ flock.l_len = 0;
+ flock.l_type = F_UNLCK;
+
+ if (sh->locked_nodes[i]) {
+ gf_log (this->name, GF_LOG_TRACE,
+ "unlocking %s on subvolume %s",
+ local->loc.path, priv->children[i]->name);
+
+ STACK_WIND (frame, afr_sh_metadata_unlck_cbk,
+ priv->children[i],
+ priv->children[i]->fops->inodelk,
+ this->name,
+ &local->loc, F_SETLK, &flock);
+
+ if (!--call_count)
+ break;
+ }
+ }
+
+ return 0;
+}
+
- gf_log (this->name, GF_LOG_INFO, "performing metadata selfheal on %s",
- uuid_utoa (inode->gfid));
+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)
+{
+ afr_local_t *local = NULL;
+ afr_self_heal_t *sh = NULL;
+ afr_private_t *priv = NULL;
+ int call_count = 0;
+
+ local = frame->local;
+ sh = &local->self_heal;
+ priv = this->private;
- ret = syncop_getxattr (priv->children[source], &loc, &xattr, NULL);
- if (ret < 0) {
- ret = -EIO;
- goto out;
+ LOCK (&frame->lock);
+ {
}
+ UNLOCK (&frame->lock);
+
+ call_count = afr_frame_return (frame);
+
+ if (call_count == 0)
+ afr_sh_metadata_finish (frame, this);
+
+ return 0;
+}
+
- afr_delete_ignorable_xattrs (xattr);
+int
+afr_sh_metadata_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;
+
+
+ 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 = CALLOC (sizeof (*erase_xattr), priv->child_count);
for (i = 0; i < priv->child_count; i++) {
- if (old_xattr) {
- dict_unref (old_xattr);
- old_xattr = NULL;
- }
+ 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_WARNING,
+ "metadata of %s not healed on any subvolume",
+ local->loc.path);
- if (!healed_sinks[i])
+ afr_sh_metadata_finish (frame, this);
+ }
+
+ for (i = 0; i < priv->child_count; i++) {
+ if (!erase_xattr[i])
continue;
- ret = syncop_setattr (priv->children[i], &loc,
- &locked_replies[source].poststat,
- AFR_HEAL_ATTR, NULL, NULL);
- if (ret)
- healed_sinks[i] = 0;
-
- ret = syncop_getxattr (priv->children[i], &loc, &old_xattr, 0);
- if (old_xattr) {
- afr_delete_ignorable_xattrs (old_xattr);
- ret = syncop_removexattr (priv->children[i], &loc, "",
- old_xattr);
+ 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]);
}
+ }
+ 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)
+{
+ afr_local_t *local = NULL;
+ afr_self_heal_t *sh = NULL;
+ afr_private_t *priv = NULL;
+ int call_count = 0;
+ int child_index = 0;
- ret = syncop_setxattr (priv->children[i], &loc, xattr, 0);
- if (ret)
- healed_sinks[i] = 0;
+
+ local = frame->local;
+ sh = &local->self_heal;
+ priv = this->private;
+
+ child_index = (long) cookie;
+
+ LOCK (&frame->lock);
+ {
+ if (op_ret == -1) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "setting attributes failed for %s on %s (%s)",
+ local->loc.path,
+ priv->children[child_index]->name,
+ strerror (op_errno));
+
+ sh->success[child_index] = 0;
+ }
}
- ret = 0;
+ UNLOCK (&frame->lock);
-out:
- loc_wipe (&loc);
- if (xattr)
- dict_unref (xattr);
- if (old_xattr)
- dict_unref (old_xattr);
+ call_count = afr_frame_return (frame);
- return ret;
+ if (call_count == 0)
+ afr_sh_metadata_erase_pending (frame, this);
+
+ return 0;
}
-static inline uint64_t
-mtime_ns(struct iatt *ia)
-{
- uint64_t ret;
- ret = (((uint64_t)(ia->ia_mtime)) * 1000000000)
- + (uint64_t)(ia->ia_mtime_nsec);
+int
+afr_sh_metadata_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno,
+ struct stat *preop, struct stat *postop)
+{
+ afr_sh_metadata_sync_cbk (frame, cookie, this, op_ret, op_errno);
- return ret;
+ return 0;
}
-/*
- * When directory content is modified, [mc]time is updated. On
- * Linux, the filesystem does it, while at least on NetBSD, the
- * kernel file-system independant code does it. This means that
- * when entries are added while bricks are down, the kernel sends
- * a SETATTR [mc]time which will cause metadata split brain for
- * the directory. In this case, clear the split brain by finding
- * the source with the most recent modification date.
- */
-static int
-afr_dirtime_splitbrain_source (call_frame_t *frame, xlator_t *this,
- struct afr_reply *replies,
- unsigned char *locked_on)
+
+int
+afr_sh_metadata_xattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno)
{
- afr_private_t *priv = NULL;
- int source = -1;
- struct iatt source_ia;
- struct iatt child_ia;
- uint64_t mtime = 0;
- int i;
- int ret = -1;
+ afr_sh_metadata_sync_cbk (frame, cookie, this, op_ret, op_errno);
- priv = this->private;
+ return 0;
+}
- for (i = 0; i < priv->child_count; i++) {
- if (!locked_on[i])
- continue;
- if (!replies[i].valid)
- continue;
+int
+afr_sh_metadata_sync (call_frame_t *frame, xlator_t *this, dict_t *xattr)
+{
+ afr_local_t *local = NULL;
+ afr_self_heal_t *sh = NULL;
+ afr_private_t *priv = NULL;
+ int source = 0;
+ int active_sinks = 0;
+ int call_count = 0;
+ int i = 0;
+
+ struct stat stbuf;
+ int32_t valid = 0;
+
+ local = frame->local;
+ sh = &local->self_heal;
+ priv = this->private;
- if (replies[i].op_ret != 0)
- continue;
+ source = sh->source;
+ active_sinks = sh->active_sinks;
- if (mtime_ns(&replies[i].poststat) <= mtime)
- continue;
+ /*
+ * 2 calls per sink - setattr, setxattr
+ */
+ if (xattr)
+ call_count = active_sinks * 2;
+ else
+ call_count = active_sinks;
+
+ local->call_count = call_count;
+
+#ifdef HAVE_STRUCT_STAT_ST_ATIM_TV_NSEC
+ stbuf.st_atim = sh->buf[source].st_atim;
+ stbuf.st_mtim = sh->buf[source].st_mtim;
+
+#elif HAVE_STRUCT_STAT_ST_ATIMESPEC_TV_NSEC
+ stbuf.st_atimespec = sh->buf[source].st_atimespec;
+ stbuf.st_mtimespec = sh->buf[source].st_mtimespec;
+#else
+ stbuf.st_atime = sh->buf[source].st_atime;
+ stbuf.st_mtime = sh->buf[source].st_mtime;
+#endif
- mtime = mtime_ns(&replies[i].poststat);
- source = i;
- }
+ stbuf.st_uid = sh->buf[source].st_uid;
+ stbuf.st_gid = sh->buf[source].st_gid;
- if (source == -1)
- goto out;
+ stbuf.st_mode = sh->buf[source].st_mode;
+
+ valid = GF_SET_ATTR_MODE |
+ GF_SET_ATTR_UID | GF_SET_ATTR_GID |
+ GF_SET_ATTR_ATIME | GF_SET_ATTR_MTIME;
- source_ia = replies[source].poststat;
- if (source_ia.ia_type != IA_IFDIR)
- goto out;
+ for (i = 0; i < priv->child_count; i++) {
+ if (call_count == 0) {
+ break;
+ }
+ if (sh->sources[i] || !local->child_up[i])
+ continue;
- for (i = 0; i < priv->child_count; i++) {
- if (i == source)
- continue;
+ gf_log (this->name, GF_LOG_DEBUG,
+ "self-healing metadata of %s from %s to %s",
+ local->loc.path, priv->children[source]->name,
+ priv->children[i]->name);
- if (!replies[i].valid)
- continue;
+ STACK_WIND_COOKIE (frame, afr_sh_metadata_setattr_cbk,
+ (void *) (long) i,
+ priv->children[i],
+ priv->children[i]->fops->setattr,
+ &local->loc, &stbuf, valid);
- if (replies[i].op_ret != 0)
- continue;
+ call_count--;
- child_ia = replies[i].poststat;
+ if (!xattr)
+ continue;
- if (!IA_EQUAL(source_ia, child_ia, gfid) ||
- !IA_EQUAL(source_ia, child_ia, type) ||
- !IA_EQUAL(source_ia, child_ia, prot) ||
- !IA_EQUAL(source_ia, child_ia, uid) ||
- !IA_EQUAL(source_ia, child_ia, gid) ||
- !afr_xattrs_are_equal (replies[source].xdata,
- replies[i].xdata))
- goto out;
- }
+ STACK_WIND_COOKIE (frame, afr_sh_metadata_xattr_cbk,
+ (void *) (long) i,
+ priv->children[i],
+ priv->children[i]->fops->setxattr,
+ &local->loc, xattr, 0);
+ call_count--;
+ }
- /*
- * Metadata split brain is just about [amc]time
- * We return our source.
- */
- ret = source;
-out:
- return ret;
+ return 0;
}
-/*
- * Look for mismatching uid/gid or mode or user xattrs even if
- * AFR xattrs don't say so, and pick one arbitrarily as winner. */
-
-static int
-__afr_selfheal_metadata_finalize_source (call_frame_t *frame, xlator_t *this,
- unsigned char *sources,
- unsigned char *healed_sinks,
- unsigned char *locked_on,
- struct afr_reply *replies)
+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)
{
- int i = 0;
- afr_private_t *priv = NULL;
- struct iatt first = {0, };
- int source = -1;
- int sources_count = 0;
+ afr_local_t *local = NULL;
+ afr_self_heal_t *sh = NULL;
+ afr_private_t *priv = NULL;
+ int source = 0;
+
+ int i;
+ local = frame->local;
+ sh = &local->self_heal;
priv = this->private;
- sources_count = AFR_COUNT (sources, priv->child_count);
+ source = sh->source;
- if ((AFR_CMP (locked_on, healed_sinks, priv->child_count) == 0)
- || !sources_count) {
- /* If this is a directory mtime/ctime only split brain
- use the most recent */
- source = afr_dirtime_splitbrain_source (frame, this,
- replies, locked_on);
- if (source != -1) {
- gf_log (this->name, GF_LOG_NOTICE, "clear time "
- "split brain on %s",
- uuid_utoa (replies[source].poststat.ia_gfid));
- sources[source] = 1;
+ if (op_ret == -1) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "getxattr of %s failed on subvolume %s (%s). proceeding without xattr",
+ local->loc.path, priv->children[source]->name,
+ strerror (op_errno));
- for (i = 0; i < priv->child_count; i++) {
- if (i == source)
- continue;
+ afr_sh_metadata_sync (frame, this, NULL);
+ } else {
+ for (i = 0; i < priv->child_count; i++) {
+ dict_del (xattr, priv->pending_key[i]);
+ }
- if (!locked_on[i])
- continue;
+ afr_sh_metadata_sync (frame, this, xattr);
+ }
- healed_sinks[i] = 1;
- }
+ return 0;
+}
- return source;
- }
- if (!priv->metadata_splitbrain_forced_heal) {
- return -EIO;
- }
+int
+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;
+ priv = this->private;
- /* Metadata split brain, select one subvol
- arbitrarily */
- for (i = 0; i < priv->child_count; i++) {
- if (locked_on[i] && healed_sinks[i]) {
- sources[i] = 1;
- healed_sinks[i] = 0;
- break;
- }
- }
- }
+ source = sh->source;
for (i = 0; i < priv->child_count; i++) {
- if (!sources[i])
- continue;
- if (source == -1) {
- source = i;
- first = replies[i].poststat;
- break;
+ 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, active_sinks);
+ STACK_WIND (frame, afr_sh_metadata_getxattr_cbk,
+ priv->children[source],
+ priv->children[source]->fops->getxattr,
+ &local->loc, NULL);
+
+ return 0;
+}
+
+
+int
+afr_sh_metadata_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 nsources = 0;
+ int source = 0;
+ int i = 0;
+
+ local = frame->local;
+ sh = &local->self_heal;
+ priv = this->private;
+
+ 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);
+ return 0;
+ }
+
+ if ((nsources == -1)
+ && (priv->favorite_child != -1)
+ && (sh->child_errno[priv->favorite_child] == 0)) {
+
+ gf_log (this->name, GF_LOG_WARNING,
+ "Picking favorite child %s as authentic source to resolve conflicting metadata of %s",
+ priv->children[priv->favorite_child]->name,
+ local->loc.path);
+
+ sh->sources[priv->favorite_child] = 1;
+
+ nsources = afr_sh_source_count (sh->sources,
+ priv->child_count);
+ }
+
+ if (nsources == -1) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Unable to self-heal permissions/ownership of '%s' "
+ "(possible split-brain). Please fix the file on "
+ "all backend volumes", local->loc.path);
+
+ local->govinda_gOvinda = 1;
+
+ afr_sh_metadata_finish (frame, this);
+ return 0;
+ }
+
+ 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_metadata_finish (frame, this);
+ return 0;
+ }
+
+ sh->source = source;
+
+ /* detect changes not visible through pending flags -- JIC */
for (i = 0; i < priv->child_count; i++) {
- if (!sources[i] || i == source)
+ if (i == source || sh->child_errno[i])
continue;
- if (!IA_EQUAL (first, replies[i].poststat, type) ||
- !IA_EQUAL (first, replies[i].poststat, uid) ||
- !IA_EQUAL (first, replies[i].poststat, gid) ||
- !IA_EQUAL (first, replies[i].poststat, prot)) {
- gf_log (this->name, GF_LOG_DEBUG, "%s: iatt mismatch "
- "for source(%d) vs (%d)",
- uuid_utoa (replies[source].poststat.ia_gfid),
- source, i);
- sources[i] = 0;
- healed_sinks[i] = 1;
- }
+
+ if (PERMISSION_DIFFERS (&sh->buf[i], &sh->buf[source]))
+ sh->sources[i] = 0;
+
+ if (OWNERSHIP_DIFFERS (&sh->buf[i], &sh->buf[source]))
+ sh->sources[i] = 0;
}
- for (i =0; i < priv->child_count; i++) {
- if (!sources[i] || i == source)
- continue;
- if (!afr_xattrs_are_equal (replies[source].xdata,
- replies[i].xdata)) {
- gf_log (this->name, GF_LOG_DEBUG, "%s: xattr mismatch "
- "for source(%d) vs (%d)",
- uuid_utoa (replies[source].poststat.ia_gfid),
- source, i);
- sources[i] = 0;
- healed_sinks[i] = 1;
- }
- }
+ afr_sh_metadata_sync_prepare (frame, this);
- return source;
+ return 0;
}
int
-__afr_selfheal_metadata_prepare (call_frame_t *frame, xlator_t *this, inode_t *inode,
- unsigned char *locked_on, unsigned char *sources,
- unsigned char *sinks, unsigned char *healed_sinks,
- struct afr_reply *replies)
+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 stat *buf, dict_t *xattr,
+ struct stat *postparent)
{
- int ret = -1;
- int source = -1;
- afr_private_t *priv = NULL;
- int i = 0;
- uint64_t *witness = NULL;
+ 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;
- ret = afr_selfheal_unlocked_discover (frame, inode, inode->gfid,
- replies);
- if (ret)
- return ret;
-
- witness = alloca0 (sizeof (*witness) * priv->child_count);
- ret = afr_selfheal_find_direction (frame, this, replies,
- AFR_METADATA_TRANSACTION,
- locked_on, sources, sinks, witness);
- if (ret)
- return ret;
-
- /* Initialize the healed_sinks[] array optimistically to
- the intersection of to-be-healed (i.e sinks[]) and
- the list of servers which are up (i.e locked_on[]).
-
- As we encounter failures in the healing process, we
- will unmark the respective servers in the healed_sinks[]
- array.
- */
- AFR_INTERSECT (healed_sinks, sinks, locked_on, priv->child_count);
-
- /* If any source has witness, pick first
- * witness source and make everybody else sinks */
- for (i = 0; i < priv->child_count; i++) {
- if (sources[i] && witness[i]) {
- source = i;
- break;
- }
- }
+ child_index = (long) cookie;
- if (source != -1) {
+ 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->st_mode);
+
+ sh->buf[child_index] = *buf;
+ if (xattr)
+ sh->xattr[child_index] = dict_ref (xattr);
+ } else {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "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);
+
+ call_count = afr_frame_return (frame);
+
+ if (call_count == 0)
+ afr_sh_metadata_fix (frame, this);
+
+ return 0;
+}
+
+
+int
+afr_sh_metadata_lookup (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;
+ int call_count = 0;
+ dict_t *xattr_req = NULL;
+ int ret = 0;
+
+ local = frame->local;
+ sh = &local->self_heal;
+ 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++) {
- if (i != source && sources[i]) {
- sources[i] = 0;
- healed_sinks[i] = 1;
- }
+ ret = dict_set_uint64 (xattr_req,
+ priv->pending_key[i],
+ 3 * sizeof(int32_t));
}
}
- source = __afr_selfheal_metadata_finalize_source (frame, this, sources,
- healed_sinks,
- locked_on, replies);
+ 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;
+}
- if (source < 0)
- return -EIO;
- return source;
+int
+afr_sh_metadata_lk_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;
+ afr_private_t *priv = NULL;
+ int call_count = 0;
+ int child_index = (long) cookie;
+
+ /* TODO: what if lock fails? */
+
+ local = frame->local;
+ sh = &local->self_heal;
+ priv = this->private;
+
+ LOCK (&frame->lock);
+ {
+ if (op_ret == -1) {
+ sh->op_failed = 1;
+
+ sh->locked_nodes[child_index] = 0;
+ gf_log (this->name, GF_LOG_DEBUG,
+ "locking of %s on child %d failed: %s",
+ local->loc.path, child_index,
+ strerror (op_errno));
+ } else {
+ sh->locked_nodes[child_index] = 1;
+ gf_log (this->name, GF_LOG_TRACE,
+ "inode of %s on child %d locked",
+ local->loc.path, child_index);
+ }
+ }
+ UNLOCK (&frame->lock);
+
+ call_count = afr_frame_return (frame);
+
+ if (call_count == 0) {
+ if (sh->op_failed) {
+ afr_sh_metadata_finish (frame, this);
+ return 0;
+ }
+
+ afr_sh_metadata_lookup (frame, this);
+ }
+
+ return 0;
}
+
int
-afr_selfheal_metadata (call_frame_t *frame, xlator_t *this, inode_t *inode)
+afr_sh_metadata_lock (call_frame_t *frame, xlator_t *this)
{
- afr_private_t *priv = NULL;
- int ret = -1;
- unsigned char *sources = NULL;
- unsigned char *sinks = NULL;
- unsigned char *data_lock = NULL;
- unsigned char *healed_sinks = NULL;
- struct afr_reply *locked_replies = NULL;
- gf_boolean_t did_sh = _gf_true;
- int source = -1;
+ afr_local_t *local = NULL;
+ afr_self_heal_t *sh = NULL;
+ afr_private_t *priv = NULL;
+ int i = 0;
+ int call_count = 0;
+ struct flock flock = {0, };
- priv = this->private;
- sources = alloca0 (priv->child_count);
- sinks = alloca0 (priv->child_count);
- healed_sinks = alloca0 (priv->child_count);
- data_lock = alloca0 (priv->child_count);
+ local = frame->local;
+ sh = &local->self_heal;
+ priv = this->private;
- locked_replies = alloca0 (sizeof (*locked_replies) * priv->child_count);
+ call_count = afr_up_children_count (priv->child_count,
+ local->child_up);
+ local->call_count = call_count;
- ret = afr_selfheal_inodelk (frame, this, inode, this->name,
- LLONG_MAX - 1, 0, data_lock);
- {
- if (ret < AFR_SH_MIN_PARTICIPANTS) {
- ret = -ENOTCONN;
- goto unlock;
+ for (i = 0; i < priv->child_count; i++) {
+ flock.l_start = 0;
+ flock.l_len = 0;
+ flock.l_type = F_WRLCK;
+
+ if (local->child_up[i]) {
+ gf_log (this->name, GF_LOG_TRACE,
+ "locking %s on subvolume %s",
+ local->loc.path, priv->children[i]->name);
+
+ STACK_WIND_COOKIE (frame, afr_sh_metadata_lk_cbk,
+ (void *) (long) i,
+ priv->children[i],
+ priv->children[i]->fops->inodelk,
+ this->name,
+ &local->loc, F_SETLK, &flock);
+
+ if (!--call_count)
+ break;
}
+ }
- ret = __afr_selfheal_metadata_prepare (frame, this, inode,
- data_lock, sources,
- sinks, healed_sinks,
- locked_replies);
- if (ret < 0)
- goto unlock;
+ return 0;
+}
- source = ret;
- if (AFR_COUNT (healed_sinks, priv->child_count) == 0) {
- did_sh = _gf_false;
- goto unlock;
- }
+int
+afr_self_heal_metadata (call_frame_t *frame, xlator_t *this)
+{
+ afr_local_t *local = NULL;
+ afr_self_heal_t *sh = NULL;
+ afr_private_t *priv = this->private;
- ret = __afr_selfheal_metadata_do (frame, this, inode, source,
- healed_sinks, locked_replies);
- if (ret)
- goto unlock;
- ret = afr_selfheal_undo_pending (frame, this, inode, sources,
- sinks, healed_sinks,
- AFR_METADATA_TRANSACTION,
- locked_replies, data_lock);
+ local = frame->local;
+ sh = &local->self_heal;
+
+ 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);
}
-unlock:
- afr_selfheal_uninodelk (frame, this, inode, this->name,
- LLONG_MAX -1, 0, data_lock);
-
- if (did_sh)
- afr_log_selfheal (inode->gfid, this, ret, "metadata", source,
- healed_sinks);
- else
- ret = 1;
-
- if (locked_replies)
- afr_replies_wipe (locked_replies, priv->child_count);
- return ret;
+
+ return 0;
}
+
diff --git a/xlators/cluster/afr/src/afr-self-heal-name.c b/xlators/cluster/afr/src/afr-self-heal-name.c
deleted file mode 100644
index af635f06d52..00000000000
--- a/xlators/cluster/afr/src/afr-self-heal-name.c
+++ /dev/null
@@ -1,706 +0,0 @@
-/*
- Copyright (c) 2013 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 "afr-self-heal.h"
-
-int
-__afr_selfheal_assign_gfid (xlator_t *this, inode_t *parent, uuid_t pargfid,
- const char *bname, inode_t *inode,
- struct afr_reply *replies, void *gfid,
- unsigned char *locked_on,
- gf_boolean_t is_gfid_absent)
-{
- int ret = 0;
- int up_count = 0;
- int locked_count = 0;
- afr_private_t *priv = NULL;
- dict_t *xdata = NULL;
- loc_t loc = {0, };
- call_frame_t *new_frame = NULL;
- afr_local_t *new_local = NULL;
-
- priv = this->private;
-
- new_frame = afr_frame_create (this);
- if (!new_frame) {
- ret = -ENOMEM;
- goto out;
- }
-
- new_local = new_frame->local;
-
- uuid_copy (parent->gfid, pargfid);
-
- xdata = dict_new ();
- if (!xdata) {
- ret = -ENOMEM;
- goto out;
- }
-
- ret = dict_set_static_bin (xdata, "gfid-req", gfid, 16);
- if (ret) {
- ret = -ENOMEM;
- goto out;
- }
-
- loc.parent = inode_ref (parent);
- loc.inode = inode_ref (inode);
- uuid_copy (loc.pargfid, pargfid);
- loc.name = bname;
-
- if (is_gfid_absent) {
- /* Ensure all children of AFR are up before performing gfid heal, to
- * guard against the possibility of gfid split brain. */
-
- up_count = AFR_COUNT (priv->child_up, priv->child_count);
- if (up_count != priv->child_count) {
- ret = -EIO;
- goto out;
- }
-
- locked_count = AFR_COUNT (locked_on, priv->child_count);
- if (locked_count != priv->child_count) {
- ret = -EIO;
- goto out;
- }
- }
-
- /* Clear out old replies here and wind lookup on all locked
- * subvolumes to achieve two things:
- * a. gfid heal on those subvolumes that do not have gfid associated
- * with the inode, and
- * b. refresh replies, which can be consumed by
- * __afr_selfheal_name_impunge().
- */
-
- afr_replies_wipe (replies, priv->child_count);
-
- AFR_ONLIST (locked_on, new_frame, afr_selfheal_discover_cbk, lookup,
- &loc, xdata);
-
- afr_replies_copy (replies, new_local->replies, priv->child_count);
-
-out:
- loc_wipe (&loc);
- if (xdata)
- dict_unref (xdata);
- if (new_frame)
- AFR_STACK_DESTROY (new_frame);
-
- return ret;
-}
-
-int
-__afr_selfheal_name_impunge (call_frame_t *frame, xlator_t *this,
- inode_t *parent, uuid_t pargfid,
- const char *bname, inode_t *inode,
- struct afr_reply *replies, int gfid_idx)
-{
- int i = 0;
- afr_private_t *priv = NULL;
- int ret = 0;
- unsigned char *newentry = NULL;
- unsigned char *sources = NULL;
-
- priv = this->private;
-
- newentry = alloca0 (priv->child_count);
- sources = alloca0 (priv->child_count);
-
- uuid_copy (parent->gfid, pargfid);
-
- for (i = 0; i < priv->child_count; i++) {
- if (!replies[i].valid)
- continue;
-
- if (uuid_compare (replies[i].poststat.ia_gfid,
- replies[gfid_idx].poststat.ia_gfid) == 0) {
- sources[i] = 1;
- continue;
- }
-
- ret |= afr_selfheal_recreate_entry (this, i, gfid_idx, parent,
- bname, inode, replies,
- newentry);
- }
-
- if (AFR_COUNT (newentry, priv->child_count))
- afr_selfheal_newentry_mark (frame, this, inode, gfid_idx, replies,
- sources, newentry);
- return ret;
-}
-
-
-int
-__afr_selfheal_name_expunge (xlator_t *this, inode_t *parent, uuid_t pargfid,
- const char *bname, inode_t *inode,
- struct afr_reply *replies)
-{
- loc_t loc = {0, };
- int i = 0;
- afr_private_t *priv = NULL;
- char g[64];
- int ret = 0;
-
- priv = this->private;
-
- loc.parent = inode_ref (parent);
- uuid_copy (loc.pargfid, pargfid);
- loc.name = bname;
- loc.inode = inode_ref (inode);
-
- for (i = 0; i < priv->child_count; i++) {
- if (!replies[i].valid)
- continue;
-
- if (replies[i].op_ret)
- continue;
-
- switch (replies[i].poststat.ia_type) {
- case IA_IFDIR:
- gf_log (this->name, GF_LOG_WARNING,
- "expunging dir %s/%s (%s) on %s",
- uuid_utoa (pargfid), bname,
- uuid_utoa_r (replies[i].poststat.ia_gfid, g),
- priv->children[i]->name);
- ret |= syncop_rmdir (priv->children[i], &loc, 1);
- break;
- default:
- gf_log (this->name, GF_LOG_WARNING,
- "expunging file %s/%s (%s) on %s",
- uuid_utoa (pargfid), bname,
- uuid_utoa_r (replies[i].poststat.ia_gfid, g),
- priv->children[i]->name);
- ret |= syncop_unlink (priv->children[i], &loc);
- break;
- }
- }
-
- loc_wipe (&loc);
-
- return ret;
-
-}
-
-/* This function is to be called after ensuring that there is no gfid mismatch
- * for the inode across multiple sources
- */
-static int
-afr_selfheal_gfid_idx_get (xlator_t *this, struct afr_reply *replies,
- unsigned char *sources)
-{
- int i = 0;
- int gfid_idx = -1;
- afr_private_t *priv = NULL;
-
- priv = this->private;
-
- for (i = 0; i < priv->child_count; i++) {
- if (!replies[i].valid)
- continue;
-
- if (!sources[i])
- continue;
-
- if (uuid_is_null (replies[i].poststat.ia_gfid))
- continue;
-
- gfid_idx = i;
- break;
- }
- return gfid_idx;
-}
-
-static gf_boolean_t
-afr_selfheal_name_need_heal_check (xlator_t *this, struct afr_reply *replies)
-{
- int i = 0;
- int first_idx = -1;
- gf_boolean_t need_heal = _gf_false;
- afr_private_t *priv = NULL;
-
- priv = this->private;
-
- for (i = 0; i < priv->child_count; i++) {
- if (!replies[i].valid)
- continue;
-
- if ((replies[i].op_ret == -1) &&
- (replies[i].op_errno == ENODATA))
- need_heal = _gf_true;
-
- if (first_idx == -1) {
- first_idx = i;
- continue;
- }
-
- if (replies[i].op_ret != replies[first_idx].op_ret)
- need_heal = _gf_true;
-
- if (uuid_compare (replies[i].poststat.ia_gfid,
- replies[first_idx].poststat.ia_gfid))
- need_heal = _gf_true;
-
- if ((replies[i].op_ret == 0) &&
- (uuid_is_null(replies[i].poststat.ia_gfid)))
- need_heal = _gf_true;
-
- }
-
- return need_heal;
-}
-
-static int
-afr_selfheal_name_type_mismatch_check (xlator_t *this, struct afr_reply *replies,
- int source, unsigned char *sources,
- uuid_t pargfid, const char *bname)
-{
- int i = 0;
- int type_idx = -1;
- ia_type_t inode_type = IA_INVAL;
- afr_private_t *priv = NULL;
-
- priv = this->private;
-
- for (i = 0; i < priv->child_count; i++) {
- if (!replies[i].valid)
- continue;
-
- if (replies[i].poststat.ia_type == IA_INVAL)
- continue;
-
- if (inode_type == IA_INVAL) {
- inode_type = replies[i].poststat.ia_type;
- type_idx = i;
- continue;
- }
-
- if (sources[i] || source == -1) {
- if ((sources[type_idx] || source == -1) &&
- (inode_type != replies[i].poststat.ia_type)) {
- gf_msg (this->name, GF_LOG_WARNING, 0,
- AFR_MSG_SPLIT_BRAIN,
- "Type mismatch for <gfid:%s>/%s: "
- "%d on %s and %d on %s",
- uuid_utoa(pargfid), bname,
- replies[i].poststat.ia_type,
- priv->children[i]->name,
- replies[type_idx].poststat.ia_type,
- priv->children[type_idx]->name);
- return -EIO;
- }
- inode_type = replies[i].poststat.ia_type;
- type_idx = i;
- }
- }
- return 0;
-}
-
-static int
-afr_selfheal_name_gfid_mismatch_check (xlator_t *this, struct afr_reply *replies,
- int source, unsigned char *sources,
- int *gfid_idx, uuid_t pargfid,
- const char *bname)
-{
- int i = 0;
- int gfid_idx_iter = -1;
- void *gfid = NULL;
- afr_private_t *priv = NULL;
- char g1[64], g2[64];
-
- priv = this->private;
-
- for (i = 0; i < priv->child_count; i++) {
- if (!replies[i].valid)
- continue;
-
- if (uuid_is_null (replies[i].poststat.ia_gfid))
- continue;
-
- if (!gfid) {
- gfid = &replies[i].poststat.ia_gfid;
- gfid_idx_iter = i;
- continue;
- }
-
- if (sources[i] || source == -1) {
- if ((sources[gfid_idx_iter] || source == -1) &&
- uuid_compare (gfid, replies[i].poststat.ia_gfid)) {
- gf_msg (this->name, GF_LOG_WARNING, 0,
- AFR_MSG_SPLIT_BRAIN,
- "GFID mismatch for <gfid:%s>/%s "
- "%s on %s and %s on %s",
- uuid_utoa (pargfid), bname,
- uuid_utoa_r (replies[i].poststat.ia_gfid, g1),
- priv->children[i]->name,
- uuid_utoa_r (replies[gfid_idx_iter].poststat.ia_gfid, g2),
- priv->children[gfid_idx_iter]->name);
- return -EIO;
- }
-
- gfid = &replies[i].poststat.ia_gfid;
- gfid_idx_iter = i;
- }
- }
-
- *gfid_idx = gfid_idx_iter;
- return 0;
-}
-
-static gf_boolean_t
-afr_selfheal_name_source_empty_check (xlator_t *this, struct afr_reply *replies,
- unsigned char *sources, int source)
-{
- int i = 0;
- afr_private_t *priv = NULL;
- gf_boolean_t source_is_empty = _gf_true;
-
- priv = this->private;
-
- if (source == -1) {
- source_is_empty = _gf_false;
- goto out;
- }
-
- for (i = 0; i < priv->child_count; i++) {
- if (!sources[i])
- continue;
-
- if (replies[i].op_ret == -1 && replies[i].op_errno == ENOENT)
- continue;
-
- source_is_empty = _gf_false;
- break;
- }
-out:
- return source_is_empty;
-}
-
-int
-__afr_selfheal_name_do (call_frame_t *frame, xlator_t *this, inode_t *parent,
- uuid_t pargfid, const char *bname, inode_t *inode,
- unsigned char *sources, unsigned char *sinks,
- unsigned char *healed_sinks, int source,
- unsigned char *locked_on, struct afr_reply *replies,
- void *gfid_req)
-{
- int gfid_idx = -1;
- int ret = -1;
- void *gfid = NULL;
- gf_boolean_t source_is_empty = _gf_true;
- gf_boolean_t need_heal = _gf_false;
- gf_boolean_t is_gfid_absent = _gf_false;
-
- need_heal = afr_selfheal_name_need_heal_check (this, replies);
- if (!need_heal)
- return 0;
-
- source_is_empty = afr_selfheal_name_source_empty_check (this, replies,
- sources,
- source);
- if (source_is_empty)
- return __afr_selfheal_name_expunge (this, parent, pargfid,
- bname, inode, replies);
-
- ret = afr_selfheal_name_type_mismatch_check (this, replies, source,
- sources, pargfid, bname);
- if (ret)
- return ret;
-
- ret = afr_selfheal_name_gfid_mismatch_check (this, replies, source,
- sources, &gfid_idx,
- pargfid, bname);
- if (ret)
- return ret;
-
- if (gfid_idx == -1) {
- if (!gfid_req || uuid_is_null (gfid_req))
- return -1;
- gfid = gfid_req;
- } else {
- gfid = &replies[gfid_idx].poststat.ia_gfid;
- }
-
- is_gfid_absent = (gfid_idx == -1) ? _gf_true : _gf_false;
- ret = __afr_selfheal_assign_gfid (this, parent, pargfid, bname, inode,
- replies, gfid, locked_on,
- is_gfid_absent);
- if (ret)
- return ret;
-
- if (gfid_idx == -1) {
- gfid_idx = afr_selfheal_gfid_idx_get (this, replies, sources);
- if (gfid_idx == -1)
- return -1;
- }
-
- return __afr_selfheal_name_impunge (frame, this, parent, pargfid,
- bname, inode,
- replies, gfid_idx);
-}
-
-
-int
-__afr_selfheal_name_finalize_source (xlator_t *this, unsigned char *sources,
- unsigned char *healed_sinks,
- unsigned char *locked_on,
- struct afr_reply *replies,
- uint64_t *witness)
-{
- int i = 0;
- afr_private_t *priv = NULL;
- int source = -1;
- int sources_count = 0;
-
- priv = this->private;
-
- sources_count = AFR_COUNT (sources, priv->child_count);
-
- if ((AFR_CMP (locked_on, healed_sinks, priv->child_count) == 0)
- || !sources_count || afr_does_witness_exist (this, witness)) {
- memset (sources, 0, sizeof (*sources) * priv->child_count);
- afr_mark_active_sinks (this, sources, locked_on, healed_sinks);
- return -1;
- }
-
- for (i = 0; i < priv->child_count; i++) {
- if (sources[i]) {
- source = i;
- break;
- }
- }
-
- return source;
-}
-
-int
-__afr_selfheal_name_prepare (call_frame_t *frame, xlator_t *this, inode_t *parent,
- uuid_t pargfid, unsigned char *locked_on,
- unsigned char *sources, unsigned char *sinks,
- unsigned char *healed_sinks, int *source_p)
-{
- int ret = -1;
- int source = -1;
- afr_private_t *priv = NULL;
- struct afr_reply *replies = NULL;
- uint64_t *witness = NULL;
-
- priv = this->private;
-
- replies = alloca0 (priv->child_count * sizeof(*replies));
-
- ret = afr_selfheal_unlocked_discover (frame, parent, pargfid, replies);
- if (ret)
- goto out;
-
- witness = alloca0 (sizeof (*witness) * priv->child_count);
- ret = afr_selfheal_find_direction (frame, this, replies,
- AFR_ENTRY_TRANSACTION,
- locked_on, sources, sinks, witness);
- if (ret)
- goto out;
-
- /* Initialize the healed_sinks[] array optimistically to
- the intersection of to-be-healed (i.e sinks[]) and
- the list of servers which are up (i.e locked_on[]).
-
- As we encounter failures in the healing process, we
- will unmark the respective servers in the healed_sinks[]
- array.
- */
- AFR_INTERSECT (healed_sinks, sinks, locked_on, priv->child_count);
-
- source = __afr_selfheal_name_finalize_source (this, sources,
- healed_sinks,
- locked_on, replies,
- witness);
- if (source < 0) {
- /* If source is < 0 (typically split-brain), we perform a
- conservative merge of entries rather than erroring out */
- }
- *source_p = source;
-
-out:
- if (replies)
- afr_replies_wipe (replies, priv->child_count);
-
- return ret;
-}
-
-
-int
-afr_selfheal_name_do (call_frame_t *frame, xlator_t *this, inode_t *parent,
- uuid_t pargfid, const char *bname, void *gfid_req)
-{
- afr_private_t *priv = NULL;
- unsigned char *sources = NULL;
- unsigned char *sinks = NULL;
- unsigned char *healed_sinks = NULL;
- unsigned char *locked_on = NULL;
- int source = -1;
- struct afr_reply *replies = NULL;
- int ret = -1;
- inode_t *inode = NULL;
- dict_t *xattr = NULL;
-
- xattr = dict_new ();
- if (!xattr)
- return -ENOMEM;
-
- ret = dict_set_int32 (xattr, GF_GFIDLESS_LOOKUP, 1);
- if (ret) {
- dict_destroy (xattr);
- return -1;
- }
-
- priv = this->private;
-
- locked_on = alloca0 (priv->child_count);
- sources = alloca0 (priv->child_count);
- sinks = alloca0 (priv->child_count);
- healed_sinks = alloca0 (priv->child_count);
-
- replies = alloca0 (priv->child_count * sizeof(*replies));
-
- ret = afr_selfheal_entrylk (frame, this, parent, this->name, bname,
- locked_on);
- {
- if (ret < AFR_SH_MIN_PARTICIPANTS) {
- ret = -ENOTCONN;
- goto unlock;
- }
-
- ret = __afr_selfheal_name_prepare (frame, this, parent, pargfid,
- locked_on, sources, sinks,
- healed_sinks, &source);
- if (ret)
- goto unlock;
-
- inode = afr_selfheal_unlocked_lookup_on (frame, parent, bname,
- replies, locked_on,
- xattr);
- if (!inode) {
- ret = -ENOMEM;
- goto unlock;
- }
-
- ret = __afr_selfheal_name_do (frame, this, parent, pargfid,
- bname, inode, sources, sinks,
- healed_sinks, source, locked_on,
- replies, gfid_req);
- }
-unlock:
- afr_selfheal_unentrylk (frame, this, parent, this->name, bname,
- locked_on);
- if (inode)
- inode_unref (inode);
-
- if (replies)
- afr_replies_wipe (replies, priv->child_count);
- if (xattr)
- dict_unref (xattr);
-
- return ret;
-}
-
-
-int
-afr_selfheal_name_unlocked_inspect (call_frame_t *frame, xlator_t *this,
- inode_t *parent, uuid_t pargfid,
- const char *bname, gf_boolean_t *need_heal)
-{
- afr_private_t *priv = NULL;
- int i = 0;
- struct afr_reply *replies = NULL;
- inode_t *inode = NULL;
- int first_idx = -1;
-
- priv = this->private;
-
- replies = alloca0 (sizeof (*replies) * priv->child_count);
-
- inode = afr_selfheal_unlocked_lookup_on (frame, parent, bname,
- replies, priv->child_up, NULL);
- if (!inode)
- return -ENOMEM;
-
- for (i = 0; i < priv->child_count; i++) {
- if (!replies[i].valid)
- continue;
-
- if ((replies[i].op_ret == -1) &&
- (replies[i].op_errno == ENODATA))
- *need_heal = _gf_true;
-
- if (first_idx == -1) {
- first_idx = i;
- continue;
- }
-
- if (replies[i].op_ret != replies[first_idx].op_ret)
- *need_heal = _gf_true;
-
- if (uuid_compare (replies[i].poststat.ia_gfid,
- replies[first_idx].poststat.ia_gfid))
- *need_heal = _gf_true;
- }
-
- if (inode)
- inode_unref (inode);
- if (replies)
- afr_replies_wipe (replies, priv->child_count);
- return 0;
-}
-
-int
-afr_selfheal_name (xlator_t *this, uuid_t pargfid, const char *bname,
- void *gfid_req)
-{
- inode_t *parent = NULL;
- call_frame_t *frame = NULL;
- int ret = -1;
- gf_boolean_t need_heal = _gf_false;
-
- parent = afr_inode_find (this, pargfid);
- if (!parent)
- goto out;
-
- frame = afr_frame_create (this);
- if (!frame)
- goto out;
-
- ret = afr_selfheal_name_unlocked_inspect (frame, this, parent, pargfid,
- bname, &need_heal);
- if (ret)
- goto out;
-
- if (need_heal) {
- ret = afr_selfheal_name_do (frame, this, parent, pargfid, bname,
- gfid_req);
- if (ret)
- goto out;
- }
-
- ret = 0;
-out:
- if (parent)
- inode_unref (parent);
- if (frame)
- AFR_STACK_DESTROY (frame);
-
- return ret;
-}
diff --git a/xlators/cluster/afr/src/afr-self-heal.h b/xlators/cluster/afr/src/afr-self-heal.h
index 026e249549e..1c2743a48da 100644
--- a/xlators/cluster/afr/src/afr-self-heal.h
+++ b/xlators/cluster/afr/src/afr-self-heal.h
@@ -1,233 +1,54 @@
/*
- Copyright (c) 2013 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-2009 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 __AFR_SELF_HEAL_H__
+#define __AFR_SELF_HEAL_H__
-#ifndef _AFR_SELFHEAL_H
-#define _AFR_SELFHEAL_H
-
-#define AFR_SH_MIN_PARTICIPANTS 2
-
-/* Perform fop on all UP subvolumes and wait for all callbacks to return */
-
-#define AFR_ONALL(frame, rfn, fop, args ...) do { \
- afr_local_t *__local = frame->local; \
- afr_private_t *__priv = frame->this->private; \
- int __i = 0, __count = 0; \
- \
- afr_local_replies_wipe (__local, __priv); \
- \
- for (__i = 0; __i < __priv->child_count; __i++) { \
- if (!__priv->child_up[__i]) continue; \
- STACK_WIND_COOKIE (frame, rfn, (void *)(long) __i, \
- __priv->children[__i], \
- __priv->children[__i]->fops->fop, args); \
- __count++; \
- } \
- syncbarrier_wait (&__local->barrier, __count); \
- } while (0)
-
-
-/* Perform fop on all subvolumes represented by list[] array and wait
- for all callbacks to return */
-
-#define AFR_ONLIST(list, frame, rfn, fop, args ...) do { \
- afr_local_t *__local = frame->local; \
- afr_private_t *__priv = frame->this->private; \
- int __i = 0, __count = 0; \
- \
- afr_local_replies_wipe (__local, __priv); \
- \
- for (__i = 0; __i < __priv->child_count; __i++) { \
- if (!list[__i]) continue; \
- STACK_WIND_COOKIE (frame, rfn, (void *)(long) __i, \
- __priv->children[__i], \
- __priv->children[__i]->fops->fop, args); \
- __count++; \
- } \
- syncbarrier_wait (&__local->barrier, __count); \
- } while (0)
-
-
-#define AFR_SEQ(frame, rfn, fop, args ...) do { \
- afr_local_t *__local = frame->local; \
- afr_private_t *__priv = frame->this->private; \
- int __i = 0; \
- \
- afr_local_replies_wipe (__local, __priv); \
- \
- for (__i = 0; __i < __priv->child_count; __i++) { \
- if (!__priv->child_up[__i]) continue; \
- STACK_WIND_COOKIE (frame, rfn, (void *)(long) __i, \
- __priv->children[__i], \
- __priv->children[__i]->fops->fop, args); \
- syncbarrier_wait (&__local->barrier, 1); \
- } \
- } while (0)
-
-
-#define ALLOC_MATRIX(n, type) ({type **__ptr = NULL; \
- int __i; \
- __ptr = alloca0 (n * sizeof(type *)); \
- for (__i = 0; __i < n; __i++) __ptr[__i] = alloca0 (n * sizeof(type)); \
- __ptr;})
-
-
-#define IA_EQUAL(f,s,field) (memcmp (&(f.ia_##field), &(s.ia_##field), sizeof (s.ia_##field)) == 0)
-
-
-int
-afr_selfheal (xlator_t *this, uuid_t gfid);
-
-int
-afr_selfheal_name (xlator_t *this, uuid_t gfid, const char *name,
- void *gfid_req);
-
-int
-afr_selfheal_data (call_frame_t *frame, xlator_t *this, inode_t *inode);
-
-int
-afr_selfheal_metadata (call_frame_t *frame, xlator_t *this, inode_t *inode);
-
-int
-afr_selfheal_entry (call_frame_t *frame, xlator_t *this, inode_t *inode);
-
-
-int
-afr_selfheal_inodelk (call_frame_t *frame, xlator_t *this, inode_t *inode,
- char *dom, off_t off, size_t size,
- unsigned char *locked_on);
-
-int
-afr_selfheal_tryinodelk (call_frame_t *frame, xlator_t *this, inode_t *inode,
- char *dom, off_t off, size_t size,
- unsigned char *locked_on);
-
-int
-afr_selfheal_uninodelk (call_frame_t *frame, xlator_t *this, inode_t *inode,
- char *dom, off_t off, size_t size,
- const unsigned char *locked_on);
+#include <sys/stat.h>
-int
-afr_selfheal_entrylk (call_frame_t *frame, xlator_t *this, inode_t *inode,
- char *dom, const char *name, unsigned char *locked_on);
-
-int
-afr_selfheal_tryentrylk (call_frame_t *frame, xlator_t *this, inode_t *inode,
- char *dom, const char *name, unsigned char *locked_on);
+#define FILETYPE_DIFFERS(buf1,buf2) ((S_IFMT & ((struct stat *)buf1)->st_mode) != (S_IFMT & ((struct stat *)buf2)->st_mode))
+#define PERMISSION_DIFFERS(buf1,buf2) ((((struct stat *)buf1)->st_mode) != (((struct stat *)buf2)->st_mode))
+#define OWNERSHIP_DIFFERS(buf1,buf2) ((((struct stat *)buf1)->st_uid) != (((struct stat *)buf2)->st_uid) || (((struct stat *)buf1)->st_gid != (((struct stat *)buf2)->st_gid)))
+#define SIZE_DIFFERS(buf1,buf2) ((((struct stat *)buf1)->st_size) != (((struct stat *)buf2)->st_size))
-int
-afr_selfheal_unentrylk (call_frame_t *frame, xlator_t *this, inode_t *inode,
- char *dom, const char *name, unsigned char *locked_on);
+#define SIZE_GREATER(buf1,buf2) ((((struct stat *)buf1)->st_size > (((struct stat *)buf2)->st_size)))
int
-afr_selfheal_unlocked_discover (call_frame_t *frame, inode_t *inode,
- uuid_t gfid, struct afr_reply *replies);
-
-inode_t *
-afr_selfheal_unlocked_lookup_on (call_frame_t *frame, inode_t *parent,
- const char *name, struct afr_reply *replies,
- unsigned char *lookup_on, dict_t *xattr);
-
+afr_sh_has_metadata_pending (dict_t *xattr, int child_count, xlator_t *this);
int
-afr_selfheal_find_direction (call_frame_t *frame, xlator_t *this,
- struct afr_reply *replies,
- afr_transaction_type type,
- unsigned char *locked_on, unsigned char *sources,
- unsigned char *sinks, uint64_t *witness);
-
+afr_sh_has_entry_pending (dict_t *xattr, int child_count, xlator_t *this);
int
-afr_selfheal_extract_xattr (xlator_t *this, struct afr_reply *replies,
- afr_transaction_type type, int *dirty, int **matrix);
+afr_sh_has_data_pending (dict_t *xattr, int child_count, xlator_t *this);
int
-afr_selfheal_undo_pending (call_frame_t *frame, xlator_t *this, inode_t *inode,
- unsigned char *sources, unsigned char *sinks,
- unsigned char *healed_sinks, afr_transaction_type type,
- struct afr_reply *replies, unsigned char *locked_on);
+afr_self_heal_entry (call_frame_t *frame, xlator_t *this);
int
-afr_selfheal_recreate_entry (xlator_t *this, int dst, int source, inode_t *dir,
- const char *name, inode_t *inode,
- struct afr_reply *replies,
- unsigned char *newentry);
+afr_self_heal_data (call_frame_t *frame, xlator_t *this);
int
-afr_selfheal_post_op (call_frame_t *frame, xlator_t *this, inode_t *inode,
- int subvol, dict_t *xattr);
-
-call_frame_t *
-afr_frame_create (xlator_t *this);
-
-inode_t *
-afr_inode_find (xlator_t *this, uuid_t gfid);
+afr_self_heal_metadata (call_frame_t *frame, xlator_t *this);
int
-afr_selfheal_discover_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 *parbuf);
-
-void
-afr_replies_copy (struct afr_reply *dst, struct afr_reply *src, int count);
+afr_self_heal_get_source (xlator_t *this, afr_local_t *local, dict_t **xattr);
int
-afr_selfheal_newentry_mark (call_frame_t *frame, xlator_t *this, inode_t *inode,
- int source, struct afr_reply *replies,
- unsigned char *sources, unsigned char *newentry);
+afr_self_heal (call_frame_t *frame, xlator_t *this);
-inode_t*
-afr_inode_link (inode_t *inode, struct iatt *iatt);
-
-unsigned int
-afr_success_count (struct afr_reply *replies, unsigned int count);
-
-void
-afr_log_selfheal (uuid_t gfid, xlator_t *this, int ret, char *type,
- int source, unsigned char *healed_sinks);
-
-void
-afr_mark_active_sinks (xlator_t *this, unsigned char *sources,
- unsigned char *locked_on, unsigned char *sinks);
-
-gf_boolean_t
-afr_does_witness_exist (xlator_t *this, uint64_t *witness);
-
-int
-__afr_selfheal_data_prepare (call_frame_t *frame, xlator_t *this,
- inode_t *inode, unsigned char *locked_on,
- unsigned char *sources,
- unsigned char *sinks, unsigned char *healed_sinks,
- struct afr_reply *replies);
-
-int
-__afr_selfheal_metadata_prepare (call_frame_t *frame, xlator_t *this,
- inode_t *inode, unsigned char *locked_on,
- unsigned char *sources,
- unsigned char *sinks,
- unsigned char *healed_sinks,
- struct afr_reply *replies);
-int
-__afr_selfheal_entry_prepare (call_frame_t *frame, xlator_t *this,
- inode_t *inode, unsigned char *locked_on,
- unsigned char *sources,
- unsigned char *sinks,
- unsigned char *healed_sinks,
- struct afr_reply *replies, int *source_p);
-
-int
-afr_selfheal_unlocked_inspect (call_frame_t *frame, xlator_t *this,
- uuid_t gfid, inode_t **link_inode,
- gf_boolean_t *data_selfheal,
- gf_boolean_t *metadata_selfheal,
- gf_boolean_t *entry_selfheal);
-
-int
-afr_selfheal_do (call_frame_t *frame, xlator_t *this, uuid_t gfid);
-#endif /* !_AFR_SELFHEAL_H */
+#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 7c235aca429..00000000000
--- a/xlators/cluster/afr/src/afr-self-heald.c
+++ /dev/null
@@ -1,1408 +0,0 @@
-/*
- Copyright (c) 2013 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 "afr-self-heal.h"
-#include "afr-self-heald.h"
-#include "protocol-common.h"
-
-#define SHD_INODE_LRU_LIMIT 2048
-#define AFR_EH_SPLIT_BRAIN_LIMIT 1024
-#define AFR_STATISTICS_HISTORY_SIZE 50
-
-
-#define ASSERT_LOCAL(this, healer) \
- if (!afr_shd_is_subvol_local(this, healer->subvol)) { \
- healer->local = _gf_false; \
- if (safe_break (healer)) { \
- break; \
- } else { \
- continue; \
- } \
- } else { \
- healer->local = _gf_true; \
- }
-
-
-#define NTH_INDEX_HEALER(this, n) &((((afr_private_t *)this->private))->shd.index_healers[n])
-#define NTH_FULL_HEALER(this, n) &((((afr_private_t *)this->private))->shd.full_healers[n])
-
-char *
-afr_subvol_name (xlator_t *this, int subvol)
-{
- afr_private_t *priv = NULL;
-
- priv = this->private;
- if (subvol < 0 || subvol > priv->child_count)
- return NULL;
-
- return priv->children[subvol]->name;
-}
-
-
-void
-afr_destroy_crawl_event_data (void *data)
-{
- return;
-}
-
-
-void
-afr_destroy_shd_event_data (void *data)
-{
- shd_event_t *shd_event = data;
-
- if (!shd_event)
- return;
- GF_FREE (shd_event->path);
-
- return;
-}
-
-
-gf_boolean_t
-afr_shd_is_subvol_local (xlator_t *this, int subvol)
-{
- char *pathinfo = NULL;
- afr_private_t *priv = NULL;
- dict_t *xattr = NULL;
- int ret = 0;
- gf_boolean_t is_local = _gf_false;
- loc_t loc = {0, };
-
- priv = this->private;
-
- loc.inode = this->itable->root;
- uuid_copy (loc.gfid, loc.inode->gfid);
-
- ret = syncop_getxattr (priv->children[subvol], &loc, &xattr,
- GF_XATTR_PATHINFO_KEY);
- if (ret) {
- is_local = _gf_false;
- goto out;
- }
-
- if (!xattr) {
- is_local = _gf_false;
- goto out;
- }
-
- ret = dict_get_str (xattr, GF_XATTR_PATHINFO_KEY, &pathinfo);
- if (ret) {
- is_local = _gf_false;
- goto out;
- }
-
- afr_local_pathinfo (pathinfo, &is_local);
-
- gf_log (this->name, GF_LOG_DEBUG, "subvol %s is %slocal",
- priv->children[subvol]->name, is_local? "" : "not ");
-
-out:
- if (xattr)
- dict_unref (xattr);
-
- return is_local;
-}
-
-
-int
-__afr_shd_healer_wait (struct subvol_healer *healer)
-{
- afr_private_t *priv = NULL;
- struct timespec wait_till = {0, };
- int ret = 0;
-
- priv = healer->this->private;
-
-disabled_loop:
- wait_till.tv_sec = time (NULL) + 60;
-
- while (!healer->rerun) {
- ret = pthread_cond_timedwait (&healer->cond,
- &healer->mutex,
- &wait_till);
- if (ret == ETIMEDOUT)
- break;
- }
-
- ret = healer->rerun;
- healer->rerun = 0;
-
- if (!priv->shd.enabled)
- goto disabled_loop;
-
- return ret;
-}
-
-
-int
-afr_shd_healer_wait (struct subvol_healer *healer)
-{
- int ret = 0;
-
- pthread_mutex_lock (&healer->mutex);
- {
- ret = __afr_shd_healer_wait (healer);
- }
- pthread_mutex_unlock (&healer->mutex);
-
- return ret;
-}
-
-
-gf_boolean_t
-safe_break (struct subvol_healer *healer)
-{
- gf_boolean_t ret = _gf_false;
-
- pthread_mutex_lock (&healer->mutex);
- {
- if (healer->rerun)
- goto unlock;
-
- healer->running = _gf_false;
- ret = _gf_true;
- }
-unlock:
- pthread_mutex_unlock (&healer->mutex);
-
- return ret;
-}
-
-
-inode_t *
-afr_shd_inode_find (xlator_t *this, xlator_t *subvol, uuid_t gfid)
-{
- inode_t *inode = NULL;
- int ret = 0;
- loc_t loc = {0, };
- struct iatt iatt = {0, };
-
- inode = inode_find (this->itable, gfid);
- if (inode) {
- inode_lookup (inode);
- goto out;
- }
-
- loc.inode = inode_new (this->itable);
- if (!loc.inode)
- goto out;
- uuid_copy (loc.gfid, gfid);
-
- ret = syncop_lookup (subvol, &loc, NULL, &iatt, NULL, NULL);
- if (ret < 0)
- goto out;
-
- inode = inode_link (loc.inode, NULL, NULL, &iatt);
- if (inode)
- inode_lookup (inode);
-out:
- loc_wipe (&loc);
- return inode;
-}
-
-
-fd_t *
-afr_shd_index_opendir (xlator_t *this, int child)
-{
- fd_t *fd = NULL;
- afr_private_t *priv = NULL;
- xlator_t *subvol = NULL;
- loc_t rootloc = {0, };
- inode_t *inode = NULL;
- int ret = 0;
- dict_t *xattr = NULL;
- void *index_gfid = NULL;
- loc_t loc = {0, };
-
- priv = this->private;
- subvol = priv->children[child];
-
- rootloc.inode = inode_ref (this->itable->root);
- uuid_copy (rootloc.gfid, rootloc.inode->gfid);
-
- ret = syncop_getxattr (subvol, &rootloc, &xattr,
- GF_XATTROP_INDEX_GFID);
- if (ret || !xattr) {
- errno = -ret;
- goto out;
- }
-
- ret = dict_get_ptr (xattr, GF_XATTROP_INDEX_GFID, &index_gfid);
- if (ret)
- goto out;
-
- gf_log (this->name, GF_LOG_DEBUG, "index-dir gfid for %s: %s",
- subvol->name, uuid_utoa (index_gfid));
-
- inode = afr_shd_inode_find (this, subvol, index_gfid);
- if (!inode)
- goto out;
-
- fd = fd_create (inode, GF_CLIENT_PID_AFR_SELF_HEALD);
- if (!fd)
- goto out;
-
- uuid_copy (loc.gfid, index_gfid);
- loc.inode = inode;
-
- ret = syncop_opendir(this, &loc, fd);
- if (ret) {
- /*
- * On Linux, if the brick was not updated, opendir will
- * fail. We therefore use backward compatible code
- * that violate the standards by reusing offsets
- * in seekdir() from different DIR *, but it works on Linux.
- *
- * On other systems it never worked, hence we do not need
- * to provide backward-compatibility.
- */
-#ifdef GF_LINUX_HOST_OS
- fd_unref (fd);
- fd = fd_anonymous (inode);
- if (!fd)
- goto out;
-#else /* GF_LINUX_HOST_OS */
- gf_log(this->name, GF_LOG_ERROR,
- "opendir of %s for %s failed: %s",
- uuid_utoa (index_gfid), subvol->name, strerror(errno));
- fd_unref (fd);
- fd = NULL;
- goto out;
-#endif /* GF_LINUX_HOST_OS */
- }
-
-out:
- loc_wipe (&rootloc);
-
- if (inode)
- inode_unref (inode);
-
- if (xattr)
- dict_unref (xattr);
- return fd;
-}
-
-
-int
-afr_shd_index_purge (xlator_t *subvol, inode_t *inode, char *name)
-{
- loc_t loc = {0, };
- int ret = 0;
-
- loc.parent = inode_ref (inode);
- loc.name = name;
-
- ret = syncop_unlink (subvol, &loc);
-
- loc_wipe (&loc);
- return ret;
-}
-
-void
-afr_shd_zero_xattrop (xlator_t *this, uuid_t gfid)
-{
-
- call_frame_t *frame = NULL;
- inode_t *inode = NULL;
- afr_private_t *priv = NULL;
- dict_t *xattr = NULL;
- int ret = 0;
- int i = 0;
- int raw[AFR_NUM_CHANGE_LOGS] = {0};
-
- priv = this->private;
- frame = afr_frame_create (this);
- if (!frame)
- goto out;
- inode = afr_inode_find (this, gfid);
- if (!inode)
- goto out;
- xattr = dict_new();
- if (!xattr)
- goto out;
- ret = dict_set_static_bin (xattr, AFR_DIRTY, raw,
- sizeof(int) * AFR_NUM_CHANGE_LOGS);
- if (ret)
- goto out;
- for (i = 0; i < priv->child_count; i++) {
- ret = dict_set_static_bin (xattr, priv->pending_key[i], raw,
- sizeof(int) * AFR_NUM_CHANGE_LOGS);
- if (ret)
- goto out;
- }
-
- /*Send xattrop to all bricks. Doing a lookup to see if bricks are up or
- * has valid repies for this gfid seems a bit of an overkill.*/
- for (i = 0; i < priv->child_count; i++)
- afr_selfheal_post_op (frame, this, inode, i, xattr);
-
-out:
- if (frame)
- AFR_STACK_DESTROY (frame);
- if (inode)
- inode_unref (inode);
- if (xattr)
- dict_unref (xattr);
- return;
-}
-
-int
-afr_shd_selfheal_name (struct subvol_healer *healer, int child, uuid_t parent,
- const char *bname)
-{
- int ret = -1;
-
- ret = afr_selfheal_name (THIS, parent, bname, NULL);
-
- return ret;
-}
-
-int
-afr_shd_selfheal (struct subvol_healer *healer, int child, uuid_t gfid)
-{
- int ret = 0;
- eh_t *eh = NULL;
- afr_private_t *priv = NULL;
- afr_self_heald_t *shd = NULL;
- shd_event_t *shd_event = NULL;
- char *path = NULL;
- xlator_t *subvol = NULL;
- xlator_t *this = NULL;
- crawl_event_t *crawl_event = NULL;
-
- this = healer->this;
- priv = this->private;
- shd = &priv->shd;
- crawl_event = &healer->crawl_event;
-
- subvol = priv->children[child];
-
- //If this fails with ENOENT/ESTALE index is stale
- ret = afr_shd_gfid_to_path (this, subvol, gfid, &path);
- if (ret < 0)
- return ret;
-
- ret = afr_selfheal (this, gfid);
-
- if (ret == -EIO) {
- eh = shd->split_brain;
- crawl_event->split_brain_count++;
- } else if (ret < 0) {
- crawl_event->heal_failed_count++;
- } else if (ret == 0) {
- crawl_event->healed_count++;
- }
-
- if (eh) {
- shd_event = GF_CALLOC (1, sizeof(*shd_event),
- gf_afr_mt_shd_event_t);
- if (!shd_event)
- goto out;
-
- shd_event->child = child;
- shd_event->path = path;
-
- if (eh_save_history (eh, shd_event) < 0)
- goto out;
-
- shd_event = NULL;
- path = NULL;
- }
-out:
- GF_FREE (shd_event);
- GF_FREE (path);
- return ret;
-}
-
-
-void
-afr_shd_sweep_prepare (struct subvol_healer *healer)
-{
- crawl_event_t *event = NULL;
-
- event = &healer->crawl_event;
-
- event->healed_count = 0;
- event->split_brain_count = 0;
- event->heal_failed_count = 0;
-
- time (&event->start_time);
- event->end_time = 0;
-}
-
-
-void
-afr_shd_sweep_done (struct subvol_healer *healer)
-{
- crawl_event_t *event = NULL;
- crawl_event_t *history = NULL;
- afr_self_heald_t *shd = NULL;
-
- event = &healer->crawl_event;
- shd = &(((afr_private_t *)healer->this->private)->shd);
-
- time (&event->end_time);
- history = memdup (event, sizeof (*event));
- event->start_time = 0;
-
- if (!history)
- return;
-
- if (eh_save_history (shd->statistics[healer->subvol], history) < 0)
- GF_FREE (history);
-}
-
-
-int
-afr_shd_index_sweep (struct subvol_healer *healer)
-{
- xlator_t *this = NULL;
- int child = -1;
- fd_t *fd = NULL;
- xlator_t *subvol = NULL;
- afr_private_t *priv = NULL;
- uint64_t offset = 0;
- gf_dirent_t entries;
- gf_dirent_t *entry = NULL;
- uuid_t gfid;
- int ret = 0;
- int count = 0;
-
- this = healer->this;
- child = healer->subvol;
- priv = this->private;
- subvol = priv->children[child];
-
- fd = afr_shd_index_opendir (this, child);
- if (!fd) {
- gf_log (this->name, GF_LOG_WARNING,
- "unable to opendir index-dir on %s", subvol->name);
- return -errno;
- }
-
- INIT_LIST_HEAD (&entries.list);
-
- while ((ret = syncop_readdir (subvol, fd, 131072, offset, &entries))) {
- if (ret > 0)
- ret = 0;
- list_for_each_entry (entry, &entries.list, list) {
- offset = entry->d_off;
-
- if (!priv->shd.enabled) {
- ret = -EBUSY;
- break;
- }
-
- if (!strcmp (entry->d_name, ".") ||
- !strcmp (entry->d_name, ".."))
- continue;
-
- gf_log (this->name, GF_LOG_DEBUG, "got entry: %s",
- entry->d_name);
-
- ret = uuid_parse (entry->d_name, gfid);
- if (ret)
- continue;
-
- ret = afr_shd_selfheal (healer, child, gfid);
- if (ret == 0)
- count++;
-
- if (ret == -ENOENT || ret == -ESTALE) {
- afr_shd_index_purge (subvol, fd->inode,
- entry->d_name);
- }
- if (ret == 2)
- /* If bricks crashed in pre-op after creating
- * indices/xattrop link but before setting afr
- * changelogs, we end up with stale xattrop links but
- * zero changelogs. Remove such entries by sending a
- * post-op with zero changelogs.
- */
- afr_shd_zero_xattrop (healer->this, gfid);
- ret = 0;
- }
-
- gf_dirent_free (&entries);
- if (ret)
- break;
- }
-
- if (fd) {
- if (fd->inode)
- inode_forget (fd->inode, 1);
- fd_unref (fd);
- }
-
- if (!ret)
- ret = count;
- return ret;
-}
-
-
-int
-afr_shd_full_sweep (struct subvol_healer *healer, inode_t *inode)
-{
- loc_t loc = {0, };
- fd_t *fd = NULL;
- xlator_t *this = NULL;
- xlator_t *subvol = NULL;
- afr_private_t *priv = NULL;
- uint64_t offset = 0;
- gf_dirent_t entries;
- gf_dirent_t *entry = NULL;
- int ret = 0;
-
- this = healer->this;
- priv = this->private;
- subvol = priv->children[healer->subvol];
-
- uuid_copy (loc.gfid, inode->gfid);
- loc.inode = inode_ref(inode);
-
- fd = fd_create (inode, GF_CLIENT_PID_AFR_SELF_HEALD);
- if (!fd) {
- gf_log(this->name, GF_LOG_ERROR,
- "fd_create of %s failed: %s",
- uuid_utoa (loc.gfid), strerror(errno));
- ret = -errno;
- goto out;
- }
-
- ret = syncop_opendir (subvol, &loc, fd);
- if (ret) {
-#ifdef GF_LINUX_HOST_OS /* See comment in afr_shd_index_opendir() */
- fd_unref(fd);
- fd = fd_anonymous (inode);
- if (!fd) {
- gf_log(this->name, GF_LOG_ERROR,
- "fd_anonymous of %s failed: %s",
- uuid_utoa (loc.gfid), strerror(errno));
- ret = -errno;
- goto out;
- }
-#else /* GF_LINUX_HOST_OS */
- gf_log(this->name, GF_LOG_ERROR,
- "opendir of %s failed: %s",
- uuid_utoa (loc.gfid), strerror(errno));
- ret = -errno;
- goto out;
-#endif /* GF_LINUX_HOST_OS */
- }
-
- INIT_LIST_HEAD (&entries.list);
-
- while ((ret = syncop_readdirp (subvol, fd, 131072, offset, 0, &entries))) {
- if (ret < 0)
- break;
-
- ret = gf_link_inodes_from_dirent (this, fd->inode, &entries);
- if (ret)
- break;
-
- list_for_each_entry (entry, &entries.list, list) {
- offset = entry->d_off;
-
- if (!priv->shd.enabled) {
- ret = -EBUSY;
- break;
- }
-
- if (!strcmp (entry->d_name, ".") ||
- !strcmp (entry->d_name, ".."))
- continue;
-
- afr_shd_selfheal_name (healer, healer->subvol,
- inode->gfid, entry->d_name);
-
- afr_shd_selfheal (healer, healer->subvol,
- entry->d_stat.ia_gfid);
-
- if (entry->d_stat.ia_type == IA_IFDIR) {
- ret = afr_shd_full_sweep (healer, entry->inode);
- if (ret)
- break;
- }
- }
-
- gf_dirent_free (&entries);
- if (ret)
- break;
- }
-
-out:
- loc_wipe (&loc);
- if (fd)
- fd_unref (fd);
- return ret;
-}
-
-
-void *
-afr_shd_index_healer (void *data)
-{
- struct subvol_healer *healer = NULL;
- xlator_t *this = NULL;
- int ret = 0;
-
- healer = data;
- THIS = this = healer->this;
-
- for (;;) {
- afr_shd_healer_wait (healer);
-
- ASSERT_LOCAL(this, healer);
-
- do {
- gf_log (this->name, GF_LOG_DEBUG,
- "starting index sweep on subvol %s",
- afr_subvol_name (this, healer->subvol));
-
- afr_shd_sweep_prepare (healer);
-
- ret = afr_shd_index_sweep (healer);
-
- afr_shd_sweep_done (healer);
- /*
- As long as at least one gfid was
- healed, keep retrying. We may have
- just healed a directory and thereby
- created entries for other gfids which
- could not be healed thus far.
- */
-
- gf_log (this->name, GF_LOG_DEBUG,
- "finished index sweep on subvol %s",
- afr_subvol_name (this, healer->subvol));
- /*
- Give a pause before retrying to avoid a busy loop
- in case the only entry in index is because of
- an ongoing I/O.
- */
- sleep (1);
- } while (ret > 0);
- }
-
- return NULL;
-}
-
-
-void *
-afr_shd_full_healer (void *data)
-{
- struct subvol_healer *healer = NULL;
- xlator_t *this = NULL;
- int run = 0;
-
- healer = data;
- THIS = this = healer->this;
-
- for (;;) {
- pthread_mutex_lock (&healer->mutex);
- {
- run = __afr_shd_healer_wait (healer);
- if (!run)
- healer->running = _gf_false;
- }
- pthread_mutex_unlock (&healer->mutex);
-
- if (!run)
- break;
-
- ASSERT_LOCAL(this, healer);
-
- gf_log (this->name, GF_LOG_INFO,
- "starting full sweep on subvol %s",
- afr_subvol_name (this, healer->subvol));
-
- afr_shd_sweep_prepare (healer);
-
- afr_shd_full_sweep (healer, this->itable->root);
-
- afr_shd_sweep_done (healer);
-
- gf_log (this->name, GF_LOG_INFO,
- "finished full sweep on subvol %s",
- afr_subvol_name (this, healer->subvol));
- }
-
- return NULL;
-}
-
-
-int
-afr_shd_healer_init (xlator_t *this, struct subvol_healer *healer)
-{
- int ret = 0;
-
- ret = pthread_mutex_init (&healer->mutex, NULL);
- if (ret)
- goto out;
-
- ret = pthread_cond_init (&healer->cond, NULL);
- if (ret)
- goto out;
-
- healer->this = this;
- healer->running = _gf_false;
- healer->rerun = _gf_false;
- healer->local = _gf_false;
-out:
- return ret;
-}
-
-
-int
-afr_shd_healer_spawn (xlator_t *this, struct subvol_healer *healer,
- void *(threadfn)(void *))
-{
- int ret = 0;
-
- pthread_mutex_lock (&healer->mutex);
- {
- if (healer->running) {
- pthread_cond_signal (&healer->cond);
- } else {
- ret = gf_thread_create (&healer->thread, NULL,
- threadfn, healer);
- if (ret)
- goto unlock;
- healer->running = 1;
- }
-
- healer->rerun = 1;
- }
-unlock:
- pthread_mutex_unlock (&healer->mutex);
-
- return ret;
-}
-
-
-int
-afr_shd_full_healer_spawn (xlator_t *this, int subvol)
-{
- return afr_shd_healer_spawn (this, NTH_FULL_HEALER (this, subvol),
- afr_shd_full_healer);
-}
-
-
-int
-afr_shd_index_healer_spawn (xlator_t *this, int subvol)
-{
- return afr_shd_healer_spawn (this, NTH_INDEX_HEALER (this, subvol),
- afr_shd_index_healer);
-}
-
-
-int
-afr_shd_dict_add_crawl_event (xlator_t *this, dict_t *output,
- crawl_event_t *crawl_event)
-{
- int ret = 0;
- uint64_t count = 0;
- char key[256] = {0};
- int xl_id = 0;
- uint64_t healed_count = 0;
- uint64_t split_brain_count = 0;
- uint64_t heal_failed_count = 0;
- char *start_time_str = 0;
- char *end_time_str = NULL;
- char *crawl_type = NULL;
- int progress = -1;
- int child = -1;
-
- child = crawl_event->child;
- healed_count = crawl_event->healed_count;
- split_brain_count = crawl_event->split_brain_count;
- heal_failed_count = crawl_event->heal_failed_count;
- crawl_type = crawl_event->crawl_type;
-
- if (!crawl_event->start_time)
- goto out;
-
- start_time_str = gf_strdup (ctime (&crawl_event->start_time));
-
- if (crawl_event->end_time)
- end_time_str = gf_strdup (ctime (&crawl_event->end_time));
-
- 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), "statistics-%d-%d-count", xl_id, child);
- ret = dict_get_uint64 (output, key, &count);
-
-
- snprintf (key, sizeof (key), "statistics_healed_cnt-%d-%d-%"PRIu64,
- xl_id, child, count);
- ret = dict_set_uint64(output, key, healed_count);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Could not add statistics_healed_count to outout");
- goto out;
- }
-
- snprintf (key, sizeof (key), "statistics_sb_cnt-%d-%d-%"PRIu64,
- xl_id, child, count);
- ret = dict_set_uint64 (output, key, split_brain_count);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Could not add statistics_split_brain_count to outout");
- goto out;
- }
-
- snprintf (key, sizeof (key), "statistics_crawl_type-%d-%d-%"PRIu64,
- xl_id, child, count);
- ret = dict_set_str (output, key, crawl_type);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Could not add statistics_crawl_type to output");
- goto out;
- }
-
- snprintf (key, sizeof (key), "statistics_heal_failed_cnt-%d-%d-%"PRIu64,
- xl_id, child, count);
- ret = dict_set_uint64 (output, key, heal_failed_count);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Could not add statistics_healed_failed_count to outout");
- goto out;
- }
-
- snprintf (key, sizeof (key), "statistics_strt_time-%d-%d-%"PRIu64,
- xl_id, child, count);
- ret = dict_set_dynstr (output, key, start_time_str);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Could not add statistics_crawl_start_time to outout");
- goto out;
- } else {
- start_time_str = NULL;
- }
-
- if (!end_time_str)
- progress = 1;
- else
- progress = 0;
-
- snprintf (key, sizeof (key), "statistics_end_time-%d-%d-%"PRIu64,
- xl_id, child, count);
- if (!end_time_str)
- end_time_str = gf_strdup ("Could not determine the end time");
- ret = dict_set_dynstr (output, key, end_time_str);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Could not add statistics_crawl_end_time to outout");
- goto out;
- } else {
- end_time_str = NULL;
- }
-
- snprintf (key, sizeof (key), "statistics_inprogress-%d-%d-%"PRIu64,
- xl_id, child, count);
-
- ret = dict_set_int32 (output, key, progress);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Could not add statistics_inprogress to outout");
- goto out;
- }
-
- snprintf (key, sizeof (key), "statistics-%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 the counter.");
- goto out;
- }
-out:
- GF_FREE (start_time_str);
- GF_FREE (end_time_str);
- return ret;
-}
-
-
-int
-afr_shd_dict_add_path (xlator_t *this, dict_t *output, int child, char *path,
- struct timeval *tv)
-{
- 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);
- ret = dict_set_dynstr (output, key, path);
-
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "%s: Could not add to output",
- path);
- goto out;
- }
-
- if (tv) {
- 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;
- }
- }
-
- 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
-afr_shd_gfid_to_path (xlator_t *this, xlator_t *subvol, uuid_t gfid, char **path_p)
-{
- int ret = 0;
- char *path = NULL;
- loc_t loc = {0,};
- dict_t *xattr = NULL;
-
- uuid_copy (loc.gfid, gfid);
- loc.inode = inode_new (this->itable);
-
- ret = syncop_getxattr (subvol, &loc, &xattr, GFID_TO_PATH_KEY);
- if (ret)
- goto out;
-
- ret = dict_get_str (xattr, GFID_TO_PATH_KEY, &path);
- if (ret || !path) {
- ret = -EINVAL;
- goto out;
- }
-
- *path_p = gf_strdup (path);
- if (!*path_p) {
- ret = -ENOMEM;
- goto out;
- }
-
- ret = 0;
-
-out:
- if (xattr)
- dict_unref (xattr);
- loc_wipe (&loc);
-
- return ret;
-}
-
-
-int
-afr_shd_gather_index_entries (xlator_t *this, int child, dict_t *output)
-{
- fd_t *fd = NULL;
- xlator_t *subvol = NULL;
- afr_private_t *priv = NULL;
- uint64_t offset = 0;
- gf_dirent_t entries;
- gf_dirent_t *entry = NULL;
- uuid_t gfid;
- int ret = 0;
- int count = 0;
- char *path = NULL;
-
- priv = this->private;
- subvol = priv->children[child];
-
- fd = afr_shd_index_opendir (this, child);
- if (!fd) {
- gf_log (this->name, GF_LOG_WARNING,
- "unable to opendir index-dir on %s", subvol->name);
- return -errno;
- }
-
- INIT_LIST_HEAD (&entries.list);
-
- while ((ret = syncop_readdir (subvol, fd, 131072, offset, &entries))) {
- if (ret > 0)
- ret = 0;
- list_for_each_entry (entry, &entries.list, list) {
- offset = entry->d_off;
-
- if (!strcmp (entry->d_name, ".") ||
- !strcmp (entry->d_name, ".."))
- continue;
-
- gf_log (this->name, GF_LOG_DEBUG, "got entry: %s",
- entry->d_name);
-
- ret = uuid_parse (entry->d_name, gfid);
- if (ret)
- continue;
-
- path = NULL;
- ret = afr_shd_gfid_to_path (this, subvol, gfid, &path);
-
- if (ret == -ENOENT || ret == -ESTALE) {
- afr_shd_index_purge (subvol, fd->inode,
- entry->d_name);
- ret = 0;
- continue;
- }
-
- afr_shd_dict_add_path (this, output, child, path, NULL);
- }
-
- gf_dirent_free (&entries);
- if (ret)
- break;
- }
-
- if (fd) {
- if (fd->inode)
- inode_forget (fd->inode, 1);
- fd_unref (fd);
- }
-
- if (!ret)
- ret = count;
- return ret;
-}
-
-
-int
-afr_add_shd_event (circular_buffer_t *cb, void *data)
-{
- dict_t *output = NULL;
- xlator_t *this = THIS;
- afr_private_t *priv = NULL;
- afr_self_heald_t *shd = NULL;
- shd_event_t *shd_event = NULL;
- char *path = NULL;
-
- output = data;
- priv = this->private;
- shd = &priv->shd;
- shd_event = cb->data;
-
- if (!shd->index_healers[shd_event->child].local)
- return 0;
-
- path = gf_strdup (shd_event->path);
- if (!path)
- return -ENOMEM;
-
- afr_shd_dict_add_path (this, output, shd_event->child, path,
- &cb->tv);
- return 0;
-}
-
-int
-afr_add_crawl_event (circular_buffer_t *cb, void *data)
-{
- dict_t *output = NULL;
- xlator_t *this = THIS;
- afr_private_t *priv = NULL;
- afr_self_heald_t *shd = NULL;
- crawl_event_t *crawl_event = NULL;
-
- output = data;
- priv = this->private;
- shd = &priv->shd;
- crawl_event = cb->data;
-
- if (!shd->index_healers[crawl_event->child].local)
- return 0;
-
- afr_shd_dict_add_crawl_event (this, output, crawl_event);
-
- return 0;
-}
-
-
-int
-afr_selfheal_daemon_init (xlator_t *this)
-{
- afr_private_t *priv = NULL;
- afr_self_heald_t *shd = NULL;
- int ret = -1;
- int i = 0;
-
- priv = this->private;
- shd = &priv->shd;
-
- this->itable = inode_table_new (SHD_INODE_LRU_LIMIT, this);
- if (!this->itable)
- goto out;
-
- shd->index_healers = GF_CALLOC (sizeof(*shd->index_healers),
- priv->child_count,
- gf_afr_mt_subvol_healer_t);
- if (!shd->index_healers)
- goto out;
-
- for (i = 0; i < priv->child_count; i++) {
- shd->index_healers[i].subvol = i;
- ret = afr_shd_healer_init (this, &shd->index_healers[i]);
- if (ret)
- goto out;
- }
-
- shd->full_healers = GF_CALLOC (sizeof(*shd->full_healers),
- priv->child_count,
- gf_afr_mt_subvol_healer_t);
- if (!shd->full_healers)
- goto out;
- for (i = 0; i < priv->child_count; i++) {
- shd->full_healers[i].subvol = i;
- ret = afr_shd_healer_init (this, &shd->full_healers[i]);
- if (ret)
- goto out;
- }
-
- shd->split_brain = eh_new (AFR_EH_SPLIT_BRAIN_LIMIT, _gf_false,
- afr_destroy_shd_event_data);
- if (!shd->split_brain)
- goto out;
-
- shd->statistics = GF_CALLOC (sizeof(eh_t *), priv->child_count,
- gf_common_mt_eh_t);
- if (!shd->statistics)
- goto out;
-
- for (i = 0; i < priv->child_count ; i++) {
- shd->statistics[i] = eh_new (AFR_STATISTICS_HISTORY_SIZE,
- _gf_false,
- afr_destroy_crawl_event_data);
- if (!shd->statistics[i])
- goto out;
- shd->full_healers[i].crawl_event.child = i;
- shd->full_healers[i].crawl_event.crawl_type = "FULL";
- shd->index_healers[i].crawl_event.child = i;
- shd->index_healers[i].crawl_event.crawl_type = "INDEX";
- }
-
- ret = 0;
-out:
- return ret;
-}
-
-
-int
-afr_selfheal_childup (xlator_t *this, int subvol)
-{
- afr_shd_index_healer_spawn (this, subvol);
-
- return 0;
-}
-
-
-int
-afr_shd_get_index_count (xlator_t *this, int i, uint64_t *count)
-{
- afr_private_t *priv = NULL;
- xlator_t *subvol = NULL;
- loc_t rootloc = {0, };
- dict_t *xattr = NULL;
- int ret = -1;
-
- priv = this->private;
- subvol = priv->children[i];
-
- rootloc.inode = inode_ref (this->itable->root);
- uuid_copy (rootloc.gfid, rootloc.inode->gfid);
-
- ret = syncop_getxattr (subvol, &rootloc, &xattr,
- GF_XATTROP_INDEX_COUNT);
- if (ret < 0)
- goto out;
-
- ret = dict_get_uint64 (xattr, GF_XATTROP_INDEX_COUNT, count);
- if (ret)
- goto out;
-
- ret = 0;
-
-out:
- if (xattr)
- dict_unref (xattr);
- loc_wipe (&rootloc);
-
- return ret;
-}
-
-
-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;
- int xl_id = 0;
- afr_private_t *priv = NULL;
- afr_self_heald_t *shd = NULL;
- struct subvol_healer *healer = NULL;
- int i = 0;
- char key[64];
- int op_ret = 0;
- uint64_t cnt = 0;
-
- priv = this->private;
- shd = &priv->shd;
-
- for (i = 0; i < priv->child_count; i++)
- if (priv->child_up[i] == -1)
- goto out;
-
- 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:
- op_ret = -1;
-
- for (i = 0; i < priv->child_count; i++) {
- healer = &shd->index_healers[i];
- snprintf (key, sizeof (key), "%d-%d-status", xl_id, i);
-
- if (!priv->child_up[i]) {
- ret = dict_set_str (output, key,
- "Brick is not connected");
- } else if (AFR_COUNT (priv->child_up,
- priv->child_count) < 2) {
- ret = dict_set_str (output, key,
- "< 2 bricks in replica are up");
- } else if (!afr_shd_is_subvol_local (this, healer->subvol)) {
- ret = dict_set_str (output, key,
- "Brick is remote");
- } else {
- ret = dict_set_str (output, key,
- "Started self-heal");
- afr_shd_index_healer_spawn (this, i);
- op_ret = 0;
- }
- }
- break;
- case GF_AFR_OP_HEAL_FULL:
- op_ret = -1;
-
- for (i = 0; i < priv->child_count; i++) {
- healer = &shd->full_healers[i];
- snprintf (key, sizeof (key), "%d-%d-status", xl_id, i);
-
- if (!priv->child_up[i]) {
- ret = dict_set_str (output, key,
- "Brick is not connected");
- } else if (AFR_COUNT (priv->child_up,
- priv->child_count) < 2) {
- ret = dict_set_str (output, key,
- "< 2 bricks in replica are up");
- } else if (!afr_shd_is_subvol_local (this, healer->subvol)) {
- ret = dict_set_str (output, key,
- "Brick is remote");
- } else {
- ret = dict_set_str (output, key,
- "Started self-heal");
- afr_shd_full_healer_spawn (this, i);
- op_ret = 0;
- }
- }
- break;
- case GF_AFR_OP_INDEX_SUMMARY:
- for (i = 0; i < priv->child_count; i++)
- if (shd->index_healers[i].local)
- afr_shd_gather_index_entries (this, i, output);
- break;
- case GF_AFR_OP_HEALED_FILES:
- case GF_AFR_OP_HEAL_FAILED_FILES:
- for (i = 0; i < priv->child_count; i++) {
- snprintf (key, sizeof (key), "%d-%d-status", xl_id, i);
- ret = dict_set_str (output, key, "Operation Not "
- "Supported");
- }
- break;
- case GF_AFR_OP_SPLIT_BRAIN_FILES:
- eh_dump (shd->split_brain, output, afr_add_shd_event);
- break;
- case GF_AFR_OP_STATISTICS:
- for (i = 0; i < priv->child_count; i++) {
- eh_dump (shd->statistics[i], output,
- afr_add_crawl_event);
- afr_shd_dict_add_crawl_event (this, output,
- &shd->index_healers[i].crawl_event);
- afr_shd_dict_add_crawl_event (this, output,
- &shd->full_healers[i].crawl_event);
- }
- break;
- case GF_AFR_OP_STATISTICS_HEAL_COUNT:
- case GF_AFR_OP_STATISTICS_HEAL_COUNT_PER_REPLICA:
- op_ret = -1;
-
- for (i = 0; i < priv->child_count; i++) {
- if (!priv->child_up[i]) {
- snprintf (key, sizeof (key), "%d-%d-status",
- xl_id, i);
- ret = dict_set_str (output, key,
- "Brick is not connected");
- } else {
- snprintf (key, sizeof (key), "%d-%d-hardlinks",
- xl_id, i);
- ret = afr_shd_get_index_count (this, i, &cnt);
- if (ret == 0) {
- ret = dict_set_uint64 (output, key, cnt);
- }
- op_ret = 0;
- }
- }
-
-// ret = _do_crawl_op_on_local_subvols (this, INDEX_TO_BE_HEALED,
-// STATISTICS_TO_BE_HEALED,
-// output);
- break;
-
- default:
- gf_log (this->name, GF_LOG_ERROR, "Unknown set op %d", op);
- break;
- }
-out:
- dict_del (output, this->name);
- return op_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 02b26b8061f..00000000000
--- a/xlators/cluster/afr/src/afr-self-heald.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- Copyright (c) 2013 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 <pthread.h>
-
-
-typedef struct {
- int child;
- char *path;
-} shd_event_t;
-
-typedef struct {
- int child;
- uint64_t healed_count;
- uint64_t split_brain_count;
- uint64_t heal_failed_count;
-
- /* If start_time is 0, it means crawler is not in progress
- and stats are not valid */
- time_t start_time;
- /* If start_time is NOT 0 and end_time is 0, it means
- cralwer is in progress */
- time_t end_time;
- char *crawl_type;
-} crawl_event_t;
-
-struct subvol_healer {
- xlator_t *this;
- int subvol;
- gf_boolean_t local;
- gf_boolean_t running;
- gf_boolean_t rerun;
- crawl_event_t crawl_event;
- pthread_mutex_t mutex;
- pthread_cond_t cond;
- pthread_t thread;
-};
-
-typedef struct {
- gf_boolean_t iamshd;
- gf_boolean_t enabled;
- struct subvol_healer *index_healers;
- struct subvol_healer *full_healers;
-
- eh_t *split_brain;
- eh_t **statistics;
-} afr_self_heald_t;
-
-
-int
-afr_selfheal_childup (xlator_t *this, int subvol);
-
-int
-afr_selfheal_daemon_init (xlator_t *this);
-
-int
-afr_xl_op (xlator_t *this, dict_t *input, dict_t *output);
-
-int
-afr_shd_gfid_to_path (xlator_t *this, xlator_t *subvol, uuid_t gfid,
- char **path_p);
-
-int
-afr_shd_index_purge (xlator_t *subvol, inode_t *inode, char *name);
-#endif /* !_AFR_SELF_HEALD_H */
diff --git a/xlators/cluster/afr/src/afr-transaction.c b/xlators/cluster/afr/src/afr-transaction.c
index bb582b5940f..53a2b380d70 100644
--- a/xlators/cluster/afr/src/afr-transaction.c
+++ b/xlators/cluster/afr/src/afr-transaction.c
@@ -1,219 +1,268 @@
/*
- Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
+ Copyright (c) 2007-2009 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 General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that 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 "dict.h"
#include "byte-order.h"
#include "common-utils.h"
-#include "timer.h"
#include "afr.h"
#include "afr-transaction.h"
#include <signal.h>
-gf_boolean_t
-afr_changelog_pre_op_uninherit (call_frame_t *frame, xlator_t *this);
-
-gf_boolean_t
-afr_changelog_pre_op_update (call_frame_t *frame, xlator_t *this);
-int
-afr_changelog_do (call_frame_t *frame, xlator_t *this, dict_t *xattr,
- afr_changelog_resume_t changelog_resume);
+#define LOCKED_NO 0x0 /* no lock held */
+#define LOCKED_YES 0x1 /* for DATA, METADATA, ENTRY and higher_path
+ of RENAME */
+#define LOCKED_LOWER 0x2 /* for lower_path of RENAME */
-int
-__afr_txn_write_fop (call_frame_t *frame, xlator_t *this)
+afr_fd_ctx_t *
+afr_fd_ctx_get (fd_t *fd, xlator_t *this)
{
- afr_local_t *local = NULL;
- afr_private_t *priv = NULL;
- int call_count = -1;
- int i = 0;
+ uint64_t ctx = 0;
+ afr_fd_ctx_t *fd_ctx = NULL;
+ int ret = 0;
- local = frame->local;
- priv = this->private;
+ ret = fd_ctx_get (fd, this, &ctx);
- call_count = AFR_COUNT (local->transaction.pre_op, priv->child_count);
+ if (ret < 0)
+ goto out;
- if (call_count == 0) {
- local->transaction.resume (frame, this);
- return 0;
- }
+ fd_ctx = (afr_fd_ctx_t *)(long) ctx;
- local->call_count = call_count;
+out:
+ return fd_ctx;
+}
- for (i = 0; i < priv->child_count; i++) {
- if (local->transaction.pre_op[i]) {
- local->transaction.wind (frame, this, i);
- if (!--call_count)
- break;
- }
- }
+static void
+afr_pid_save (call_frame_t *frame)
+{
+ afr_local_t * local = NULL;
- return 0;
+ local = frame->local;
+
+ local->saved_pid = frame->root->pid;
}
-int
-__afr_txn_write_done (call_frame_t *frame, xlator_t *this)
+static void
+afr_pid_restore (call_frame_t *frame)
{
- afr_local_t *local = NULL;
+ afr_local_t * local = NULL;
local = frame->local;
- local->transaction.unwind (frame, this);
+ frame->root->pid = local->saved_pid;
+}
- AFR_STACK_DESTROY (frame);
- return 0;
+static void
+__mark_all_pending (int32_t *pending[], int child_count,
+ afr_transaction_type type)
+{
+ int i;
+ int j;
+
+ for (i = 0; i < child_count; i++) {
+ j = afr_index_for_transaction_type (type);
+ pending[i][j] = hton32 (1);
+ }
}
-call_frame_t*
-afr_transaction_detach_fop_frame (call_frame_t *frame)
+static void
+__mark_child_dead (int32_t *pending[], int child_count, int child,
+ afr_transaction_type type)
{
- afr_local_t * local = NULL;
- call_frame_t *fop_frame = NULL;
+ int j;
+
+ j = afr_index_for_transaction_type (type);
+
+ pending[child][j] = 0;
+}
+
+
+static void
+__mark_pre_op_done_on_fd (call_frame_t *frame, xlator_t *this, int child_index)
+{
+ afr_local_t *local = NULL;
+ afr_fd_ctx_t * fd_ctx = NULL;
local = frame->local;
- LOCK (&frame->lock);
+ if (!local->fd)
+ return;
+
+ fd_ctx = afr_fd_ctx_get (local->fd, this);
+ if (!fd_ctx)
+ goto out;
+
+ LOCK (&local->fd->lock);
{
- fop_frame = local->transaction.main_frame;
- local->transaction.main_frame = NULL;
+ if (local->transaction.type == AFR_DATA_TRANSACTION)
+ fd_ctx->pre_op_done[child_index]++;
}
- UNLOCK (&frame->lock);
+ UNLOCK (&local->fd->lock);
- return fop_frame;
+out:
+ return;
}
static void
-afr_save_lk_owner (call_frame_t *frame)
+__mark_pre_op_undone_on_fd (call_frame_t *frame, xlator_t *this, int child_index)
{
- afr_local_t * local = NULL;
+ afr_local_t *local = NULL;
+ afr_fd_ctx_t * fd_ctx = NULL;
local = frame->local;
- local->saved_lk_owner = frame->root->lk_owner;
+ if (!local->fd)
+ return;
+
+ fd_ctx = afr_fd_ctx_get (local->fd, this);
+ if (!fd_ctx)
+ goto out;
+
+ LOCK (&local->fd->lock);
+ {
+ if (local->transaction.type == AFR_DATA_TRANSACTION)
+ fd_ctx->pre_op_done[child_index]--;
+ }
+ UNLOCK (&local->fd->lock);
+
+out:
+ return;
}
static void
-afr_restore_lk_owner (call_frame_t *frame)
+__mark_down_children (int32_t *pending[], int child_count,
+ unsigned char *child_up, afr_transaction_type type)
{
- afr_local_t * local = NULL;
+ int i;
+ int j;
- local = frame->local;
+ for (i = 0; i < child_count; i++) {
+ j = afr_index_for_transaction_type (type);
- frame->root->lk_owner = local->saved_lk_owner;
+ if (!child_up[i])
+ pending[i][j] = 0;
+ }
}
-void
-__mark_all_success (call_frame_t *frame, xlator_t *this)
+
+static void
+__mark_all_success (int32_t *pending[], int child_count,
+ afr_transaction_type type)
{
- afr_private_t *priv = NULL;
- afr_local_t *local = NULL;
int i;
+ int j;
- local = frame->local;
- priv = this->private;
-
- for (i = 0; i < priv->child_count; i++) {
- local->transaction.failed_subvols[i] = 0;
- }
+ for (i = 0; i < child_count; i++) {
+ j = afr_index_for_transaction_type (type);
+ pending[i][j] = hton32 (-1);
+ }
}
-int
-afr_transaction_perform_fop (call_frame_t *frame, xlator_t *this)
+
+static int
+__changelog_enabled (afr_private_t *priv, afr_transaction_type type)
{
- afr_local_t *local = NULL;
- fd_t *fd = NULL;
+ int ret = 0;
- local = frame->local;
- fd = local->fd;
-
- /* 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;
-
- if (local->pre_op_compat)
- /* old mode, pre-op was done as afr_changelog_do()
- just now, before OP */
- afr_changelog_pre_op_update (frame, this);
-
- /* 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.
- */
- if (fd)
- afr_delayed_changelog_wake_up (this, fd);
- local->transaction.fop (frame, this);
+ switch (type) {
+ case AFR_DATA_TRANSACTION:
+ if (priv->data_change_log)
+ ret = 1;
+
+ break;
- return 0;
+ case AFR_METADATA_TRANSACTION:
+ if (priv->metadata_change_log)
+ ret = 1;
+
+ break;
+
+ case AFR_ENTRY_TRANSACTION:
+ case AFR_ENTRY_RENAME_TRANSACTION:
+ if (priv->entry_change_log)
+ ret = 1;
+
+ break;
+ }
+
+ return ret;
}
static int
-__changelog_enabled (afr_private_t *priv, afr_transaction_type type)
+__changelog_needed_pre_op (call_frame_t *frame, xlator_t *this)
{
- int ret = 0;
+ afr_private_t * priv = NULL;
+ afr_local_t * local = NULL;
- switch (type) {
- case AFR_DATA_TRANSACTION:
- if (priv->data_change_log)
- ret = 1;
+ int op_ret = 0;
- break;
+ priv = this->private;
+ local = frame->local;
+
+ if (__changelog_enabled (priv, local->transaction.type)) {
+ switch (local->op) {
- case AFR_METADATA_TRANSACTION:
- if (priv->metadata_change_log)
- ret = 1;
+ case GF_FOP_WRITE:
+ case GF_FOP_FTRUNCATE:
+ op_ret = 1;
+ break;
- break;
+ case GF_FOP_FLUSH:
+ /* only do post-op on flush() */
- case AFR_ENTRY_TRANSACTION:
- case AFR_ENTRY_RENAME_TRANSACTION:
- if (priv->entry_change_log)
- ret = 1;
+ op_ret = 0;
+ break;
- break;
- }
+ default:
+ op_ret = 1;
+ }
+ }
- return ret;
+ return op_ret;
}
static int
-__fop_changelog_needed (call_frame_t *frame, xlator_t *this)
+__changelog_needed_post_op (call_frame_t *frame, xlator_t *this)
{
- afr_private_t * priv = NULL;
- afr_local_t * local = NULL;
- int op_ret = 0;
- afr_transaction_type type = -1;
+ afr_private_t * priv = NULL;
+ afr_local_t * local = NULL;
- priv = this->private;
- local = frame->local;
- type = local->transaction.type;
+ int op_ret = 0;
+ afr_transaction_type type = -1;
+
+ priv = this->private;
+ local = frame->local;
+ type = local->transaction.type;
- if (__changelog_enabled (priv, type)) {
+ if (__changelog_enabled (priv, type)) {
switch (local->op) {
case GF_FOP_WRITE:
@@ -230,1496 +279,1113 @@ __fop_changelog_needed (call_frame_t *frame, xlator_t *this)
}
}
- return op_ret;
+ return op_ret;
}
-int
-afr_set_pending_dict (afr_private_t *priv, dict_t *xattr, int **pending)
+static int
+afr_set_piggyback_dict (afr_private_t *priv, dict_t *xattr, int32_t **pending,
+ afr_transaction_type type)
{
- int i = 0;
+ int i;
int ret = 0;
+ int *arr = NULL;
+ int index = 0;
+
+ index = afr_index_for_transaction_type (type);
for (i = 0; i < priv->child_count; i++) {
+ arr = CALLOC (3 * sizeof (int32_t), priv->child_count);
+ if (!arr) {
+ ret = -1;
+ goto out;
+ }
- ret = dict_set_static_bin (xattr, priv->pending_key[i],
- pending[i],
- AFR_NUM_CHANGE_LOGS * sizeof (int));
+ memcpy (arr, pending[i], 3 * sizeof (int32_t));
+ arr[index]++;
+ ret = dict_set_bin (xattr, priv->pending_key[i],
+ arr, 3 * sizeof (int32_t));
/* 3 = data+metadata+entry */
- if (ret)
- break;
+ if (ret < 0)
+ goto out;
}
+out:
return ret;
}
-int
-afr_lock_server_count (afr_private_t *priv, afr_transaction_type type)
+
+static int
+afr_set_pending_dict (afr_private_t *priv, dict_t *xattr, int32_t **pending)
{
+ int i;
int ret = 0;
- switch (type) {
- case AFR_DATA_TRANSACTION:
- ret = priv->child_count;
- break;
-
- case AFR_METADATA_TRANSACTION:
- ret = priv->child_count;
- break;
-
- case AFR_ENTRY_TRANSACTION:
- case AFR_ENTRY_RENAME_TRANSACTION:
- ret = priv->child_count;
- break;
+ for (i = 0; i < priv->child_count; i++) {
+ ret = dict_set_static_bin (xattr, priv->pending_key[i],
+ pending[i], 3 * sizeof (int32_t));
+ /* 3 = data+metadata+entry */
+
+ if (ret < 0)
+ goto out;
}
+out:
return ret;
}
-/* {{{ pending */
-
int
-afr_changelog_post_op_done (call_frame_t *frame, xlator_t *this)
+afr_lock_server_count (afr_private_t *priv, afr_transaction_type type)
{
- afr_local_t *local = NULL;
- afr_private_t *priv = NULL;
- afr_internal_lock_t *int_lock = NULL;
+ int ret = 0;
- local = frame->local;
- priv = this->private;
- int_lock = &local->internal_lock;
+ switch (type) {
+ case AFR_DATA_TRANSACTION:
+ ret = priv->data_lock_server_count;
+ break;
- if (local->transaction.resume_stub) {
- call_resume (local->transaction.resume_stub);
- local->transaction.resume_stub = NULL;
- }
+ case AFR_METADATA_TRANSACTION:
+ ret = priv->metadata_lock_server_count;
+ break;
- if (afr_lock_server_count (priv, local->transaction.type) == 0) {
- local->transaction.done (frame, this);
- } else {
- int_lock->lock_cbk = local->transaction.done;
- afr_unlock (frame, this);
+ case AFR_ENTRY_TRANSACTION:
+ case AFR_ENTRY_RENAME_TRANSACTION:
+ ret = priv->entry_lock_server_count;
+ break;
}
- return 0;
-}
-
-
-afr_inodelk_t*
-afr_get_inodelk (afr_internal_lock_t *int_lock, char *dom)
-{
- afr_inodelk_t *inodelk = NULL;
- int i = 0;
-
- for (i = 0; int_lock->inodelk[i].domain; i++) {
- inodelk = &int_lock->inodelk[i];
- if (strcmp (dom, inodelk->domain) == 0)
- return inodelk;
- }
- return NULL;
+ return ret;
}
-unsigned char*
-afr_locked_nodes_get (afr_transaction_type type, afr_internal_lock_t *int_lock)
-{
- unsigned char *locked_nodes = NULL;
- afr_inodelk_t *inodelk = NULL;
- switch (type) {
- case AFR_DATA_TRANSACTION:
- case AFR_METADATA_TRANSACTION:
- inodelk = afr_get_inodelk (int_lock, int_lock->domain);
- locked_nodes = inodelk->locked_nodes;
- break;
-
- case AFR_ENTRY_TRANSACTION:
- case AFR_ENTRY_RENAME_TRANSACTION:
- /*Because same set of subvols participate in all lockee
- * entities*/
- locked_nodes = int_lock->lockee[0].locked_nodes;
- break;
- }
- return locked_nodes;
-}
+/* {{{ unlock */
-int
-afr_changelog_call_count (afr_transaction_type type,
- unsigned char *pre_op_subvols,
- unsigned int child_count)
+static int
+afr_transaction_locked_nodes_count (afr_local_t *local, int child_count)
{
+ int i;
int call_count = 0;
- call_count = AFR_COUNT(pre_op_subvols, child_count);
+ for (i = 0; i < child_count; i++) {
+ if (local->transaction.locked_nodes[i] & LOCKED_YES)
+ call_count++;
- if (type == AFR_ENTRY_RENAME_TRANSACTION)
- call_count *= 2;
+ if ((local->transaction.type == AFR_ENTRY_RENAME_TRANSACTION)
+ && (local->transaction.locked_nodes[i] & LOCKED_LOWER)) {
+ call_count++;
+ }
+ }
return call_count;
}
-gf_boolean_t
-afr_txn_nothing_failed (call_frame_t *frame, xlator_t *this)
+static loc_t *
+lower_path (loc_t *l1, const char *b1, loc_t *l2, const char *b2)
{
- afr_private_t *priv = NULL;
- afr_local_t *local = NULL;
- int i = 0;
-
- local = frame->local;
- priv = this->private;
+ int ret = 0;
- for (i = 0; i < priv->child_count; i++) {
- if (local->transaction.failed_subvols[i])
- return _gf_false;
- }
+ ret = strcmp (l1->path, l2->path);
+
+ if (ret == 0)
+ ret = strcmp (b1, b2);
- return _gf_true;
+ if (ret <= 0)
+ return l1;
+ else
+ return l2;
}
-void
-afr_handle_symmetric_errors (call_frame_t *frame, xlator_t *this)
+int32_t
+afr_unlock_common_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno)
{
- afr_local_t *local = NULL;
- afr_private_t *priv = NULL;
- int op_errno = 0;
- int i_errno = 0;
- gf_boolean_t matching_errors = _gf_true;
- int i = 0;
+ afr_local_t *local;
+ int call_count = 0;
- priv = this->private;
local = frame->local;
- for (i = 0; i < priv->child_count; i++) {
- if (!local->replies[i].valid)
- continue;
- if (local->replies[i].op_ret != -1) {
- /* Operation succeeded on at least on subvol,
- so it is not a failed-everywhere situation.
- */
- matching_errors = _gf_false;
- break;
- }
- i_errno = local->replies[i].op_errno;
-
- if (i_errno == ENOTCONN) {
- /* ENOTCONN is not a symmetric error. We do not
- know if the operation was performed on the
- backend or not.
- */
- matching_errors = _gf_false;
- break;
- }
-
- if (!op_errno) {
- op_errno = i_errno;
- } else if (op_errno != i_errno) {
- /* Mismatching op_errno's */
- matching_errors = _gf_false;
- break;
- }
+ LOCK (&frame->lock);
+ {
+ call_count = --local->call_count;
}
+ UNLOCK (&frame->lock);
- if (matching_errors)
- __mark_all_success (frame, this);
-}
-
-gf_boolean_t
-afr_has_quorum (unsigned char *subvols, xlator_t *this)
-{
- unsigned int quorum_count = 0;
- afr_private_t *priv = NULL;
- unsigned int up_children_count = 0;
-
- priv = this->private;
- up_children_count = AFR_COUNT (subvols, priv->child_count);
-
- if (priv->quorum_count == AFR_QUORUM_AUTO) {
- /*
- * Special case for even numbers of nodes in auto-quorum:
- * if we have exactly half children up
- * 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) &&
- (up_children_count == (priv->child_count/2)))
- return subvols[0];
- }
-
- if (priv->quorum_count == AFR_QUORUM_AUTO) {
- quorum_count = priv->child_count/2 + 1;
- } else {
- quorum_count = priv->quorum_count;
- }
-
- if (up_children_count >= quorum_count)
- return _gf_true;
-
- return _gf_false;
-}
-
-static gf_boolean_t
-afr_has_fop_quorum (call_frame_t *frame)
-{
- xlator_t *this = frame->this;
- afr_local_t *local = frame->local;
- unsigned char *locked_nodes = NULL;
-
- locked_nodes = afr_locked_nodes_get (local->transaction.type,
- &local->internal_lock);
- return afr_has_quorum (locked_nodes, this);
-}
-
-static gf_boolean_t
-afr_has_fop_cbk_quorum (call_frame_t *frame)
-{
- afr_local_t *local = frame->local;
- xlator_t *this = frame->this;
- afr_private_t *priv = this->private;
- unsigned char *success = alloca0(priv->child_count);
- int i = 0;
-
- for (i = 0; i < priv->child_count; i++) {
- if (local->transaction.pre_op[i])
- if (!local->transaction.failed_subvols[i])
- success[i] = 1;
- }
-
- return afr_has_quorum (success, this);
+ if (call_count == 0) {
+ local->transaction.done (frame, this);
+ }
+
+ return 0;
}
-void
-afr_handle_quorum (call_frame_t *frame)
-{
- afr_local_t *local = NULL;
- afr_private_t *priv = NULL;
- int i = 0;
- const char *file = NULL;
- uuid_t gfid = {0};
-
- local = frame->local;
- priv = frame->this->private;
-
- if (priv->quorum_count == 0)
- return;
-
- /* If the fop already failed return right away to preserve errno */
- if (local->op_ret == -1)
- return;
-
- /*
- * Network split may happen just after the fops are unwound, so check
- * if the fop succeeded in a way it still follows quorum. If it doesn't,
- * mark the fop as failure, mark the changelogs so it reflects that
- * failure.
- *
- * Scenario:
- * There are 3 mounts on 3 machines(node1, node2, node3) all writing to
- * single file. Network split happened in a way that node1 can't see
- * node2, node3. Node2, node3 both of them can't see node1. Now at the
- * time of sending write all the bricks are up. Just after write fop is
- * wound on node1, network split happens. Node1 thinks write fop failed
- * on node2, node3 so marks pending changelog for those 2 extended
- * attributes on node1. Node2, node3 thinks writes failed on node1 so
- * they mark pending changelog for node1. When the network is stable
- * again the file already is in split-brain. These checks prevent
- * marking pending changelog on other subvolumes if the fop doesn't
- * succeed in a way it is still following quorum. So with this fix what
- * is happening is, node1 will have all pending changelog(FOOL) because
- * the write succeeded only on node1 but failed on node2, node3 so
- * instead of marking pending changelogs on node2, node3 it just treats
- * the fop as failure and goes into DIRTY state. Where as node2, node3
- * say they are sources and have pending changelog to node1 so there is
- * no split-brain with the fix. The problem is eliminated completely.
- */
-
- if (afr_has_fop_cbk_quorum (frame))
- return;
-
- if (local->fd) {
- uuid_copy (gfid, local->fd->inode->gfid);
- file = uuid_utoa (gfid);
- } else {
- loc_path (&local->loc, local->loc.name);
- file = local->loc.path;
- }
-
- gf_msg (frame->this->name, GF_LOG_WARNING, 0, AFR_MSG_QUORUM_FAIL,
- "%s: Failing %s as quorum is not met",
- file, gf_fop_list[local->op]);
-
- for (i = 0; i < priv->child_count; i++) {
- if (local->transaction.pre_op[i])
- afr_transaction_fop_failed (frame, frame->this, i);
- }
-
- local->op_ret = -1;
- local->op_errno = EROFS;
-}
int
-afr_changelog_post_op_now (call_frame_t *frame, xlator_t *this)
+afr_unlock (call_frame_t *frame, xlator_t *this)
{
- afr_private_t * priv = this->private;
- int i = 0;
- int ret = 0;
- int idx = 0;
- afr_local_t * local = NULL;
- dict_t *xattr = NULL;
- int nothing_failed = 1;
- gf_boolean_t need_undirty = _gf_false;
+ struct flock flock;
- afr_handle_quorum (frame);
- local = frame->local;
- idx = afr_index_for_transaction_type (local->transaction.type);
+ int i = 0;
+ int call_count = 0;
- nothing_failed = afr_txn_nothing_failed (frame, this);
+ afr_local_t *local = NULL;
+ afr_private_t * priv = this->private;
- if (afr_changelog_pre_op_uninherit (frame, this))
- need_undirty = _gf_false;
- else
- need_undirty = _gf_true;
+ loc_t * lower = NULL;
+ loc_t * higher = NULL;
- //If the fop fails on all the subvols then pending markers are placed
- //for every subvol on all subvolumes. Which is nothing but split-brain.
- //Avoid this by not doing post-op in case of failures.
- if (local->op_ret < 0) {
- afr_changelog_post_op_done (frame, this);
- goto out;
- }
+ const char *lower_name = NULL;
+ const char *higher_name = NULL;
- if (nothing_failed && !need_undirty) {
- afr_changelog_post_op_done (frame, this);
- goto out;
- }
+ local = frame->local;
- xattr = dict_new ();
- if (!xattr) {
- local->op_ret = -1;
- local->op_errno = ENOMEM;
- afr_changelog_post_op_done (frame, this);
- goto out;
- }
+ /*
+ pid has been restored to saved_pid in the fop,
+ so set it back to frame->root
+ */
- if (need_undirty)
- local->dirty[idx] = hton32(-1);
- else
- local->dirty[idx] = hton32(0);
-
- ret = dict_set_static_bin (xattr, AFR_DIRTY, local->dirty,
- sizeof(int) * AFR_NUM_CHANGE_LOGS);
- if (ret) {
- local->op_ret = -1;
- local->op_errno = ENOMEM;
- afr_changelog_post_op_done (frame, this);
- goto out;
- }
+ frame->root->pid = (long) frame->root;
- for (i = 0; i < priv->child_count; i++) {
- if (local->transaction.failed_subvols[i])
- local->pending[i][idx] = hton32(1);
- }
+ call_count = afr_transaction_locked_nodes_count (local,
+ priv->child_count);
- ret = afr_set_pending_dict (priv, xattr, local->pending);
- if (ret < 0) {
- local->op_ret = -1;
- local->op_errno = ENOMEM;
- afr_changelog_post_op_done (frame, this);
- goto out;
+ if (call_count == 0) {
+ local->transaction.done (frame, this);
+ return 0;
}
- afr_changelog_do (frame, this, xattr, afr_changelog_post_op_done);
-out:
- if (xattr)
- dict_unref (xattr);
+ local->call_count = call_count;
- return 0;
-}
+ for (i = 0; i < priv->child_count; i++) {
+ flock.l_start = local->transaction.start;
+ flock.l_len = local->transaction.len;
+ flock.l_type = F_UNLCK;
+ switch (local->transaction.type) {
+ case AFR_DATA_TRANSACTION:
+ case AFR_METADATA_TRANSACTION:
-gf_boolean_t
-afr_changelog_pre_op_uninherit (call_frame_t *frame, xlator_t *this)
-{
- afr_local_t *local = NULL;
- afr_private_t *priv = NULL;
- fd_t *fd = NULL;
- int i = 0;
- gf_boolean_t ret = _gf_false;
- afr_fd_ctx_t *fd_ctx = NULL;
- int type = 0;
-
- local = frame->local;
- priv = this->private;
- fd = local->fd;
-
- type = afr_index_for_transaction_type (local->transaction.type);
- if (type != AFR_DATA_TRANSACTION)
- return !local->transaction.dirtied;
+ if (local->transaction.locked_nodes[i] & LOCKED_YES) {
+ if (local->fd) {
+ STACK_WIND (frame, afr_unlock_common_cbk,
+ priv->children[i],
+ priv->children[i]->fops->finodelk,
+ this->name, local->fd,
+ F_SETLK, &flock);
+ } else {
+ STACK_WIND (frame, afr_unlock_common_cbk,
+ priv->children[i],
+ priv->children[i]->fops->inodelk,
+ this->name, &local->loc,
+ F_SETLK, &flock);
+ }
+
+ call_count--;
+ }
- if (!fd)
- return !local->transaction.dirtied;
+ break;
- fd_ctx = afr_fd_ctx_get (fd, this);
- if (!fd_ctx)
- return _gf_false;
+ case AFR_ENTRY_RENAME_TRANSACTION:
+ lower = lower_path (&local->transaction.parent_loc,
+ local->transaction.basename,
+ &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);
+
+ higher_name = (higher == &local->transaction.parent_loc ?
+ local->transaction.basename :
+ local->transaction.new_basename);
+
+ if (local->transaction.locked_nodes[i] & LOCKED_LOWER) {
+ STACK_WIND (frame, afr_unlock_common_cbk,
+ priv->children[i],
+ priv->children[i]->fops->entrylk,
+ this->name,
+ lower, lower_name,
+ ENTRYLK_UNLOCK, ENTRYLK_WRLCK);
+
+ call_count--;
+ }
- if (local->transaction.no_uninherit)
- return _gf_false;
+ if (call_count &&
+ local->transaction.locked_nodes[i] & LOCKED_YES) {
+ STACK_WIND (frame, afr_unlock_common_cbk,
+ priv->children[i],
+ priv->children[i]->fops->entrylk,
+ this->name,
+ higher, higher_name,
+ ENTRYLK_UNLOCK, ENTRYLK_WRLCK);
- /* This function must be idempotent. So check if we
- were called before and return the same answer again.
+ call_count--;
+ }
- It is important to keep this function idempotent for
- the call in afr_changelog_post_op_safe() to not have
- side effects on the call from afr_changelog_post_op_now()
- */
- if (local->transaction.uninherit_done)
- return local->transaction.uninherit_value;
+ break;
- LOCK(&fd->lock);
- {
- for (i = 0; i < priv->child_count; i++) {
- if (local->transaction.pre_op[i] !=
- fd_ctx->pre_op_done[type][i]) {
- ret = !local->transaction.dirtied;
- goto unlock;
- }
- }
+ case AFR_ENTRY_TRANSACTION:
+ if (local->transaction.locked_nodes[i] & LOCKED_YES) {
+ if (local->fd) {
+ STACK_WIND (frame, afr_unlock_common_cbk,
+ priv->children[i],
+ priv->children[i]->fops->fentrylk,
+ this->name, local->fd,
+ local->transaction.basename,
+ ENTRYLK_UNLOCK, ENTRYLK_WRLCK);
+ } else {
+ STACK_WIND (frame, afr_unlock_common_cbk,
+ priv->children[i],
+ priv->children[i]->fops->entrylk,
+ this->name,
+ &local->transaction.parent_loc,
+ local->transaction.basename,
+ ENTRYLK_UNLOCK, ENTRYLK_WRLCK);
+
+ }
+
+ call_count--;
+ }
- if (fd_ctx->inherited[type]) {
- ret = _gf_true;
- fd_ctx->inherited[type]--;
- } else if (fd_ctx->on_disk[type]) {
- ret = _gf_false;
- fd_ctx->on_disk[type]--;
- } else {
- /* ASSERT */
- ret = _gf_false;
- }
+ break;
+ }
- if (!fd_ctx->inherited[type] && !fd_ctx->on_disk[type]) {
- for (i = 0; i < priv->child_count; i++)
- fd_ctx->pre_op_done[type][i] = 0;
- }
+ if (!call_count)
+ break;
}
-unlock:
- UNLOCK(&fd->lock);
- local->transaction.uninherit_done = _gf_true;
- local->transaction.uninherit_value = ret;
-
- return ret;
+ return 0;
}
+/* }}} */
-gf_boolean_t
-afr_changelog_pre_op_inherit (call_frame_t *frame, xlator_t *this)
-{
- afr_local_t *local = NULL;
- afr_private_t *priv = NULL;
- fd_t *fd = NULL;
- int i = 0;
- gf_boolean_t ret = _gf_false;
- afr_fd_ctx_t *fd_ctx = NULL;
- int type = 0;
-
- local = frame->local;
- priv = this->private;
- fd = local->fd;
- if (local->transaction.type != AFR_DATA_TRANSACTION)
- return _gf_false;
+/* {{{ pending */
- type = afr_index_for_transaction_type (local->transaction.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)
+{
+ afr_private_t * priv = NULL;
+ afr_local_t * local = NULL;
+ int child_index = -1;
- if (!fd)
- return _gf_false;
+ int call_count = -1;
- fd_ctx = afr_fd_ctx_get (fd, this);
- if (!fd_ctx)
- return _gf_false;
+ priv = this->private;
+ local = frame->local;
- LOCK(&fd->lock);
+ LOCK (&frame->lock);
{
- if (!fd_ctx->on_disk[type]) {
- /* nothing to inherit yet */
- ret = _gf_false;
- goto unlock;
- }
-
- for (i = 0; i < priv->child_count; i++) {
- if (local->transaction.pre_op[i] !=
- fd_ctx->pre_op_done[type][i]) {
- /* either inherit exactly, or don't */
- ret = _gf_false;
- goto unlock;
- }
- }
-
- fd_ctx->inherited[type]++;
-
- ret = _gf_true;
-
- local->transaction.inherited = _gf_true;
+ call_count = --local->call_count;
}
-unlock:
- UNLOCK(&fd->lock);
-
- return ret;
-}
-
-
-gf_boolean_t
-afr_changelog_pre_op_update (call_frame_t *frame, xlator_t *this)
-{
- afr_local_t *local = NULL;
- afr_private_t *priv = NULL;
- fd_t *fd = NULL;
- afr_fd_ctx_t *fd_ctx = NULL;
- int i = 0;
- gf_boolean_t ret = _gf_false;
- int type = 0;
+ UNLOCK (&frame->lock);
- local = frame->local;
- priv = this->private;
- fd = local->fd;
-
- if (!fd)
- return _gf_false;
-
- fd_ctx = afr_fd_ctx_get (fd, this);
- if (!fd_ctx)
- return _gf_false;
-
- if (local->transaction.inherited)
- /* was already inherited in afr_changelog_pre_op */
- return _gf_false;
-
- if (!local->transaction.dirtied)
- return _gf_false;
-
- if (!afr_txn_nothing_failed (frame, this))
- return _gf_false;
+ child_index = (long) cookie;
- type = afr_index_for_transaction_type (local->transaction.type);
-
- ret = _gf_false;
+ if (op_ret == 1) {
+ /* cached */
+ }
- LOCK(&fd->lock);
- {
- if (!fd_ctx->on_disk[type]) {
- for (i = 0; i < priv->child_count; i++)
- fd_ctx->pre_op_done[type][i] =
- local->transaction.pre_op[i];
- } else {
- for (i = 0; i < priv->child_count; i++)
- if (fd_ctx->pre_op_done[type][i] !=
- local->transaction.pre_op[i]) {
- local->transaction.no_uninherit = 1;
- goto unlock;
- }
- }
- fd_ctx->on_disk[type]++;
+ if (op_ret == 0) {
+ __mark_pre_op_undone_on_fd (frame, this, child_index);
+ }
- ret = _gf_true;
- }
-unlock:
- UNLOCK(&fd->lock);
+ if (call_count == 0) {
+ if (afr_lock_server_count (priv, local->transaction.type) == 0) {
+ local->transaction.done (frame, this);
+ } else {
+ afr_unlock (frame, this);
+ }
+ }
- return ret;
+ return 0;
}
-int
-afr_changelog_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int op_ret, int op_errno, dict_t *xattr, dict_t *xdata)
+int
+afr_changelog_post_op (call_frame_t *frame, xlator_t *this)
{
- afr_local_t *local = NULL;
- int call_count = -1;
+ afr_private_t * priv = this->private;
- local = frame->local;
-
- if (op_ret == -1)
- afr_transaction_fop_failed (frame, this, (long) cookie);
+ int ret = 0;
+ int i = 0;
+ int call_count = 0;
+
+ afr_local_t * local = NULL;
+ dict_t **xattr = NULL;
+ afr_fd_ctx_t *fdctx = NULL;
+ int piggyback = 0;
+ int index = 0;
+ int nothing_failed = 1;
- call_count = afr_frame_return (frame);
- if (call_count == 0)
- local->transaction.changelog_resume (frame, this);
+ local = frame->local;
- return 0;
-}
+ __mark_down_children (local->pending, priv->child_count,
+ local->child_up, 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] = get_new_dict ();
+ dict_ref (xattr[i]);
+ }
+ call_count = afr_up_children_count (priv->child_count, local->child_up);
-int
-afr_changelog_do (call_frame_t *frame, xlator_t *this, dict_t *xattr,
- afr_changelog_resume_t changelog_resume)
-{
- afr_local_t *local = NULL;
- afr_private_t *priv = NULL;
- int i = 0;
- int call_count = 0;
+ if (local->transaction.type == AFR_ENTRY_RENAME_TRANSACTION) {
+ call_count *= 2;
+ }
- local = frame->local;
- priv = this->private;
+ if (local->fd)
+ fdctx = afr_fd_ctx_get (local->fd, this);
- call_count = afr_changelog_call_count (local->transaction.type,
- local->transaction.pre_op,
- priv->child_count);
+ local->call_count = call_count;
if (call_count == 0) {
- changelog_resume (frame, this);
+ /* no child is up */
+ for (i = 0; i < priv->child_count; i++) {
+ dict_unref (xattr[i]);
+ }
+
+ afr_unlock (frame, this);
return 0;
}
- local->call_count = call_count;
+ /* check if something has failed, to handle piggybacking */
+ nothing_failed = 1;
+ index = afr_index_for_transaction_type (local->transaction.type);
+ for (i = 0; i < priv->child_count; i++) {
+ if (local->pending[i][index] == 0) {
+ nothing_failed = 0;
+ break;
+ }
+ }
- local->transaction.changelog_resume = changelog_resume;
- for (i = 0; i < priv->child_count; i++) {
- if (!local->transaction.pre_op[i])
+ for (i = 0; i < priv->child_count; i++) {
+ if (!local->child_up[i])
continue;
+ ret = afr_set_pending_dict (priv, xattr[i],
+ local->pending);
+
+ if (ret < 0)
+ gf_log (this->name, GF_LOG_DEBUG,
+ "failed to set pending entry");
+
+
switch (local->transaction.type) {
case AFR_DATA_TRANSACTION:
- case AFR_METADATA_TRANSACTION:
- if (!local->fd) {
- STACK_WIND_COOKIE (frame, afr_changelog_cbk,
- (void *) (long) i,
- priv->children[i],
- priv->children[i]->fops->xattrop,
- &local->loc,
- GF_XATTROP_ADD_ARRAY, xattr,
- NULL);
+ {
+ if (!fdctx) {
+ STACK_WIND (frame, afr_changelog_post_op_cbk,
+ priv->children[i],
+ priv->children[i]->fops->xattrop,
+ &local->loc,
+ GF_XATTROP_ADD_ARRAY, xattr[i]);
+ break;
+ }
+
+ LOCK (&local->fd->lock);
+ {
+ piggyback = 0;
+ if (fdctx->pre_op_piggyback[i]) {
+ fdctx->pre_op_piggyback[i]--;
+ piggyback = 1;
+ }
+ }
+ UNLOCK (&local->fd->lock);
+
+ 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]);
} else {
- STACK_WIND_COOKIE (frame, afr_changelog_cbk,
- (void *) (long) i,
- priv->children[i],
- priv->children[i]->fops->fxattrop,
- local->fd,
- GF_XATTROP_ADD_ARRAY, xattr,
- NULL);
+ 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]);
}
- break;
- case AFR_ENTRY_RENAME_TRANSACTION:
+ }
+ break;
- STACK_WIND_COOKIE (frame, afr_changelog_cbk,
- (void *) (long) i,
- priv->children[i],
- priv->children[i]->fops->xattrop,
- &local->transaction.new_parent_loc,
- GF_XATTROP_ADD_ARRAY, xattr,
- NULL);
+ case AFR_METADATA_TRANSACTION:
+ {
+ if (local->fd)
+ STACK_WIND (frame, afr_changelog_post_op_cbk,
+ priv->children[i],
+ priv->children[i]->fops->fxattrop,
+ local->fd,
+ 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]);
call_count--;
+ }
+ break;
+
+ case AFR_ENTRY_RENAME_TRANSACTION:
+ {
+ 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]);
+ call_count--;
+ }
+
+ /*
+ set it again because previous stack_wind
+ might have already returned (think of case
+ where subvolume is posix) and would have
+ used the dict as placeholder for return
+ value
+ */
+ ret = afr_set_pending_dict (priv, xattr[i],
+ local->pending);
+
+ if (ret < 0)
+ gf_log (this->name, GF_LOG_DEBUG,
+ "failed to set pending entry");
/* fall through */
case AFR_ENTRY_TRANSACTION:
+ {
if (local->fd)
- STACK_WIND_COOKIE (frame, afr_changelog_cbk,
- (void *) (long) i,
- priv->children[i],
- priv->children[i]->fops->fxattrop,
- local->fd,
- GF_XATTROP_ADD_ARRAY, xattr,
- NULL);
+ STACK_WIND (frame, afr_changelog_post_op_cbk,
+ priv->children[i],
+ priv->children[i]->fops->fxattrop,
+ local->fd,
+ GF_XATTROP_ADD_ARRAY, xattr[i]);
else
- STACK_WIND_COOKIE (frame, afr_changelog_cbk,
- (void *) (long) i,
- priv->children[i],
- priv->children[i]->fops->xattrop,
- &local->transaction.parent_loc,
- GF_XATTROP_ADD_ARRAY, xattr,
- NULL);
- break;
- }
+ 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]);
+ call_count--;
+ }
+ break;
+ }
- if (!--call_count)
+ if (!call_count)
break;
+ }
+
+ for (i = 0; i < priv->child_count; i++) {
+ dict_unref (xattr[i]);
}
return 0;
}
-int
-afr_changelog_pre_op (call_frame_t *frame, xlator_t *this)
+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)
{
- afr_private_t * priv = this->private;
- int i = 0;
- int ret = 0;
- int call_count = 0;
- int op_errno = 0;
- afr_local_t *local = NULL;
- afr_internal_lock_t *int_lock = NULL;
- unsigned char *locked_nodes = NULL;
- unsigned char *pending_subvols = NULL;
- int idx = -1;
- gf_boolean_t pre_nop = _gf_true;
- dict_t *xdata_req = NULL;
+ afr_local_t * local = NULL;
+ afr_private_t * priv = this->private;
+ loc_t * loc = NULL;
- local = frame->local;
- int_lock = &local->internal_lock;
- idx = afr_index_for_transaction_type (local->transaction.type);
-
- locked_nodes = afr_locked_nodes_get (local->transaction.type, int_lock);
+ int call_count = -1;
+ int child_index = (long) cookie;
- pending_subvols = alloca0 (priv->child_count);
+ local = frame->local;
+ loc = &local->loc;
- for (i = 0; i < priv->child_count; i++) {
- if (locked_nodes[i]) {
- local->transaction.pre_op[i] = 1;
- call_count++;
- } else {
- pending_subvols[i] = 1;
- }
- }
+ LOCK (&frame->lock);
+ {
+ if (op_ret == 1) {
+ /* special op_ret for piggyback */
+ }
- /* This condition should not be met with present code, as
- * transaction.done will be called if locks are not acquired on even a
- * single node.
- */
- if (call_count == 0) {
- op_errno = ENOTCONN;
- goto err;
- }
+ if (op_ret == 0) {
+ __mark_pre_op_done_on_fd (frame, this, child_index);
+ }
- /* Check if the fop can be performed on at least
- * quorum number of nodes.
- */
- if (priv->quorum_count && !afr_has_fop_quorum (frame)) {
- op_errno = EROFS;
- goto err;
- }
+ 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",
+ priv->children[child_index]->name);
+ local->op_ret = -1;
+
+ } else if (!child_went_down (op_ret, op_errno)) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "xattrop failed on child %s: %s",
+ priv->children[child_index]->name,
+ strerror (op_errno));
+ }
+ local->op_errno = op_errno;
+ }
- xdata_req = dict_new();
- if (!xdata_req) {
- op_errno = ENOMEM;
- goto err;
+ call_count = --local->call_count;
}
+ UNLOCK (&frame->lock);
- pre_nop = _gf_true;
+ if (call_count == 0) {
+ if ((local->op_ret == -1) &&
+ (local->op_errno == ENOTSUP)) {
+ local->transaction.resume (frame, this);
+ } else {
+ __mark_all_success (local->pending, priv->child_count,
+ local->transaction.type);
- if (afr_changelog_pre_op_inherit (frame, this))
- goto next;
+ afr_pid_restore (frame);
- if (call_count < priv->child_count) {
- /* For subvols we are not performing operation on,
- mark them as pending up-front along with the FOP
- so that we can safely defer unmarking dirty until
- later.
- */
- for (i = 0; i < priv->child_count; i++) {
- if (pending_subvols[i])
- local->pending[i][idx] = hton32(1);
- }
- ret = afr_set_pending_dict (priv, xdata_req,
- local->pending);
- if (ret < 0) {
- op_errno = ENOMEM;
- goto err;
+ local->transaction.fop (frame, this);
}
- pre_nop = _gf_false;
}
- if (call_count > 1 &&
- (local->transaction.type == AFR_DATA_TRANSACTION ||
- !local->optimistic_change_log)) {
-
- /* If we are performing change on only one subvol, no
- need to mark dirty, because we are setting the pending
- counts already anyways
- */
- local->dirty[idx] = hton32(1);
-
- ret = dict_set_static_bin (xdata_req, AFR_DIRTY, local->dirty,
- sizeof(int) * AFR_NUM_CHANGE_LOGS);
- if (ret) {
- op_errno = ENOMEM;
- goto err;
- }
-
- pre_nop = _gf_false;
- local->transaction.dirtied = 1;
- }
-
- if (pre_nop)
- goto next;
-
- if (!local->pre_op_compat) {
- dict_copy (xdata_req, local->xdata_req);
- goto next;
- }
-
- afr_changelog_do (frame, this, xdata_req, afr_transaction_perform_fop);
-
- if (xdata_req)
- dict_unref (xdata_req);
-
- return 0;
-next:
- afr_transaction_perform_fop (frame, this);
-
- if (xdata_req)
- dict_unref (xdata_req);
-
- return 0;
-err:
- local->internal_lock.lock_cbk = local->transaction.done;
- local->op_ret = -1;
- local->op_errno = op_errno;
-
- afr_unlock (frame, this);
-
- if (xdata_req)
- dict_unref (xdata_req);
-
- return 0;
+ return 0;
}
-int
-afr_post_blocking_inodelk_cbk (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;
-
- if (int_lock->lock_op_ret < 0) {
- gf_log (this->name, GF_LOG_INFO,
- "Blocking inodelks failed.");
- local->transaction.done (frame, this);
- } else {
-
- gf_log (this->name, GF_LOG_DEBUG,
- "Blocking inodelks done. Proceeding to FOP");
- afr_internal_lock_finish (frame, this);
- }
-
- return 0;
-}
-
-
-int
-afr_post_nonblocking_inodelk_cbk (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;
-
- /* Initiate blocking locks if non-blocking has failed */
- if (int_lock->lock_op_ret < 0) {
- gf_log (this->name, GF_LOG_DEBUG,
- "Non blocking inodelks failed. Proceeding to blocking");
- int_lock->lock_cbk = afr_post_blocking_inodelk_cbk;
- afr_blocking_lock (frame, this);
- } else {
-
- gf_log (this->name, GF_LOG_DEBUG,
- "Non blocking inodelks done. Proceeding to FOP");
- afr_internal_lock_finish (frame, this);
- }
-
- return 0;
-}
-
-
-int
-afr_post_blocking_entrylk_cbk (call_frame_t *frame, xlator_t *this)
+int
+afr_changelog_pre_op (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;
-
- if (int_lock->lock_op_ret < 0) {
- gf_log (this->name, GF_LOG_INFO,
- "Blocking entrylks failed.");
- local->transaction.done (frame, this);
- } else {
-
- gf_log (this->name, GF_LOG_DEBUG,
- "Blocking entrylks done. Proceeding to FOP");
- afr_internal_lock_finish (frame, this);
- }
-
- return 0;
-}
+ afr_private_t * priv = this->private;
+ int i = 0;
+ int ret = 0;
+ int call_count = 0;
+ dict_t **xattr = NULL;
+ afr_fd_ctx_t *fdctx = NULL;
+ int piggyback = 0;
-int
-afr_post_nonblocking_entrylk_cbk (call_frame_t *frame, xlator_t *this)
-{
- afr_internal_lock_t *int_lock = NULL;
- afr_local_t *local = NULL;
+ afr_local_t *local = NULL;
- local = frame->local;
- int_lock = &local->internal_lock;
-
- /* Initiate blocking locks if non-blocking has failed */
- if (int_lock->lock_op_ret < 0) {
- gf_log (this->name, GF_LOG_DEBUG,
- "Non blocking entrylks failed. Proceeding to blocking");
- int_lock->lock_cbk = afr_post_blocking_entrylk_cbk;
- afr_blocking_lock (frame, this);
- } else {
+ local = frame->local;
+
+ xattr = alloca (priv->child_count * sizeof (*xattr));
+ memset (xattr, 0, (priv->child_count * sizeof (*xattr)));
- gf_log (this->name, GF_LOG_DEBUG,
- "Non blocking entrylks done. Proceeding to FOP");
- afr_internal_lock_finish (frame, this);
+ for (i = 0; i < priv->child_count; i++) {
+ xattr[i] = get_new_dict ();
+ dict_ref (xattr[i]);
}
- return 0;
-}
-
-
-int
-afr_post_blocking_rename_cbk (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;
+ call_count = afr_up_children_count (priv->child_count,
+ local->child_up);
- if (int_lock->lock_op_ret < 0) {
- gf_log (this->name, GF_LOG_INFO,
- "Blocking entrylks failed.");
- local->transaction.done (frame, this);
- } else {
+ if (local->transaction.type == AFR_ENTRY_RENAME_TRANSACTION) {
+ call_count *= 2;
+ }
- gf_log (this->name, GF_LOG_DEBUG,
- "Blocking entrylks done. Proceeding to FOP");
- afr_internal_lock_finish (frame, this);
- }
- return 0;
-}
+ if (call_count == 0) {
+ /* no child is up */
+ for (i = 0; i < priv->child_count; i++) {
+ dict_unref (xattr[i]);
+ }
+
+ afr_unlock (frame, this);
+ return 0;
+ }
-int
-afr_post_lower_unlock_cbk (call_frame_t *frame, xlator_t *this)
-{
- afr_internal_lock_t *int_lock = NULL;
- afr_local_t *local = NULL;
+ local->call_count = call_count;
- local = frame->local;
- int_lock = &local->internal_lock;
+ __mark_all_pending (local->pending, priv->child_count,
+ local->transaction.type);
- GF_ASSERT (!int_lock->higher_locked);
+ if (local->fd)
+ fdctx = afr_fd_ctx_get (local->fd, this);
- int_lock->lock_cbk = afr_post_blocking_rename_cbk;
- afr_blocking_lock (frame, this);
+ for (i = 0; i < priv->child_count; i++) {
+ if (!local->child_up[i])
+ continue;
- return 0;
-}
+ ret = afr_set_pending_dict (priv, xattr[i],
+ local->pending);
+ if (ret < 0)
+ gf_log (this->name, GF_LOG_DEBUG,
+ "failed to set pending entry");
-int
-afr_set_transaction_flock (afr_local_t *local)
-{
- afr_internal_lock_t *int_lock = NULL;
- afr_inodelk_t *inodelk = NULL;
- int_lock = &local->internal_lock;
- inodelk = afr_get_inodelk (int_lock, int_lock->domain);
+ switch (local->transaction.type) {
+ case AFR_DATA_TRANSACTION:
+ {
+ if (!fdctx) {
+ STACK_WIND_COOKIE (frame,
+ afr_changelog_pre_op_cbk,
+ (void *) (long) i,
+ priv->children[i],
+ priv->children[i]->fops->xattrop,
+ &(local->loc),
+ GF_XATTROP_ADD_ARRAY, xattr[i]);
+ break;
+ }
- inodelk->flock.l_len = local->transaction.len;
- inodelk->flock.l_start = local->transaction.start;
- inodelk->flock.l_type = F_WRLCK;
+ LOCK (&local->fd->lock);
+ {
+ piggyback = 0;
+ if (fdctx->pre_op_done[i]) {
+ fdctx->pre_op_piggyback[i]++;
+ piggyback = 1;
+ fdctx->hit++;
+ } else {
+ fdctx->miss++;
+ }
+ }
+ UNLOCK (&local->fd->lock);
- return 0;
-}
+ if (piggyback)
+ afr_changelog_pre_op_cbk (frame, (void *)(long)i,
+ this, 1, 0, xattr[i]);
+ else
+ STACK_WIND_COOKIE (frame,
+ afr_changelog_pre_op_cbk,
+ (void *) (long) i,
+ priv->children[i],
+ priv->children[i]->fops->fxattrop,
+ local->fd,
+ GF_XATTROP_ADD_ARRAY, xattr[i]);
+ }
+ break;
-int
-afr_lock_rec (call_frame_t *frame, xlator_t *this)
-{
- afr_internal_lock_t *int_lock = NULL;
- afr_local_t *local = NULL;
+ case AFR_METADATA_TRANSACTION:
+ {
+ if (local->fd)
+ STACK_WIND_COOKIE (frame,
+ afr_changelog_pre_op_cbk,
+ (void *) (long) i,
+ priv->children[i],
+ priv->children[i]->fops->fxattrop,
+ local->fd,
+ GF_XATTROP_ADD_ARRAY, xattr[i]);
+ else
+ STACK_WIND_COOKIE (frame,
+ afr_changelog_pre_op_cbk,
+ (void *) (long) i,
+ priv->children[i],
+ priv->children[i]->fops->xattrop,
+ &(local->loc),
+ GF_XATTROP_ADD_ARRAY, xattr[i]);
+ }
+ break;
+
+ case AFR_ENTRY_RENAME_TRANSACTION:
+ {
+ STACK_WIND_COOKIE (frame,
+ afr_changelog_pre_op_cbk,
+ (void *) (long) i,
+ priv->children[i],
+ priv->children[i]->fops->xattrop,
+ &local->transaction.new_parent_loc,
+ GF_XATTROP_ADD_ARRAY, xattr[i]);
- local = frame->local;
- int_lock = &local->internal_lock;
+ call_count--;
+ }
- int_lock->transaction_lk_type = AFR_TRANSACTION_LK;
- int_lock->domain = this->name;
- switch (local->transaction.type) {
- case AFR_DATA_TRANSACTION:
- case AFR_METADATA_TRANSACTION:
- afr_set_transaction_flock (local);
+ /*
+ set it again because previous stack_wind
+ might have already returned (think of case
+ where subvolume is posix) and would have
+ used the dict as placeholder for return
+ value
+ */
- int_lock->lock_cbk = afr_post_nonblocking_inodelk_cbk;
+ ret = afr_set_pending_dict (priv, xattr[i],
+ local->pending);
- afr_nonblocking_inodelk (frame, this);
- break;
+ if (ret < 0)
+ gf_log (this->name, GF_LOG_DEBUG,
+ "failed to set pending entry");
- case AFR_ENTRY_RENAME_TRANSACTION:
+ /* fall through */
+
+ case AFR_ENTRY_TRANSACTION:
+ {
+ if (local->fd)
+ STACK_WIND_COOKIE (frame,
+ afr_changelog_pre_op_cbk,
+ (void *) (long) i,
+ priv->children[i],
+ priv->children[i]->fops->fxattrop,
+ local->fd,
+ GF_XATTROP_ADD_ARRAY, xattr[i]);
+ else
+ STACK_WIND_COOKIE (frame,
+ afr_changelog_pre_op_cbk,
+ (void *) (long) i,
+ priv->children[i],
+ priv->children[i]->fops->xattrop,
+ &local->transaction.parent_loc,
+ GF_XATTROP_ADD_ARRAY, xattr[i]);
+ }
- int_lock->lock_cbk = afr_post_nonblocking_entrylk_cbk;
- afr_nonblocking_entrylk (frame, this);
break;
+ }
- case AFR_ENTRY_TRANSACTION:
- int_lock->lk_basename = local->transaction.basename;
- if (&local->transaction.parent_loc)
- int_lock->lk_loc = &local->transaction.parent_loc;
- else
- GF_ASSERT (local->fd);
-
- int_lock->lock_cbk = afr_post_nonblocking_entrylk_cbk;
- afr_nonblocking_entrylk (frame, this);
- break;
+ if (!--call_count)
+ break;
+ }
+
+ for (i = 0; i < priv->child_count; i++) {
+ dict_unref (xattr[i]);
}
-
- return 0;
+
+ return 0;
}
+/* }}} */
-int
-afr_lock (call_frame_t *frame, xlator_t *this)
-{
- afr_set_lock_number (frame, this);
+/* {{{ lock */
- return afr_lock_rec (frame, this);
-}
+static
+int afr_lock_rec (call_frame_t *frame, xlator_t *this, int child_index);
+int32_t
+afr_lock_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno)
+{
+ afr_local_t * local = NULL;
+ afr_private_t * priv = NULL;
+ int done = 0;
+ int child_index = (long) cookie;
-/* }}} */
+ local = frame->local;
+ priv = this->private;
-int
-afr_internal_lock_finish (call_frame_t *frame, xlator_t *this)
-{
- if (__fop_changelog_needed (frame, this)) {
- afr_changelog_pre_op (frame, this);
+ LOCK (&frame->lock);
+ {
+ if (op_ret == -1) {
+ if (op_errno == ENOSYS) {
+ /* return ENOTSUP */
+ gf_log (this->name, GF_LOG_ERROR,
+ "subvolume does not support locking. "
+ "please load features/posix-locks xlator on server");
+ local->op_ret = op_ret;
+ done = 1;
+ }
+
+ local->child_up[child_index] = 0;
+ local->op_errno = op_errno;
+ }
+ }
+ UNLOCK (&frame->lock);
+
+ if ((op_ret == -1) &&
+ (op_errno == ENOSYS)) {
+ afr_unlock (frame, this);
} else {
- afr_transaction_perform_fop (frame, this);
+ if (op_ret == 0) {
+ local->transaction.locked_nodes[child_index]
+ |= LOCKED_YES;
+ local->transaction.lock_count++;
+ }
+ afr_lock_rec (frame, this, child_index + 1);
}
- return 0;
+ return 0;
}
-void
-afr_set_delayed_post_op (call_frame_t *frame, xlator_t *this)
+int32_t
+afr_lock_lower_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno)
{
- 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:
+ afr_private_t *priv = NULL;
+ afr_local_t *local = NULL;
- - changelog piggybacking
- - eager locking
- */
+ int child_index = (long) cookie;
- priv = this->private;
- if (!priv)
- return;
+ loc_t * lower = NULL;
+ loc_t * higher = NULL;
- if (!priv->post_op_delay_secs)
- return;
+ const char *lower_name = NULL;
+ const char *higher_name = NULL;
+ priv = this->private;
local = frame->local;
- if (!local->transaction.eager_lock_on)
- return;
-
- if (!local)
- return;
-
- if (!local->fd)
- return;
-
- if (local->op == GF_FOP_WRITE)
- local->delayed_post_op = _gf_true;
-}
-
-gf_boolean_t
-afr_are_multiple_fds_opened (fd_t *fd, xlator_t *this)
-{
- afr_fd_ctx_t *fd_ctx = NULL;
-
- if (!fd) {
- /* If false is returned, it may keep on taking eager-lock
- * which may lead to starvation, so return true to avoid that.
- */
- gf_log_callingfn (this->name, GF_LOG_ERROR, "Invalid fd");
- return _gf_true;
- }
- /* Lets say mount1 has eager-lock(full-lock) and after the eager-lock
- * is taken mount2 opened the same file, it won't be able to
- * perform any data operations until mount1 releases eager-lock.
- * To avoid such scenario do not enable eager-lock for this transaction
- * if open-fd-count is > 1
- */
-
- fd_ctx = afr_fd_ctx_get (fd, this);
- if (!fd_ctx)
- return _gf_true;
-
- if (fd_ctx->open_fd_count > 1)
- return _gf_true;
-
- return _gf_false;
-}
+ LOCK (&frame->lock);
+ {
+ if (op_ret == -1) {
+ if (op_errno == ENOSYS) {
+ /* return ENOTSUP */
-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;
+ gf_log (this->name, GF_LOG_ERROR,
+ "subvolume does not support locking. "
+ "please load features/posix-locks xlator on server");
- local = frame->local;
- if (!local)
- goto out;
-
- if (!local->delayed_post_op)
- goto out;
+ local->op_ret = op_ret;
+ }
- //Mark pending changelog ASAP
- if (!afr_txn_nothing_failed (frame, this))
- goto out;
+ local->child_up[child_index] = 0;
+ local->op_errno = op_errno;
+ }
+ }
+ UNLOCK (&frame->lock);
- if (local->fd && afr_are_multiple_fds_opened (local->fd, this))
+ if (op_ret != 0) {
+ afr_unlock (frame, this);
goto out;
+ } else {
+ local->transaction.locked_nodes[child_index] |= LOCKED_LOWER;
+ }
- res = _gf_true;
-out:
- return res;
-}
-
-
-void
-afr_delayed_changelog_post_op (xlator_t *this, call_frame_t *frame, fd_t *fd,
- call_stub_t *stub);
-
-void
-afr_delayed_changelog_wake_up_cbk (void *data)
-{
- fd_t *fd = NULL;
+ /* The lower path has been locked. Now lock the higher path */
- fd = data;
+ lower = lower_path (&local->transaction.parent_loc,
+ local->transaction.basename,
+ &local->transaction.new_parent_loc,
+ local->transaction.new_basename);
- afr_delayed_changelog_wake_up (THIS, fd);
-}
+ 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);
-/* SET operation */
-int
-afr_fd_report_unstable_write (xlator_t *this, fd_t *fd)
-{
- afr_fd_ctx_t *fdctx = NULL;
+ higher_name = (higher == &local->transaction.parent_loc ?
+ local->transaction.basename :
+ local->transaction.new_basename);
- fdctx = afr_fd_ctx_get (fd, this);
-
- LOCK(&fd->lock);
- {
- fdctx->witnessed_unstable_write = _gf_true;
- }
- UNLOCK(&fd->lock);
+ STACK_WIND_COOKIE (frame, afr_lock_cbk,
+ (void *) (long) child_index,
+ priv->children[child_index],
+ priv->children[child_index]->fops->entrylk,
+ this->name, higher, higher_name,
+ ENTRYLK_LOCK, ENTRYLK_WRLCK);
+out:
return 0;
}
-/* TEST and CLEAR operation */
-gf_boolean_t
-afr_fd_has_witnessed_unstable_write (xlator_t *this, fd_t *fd)
-{
- afr_fd_ctx_t *fdctx = NULL;
- gf_boolean_t witness = _gf_false;
-
- fdctx = afr_fd_ctx_get (fd, this);
- if (!fdctx)
- return _gf_true;
- LOCK(&fd->lock);
- {
- if (fdctx->witnessed_unstable_write) {
- witness = _gf_true;
- fdctx->witnessed_unstable_write = _gf_false;
- }
- }
- UNLOCK (&fd->lock);
-
- return witness;
-}
-
-
-int
-afr_changelog_fsync_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int op_ret, int op_errno, struct iatt *pre,
- struct iatt *post, dict_t *xdata)
+static
+int afr_lock_rec (call_frame_t *frame, xlator_t *this, int child_index)
{
- afr_private_t *priv = NULL;
- int child_index = (long) cookie;
- int call_count = -1;
- afr_local_t *local = NULL;
-
- priv = this->private;
- local = frame->local;
-
- if (op_ret != 0) {
- /* Failure of fsync() is as good as failure of previous
- write(). So treat it like one.
- */
- gf_log (this->name, GF_LOG_WARNING,
- "fsync(%s) failed on subvolume %s. Transaction was %s",
- uuid_utoa (local->fd->inode->gfid),
- priv->children[child_index]->name,
- gf_fop_list[local->op]);
-
- afr_transaction_fop_failed (frame, this, child_index);
- }
+ afr_local_t * local = NULL;
+ afr_private_t * priv = NULL;
- call_count = afr_frame_return (frame);
+ uint64_t ctx;
+ afr_fd_ctx_t *fd_ctx;
- if (call_count == 0)
- afr_changelog_post_op_now (frame, this);
+ struct flock flock;
- return 0;
-}
+ int ret = 0;
+ loc_t * lower = NULL;
+ loc_t * higher = NULL;
-int
-afr_changelog_fsync (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 *xdata = NULL;
- GF_UNUSED int ret = -1;
+ const char *lower_name = NULL;
+ const char *higher_name = NULL;
- local = frame->local;
- priv = this->private;
+ local = frame->local;
+ priv = this->private;
- call_count = AFR_COUNT (local->transaction.pre_op, priv->child_count);
+ flock.l_start = local->transaction.start;
+ flock.l_len = local->transaction.len;
+ flock.l_type = F_WRLCK;
- if (!call_count) {
- /* will go straight to unlock */
- afr_changelog_post_op_now (frame, this);
- return 0;
- }
+ if (local->fd) {
+ ret = fd_ctx_get (local->fd, this, &ctx);
- local->call_count = call_count;
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "unable to get fd ctx for fd=%p",
+ local->fd);
- xdata = dict_new();
- if (xdata)
- ret = dict_set_int32 (xdata, "batch-fsync", 1);
+ local->op_ret = -1;
+ local->op_errno = EINVAL;
- for (i = 0; i < priv->child_count; i++) {
- if (!local->transaction.pre_op[i])
- continue;
+ afr_unlock (frame, this);
- STACK_WIND_COOKIE (frame, afr_changelog_fsync_cbk,
- (void *) (long) i, priv->children[i],
- priv->children[i]->fops->fsync, local->fd,
- 1, xdata);
- if (!--call_count)
- break;
- }
+ return 0;
+ }
- if (xdata)
- dict_unref (xdata);
+ fd_ctx = (afr_fd_ctx_t *)(long) ctx;
- return 0;
-}
+ /* skip over children that or down
+ or don't have the fd open */
+ while ((child_index < priv->child_count)
+ && (!local->child_up[child_index]
+ || !fd_ctx->opened_on[child_index]))
-int
-afr_changelog_post_op_safe (call_frame_t *frame, xlator_t *this)
-{
- afr_local_t *local = NULL;
- afr_private_t *priv = NULL;
+ child_index++;
+ } else {
+ /* skip over children that are down */
+ while ((child_index < priv->child_count)
+ && !local->child_up[child_index])
+ child_index++;
+ }
- local = frame->local;
- priv = this->private;
+ if ((child_index == priv->child_count) &&
+ local->transaction.lock_count == 0) {
- if (!local->fd || local->transaction.type != AFR_DATA_TRANSACTION) {
- afr_changelog_post_op_now (frame, this);
- return 0;
- }
+ gf_log (this->name, GF_LOG_DEBUG,
+ "unable to lock on even one child");
- if (afr_changelog_pre_op_uninherit (frame, this) &&
- afr_txn_nothing_failed (frame, this)) {
- /* just detected that this post-op is about to
- be optimized away as a new write() has
- already piggybacked on this frame's changelog.
- */
- afr_changelog_post_op_now (frame, this);
- return 0;
- }
+ local->op_ret = -1;
+ local->op_errno = EAGAIN;
- /* Calling afr_changelog_post_op_now() now will result in
- issuing ->[f]xattrop().
-
- Performing a hard POST-OP (->[f]xattrop() FOP) is a more
- responsible operation that what it might appear on the surface.
-
- The changelog of a file (in the xattr of the file on the server)
- stores information (pending count) about the state of the file
- on the OTHER server. This changelog is blindly trusted, and must
- therefore be updated in such a way it remains trustworthy. This
- implies that decrementing the pending count (essentially "clearing
- the dirty flag") must be done STRICTLY after we are sure that the
- operation on the other server has reached stable storage.
-
- While the backend filesystem on that server will eventually flush
- it to stable storage, we (being in userspace) have no mechanism
- to get notified when the write became "stable".
-
- This means we need take matter into our own hands and issue an
- fsync() EVEN IF THE APPLICATION WAS PERFORMING UNSTABLE WRITES,
- and get an acknowledgement for it. And we need to wait for the
- fsync() acknowledgement before initiating the hard POST-OP.
-
- However if the FD itself was opened in O_SYNC or O_DSYNC then
- we are already guaranteed that the writes were made stable as
- part of the FOP itself. The same holds true for NFS stable
- writes which happen on an anonymous FD with O_DSYNC or O_SYNC
- flag set in the writev() @flags param. For all other write types,
- mark a flag in the fdctx whenever an unstable write is witnessed.
- */
-
- if (!afr_fd_has_witnessed_unstable_write (this, local->fd)) {
- afr_changelog_post_op_now (frame, this);
- return 0;
- }
+ afr_unlock (frame, this);
+
+ return 0;
- /* Check whether users want durability and perform fsync/post-op
- * accordingly.
- */
- if (priv->ensure_durability) {
- /* Time to fsync() */
- afr_changelog_fsync (frame, this);
- } else {
- afr_changelog_post_op_now (frame, this);
- }
+ }
- return 0;
-}
+ if ((child_index == priv->child_count)
+ || (local->transaction.lock_count ==
+ afr_lock_server_count (priv, local->transaction.type))) {
+ /* we're done locking */
-void
-afr_delayed_changelog_post_op (xlator_t *this, call_frame_t *frame, fd_t *fd,
- call_stub_t *stub)
-{
- afr_fd_ctx_t *fd_ctx = NULL;
- call_frame_t *prev_frame = NULL;
- struct timespec delta = {0, };
- afr_private_t *priv = NULL;
- afr_local_t *local = NULL;
+ 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);
- priv = this->private;
+ afr_pid_restore (frame);
- fd_ctx = afr_fd_ctx_get (fd, this);
- if (!fd_ctx)
- goto out;
+ local->transaction.fop (frame, this);
+ }
- delta.tv_sec = priv->post_op_delay_secs;
- delta.tv_nsec = 0;
+ return 0;
+ }
- pthread_mutex_lock (&fd_ctx->delay_lock);
+ switch (local->transaction.type) {
+ case AFR_DATA_TRANSACTION:
+ case AFR_METADATA_TRANSACTION:
+
+ if (local->fd) {
+ STACK_WIND_COOKIE (frame, afr_lock_cbk,
+ (void *) (long) child_index,
+ priv->children[child_index],
+ priv->children[child_index]->fops->finodelk,
+ this->name, local->fd,
+ F_SETLKW, &flock);
+
+ } else {
+ STACK_WIND_COOKIE (frame, afr_lock_cbk,
+ (void *) (long) child_index,
+ priv->children[child_index],
+ priv->children[child_index]->fops->inodelk,
+ this->name, &local->loc,
+ F_SETLKW, &flock);
+ }
+
+ break;
+
+ case AFR_ENTRY_RENAME_TRANSACTION:
{
- 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;
+ lower = lower_path (&local->transaction.parent_loc,
+ local->transaction.basename,
+ &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);
+
+ higher_name = (higher == &local->transaction.parent_loc ?
+ local->transaction.basename :
+ local->transaction.new_basename);
+
+ STACK_WIND_COOKIE (frame, afr_lock_lower_cbk,
+ (void *) (long) child_index,
+ priv->children[child_index],
+ priv->children[child_index]->fops->entrylk,
+ this->name, lower, lower_name,
+ ENTRYLK_LOCK, ENTRYLK_WRLCK);
+
+ break;
}
-unlock:
- pthread_mutex_unlock (&fd_ctx->delay_lock);
+
+ case AFR_ENTRY_TRANSACTION:
+ if (local->fd) {
+ STACK_WIND_COOKIE (frame, afr_lock_cbk,
+ (void *) (long) child_index,
+ priv->children[child_index],
+ priv->children[child_index]->fops->fentrylk,
+ this->name, local->fd,
+ local->transaction.basename,
+ ENTRYLK_LOCK, ENTRYLK_WRLCK);
+ } else {
+ STACK_WIND_COOKIE (frame, afr_lock_cbk,
+ (void *) (long) child_index,
+ priv->children[child_index],
+ priv->children[child_index]->fops->entrylk,
+ this->name,
+ &local->transaction.parent_loc,
+ local->transaction.basename,
+ ENTRYLK_LOCK, ENTRYLK_WRLCK);
+ }
-out:
- if (prev_frame) {
- local = prev_frame->local;
- local->transaction.resume_stub = stub;
- afr_changelog_post_op_now (prev_frame, this);
- } else if (stub) {
- call_resume (stub);
+ break;
}
+
+ return 0;
}
-void
-afr_changelog_post_op (call_frame_t *frame, xlator_t *this)
+int32_t afr_lock (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, NULL);
- else
- afr_changelog_post_op_safe (frame, this);
-}
+ afr_pid_save (frame);
+ frame->root->pid = (long) frame->root;
+ afr_set_lk_owner (frame, this);
-/* Wake up the sleeping/delayed post-op, and also register
- a stub to have it resumed after this transaction
- completely finishes.
-
- The @stub gets saved in @local and gets resumed in
- afr_local_cleanup()
- */
-void
-afr_delayed_changelog_wake_resume (xlator_t *this, fd_t *fd, call_stub_t *stub)
-{
- afr_delayed_changelog_post_op (this, NULL, fd, stub);
+ return afr_lock_rec (frame, this, 0);
}
-void
-afr_delayed_changelog_wake_up (xlator_t *this, fd_t *fd)
-{
- afr_delayed_changelog_post_op (this, NULL, fd, NULL);
-}
-
+/* }}} */
-int
+int32_t
afr_transaction_resume (call_frame_t *frame, xlator_t *this)
{
- afr_local_t *local = NULL;
-
- local = frame->local;
-
- if (local->transaction.eager_lock_on) {
- /* We don't need to retain "local" in the
- fd list anymore, writes to all subvols
- are finished by now */
- afr_remove_eager_lock_stub (local);
- }
-
- afr_restore_lk_owner (frame);
-
- afr_handle_symmetric_errors (frame, this);
+ afr_local_t * local = NULL;
+ afr_private_t * priv = NULL;
- if (!local->pre_op_compat)
- /* new mode, pre-op was done along
- with OP */
- afr_changelog_pre_op_update (frame, this);
+ local = frame->local;
+ priv = this->private;
- if (__fop_changelog_needed (frame, this)) {
- afr_changelog_post_op (frame, this);
- } else {
- afr_changelog_post_op_done (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) {
+ local->transaction.done (frame, this);
+ } else {
+ afr_unlock (frame, this);
+ }
+ }
- return 0;
+ return 0;
}
@@ -1728,141 +1394,47 @@ afr_transaction_resume (call_frame_t *frame, xlator_t *this)
*/
void
-afr_transaction_fop_failed (call_frame_t *frame, xlator_t *this,
- int child_index)
+afr_transaction_fop_failed (call_frame_t *frame, xlator_t *this, int child_index)
{
- afr_local_t * local = NULL;
-
- local = frame->local;
-
- local->transaction.failed_subvols[child_index] = 1;
-}
-
+ afr_local_t * local = NULL;
+ afr_private_t * priv = NULL;
+ local = frame->local;
+ priv = this->private;
- static gf_boolean_t
-afr_locals_overlap (afr_local_t *local1, afr_local_t *local2)
-{
- uint64_t start1 = local1->transaction.start;
- uint64_t start2 = local2->transaction.start;
- uint64_t end1 = 0;
- uint64_t end2 = 0;
-
- if (local1->transaction.len)
- end1 = start1 + local1->transaction.len - 1;
- else
- end1 = ULLONG_MAX;
-
- if (local2->transaction.len)
- end2 = start2 + local2->transaction.len - 1;
- else
- end2 = ULLONG_MAX;
-
- return ((end1 >= start2) && (end2 >= start1));
-}
-
-void
-afr_transaction_eager_lock_init (afr_local_t *local, xlator_t *this)
-{
- afr_private_t *priv = NULL;
- afr_fd_ctx_t *fdctx = NULL;
- afr_local_t *each = NULL;
-
- priv = this->private;
-
- if (!local->fd)
- return;
-
- if (local->transaction.type != AFR_DATA_TRANSACTION)
- return;
-
- if (!priv->eager_lock)
- return;
-
- fdctx = afr_fd_ctx_get (local->fd, this);
- if (!fdctx)
- return;
-
- if (afr_are_multiple_fds_opened (local->fd, this))
- return;
- /*
- * Once full file lock is acquired in eager-lock phase, overlapping
- * writes do not compete for inode-locks, instead are transferred to the
- * next writes. Because of this overlapping writes are not ordered.
- * This can cause inconsistencies in replication.
- * Example:
- * Two overlapping writes w1, w2 are sent in parallel on same fd
- * in two threads t1, t2.
- * Both threads can execute afr_writev_wind in the following manner.
- * t1 winds w1 on brick-0
- * t2 winds w2 on brick-0
- * t2 winds w2 on brick-1
- * t1 winds w1 on brick-1
- *
- * This check makes sure the locks are not transferred for
- * overlapping writes.
- */
- LOCK (&local->fd->lock);
- {
- list_for_each_entry (each, &fdctx->eager_locked,
- transaction.eager_locked) {
- if (afr_locals_overlap (each, local)) {
- local->transaction.eager_lock_on = _gf_false;
- goto unlock;
- }
- }
-
- local->transaction.eager_lock_on = _gf_true;
- list_add_tail (&local->transaction.eager_locked,
- &fdctx->eager_locked);
- }
-unlock:
- UNLOCK (&local->fd->lock);
+ __mark_child_dead (local->pending, priv->child_count,
+ child_index, local->transaction.type);
}
-int
+int32_t
afr_transaction (call_frame_t *frame, xlator_t *this, afr_transaction_type type)
{
- afr_local_t * local = NULL;
- afr_private_t * priv = NULL;
- fd_t *fd = NULL;
- int ret = -1;
+ afr_local_t * local = NULL;
+ afr_private_t * priv = NULL;
- local = frame->local;
- priv = this->private;
+ local = frame->local;
+ priv = this->private;
- local->transaction.resume = afr_transaction_resume;
- local->transaction.type = type;
+ afr_transaction_local_init (local, priv);
- ret = afr_transaction_local_init (local, this);
- if (ret < 0)
- goto out;
+ local->transaction.resume = afr_transaction_resume;
+ local->transaction.type = type;
- afr_transaction_eager_lock_init (local, this);
-
- if (local->fd && local->transaction.eager_lock_on)
- afr_set_lk_owner (frame, this, local->fd);
- else
- afr_set_lk_owner (frame, this, frame->root);
+ if (afr_lock_server_count (priv, local->transaction.type) == 0) {
+ 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);
- if (!local->transaction.eager_lock_on && local->loc.inode) {
- fd = fd_lookup (local->loc.inode, frame->root->pid);
- if (fd == NULL)
- fd = fd_lookup_anonymous (local->loc.inode);
+ afr_pid_restore (frame);
- if (fd) {
- afr_delayed_changelog_wake_up (this, fd);
- fd_unref (fd);
- }
- }
+ local->transaction.fop (frame, this);
+ }
+ } else {
+ afr_lock (frame, this);
+ }
- if (afr_lock_server_count (priv, local->transaction.type) == 0) {
- afr_internal_lock_finish (frame, this);
- } else {
- afr_lock (frame, this);
- }
- ret = 0;
-out:
- return ret;
+ return 0;
}
diff --git a/xlators/cluster/afr/src/afr-transaction.h b/xlators/cluster/afr/src/afr-transaction.h
index c3ce333b771..0d3d4443e30 100644
--- a/xlators/cluster/afr/src/afr-transaction.h
+++ b/xlators/cluster/afr/src/afr-transaction.h
@@ -1,18 +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-2009 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 __TRANSACTION_H__
#define __TRANSACTION_H__
-#include "afr.h"
-
void
afr_transaction_fop_failed (call_frame_t *frame, xlator_t *this,
int child_index);
@@ -20,35 +27,7 @@ afr_transaction_fop_failed (call_frame_t *frame, xlator_t *this,
int
afr_lock_server_count (afr_private_t *priv, afr_transaction_type type);
-afr_inodelk_t*
-afr_get_inodelk (afr_internal_lock_t *int_lock, char *dom);
-
int32_t
afr_transaction (call_frame_t *frame, xlator_t *this, afr_transaction_type type);
-int
-afr_set_pending_dict (afr_private_t *priv, dict_t *xattr, int32_t **pending);
-
-void
-afr_set_delayed_post_op (call_frame_t *frame, xlator_t *this);
-
-void
-afr_delayed_changelog_wake_up (xlator_t *this, fd_t *fd);
-
-void
-__mark_all_success (call_frame_t *frame, xlator_t *this);
-
-gf_boolean_t
-afr_txn_nothing_failed (call_frame_t *frame, xlator_t *this);
-
-int afr_read_txn (call_frame_t *frame, xlator_t *this, inode_t *inode,
- afr_read_txn_wind_t readfn, afr_transaction_type type);
-
-int afr_read_txn_continue (call_frame_t *frame, xlator_t *this, int subvol);
-
-int __afr_txn_write_fop (call_frame_t *frame, xlator_t *this);
-int __afr_txn_write_done (call_frame_t *frame, xlator_t *this);
-call_frame_t *afr_transaction_detach_fop_frame (call_frame_t *frame);
-gf_boolean_t afr_has_quorum (unsigned char *subvols, xlator_t *this);
-
#endif /* __TRANSACTION_H__ */
diff --git a/xlators/cluster/afr/src/afr.c b/xlators/cluster/afr/src/afr.c
index 1382f266872..9df5d5c0e31 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>
- 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-2009 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 <libgen.h>
@@ -19,751 +28,3123 @@
#define _CONFIG_H
#include "config.h"
#endif
-#include "afr-common.c"
-
-struct volume_options options[];
-int32_t
-notify (xlator_t *this, int32_t event,
- void *data, ...)
-{
- int ret = -1;
- va_list ap;
- void *data2 = NULL;
+#include "glusterfs.h"
+#include "afr.h"
+#include "dict.h"
+#include "xlator.h"
+#include "hashfn.h"
+#include "logging.h"
+#include "stack.h"
+#include "list.h"
+#include "call-stub.h"
+#include "defaults.h"
+#include "common-utils.h"
+#include "compat-errno.h"
+#include "compat.h"
+#include "byte-order.h"
+#include "statedump.h"
+
+#include "fd.h"
+
+#include "afr-inode-read.h"
+#include "afr-inode-write.h"
+#include "afr-dir-read.h"
+#include "afr-dir-write.h"
+#include "afr-transaction.h"
+
+#include "afr-self-heal.h"
+
+#define AFR_ICTX_OPENDIR_DONE_MASK 0x0000000200000000ULL
+#define AFR_ICTX_SPLIT_BRAIN_MASK 0x0000000100000000ULL
+#define AFR_ICTX_READ_CHILD_MASK 0x00000000FFFFFFFFULL
- va_start (ap, data);
- data2 = va_arg (ap, dict_t*);
- va_end (ap);
- ret = afr_notify (this, event, data, data2);
- return ret;
+void
+afr_set_lk_owner (call_frame_t *frame, xlator_t *this)
+{
+ if (!frame->root->lk_owner) {
+ gf_log (this->name, GF_LOG_TRACE,
+ "Setting lk-owner=%llu",
+ (unsigned long long) frame->root);
+ frame->root->lk_owner = (uint64_t) frame->root;
+ }
}
-int32_t
-mem_acct_init (xlator_t *this)
+uint64_t
+afr_is_split_brain (xlator_t *this, inode_t *inode)
{
- int ret = -1;
+ int ret = 0;
- if (!this)
- return ret;
+ uint64_t ctx = 0;
+ uint64_t split_brain = 0;
- ret = xlator_mem_acct_init (this, gf_afr_mt_end + 1);
+ VALIDATE_OR_GOTO (inode, out);
- if (ret != 0) {
- gf_log(this->name, GF_LOG_ERROR, "Memory accounting init"
- "failed");
- return ret;
+ LOCK (&inode->lock);
+ {
+ ret = __inode_ctx_get (inode, this, &ctx);
+
+ if (ret < 0)
+ goto unlock;
+
+ split_brain = ctx & AFR_ICTX_SPLIT_BRAIN_MASK;
}
+unlock:
+ UNLOCK (&inode->lock);
- return ret;
+out:
+ return split_brain;
}
-int
-xlator_subvolume_index (xlator_t *this, xlator_t *subvol)
+void
+afr_set_split_brain (xlator_t *this, inode_t *inode, gf_boolean_t set)
{
- int index = -1;
- int i = 0;
- xlator_list_t *list = NULL;
+ uint64_t ctx = 0;
+ int ret = 0;
- list = this->children;
+ VALIDATE_OR_GOTO (inode, out);
- while (list) {
- if (subvol == list->xlator ||
- strcmp (subvol->name, list->xlator->name) == 0) {
- index = i;
- break;
+ LOCK (&inode->lock);
+ {
+ ret = __inode_ctx_get (inode, this, &ctx);
+
+ if (ret < 0) {
+ ctx = 0;
}
- list = list->next;
- i++;
+
+ if (set) {
+ ctx = (~AFR_ICTX_SPLIT_BRAIN_MASK & ctx)
+ | (0xFFFFFFFFFFFFFFFFULL & AFR_ICTX_SPLIT_BRAIN_MASK);
+ } else {
+ ctx = (~AFR_ICTX_SPLIT_BRAIN_MASK & ctx);
+ }
+ __inode_ctx_put (inode, this, ctx);
}
+ UNLOCK (&inode->lock);
+out:
+ return;
+}
+
+
+uint64_t
+afr_is_opendir_done (xlator_t *this, inode_t *inode)
+{
+ int ret = 0;
+
+ uint64_t ctx = 0;
+ uint64_t opendir_done = 0;
- return index;
+ VALIDATE_OR_GOTO (inode, out);
+
+ LOCK (&inode->lock);
+ {
+ ret = __inode_ctx_get (inode, this, &ctx);
+
+ if (ret < 0)
+ goto unlock;
+
+ opendir_done = ctx & AFR_ICTX_OPENDIR_DONE_MASK;
+ }
+unlock:
+ UNLOCK (&inode->lock);
+
+out:
+ return opendir_done;
}
+
void
-fix_quorum_options (xlator_t *this, afr_private_t *priv, char *qtype)
+afr_set_opendir_done (xlator_t *this, inode_t *inode)
{
- if (priv->quorum_count && strcmp(qtype,"fixed")) {
- gf_msg (this->name,GF_LOG_WARNING, 0, AFR_MSG_QUORUM_OVERRIDE,
- "quorum-type %s overriding quorum-count %u",
- qtype, priv->quorum_count);
+ uint64_t ctx = 0;
+ int ret = 0;
+
+ VALIDATE_OR_GOTO (inode, out);
+
+ LOCK (&inode->lock);
+ {
+ ret = __inode_ctx_get (inode, this, &ctx);
+
+ if (ret < 0) {
+ ctx = 0;
+ }
+
+ ctx = (~AFR_ICTX_OPENDIR_DONE_MASK & ctx)
+ | (0xFFFFFFFFFFFFFFFFULL & AFR_ICTX_OPENDIR_DONE_MASK);
+
+ __inode_ctx_put (inode, this, ctx);
}
- if (!strcmp(qtype,"none")) {
- priv->quorum_count = 0;
+ UNLOCK (&inode->lock);
+out:
+ return;
+}
+
+
+uint64_t
+afr_read_child (xlator_t *this, inode_t *inode)
+{
+ int ret = 0;
+
+ uint64_t ctx = 0;
+ uint64_t read_child = 0;
+
+ VALIDATE_OR_GOTO (inode, out);
+
+ LOCK (&inode->lock);
+ {
+ ret = __inode_ctx_get (inode, this, &ctx);
+
+ if (ret < 0)
+ goto unlock;
+
+ read_child = ctx & AFR_ICTX_READ_CHILD_MASK;
}
- else if (!strcmp(qtype,"auto")) {
- priv->quorum_count = AFR_QUORUM_AUTO;
+unlock:
+ UNLOCK (&inode->lock);
+
+out:
+ return read_child;
+}
+
+
+void
+afr_set_read_child (xlator_t *this, inode_t *inode, int32_t read_child)
+{
+ uint64_t ctx = 0;
+ int ret = 0;
+
+ VALIDATE_OR_GOTO (inode, out);
+
+ LOCK (&inode->lock);
+ {
+ ret = __inode_ctx_get (inode, this, &ctx);
+
+ if (ret < 0) {
+ ctx = 0;
+ }
+
+ ctx = (~AFR_ICTX_READ_CHILD_MASK & ctx)
+ | (AFR_ICTX_READ_CHILD_MASK & read_child);
+
+ __inode_ctx_put (inode, this, ctx);
}
+ UNLOCK (&inode->lock);
+
+out:
+ return;
}
-int
-reconfigure (xlator_t *this, dict_t *options)
+
+/**
+ * afr_local_cleanup - cleanup everything in frame->local
+ */
+
+void
+afr_local_sh_cleanup (afr_local_t *local, xlator_t *this)
{
- afr_private_t *priv = NULL;
- xlator_t *read_subvol = NULL;
- int read_subvol_index = -1;
- int ret = -1;
- int index = -1;
- char *qtype = NULL;
+ afr_self_heal_t *sh = NULL;
+ afr_private_t *priv = NULL;
+ int i = 0;
- priv = this->private;
- GF_OPTION_RECONF ("afr-dirty-xattr",
- priv->afr_dirty, options, str,
- out);
+ sh = &local->self_heal;
+ priv = this->private;
- GF_OPTION_RECONF ("metadata-splitbrain-forced-heal",
- priv->metadata_splitbrain_forced_heal, options, bool,
- out);
+ if (sh->buf)
+ FREE (sh->buf);
- GF_OPTION_RECONF ("background-self-heal-count",
- priv->background_self_heal_count, options, uint32,
- out);
+ if (sh->xattr) {
+ for (i = 0; i < priv->child_count; i++) {
+ if (sh->xattr[i]) {
+ dict_unref (sh->xattr[i]);
+ sh->xattr[i] = NULL;
+ }
+ }
+ FREE (sh->xattr);
+ }
- GF_OPTION_RECONF ("metadata-self-heal",
- priv->metadata_self_heal, options, bool, out);
+ if (sh->child_errno)
+ FREE (sh->child_errno);
- GF_OPTION_RECONF ("data-self-heal", priv->data_self_heal, options, str,
- out);
+ if (sh->pending_matrix) {
+ for (i = 0; i < priv->child_count; i++) {
+ FREE (sh->pending_matrix[i]);
+ }
+ FREE (sh->pending_matrix);
+ }
- GF_OPTION_RECONF ("entry-self-heal", priv->entry_self_heal, options,
- bool, out);
+ if (sh->delta_matrix) {
+ for (i = 0; i < priv->child_count; i++) {
+ FREE (sh->delta_matrix[i]);
+ }
+ FREE (sh->delta_matrix);
+ }
- GF_OPTION_RECONF ("data-self-heal-window-size",
- priv->data_self_heal_window_size, options,
- uint32, out);
+ if (sh->sources)
+ FREE (sh->sources);
- GF_OPTION_RECONF ("data-change-log", priv->data_change_log, options,
- bool, out);
+ if (sh->success)
+ FREE (sh->success);
- GF_OPTION_RECONF ("metadata-change-log",
- priv->metadata_change_log, options, bool, out);
+ if (sh->locked_nodes)
+ FREE (sh->locked_nodes);
- GF_OPTION_RECONF ("entry-change-log", priv->entry_change_log, options,
- bool, out);
+ if (sh->healing_fd && !sh->healing_fd_opened) {
+ fd_unref (sh->healing_fd);
+ sh->healing_fd = NULL;
+ }
- GF_OPTION_RECONF ("data-self-heal-algorithm",
- priv->data_self_heal_algorithm, options, str, out);
+ if (sh->linkname)
+ FREE (sh->linkname);
- GF_OPTION_RECONF ("read-subvolume", read_subvol, options, xlator, out);
+ loc_wipe (&sh->parent_loc);
+}
- 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);
- goto out;
- }
- priv->read_child = index;
+void
+afr_local_transaction_cleanup (afr_local_t *local, xlator_t *this)
+{
+ int i = 0;
+ afr_private_t * priv = NULL;
+
+ priv = this->private;
+
+ for (i = 0; i < priv->child_count; i++) {
+ if (local->pending && local->pending[i])
+ FREE (local->pending[i]);
}
- GF_OPTION_RECONF ("read-subvolume-index",read_subvol_index, options,int32,out);
+ FREE (local->pending);
- 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);
- goto out;
+ FREE (local->transaction.locked_nodes);
+ FREE (local->transaction.child_errno);
+ FREE (local->child_errno);
+
+ FREE (local->transaction.basename);
+ FREE (local->transaction.new_basename);
+
+ loc_wipe (&local->transaction.parent_loc);
+ loc_wipe (&local->transaction.new_parent_loc);
+}
+
+
+void
+afr_local_cleanup (afr_local_t *local, xlator_t *this)
+{
+ int i;
+ afr_private_t * priv = NULL;
+
+ if (!local)
+ return;
+
+ afr_local_sh_cleanup (local, this);
+
+ afr_local_transaction_cleanup (local, this);
+
+ priv = this->private;
+
+ loc_wipe (&local->loc);
+ loc_wipe (&local->newloc);
+
+ if (local->fd)
+ fd_unref (local->fd);
+
+ if (local->xattr_req)
+ dict_unref (local->xattr_req);
+
+ FREE (local->child_up);
+
+ { /* lookup */
+ if (local->cont.lookup.xattrs) {
+ 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;
+ }
+ }
+ FREE (local->cont.lookup.xattrs);
+ local->cont.lookup.xattrs = NULL;
}
- priv->read_child = index;
+
+ if (local->cont.lookup.xattr) {
+ dict_unref (local->cont.lookup.xattr);
+ }
+
+ if (local->cont.lookup.inode) {
+ inode_unref (local->cont.lookup.inode);
+ }
+ }
+
+ { /* getxattr */
+ if (local->cont.getxattr.name)
+ FREE (local->cont.getxattr.name);
+ }
+
+ { /* lk */
+ if (local->cont.lk.locked_nodes)
+ FREE (local->cont.lk.locked_nodes);
+ }
+
+ { /* checksum */
+ if (local->cont.checksum.file_checksum)
+ FREE (local->cont.checksum.file_checksum);
+ if (local->cont.checksum.dir_checksum)
+ FREE (local->cont.checksum.dir_checksum);
+ }
+
+ { /* create */
+ if (local->cont.create.fd)
+ fd_unref (local->cont.create.fd);
+ }
+
+ { /* writev */
+ FREE (local->cont.writev.vector);
+ }
+
+ { /* setxattr */
+ if (local->cont.setxattr.dict)
+ dict_unref (local->cont.setxattr.dict);
+ }
+
+ { /* removexattr */
+ FREE (local->cont.removexattr.name);
+ }
+
+ { /* symlink */
+ FREE (local->cont.symlink.linkpath);
+ }
+
+ { /* opendir */
+ if (local->cont.opendir.checksum)
+ FREE (local->cont.opendir.checksum);
}
+}
+
+
+int
+afr_frame_return (call_frame_t *frame)
+{
+ afr_local_t *local = NULL;
+ int call_count = 0;
+
+ local = frame->local;
+
+ LOCK (&frame->lock);
+ {
+ call_count = --local->call_count;
+ }
+ UNLOCK (&frame->lock);
+
+ return call_count;
+}
- GF_OPTION_RECONF ("pre-op-compat", priv->pre_op_compat, options, bool, out);
- 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);
- if (priv->quorum_count && !afr_has_quorum (priv->child_up, this))
- gf_msg (this->name, GF_LOG_WARNING, 0, AFR_MSG_QUORUM_FAIL,
- "Client-quorum is not met");
+/**
+ * up_children_count - return the number of children that are up
+ */
+int
+afr_up_children_count (int child_count, unsigned char *child_up)
+{
+ int i = 0;
+ int ret = 0;
- GF_OPTION_RECONF ("post-op-delay-secs", priv->post_op_delay_secs, options,
- uint32, out);
+ for (i = 0; i < child_count; i++)
+ if (child_up[i])
+ ret++;
+ return ret;
+}
- GF_OPTION_RECONF (AFR_SH_READDIR_SIZE_KEY, priv->sh_readdir_size,
- options, size_uint64, out);
- /* Reset this so we re-discover in case the topology changed. */
- GF_OPTION_RECONF ("ensure-durability", priv->ensure_durability, options,
- bool, out);
- GF_OPTION_RECONF ("self-heal-daemon", priv->shd.enabled, options,
- bool, out);
+int
+afr_locked_nodes_count (unsigned char *locked_nodes, int child_count)
+{
+ int ret = 0;
+ int i;
- GF_OPTION_RECONF ("iam-self-heal-daemon", priv->shd.iamshd, options,
- bool, out);
+ for (i = 0; i < child_count; i++)
+ if (locked_nodes[i])
+ ret++;
- GF_OPTION_RECONF ("consistent-metadata", priv->consistent_metadata,
- options, bool, out);
+ return ret;
+}
- priv->did_discovery = _gf_false;
- ret = 0;
+ino64_t
+afr_itransform (ino64_t ino, int child_count, int child_index)
+{
+ ino64_t scaled_ino = -1;
+
+ if (ino == ((uint64_t) -1)) {
+ scaled_ino = ((uint64_t) -1);
+ goto out;
+ }
+
+ scaled_ino = (ino * child_count) + child_index;
+
out:
- return ret;
+ return scaled_ino;
+}
+
+
+int
+afr_deitransform_orig (ino64_t ino, int child_count)
+{
+ int index = -1;
+
+ index = ino % child_count;
+ return index;
}
-static const char *favorite_child_warning_str = "You have specified subvolume '%s' "
- "as the 'favorite child'. This means that if a discrepancy in the content "
- "or attributes (ownership, permission, etc.) of a file is detected among "
- "the subvolumes, the file on '%s' will be considered the definitive "
- "version and its contents will OVERWRITE the contents of the file on other "
- "subvolumes. All versions of the file except that on '%s' "
- "WILL BE LOST.";
+int
+afr_deitransform (ino64_t ino, int child_count)
+{
+ return 0;
+}
-int32_t
-init (xlator_t *this)
+int
+afr_self_heal_lookup_unwind (call_frame_t *frame, 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;
-
- if (!this->children) {
- gf_log (this->name, GF_LOG_ERROR,
- "replicate translator needs more than one "
- "subvolume defined.");
- return -1;
+ afr_local_t *local = NULL;
+
+ local = frame->local;
+
+ if (local->govinda_gOvinda) {
+ afr_set_split_brain (this, local->cont.lookup.inode, _gf_true);
+ }
+
+ 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_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 = 0;
+
+ if (afr_sh_has_metadata_pending (xattr, child_index, this))
+ local->self_heal.need_metadata_self_heal = _gf_true;
+
+ if (afr_sh_has_entry_pending (xattr, child_index, this))
+ local->self_heal.need_entry_self_heal = _gf_true;
+
+ if (afr_sh_has_data_pending (xattr, child_index, this))
+ local->self_heal.need_data_self_heal = _gf_true;
+
+ ret = dict_get_uint32 (xattr, GLUSTERFS_INODELK_COUNT,
+ &inodelk_count);
+ if (ret == 0)
+ local->inodelk_count += inodelk_count;
+
+ ret = dict_get_uint32 (xattr, GLUSTERFS_ENTRYLK_COUNT,
+ &entrylk_count);
+ if (ret == 0)
+ local->entrylk_count += entrylk_count;
+}
+
+
+static void
+afr_lookup_self_heal_check (afr_local_t *local, struct stat *buf,
+ struct stat *lookup_buf)
+{
+ if (FILETYPE_DIFFERS (buf, lookup_buf)) {
+ /* mismatching filetypes with same name
+ -- Govinda !! GOvinda !!!
+ */
+
+ gf_log ("afr", GF_LOG_TRACE,
+ "file %s is govinda!", local->loc.path);
+
+ local->govinda_gOvinda = 1;
}
- if (!this->parents) {
- gf_log (this->name, GF_LOG_WARNING,
- "Volume is dangling.");
+ if (PERMISSION_DIFFERS (buf, lookup_buf)) {
+ /* mismatching permissions */
+ local->self_heal.need_metadata_self_heal = _gf_true;
}
- this->private = GF_CALLOC (1, sizeof (afr_private_t),
- gf_afr_mt_afr_private_t);
- if (!this->private)
- goto out;
+ if (OWNERSHIP_DIFFERS (buf, lookup_buf)) {
+ /* mismatching permissions */
+ local->self_heal.need_metadata_self_heal = _gf_true;
+ }
- priv = this->private;
- LOCK_INIT (&priv->lock);
+ if (SIZE_DIFFERS (buf, lookup_buf)
+ && S_ISREG (buf->st_mode)) {
+ local->self_heal.need_data_self_heal = _gf_true;
+ }
- child_count = xlator_subvolume_count (this);
+}
- priv->child_count = child_count;
- priv->read_child = -1;
+static void
+afr_lookup_done (call_frame_t *frame, xlator_t *this, struct stat *lookup_buf)
+{
+ int unwind = 1;
+ int source = -1;
- GF_OPTION_INIT ("afr-dirty-xattr", priv->afr_dirty, str, out);
+ afr_local_t *local = NULL;
- GF_OPTION_INIT ("metadata-splitbrain-forced-heal",
- priv->metadata_splitbrain_forced_heal, bool, out);
+ local = frame->local;
- 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;
- }
+ local->cont.lookup.postparent.st_ino = local->cont.lookup.parent_ino;
+
+ if (local->cont.lookup.ino) {
+ local->cont.lookup.buf.st_ino = local->cont.lookup.ino;
+ local->cont.lookup.buf.st_dev = local->cont.lookup.gen;
}
- 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;
+
+ if (local->op_ret == 0) {
+ /* KLUDGE: assuming DHT will not itransform in
+ revalidate */
+ if (local->cont.lookup.inode->ino) {
+ local->cont.lookup.buf.st_ino =
+ local->cont.lookup.inode->ino;
+ local->cont.lookup.buf.st_dev =
+ local->cont.lookup.inode->generation;
}
- 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);
+ 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;
+ }
- 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;
+ 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;
+ }
+
+ 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))) {
+
+ if (local->inodelk_count || local->entrylk_count) {
+
+ /* Someone else is doing self-heal on this file.
+ So just make a best effort to set the read-subvolume
+ and return */
+
+ if (S_ISREG (local->cont.lookup.inode->st_mode)) {
+ source = afr_self_heal_get_source (this, local, local->cont.lookup.xattrs);
+
+ if (source >= 0) {
+ afr_set_read_child (this,
+ local->cont.lookup.inode,
+ source);
+ }
+ }
+ } else {
+ if (!local->cont.lookup.inode->st_mode) {
+ /* fix for RT #602 */
+ local->cont.lookup.inode->st_mode =
+ lookup_buf->st_mode;
+ }
+
+ local->self_heal.background = _gf_true;
+ local->self_heal.mode = local->cont.lookup.buf.st_mode;
+ local->self_heal.unwind = afr_self_heal_lookup_unwind;
+
+ unwind = 0;
+
+ afr_self_heal (frame, this);
}
- gf_log (this->name, GF_LOG_WARNING,
- favorite_child_warning_str, fav_child->name,
- fav_child->name, fav_child->name);
}
+ 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
+ * returning to the user.
+ *
+ * The hierarchy is ESTALE > ENOENT > others
+ *
+ */
+
+static gf_boolean_t
+__error_more_important (int32_t old_errno, int32_t new_errno)
+{
+ gf_boolean_t ret = _gf_true;
+
+ /* Nothing should ever overwrite ESTALE */
+ if (old_errno == ESTALE)
+ ret = _gf_false;
+
+ /* Nothing should overwrite ENOENT, except ESTALE */
+ else if ((old_errno == ENOENT) && (new_errno != ESTALE))
+ ret = _gf_false;
+
+ return ret;
+}
+
+
+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 stat *buf, dict_t *xattr,
+ struct stat *postparent)
+{
+ afr_local_t * local = NULL;
+ afr_private_t * priv = NULL;
+ struct stat * lookup_buf = NULL;
+
+ int call_count = -1;
+ int child_index = -1;
+ int first_up_child = -1;
+
+ child_index = (long) cookie;
+ priv = this->private;
+
+ LOCK (&frame->lock);
+ {
+ local = frame->local;
+
+ lookup_buf = &local->cont.lookup.buf;
+
+ if (op_ret == -1) {
+ 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_collect_xattr (local, this, child_index, xattr);
+
+ first_up_child = afr_first_up_child (priv);
+
+ if (child_index == first_up_child) {
+ local->cont.lookup.ino =
+ afr_itransform (buf->st_ino,
+ priv->child_count,
+ first_up_child);
+ local->cont.lookup.gen = buf->st_dev;
+ }
+
+ if (local->success_count == 0) {
+ if (local->op_errno != ESTALE)
+ local->op_ret = op_ret;
+
+ 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;
+
+ *lookup_buf = *buf;
+
+ lookup_buf->st_ino = afr_itransform (buf->st_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);
+ }
+
+ } else {
+ afr_lookup_self_heal_check (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;
+
+ 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,
+ local->read_child_index);
+ }
+ }
+
+ }
+
+ 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_revalidate_lookup_cbk (call_frame_t *frame, void *cookie,
+ xlator_t *this, int32_t op_ret, int32_t op_errno,
+ inode_t *inode, struct stat *buf, dict_t *xattr,
+ struct stat *postparent)
+{
+ afr_local_t * local = NULL;
+ afr_private_t * priv = NULL;
+ struct stat * lookup_buf = NULL;
+
+ int call_count = -1;
+ int child_index = -1;
+ int first_up_child = -1;
+
+ child_index = (long) cookie;
+ priv = this->private;
+
+ LOCK (&frame->lock);
+ {
+ local = frame->local;
+
+ lookup_buf = &local->cont.lookup.buf;
+
+ if (op_ret == -1) {
+ 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_collect_xattr (local, this, child_index, xattr);
+
+ first_up_child = afr_first_up_child (priv);
+
+ if (child_index == first_up_child) {
+ local->cont.lookup.ino =
+ afr_itransform (buf->st_ino,
+ priv->child_count,
+ first_up_child);
+ local->cont.lookup.gen = buf->st_dev;
+ }
+
+ /* 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 */
+
+ /* inode number should be preserved across revalidates */
+
+ if (local->success_count == 0) {
+ if (local->op_errno != ESTALE)
+ local->op_ret = op_ret;
- GF_OPTION_INIT ("background-self-heal-count",
- priv->background_self_heal_count, uint32, 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;
- GF_OPTION_INIT ("data-self-heal", priv->data_self_heal, str, out);
+ *lookup_buf = *buf;
- GF_OPTION_INIT ("data-self-heal-algorithm",
- priv->data_self_heal_algorithm, str, out);
+ lookup_buf->st_ino = afr_itransform (buf->st_ino,
+ priv->child_count,
+ child_index);
- GF_OPTION_INIT ("data-self-heal-window-size",
- priv->data_self_heal_window_size, uint32, out);
+ 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);
+ }
- GF_OPTION_INIT ("metadata-self-heal", priv->metadata_self_heal, bool,
- out);
+ } else {
+ afr_lookup_self_heal_check (local, buf, lookup_buf);
- GF_OPTION_INIT ("entry-self-heal", priv->entry_self_heal, bool, out);
+ if (child_index == local->read_child_index) {
- GF_OPTION_INIT ("data-change-log", priv->data_change_log, bool, out);
+ /*
+ lookup has succeeded on the read child.
+ So use its inode number
+ */
- GF_OPTION_INIT ("metadata-change-log", priv->metadata_change_log, bool,
- out);
+ if (local->cont.lookup.xattr)
+ dict_unref (local->cont.lookup.xattr);
- GF_OPTION_INIT ("entry-change-log", priv->entry_change_log, bool, out);
+ local->cont.lookup.xattr = dict_ref (xattr);
+ local->cont.lookup.xattrs[child_index] = dict_ref (xattr);
+ local->cont.lookup.postparent = *postparent;
- GF_OPTION_INIT ("optimistic-change-log", priv->optimistic_change_log,
- bool, out);
+ *lookup_buf = *buf;
- GF_OPTION_INIT ("inodelk-trace", priv->inodelk_trace, bool, out);
+ 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,
+ local->read_child_index);
+ }
+ }
- GF_OPTION_INIT ("entrylk-trace", priv->entrylk_trace, bool, out);
+ }
- GF_OPTION_INIT ("pre-op-compat", priv->pre_op_compat, bool, out);
+ 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;
+}
- 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);
- GF_OPTION_INIT (AFR_SH_READDIR_SIZE_KEY, priv->sh_readdir_size, size_uint64,
- out);
- fix_quorum_options(this,priv,qtype);
- GF_OPTION_INIT ("post-op-delay-secs", priv->post_op_delay_secs, uint32, out);
- GF_OPTION_INIT ("ensure-durability", priv->ensure_durability, bool,
- out);
+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;
+ int ret = -1;
+ int i = 0;
- GF_OPTION_INIT ("self-heal-daemon", priv->shd.enabled, bool, out);
+ fop_lookup_cbk_t callback;
- GF_OPTION_INIT ("iam-self-heal-daemon", priv->shd.iamshd, bool, out);
+ int call_count = 0;
- GF_OPTION_INIT ("consistent-metadata", priv->consistent_metadata, bool,
- out);
+ uint64_t ctx;
- priv->wait_count = 1;
+ int32_t op_errno = 0;
- priv->child_up = GF_CALLOC (sizeof (unsigned char), child_count,
- gf_afr_mt_char);
- if (!priv->child_up) {
- ret = -ENOMEM;
+ priv = this->private;
+
+ ALLOC_OR_GOTO (local, afr_local_t, out);
+
+ local->op_ret = -1;
+
+ frame->local = local;
+
+ if (!strcmp (loc->path, "/" GF_REPLICATE_TRASH_DIR)) {
+ op_errno = ENOENT;
goto out;
}
- for (i = 0; i < child_count; i++)
- priv->child_up[i] = -1; /* start with unknown state.
- this initialization needed
- for afr_notify() to work
- reliably
- */
-
- priv->children = GF_CALLOC (sizeof (xlator_t *), child_count,
- gf_afr_mt_xlator_t);
- if (!priv->children) {
- ret = -ENOMEM;
- goto out;
+ loc_copy (&local->loc, loc);
+
+ ret = inode_ctx_get (loc->inode, this, &ctx);
+ if (ret == 0) {
+ /* lookup is a revalidate */
+
+ 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);
+ {
+ local->read_child_index = (++priv->read_child_rr)
+ % (priv->child_count);
+ }
+ UNLOCK (&priv->read_child_lock);
}
- priv->pending_key = GF_CALLOC (sizeof (*priv->pending_key),
- child_count,
- gf_afr_mt_char);
- if (!priv->pending_key) {
- ret = -ENOMEM;
+ local->child_up = memdup (priv->child_up, priv->child_count);
+
+ local->cont.lookup.xattrs = CALLOC (priv->child_count,
+ sizeof (*local->cont.lookup.xattr));
+
+ 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;
goto out;
}
- trav = this->children;
- i = 0;
- while (i < child_count) {
- priv->children[i] = trav->xlator;
+ /* By default assume ENOTCONN. On success it will be set to 0. */
+ local->op_errno = ENOTCONN;
+
+ 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));
+
+ /* 3 = data+metadata+entry */
+ }
- ret = gf_asprintf (&priv->pending_key[i], "%s.%s",
- AFR_XATTR_PREFIX,
- trav->xlator->name);
- if (-1 == ret) {
- ret = -ENOMEM;
- goto out;
+ ret = dict_set_uint64 (local->xattr_req, GLUSTERFS_INODELK_COUNT, 0);
+ ret = dict_set_uint64 (local->xattr_req, GLUSTERFS_ENTRYLK_COUNT, 0);
+
+ for (i = 0; i < priv->child_count; i++) {
+ if (local->child_up[i]) {
+ STACK_WIND_COOKIE (frame, callback, (void *) (long) i,
+ priv->children[i],
+ priv->children[i]->fops->lookup,
+ loc, local->xattr_req);
+ if (!--call_count)
+ break;
+ }
+ }
+
+ ret = 0;
+out:
+ if (ret == -1)
+ AFR_STACK_UNWIND (lookup, frame, -1, op_errno,
+ NULL, NULL, NULL, NULL);
+
+ return 0;
+}
+
+
+/* {{{ open */
+
+int
+afr_fd_ctx_set (xlator_t *this, fd_t *fd)
+{
+ afr_private_t * priv = NULL;
+
+ int op_ret = 0;
+ int ret = 0;
+
+ uint64_t ctx;
+ afr_fd_ctx_t * fd_ctx = NULL;
+
+ VALIDATE_OR_GOTO (this->private, out);
+ VALIDATE_OR_GOTO (fd, out);
+
+ priv = this->private;
+
+ LOCK (&fd->lock);
+ {
+ ret = __fd_ctx_get (fd, this, &ctx);
+
+ if (ret == 0)
+ goto unlock;
+
+ fd_ctx = CALLOC (1, sizeof (afr_fd_ctx_t));
+ if (!fd_ctx) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory");
+
+ op_ret = -ENOMEM;
+ goto unlock;
+ }
+
+ fd_ctx->pre_op_done = CALLOC (sizeof (*fd_ctx->pre_op_done),
+ priv->child_count);
+ if (!fd_ctx->pre_op_done) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory");
+ op_ret = -ENOMEM;
+ goto unlock;
+ }
+
+ fd_ctx->opened_on = CALLOC (sizeof (*fd_ctx->opened_on),
+ priv->child_count);
+ if (!fd_ctx->opened_on) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory");
+ op_ret = -ENOMEM;
+ goto unlock;
+ }
+
+ fd_ctx->pre_op_piggyback = CALLOC (sizeof (*fd_ctx->pre_op_piggyback),
+ priv->child_count);
+
+ if (!fd_ctx->pre_op_piggyback) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory");
+
+ op_ret = -ENOMEM;
+ goto unlock;
}
- trav = trav->next;
- i++;
+ fd_ctx->up_count = priv->up_count;
+ fd_ctx->down_count = priv->down_count;
+
+ ret = __fd_ctx_set (fd, this, (uint64_t)(long) fd_ctx);
+ if (ret < 0) {
+ op_ret = ret;
+ }
+
+ INIT_LIST_HEAD (&fd_ctx->entries);
}
+unlock:
+ UNLOCK (&fd->lock);
+out:
+ return ret;
+}
+
+/* {{{ flush */
+
+int
+afr_flush_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);
+ {
+ if (local->transaction.main_frame)
+ main_frame = local->transaction.main_frame;
+ local->transaction.main_frame = NULL;
+ }
+ UNLOCK (&frame->lock);
- ret = gf_asprintf (&priv->sh_domain, AFR_SH_DATA_DOMAIN_FMT,
- this->name);
- if (-1 == ret) {
- ret = -ENOMEM;
+ if (main_frame) {
+ AFR_STACK_UNWIND (flush, main_frame,
+ local->op_ret, local->op_errno);
+ }
+
+ return 0;
+}
+
+
+int
+afr_flush_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno)
+{
+ afr_local_t * local = NULL;
+ afr_private_t * priv = NULL;
+
+ int call_count = -1;
+ int child_index = (long) cookie;
+ int need_unwind = 0;
+
+ local = frame->local;
+ priv = this->private;
+
+ LOCK (&frame->lock);
+ {
+ if (afr_fop_failed (op_ret, op_errno))
+ afr_transaction_fop_failed (frame, this, child_index);
+
+ 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)
+ afr_flush_unwind (frame, this);
+
+ call_count = afr_frame_return (frame);
+
+ if (call_count == 0) {
+ local->transaction.resume (frame, this);
+ }
+
+ return 0;
+}
+
+
+int
+afr_flush_wind (call_frame_t *frame, xlator_t *this)
+{
+ afr_local_t *local = NULL;
+ afr_private_t *priv = NULL;
+
+ int i = 0;
+ int call_count = -1;
+
+ local = frame->local;
+ priv = this->private;
+
+ call_count = afr_up_children_count (priv->child_count, local->child_up);
+
+ 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->child_up[i]) {
+ STACK_WIND_COOKIE (frame, afr_flush_wind_cbk,
+ (void *) (long) i,
+ priv->children[i],
+ priv->children[i]->fops->flush,
+ local->fd);
+
+ if (!--call_count)
+ break;
+ }
+ }
+
+ return 0;
+}
+
+
+int
+afr_flush_done (call_frame_t *frame, xlator_t *this)
+{
+ afr_local_t *local = NULL;
+
+ local = frame->local;
+
+ local->transaction.unwind (frame, this);
+
+ AFR_STACK_DESTROY (frame);
+
+ return 0;
+}
+
+
+int
+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_ret = -1;
+ int op_errno = 0;
+
+ int call_count = 0;
+
+ VALIDATE_OR_GOTO (frame, out);
+ VALIDATE_OR_GOTO (this, out);
+ VALIDATE_OR_GOTO (this->private, out);
+
+ 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;
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory.");
goto out;
}
- priv->last_event = GF_CALLOC (child_count, sizeof (*priv->last_event),
- gf_afr_mt_int32_t);
- if (!priv->last_event) {
- ret = -ENOMEM;
+ transaction_frame->local = local;
+
+ local->op = GF_FOP_FLUSH;
+
+ local->transaction.fop = afr_flush_wind;
+ local->transaction.done = afr_flush_done;
+ local->transaction.unwind = afr_flush_unwind;
+
+ local->fd = fd_ref (fd);
+
+ local->transaction.main_frame = frame;
+ local->transaction.start = 0;
+ local->transaction.len = 0;
+
+ afr_transaction (transaction_frame, this, AFR_DATA_TRANSACTION);
+
+ op_ret = 0;
+out:
+ if (op_ret == -1) {
+ if (transaction_frame)
+ AFR_STACK_DESTROY (transaction_frame);
+
+ AFR_STACK_UNWIND (flush, frame, op_ret, op_errno);
+ }
+
+ return 0;
+}
+
+/* }}} */
+
+
+int
+afr_cleanup_fd_ctx (xlator_t *this, fd_t *fd)
+{
+ uint64_t ctx = 0;
+ afr_fd_ctx_t *fd_ctx = NULL;
+ int ret = 0;
+
+ ret = fd_ctx_get (fd, this, &ctx);
+
+ if (ret < 0)
goto out;
+
+ fd_ctx = (afr_fd_ctx_t *)(long) ctx;
+
+ if (fd_ctx) {
+ if (fd_ctx->pre_op_piggyback)
+ FREE (fd_ctx->pre_op_piggyback);
+
+ if (fd_ctx->pre_op_done)
+ FREE (fd_ctx->pre_op_done);
+
+ if (fd_ctx->opened_on)
+ FREE (fd_ctx->opened_on);
+
+ FREE (fd_ctx);
+ }
+
+out:
+ return 0;
+}
+
+
+int
+afr_release (xlator_t *this, fd_t *fd)
+{
+ afr_cleanup_fd_ctx (this, fd);
+
+ return 0;
+}
+
+
+/* {{{ fsync */
+
+int
+afr_fsync_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct stat *prebuf,
+ struct stat *postbuf)
+{
+ afr_local_t *local = NULL;
+
+ int call_count = -1;
+
+ int child_index = (long) cookie;
+ int read_child = 0;
+
+ local = frame->local;
+
+ read_child = afr_read_child (this, local->fd->inode);
+
+ LOCK (&frame->lock);
+ {
+ if (child_index == read_child) {
+ local->read_child_returned = _gf_true;
+ }
+
+ if (op_ret == 0) {
+ local->op_ret = 0;
+
+ if (local->success_count == 0) {
+ local->cont.fsync.prebuf = *prebuf;
+ local->cont.fsync.postbuf = *postbuf;
+ }
+
+ if (child_index == read_child) {
+ local->cont.fsync.prebuf = *prebuf;
+ local->cont.fsync.postbuf = *postbuf;
+ }
+
+ local->success_count++;
+ }
+
+ local->op_errno = op_errno;
+ }
+ UNLOCK (&frame->lock);
+
+ call_count = afr_frame_return (frame);
+
+ if (call_count == 0) {
+ local->cont.fsync.prebuf.st_ino = local->cont.fsync.ino;
+ local->cont.fsync.postbuf.st_ino = local->cont.fsync.ino;
+
+ AFR_STACK_UNWIND (fsync, frame, local->op_ret, local->op_errno,
+ &local->cont.fsync.prebuf,
+ &local->cont.fsync.postbuf);
}
- ret = afr_selfheal_daemon_init (this);
- if (ret) {
- ret = -ENOMEM;
+ return 0;
+}
+
+
+int
+afr_fsync (call_frame_t *frame, xlator_t *this, fd_t *fd,
+ 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);
+ VALIDATE_OR_GOTO (this, out);
+ VALIDATE_OR_GOTO (this->private, out);
+
+ 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;
}
- /* 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;
+ 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]) {
+ STACK_WIND_COOKIE (frame, afr_fsync_cbk,
+ (void *) (long) i,
+ priv->children[i],
+ priv->children[i]->fops->fsync,
+ fd, datasync);
+ if (!--call_count)
+ break;
+ }
+ }
+
+ op_ret = 0;
+out:
+ if (op_ret == -1) {
+ AFR_STACK_UNWIND (fsync, frame, op_ret, op_errno, NULL, NULL);
+ }
+ return 0;
+}
+
+/* }}} */
+
+/* {{{ fsync */
+
+int32_t
+afr_fsyncdir_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;
+
+ local = frame->local;
+
+ LOCK (&frame->lock);
+ {
+ if (op_ret == 0)
+ local->op_ret = 0;
+
+ local->op_errno = op_errno;
+ }
+ UNLOCK (&frame->lock);
+
+ call_count = afr_frame_return (frame);
+
+ if (call_count == 0)
+ AFR_STACK_UNWIND (fsyncdir, frame, local->op_ret,
+ local->op_errno);
+
+ return 0;
+}
+
+
+int32_t
+afr_fsyncdir (call_frame_t *frame, xlator_t *this, fd_t *fd,
+ 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);
+ VALIDATE_OR_GOTO (this, out);
+ VALIDATE_OR_GOTO (this->private, out);
+
+ 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 = 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);
+ if (!--call_count)
+ break;
+ }
+ }
+
+ op_ret = 0;
+out:
+ if (op_ret == -1) {
+ AFR_STACK_UNWIND (fsyncdir, frame, op_ret, op_errno);
+ }
+ return 0;
+}
+
+/* }}} */
+
+/* {{{ xattrop */
+
+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)
+{
+ afr_local_t *local = NULL;
+
+ int call_count = -1;
+
+ local = frame->local;
+
+ LOCK (&frame->lock);
+ {
+ if (op_ret == 0)
+ local->op_ret = 0;
+
+ local->op_errno = op_errno;
+ }
+ UNLOCK (&frame->lock);
+
+ call_count = afr_frame_return (frame);
+
+ if (call_count == 0)
+ AFR_STACK_UNWIND (xattrop, frame, local->op_ret, local->op_errno,
+ xattr);
+
+ return 0;
+}
+
+
+int32_t
+afr_xattrop (call_frame_t *frame, xlator_t *this, loc_t *loc,
+ 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);
+ VALIDATE_OR_GOTO (this, out);
+ VALIDATE_OR_GOTO (this->private, out);
+
+ 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 = 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);
+ if (!--call_count)
+ break;
+ }
+ }
+
+ op_ret = 0;
+out:
+ if (op_ret == -1) {
+ AFR_STACK_UNWIND (xattrop, frame, op_ret, op_errno, NULL);
+ }
+ return 0;
+}
+
+/* }}} */
+
+/* {{{ fxattrop */
+
+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)
+{
+ afr_local_t *local = NULL;
+
+ int call_count = -1;
+
+ local = frame->local;
+
+ LOCK (&frame->lock);
+ {
+ if (op_ret == 0)
+ local->op_ret = 0;
+
+ local->op_errno = op_errno;
+ }
+ UNLOCK (&frame->lock);
+
+ call_count = afr_frame_return (frame);
+
+ if (call_count == 0)
+ AFR_STACK_UNWIND (fxattrop, frame, local->op_ret, local->op_errno,
+ xattr);
+
+ return 0;
+}
+
+
+int32_t
+afr_fxattrop (call_frame_t *frame, xlator_t *this, fd_t *fd,
+ 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);
+ VALIDATE_OR_GOTO (this, out);
+ VALIDATE_OR_GOTO (this->private, out);
+
+ 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 = 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);
+ if (!--call_count)
+ break;
+ }
+ }
+
+ op_ret = 0;
+out:
+ if (op_ret == -1) {
+ AFR_STACK_UNWIND (fxattrop, frame, op_ret, op_errno, NULL);
+ }
+ return 0;
+}
+
+/* }}} */
+
+
+int32_t
+afr_inodelk_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;
+
+ local = frame->local;
+
+ LOCK (&frame->lock);
+ {
+ if (op_ret == 0)
+ local->op_ret = 0;
+
+ local->op_errno = op_errno;
+ }
+ UNLOCK (&frame->lock);
+
+ call_count = afr_frame_return (frame);
+
+ if (call_count == 0)
+ AFR_STACK_UNWIND (inodelk, frame, local->op_ret,
+ local->op_errno);
+
+ return 0;
+}
+
+
+int32_t
+afr_inodelk (call_frame_t *frame, xlator_t *this,
+ const char *volume, loc_t *loc, int32_t cmd, struct 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);
+ VALIDATE_OR_GOTO (this, out);
+ VALIDATE_OR_GOTO (this->private, out);
+
+ 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 = 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);
+
+ if (!--call_count)
+ break;
+ }
+ }
+
+ op_ret = 0;
+out:
+ 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)
+
+{
+ afr_local_t *local = NULL;
+
+ int call_count = -1;
+
+ local = frame->local;
+
+ LOCK (&frame->lock);
+ {
+ if (op_ret == 0)
+ local->op_ret = 0;
+
+ local->op_errno = op_errno;
+ }
+ UNLOCK (&frame->lock);
+
+ call_count = afr_frame_return (frame);
+
+ if (call_count == 0)
+ AFR_STACK_UNWIND (finodelk, frame, local->op_ret,
+ local->op_errno);
+
+ return 0;
+}
+
+
+int32_t
+afr_finodelk (call_frame_t *frame, xlator_t *this,
+ const char *volume, fd_t *fd, int32_t cmd, struct 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);
+ VALIDATE_OR_GOTO (this, out);
+ VALIDATE_OR_GOTO (this->private, out);
+
+ 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 = 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);
+
+ if (!--call_count)
+ break;
+ }
+ }
+
+ op_ret = 0;
+out:
+ 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)
+
+{
+ afr_local_t *local = NULL;
+
+ int call_count = -1;
+
+ local = frame->local;
+
+ LOCK (&frame->lock);
+ {
+ if (op_ret == 0)
+ local->op_ret = 0;
+
+ local->op_errno = op_errno;
+ }
+ UNLOCK (&frame->lock);
+
+ call_count = afr_frame_return (frame);
+
+ if (call_count == 0)
+ AFR_STACK_UNWIND (entrylk, frame, local->op_ret,
+ local->op_errno);
+
+ return 0;
+}
+
+
+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)
+{
+ 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);
+ VALIDATE_OR_GOTO (this, out);
+ VALIDATE_OR_GOTO (this->private, out);
+
+ 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 = 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);
+
+ if (!--call_count)
+ break;
+ }
+ }
+
+ op_ret = 0;
+out:
+ if (op_ret == -1) {
+ AFR_STACK_UNWIND (entrylk, frame, op_ret, op_errno);
+ }
+ return 0;
+}
+
+
+
+int32_t
+afr_fentrylk_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;
+
+ local = frame->local;
+
+ LOCK (&frame->lock);
+ {
+ if (op_ret == 0)
+ local->op_ret = 0;
+
+ local->op_errno = op_errno;
+ }
+ UNLOCK (&frame->lock);
+
+ call_count = afr_frame_return (frame);
+
+ if (call_count == 0)
+ AFR_STACK_UNWIND (fentrylk, frame, local->op_ret,
+ local->op_errno);
+
+ return 0;
+}
+
+
+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)
+{
+ 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);
+ VALIDATE_OR_GOTO (this, out);
+ VALIDATE_OR_GOTO (this->private, out);
+
+ 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 = 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);
+
+ if (!--call_count)
+ break;
+ }
+ }
+
+ op_ret = 0;
+out:
+ if (op_ret == -1) {
+ AFR_STACK_UNWIND (fentrylk, frame, op_ret, op_errno);
+ }
+ return 0;
+}
+
+
+int32_t
+afr_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)
+
+{
+ afr_local_t *local = NULL;
+
+ int call_count = -1;
+
+ local = frame->local;
+
+ LOCK (&frame->lock);
+ {
+ if (op_ret == 0 && (local->op_ret != 0)) {
+ local->op_ret = 0;
+
+ local->cont.checksum.file_checksum = MALLOC (NAME_MAX);
+ memcpy (local->cont.checksum.file_checksum, file_checksum,
+ NAME_MAX);
+
+ local->cont.checksum.dir_checksum = MALLOC (NAME_MAX);
+ memcpy (local->cont.checksum.dir_checksum, dir_checksum,
+ NAME_MAX);
+
+ }
+
+ local->op_errno = op_errno;
+ }
+ UNLOCK (&frame->lock);
+
+ call_count = afr_frame_return (frame);
+
+ if (call_count == 0)
+ AFR_STACK_UNWIND (checksum, frame, local->op_ret, local->op_errno,
+ local->cont.checksum.file_checksum,
+ local->cont.checksum.dir_checksum);
+
+ return 0;
+}
+
+
+int32_t
+afr_checksum (call_frame_t *frame, xlator_t *this, loc_t *loc,
+ int32_t flag)
+{
+ 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);
+ VALIDATE_OR_GOTO (this, out);
+ VALIDATE_OR_GOTO (this->private, out);
+
+ 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 = local->call_count;
+ frame->local = local;
+
+ for (i = 0; i < priv->child_count; i++) {
+ if (local->child_up[i]) {
+ STACK_WIND (frame, afr_checksum_cbk,
+ priv->children[i],
+ priv->children[i]->fops->checksum,
+ loc, flag);
+
+ if (!--call_count)
+ break;
+ }
+ }
+
+ op_ret = 0;
+out:
+ if (op_ret == -1) {
+ AFR_STACK_UNWIND (checksum, frame, op_ret, op_errno,
+ NULL, NULL);
+ }
+ 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)
+{
+ afr_local_t *local = NULL;
+
+ int call_count = 0;
+
+ LOCK (&frame->lock);
+ {
+ local = frame->local;
+
+ if (op_ret == 0) {
+ local->op_ret = op_ret;
+
+ if (local->cont.statfs.buf_set) {
+ if (statvfs->f_bavail < local->cont.statfs.buf.f_bavail)
+ local->cont.statfs.buf = *statvfs;
+ } else {
+ local->cont.statfs.buf = *statvfs;
+ local->cont.statfs.buf_set = 1;
+ }
+ }
+
+ if (op_ret == -1)
+ local->op_errno = op_errno;
+
+ }
+ UNLOCK (&frame->lock);
+
+ call_count = afr_frame_return (frame);
+
+ if (call_count == 0)
+ AFR_STACK_UNWIND (statfs, frame, local->op_ret, local->op_errno,
+ &local->cont.statfs.buf);
+
+ return 0;
+}
+
+
+int32_t
+afr_statfs (call_frame_t *frame, xlator_t *this,
+ loc_t *loc)
+{
+ afr_private_t * priv = NULL;
+ int child_count = 0;
+ afr_local_t * local = NULL;
+ 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);
+ VALIDATE_OR_GOTO (this->private, out);
+ VALIDATE_OR_GOTO (loc, out);
+
+ priv = this->private;
+ child_count = priv->child_count;
+
+ ALLOC_OR_GOTO (local, afr_local_t, out);
+
+ 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++) {
+ if (local->child_up[i]) {
+ STACK_WIND (frame, afr_statfs_cbk,
+ priv->children[i],
+ priv->children[i]->fops->statfs,
+ loc);
+ if (!--call_count)
+ break;
+ }
+ }
+
+ op_ret = 0;
+out:
+ 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 flock *lock)
+{
+ afr_local_t * local = NULL;
+
+ int call_count = -1;
+
+ local = frame->local;
+ call_count = afr_frame_return (frame);
+
+ if (call_count == 0)
+ AFR_STACK_UNWIND (lk, frame, local->op_ret, local->op_errno,
+ lock);
+
+ return 0;
+}
+
+
+int32_t
+afr_lk_unlock (call_frame_t *frame, xlator_t *this)
+{
+ afr_local_t * local = NULL;
+ afr_private_t * priv = NULL;
+
+ int i;
+ int call_count = 0;
+
+ local = frame->local;
+ priv = this->private;
+
+ call_count = afr_locked_nodes_count (local->cont.lk.locked_nodes,
+ priv->child_count);
+
+ if (call_count == 0) {
+ AFR_STACK_UNWIND (lk, frame, local->op_ret, local->op_errno,
+ &local->cont.lk.ret_flock);
+ return 0;
+ }
+
+ local->call_count = call_count;
+
+ local->cont.lk.user_flock.l_type = F_UNLCK;
+
+ for (i = 0; i < priv->child_count; i++) {
+ if (local->cont.lk.locked_nodes[i]) {
+ STACK_WIND (frame, afr_lk_unlock_cbk,
+ priv->children[i],
+ priv->children[i]->fops->lk,
+ local->fd, F_SETLK,
+ &local->cont.lk.user_flock);
+
+ if (!--call_count)
+ break;
+ }
+ }
+
+ return 0;
+}
+
+
+int32_t
+afr_lk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct flock *lock)
+{
+ afr_local_t *local = NULL;
+ afr_private_t *priv = NULL;
+
+ int call_count = -1;
+ int child_index = -1;
+
+ local = frame->local;
+ priv = this->private;
+
+ child_index = (long) cookie;
+
+ call_count = --local->call_count;
+
+ if (!child_went_down (op_ret, op_errno) && (op_ret == -1)) {
+ local->op_ret = -1;
+ local->op_errno = op_errno;
+
+ afr_lk_unlock (frame, this);
+ return 0;
+ }
+
+ if (op_ret == 0) {
+ local->op_ret = 0;
+ local->op_errno = 0;
+ local->cont.lk.locked_nodes[child_index] = 1;
+ local->cont.lk.ret_flock = *lock;
+ }
+
+ child_index++;
+
+ if (child_index < priv->child_count) {
+ STACK_WIND_COOKIE (frame, afr_lk_cbk, (void *) (long) child_index,
+ priv->children[child_index],
+ priv->children[child_index]->fops->lk,
+ local->fd, local->cont.lk.cmd,
+ &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);
+ } else {
+ /* locking has succeeded on all nodes that are up */
+
+ AFR_STACK_UNWIND (lk, frame, local->op_ret, local->op_errno,
+ &local->cont.lk.ret_flock);
+ }
+
+ return 0;
+}
+
+static int
+is_blocking_cmd (int32_t cmd)
+{
+ return (cmd == F_SETLKW);
+}
+
+static int32_t
+afr_do_real_lk (call_frame_t *frame, xlator_t *this)
+{
+ afr_private_t *priv = NULL;
+ afr_local_t *local = NULL;
+ int i = 0;
+
+ priv = this->private;
+ local = frame->local;
+
+ STACK_WIND_COOKIE (frame, afr_lk_cbk, (void *) (long) 0,
+ priv->children[i],
+ priv->children[i]->fops->lk,
+ local->fd, F_SETLKW,
+ &local->cont.lk.user_flock);
+
+ return 0;
+}
+
+int32_t
+afr_lk_unlock_broadcast_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct flock *lock)
+{
+ afr_local_t *local = NULL;
+ int call_count = -1;
+
+ local = frame->local;
+ call_count = afr_frame_return (frame);
+
+ if (call_count == 0) {
+ gf_log (this->name, GF_LOG_TRACE,
+ "Got last unlock broadcast reply");
+
+ afr_do_real_lk (frame, this);
+ }
+
+ return 0;
+
+}
+
+static int
+afr_lk_unlock_broadcast (call_frame_t *frame, xlator_t *this,
+ struct flock *flock)
+{
+ afr_private_t *priv = NULL;
+ afr_local_t *local = NULL;
+ struct flock unlock = {0,};
+ int32_t call_count = 0;
+ int ret = 0;
+ int i = 0;
+
+ priv = this->private;
+ local = frame->local;
+
+ unlock.l_type = F_UNLCK;
+ unlock.l_whence = flock->l_whence;
+ unlock.l_start = flock->l_start;
+ unlock.l_len = flock->l_len;
+ unlock.l_pid = flock->l_pid;
+
+ call_count = afr_up_children_count (priv->child_count,
+ local->child_up);
+ if (call_count == 0) {
+ ret = -1;
+ goto out;
+ }
+
+ local->call_count = call_count;
+
+ for (i = 0; i < priv->child_count; i++) {
+ if (local->child_up[i]) {
+ STACK_WIND_COOKIE (frame, afr_lk_unlock_broadcast_cbk,
+ (void *) (long) 0,
+ priv->children[i],
+ priv->children[i]->fops->lk,
+ local->fd, F_SETLK, &unlock);
+ if (!--call_count)
+ break;
+ }
+ }
+
+out:
+ return ret;
+}
+
+int
+afr_lk (call_frame_t *frame, xlator_t *this,
+ fd_t *fd, int32_t cmd,
+ struct flock *flock)
+{
+ afr_private_t *priv = NULL;
+ afr_local_t *local = NULL;
+
+ int i = 0;
+ int ret = 0;
+
+ int32_t op_ret = -1;
+ int32_t op_errno = 0;
+
+ VALIDATE_OR_GOTO (frame, out);
+ VALIDATE_OR_GOTO (this, out);
+ VALIDATE_OR_GOTO (this->private, out);
+
+ priv = this->private;
+
+ ALLOC_OR_GOTO (local, afr_local_t, out);
+ AFR_LOCAL_INIT (local, priv);
+
+ frame->local = local;
+
+ local->cont.lk.locked_nodes = CALLOC (priv->child_count,
+ sizeof (*local->cont.lk.locked_nodes));
+
+ if (!local->cont.lk.locked_nodes) {
+ gf_log (this->name, GF_LOG_ERROR, "Out of memory");
+ op_errno = ENOMEM;
+ goto out;
+ }
+
+ local->fd = fd_ref (fd);
+ local->cont.lk.cmd = cmd;
+ local->cont.lk.user_flock = *flock;
+ local->cont.lk.ret_flock = *flock;
+
+ /* Send an unlock broadcast in the case of a blocking lock call
+ to prevent deadlock due to blocking lock upgrades / downgrades
+ */
+ if (is_blocking_cmd (cmd)) {
+ ret = afr_lk_unlock_broadcast (frame, this, flock);
+ if (ret) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "Could not send unlock broadcast");
+ } else {
+ op_ret = 0;
+ gf_log (this->name, GF_LOG_DEBUG,
+ "Sent unlock broadcast");
+ goto out;
+ }
+ }
+
+ STACK_WIND_COOKIE (frame, afr_lk_cbk, (void *) (long) 0,
+ priv->children[i],
+ priv->children[i]->fops->lk,
+ fd, cmd, flock);
+
+ op_ret = 0;
+out:
+ if (op_ret == -1) {
+ AFR_STACK_UNWIND (lk, frame, op_ret, op_errno, NULL);
+ }
+ return 0;
+}
+
+int
+afr_priv_dump (xlator_t *this)
+{
+ afr_private_t *priv = NULL;
+ char key_prefix[GF_DUMP_MAX_BUF_LEN];
+ char key[GF_DUMP_MAX_BUF_LEN];
+ int i = 0;
+
+
+ assert(this);
+ priv = this->private;
+
+ 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_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++) {
+ gf_proc_dump_build_key(key, key_prefix, "child_up[%d]", i);
+ gf_proc_dump_write(key, "%d", priv->child_up[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_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;
+}
+
+
+/**
+ * find_child_index - find the child's index in the array of subvolumes
+ * @this: AFR
+ * @child: child
+ */
+
+static int
+find_child_index (xlator_t *this, xlator_t *child)
+{
+ afr_private_t *priv = NULL;
+
+ int i = -1;
+
+ priv = this->private;
+
+ for (i = 0; i < priv->child_count; i++) {
+ if ((xlator_t *) child == priv->children[i])
+ break;
+ }
+
+ return i;
+}
+
+
+int32_t
+notify (xlator_t *this, int32_t event,
+ void *data, ...)
+{
+ afr_private_t * priv = NULL;
+ unsigned char * child_up = NULL;
+
+ int i = -1;
+ int up_children = 0;
+
+ priv = this->private;
+
+ if (!priv)
+ return 0;
+
+ child_up = priv->child_up;
+
+ switch (event) {
+ case GF_EVENT_CHILD_UP:
+ i = find_child_index (this, data);
+
+ child_up[i] = 1;
+
+ LOCK (&priv->lock);
+ {
+ priv->up_count++;
+ }
+ UNLOCK (&priv->lock);
+
+ /*
+ if all the children were down, and one child came up,
+ send notify to parent
+ */
+
+ for (i = 0; i < priv->child_count; i++)
+ if (child_up[i])
+ up_children++;
+
+ if (up_children == 1) {
+ gf_log (this->name, GF_LOG_NORMAL,
+ "Subvolume '%s' came back up; "
+ "going online.", ((xlator_t *)data)->name);
+
+ default_notify (this, event, data);
+ }
+
+ break;
+
+ case GF_EVENT_CHILD_DOWN:
+ i = find_child_index (this, data);
+
+ child_up[i] = 0;
+
+ LOCK (&priv->lock);
+ {
+ priv->down_count++;
+ }
+ UNLOCK (&priv->lock);
+
+ /*
+ if all children are down, and this was the last to go down,
+ send notify to parent
+ */
+
+ for (i = 0; i < priv->child_count; i++)
+ if (child_up[i])
+ up_children++;
+
+ if (up_children == 0) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "All subvolumes are down. Going offline "
+ "until atleast one of them comes back up.");
+
+ default_notify (this, event, data);
+ }
+
+ break;
+
+ default:
+ default_notify (this, event, data);
+ }
+
+ return 0;
+}
+
+
+static const char *favorite_child_warning_str = "You have specified subvolume '%s' "
+ "as the 'favorite child'. This means that if a discrepancy in the content "
+ "or attributes (ownership, permission, etc.) of a file is detected among "
+ "the subvolumes, the file on '%s' will be considered the definitive "
+ "version and its contents will OVERWRITE the contents of the file on other "
+ "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;
+ 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;
+
+ int32_t background_count = 0;
+ int32_t lock_server_count = 1;
+ int32_t window_size;
+
+ int fav_ret = -1;
+ int read_ret = -1;
+ int dict_ret = -1;
+
+ if (!this->children) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "replicate translator needs more than one "
+ "subvolume defined.");
+ return -1;
+ }
+
+ if (!this->parents) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "Volume is dangling.");
+ }
+
+ ALLOC_OR_GOTO (this->private, afr_private_t, out);
+
+ priv = this->private;
+
+ read_ret = dict_get_str (this->options, "read-subvolume", &read_subvol);
+ priv->read_child = -1;
+
+ fav_ret = dict_get_str (this->options, "favorite-child", &fav_child);
+ priv->favorite_child = -1;
+
+ priv->background_self_heal_count = 16;
+
+ 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.",
+ window_size);
+
+ 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;
+ }
+ }
+
+ 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 = 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;
+ }
+ }
+
+ 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;
+ }
+ }
+
+ /* Change log options */
+
+ priv->data_change_log = 1;
+ priv->metadata_change_log = 0;
+ priv->entry_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;
+ }
+ }
+
+ /* Locking options */
+
+ priv->data_lock_server_count = 1;
+ priv->metadata_lock_server_count = 0;
+ priv->entry_lock_server_count = 1;
+
+ 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);
+
+ if (lock_server_count == 0)
+ gf_log (this->name, GF_LOG_WARNING, "%s",
+ no_lock_servers_warning_str);
+
+ priv->data_lock_server_count = lock_server_count;
+ }
+
+
+ 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;
+ }
+
+
+ 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);
+
+ priv->entry_lock_server_count = lock_server_count;
+ }
+
+ 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);
+ }
+ }
+
+ 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);
+
+ priv->read_child = child_count;
+ }
+
+ 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;
+ }
+
+ 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 = CALLOC (sizeof (unsigned char), child_count);
+ if (!priv->child_up) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory.");
+ op_errno = ENOMEM;
+ goto out;
+ }
+
+ priv->children = CALLOC (sizeof (xlator_t *), child_count);
+ if (!priv->children) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory.");
+ op_errno = ENOMEM;
+ goto out;
+ }
+
+ priv->pending_key = CALLOC (sizeof (*priv->pending_key), child_count);
+ if (!priv->pending_key) {
gf_log (this->name, GF_LOG_ERROR,
- "failed to create local_t's memory pool");
+ "Out of memory.");
+ op_errno = ENOMEM;
goto out;
}
- priv->root_inode = NULL;
+ trav = this->children;
+ i = 0;
+ while (i < child_count) {
+ priv->children[i] = trav->xlator;
- ret = 0;
+ 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");
+ op_errno = ENOMEM;
+ goto out;
+ }
+
+ trav = trav->next;
+ i++;
+ }
+
+ ret = 0;
out:
- return ret;
+ return ret;
}
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;
+ return 0;
}
struct xlator_fops fops = {
- .lookup = afr_lookup,
- .open = afr_open,
- .lk = afr_lk,
- .flush = afr_flush,
- .statfs = afr_statfs,
- .fsync = afr_fsync,
- .fsyncdir = afr_fsyncdir,
- .xattrop = afr_xattrop,
- .fxattrop = afr_fxattrop,
- .inodelk = afr_inodelk,
- .finodelk = afr_finodelk,
- .entrylk = afr_entrylk,
- .fentrylk = afr_fentrylk,
-
- /* inode read */
- .access = afr_access,
- .stat = afr_stat,
- .fstat = afr_fstat,
- .readlink = afr_readlink,
- .getxattr = afr_getxattr,
- .fgetxattr = afr_fgetxattr,
- .readv = afr_readv,
-
- /* inode write */
- .writev = afr_writev,
- .truncate = afr_truncate,
- .ftruncate = afr_ftruncate,
- .setxattr = afr_setxattr,
- .fsetxattr = afr_fsetxattr,
+ .lookup = afr_lookup,
+ .open = afr_open,
+ .lk = afr_lk,
+ .flush = afr_flush,
+ .statfs = afr_statfs,
+ .fsync = afr_fsync,
+ .fsyncdir = afr_fsyncdir,
+ .xattrop = afr_xattrop,
+ .fxattrop = afr_fxattrop,
+ .inodelk = afr_inodelk,
+ .finodelk = afr_finodelk,
+ .entrylk = afr_entrylk,
+ .fentrylk = afr_fentrylk,
+ .checksum = afr_checksum,
+
+ /* inode read */
+ .access = afr_access,
+ .stat = afr_stat,
+ .fstat = afr_fstat,
+ .readlink = afr_readlink,
+ .getxattr = afr_getxattr,
+ .readv = afr_readv,
+
+ /* inode write */
+ .writev = afr_writev,
+ .truncate = afr_truncate,
+ .ftruncate = afr_ftruncate,
+ .setxattr = afr_setxattr,
.setattr = afr_setattr,
- .fsetattr = afr_fsetattr,
- .removexattr = afr_removexattr,
- .fremovexattr = afr_fremovexattr,
- .fallocate = afr_fallocate,
- .discard = afr_discard,
- .zerofill = afr_zerofill,
-
- /* dir read */
- .opendir = afr_opendir,
- .readdir = afr_readdir,
- .readdirp = afr_readdirp,
-
- /* dir write */
- .create = afr_create,
- .mknod = afr_mknod,
- .mkdir = afr_mkdir,
- .unlink = afr_unlink,
- .rmdir = afr_rmdir,
- .link = afr_link,
- .symlink = afr_symlink,
- .rename = afr_rename,
+ .fsetattr = afr_fsetattr,
+ .removexattr = afr_removexattr,
+
+ /* dir read */
+ .opendir = afr_opendir,
+ .readdir = afr_readdir,
+ .readdirp = afr_readdirp,
+ .getdents = afr_getdents,
+
+ /* dir write */
+ .create = afr_create,
+ .mknod = afr_mknod,
+ .mkdir = afr_mkdir,
+ .unlink = afr_unlink,
+ .rmdir = afr_rmdir,
+ .link = afr_link,
+ .symlink = afr_symlink,
+ .rename = afr_rename,
+ .setdents = afr_setdents,
};
+struct xlator_mops mops = {
+};
+
struct xlator_dumpops dumpops = {
.priv = afr_priv_dump,
};
struct xlator_cbks cbks = {
- .release = afr_release,
- .releasedir = afr_releasedir,
- .forget = afr_forget,
+ .release = afr_release,
+ .releasedir = afr_releasedir,
};
struct volume_options options[] = {
- { .key = {"read-subvolume" },
- .type = GF_OPTION_TYPE_XLATOR,
- .description = "inode-read fops happen only on one of the bricks in "
- "replicate. Afr will prefer the one specified using "
- "this option if it is not stale. Option value must be "
- "one of the xlator names of the children. "
- "Ex: <volname>-client-0 till "
- "<volname>-client-<number-of-bricks - 1>"
- },
- { .key = {"read-subvolume-index" },
- .type = GF_OPTION_TYPE_INT,
- .default_value = "-1",
- .description = "inode-read fops happen only on one of the bricks in "
- "replicate. AFR will prefer the one specified using "
- "this option if it is not stale. allowed options"
- " include -1 till replica-count - 1"
- },
- { .key = {"read-hash-mode" },
- .type = GF_OPTION_TYPE_INT,
- .min = 0,
- .max = 2,
- .default_value = "1",
- .description = "inode-read fops happen only on one of the bricks in "
- "replicate. AFR will prefer the one computed using "
- "the method specified using this option"
- "0 = first up server, "
- "1 = hash by GFID of file (all clients use "
- "same subvolume), "
- "2 = hash by GFID of file and client PID",
- },
- { .key = {"choose-local" },
- .type = GF_OPTION_TYPE_BOOL,
- .default_value = "true",
- .description = "Choose a local subvolume (i.e. Brick) to read from"
- " if read-subvolume is not explicitly set.",
- },
- { .key = {"favorite-child"},
- .type = GF_OPTION_TYPE_XLATOR,
- .description = "If a split-brain happens choose subvol/brick set by "
- "this option as source."
- },
+ { .key = {"read-subvolume" },
+ .type = GF_OPTION_TYPE_XLATOR
+ },
+ { .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,
- .description = "This specifies the number of self-heals that can be "
- " performed in background without blocking the fop"
- },
- { .key = {"data-self-heal"},
- .type = GF_OPTION_TYPE_STR,
- .value = {"1", "on", "yes", "true", "enable",
- "0", "off", "no", "false", "disable",
- "open"},
- .default_value = "on",
- .description = "Using this option we can enable/disable data "
- "self-heal on the file. \"open\" means data "
- "self-heal action will only be triggered by file "
- "open operations."
+ .min = 0
},
+ { .key = {"data-self-heal"},
+ .type = GF_OPTION_TYPE_BOOL
+ },
{ .key = {"data-self-heal-algorithm"},
- .type = GF_OPTION_TYPE_STR,
- .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. If no option is configured "
- "the option is chosen dynamically as follows: "
- "If the file does not exist on one of the sinks "
- "or empty file exists or if the source file size is "
- "about the same as page size the entire file will "
- "be read and written i.e \"full\" algo, "
- "otherwise \"diff\" algo is chosen.",
- .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."
- },
- { .key = {"metadata-self-heal"},
- .type = GF_OPTION_TYPE_BOOL,
- .default_value = "on",
- .description = "Using this option we can enable/disable metadata "
- "i.e. Permissions, ownerships, xattrs self-heal on "
- "the file/directory."
- },
- { .key = {"entry-self-heal"},
- .type = GF_OPTION_TYPE_BOOL,
- .default_value = "on",
- .description = "Using this option we can enable/disable entry "
- "self-heal on the directory."
- },
- { .key = {"data-change-log"},
- .type = GF_OPTION_TYPE_BOOL,
- .default_value = "on",
- .description = "Data fops like write/truncate will not perform "
- "pre/post fop changelog operations in afr transaction "
- "if this option is disabled"
- },
- { .key = {"metadata-change-log"},
- .type = GF_OPTION_TYPE_BOOL,
- .default_value = "on",
- .description = "Metadata fops like setattr/setxattr will not perform "
- "pre/post fop changelog operations in afr transaction "
- "if this option is disabled"
- },
- { .key = {"entry-change-log"},
- .type = GF_OPTION_TYPE_BOOL,
- .default_value = "on",
- .description = "Entry fops like create/unlink will not perform "
- "pre/post fop changelog operations in afr transaction "
- "if this option is disabled"
- },
- { .key = {"optimistic-change-log"},
- .type = GF_OPTION_TYPE_BOOL,
- .default_value = "on",
- .description = "Entry/Metadata fops will not perform "
- "pre fop changelog operations in afr transaction "
- "if this option is enabled."
- },
- { .key = {"inodelk-trace"},
- .type = GF_OPTION_TYPE_BOOL,
- .default_value = "off",
- .description = "Enabling this option logs inode lock/unlocks"
+ .max = 1024
},
- { .key = {"entrylk-trace"},
- .type = GF_OPTION_TYPE_BOOL,
- .default_value = "off",
- .description = "Enabling this option logs entry lock/unlocks"
- },
- { .key = {"pre-op-compat"},
- .type = GF_OPTION_TYPE_BOOL,
- .default_value = "on",
- .description = "Use separate pre-op xattrop() FOP rather than "
- "overloading xdata of the OP"
+ { .key = {"metadata-self-heal"},
+ .type = GF_OPTION_TYPE_BOOL
},
- { .key = {"eager-lock"},
- .type = GF_OPTION_TYPE_BOOL,
- .default_value = "on",
- .description = "Lock phase of a transaction has two sub-phases. "
- "First is an attempt to acquire locks in parallel by "
- "broadcasting non-blocking lock requests. If lock "
- "acquisition fails on any server, then the held locks "
- "are unlocked and revert to a blocking locked mode "
- "sequentially on one server after another. If this "
- "option is enabled the initial broadcasting lock "
- "request attempt to acquire lock on the entire file. "
- "If this fails, we revert back to the sequential "
- "\"regional\" blocking lock as before. In the case "
- "where such an \"eager\" lock is granted in the "
- "non-blocking phase, it gives rise to an opportunity "
- "for optimization. i.e, if the next write transaction "
- "on the same FD arrives before the unlock phase of "
- "the first transaction, it \"takes over\" the full "
- "file lock. Similarly if yet another data transaction "
- "arrives before the unlock phase of the \"optimized\" "
- "transaction, that in turn \"takes over\" the lock as "
- "well. The actual unlock now happens at the end of "
- "the last \"optimized\" transaction."
-
- },
- { .key = {"self-heal-daemon"},
- .type = GF_OPTION_TYPE_BOOL,
- .default_value = "on",
- .description = "This option applies to only self-heal-daemon. "
- "Index directory crawl and automatic healing of files "
- "will not be performed if this option is turned off."
- },
- { .key = {"iam-self-heal-daemon"},
- .type = GF_OPTION_TYPE_BOOL,
- .default_value = "off",
- .description = "This option differentiates if the replicate "
- "translator is running as part of self-heal-daemon "
- "or not."
- },
- { .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"},
- .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, used in starting "
- "self-heal-daemon so that it can crawl only on "
- "local index directories.",
- },
- { .key = {"post-op-delay-secs"},
- .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.",
- },
- { .key = {AFR_SH_READDIR_SIZE_KEY},
- .type = GF_OPTION_TYPE_SIZET,
- .description = "readdirp size for performing entry self-heal",
- .min = 1024,
- .max = 131072,
- .default_value = "1KB",
- },
- { .key = {"ensure-durability"},
- .type = GF_OPTION_TYPE_BOOL,
- .description = "Afr performs fsyncs for transactions if this "
- "option is on to make sure the changelogs/data is "
- "written to the disk",
- .default_value = "on",
- },
- { .key = {"afr-dirty-xattr"},
- .type = GF_OPTION_TYPE_STR,
- .default_value = AFR_DIRTY_DEFAULT,
+ { .key = {"entry-self-heal"},
+ .type = GF_OPTION_TYPE_BOOL
},
- { .key = {"metadata-splitbrain-forced-heal"},
+ { .key = {"data-change-log"},
+ .type = GF_OPTION_TYPE_BOOL
+ },
+ { .key = {"metadata-change-log"},
+ .type = GF_OPTION_TYPE_BOOL
+ },
+ { .key = {"entry-change-log"},
+ .type = GF_OPTION_TYPE_BOOL
+ },
+ { .key = {"data-lock-server-count"},
+ .type = GF_OPTION_TYPE_INT,
+ .min = 0
+ },
+ { .key = {"metadata-lock-server-count"},
+ .type = GF_OPTION_TYPE_INT,
+ .min = 0
+ },
+ { .key = {"entry-lock-server-count"},
+ .type = GF_OPTION_TYPE_INT,
+ .min = 0
+ },
+ { .key = {"strict-readdir"},
.type = GF_OPTION_TYPE_BOOL,
- .default_value = "off",
},
- { .key = {"consistent-metadata"},
- .type = GF_OPTION_TYPE_BOOL,
- .default_value = "no",
- .description = "If this option is enabled, readdirp will force "
- "lookups on those entries read whose read child is "
- "not the same as that of the parent. This will "
- "guarantee that all read operations on a file serve "
- "attributes from the same subvol as long as it holds "
- " a good copy of the file/dir.",
- },
- { .key = {NULL} },
+ { .key = {NULL} },
};
diff --git a/xlators/cluster/afr/src/afr.h b/xlators/cluster/afr/src/afr.h
index d04f2755114..a0861e5bae4 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>
- 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-2009 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/>.
*/
@@ -17,150 +26,144 @@
#include "config.h"
#endif
+#include "scheduler.h"
#include "call-stub.h"
#include "compat-errno.h"
-#include "afr-mem-types.h"
-
-#include "libxlator.h"
-#include "timer.h"
-#include "syncop.h"
-
-#include "afr-self-heald.h"
-#include "afr-messages.h"
#define AFR_XATTR_PREFIX "trusted.afr"
-#define AFR_PATHINFO_HEADER "REPLICATE:"
-#define AFR_SH_READDIR_SIZE_KEY "self-heal-readdir-size"
-#define AFR_SH_DATA_DOMAIN_FMT "%s:self-heal"
-#define AFR_DIRTY_DEFAULT AFR_XATTR_PREFIX ".dirty"
-#define AFR_DIRTY (((afr_private_t *) (THIS->private))->afr_dirty)
-
-#define AFR_LOCKEE_COUNT_MAX 3
-#define AFR_DOM_COUNT_MAX 3
-#define AFR_NUM_CHANGE_LOGS 3 /*data + metadata + entry*/
-
-typedef int (*afr_lock_cbk_t) (call_frame_t *frame, xlator_t *this);
-
-typedef int (*afr_read_txn_wind_t) (call_frame_t *frame, xlator_t *this, int subvol);
-
-typedef int (*afr_inode_refresh_cbk_t) (call_frame_t *frame, xlator_t *this, int err);
-
-typedef int (*afr_changelog_resume_t) (call_frame_t *frame, xlator_t *this);
-
-#define alloca0(size) ({void *__ptr; __ptr = alloca(size); memset(__ptr, 0, size); __ptr;})
-#define AFR_COUNT(array,max) ({int __i; int __res = 0; for (__i = 0; __i < max; __i++) if (array[__i]) __res++; __res;})
-#define AFR_INTERSECT(dst,src1,src2,max) ({int __i; for (__i = 0; __i < max; __i++) dst[__i] = src1[__i] && src2[__i];})
-#define AFR_CMP(a1,a2,len) ({int __cmp = 0; int __i; for (__i = 0; __i < len; __i++) if (a1[__i] != a2[__i]) { __cmp = 1; break;} __cmp;})
typedef struct _afr_private {
- gf_lock_t lock; /* to guard access to child_count, etc */
- unsigned int child_count; /* total number of children */
+ gf_lock_t lock; /* to guard access to child_count, etc */
+ unsigned int child_count; /* total number of children */
- xlator_t **children;
+ unsigned int read_child_rr; /* round-robin index of the read_child */
+ gf_lock_t read_child_lock; /* lock to protect above */
+
+ xlator_t **children;
- inode_t *root_inode;
-
- unsigned char *child_up;
+ unsigned char *child_up;
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 */
unsigned int background_self_heal_count;
unsigned int background_self_heals_started;
- gf_boolean_t metadata_self_heal; /* on/off */
- gf_boolean_t entry_self_heal; /* on/off */
+ gf_boolean_t metadata_self_heal; /* on/off */
+ gf_boolean_t entry_self_heal; /* on/off */
+
+ 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 data_change_log; /* on/off */
- gf_boolean_t metadata_change_log; /* on/off */
- gf_boolean_t entry_change_log; /* on/off */
+ int read_child; /* read-subvolume */
+ unsigned int favorite_child; /* subvolume to be preferred in resolving
+ split-brain cases */
- gf_boolean_t metadata_splitbrain_forced_heal; /* 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;
+ gf_boolean_t strict_readdir;
- unsigned int wait_count; /* # of servers to wait for success */
+ unsigned int wait_count; /* # of servers to wait for success */
uint64_t up_count; /* number of CHILD_UPs we have seen */
uint64_t down_count; /* number of CHILD_DOWNs we have seen */
+} afr_private_t;
- gf_boolean_t optimistic_change_log;
- gf_boolean_t eager_lock;
- gf_boolean_t pre_op_compat; /* on/off */
- uint32_t post_op_delay_secs;
- unsigned int quorum_count;
-
- char vol_uuid[UUID_SIZE + 1];
- int32_t *last_event;
-
- /* @event_generation: Keeps count of number of events received which can
- potentially impact consistency decisions. The events are CHILD_UP
- and CHILD_DOWN, when we have to recalculate the freshness/staleness
- of copies to detect if changes had happened while the other server
- was down. CHILD_DOWN and CHILD_UP can also be received on network
- disconnect/reconnects and not necessarily server going down/up.
- Recalculating freshness/staleness on network events is equally
- important as we might have had a network split brain.
- */
- uint32_t event_generation;
+typedef struct {
+ /* External interface: These are variables (some optional) that
+ are set by whoever has triggered self-heal */
- gf_boolean_t choose_local;
- gf_boolean_t did_discovery;
- uint64_t sh_readdir_size;
- gf_boolean_t ensure_durability;
- char *sh_domain;
- char *afr_dirty;
+ gf_boolean_t need_data_self_heal;
+ gf_boolean_t need_metadata_self_heal;
+ gf_boolean_t need_entry_self_heal;
- afr_self_heald_t shd;
+ gf_boolean_t forced_merge; /* Is this a self-heal triggered to
+ forcibly merge the directories? */
- /* pump dependencies */
- void *pump_private;
- gf_boolean_t use_afr_in_pump;
- gf_boolean_t consistent_metadata;
-} afr_private_t;
+ 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 */
-typedef enum {
- AFR_DATA_TRANSACTION, /* truncate, write, ... */
- AFR_METADATA_TRANSACTION, /* chmod, chown, ... */
- AFR_ENTRY_TRANSACTION, /* create, rmdir, ... */
- AFR_ENTRY_RENAME_TRANSACTION, /* rename */
-} afr_transaction_type;
+ fd_t *healing_fd; /* set if callers has opened fd */
-typedef enum {
- AFR_TRANSACTION_LK,
- AFR_SELFHEAL_LK,
-} transaction_lk_type_t;
+ gf_boolean_t background; /* do self-heal in background
+ if possible */
-typedef enum {
- AFR_LOCK_OP,
- AFR_UNLOCK_OP,
-} afr_lock_op_type_t;
+ mode_t mode; /* st_mode of the entry we're doing
+ self-heal on */
+
+ /* 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);
+
+ /* End of external interface members */
+
+
+ /* array of stat's, one for each child */
+ struct stat *buf;
+ struct stat parentbuf;
+
+ /* array of xattr's, one for each child */
+ dict_t **xattr;
+
+ /* array of errno's, one for each child */
+ int *child_errno;
+
+ int32_t **pending_matrix;
+ int32_t **delta_matrix;
+
+ int *sources;
+ int source;
+ int active_source;
+ int active_sinks;
+ int *success;
+ int *locked_nodes;
+ int lock_count;
+
+ mode_t impunging_entry_mode;
+ const char *linkname;
+
+ int op_failed;
+
+ int file_has_holes;
+ blksize_t block_size;
+ off_t file_size;
+ off_t offset;
+
+ loc_t parent_loc;
+
+ call_frame_t *orig_frame;
+ gf_boolean_t unwound;
+
+ /* private data for the particular self-heal algorithm */
+ void *private;
+
+ int (*flush_self_heal_cbk) (call_frame_t *frame, xlator_t *this);
+
+ int (*completion_cbk) (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);
+
+ call_frame_t *sh_frame;
+} afr_self_heal_t;
-typedef enum {
- AFR_DATA_SELF_HEAL_LK,
- AFR_METADATA_SELF_HEAL_LK,
- AFR_ENTRY_SELF_HEAL_LK,
-}selfheal_lk_type_t;
typedef enum {
- AFR_INODELK_TRANSACTION,
- AFR_INODELK_NB_TRANSACTION,
- AFR_ENTRYLK_TRANSACTION,
- AFR_ENTRYLK_NB_TRANSACTION,
- AFR_INODELK_SELFHEAL,
- AFR_INODELK_NB_SELFHEAL,
- AFR_ENTRYLK_SELFHEAL,
- AFR_ENTRYLK_NB_SELFHEAL,
-} afr_lock_call_type_t;
+ AFR_DATA_TRANSACTION, /* truncate, write, ... */
+ AFR_METADATA_TRANSACTION, /* chmod, chown, ... */
+ AFR_ENTRY_TRANSACTION, /* create, rmdir, ... */
+ AFR_ENTRY_RENAME_TRANSACTION, /* rename */
+} afr_transaction_type;
+
/*
xattr format: trusted.afr.volume = [x y z]
@@ -173,7 +176,7 @@ static inline int
afr_index_for_transaction_type (afr_transaction_type type)
{
switch (type) {
-
+
case AFR_DATA_TRANSACTION:
return 0;
@@ -188,683 +191,434 @@ afr_index_for_transaction_type (afr_transaction_type type)
return -1; /* make gcc happy */
}
-static inline int
-afr_index_from_ia_type (ia_type_t type)
-{
- switch (type) {
- case IA_IFDIR:
- return afr_index_for_transaction_type (AFR_ENTRY_TRANSACTION);
- case IA_IFREG:
- return afr_index_for_transaction_type (AFR_DATA_TRANSACTION);
- default: return -1;
- }
-}
-
-typedef struct {
- loc_t loc;
- char *basename;
- unsigned char *locked_nodes;
- int locked_count;
-
-} afr_entry_lockee_t;
-
-int
-afr_entry_lockee_cmp (const void *l1, const void *l2);
-
-typedef struct {
- char *domain; /* Domain on which inodelk is taken */
- struct gf_flock flock;
- unsigned char *locked_nodes;
- int32_t lock_count;
-} afr_inodelk_t;
-
-typedef struct {
- loc_t *lk_loc;
-
- int lockee_count;
- afr_entry_lockee_t lockee[AFR_LOCKEE_COUNT_MAX];
-
- afr_inodelk_t inodelk[AFR_DOM_COUNT_MAX];
- const char *lk_basename;
- const char *lower_basename;
- const char *higher_basename;
- char lower_locked;
- char higher_locked;
-
- unsigned char *locked_nodes;
- unsigned char *lower_locked_nodes;
-
- selfheal_lk_type_t selfheal_lk_type;
- transaction_lk_type_t transaction_lk_type;
-
- int32_t lock_count;
- int32_t entrylk_lock_count;
-
- uint64_t lock_number;
- int32_t lk_call_count;
- int32_t lk_expected_count;
- int32_t lk_attempted_count;
-
- int32_t lock_op_ret;
- int32_t lock_op_errno;
- afr_lock_cbk_t lock_cbk;
- char *domain; /* Domain on which inode/entry lock/unlock in progress.*/
-} afr_internal_lock_t;
-
-struct afr_reply {
- int valid;
- int32_t op_ret;
- int32_t op_errno;
- dict_t *xdata;
- struct iatt poststat;
- struct iatt postparent;
- struct iatt prestat;
- struct iatt preparent;
- struct iatt preparent2;
- struct iatt postparent2;
- uint8_t checksum[MD5_DIGEST_LENGTH];
-};
-
-typedef enum {
- AFR_FD_NOT_OPENED,
- AFR_FD_OPENED,
- AFR_FD_OPENING
-} afr_fd_open_status_t;
-
-typedef struct {
- unsigned int *pre_op_done[AFR_NUM_CHANGE_LOGS];
- int inherited[AFR_NUM_CHANGE_LOGS];
- int on_disk[AFR_NUM_CHANGE_LOGS];
- afr_fd_open_status_t *opened_on; /* which subvolumes the fd is open on */
-
- unsigned int *lock_piggyback;
- unsigned int *lock_acquired;
-
- int flags;
-
- /* used for delayed-post-op optimization */
- pthread_mutex_t delay_lock;
- gf_timer_t *delay_timer;
- call_frame_t *delay_frame;
-
- /* set if any write on this fd was a non stable write
- (i.e, without O_SYNC or O_DSYNC)
- */
- gf_boolean_t witnessed_unstable_write;
-
- /* @open_fd_count:
- Number of open FDs queried from the server, as queried through
- xdata in FOPs. Currently, used to decide if eager-locking must be
- temporarily disabled.
- */
- uint32_t open_fd_count;
-
-
- /* list of frames currently in progress */
- struct list_head eager_locked;
-
- /* the subvolume on which the latest sequence of readdirs (starting
- at offset 0) has begun. Till the next readdir request with 0 offset
- arrives, we continue to read off this subvol.
- */
- int readdir_subvol;
-} afr_fd_ctx_t;
-
typedef struct _afr_local {
- glusterfs_fop_t op;
- unsigned int call_count;
-
- /* @event_generation: copy of priv->event_generation taken at the
- time of starting the transaction. The copy is made so that we
- have a stable value through the various phases of the transaction.
- */
- unsigned int event_generation;
-
- uint32_t open_fd_count;
- gf_boolean_t update_open_fd_count;
-
- gf_lkowner_t saved_lk_owner;
-
- int32_t op_ret;
- int32_t op_errno;
-
- int32_t **pending;
-
- int dirty[AFR_NUM_CHANGE_LOGS];
+ unsigned int call_count;
+ unsigned int success_count;
+ unsigned int enoent_count;
- loc_t loc;
- loc_t newloc;
+ unsigned int govinda_gOvinda;
- fd_t *fd;
- afr_fd_ctx_t *fd_ctx;
+ unsigned int read_child_index;
+ unsigned char read_child_returned;
+ unsigned int first_up_child;
- /* @child_up: copy of priv->child_up taken at the time of transaction
- start. The copy is taken so that we have a stable child_up array
- through the phases of the transaction as priv->child_up[i] can keep
- changing through time.
- */
- unsigned char *child_up;
-
- /* @read_attempted:
- array of flags representing subvolumes where read operations of
- the read transaction have already been attempted. The array is
- first pre-filled with down subvolumes, and as reads are performed
- on other subvolumes, those are set as well. This way if the read
- operation fails we do not retry on that subvolume again.
- */
- unsigned char *read_attempted;
+ pid_t saved_pid;
- /* @readfn:
+ int32_t op_ret;
+ int32_t op_errno;
- pointer to function which will perform the read operation on a given
- subvolume. Used in read transactions.
- */
+ int32_t **pending;
- afr_read_txn_wind_t readfn;
+ loc_t loc;
+ loc_t newloc;
- /* @refreshed:
+ fd_t *fd;
- the inode was "refreshed" (i.e, pending xattrs from all subvols
- freshly inspected and inode ctx updated accordingly) as part of
- this transaction already.
- */
- gf_boolean_t refreshed;
+ glusterfs_fop_t fop;
- /* @inode:
+ unsigned char *child_up;
- the inode on which the read txn is performed on. ref'ed and copied
- from either fd->inode or loc.inode
- */
-
- inode_t *inode;
-
- /* @parent[2]:
-
- parent inode[s] on which directory transactions are performed.
- */
+ int32_t *child_errno;
+
+ dict_t *xattr_req;
- inode_t *parent;
- inode_t *parent2;
+ int32_t inodelk_count;
+ int32_t entrylk_count;
- /* @readable:
+ int (*openfd_flush_cbk) (call_frame_t *, xlator_t *);
- array of flags representing servers from which a read can be
- performed. This is the output of afr_inode_refresh()
+ /*
+ This struct contains the arguments for the "continuation"
+ (scheme-like) of fops
*/
- unsigned char *readable;
- afr_inode_refresh_cbk_t refreshfn;
-
- /* @refreshinode:
-
- Inode currently getting refreshed.
- */
- inode_t *refreshinode;
-
- /*
- @pre_op_compat:
-
- compatibility mode of pre-op. send a separate pre-op and
- op operations as part of transaction, rather than combining
- */
-
- gf_boolean_t pre_op_compat;
-
- dict_t *xattr_req;
-
- afr_internal_lock_t internal_lock;
-
- dict_t *dict;
-
- int optimistic_change_log;
- gf_boolean_t delayed_post_op;
-
- /* Is the current writev() going to perform a stable write?
- i.e, is fd->flags or @flags writev param have O_SYNC or
- O_DSYNC?
- */
- gf_boolean_t stable_write;
-
- /* This write appended to the file. Nnot necessarily O_APPEND,
- just means the offset of write was at the end of file.
- */
- gf_boolean_t append_write;
-
- /*
- This struct contains the arguments for the "continuation"
- (scheme-like) of fops
- */
+ int op;
+ struct {
+ struct {
+ unsigned char buf_set;
+ struct statvfs buf;
+ } statfs;
- struct {
- struct {
- gf_boolean_t needs_fresh_lookup;
- uuid_t gfid_req;
- } lookup;
+ struct {
+ inode_t *inode;
+ struct stat buf;
+ struct stat read_child_buf;
+ struct stat postparent;
+ ino_t ino;
+ uint64_t gen;
+ ino_t parent_ino;
+ dict_t *xattr;
+ dict_t **xattrs;
+ gf_boolean_t is_revalidate;
+ } lookup;
- struct {
- unsigned char buf_set;
- struct statvfs buf;
- } statfs;
+ struct {
+ int32_t flags;
+ int32_t wbflags;
+ } open;
- struct {
- int32_t flags;
- } open;
+ struct {
+ int32_t cmd;
+ struct flock user_flock;
+ struct flock ret_flock;
+ unsigned char *locked_nodes;
+ } lk;
- struct {
- int32_t cmd;
- struct gf_flock user_flock;
- struct gf_flock ret_flock;
- unsigned char *locked_nodes;
- } lk;
+ struct {
+ uint8_t *file_checksum;
+ uint8_t *dir_checksum;
+ } checksum;
- /* inode read */
+ /* inode read */
- struct {
- int32_t mask;
- int last_index; /* index of the child we tried previously */
- } access;
+ struct {
+ int32_t mask;
+ int last_tried; /* index of the child we tried previously */
+ } access;
- struct {
- int last_index;
- } stat;
+ struct {
+ int last_tried;
+ ino_t ino;
+ } stat;
- struct {
- int last_index;
- } fstat;
+ struct {
+ int last_tried;
+ ino_t ino;
+ } fstat;
- struct {
- size_t size;
- int last_index;
- } readlink;
+ struct {
+ size_t size;
+ int last_tried;
+ ino_t ino;
+ } readlink;
- struct {
- char *name;
- int last_index;
- long xattr_len;
- } getxattr;
+ struct {
+ const char *name;
+ int last_tried;
+ } getxattr;
- struct {
- size_t size;
- off_t offset;
- int last_index;
- uint32_t flags;
- } readv;
+ struct {
+ ino_t ino;
+ size_t size;
+ off_t offset;
+ int last_tried;
+ } readv;
- /* dir read */
+ /* dir read */
- struct {
- int success_count;
- int32_t op_ret;
- int32_t op_errno;
+ struct {
+ int success_count;
+ int32_t op_ret;
+ int32_t op_errno;
uint32_t *checksum;
- } opendir;
-
- struct {
- int32_t op_ret;
- int32_t op_errno;
- size_t size;
- off_t offset;
- dict_t *dict;
- gf_boolean_t failed;
- int last_index;
- } readdir;
- /* inode write */
-
- struct {
- struct iatt prebuf;
- struct iatt postbuf;
- } inode_wfop; //common structure for all inode-write-fops
-
- struct {
- int32_t op_ret;
-
- struct iovec *vector;
- struct iobref *iobref;
- int32_t count;
- off_t offset;
- uint32_t flags;
- } writev;
-
- struct {
- off_t offset;
- } truncate;
-
- struct {
- off_t offset;
- } ftruncate;
+ } opendir;
- struct {
- struct iatt in_buf;
- int32_t valid;
- } setattr;
-
- struct {
- struct iatt in_buf;
- int32_t valid;
- } fsetattr;
-
- struct {
- dict_t *dict;
- int32_t flags;
- } setxattr;
-
- struct {
- dict_t *dict;
- int32_t flags;
- } fsetxattr;
+ struct {
+ int32_t op_ret;
+ int32_t op_errno;
+ size_t size;
+ off_t offset;
- struct {
- char *name;
- } removexattr;
+ gf_boolean_t failed;
+ int last_tried;
+ } readdir;
- struct {
- dict_t *xattr;
- } xattrop;
+ struct {
+ int32_t op_ret;
+ int32_t op_errno;
- struct {
- dict_t *xattr;
- } fxattrop;
+ size_t size;
+ off_t offset;
+ int32_t flag;
- /* dir write */
+ int last_tried;
+ } getdents;
- struct {
- inode_t *inode;
- struct iatt buf;
- struct iatt preparent;
- struct iatt postparent;
- struct iatt prenewparent;
- struct iatt postnewparent;
- } dir_fop; //common structure for all dir fops
+ /* inode write */
- struct {
- fd_t *fd;
- dict_t *params;
- int32_t flags;
- mode_t mode;
- } create;
-
- struct {
- dev_t dev;
- mode_t mode;
- dict_t *params;
- } mknod;
+ struct {
+ ino_t ino;
+ struct stat prebuf;
+ struct stat postbuf;
- struct {
- int32_t mode;
- dict_t *params;
- } mkdir;
+ int32_t op_ret;
- struct {
- int flags;
- } rmdir;
+ struct iovec *vector;
+ struct iobref *iobref;
+ int32_t count;
+ off_t offset;
+ } writev;
struct {
- dict_t *params;
- char *linkpath;
- } symlink;
+ ino_t ino;
+ struct stat prebuf;
+ struct stat postbuf;
+ } fsync;
struct {
- int32_t mode;
+ ino_t ino;
off_t offset;
- size_t len;
- } fallocate;
+ struct stat prebuf;
+ struct stat postbuf;
+ } truncate;
struct {
+ ino_t ino;
off_t offset;
- size_t len;
- } discard;
+ struct stat prebuf;
+ struct stat postbuf;
+ } ftruncate;
- struct {
- off_t offset;
- off_t len;
- struct iatt prebuf;
- struct iatt postbuf;
- } zerofill;
-
- struct {
- char *volume;
- int32_t cmd;
- struct gf_flock flock;
- } inodelk;
-
- } cont;
-
- struct {
- off_t start, len;
-
- gf_boolean_t eager_lock_on;
- int *eager_lock;
-
- char *basename;
- char *new_basename;
-
- loc_t parent_loc;
- loc_t new_parent_loc;
+ struct {
+ ino_t ino;
+ struct stat in_buf;
+ int32_t valid;
+ struct stat preop_buf;
+ struct stat postop_buf;
+ } setattr;
- afr_transaction_type type;
+ struct {
+ ino_t ino;
+ struct stat in_buf;
+ int32_t valid;
+ struct stat preop_buf;
+ struct stat postop_buf;
+ } fsetattr;
- /* stub to resume on destruction
- of the transaction frame */
- call_stub_t *resume_stub;
+ struct {
+ dict_t *dict;
+ int32_t flags;
+ } setxattr;
- struct list_head eager_locked;
+ struct {
+ const char *name;
+ } removexattr;
- unsigned char *pre_op;
+ /* dir write */
+
+ struct {
+ ino_t ino;
+ uint64_t gen;
+ ino_t parent_ino;
+ fd_t *fd;
+ int32_t flags;
+ mode_t mode;
+ inode_t *inode;
+ struct stat buf;
+ struct stat preparent;
+ struct stat postparent;
+ struct stat read_child_buf;
+ } create;
- /* @fop_subvols: subvolumes on which FOP will be attempted */
- unsigned char *fop_subvols;
+ struct {
+ ino_t ino;
+ uint64_t gen;
+ ino_t parent_ino;
+ dev_t dev;
+ mode_t mode;
+ inode_t *inode;
+ struct stat buf;
+ struct stat preparent;
+ struct stat postparent;
+ struct stat read_child_buf;
+ } mknod;
- /* @failed_subvols: subvolumes on which FOP failed. Always
- a subset of @fop_subvols */
- unsigned char *failed_subvols;
+ struct {
+ ino_t ino;
+ uint64_t gen;
+ ino_t parent_ino;
+ int32_t mode;
+ inode_t *inode;
+ struct stat buf;
+ struct stat read_child_buf;
+ struct stat preparent;
+ struct stat postparent;
+ } mkdir;
- /* @dirtied: flag which indicates whether we set dirty flag
- in the OP. Typically true when we are performing operation
- on more than one subvol and optimistic changelog is disabled
+ struct {
+ ino_t parent_ino;
+ int32_t op_ret;
+ int32_t op_errno;
+ struct stat preparent;
+ struct stat postparent;
+ } unlink;
- A 'true' value set in @dirtied flag means an 'undirtying'
- has to be done in POST-OP phase.
- */
- gf_boolean_t dirtied;
+ struct {
+ ino_t parent_ino;
+ int32_t op_ret;
+ int32_t op_errno;
+ struct stat preparent;
+ struct stat postparent;
+ } rmdir;
- /* @inherited: flag which indicates that the dirty flags
- of the previous transaction were inherited
- */
- gf_boolean_t inherited;
+ struct {
+ ino_t oldparent_ino;
+ ino_t newparent_ino;
+ ino_t ino;
+ struct stat buf;
+ struct stat read_child_buf;
+ struct stat preoldparent;
+ struct stat prenewparent;
+ struct stat postoldparent;
+ struct stat postnewparent;
+ } rename;
- /*
- @no_uninherit: flag which indicates that a pre_op_uninherit()
- must _not_ be attempted (and returned as failure) always. This
- flag is set when a hard pre-op is performed, but not accounted
- for it in fd_ctx->on_disk[]. Such transactions are "isolated"
- from the pre-op piggybacking entirely and therefore uninherit
- must not be attempted.
- */
- gf_boolean_t no_uninherit;
+ struct {
+ ino_t ino;
+ uint64_t gen;
+ ino_t parent_ino;
+ inode_t *inode;
+ struct stat buf;
+ struct stat read_child_buf;
+ struct stat preparent;
+ struct stat postparent;
+ } link;
- /* @uninherit_done:
- @uninherit_value:
+ struct {
+ ino_t ino;
+ uint64_t gen;
+ ino_t parent_ino;
+ inode_t *inode;
+ struct stat buf;
+ struct stat read_child_buf;
+ char *linkpath;
+ struct stat preparent;
+ struct stat postparent;
+ } symlink;
- The above pair variables make pre_op_uninherit() idempotent.
- Both are FALSE initially. The first call to pre_op_uninherit
- sets @uninherit_done to TRUE and the return value to
- @uninherit_value. Further calls will check for @uninherit_done
- to be TRUE and if so will simply return @uninherit_value.
- */
- gf_boolean_t uninherit_done;
- gf_boolean_t uninherit_value;
+ struct {
+ int32_t flags;
+ dir_entry_t *entries;
+ int32_t count;
+ } setdents;
+ } cont;
+
+ struct {
+ off_t start, len;
- /* @changelog_resume: function to be called after changlogging
- (either pre-op or post-op) is done
- */
+ unsigned char *locked_nodes;
+ int lock_count;
- afr_changelog_resume_t changelog_resume;
+ const char *basename;
+ const char *new_basename;
- call_frame_t *main_frame;
+ loc_t parent_loc;
+ loc_t new_parent_loc;
- int (*wind) (call_frame_t *frame, xlator_t *this, int subvol);
+ afr_transaction_type type;
- int (*fop) (call_frame_t *frame, xlator_t *this);
+ int success_count;
+ int erase_pending;
+ int failure_count;
- int (*done) (call_frame_t *frame, xlator_t *this);
+ int last_tried;
+ int32_t *child_errno;
- int (*resume) (call_frame_t *frame, xlator_t *this);
+ call_frame_t *main_frame;
- int (*unwind) (call_frame_t *frame, xlator_t *this);
+ int (*fop) (call_frame_t *frame, xlator_t *this);
- /* post-op hook */
- } transaction;
+ int (*done) (call_frame_t *frame, xlator_t *this);
- syncbarrier_t barrier;
+ int (*resume) (call_frame_t *frame, xlator_t *this);
- struct marker_str marker;
+ int (*unwind) (call_frame_t *frame, xlator_t *this);
- /* extra data for fops */
- dict_t *xdata_req;
- dict_t *xdata_rsp;
+ } transaction;
- mode_t umask;
- int xflag;
- gf_boolean_t do_discovery;
- struct afr_reply *replies;
+ afr_self_heal_t self_heal;
} afr_local_t;
-typedef struct afr_read_subvol_args {
- ia_type_t ia_type;
- uuid_t gfid;
-} afr_read_subvol_args_t;
-
-/* did a call fail due to a child failing? */
-#define child_went_down(op_ret, op_errno) (((op_ret) < 0) && \
- ((op_errno == ENOTCONN) || \
- (op_errno == EBADFD)))
-int
-afr_inode_read_subvol_get (inode_t *inode, xlator_t *this,
- unsigned char *data_subvols,
- unsigned char *metadata_subvols,
- int *event_generation);
-int
-__afr_inode_read_subvol_get (inode_t *inode, xlator_t *this,
- unsigned char *data_subvols,
- unsigned char *metadata_subvols,
- int *event_generation);
-
-int
-__afr_inode_read_subvol_set (inode_t *inode, xlator_t *this,
- unsigned char *data_subvols,
- unsigned char *metadata_subvol,
- int event_generation);
-int
-afr_inode_read_subvol_set (inode_t *inode, xlator_t *this,
- unsigned char *data_subvols,
- unsigned char *metadata_subvols,
- int event_generation);
-
-int
-afr_inode_read_subvol_reset (inode_t *inode, xlator_t *this);
+typedef struct {
+ unsigned int *pre_op_done;
+ unsigned int *opened_on; /* which subvolumes the fd is open on */
+ unsigned int *pre_op_piggyback;
+ 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 */
-int
-afr_read_subvol_select_by_policy (inode_t *inode, xlator_t *this,
- unsigned char *readable,
- afr_read_subvol_args_t *args);
+ int32_t last_tried;
-int
-afr_inode_read_subvol_type_get (inode_t *inode, xlator_t *this,
- unsigned char *readable, int *event_p,
- int type);
-int
-afr_read_subvol_get (inode_t *inode, xlator_t *this, int *subvol_p,
- int *event_p, afr_transaction_type type,
- afr_read_subvol_args_t *args);
+ int hit, miss;
+ gf_boolean_t failed_over;
+ struct list_head entries; /* needed for readdir failover */
+} afr_fd_ctx_t;
-#define afr_data_subvol_get(i, t, s, e, a) \
- afr_read_subvol_get(i, t, s, e, AFR_DATA_TRANSACTION, a)
-#define afr_metadata_subvol_get(i, t, s, e, a) \
- afr_read_subvol_get(i, t, s, e, AFR_METADATA_TRANSACTION, a)
+/* try alloc and if it fails, goto label */
+#define ALLOC_OR_GOTO(var, type, label) do { \
+ var = CALLOC (sizeof (type), 1); \
+ if (!var) { \
+ gf_log (this->name, GF_LOG_ERROR, \
+ "out of memory :("); \
+ op_errno = ENOMEM; \
+ goto label; \
+ } \
+ } while (0);
-int
-afr_inode_refresh (call_frame_t *frame, xlator_t *this, inode_t *inode,
- afr_inode_refresh_cbk_t cbk);
-int32_t
-afr_notify (xlator_t *this, int32_t event, void *data, void *data2);
+/* did a call fail due to a child failing? */
+#define child_went_down(op_ret, op_errno) (((op_ret) < 0) && \
+ ((op_errno == ENOTCONN) || \
+ (op_errno == EBADFD)))
-int
-xattr_is_equal (dict_t *this, char *key1, data_t *value1, void *data);
+#define afr_fop_failed(op_ret, op_errno) ((op_ret) == -1)
-int
-afr_init_entry_lockee (afr_entry_lockee_t *lockee, afr_local_t *local,
- loc_t *loc, char *basename, int child_count);
+/* have we tried all children? */
+#define all_tried(i, count) ((i) == (count) - 1)
void
-afr_entry_lockee_cleanup (afr_internal_lock_t *int_lock);
+afr_set_lk_owner (call_frame_t *frame, xlator_t *this);
int
-afr_attempt_lock_recovery (xlator_t *this, int32_t child_index);
+afr_fd_ctx_set (xlator_t *this, fd_t *fd);
-int
-afr_mark_locked_nodes (xlator_t *this, fd_t *fd,
- unsigned char *locked_nodes);
+uint64_t
+afr_read_child (xlator_t *this, inode_t *inode);
void
-afr_set_lk_owner (call_frame_t *frame, xlator_t *this, void *lk_owner);
-
-int
-afr_set_lock_number (call_frame_t *frame, xlator_t *this);
+afr_set_read_child (xlator_t *this, inode_t *inode, int32_t read_child);
-int32_t
-afr_unlock (call_frame_t *frame, xlator_t *this);
-
-int
-afr_nonblocking_entrylk (call_frame_t *frame, xlator_t *this);
+void
+afr_build_parent_loc (loc_t *parent, loc_t *child);
int
-afr_nonblocking_inodelk (call_frame_t *frame, xlator_t *this);
+afr_up_children_count (int child_count, unsigned char *child_up);
int
-afr_blocking_lock (call_frame_t *frame, xlator_t *this);
+afr_locked_nodes_count (unsigned char *locked_nodes, int child_count);
-int
-afr_internal_lock_finish (call_frame_t *frame, xlator_t *this);
+ino64_t
+afr_itransform (ino64_t ino, int child_count, int child_index);
int
-afr_lk_transfer_datalock (call_frame_t *dst, call_frame_t *src, char *dom,
- unsigned int child_count);
+afr_deitransform (ino64_t ino, int child_count);
-int
-__afr_fd_ctx_set (xlator_t *this, fd_t *fd);
+void
+afr_local_cleanup (afr_local_t *local, xlator_t *this);
int
-afr_fd_ctx_set (xlator_t *this, fd_t *fd);
+afr_frame_return (call_frame_t *frame);
-afr_fd_ctx_t *
-afr_fd_ctx_get (fd_t *fd, xlator_t *this);
+uint64_t
+afr_is_split_brain (xlator_t *this, inode_t *inode);
-int
-afr_build_parent_loc (loc_t *parent, loc_t *child, int32_t *op_errno);
-
-int
-afr_locked_nodes_count (unsigned char *locked_nodes, int child_count);
+void
+afr_set_split_brain (xlator_t *this, inode_t *inode, gf_boolean_t set);
int
-afr_replies_interpret (call_frame_t *frame, xlator_t *this, inode_t *inode);
+afr_open (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
+ fd_t *fd, int32_t wbflags);
void
-afr_local_replies_wipe (afr_local_t *local, afr_private_t *priv);
+afr_set_opendir_done (xlator_t *this, inode_t *inode);
-void
-afr_local_cleanup (afr_local_t *local, xlator_t *this);
-
-int
-afr_frame_return (call_frame_t *frame);
-
-int
-afr_open (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
- fd_t *fd, dict_t *xdata);
+uint64_t
+afr_is_opendir_done (xlator_t *this, inode_t *inode);
void
afr_local_transaction_cleanup (afr_local_t *local, xlator_t *this);
@@ -872,160 +626,134 @@ afr_local_transaction_cleanup (afr_local_t *local, xlator_t *this);
int
afr_cleanup_fd_ctx (xlator_t *this, fd_t *fd);
-#define AFR_STACK_UNWIND(fop, frame, params ...) \
- do { \
- afr_local_t *__local = NULL; \
- xlator_t *__this = NULL; \
- if (frame) { \
- __local = frame->local; \
- __this = frame->this; \
- frame->local = NULL; \
- } \
- STACK_UNWIND_STRICT (fop, frame, params); \
- if (__local) { \
- afr_local_cleanup (__local, __this); \
- mem_put (__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); \
- } \
- } while (0);
-
-#define AFR_FRAME_INIT(frame, op_errno) \
- ({frame->local = mem_get0 (THIS->local_pool); \
- if (afr_local_init (frame->local, THIS->private, &op_errno)) { \
- afr_local_cleanup (frame->local, THIS); \
- mem_put (frame->local); \
- frame->local = NULL; }; \
- frame->local;})
-
-#define AFR_STACK_RESET(frame) \
- do { \
- afr_local_t *__local = NULL; \
- xlator_t *__this = NULL; \
- __local = frame->local; \
- __this = frame->this; \
- frame->local = NULL; \
- int __opr; \
- STACK_RESET (frame->root); \
- if (__local) { \
- afr_local_cleanup (__local, __this); \
- mem_put (__local); \
- } \
- AFR_FRAME_INIT (frame, __opr); \
- } while (0)
+int
+afr_openfd_flush (call_frame_t *frame, xlator_t *this, fd_t *fd);
+
+
+#define AFR_STACK_UNWIND(fop, frame, params ...) \
+ do { \
+ afr_local_t *__local = NULL; \
+ xlator_t *__this = NULL; \
+ __local = frame->local; \
+ __this = frame->this; \
+ frame->local = NULL; \
+ STACK_UNWIND_STRICT (fop, frame, params); \
+ afr_local_cleanup (__local, __this); \
+ 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); \
+ afr_local_cleanup (__local, __this); \
+ free (__local); \
+} while (0);
/* allocate and return a string that is the basename of argument */
-static inline char *
-AFR_BASENAME (const char *str)
+static inline char *
+AFR_BASENAME (const char *str)
{
- char *__tmp_str = NULL;
- char *__basename_str = NULL;
- __tmp_str = gf_strdup (str);
- __basename_str = gf_strdup (basename (__tmp_str));
- GF_FREE (__tmp_str);
- return __basename_str;
+ char *__tmp_str = NULL;
+ char *__basename_str = NULL;
+ __tmp_str = strdup (str);
+ __basename_str = strdup (basename (__tmp_str));
+ FREE (__tmp_str);
+ return __basename_str;
}
-call_frame_t *
-afr_copy_frame (call_frame_t *base);
-
-int
-afr_transaction_local_init (afr_local_t *local, xlator_t *this);
-
-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 );
-
-int
-afr_local_init (afr_local_t *local, afr_private_t *priv, int32_t *op_errno);
-
-int
-afr_internal_lock_init (afr_internal_lock_t *lk, size_t child_count,
- transaction_lk_type_t lk_type);
-
-int
-afr_higher_errno (int32_t old_errno, int32_t new_errno);
-
-int
-afr_final_errno (afr_local_t *local, afr_private_t *priv);
-
-int
-afr_xattr_req_prepare (xlator_t *this, dict_t *xattr_req);
+/* initialize local_t */
+static inline int
+AFR_LOCAL_INIT (afr_local_t *local, afr_private_t *priv)
+{
+ local->child_up = CALLOC (sizeof (*local->child_up),
+ priv->child_count);
+ if (!local->child_up) {
+ return -ENOMEM;
+ }
-void
-afr_fix_open (fd_t *fd, xlator_t *this);
+ memcpy (local->child_up, priv->child_up,
+ sizeof (*local->child_up) * priv->child_count);
-afr_fd_ctx_t *
-afr_fd_ctx_get (fd_t *fd, xlator_t *this);
-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);
+ local->call_count = afr_up_children_count (priv->child_count, local->child_up);
+ if (local->call_count == 0)
+ return -ENOTCONN;
-void
-afr_matrix_cleanup (int32_t **pending, unsigned int m);
+ local->transaction.erase_pending = 1;
-int32_t**
-afr_matrix_create (unsigned int m, unsigned int n);
+ local->op_ret = -1;
+ local->op_errno = EUCLEAN;
-int**
-afr_mark_pending_changelog (afr_private_t *priv, unsigned char *pending,
- dict_t *xattr, ia_type_t iat);
+ return 0;
+}
-void
-afr_filter_xattrs (dict_t *xattr);
-/*
- * Special value indicating we should use the "auto" quorum method instead of
- * a fixed value (including zero to turn off quorum enforcement).
+/**
+ * first_up_child - return the index of the first child that is up
*/
-#define AFR_QUORUM_AUTO INT_MAX
-
-int
-afr_fd_report_unstable_write (xlator_t *this, fd_t *fd);
-
-gf_boolean_t
-afr_fd_has_witnessed_unstable_write (xlator_t *this, fd_t *fd);
-void
-afr_delayed_changelog_wake_resume (xlator_t *this, fd_t *fd, call_stub_t *stub);
-
-int
-afr_inodelk_init (afr_inodelk_t *lk, char *dom, size_t child_count);
-
-void
-afr_handle_open_fd_count (call_frame_t *frame, xlator_t *this);
-
-int
-afr_local_pathinfo (char *pathinfo, gf_boolean_t *is_local);
+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);
+
+ return ret;
+}
-void
-afr_remove_eager_lock_stub (afr_local_t *local);
-void
-afr_replies_wipe (struct afr_reply *replies, int count);
+static inline int
+afr_transaction_local_init (afr_local_t *local, afr_private_t *priv)
+{
+ int i;
+
+ local->first_up_child = afr_first_up_child (priv);
+
+ local->child_errno = CALLOC (sizeof (*local->child_errno),
+ priv->child_count);
+ if (!local->child_errno) {
+ return -ENOMEM;
+ }
+
+ local->pending = CALLOC (sizeof (*local->pending),
+ priv->child_count);
+
+ if (!local->pending) {
+ return -ENOMEM;
+ }
+
+ for (i = 0; i < priv->child_count; i++) {
+ local->pending[i] = CALLOC (sizeof (*local->pending[i]),
+ 3); /* data + metadata + entry */
+ if (!local->pending[i])
+ return -ENOMEM;
+ }
+
+ local->transaction.locked_nodes = CALLOC (sizeof (*local->transaction.locked_nodes),
+ priv->child_count);
-gf_boolean_t
-afr_xattrs_are_equal (dict_t *dict1, dict_t *dict2);
+ local->transaction.child_errno = CALLOC (sizeof (*local->transaction.child_errno),
+ priv->child_count);
-gf_boolean_t
-afr_is_xattr_ignorable (char *key);
+ return 0;
+}
-int
-afr_get_heal_info (call_frame_t *frame, xlator_t *this, loc_t *loc,
- dict_t *xdata);
#endif /* __AFR_H__ */
diff --git a/xlators/cluster/afr/src/pump.c b/xlators/cluster/afr/src/pump.c
deleted file mode 100644
index 23618b8ac1c..00000000000
--- a/xlators/cluster/afr/src/pump.c
+++ /dev/null
@@ -1,2474 +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 <unistd.h>
-#include <sys/time.h>
-#include <stdlib.h>
-#include <fnmatch.h>
-
-#ifndef _CONFIG_H
-#define _CONFIG_H
-#include "config.h"
-#endif
-
-#include "afr-common.c"
-#include "defaults.c"
-#include "glusterfs.h"
-#include "pump.h"
-
-
-static int
-afr_set_dict_gfid (dict_t *dict, uuid_t gfid)
-{
- int ret = 0;
- uuid_t *pgfid = NULL;
-
- 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));
- if (ret)
- gf_log (THIS->name, GF_LOG_ERROR, "gfid set failed");
-
-out:
- if (ret && pgfid)
- GF_FREE (pgfid);
- return ret;
-}
-
-static 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;
-}
-
-static 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;
-}
-
-static 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);
-}
-
-static 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);
-}
-
-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)
-{
- afr_private_t *priv = NULL;
- pump_private_t *pump_priv = NULL;
-
- priv = this->private;
- pump_priv = priv->pump_private;
-
- pump_priv->pump_start_pending = 1;
-
- return 0;
-}
-
-static int
-is_pump_start_pending (xlator_t *this)
-{
- afr_private_t *priv = NULL;
- pump_private_t *pump_priv = NULL;
-
- priv = this->private;
- pump_priv = priv->pump_private;
-
- return (pump_priv->pump_start_pending);
-}
-
-static int
-pump_remove_start_pending (xlator_t *this)
-{
- afr_private_t *priv = NULL;
- pump_private_t *pump_priv = NULL;
-
- priv = this->private;
- pump_priv = priv->pump_private;
-
- pump_priv->pump_start_pending = 0;
-
- return 0;
-}
-
-static pump_state_t
-pump_get_state ()
-{
- xlator_t *this = NULL;
- afr_private_t *priv = NULL;
- pump_private_t *pump_priv = NULL;
-
- pump_state_t ret;
-
- this = THIS;
- priv = this->private;
- pump_priv = priv->pump_private;
-
- LOCK (&pump_priv->pump_state_lock);
- {
- ret = pump_priv->pump_state;
- }
- UNLOCK (&pump_priv->pump_state_lock);
-
- return ret;
-}
-
-int
-pump_change_state (xlator_t *this, pump_state_t state)
-{
- afr_private_t *priv = NULL;
- pump_private_t *pump_priv = NULL;
-
- pump_state_t state_old;
- pump_state_t state_new;
-
-
- priv = this->private;
- pump_priv = priv->pump_private;
-
- GF_ASSERT (pump_priv);
-
- LOCK (&pump_priv->pump_state_lock);
- {
- state_old = pump_priv->pump_state;
- state_new = state;
-
- pump_priv->pump_state = state;
-
- }
- UNLOCK (&pump_priv->pump_state_lock);
-
- gf_log (this->name, GF_LOG_DEBUG,
- "Pump changing state from %d to %d",
- state_old,
- state_new);
-
- return 0;
-}
-
-static int
-pump_set_resume_path (xlator_t *this, const char *path)
-{
- int ret = 0;
-
- afr_private_t *priv = NULL;
- pump_private_t *pump_priv = NULL;
-
- priv = this->private;
- pump_priv = priv->pump_private;
-
- GF_ASSERT (pump_priv);
-
- LOCK (&pump_priv->resume_path_lock);
- {
- strncpy (pump_priv->resume_path, path, strlen (path) + 1);
- }
- UNLOCK (&pump_priv->resume_path_lock);
-
- return ret;
-}
-
-static int
-pump_save_path (xlator_t *this, const char *path)
-{
- afr_private_t *priv = NULL;
- pump_state_t state;
- dict_t *dict = NULL;
- loc_t loc = {0};
- int dict_ret = 0;
- int ret = -1;
-
- state = pump_get_state ();
- if (state == PUMP_STATE_RESUME)
- return 0;
-
- priv = this->private;
-
- GF_ASSERT (priv->root_inode);
-
- afr_build_root_loc (this, &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,
- "setxattr failed - could not save path=%s", path);
- } else {
- gf_log (this->name, GF_LOG_DEBUG,
- "setxattr succeeded - saved path=%s", path);
- }
-
- dict_unref (dict);
-
- loc_wipe (&loc);
- return 0;
-}
-
-static int
-pump_check_and_update_status (xlator_t *this)
-{
- pump_state_t state;
- int ret = -1;
-
- state = pump_get_state ();
-
- switch (state) {
-
- case PUMP_STATE_RESUME:
- case PUMP_STATE_RUNNING:
- {
- ret = 0;
- break;
- }
- case PUMP_STATE_PAUSE:
- {
- ret = -1;
- break;
- }
- case PUMP_STATE_ABORT:
- {
- pump_save_path (this, "/");
- ret = -1;
- break;
- }
- default:
- {
- gf_log (this->name, GF_LOG_DEBUG,
- "Unknown pump state");
- ret = -1;
- break;
- }
-
- }
-
- return ret;
-}
-
-static const char *
-pump_get_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_priv->resume_path;
-
- return resume_path;
-}
-
-static int
-pump_update_resume_state (xlator_t *this, const char *path)
-{
- pump_state_t state;
- const char *resume_path = NULL;
-
- state = pump_get_state ();
-
- if (state == PUMP_STATE_RESUME) {
- resume_path = pump_get_resume_path (this);
- if (strcmp (resume_path, "/") == 0) {
- gf_log (this->name, GF_LOG_DEBUG,
- "Reached the resume path (/). Proceeding to change state"
- " to running");
- pump_change_state (this, PUMP_STATE_RUNNING);
- } else if (strcmp (resume_path, path) == 0) {
- gf_log (this->name, GF_LOG_DEBUG,
- "Reached the resume path. Proceeding to change state"
- " to running");
- pump_change_state (this, PUMP_STATE_RUNNING);
- } else {
- gf_log (this->name, GF_LOG_DEBUG,
- "Not yet hit the resume path:res-path=%s,path=%s",
- resume_path, path);
- }
- }
-
- return 0;
-}
-
-static gf_boolean_t
-is_pump_traversal_allowed (xlator_t *this, const char *path)
-{
- pump_state_t state;
- const char *resume_path = NULL;
- gf_boolean_t ret = _gf_true;
-
- state = pump_get_state ();
-
- if (state == PUMP_STATE_RESUME) {
- resume_path = pump_get_resume_path (this);
- if (strstr (resume_path, path)) {
- gf_log (this->name, GF_LOG_DEBUG,
- "On the right path to resumption path");
- ret = _gf_true;
- } else {
- gf_log (this->name, GF_LOG_DEBUG,
- "Not the right path to resuming=> ignoring traverse");
- ret = _gf_false;
- }
- }
-
- return ret;
-}
-
-static int
-pump_save_file_stats (xlator_t *this, const char *path)
-{
- afr_private_t *priv = NULL;
- pump_private_t *pump_priv = NULL;
-
- priv = this->private;
- pump_priv = priv->pump_private;
-
- LOCK (&pump_priv->resume_path_lock);
- {
- pump_priv->number_files_pumped++;
-
- strncpy (pump_priv->current_file, path,
- PATH_MAX);
- }
- UNLOCK (&pump_priv->resume_path_lock);
-
- return 0;
-}
-
-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;
-
- INIT_LIST_HEAD (&entries.list);
- this = THIS;
-
- GF_ASSERT (loc->inode);
-
- 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);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_DEBUG,
- "opendir failed on %s", loc->path);
- goto out;
- }
-
- gf_log (this->name, GF_LOG_TRACE,
- "pump opendir on %s returned=%d",
- loc->path, ret);
-
- while (syncop_readdirp (this, fd, 131072, offset, NULL, &entries)) {
- free_entries = _gf_true;
-
- if (list_empty (&entries.list)) {
- gf_log (this->name, GF_LOG_TRACE,
- "no more entries in directory");
- goto out;
- }
-
- list_for_each_entry_safe (entry, tmp, &entries.list, list) {
- 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)
- goto out;
-
- if ((strcmp (entry->d_name, ".") == 0) ||
- (strcmp (entry->d_name, "..") == 0))
- continue;
-
- is_directory_empty = _gf_false;
- gf_log (this->name, GF_LOG_DEBUG,
- "lookup %s => %"PRId64,
- entry_loc.path,
- iatt.ia_ino);
-
- 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;
- }
-
- ret = afr_selfheal_name (this, loc->gfid, entry->d_name,
- NULL);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "%s: name self-heal failed (%s/%s)",
- entry_loc.path, uuid_utoa (loc->gfid),
- entry->d_name);
- continue;
- }
-
- ret = afr_selfheal (this, iatt.ia_gfid);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "%s: self-heal failed (%s)",
- entry_loc.path, uuid_utoa (iatt.ia_gfid));
- continue;
- }
-
- pump_fill_loc_info (&entry_loc, &iatt, &parent);
-
- pump_update_resume_state (this, entry_loc.path);
-
- pump_save_path (this, entry_loc.path);
- pump_save_file_stats (this, entry_loc.path);
-
- ret = pump_check_and_update_status (this);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_DEBUG,
- "Pump beginning to exit out");
- goto out;
- }
-
- if (IA_ISDIR (iatt.ia_type)) {
- if (is_pump_traversal_allowed (this, entry_loc.path)) {
- gf_log (this->name, GF_LOG_TRACE,
- "entering dir=%s", entry->d_name);
- gf_pump_traverse_directory (&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 && (strcmp (loc->path, "/") == 0)) {
- 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;
-}
-
-static int
-pump_update_resume_path (xlator_t *this)
-{
- const char *resume_path = NULL;
-
- resume_path = pump_get_resume_path (this);
-
- if (resume_path) {
- gf_log (this->name, GF_LOG_DEBUG,
- "Found a path to resume from: %s",
- resume_path);
-
- }else {
- gf_log (this->name, GF_LOG_DEBUG,
- "Did not find a path=> setting to '/'");
- pump_set_resume_path (this, "/");
- }
-
- pump_change_state (this, PUMP_STATE_RESUME);
-
- 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, 0);
-
- ret = syncop_removexattr (priv->children[sink], &loc,
- PUMP_SINK_COMPLETE, 0);
-
- for (i = 0; i < priv->child_count; i++) {
- ret = syncop_removexattr (priv->children[i], &loc,
- PUMP_SOURCE_COMPLETE, 0);
- if (ret) {
- gf_log (this->name, GF_LOG_DEBUG, "removexattr "
- "failed with %s", strerror (-ret));
- }
- }
-
- loc_wipe (&loc);
- return pump_command_reply (frame, this);
-}
-
-static int
-pump_complete_migration (xlator_t *this)
-{
- afr_private_t *priv = NULL;
- pump_private_t *pump_priv = NULL;
- dict_t *dict = NULL;
- pump_state_t state;
- loc_t loc = {0};
- int dict_ret = 0;
- int ret = -1;
-
- priv = this->private;
- pump_priv = priv->pump_private;
-
- GF_ASSERT (priv->root_inode);
-
- afr_build_root_loc (this, &loc);
-
- dict = dict_new ();
-
- state = pump_get_state ();
- if (state == PUMP_STATE_RUNNING) {
- gf_log (this->name, GF_LOG_DEBUG,
- "Pump finished pumping");
-
- 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) {
- gf_log (this->name, GF_LOG_DEBUG,
- "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) {
- gf_log (this->name, GF_LOG_DEBUG,
- "setxattr failed - while notifying sink complete");
- }
-
- 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_lookup_sink (loc_t *loc)
-{
- xlator_t *this = NULL;
- struct iatt iatt, parent;
- dict_t *xattr_rsp;
- dict_t *xattr_req = NULL;
- int ret = 0;
-
- this = THIS;
-
- xattr_req = dict_new ();
-
- ret = afr_set_root_gfid (xattr_req);
- if (ret)
- goto out;
-
- ret = syncop_lookup (PUMP_SINK_CHILD (this), loc,
- xattr_req, &iatt, &xattr_rsp, &parent);
-
- if (ret) {
- gf_log (this->name, GF_LOG_DEBUG,
- "Lookup on sink child failed");
- ret = -1;
- goto out;
- }
-
-out:
- if (xattr_req)
- dict_unref (xattr_req);
-
- return ret;
-}
-
-static int
-pump_task (void *data)
-{
- xlator_t *this = NULL;
- afr_private_t *priv = NULL;
-
-
- loc_t loc = {0};
- struct iatt iatt, parent;
- dict_t *xattr_rsp = NULL;
- dict_t *xattr_req = NULL;
-
- int ret = -1;
-
- this = THIS;
- priv = this->private;
-
- GF_ASSERT (priv->root_inode);
-
- afr_build_root_loc (this, &loc);
- xattr_req = dict_new ();
- if (!xattr_req) {
- gf_log (this->name, GF_LOG_DEBUG,
- "Out of memory");
- ret = -1;
- goto out;
- }
-
- afr_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));
-
- ret = pump_check_and_update_status (this);
- if (ret < 0) {
- goto out;
- }
-
- pump_update_resume_path (this);
-
- afr_set_root_gfid (xattr_req);
- ret = pump_lookup_sink (&loc);
- if (ret) {
- pump_update_resume_path (this);
- goto out;
- }
-
- gf_pump_traverse_directory (&loc);
-
- pump_complete_migration (this);
-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)
-{
- xlator_t *this = NULL;
- afr_private_t *priv = NULL;
-
- this = THIS;
-
- priv = this->private;
-
- inode_unref (priv->root_inode);
- STACK_DESTROY (sync_frame->root);
-
- gf_log (this->name, GF_LOG_DEBUG,
- "Pump xlator exiting");
- return 0;
-}
-
-int
-pump_start (call_frame_t *pump_frame, xlator_t *this)
-{
- afr_private_t *priv = NULL;
- pump_private_t *pump_priv = NULL;
-
- int ret = -1;
-
- 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;
-
- ret = synctask_new (pump_priv->env, pump_task,
- pump_task_completion,
- pump_frame, NULL);
- if (ret == -1) {
- gf_log (this->name, GF_LOG_ERROR,
- "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);
-
- priv->use_afr_in_pump = 1;
-out:
- return ret;
-}
-
-static int
-pump_start_synctask (xlator_t *this)
-{
- call_frame_t *frame = NULL;
- int ret = 0;
-
- frame = create_frame (this, this->ctx->pool);
- if (!frame) {
- gf_log (this->name, GF_LOG_ERROR,
- "Out of memory");
- ret = -1;
- goto out;
- }
-
- pump_change_state (this, PUMP_STATE_RUNNING);
-
- ret = pump_start (frame, this);
-
-out:
- return ret;
-}
-
-int32_t
-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)
-
-{
- call_frame_t *prev = NULL;
- afr_local_t *local = NULL;
- int ret = 0;
-
- local = frame->local;
-
- if (op_ret < 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "Could not initiate destination "
- "brick connect");
- ret = op_ret;
- goto out;
- }
-
- gf_log (this->name, GF_LOG_DEBUG,
- "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);
-
-out:
- local->op_ret = ret;
- pump_command_reply (frame, this);
-
- return 0;
-}
-
-static int
-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;
- loc_t loc = {0};
-
- int ret = 0;
-
- priv = this->private;
- local = frame->local;
-
- GF_ASSERT (priv->root_inode);
-
- afr_build_root_loc (this, &loc);
-
- data = data_ref (dict_get (local->dict, RB_PUMP_CMD_START));
- if (!data) {
- ret = -1;
- gf_log (this->name, GF_LOG_ERROR,
- "Could not get destination brick value");
- goto out;
- }
-
- dict = dict_new ();
- if (!dict) {
- 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);
-
- ret = dict_set_dynstr (dict, CLIENT_CMD_CONNECT, clnt_cmd);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "Could not inititiate destination brick "
- "connect");
- goto out;
- }
-
- STACK_WIND (frame,
- pump_cmd_start_setxattr_cbk,
- PUMP_SINK_CHILD(this),
- PUMP_SINK_CHILD(this)->fops->setxattr,
- &loc,
- dict,
- 0, NULL);
-
- ret = 0;
-
-out:
- if (dict)
- dict_unref (dict);
-
- if (data)
- data_unref (data);
-
- if (ret && clnt_cmd)
- GF_FREE (clnt_cmd);
-
- loc_wipe (&loc);
- return ret;
-}
-
-static int
-is_pump_aborted (xlator_t *this)
-{
- pump_state_t state;
-
- state = pump_get_state ();
-
- return ((state == PUMP_STATE_ABORT));
-}
-
-int32_t
-pump_cmd_start_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)
-{
- afr_local_t *local = NULL;
- char *path = NULL;
-
- pump_state_t state;
- int ret = 0;
- int need_unwind = 0;
- int dict_ret = -1;
-
- local = frame->local;
-
- if (op_ret < 0) {
- gf_log (this->name, GF_LOG_DEBUG,
- "getxattr failed - changing pump "
- "state to RUNNING with '/'");
- path = "/";
- ret = op_ret;
- } else {
- gf_log (this->name, GF_LOG_TRACE,
- "getxattr succeeded");
-
- dict_ret = dict_get_str (dict, PUMP_PATH, &path);
- if (dict_ret < 0)
- path = "/";
- }
-
- state = pump_get_state ();
- if ((state == PUMP_STATE_RUNNING) ||
- (state == PUMP_STATE_RESUME)) {
- gf_log (this->name, GF_LOG_ERROR,
- "Pump is already started");
- ret = -1;
- goto out;
- }
-
- pump_set_resume_path (this, path);
-
- if (is_pump_aborted (this))
- /* We're re-starting pump afresh */
- ret = pump_initiate_sink_connect (frame, this);
- else {
- /* We're re-starting pump from a previous
- pause */
- gf_log (this->name, GF_LOG_DEBUG,
- "about to start synctask");
- ret = pump_start_synctask (this);
- need_unwind = 1;
- }
-
-out:
- if ((ret < 0) || (need_unwind == 1)) {
- local->op_ret = ret;
- pump_command_reply (frame, this);
- }
- return 0;
-}
-
-int
-pump_execute_status (call_frame_t *frame, xlator_t *this)
-{
- afr_private_t *priv = NULL;
- pump_private_t *pump_priv = NULL;
-
- uint64_t number_files = 0;
-
- char filename[PATH_MAX];
- char summary[PATH_MAX+256];
- char *dict_str = NULL;
-
- int32_t op_ret = 0;
- int32_t op_errno = 0;
-
- dict_t *dict = NULL;
- int ret = -1;
-
- priv = this->private;
- pump_priv = priv->pump_private;
-
- LOCK (&pump_priv->resume_path_lock);
- {
- number_files = pump_priv->number_files_pumped;
- strncpy (filename, pump_priv->current_file, PATH_MAX);
- }
- UNLOCK (&pump_priv->resume_path_lock);
-
- dict_str = GF_CALLOC (1, PATH_MAX + 256, gf_afr_mt_char);
- if (!dict_str) {
- gf_log (this->name, GF_LOG_ERROR,
- "Out of memory");
- op_ret = -1;
- op_errno = ENOMEM;
- goto out;
- }
-
- if (pump_priv->pump_finished) {
- snprintf (summary, PATH_MAX+256,
- "no_of_files=%"PRIu64, number_files);
- } else {
- snprintf (summary, PATH_MAX+256,
- "no_of_files=%"PRIu64":current_file=%s",
- number_files, filename);
- }
- snprintf (dict_str, PATH_MAX+256, "status=%d:%s",
- (pump_priv->pump_finished)?1:0, summary);
-
- dict = dict_new ();
-
- ret = dict_set_dynstr (dict, RB_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;
- }
-
- op_ret = 0;
-
-out:
-
- AFR_STACK_UNWIND (getxattr, frame, op_ret, op_errno, dict, NULL);
-
- if (dict)
- dict_unref (dict);
-
- GF_FREE (dict_str);
-
- return 0;
-}
-
-int
-pump_execute_pause (call_frame_t *frame, xlator_t *this)
-{
- afr_local_t *local = NULL;
-
- local = frame->local;
-
- pump_change_state (this, PUMP_STATE_PAUSE);
-
- local->op_ret = 0;
- pump_command_reply (frame, this);
-
- return 0;
-}
-
-int
-pump_execute_start (call_frame_t *frame, xlator_t *this)
-{
- afr_private_t *priv = NULL;
- afr_local_t *local = NULL;
-
- int ret = 0;
- loc_t loc = {0};
-
- priv = this->private;
- local = frame->local;
-
- if (!priv->root_inode) {
- gf_log (this->name, GF_LOG_ERROR,
- "Pump xlator cannot be started without an initial "
- "lookup");
- ret = -1;
- goto out;
- }
-
- GF_ASSERT (priv->root_inode);
-
- afr_build_root_loc (this, &loc);
-
- STACK_WIND (frame,
- pump_cmd_start_getxattr_cbk,
- PUMP_SOURCE_CHILD(this),
- PUMP_SOURCE_CHILD(this)->fops->getxattr,
- &loc,
- PUMP_PATH, NULL);
-
- ret = 0;
-
-out:
- if (ret < 0) {
- local->op_ret = ret;
- 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;
-
- priv = this->private;
- pump_priv = priv->pump_private;
- local = frame->local;
-
- pump_change_state (this, PUMP_STATE_ABORT);
-
- LOCK (&pump_priv->resume_path_lock);
- {
- pump_priv->number_files_pumped = 0;
- pump_priv->current_file[0] = '\0';
- }
- 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);
- }
-
- return 0;
-}
-
-gf_boolean_t
-pump_command_status (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_STATUS, &cmd);
- if (dict_ret < 0) {
- gf_log (this->name, GF_LOG_DEBUG,
- "Not a pump status command");
- ret = _gf_false;
- goto out;
- }
-
- gf_log (this->name, GF_LOG_DEBUG,
- "Hit a pump command - status");
- ret = _gf_true;
-
-out:
- return ret;
-
-}
-
-gf_boolean_t
-pump_command_pause (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_PAUSE, &cmd);
- if (dict_ret < 0) {
- gf_log (this->name, GF_LOG_DEBUG,
- "Not a pump pause command");
- ret = _gf_false;
- goto out;
- }
-
- gf_log (this->name, GF_LOG_DEBUG,
- "Hit a pump command - pause");
- ret = _gf_true;
-
-out:
- return ret;
-
-}
-
-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);
- if (dict_ret < 0) {
- gf_log (this->name, GF_LOG_DEBUG,
- "Not a pump abort command");
- ret = _gf_false;
- goto out;
- }
-
- gf_log (this->name, GF_LOG_DEBUG,
- "Hit a pump command - abort");
- ret = _gf_true;
-
-out:
- return ret;
-
-}
-
-gf_boolean_t
-pump_command_start (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_START, &cmd);
- if (dict_ret < 0) {
- gf_log (this->name, GF_LOG_DEBUG,
- "Not a pump start command");
- ret = _gf_false;
- goto out;
- }
-
- gf_log (this->name, GF_LOG_DEBUG,
- "Hit a pump command - start");
- ret = _gf_true;
-
-out:
- return ret;
-
-}
-
-int
-pump_getxattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
- const char *name, dict_t *xdata)
-{
- afr_private_t *priv = NULL;
- int op_errno = 0;
- int ret = 0;
-
- priv = this->private;
-
- 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;
- }
-
- if (name) {
- if (!strncmp (name, AFR_XATTR_PREFIX,
- strlen (AFR_XATTR_PREFIX))) {
-
- op_errno = ENODATA;
- goto out;
- }
-
- if (!strcmp (name, RB_PUMP_CMD_STATUS)) {
- gf_log (this->name, GF_LOG_DEBUG,
- "Hit pump command - status");
- pump_execute_status (frame, this);
- ret = 0;
- goto out;
- }
- }
-
- afr_getxattr (frame, this, loc, name, xdata);
-
- ret = 0;
-out:
- if (ret < 0)
- AFR_STACK_UNWIND (getxattr, frame, -1, op_errno, NULL, NULL);
- return 0;
-}
-
-int
-pump_command_reply (call_frame_t *frame, xlator_t *this)
-{
- afr_local_t *local = NULL;
-
- local = frame->local;
-
- if (local->op_ret < 0)
- gf_log (this->name, GF_LOG_INFO,
- "Command failed");
- else
- gf_log (this->name, GF_LOG_INFO,
- "Command succeeded");
-
- AFR_STACK_UNWIND (setxattr,
- frame,
- local->op_ret,
- local->op_errno, NULL);
-
- return 0;
-}
-
-int
-pump_parse_command (call_frame_t *frame, xlator_t *this, dict_t *dict,
- int *op_errno_p)
-{
- afr_local_t *local = NULL;
- int ret = -1;
- int op_errno = 0;
-
- if (pump_command_start (this, dict)) {
- local = AFR_FRAME_INIT (frame, op_errno);
- if (!local)
- goto out;
- local->dict = dict_ref (dict);
- ret = pump_execute_start (frame, this);
-
- } else if (pump_command_pause (this, dict)) {
- local = AFR_FRAME_INIT (frame, op_errno);
- if (!local)
- goto out;
- local->dict = dict_ref (dict);
- ret = pump_execute_pause (frame, this);
-
- } else if (pump_command_abort (this, dict)) {
- local = AFR_FRAME_INIT (frame, op_errno);
- if (!local)
- goto out;
- local->dict = dict_ref (dict);
- ret = pump_execute_abort (frame, this);
-
- } else if (pump_command_commit (this, dict)) {
- local = AFR_FRAME_INIT (frame, op_errno);
- if (!local)
- goto out;
- local->dict = dict_ref (dict);
- ret = pump_execute_commit (frame, this);
- }
-out:
- if (op_errno_p)
- *op_errno_p = op_errno;
- return ret;
-}
-
-int
-pump_setxattr (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *dict,
- int32_t flags, dict_t *xdata)
-{
- afr_private_t *priv = NULL;
- int ret = -1;
- int op_errno = 0;
-
- GF_IF_INTERNAL_XATTR_GOTO ("trusted.glusterfs.pump*", dict, 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;
- }
-
- ret = pump_parse_command (frame, this, dict, &op_errno);
- if (ret >= 0)
- goto out;
-
- afr_setxattr (frame, this, loc, dict, flags, xdata);
-
- ret = 0;
-out:
- if (ret < 0) {
- AFR_STACK_UNWIND (setxattr, frame, -1, op_errno, NULL);
- }
-
- return 0;
-}
-
-/* Defaults */
-static int32_t
-pump_lookup (call_frame_t *frame,
- xlator_t *this,
- loc_t *loc,
- dict_t *xattr_req)
-{
- afr_private_t *priv = NULL;
- priv = this->private;
- if (!priv->use_afr_in_pump) {
- STACK_WIND (frame,
- default_lookup_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->lookup,
- loc,
- xattr_req);
- return 0;
- }
-
- afr_lookup (frame, this, loc, xattr_req);
- return 0;
-}
-
-
-static int32_t
-pump_truncate (call_frame_t *frame,
- xlator_t *this,
- loc_t *loc,
- off_t offset, dict_t *xdata)
-{
- afr_private_t *priv = NULL;
- priv = this->private;
- if (!priv->use_afr_in_pump) {
- STACK_WIND (frame,
- default_truncate_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->truncate,
- loc,
- offset, xdata);
- return 0;
- }
-
- afr_truncate (frame, this, loc, offset, xdata);
- return 0;
-}
-
-
-static int32_t
-pump_ftruncate (call_frame_t *frame,
- xlator_t *this,
- fd_t *fd,
- off_t offset, dict_t *xdata)
-{
- afr_private_t *priv = NULL;
- priv = this->private;
- if (!priv->use_afr_in_pump) {
- STACK_WIND (frame,
- default_ftruncate_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->ftruncate,
- fd,
- offset, xdata);
- return 0;
- }
-
- afr_ftruncate (frame, this, fd, offset, xdata);
- return 0;
-}
-
-
-
-
-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)
-{
- afr_private_t *priv = NULL;
- priv = this->private;
- if (!priv->use_afr_in_pump) {
- STACK_WIND (frame, default_mknod_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->mknod,
- loc, mode, rdev, umask, xdata);
- return 0;
- }
- afr_mknod (frame, this, loc, mode, rdev, umask, xdata);
- return 0;
-
-}
-
-
-
-int
-pump_mkdir (call_frame_t *frame, xlator_t *this,
- loc_t *loc, mode_t mode, mode_t umask, dict_t *xdata)
-{
- afr_private_t *priv = NULL;
- priv = this->private;
- if (!priv->use_afr_in_pump) {
- STACK_WIND (frame, default_mkdir_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->mkdir,
- loc, mode, umask, xdata);
- return 0;
- }
- afr_mkdir (frame, this, loc, mode, umask, xdata);
- return 0;
-
-}
-
-
-static int32_t
-pump_unlink (call_frame_t *frame,
- xlator_t *this,
- loc_t *loc, int xflag, dict_t *xdata)
-{
- afr_private_t *priv = NULL;
- priv = this->private;
- if (!priv->use_afr_in_pump) {
- STACK_WIND (frame,
- default_unlink_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->unlink,
- loc, xflag, xdata);
- return 0;
- }
- afr_unlink (frame, this, loc, xflag, xdata);
- return 0;
-
-}
-
-
-static int
-pump_rmdir (call_frame_t *frame, xlator_t *this,
- loc_t *loc, int flags, dict_t *xdata)
-{
- afr_private_t *priv = NULL;
-
- priv = this->private;
-
- if (!priv->use_afr_in_pump) {
- STACK_WIND (frame, default_rmdir_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->rmdir,
- loc, flags, xdata);
- return 0;
- }
-
- afr_rmdir (frame, this, loc, flags, xdata);
- return 0;
-
-}
-
-
-
-int
-pump_symlink (call_frame_t *frame, xlator_t *this,
- const char *linkpath, loc_t *loc, mode_t umask, dict_t *xdata)
-{
- afr_private_t *priv = NULL;
- priv = this->private;
- if (!priv->use_afr_in_pump) {
- STACK_WIND (frame, default_symlink_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->symlink,
- linkpath, loc, umask, xdata);
- return 0;
- }
- afr_symlink (frame, this, linkpath, loc, umask, xdata);
- return 0;
-
-}
-
-
-static int32_t
-pump_rename (call_frame_t *frame,
- xlator_t *this,
- loc_t *oldloc,
- loc_t *newloc, dict_t *xdata)
-{
- afr_private_t *priv = NULL;
- priv = this->private;
- if (!priv->use_afr_in_pump) {
- STACK_WIND (frame,
- default_rename_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->rename,
- oldloc, newloc, xdata);
- return 0;
- }
- afr_rename (frame, this, oldloc, newloc, xdata);
- return 0;
-
-}
-
-
-static int32_t
-pump_link (call_frame_t *frame,
- xlator_t *this,
- loc_t *oldloc,
- loc_t *newloc, dict_t *xdata)
-{
- afr_private_t *priv = NULL;
- priv = this->private;
- if (!priv->use_afr_in_pump) {
- STACK_WIND (frame,
- default_link_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->link,
- oldloc, newloc, xdata);
- return 0;
- }
- afr_link (frame, this, oldloc, newloc, xdata);
- return 0;
-
-}
-
-
-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)
-{
- afr_private_t *priv = NULL;
- priv = this->private;
- if (!priv->use_afr_in_pump) {
- STACK_WIND (frame, default_create_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->create,
- loc, flags, mode, umask, fd, xdata);
- return 0;
- }
- afr_create (frame, this, loc, flags, mode, umask, fd, xdata);
- return 0;
-
-}
-
-
-static int32_t
-pump_open (call_frame_t *frame,
- xlator_t *this,
- loc_t *loc,
- int32_t flags, fd_t *fd, dict_t *xdata)
-{
- afr_private_t *priv = NULL;
- priv = this->private;
- if (!priv->use_afr_in_pump) {
- STACK_WIND (frame,
- default_open_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->open,
- loc, flags, fd, xdata);
- return 0;
- }
- afr_open (frame, this, loc, flags, fd, xdata);
- return 0;
-
-}
-
-
-static int32_t
-pump_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)
-{
- afr_private_t *priv = NULL;
- priv = this->private;
- if (!priv->use_afr_in_pump) {
- STACK_WIND (frame,
- default_writev_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->writev,
- fd,
- vector,
- count,
- off, flags,
- iobref, xdata);
- return 0;
- }
-
- afr_writev (frame, this, fd, vector, count, off, flags, iobref, xdata);
- return 0;
-}
-
-
-static int32_t
-pump_flush (call_frame_t *frame,
- xlator_t *this,
- fd_t *fd, dict_t *xdata)
-{
- afr_private_t *priv = NULL;
- priv = this->private;
- if (!priv->use_afr_in_pump) {
- STACK_WIND (frame,
- default_flush_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->flush,
- fd, xdata);
- return 0;
- }
- afr_flush (frame, this, fd, xdata);
- return 0;
-
-}
-
-
-static int32_t
-pump_fsync (call_frame_t *frame,
- xlator_t *this,
- fd_t *fd,
- int32_t flags, dict_t *xdata)
-{
- afr_private_t *priv = NULL;
- priv = this->private;
- if (!priv->use_afr_in_pump) {
- STACK_WIND (frame,
- default_fsync_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fsync,
- fd,
- flags, xdata);
- return 0;
- }
- afr_fsync (frame, this, fd, flags, xdata);
- return 0;
-
-}
-
-
-static int32_t
-pump_opendir (call_frame_t *frame,
- xlator_t *this,
- loc_t *loc, fd_t *fd, dict_t *xdata)
-{
- afr_private_t *priv = NULL;
- priv = this->private;
- if (!priv->use_afr_in_pump) {
- STACK_WIND (frame,
- default_opendir_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->opendir,
- loc, fd, xdata);
- return 0;
- }
- afr_opendir (frame, this, loc, fd, xdata);
- return 0;
-
-}
-
-
-static int32_t
-pump_fsyncdir (call_frame_t *frame,
- xlator_t *this,
- fd_t *fd,
- int32_t flags, dict_t *xdata)
-{
- afr_private_t *priv = NULL;
- priv = this->private;
- if (!priv->use_afr_in_pump) {
- STACK_WIND (frame,
- default_fsyncdir_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fsyncdir,
- fd,
- flags, xdata);
- return 0;
- }
- afr_fsyncdir (frame, this, fd, flags, xdata);
- return 0;
-
-}
-
-
-static int32_t
-pump_xattrop (call_frame_t *frame,
- xlator_t *this,
- loc_t *loc,
- gf_xattrop_flags_t flags,
- dict_t *dict, dict_t *xdata)
-{
- afr_private_t *priv = NULL;
- priv = this->private;
- if (!priv->use_afr_in_pump) {
- STACK_WIND (frame,
- default_xattrop_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->xattrop,
- loc,
- flags,
- dict, xdata);
- return 0;
- }
- afr_xattrop (frame, this, loc, flags, dict, xdata);
- return 0;
-
-}
-
-static int32_t
-pump_fxattrop (call_frame_t *frame,
- xlator_t *this,
- fd_t *fd,
- gf_xattrop_flags_t flags,
- dict_t *dict, dict_t *xdata)
-{
- afr_private_t *priv = NULL;
- priv = this->private;
- if (!priv->use_afr_in_pump) {
- STACK_WIND (frame,
- default_fxattrop_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fxattrop,
- fd,
- flags,
- dict, xdata);
- return 0;
- }
- afr_fxattrop (frame, this, fd, flags, dict, xdata);
- return 0;
-
-}
-
-
-static int32_t
-pump_removexattr (call_frame_t *frame,
- xlator_t *this,
- loc_t *loc,
- const char *name, dict_t *xdata)
-{
- 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;
- priv = this->private;
- if (!priv->use_afr_in_pump) {
- STACK_WIND (frame,
- default_removexattr_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->removexattr,
- loc,
- name, xdata);
- return 0;
- }
- afr_removexattr (frame, this, loc, name, xdata);
-
- out:
- if (op_errno)
- AFR_STACK_UNWIND (removexattr, frame, -1, op_errno, NULL);
- return 0;
-
-}
-
-
-
-static int32_t
-pump_readdir (call_frame_t *frame,
- xlator_t *this,
- fd_t *fd,
- size_t size,
- off_t off, dict_t *xdata)
-{
- afr_private_t *priv = NULL;
- priv = this->private;
- if (!priv->use_afr_in_pump) {
- STACK_WIND (frame,
- default_readdir_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->readdir,
- fd, size, off, xdata);
- return 0;
- }
- afr_readdir (frame, this, fd, size, off, xdata);
- 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)
-{
- afr_private_t *priv = NULL;
- priv = this->private;
- if (!priv->use_afr_in_pump) {
- STACK_WIND (frame,
- default_readdirp_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->readdirp,
- fd, size, off, dict);
- return 0;
- }
- afr_readdirp (frame, this, fd, size, off, dict);
- return 0;
-
-}
-
-
-
-static int32_t
-pump_releasedir (xlator_t *this,
- fd_t *fd)
-{
- afr_private_t *priv = NULL;
- priv = this->private;
- if (priv->use_afr_in_pump)
- afr_releasedir (this, fd);
- return 0;
-
-}
-
-static int32_t
-pump_release (xlator_t *this,
- fd_t *fd)
-{
- afr_private_t *priv = NULL;
- priv = this->private;
- if (priv->use_afr_in_pump)
- afr_release (this, fd);
- return 0;
-
-}
-
-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)
-{
- afr_private_t *priv = NULL;
- priv = this->private;
- if (!priv->use_afr_in_pump) {
- STACK_WIND (frame,
- default_setattr_cbk,
- FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->setattr,
- loc, stbuf, valid, xdata);
- return 0;
- }
- afr_setattr (frame, this, loc, stbuf, valid, xdata);
- return 0;
-
-}
-
-
-static int32_t
-pump_fsetattr (call_frame_t *frame,
- xlator_t *this,
- fd_t *fd,
- struct iatt *stbuf,
- int32_t valid, dict_t *xdata)
-{
- afr_private_t *priv = NULL;
- priv = this->private;
- if (!priv->use_afr_in_pump) {
- STACK_WIND (frame,
- default_fsetattr_cbk,
- FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->fsetattr,
- fd, stbuf, valid, xdata);
- return 0;
- }
- afr_fsetattr (frame, this, fd, stbuf, valid, xdata);
- return 0;
-
-}
-
-
-/* End of defaults */
-
-
-int32_t
-mem_acct_init (xlator_t *this)
-{
- int ret = -1;
-
- if (!this)
- return ret;
-
- ret = xlator_mem_acct_init (this, gf_afr_mt_end + 1);
-
- if (ret != 0) {
- gf_log(this->name, GF_LOG_ERROR, "Memory accounting init"
- "failed");
- return ret;
- }
-
- return ret;
-}
-
-static int
-is_xlator_pump_sink (xlator_t *child)
-{
- return (child == PUMP_SINK_CHILD(THIS));
-}
-
-static int
-is_xlator_pump_source (xlator_t *child)
-{
- return (child == PUMP_SOURCE_CHILD(THIS));
-}
-
-int32_t
-notify (xlator_t *this, int32_t event,
- void *data, ...)
-{
- int ret = -1;
- xlator_t *child_xl = NULL;
-
- child_xl = (xlator_t *) data;
-
- ret = afr_notify (this, event, data, NULL);
-
- switch (event) {
- case GF_EVENT_CHILD_DOWN:
- if (is_xlator_pump_source (child_xl))
- pump_change_state (this, PUMP_STATE_ABORT);
- break;
-
- case GF_EVENT_CHILD_UP:
- if (is_xlator_pump_sink (child_xl))
- if (is_pump_start_pending (this)) {
- gf_log (this->name, GF_LOG_DEBUG,
- "about to start synctask");
- ret = pump_start_synctask (this);
- if (ret < 0)
- gf_log (this->name, GF_LOG_DEBUG,
- "Could not start pump "
- "synctask");
- else
- pump_remove_start_pending (this);
- }
- }
-
- return ret;
-}
-
-int32_t
-init (xlator_t *this)
-{
- afr_private_t * priv = NULL;
- pump_private_t *pump_priv = NULL;
- int child_count = 0;
- xlator_list_t * trav = NULL;
- int i = 0;
- int ret = -1;
- GF_UNUSED int op_errno = 0;
-
- int source_child = 0;
-
- if (!this->children) {
- gf_log (this->name, GF_LOG_ERROR,
- "pump translator needs a source and sink"
- "subvolumes defined.");
- return -1;
- }
-
- if (!this->parents) {
- gf_log (this->name, GF_LOG_WARNING,
- "Volume is dangling.");
- }
-
- priv = GF_CALLOC (1, sizeof (afr_private_t), gf_afr_mt_afr_private_t);
- if (!priv)
- goto out;
-
- LOCK_INIT (&priv->lock);
-
- 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->metadata_self_heal = 1;
- priv->entry_self_heal = 1;
-
- priv->data_self_heal_window_size = 16;
-
- priv->data_change_log = 1;
- priv->metadata_change_log = 1;
- priv->entry_change_log = 1;
- priv->use_afr_in_pump = 1;
- priv->sh_readdir_size = 65536;
-
- /* Locking options */
-
- /* Lock server count infact does not matter. Locks are held
- on all subvolumes, in this case being the source
- and the sink.
- */
-
- priv->child_up = GF_CALLOC (sizeof (unsigned char), child_count,
- gf_afr_mt_char);
- if (!priv->child_up) {
- gf_log (this->name, GF_LOG_ERROR,
- "Out of memory.");
- op_errno = ENOMEM;
- goto out;
- }
-
- priv->children = GF_CALLOC (sizeof (xlator_t *), child_count,
- gf_afr_mt_xlator_t);
- if (!priv->children) {
- gf_log (this->name, GF_LOG_ERROR,
- "Out of memory.");
- op_errno = ENOMEM;
- goto out;
- }
-
- priv->pending_key = GF_CALLOC (sizeof (*priv->pending_key),
- child_count,
- gf_afr_mt_char);
- if (!priv->pending_key) {
- gf_log (this->name, GF_LOG_ERROR,
- "Out of memory.");
- op_errno = ENOMEM;
- goto out;
- }
-
- trav = this->children;
- i = 0;
- while (i < child_count) {
- priv->children[i] = trav->xlator;
-
- ret = gf_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");
- op_errno = ENOMEM;
- goto out;
- }
-
- trav = trav->next;
- i++;
- }
-
- ret = gf_asprintf (&priv->sh_domain, "%s-self-heal", this->name);
- if (-1 == ret) {
- op_errno = ENOMEM;
- goto out;
- }
-
- 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) {
- gf_log (this->name, GF_LOG_ERROR,
- "Out of memory");
- op_errno = ENOMEM;
- goto out;
- }
-
- LOCK_INIT (&pump_priv->resume_path_lock);
- LOCK_INIT (&pump_priv->pump_state_lock);
-
- pump_priv->resume_path = GF_CALLOC (1, PATH_MAX,
- gf_afr_mt_char);
- if (!pump_priv->resume_path) {
- gf_log (this->name, GF_LOG_ERROR, "Out of memory");
- ret = -1;
- goto out;
- }
-
- pump_priv->env = this->ctx->env;
- if (!pump_priv->env) {
- gf_log (this->name, GF_LOG_ERROR,
- "Could not create new sync-environment");
- ret = -1;
- 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;
- pump_priv = NULL;
-
- this->private = priv;
- priv = NULL;
-
- pump_change_state (this, PUMP_STATE_ABORT);
-
- ret = 0;
-out:
-
- if (pump_priv) {
- GF_FREE (pump_priv->resume_path);
- LOCK_DESTROY (&pump_priv->resume_path_lock);
- LOCK_DESTROY (&pump_priv->pump_state_lock);
- GF_FREE (pump_priv);
- }
-
- if (priv) {
- GF_FREE (priv->child_up);
- GF_FREE (priv->children);
- GF_FREE (priv->pending_key);
- GF_FREE (priv->last_event);
- LOCK_DESTROY (&priv->lock);
- GF_FREE (priv);
- }
-
- return ret;
-}
-
-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;
-
- 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;
-}
-
-
-struct xlator_fops fops = {
- .lookup = pump_lookup,
- .open = pump_open,
- .flush = pump_flush,
- .fsync = pump_fsync,
- .fsyncdir = pump_fsyncdir,
- .xattrop = pump_xattrop,
- .fxattrop = pump_fxattrop,
- .getxattr = pump_getxattr,
-
- /* inode write */
- .writev = pump_writev,
- .truncate = pump_truncate,
- .ftruncate = pump_ftruncate,
- .setxattr = pump_setxattr,
- .setattr = pump_setattr,
- .fsetattr = pump_fsetattr,
- .removexattr = pump_removexattr,
-
- /* dir read */
- .opendir = pump_opendir,
- .readdir = pump_readdir,
- .readdirp = pump_readdirp,
-
- /* dir write */
- .create = pump_create,
- .mknod = pump_mknod,
- .mkdir = pump_mkdir,
- .unlink = pump_unlink,
- .rmdir = pump_rmdir,
- .link = pump_link,
- .symlink = pump_symlink,
- .rename = pump_rename,
-};
-
-struct xlator_dumpops dumpops = {
- .priv = afr_priv_dump,
-};
-
-
-struct xlator_cbks cbks = {
- .release = pump_release,
- .releasedir = pump_releasedir,
- .forget = pump_forget,
-};
-
-struct volume_options options[] = {
- { .key = {NULL} },
-};
diff --git a/xlators/cluster/afr/src/pump.h b/xlators/cluster/afr/src/pump.h
deleted file mode 100644
index 9d0b6db6a5e..00000000000
--- a/xlators/cluster/afr/src/pump.h
+++ /dev/null
@@ -1,81 +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 __PUMP_H__
-#define __PUMP_H__
-
-#include "syncop.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 PUMP_SOURCE_COMPLETE "trusted.glusterfs.pump-source-complete"
-#define PUMP_SINK_COMPLETE "trusted.glusterfs.pump-sink-complete"
-
-#define PUMP_PATH "trusted.glusterfs.pump-path"
-
-#define PUMP_SOURCE_CHILD(xl) (xl->children->xlator)
-#define PUMP_SINK_CHILD(xl) (xl->children->next->xlator)
-
-typedef enum {
- PUMP_STATE_RUNNING, /* Pump is running and migrating files */
- 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 */
- 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 */
- char current_file[PATH_MAX]; /* Current file being pumped */
- uint64_t number_files_pumped; /* Number of files pumped */
- 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
-build_root_loc (inode_t *inode, loc_t *loc);
-int pump_start (call_frame_t *frame, xlator_t *this);
-
-gf_boolean_t
-pump_command_start (xlator_t *this, dict_t *dict);
-
-int
-pump_execute_start (call_frame_t *frame, xlator_t *this);
-
-gf_boolean_t
-pump_command_pause (xlator_t *this, dict_t *dict);
-
-int
-pump_execute_pause (call_frame_t *frame, xlator_t *this);
-
-gf_boolean_t
-pump_command_abort (xlator_t *this, dict_t *dict);
-
-int
-pump_execute_abort (call_frame_t *frame, xlator_t *this);
-
-gf_boolean_t
-pump_command_status (xlator_t *this, dict_t *dict);
-
-int
-pump_execute_status (call_frame_t *frame, xlator_t *this);
-
-int
-pump_command_reply (call_frame_t *frame, xlator_t *this);
-
-#endif /* __PUMP_H__ */
diff --git a/xlators/cluster/dht/src/Makefile.am b/xlators/cluster/dht/src/Makefile.am
index 425ebc75e59..70b89521e17 100644
--- a/xlators/cluster/dht/src/Makefile.am
+++ b/xlators/cluster/dht/src/Makefile.am
@@ -1,37 +1,34 @@
+
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 dht-shared.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
+
+dht_la_SOURCES = $(dht_common_source) dht.c
nufa_la_SOURCES = $(dht_common_source) nufa.c
switch_la_SOURCES = $(dht_common_source) switch.c
-dht_la_LDFLAGS = -module -avoid-version
+dht_la_LDFLAGS = -module -avoidversion
dht_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la
-nufa_la_LDFLAGS = -module -avoid-version
+nufa_la_LDFLAGS = -module -avoidversion
nufa_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la
-switch_la_LDFLAGS = -module -avoid-version
+switch_la_LDFLAGS = -module -avoidversion
switch_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la
-noinst_HEADERS = dht-common.h dht-mem-types.h dht-messages.h dht-helper.h \
- $(top_builddir)/xlators/lib/src/libxlator.h
-
-AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \
- -I$(top_srcdir)/xlators/lib/src
+noinst_HEADERS = dht-common.h dht-common.c
-AM_CFLAGS = -Wall $(GF_CFLAGS)
+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 =
+CLEANFILES =
uninstall-local:
rm -f $(DESTDIR)$(xlatordir)/distribute.so
install-data-hook:
- ln -sf dht.so $(DESTDIR)$(xlatordir)/distribute.so
+ ln -sf dht.so $(DESTDIR)$(xlatordir)/distribute.so \ No newline at end of file
diff --git a/xlators/cluster/dht/src/dht-common.c b/xlators/cluster/dht/src/dht-common.c
index e793c8561c0..82c3d63755b 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>
- 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) 2009-2009 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/>.
*/
@@ -18,93 +27,11 @@
#include "glusterfs.h"
#include "xlator.h"
-#include "libxlator.h"
#include "dht-common.h"
#include "defaults.h"
-#include "byte-order.h"
-#include "glusterfs-acl.h"
#include <sys/time.h>
#include <libgen.h>
-#include <signal.h>
-
-int
-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_t *dict_data = NULL;
-
- 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_msg ("dht", GF_LOG_WARNING, 0,
- DHT_MSG_NO_MEMORY,
- "Memory allocation failed");
- return -1;
- }
- ret = dict_set_bin (dst, key, size, sizeof (int64_t));
- if (ret < 0) {
- gf_log ("dht", GF_LOG_WARNING,
- "dht aggregate dict set failed");
- GF_FREE (size);
- return -1;
- }
- }
-
- ptr = data_to_bin (value);
- if (ptr == NULL) {
- gf_log ("dht", GF_LOG_WARNING, "data to bin failed");
- return -1;
- }
-
- *size = hton64 (ntoh64 (*size) + ntoh64 (*ptr));
-
- } else if (fnmatch (GF_XATTR_STIME_PATTERN, key, FNM_NOESCAPE) == 0) {
- ret = gf_get_min_stime (THIS, dst, key, value);
- if (ret < 0)
- return ret;
- } else {
- /* compare user xattrs only */
- if (!strncmp (key, "user.", strlen ("user."))) {
- ret = dict_lookup (dst, key, &dict_data);
- if (!ret && dict_data && value) {
- ret = is_data_equal (dict_data, value);
- if (!ret)
- gf_msg_debug ("dht", 0,
- "xattr mismatch for %s",
- key);
- }
- }
- ret = dict_set (dst, key, value);
- if (ret)
- gf_msg ("dht", GF_LOG_WARNING, 0,
- DHT_MSG_DICT_SET_FAILED,
- "Failed to set dictionary value: key = %s",
- key);
- }
-
- return 0;
-}
-
-
-void
-dht_aggregate_xattr (dict_t *dst, dict_t *src)
-{
- if ((dst == NULL) || (src == NULL)) {
- goto out;
- }
-
- dict_foreach (src, dht_aggregate, dst);
-out:
- return;
-}
/* TODO:
- use volumename in xattr instead of "dht"
@@ -116,422 +43,104 @@ out:
int
dht_lookup_selfheal_cbk (call_frame_t *frame, void *cookie,
- xlator_t *this,
- int op_ret, int op_errno, dict_t *xdata)
-{
- dht_local_t *local = NULL;
- dht_layout_t *layout = NULL;
- int ret = -1;
-
- GF_VALIDATE_OR_GOTO ("dht", frame, out);
- GF_VALIDATE_OR_GOTO ("dht", this, out);
- GF_VALIDATE_OR_GOTO ("dht", frame->local, out);
-
- local = frame->local;
- ret = op_ret;
-
- FRAME_SU_UNDO (frame, dht_local_t);
-
- if (ret == 0) {
- layout = local->selfheal.layout;
- ret = dht_layout_set (this, local->inode, layout);
- }
-
- if (local->loc.parent) {
- dht_inode_ctx_time_update (local->loc.parent, this,
- &local->postparent, 1);
- }
-
- DHT_STRIP_PHASE1_FLAGS (&local->stbuf);
-
- DHT_STACK_UNWIND (lookup, frame, ret, local->op_errno, local->inode,
- &local->stbuf, local->xattr, &local->postparent);
-
-out:
- return ret;
-}
-
-
-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;
- dht_conf_t *conf = NULL;
-
- local = discover_frame->local;
- layout = local->layout;
- conf = this->private;
-
- 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_msg (this->name, GF_LOG_ERROR, 0,
- DHT_MSG_FILE_TYPE_MISMATCH,
- "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_msg (this->name, GF_LOG_WARNING, 0,
- DHT_MSG_LAYOUT_SET_FAILED,
- "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_msg_debug (this->name, 0,
- "normalizing failed on %s "
- "(overlaps/holes present: %s, "
- "ENOENT errors: %d)", local->loc.path,
- (ret < 0) ? "yes" : "no", (ret > 0) ? ret : 0);
- if ((ret > 0) && (ret == conf->subvolume_cnt)) {
- op_errno = ESTALE;
- goto out;
- }
-
- /* For fixing the directory layout, we need to choose
- * the subvolume on which layout will be set first.
- * Because in nameless lookup, we have gfid only,
- * we are dependent on gfid. Therefore if conf->
- * randomize_by_gfid is set, then only we proceed for
- * healing layout of directory otherwise we don't heal.
- */
-
- if (local->inode && conf->randomize_by_gfid)
- goto selfheal;
- }
-
- if (local->inode)
- 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;
-
-selfheal:
-
- main_frame->local = local;
- discover_frame->local = NULL;
- FRAME_SU_DO (main_frame, dht_local_t);
- uuid_copy (local->loc.gfid, local->gfid);
- ret = dht_selfheal_directory_for_nameless_lookup (main_frame,
- dht_lookup_selfheal_cbk,
- &local->loc, layout);
- 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_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;
- dht_conf_t *conf = 0;
- char gfid_local[GF_UUID_BUF_SIZE] = {0};
- char gfid_node[GF_UUID_BUF_SIZE] = {0};
-
- GF_VALIDATE_OR_GOTO ("dht", frame, out);
- GF_VALIDATE_OR_GOTO ("dht", this, out);
- GF_VALIDATE_OR_GOTO ("dht", frame->local, out);
- GF_VALIDATE_OR_GOTO ("dht", this->private, out);
- GF_VALIDATE_OR_GOTO ("dht", cookie, out);
-
- local = frame->local;
- prev = cookie;
- conf = this->private;
-
- layout = local->layout;
-
-
- /* Check if the gfid is different for file from other node */
- if (!op_ret && uuid_compare (local->gfid, stbuf->ia_gfid)) {
-
- uuid_unparse(stbuf->ia_gfid, gfid_node);
- uuid_unparse(local->gfid, gfid_local);
-
- gf_msg (this->name, GF_LOG_WARNING, 0,
- DHT_MSG_GFID_MISMATCH,
- "%s: gfid different on %s, gfid local = %s"
- "gfid other = %s",
- local->loc.path, prev->this->name,
- gfid_local, gfid_node);
- }
-
-
- 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 (ret)
- gf_msg (this->name, GF_LOG_WARNING, 0,
- DHT_MSG_LAYOUT_MERGE_FAILED,
- "%s: failed to merge layouts for subvol %s",
- local->loc.path, prev->this->name);
-
- if (op_ret == -1) {
- local->op_errno = op_errno;
- gf_msg_debug (this->name, 0,
- "lookup of %s on %s returned error (%s)",
- local->loc.path, prev->this->name,
- strerror (op_errno));
-
- goto unlock;
- }
-
- is_linkfile = check_is_linkfile (inode, stbuf, xattr,
- conf->link_xattr_name);
- 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;
- }
- }
-
- local->op_ret = 0;
-
- if (local->xattr == NULL) {
- local->xattr = dict_ref (xattr);
- } else {
- dht_aggregate_xattr (local->xattr, xattr);
- }
-
- if (local->inode == NULL)
- local->inode = inode_ref (inode);
-
- dht_iatt_merge (this, &local->stbuf, stbuf, prev->this);
- dht_iatt_merge (this, &local->postparent, postparent,
- prev->this);
- }
-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)
+ xlator_t *this,
+ int op_ret, int op_errno)
{
- 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, conf->xattr_name, 4 * 4);
- if (ret)
- gf_msg (this->name, GF_LOG_WARNING, 0,
- DHT_MSG_DICT_SET_FAILED,
- "%s: Failed to set dictionary value:key = %s",
- loc->path, conf->xattr_name);
-
- ret = dict_set_uint32 (local->xattr_req, conf->link_xattr_name, 256);
- if (ret)
- gf_msg (this->name, GF_LOG_WARNING, 0,
- DHT_MSG_DICT_SET_FAILED,
- "%s: Failed to set dictionary value:key = %s",
- loc->path, conf->link_xattr_name);
+ dht_local_t *local = NULL;
+ dht_layout_t *layout = NULL;
+ int ret = 0;
- call_cnt = conf->subvolume_cnt;
- local->call_cnt = call_cnt;
-
- local->layout = dht_layout_new (this, conf->subvolume_cnt);
-
- if (!local->layout) {
- op_errno = ENOMEM;
- goto err;
- }
-
- uuid_copy (local->gfid, loc->gfid);
-
- discover_frame = copy_frame (frame);
- if (!discover_frame) {
- op_errno = ENOMEM;
- goto err;
- }
-
- discover_frame->local = local;
- frame->local = NULL;
- local->main_frame = frame;
-
- 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);
- }
+ local = frame->local;
+ ret = op_ret;
+
+ if (ret == 0) {
+ layout = local->selfheal.layout;
+ ret = dht_layout_set (this, local->inode, layout);
+
+ if (local->st_ino) {
+ local->stbuf.st_ino = local->st_ino;
+ } else {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "could not find hashed subvolume for %s",
+ local->loc.path);
+ }
- return 0;
+ if (local->loc.parent)
+ local->postparent.st_ino = local->loc.parent->ino;
+ }
-err:
- DHT_STACK_UNWIND (lookup, frame, -1, op_errno, NULL, NULL, NULL,
- NULL);
+ DHT_STACK_UNWIND (lookup, frame, ret, local->op_errno, local->inode,
+ &local->stbuf, local->xattr, &local->postparent);
- return 0;
+ return 0;
}
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)
+ inode_t *inode, struct stat *stbuf, dict_t *xattr,
+ struct stat *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;
- char gfid_local[GF_UUID_BUF_SIZE] = {0};
- char gfid_node[GF_UUID_BUF_SIZE] = {0};
-
- GF_VALIDATE_OR_GOTO ("dht", frame, out);
- GF_VALIDATE_OR_GOTO ("dht", this, out);
- GF_VALIDATE_OR_GOTO ("dht", frame->local, out);
- GF_VALIDATE_OR_GOTO ("dht", this->private, out);
- GF_VALIDATE_OR_GOTO ("dht", cookie, out);
+ dht_layout_t *layout = NULL;
+ int ret = 0;
+ int is_dir = 0;
+ 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)) {
-
- uuid_unparse(stbuf->ia_gfid, gfid_node);
- uuid_unparse(local->gfid, gfid_local);
-
- gf_msg (this->name, GF_LOG_WARNING, 0,
- DHT_MSG_GFID_MISMATCH,
- "%s: gfid different on %s."
- " gfid local = %s, gfid subvol = %s",
- local->loc.path, prev->this->name,
- gfid_local, gfid_node);
- }
+ layout = local->layout;
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);
+ local->stbuf->st_mode
- if (op_ret == -1) {
- local->op_errno = op_errno;
- gf_msg_debug (this->name, 0,
- "lookup of %s on %s returned error (%s)",
- local->loc.path, prev->this->name,
- strerror (op_errno));
+ else mkdir/chmod/chown and fix
+ */
+ ret = dht_layout_merge (this, layout, prev->this,
+ op_ret, op_errno, xattr);
- goto unlock;
- }
+ if (op_ret == -1) {
+ 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,
+ strerror (op_errno));
- is_dir = check_is_dir (inode, stbuf, xattr);
- if (!is_dir) {
-
- gf_msg_debug (this->name, 0,
- "lookup of %s on %s returned non"
- "dir 0%o"
- "calling lookup_everywhere",
- local->loc.path, prev->this->name,
- stbuf->ia_type);
+ goto unlock;
+ }
+ is_dir = check_is_dir (inode, stbuf, xattr);
+ 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->st_mode);
local->need_selfheal = 1;
- goto unlock;
+ goto unlock;
}
- local->op_ret = 0;
- if (local->xattr == NULL) {
- local->xattr = dict_ref (xattr);
- } else {
- dht_aggregate_xattr (local->xattr, xattr);
- }
+ local->op_ret = 0;
+ if (local->xattr == NULL)
+ local->xattr = dict_ref (xattr);
+ if (local->inode == NULL)
+ local->inode = inode_ref (inode);
- if (local->inode == NULL)
- local->inode = inode_ref (inode);
-
- dht_iatt_merge (this, &local->stbuf, stbuf, prev->this);
- dht_iatt_merge (this, &local->postparent, postparent,
+ dht_stat_merge (this, &local->stbuf, stbuf, prev->this);
+ dht_stat_merge (this, &local->postparent, postparent,
prev->this);
+
+ if (prev->this == local->hashed_subvol) {
+ local->st_ino = local->stbuf.st_ino;
+ local->st_dev = local->stbuf.st_dev;
+ }
+
}
unlock:
UNLOCK (&frame->lock);
@@ -546,1172 +155,460 @@ unlock:
return 0;
}
- if (local->op_ret == 0) {
- ret = dht_layout_normalize (this, &local->loc, layout);
+ if (local->op_ret == 0) {
+ ret = dht_layout_normalize (this, &local->loc, layout);
- if (ret != 0) {
- gf_msg_debug (this->name, 0,
- "fixing assignment on %s",
- local->loc.path);
- goto selfheal;
- }
-
- dht_layout_set (this, local->inode, layout);
- }
+ if (ret != 0) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "fixing assignment on %s",
+ local->loc.path);
+ goto selfheal;
+ }
+
+ dht_layout_set (this, local->inode, layout);
+
+ if (local->st_ino) {
+ local->stbuf.st_ino = local->st_ino;
+ local->stbuf.st_dev = local->st_dev;
+ } else {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "could not find hashed subvol for %s",
+ local->loc.path);
+ }
- if (local->loc.parent) {
- dht_inode_ctx_time_update (local->loc.parent, this,
- &local->postparent, 1);
- }
+ if (local->loc.parent)
+ local->postparent.st_ino =
+ local->loc.parent->ino;
+ }
- DHT_STRIP_PHASE1_FLAGS (&local->stbuf);
- DHT_STACK_UNWIND (lookup, frame, local->op_ret, local->op_errno,
- local->inode, &local->stbuf, local->xattr,
+ DHT_STACK_UNWIND (lookup, frame, local->op_ret, local->op_errno,
+ local->inode, &local->stbuf, local->xattr,
&local->postparent);
}
- return 0;
+ return 0;
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);
-out:
- return ret;
+ ret = dht_selfheal_directory (frame, dht_lookup_selfheal_cbk,
+ &local->loc, layout);
+
+ return 0;
}
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)
+ inode_t *inode, struct stat *stbuf, dict_t *xattr,
+ struct stat *postparent)
{
dht_local_t *local = NULL;
int this_call_cnt = 0;
call_frame_t *prev = NULL;
- dht_layout_t *layout = NULL;
- dht_conf_t *conf = NULL;
- int ret = -1;
- int is_dir = 0;
- int is_linkfile = 0;
- call_frame_t *copy = NULL;
- dht_local_t *copy_local = NULL;
- char gfid[GF_UUID_BUF_SIZE] = {0};
-
- GF_VALIDATE_OR_GOTO ("dht", frame, err);
- GF_VALIDATE_OR_GOTO ("dht", this, err);
- GF_VALIDATE_OR_GOTO ("dht", frame->local, err);
- GF_VALIDATE_OR_GOTO ("dht", cookie, err);
+ dht_layout_t *layout = NULL;
+ dht_conf_t *conf = NULL;
+ int ret = -1;
+ int is_dir = 0;
+ int is_linkfile = 0;
local = frame->local;
prev = cookie;
- conf = this->private;
- if (!conf)
- goto out;
-
- uuid_unparse (local->loc.gfid, gfid);
+ conf = this->private;
LOCK (&frame->lock);
{
+ if (op_ret == -1) {
+ local->op_errno = op_errno;
- gf_msg_debug (this->name, 0,
- "revalidate lookup of %s "
- "returned with op_ret %d and op_errno %d",
- local->loc.path, op_ret, op_errno);
-
- if (op_ret == -1) {
- local->op_errno = op_errno;
-
- if ((op_errno != ENOTCONN)
+ if ((op_errno != ENOTCONN)
&& (op_errno != ENOENT)
&& (op_errno != ESTALE)) {
- gf_log (this->name, GF_LOG_INFO,
- "Revalidate: subvolume %s for %s "
- "(gfid = %s) returned -1 (%s)",
- prev->this->name, local->loc.path,
- gfid, strerror (op_errno));
+ gf_log (this->name, GF_LOG_DEBUG,
+ "subvolume %s returned -1 (%s)",
+ prev->this->name, 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;
- }
-
- /* 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)) {
-
- gf_msg_debug (this->name, 0,
- "found ENOENT for %s. "
- "Setting "
- "need_lookup_everywhere"
- " flag to 1",
- local->loc.path);
-
- local->need_lookup_everywhere = 1;
- }
+ local->layout_mismatch = 1;
}
- goto unlock;
- }
-
- if (stbuf->ia_type != local->inode->ia_type) {
- gf_msg (this->name, GF_LOG_WARNING, 0,
- DHT_MSG_FILE_TYPE_MISMATCH,
- "mismatching filetypes 0%o v/s 0%o for %s,"
- " gfid = %s",
- (stbuf->ia_type), (local->inode->ia_type),
- local->loc.path, gfid);
- local->op_ret = -1;
- local->op_errno = EINVAL;
-
- goto unlock;
- }
-
- layout = local->layout;
-
- is_dir = check_is_dir (inode, stbuf, xattr);
- is_linkfile = check_is_linkfile (inode, stbuf, xattr,
- conf->link_xattr_name);
-
- if (is_linkfile) {
- gf_log (this->name, GF_LOG_INFO,
- "Revalidate: linkfile found %s, (gfid = %s)",
- local->loc.path, gfid);
- local->return_estale = 1;
+ goto unlock;
+ }
- goto unlock;
- }
+ if (S_IFMT & (stbuf->st_mode ^ local->inode->st_mode)) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "mismatching filetypes 0%o v/s 0%o for %s",
+ (stbuf->st_mode & S_IFMT),
+ (local->inode->st_mode & S_IFMT),
+ local->loc.path);
- if (is_dir) {
- ret = dht_dir_has_layout (xattr, conf->xattr_name);
- if (ret >= 0) {
- if (is_greater_time(local->stbuf.ia_ctime,
- local->stbuf.ia_ctime_nsec,
- stbuf->ia_ctime,
- stbuf->ia_ctime_nsec)) {
- local->prebuf.ia_gid = stbuf->ia_gid;
- local->prebuf.ia_uid = stbuf->ia_uid;
- }
- }
- if (local->stbuf.ia_type != IA_INVAL)
- {
- if ((local->stbuf.ia_gid != stbuf->ia_gid) ||
- (local->stbuf.ia_uid != stbuf->ia_uid)) {
- local->need_selfheal = 1;
- }
- }
- ret = dht_layout_dir_mismatch (this, layout,
- prev->this, &local->loc,
- xattr);
- if (ret != 0) {
- gf_msg (this->name, GF_LOG_INFO, 0,
- DHT_MSG_LAYOUT_MISMATCH,
- "Mismatching layouts for %s, gfid = %s",
- local->loc.path, gfid);
+ local->op_ret = -1;
+ local->op_errno = EINVAL;
- local->layout_mismatch = 1;
+ goto unlock;
+ }
- goto unlock;
- }
- }
+ layout = local->layout;
+
+ is_dir = check_is_dir (inode, stbuf, xattr);
+ is_linkfile = check_is_linkfile (inode, stbuf, xattr);
+
+ if (is_linkfile) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "linkfile found in revalidate for %s",
+ local->loc.path);
+ local->layout_mismatch = 1;
+
+ goto unlock;
+ }
- dht_iatt_merge (this, &local->stbuf, stbuf, prev->this);
- dht_iatt_merge (this, &local->postparent, postparent,
+ if (is_dir) {
+ ret = dht_layout_dir_mismatch (this, layout,
+ prev->this, &local->loc,
+ xattr);
+ if (ret != 0) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "mismatching layouts for %s",
+ local->loc.path);
+
+ local->layout_mismatch = 1;
+
+ goto unlock;
+ }
+ }
+
+ dht_stat_merge (this, &local->stbuf, stbuf, prev->this);
+ dht_stat_merge (this, &local->postparent, postparent,
prev->this);
+
+ local->op_ret = 0;
+ local->stbuf.st_ino = local->st_ino;
+ local->stbuf.st_dev = local->loc.inode->generation;
- local->op_ret = 0;
+ if (local->loc.parent)
+ local->postparent.st_ino = local->loc.parent->ino;
- if (!local->xattr) {
- local->xattr = dict_ref (xattr);
- } else if (is_dir) {
- dht_aggregate_xattr (local->xattr, xattr);
- }
- }
+ if (!local->xattr)
+ local->xattr = dict_ref (xattr);
+ }
unlock:
- UNLOCK (&frame->lock);
-out:
+ UNLOCK (&frame->lock);
+
this_call_cnt = dht_frame_return (frame);
if (is_last_call (this_call_cnt)) {
- if (!IA_ISDIR (local->stbuf.ia_type)
- && (local->hashed_subvol != local->cached_subvol)
- && (local->stbuf.ia_nlink == 1)
- && (conf && conf->unhashed_sticky_bit)) {
- local->stbuf.ia_prot.sticky = 1;
- }
- if (local->need_selfheal) {
- local->need_selfheal = 0;
- uuid_copy (local->gfid, local->stbuf.ia_gfid);
- local->stbuf.ia_gid = local->prebuf.ia_gid;
- local->stbuf.ia_uid = local->prebuf.ia_uid;
- copy = create_frame (this, this->ctx->pool);
- if (copy) {
- copy_local = dht_local_init (copy, &local->loc,
- NULL, 0);
- if (!copy_local)
- goto cont;
- copy_local->stbuf = local->stbuf;
- copy->local = copy_local;
- FRAME_SU_DO (copy, dht_local_t);
- ret = synctask_new (this->ctx->env,
- dht_dir_attr_heal,
- dht_dir_attr_heal_done,
- copy, copy);
- }
- }
-cont:
- 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) {
- local->op_ret = -1;
- local->op_errno = ESTALE;
- }
-
- if (local->loc.parent) {
- dht_inode_ctx_time_update (local->loc.parent, this,
- &local->postparent, 1);
- }
+ if (!S_ISDIR (local->stbuf.st_mode)
+ && (local->hashed_subvol != local->cached_subvol)
+ && (local->stbuf.st_nlink == 1)
+ && (conf->unhashed_sticky_bit)) {
+ local->stbuf.st_mode |= S_ISVTX;
+ }
- DHT_STRIP_PHASE1_FLAGS (&local->stbuf);
- DHT_STACK_UNWIND (lookup, frame, local->op_ret, local->op_errno,
- local->inode, &local->stbuf, local->xattr,
+ if (local->layout_mismatch) {
+ local->op_ret = -1;
+ local->op_errno = ESTALE;
+ }
+
+ DHT_STACK_UNWIND (lookup, frame, local->op_ret, local->op_errno,
+ local->inode, &local->stbuf, local->xattr,
&local->postparent);
- }
+ }
-err:
- return ret;
+ return 0;
}
int
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)
+ xlator_t *this,
+ int32_t op_ret, int32_t op_errno,
+ inode_t *inode, struct stat *stbuf,
+ struct stat *preparent, struct stat *postparent)
{
- dht_local_t *local = NULL;
- xlator_t *cached_subvol = NULL;
- dht_conf_t *conf = NULL;
+ dht_local_t *local = NULL;
+ xlator_t *cached_subvol = NULL;
+ dht_conf_t *conf = NULL;
int ret = -1;
- char gfid[GF_UUID_BUF_SIZE] = {0};
-
- GF_VALIDATE_OR_GOTO ("dht", frame, out);
- GF_VALIDATE_OR_GOTO ("dht", this, out);
- GF_VALIDATE_OR_GOTO ("dht", frame->local, out);
- GF_VALIDATE_OR_GOTO ("dht", this->private, out);
- GF_VALIDATE_OR_GOTO ("dht", cookie, out);
- local = frame->local;
- cached_subvol = local->cached_subvol;
- conf = this->private;
-
- uuid_unparse(local->loc.gfid, gfid);
+ local = frame->local;
+ cached_subvol = local->cached_subvol;
+ conf = this->private;
- ret = dht_layout_preset (this, local->cached_subvol, local->loc.inode);
+ ret = dht_layout_preset (this, local->cached_subvol, inode);
if (ret < 0) {
- gf_msg_debug (this->name, 0,
- "Failed to set layout for subvolume %s, "
- "(gfid = %s)",
- cached_subvol ? cached_subvol->name : "<nil>",
- gfid);
+ gf_log (this->name, GF_LOG_DEBUG,
+ "failed to set layout for subvolume %s",
+ cached_subvol ? cached_subvol->name : "<nil>");
local->op_ret = -1;
local->op_errno = EINVAL;
goto unwind;
}
- local->op_ret = 0;
- if ((local->stbuf.ia_nlink == 1)
- && (conf && conf->unhashed_sticky_bit)) {
- local->stbuf.ia_prot.sticky = 1;
- }
+ local->op_ret = 0;
+ if ((local->stbuf.st_nlink == 1)
+ && (conf->unhashed_sticky_bit)) {
+ local->stbuf.st_mode |= S_ISVTX;
+ }
- if (local->loc.parent) {
- dht_inode_ctx_time_update (local->loc.parent, this,
- postparent, 1);
- }
+ if (local->loc.parent)
+ local->postparent.st_ino = local->loc.parent->ino;
unwind:
- gf_msg_debug (this->name, 0,
- "creation of linkto on hashed subvol:%s, "
- "returned with op_ret %d and op_errno %d: %s",
- local->hashed_subvol->name,
- op_ret, op_errno, uuid_utoa (local->loc.gfid));
-
- if (local->linked == _gf_true)
- dht_linkfile_attr_heal (frame, this);
-
-
- DHT_STRIP_PHASE1_FLAGS (&local->stbuf);
- DHT_STACK_UNWIND (lookup, frame, local->op_ret, local->op_errno,
- local->inode, &local->stbuf, local->xattr,
+ DHT_STACK_UNWIND (lookup, frame, local->op_ret, local->op_errno,
+ local->inode, &local->stbuf, local->xattr,
&local->postparent);
-out:
- 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;
- dht_local_t *local = NULL;
- const char *path = NULL;
-
- local = (dht_local_t*)frame->local;
- path = local->loc.path;
-
- gf_log (this->name, GF_LOG_INFO, "lookup_unlink returned with "
- "op_ret -> %d and op-errno -> %d for %s", op_ret, op_errno,
- ((path == NULL)? "null" : path ));
-
- 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_unlink_of_false_linkto_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;
- dht_local_t *local = NULL;
- const char *path = NULL;
-
- local = (dht_local_t*)frame->local;
- path = local->loc.path;
-
- gf_log (this->name, GF_LOG_INFO, "lookup_unlink returned with "
- "op_ret -> %d and op-errno -> %d for %s", op_ret, op_errno,
- ((path == NULL)? "null" : path ));
-
- this_call_cnt = dht_frame_return (frame);
- if (is_last_call (this_call_cnt)) {
-
- if (op_ret == 0) {
- dht_lookup_everywhere_done (frame, this);
- } else {
- /*When dht_lookup_everywhere is performed, one cached
- *and one hashed file was found and hashed file does
- *not point to the above mentioned cached node. So it
- *was considered as stale and an unlink was performed.
- *But unlink fails. So may be rebalance is in progress.
- *now ideally we have two data-files. One obtained during
- *lookup_everywhere and one where unlink-failed. So
- *at this point in time we cannot decide which one to
- *choose because there are chances of first cached
- *file is truncated after rebalance and if it is choosen
- *as cached node, application will fail. So return EIO.*/
-
- if (op_errno == EBUSY) {
-
- gf_log (this->name, GF_LOG_ERROR,
- "Could not unlink the linkto file as "
- "either fd is open and/or linkto xattr "
- "is set for %s",
- ((path == NULL)? "null":path));
-
- }
- DHT_STACK_UNWIND (lookup, frame, -1, EIO, NULL, NULL,
- NULL, NULL);
-
- }
- }
-
- return 0;
-}
-
-int
-dht_lookup_unlink_stale_linkto_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;
- const char *path = NULL;
-
- /* NOTE:
- * If stale file unlink fails either there is an open-fd or is not an
- * dht-linkto-file then posix_unlink returns EBUSY, which is overwritten
- * to ENOENT
- */
-
- local = frame->local;
-
- if (local && local->loc.path)
- path = local->loc.path;
-
- gf_log (this->name, GF_LOG_INFO, "Returned with op_ret %d and "
- "op_errno %d for %s", op_ret, op_errno,
- ((path==NULL)?"null":path));
-
- DHT_STACK_UNWIND (lookup, frame, -1, ENOENT, NULL, NULL, NULL,
- NULL);
-
- return 0;
-}
-
-int
-dht_fill_dict_to_avoid_unlink_of_migrating_file (dict_t *dict) {
-
- int ret = 0;
-
- ret = dict_set_int32 (dict, DHT_SKIP_NON_LINKTO_UNLINK, 1);
-
- if (ret)
- goto err;
-
- ret = dict_set_int32 (dict, DHT_SKIP_OPEN_FD_UNLINK, 1);
-
- if (ret)
- goto err;
-
-
- return 0;
-
-err:
- return -1;
-
+ return 0;
}
-/* Rebalance is performed from cached_node to hashed_node. Initial cached_node
- * contains a non-linkto file. After migration it is converted to linkto and
- * then unlinked. And at hashed_subvolume, first a linkto file is present,
- * then after migration it is converted to a non-linkto file.
- *
- * Lets assume a file is present on cached subvolume and a new brick is added
- * and new brick is the new_hashed subvolume. So fresh lookup on newly added
- * hashed subvolume will fail and dht_lookup_everywhere gets called. If just
- * before sending the dht_lookup_everywhere request rebalance is in progress,
- *
- * from cached subvolume it may see: Nonlinkto or linkto or No file
- * from hashed subvolume it may see: No file or linkto file or non-linkto file
- *
- * So this boils down to 9 cases:
- * at cached_subvol at hashed_subvol
- * ---------------- -----------------
- *
- *a) No file No file
- * [request reached after [Request reached before
- * migration] Migration]
- *
- *b) No file Linkto File
- *
- *c) No file Non-Linkto File
- *
- *d) Linkto No-File
- *
- *e) Linkto Linkto
- *
- *f) Linkto Non-Linkto
- *
- *g) NonLinkto No-File
- *
- *h) NonLinkto Linkto
- *
- *i) NonLinkto NonLinkto
- *
- * dht_lookup_everywhere_done takes decision based on any of the above case
- */
-
-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;
- char gfid[GF_UUID_BUF_SIZE] = {0};
- gf_boolean_t found_non_linkto_on_hashed = _gf_false;
-
- local = frame->local;
- hashed_subvol = local->hashed_subvol;
- cached_subvol = local->cached_subvol;
-
- uuid_unparse (local->loc.gfid, gfid);
-
- if (local->file_count && local->dir_count) {
- gf_msg (this->name, GF_LOG_ERROR, 0,
- DHT_MSG_FILE_TYPE_MISMATCH,
- "path %s (gfid = %s)exists as a file on one "
- "subvolume and directory on another. "
- "Please fix it manually",
- local->loc.path, gfid);
- 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;
- }
-
- gf_msg_debug (this->name, 0, "STATUS: hashed_subvol %s "
- "cached_subvol %s",
- (hashed_subvol == NULL)?"null":hashed_subvol->name,
- (cached_subvol == NULL)?"null":cached_subvol->name);
-
- if (!cached_subvol) {
-
- if (local->skip_unlink.handle_valid_link && hashed_subvol) {
-
- /*Purpose of "DHT_SKIP_NON_LINKTO_UNLINK":
- * If this lookup is performed by rebalance and this
- * rebalance process detected hashed file and by
- * the time it sends the lookup request to cached node,
- * file got migrated and now at intial hashed_node,
- * final migrated file is present. With current logic,
- * because this process fails to find the cached_node,
- * it will unlink the file at initial hashed_node.
- *
- * So we avoid this by setting key, and checking at the
- * posix_unlink that unlink the file only if file is a
- * linkto file and not a migrated_file.
- */
-
-
- ret = dht_fill_dict_to_avoid_unlink_of_migrating_file
- (local->xattr_req);
-
- if (ret) {
- /* If for some reason, setting key in the dict
- * fails, return with ENOENT, as with respect to
- * this process, it detected only a stale link
- * file.
- *
- * Next lookup will delete it.
- *
- * Performing deletion of stale link file when
- * setting key in dict fails, may cause the data
- * loss becase of the above mentioned race.
- */
-
-
- DHT_STACK_UNWIND (lookup, frame, -1, ENOENT,
- NULL, NULL, NULL, NULL);
- } else {
- local->skip_unlink.handle_valid_link = _gf_false;
-
- gf_msg_debug (this->name, 0,
- "No Cached was found and "
- "unlink on hashed was skipped"
- " so performing now: %s",
- local->loc.path);
-
- STACK_WIND (frame,
- dht_lookup_unlink_stale_linkto_cbk,
- hashed_subvol,
- hashed_subvol->fops->unlink,
- &local->loc, 0, local->xattr_req);
- }
-
- } else {
-
- gf_msg_debug (this->name, 0,
- "There was no cached file and "
- "unlink on hashed is not skipped %s",
- local->loc.path);
-
- DHT_STACK_UNWIND (lookup, frame, -1, ENOENT, NULL, NULL,
- NULL, NULL);
- }
- return 0;
- }
-
- /* At the time of dht_lookup, no file was found on hashed and that is
- * why dht_lookup_everywhere is called, but by the time
- * dht_lookup_everywhere
- * reached to server, file might have already migrated. In that case we
- * will find a migrated file at the hashed_node. In this case store the
- * layout in context and return successfully.
- */
-
- if (hashed_subvol || local->need_lookup_everywhere) {
-
- if (local->need_lookup_everywhere) {
-
- found_non_linkto_on_hashed = _gf_true;
-
- } else if ((local->file_count == 1) &&
- (hashed_subvol == cached_subvol)) {
-
- gf_msg_debug (this->name, 0,
- "found cached file on hashed subvolume "
- "so store in context and return for %s",
- local->loc.path);
-
- found_non_linkto_on_hashed = _gf_true;
- }
-
- if (found_non_linkto_on_hashed)
- goto preset_layout;
-
- }
-
-
- if (hashed_subvol) {
- if (local->skip_unlink.handle_valid_link == _gf_true) {
- if (cached_subvol == local->skip_unlink.hash_links_to) {
-
- if (uuid_compare (local->skip_unlink.cached_gfid,
- local->skip_unlink.hashed_gfid)){
-
- /*GFID different, return error*/
- DHT_STACK_UNWIND (lookup, frame, -1,
- ESTALE, NULL, NULL,
- NULL, NULL);
-
- return 0;
- }
-
- ret = dht_layout_preset (this, cached_subvol,
- local->loc.inode);
- if (ret) {
- gf_log (this->name, GF_LOG_INFO,
- "Could not set pre-set layout "
- "for subvolume %s",
- cached_subvol->name);
- }
-
- local->op_ret = (ret == 0) ? ret : -1;
- local->op_errno = (ret == 0) ? ret : EINVAL;
-
- /* Presence of local->cached_subvol validates
- * that lookup from cached node is successful
- */
-
- if (!local->op_ret && local->loc.parent) {
- dht_inode_ctx_time_update
- (local->loc.parent, this,
- &local->postparent, 1);
- }
-
- gf_msg_debug (this->name, 0,
- "Skipped unlinking linkto file "
- "on the hashed subvolume. "
- "Returning success as it is a "
- "valid linkto file. Path:%s"
- ,local->loc.path);
-
- goto unwind_hashed_and_cached;
- } else {
-
- local->skip_unlink.handle_valid_link = _gf_false;
-
- gf_msg_debug (this->name, 0,
- "Linkto file found on hashed "
- "subvol "
- "and data file found on cached "
- "subvolume. But linkto points to "
- "different cached subvolume (%s) "
- "path %s",
- (local->skip_unlink.hash_links_to ?
- local->skip_unlink.hash_links_to->name :
- " <nil>"), local->loc.path);
-
- if (local->skip_unlink.opend_fd_count == 0) {
-
-
- ret = dht_fill_dict_to_avoid_unlink_of_migrating_file
- (local->xattr_req);
-
-
- if (ret) {
- DHT_STACK_UNWIND (lookup, frame, -1,
- EIO, NULL, NULL,
- NULL, NULL);
- } else {
- local->call_cnt = 1;
- STACK_WIND (frame,
- dht_lookup_unlink_of_false_linkto_cbk,
- hashed_subvol,
- hashed_subvol->fops->unlink,
- &local->loc, 0,
- local->xattr_req);
- }
-
- return 0;
-
- }
- }
-
- }
- }
-
-
-preset_layout:
-
- if (found_non_linkto_on_hashed) {
-
- 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,"
- " gfid = %s",
- local->loc.path, (cached_subvol ?
- cached_subvol->name :
- "<nil>"), gfid);
- }
-
- 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, "
- "gfid = %s",
- local->loc.path, (cached_subvol ?
- cached_subvol->name :
- "<nil>"), gfid);
- }
-
- if (local->loc.parent) {
- dht_inode_ctx_time_update (local->loc.parent, this,
- &local->postparent, 1);
- }
-
- 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_msg_debug (this->name, 0,
- "Cannot create linkfile for %s on %s: "
- "hashed subvolume cannot be found, gfid = %s.",
- local->loc.path, cached_subvol->name, gfid);
-
- 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"
- ", gfid = %s",
- cached_subvol ? cached_subvol->name :
- "<nil>", gfid);
- local->op_ret = -1;
- local->op_errno = EINVAL;
- }
-
- if (local->loc.parent) {
- dht_inode_ctx_time_update (local->loc.parent, this,
- &local->postparent, 1);
- }
-
- 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_msg_debug (this->name, 0,
- "Linking file %s on %s to %s (hash)(gfid = %s)",
- local->loc.path, cached_subvol->name,
- hashed_subvol->name, gfid);
-
- ret = dht_linkfile_create (frame,
- dht_lookup_linkfile_create_cbk, this,
- cached_subvol, hashed_subvol, &local->loc);
-
- return ret;
-unwind_hashed_and_cached:
- DHT_STRIP_PHASE1_FLAGS (&local->stbuf);
- DHT_STACK_UNWIND (lookup, frame, local->op_ret, local->op_errno,
- local->loc.inode, &local->stbuf, local->xattr,
- &local->postparent);
- 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)
+ int32_t op_ret, int32_t op_errno,
+ inode_t *inode, struct stat *buf, dict_t *xattr,
+ struct stat *postparent)
{
+ dht_conf_t *conf = NULL;
dht_local_t *local = NULL;
int this_call_cnt = 0;
call_frame_t *prev = NULL;
- int is_linkfile = 0;
- int is_dir = 0;
- xlator_t *subvol = NULL;
- loc_t *loc = NULL;
- xlator_t *link_subvol = NULL;
- int ret = -1;
- int32_t fd_count = 0;
- dht_conf_t *conf = NULL;
- char gfid[GF_UUID_BUF_SIZE] = {0};
- dict_t *dict_req = {0};
-
- GF_VALIDATE_OR_GOTO ("dht", frame, out);
- GF_VALIDATE_OR_GOTO ("dht", this, out);
- GF_VALIDATE_OR_GOTO ("dht", frame->local, out);
- GF_VALIDATE_OR_GOTO ("dht", cookie, out);
- GF_VALIDATE_OR_GOTO ("dht", this->private, out);
-
- local = frame->local;
- loc = &local->loc;
- conf = this->private;
-
- prev = cookie;
- subvol = prev->this;
-
- gf_msg_debug (this->name, 0,
- "returned with op_ret %d and op_errno %d (%s) "
- "from subvol %s", op_ret, op_errno, loc->path,
- subvol->name);
-
- LOCK (&frame->lock);
- {
- if (op_ret == -1) {
- if (op_errno != ENOENT)
- local->op_errno = op_errno;
- goto unlock;
- }
-
- if (uuid_is_null (local->gfid))
- uuid_copy (local->gfid, buf->ia_gfid);
-
- uuid_unparse(local->gfid, gfid);
-
- if (uuid_compare (local->gfid, buf->ia_gfid)) {
- gf_msg (this->name, GF_LOG_WARNING, 0,
- DHT_MSG_GFID_MISMATCH,
- "%s: gfid differs on subvolume %s,"
- " gfid local = %s, gfid node = %s",
- loc->path, prev->this->name, gfid,
- uuid_utoa(buf->ia_gfid));
- }
-
- is_linkfile = check_is_linkfile (inode, buf, xattr,
- conf->link_xattr_name);
+ int is_linkfile = 0;
+ int is_dir = 0;
+ 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;
- if (is_linkfile) {
+ conf = this->private;
- gf_msg_debug (this->name, 0,
- "Found linktofile on %s for %s",
- subvol->name, loc->path);
+ local = frame->local;
+ loc = &local->loc;
- }
- is_dir = check_is_dir (inode, buf, xattr);
+ prev = cookie;
+ subvol = prev->this;
- if (is_linkfile) {
- link_subvol = dht_linkfile_subvol (this, inode, buf,
- xattr);
- gf_msg_debug (this->name, 0,
- "found on %s linkfile %s (-> %s)",
- subvol->name, loc->path,
- link_subvol ? link_subvol->name : "''");
- goto unlock;
- }
+ LOCK (&frame->lock);
+ {
+ if (op_ret == -1) {
+ if (op_errno != ENOENT)
+ local->op_errno = op_errno;
+ goto unlock;
+ }
- /* non linkfile GFID takes precedence */
- uuid_copy (local->gfid, buf->ia_gfid);
+ is_linkfile = check_is_linkfile (inode, buf, xattr);
+ is_dir = check_is_dir (inode, buf, xattr);
+
+ if (is_linkfile) {
+ link_subvol = dht_linkfile_subvol (this, inode, buf,
+ xattr);
+ gf_log (this->name, GF_LOG_DEBUG,
+ "found on %s linkfile %s (-> %s)",
+ subvol->name, loc->path,
+ link_subvol ? link_subvol->name : "''");
+ goto unlock;
+ }
if (is_dir) {
local->dir_count++;
- gf_msg_debug (this->name, 0,
- "found on %s directory %s",
- subvol->name, loc->path);
+ gf_log (this->name, GF_LOG_DEBUG,
+ "found on %s directory %s",
+ subvol->name, loc->path);
} else {
local->file_count++;
- gf_msg_debug (this->name, 0,
- "found cached file on %s for %s",
- subvol->name, loc->path);
-
if (!local->cached_subvol) {
/* found one file */
- dht_iatt_merge (this, &local->stbuf, buf,
+ dht_stat_merge (this, &local->stbuf, buf,
subvol);
local->xattr = dict_ref (xattr);
local->cached_subvol = subvol;
-
- gf_msg_debug (this->name, 0,
- "storing cached on %s file"
- " %s", subvol->name, loc->path);
-
- dht_iatt_merge (this, &local->postparent,
+ gf_log (this->name, GF_LOG_DEBUG,
+ "found on %s file %s",
+ subvol->name, loc->path);
+
+ dht_stat_merge (this, &local->postparent,
postparent, subvol);
-
- uuid_copy (local->skip_unlink.cached_gfid,
- buf->ia_gfid);
} else {
- /* This is where we need 'rename' both entries logic */
- gf_msg (this->name, GF_LOG_WARNING, 0,
- DHT_MSG_FILE_ON_MULT_SUBVOL,
+ gf_log (this->name, GF_LOG_DEBUG,
"multiple subvolumes (%s and %s) have "
- "file %s (preferably rename the file "
- "in the backend,and do a fresh lookup)",
- local->cached_subvol->name,
+ "file %s", local->cached_subvol->name,
subvol->name, local->loc.path);
}
}
- }
+ }
unlock:
- UNLOCK (&frame->lock);
+ UNLOCK (&frame->lock);
- if (is_linkfile) {
- ret = dict_get_int32 (xattr, GLUSTERFS_OPEN_FD_COUNT, &fd_count);
-
- /* Any linkto file found on the non-hashed subvolume should
- * be unlinked (performed in the "else if" block below)
- *
- * But if a linkto file is found on hashed subvolume, it may be
- * pointing to vaild cached node. So unlinking of linkto
- * file on hashed subvolume is skipped and inside
- * dht_lookup_everywhere_done, checks are performed. If this
- * linkto file is found as stale linkto file, it is deleted
- * otherwise unlink is skipped.
- */
-
- if (local->hashed_subvol && local->hashed_subvol == subvol) {
-
- local->skip_unlink.handle_valid_link = _gf_true;
- local->skip_unlink.opend_fd_count = fd_count;
- local->skip_unlink.hash_links_to = link_subvol;
- uuid_copy (local->skip_unlink.hashed_gfid,
- buf->ia_gfid);
-
- gf_msg_debug (this->name, 0, "Found"
- " one linkto file on hashed subvol %s "
- "for %s: Skipping unlinking till "
- "everywhere_done", subvol->name,
- loc->path);
-
- } else if (!ret && (fd_count == 0)) {
- dict_req = dict_new ();
-
- ret = dht_fill_dict_to_avoid_unlink_of_migrating_file
- (dict_req);
-
- if (ret) {
-
- /* Skip unlinking for dict_failure
- *File is found as a linkto file on non-hashed,
- *subvolume. In the current implementation,
- *finding a linkto-file on non-hashed does not
- *always implies that it is stale. So deletion
- *of file should be done only when both fd is
- *closed and linkto-xattr is set. In case of
- *dict_set failure, avoid skipping of file.
- *NOTE: dht_frame_return should get called for
- * this block.
- */
-
- dict_unref (dict_req);
+ if (is_linkfile) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "deleting stale linkfile %s on %s",
+ loc->path, subvol->name);
+ dht_linkfile_unlink (frame, this, subvol, loc);
+ }
- } else {
- gf_log (this->name, GF_LOG_INFO,
- "attempting deletion of stale linkfile "
- "%s on %s", loc->path, subvol->name);
+ this_call_cnt = dht_frame_return (frame);
+ if (is_last_call (this_call_cnt)) {
+ 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;
+ }
- STACK_WIND (frame, dht_lookup_unlink_cbk,
- subvol, subvol->fops->unlink, loc,
- 0, dict_req);
+ if (!cached_subvol) {
+ DHT_STACK_UNWIND (lookup, frame, -1, ENOENT, NULL, NULL, NULL,
+ NULL);
+ return 0;
+ }
- dict_unref (dict_req);
+ if (!hashed_subvol) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "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;
- return 0;
+ ret = dht_layout_preset (frame->this, cached_subvol,
+ local->inode);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "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.st_ino =
+ local->loc.parent->ino;
+
+ DHT_STACK_UNWIND (lookup, frame, local->op_ret,
+ local->op_errno, local->inode,
+ &local->stbuf, local->xattr,
+ &local->postparent);
+ return 0;
}
- }
- this_call_cnt = dht_frame_return (frame);
- if (is_last_call (this_call_cnt)) {
- dht_lookup_everywhere_done (frame, this);
- }
+ gf_log (this->name, GF_LOG_DEBUG,
+ "linking file %s existing on %s to %s (hash)",
+ loc->path, cached_subvol->name,
+ hashed_subvol->name);
+
+ dht_linkfile_create (frame,
+ dht_lookup_linkfile_create_cbk,
+ cached_subvol, hashed_subvol, loc);
+ }
-out:
- return ret;
+ return 0;
}
int
dht_lookup_everywhere (call_frame_t *frame, xlator_t *this, loc_t *loc)
{
- dht_conf_t *conf = NULL;
- dht_local_t *local = NULL;
- int i = 0;
- int call_cnt = 0;
-
- 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", this->private, out);
- GF_VALIDATE_OR_GOTO ("dht", loc, out);
-
- conf = this->private;
- local = frame->local;
+ dht_conf_t *conf = NULL;
+ dht_local_t *local = NULL;
+ int i = 0;
+ int call_cnt = 0;
- call_cnt = conf->subvolume_cnt;
- local->call_cnt = call_cnt;
+ conf = this->private;
+ local = frame->local;
- if (!local->inode)
- local->inode = inode_ref (loc->inode);
+ call_cnt = conf->subvolume_cnt;
+ local->call_cnt = call_cnt;
- gf_msg_debug (this->name, 0,
- "winding lookup call to %d subvols", call_cnt);
+ if (!local->inode)
+ local->inode = inode_ref (loc->inode);
- for (i = 0; i < call_cnt; i++) {
- STACK_WIND (frame, dht_lookup_everywhere_cbk,
- conf->subvolumes[i],
- conf->subvolumes[i]->fops->lookup,
- loc, local->xattr_req);
- }
+ for (i = 0; i < call_cnt; i++) {
+ STACK_WIND (frame, dht_lookup_everywhere_cbk,
+ conf->subvolumes[i],
+ conf->subvolumes[i]->fops->lookup,
+ loc, local->xattr_req);
+ }
- return 0;
-out:
- DHT_STACK_UNWIND (lookup, frame, -1, EINVAL, NULL, NULL, NULL, NULL);
-err:
- return -1;
+ return 0;
}
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)
+ inode_t *inode, struct stat *stbuf, dict_t *xattr,
+ struct stat *postparent)
{
call_frame_t *prev = NULL;
- dht_local_t *local = NULL;
- xlator_t *subvol = NULL;
- loc_t *loc = NULL;
- dht_conf_t *conf = NULL;
+ dht_local_t *local = NULL;
+ xlator_t *subvol = NULL;
+ loc_t *loc = NULL;
+ dht_conf_t *conf = NULL;
int ret = 0;
- char gfid[GF_UUID_BUF_SIZE] = {0};
-
- GF_VALIDATE_OR_GOTO ("dht", frame, out);
- GF_VALIDATE_OR_GOTO ("dht", this, unwind);
- GF_VALIDATE_OR_GOTO ("dht", frame->local, unwind);
- GF_VALIDATE_OR_GOTO ("dht", this->private, unwind);
- GF_VALIDATE_OR_GOTO ("dht", cookie, unwind);
prev = cookie;
- subvol = prev->this;
- conf = this->private;
- local = frame->local;
- loc = &local->loc;
-
- uuid_unparse(loc->gfid, gfid);
+ subvol = prev->this;
+ conf = this->private;
+ local = frame->local;
+ loc = &local->loc;
if (op_ret == -1) {
- gf_log (this->name, GF_LOG_INFO,
- "Lookup of %s on %s (following linkfile) failed (%s)"
- ",gfid = %s", local->loc.path, subvol->name,
- strerror (op_errno), gfid);
-
- /* If cached subvol returned ENOTCONN, do not do
- lookup_everywhere. We need to make sure linkfile does not get
- removed, which can take away the namespace, and subvol is
- anyways down. */
-
- if (op_errno != ENOTCONN)
- goto err;
- else
- goto unwind;
- }
-
- if (check_is_dir (inode, stbuf, xattr)) {
- gf_log (this->name, GF_LOG_INFO,
- "Lookup of %s on %s (following linkfile) reached dir,"
- " gfid = %s", local->loc.path, subvol->name, gfid);
+ gf_log (this->name, GF_LOG_DEBUG,
+ "lookup of %s on %s (following linkfile) failed (%s)",
+ local->loc.path, subvol->name, strerror (op_errno));
goto err;
- }
+ }
- if (check_is_linkfile (inode, stbuf, xattr, conf->link_xattr_name)) {
- gf_log (this->name, GF_LOG_INFO,
- "lookup of %s on %s (following linkfile) reached link,"
- "gfid = %s", local->loc.path, subvol->name, gfid);
+ if (check_is_dir (inode, stbuf, xattr)) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "lookup of %s on %s (following linkfile) reached dir",
+ local->loc.path, subvol->name);
goto err;
}
- if (uuid_compare (local->gfid, stbuf->ia_gfid)) {
- gf_msg (this->name, GF_LOG_WARNING, 0,
- DHT_MSG_GFID_MISMATCH,
- "%s: gfid different on data file on %s,"
- " gfid local = %s, gfid node = %s ",
- local->loc.path, subvol->name, gfid,
- uuid_utoa(stbuf->ia_gfid));
+ if (check_is_linkfile (inode, stbuf, xattr)) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "lookup of %s on %s (following linkfile) reached link",
+ local->loc.path, subvol->name);
goto err;
}
- if ((stbuf->ia_nlink == 1)
- && (conf && conf->unhashed_sticky_bit)) {
- stbuf->ia_prot.sticky = 1;
- }
-
- ret = dht_layout_preset (this, prev->this, inode);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_INFO,
- "Failed to set layout for subvolume %s,"
- "gfid = %s", prev->this->name, gfid);
- op_ret = -1;
- op_errno = EINVAL;
- }
-
- if (local->loc.parent) {
- dht_inode_ctx_time_update (local->loc.parent, this,
- postparent, 1);
- }
+ if ((stbuf->st_nlink == 1)
+ && (conf->unhashed_sticky_bit)) {
+ stbuf->st_mode |= S_ISVTX;
+ }
+ dht_itransform (this, prev->this, stbuf->st_ino, &stbuf->st_ino);
+ if (local->loc.parent)
+ postparent->st_ino = local->loc.parent->ino;
+
+ ret = dht_layout_preset (this, prev->this, inode);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "failed to set layout for subvolume %s",
+ prev->this->name);
+ op_ret = -1;
+ op_errno = EINVAL;
+ goto out;
+ }
-unwind:
- DHT_STRIP_PHASE1_FLAGS (stbuf);
+out:
DHT_STACK_UNWIND (lookup, frame, op_ret, op_errno, inode, stbuf, xattr,
postparent);
@@ -1719,7 +616,7 @@ unwind:
err:
dht_lookup_everywhere (frame, this, loc);
-out:
+
return 0;
}
@@ -1731,40 +628,21 @@ 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);
- GF_VALIDATE_OR_GOTO ("dht", frame->local, unwind);
- GF_VALIDATE_OR_GOTO ("dht", this->private, unwind);
- GF_VALIDATE_OR_GOTO ("dht", loc, unwind);
conf = this->private;
local = frame->local;
call_cnt = conf->subvolume_cnt;
local->call_cnt = call_cnt;
-
+
local->layout = dht_layout_new (this, conf->subvolume_cnt);
if (!local->layout) {
- goto unwind;
- }
-
- if (local->xattr != NULL) {
- dict_unref (local->xattr);
- 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_msg (this->name, GF_LOG_WARNING, 0,
- DHT_MSG_DICT_SET_FAILED,
- "%s: Failed to set dictionary value:"
- " key = gfid-req", local->loc.path);
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory");
+ DHT_STACK_UNWIND (lookup, frame, -1, ENOMEM, NULL, NULL, NULL, NULL);
+ return 0;
}
-
+
for (i = 0; i < call_cnt; i++) {
STACK_WIND (frame, dht_lookup_dir_cbk,
conf->subvolumes[i],
@@ -1772,19 +650,14 @@ dht_lookup_directory (call_frame_t *frame, xlator_t *this, loc_t *loc)
&local->loc, local->xattr_req);
}
return 0;
-unwind:
- DHT_STACK_UNWIND (lookup, frame, -1, ENOMEM, NULL, NULL, NULL, NULL);
-out:
- return 0;
-
}
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)
+ inode_t *inode, struct stat *stbuf, dict_t *xattr,
+ struct stat *postparent)
{
char is_linkfile = 0;
char is_dir = 0;
@@ -1794,168 +667,102 @@ dht_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
loc_t *loc = NULL;
call_frame_t *prev = NULL;
int ret = 0;
+ uint64_t tmp_layout = 0;
dht_layout_t *parent_layout = 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);
- GF_VALIDATE_OR_GOTO ("dht", this->private, out);
-
conf = this->private;
prev = cookie;
local = frame->local;
loc = &local->loc;
- /* This is required for handling stale linkfile deletion,
- * or any more call which happens from this 'loc'.
- */
- if (!op_ret && uuid_is_null (local->gfid))
- memcpy (local->gfid, stbuf->ia_gfid, 16);
-
- gf_msg_debug (this->name, 0,
- "fresh_lookup returned for %s with op_ret %d and "
- "op_errno %d", loc->path, op_ret, op_errno);
-
- if (ENTRY_MISSING (op_ret, op_errno)) {
- gf_msg_debug (this->name, 0, "Entry %s missing on subvol"
- " %s", loc->path, prev->this->name);
+ if (ENTRY_MISSING (op_ret, op_errno)) {
if (conf->search_unhashed == GF_DHT_LOOKUP_UNHASHED_ON) {
- local->op_errno = ENOENT;
- dht_lookup_everywhere (frame, this, loc);
- return 0;
- }
+ local->op_errno = ENOENT;
+ dht_lookup_everywhere (frame, this, loc);
+ return 0;
+ }
if ((conf->search_unhashed == GF_DHT_LOOKUP_UNHASHED_AUTO) &&
(loc->parent)) {
- ret = dht_inode_ctx_layout_get (loc->parent, this,
- &parent_layout);
- if (ret || !parent_layout)
- goto out;
+ ret = inode_ctx_get (loc->parent, this, &tmp_layout);
+ parent_layout = (dht_layout_t *)(long)tmp_layout;
if (parent_layout->search_unhashed) {
local->op_errno = ENOENT;
dht_lookup_everywhere (frame, this, loc);
return 0;
}
}
- }
+ }
- if (op_ret == 0) {
- is_dir = check_is_dir (inode, stbuf, xattr);
- if (is_dir) {
- local->inode = inode_ref (inode);
- local->xattr = dict_ref (xattr);
- }
- }
+ if (op_ret == 0) {
+ is_dir = check_is_dir (inode, stbuf, xattr);
+ if (is_dir) {
+ local->inode = inode_ref (inode);
+ local->xattr = dict_ref (xattr);
+ }
+ }
- if (is_dir || (op_ret == -1 && op_errno == ENOTCONN)) {
+ if (is_dir || (op_ret == -1 && op_errno == ENOTCONN)) {
dht_lookup_directory (frame, this, &local->loc);
return 0;
- }
-
- if (op_ret == -1) {
- gf_msg_debug (this->name, 0, "Lookup of %s for subvolume"
- " %s failed with error %s", loc->path,
- prev->this->name, strerror (op_errno));
+ }
+
+ if (op_ret == -1)
goto out;
- }
- is_linkfile = check_is_linkfile (inode, stbuf, xattr,
- conf->link_xattr_name);
+ is_linkfile = check_is_linkfile (inode, stbuf, xattr);
+ is_dir = check_is_dir (inode, stbuf, xattr);
- if (!is_linkfile) {
+ if (!is_dir && !is_linkfile) {
/* non-directory and not a linkfile */
- ret = dht_layout_preset (this, prev->this, inode);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_INFO,
- "could not set pre-set layout for subvolume %s",
- prev->this->name);
- op_ret = -1;
- op_errno = EINVAL;
- goto out;
- }
- goto out;
- }
+ dht_itransform (this, prev->this, stbuf->st_ino,
+ &stbuf->st_ino);
+ if (loc->parent)
+ postparent->st_ino = loc->parent->ino;
+
+ ret = dht_layout_preset (this, prev->this, inode);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "could not set pre-set layout for subvolume %s",
+ prev->this->name);
+ op_ret = -1;
+ op_errno = EINVAL;
+ goto out;
+ }
+ goto out;
+ }
- subvol = dht_linkfile_subvol (this, inode, stbuf, xattr);
- if (!subvol) {
+ if (is_linkfile) {
+ subvol = dht_linkfile_subvol (this, inode, stbuf, xattr);
- gf_log (this->name, GF_LOG_INFO, "linkfile not having link "
- "subvol for %s", loc->path);
+ if (!subvol) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "linkfile not having link subvolume. path=%s",
+ loc->path);
+ dht_lookup_everywhere (frame, this, loc);
+ return 0;
+ }
- gf_msg_debug (this->name, 0,
- "linkfile not having link subvolume. path=%s",
- loc->path);
- dht_lookup_everywhere (frame, this, loc);
- return 0;
+ STACK_WIND (frame, dht_lookup_linkfile_cbk,
+ subvol, subvol->fops->lookup,
+ &local->loc, local->xattr_req);
}
- gf_msg_debug (this->name, 0,
- "Calling lookup on linkto target %s for path %s",
- subvol->name, loc->path);
-
- STACK_WIND (frame, dht_lookup_linkfile_cbk,
- subvol, subvol->fops->lookup,
- &local->loc, local->xattr_req);
-
return 0;
out:
- /*
- * FIXME: postparent->ia_size and postparent->st_blocks do not have
- * correct values. since, postparent corresponds to a directory these
+ /*
+ * FIXME: postparent->st_size and postparent->st_blocks do not have
+ * correct values. since, postparent corresponds to a directory these
* two members should have values equal to sum of corresponding values
- * from each of the subvolume. See dht_iatt_merge for reference.
- */
-
- if (!op_ret && local->loc.parent) {
- dht_inode_ctx_time_update (local->loc.parent, this,
- postparent, 1);
- }
-
- DHT_STRIP_PHASE1_FLAGS (stbuf);
+ * from each of the subvolume. See dht_stat_merge for reference.
+ */
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_msg (THIS->name, GF_LOG_WARNING, 0,
- DHT_MSG_DICT_SET_FAILED,
- "Failed to set dictionary value: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_msg (THIS->name, GF_LOG_WARNING, 0,
- DHT_MSG_DICT_SET_FAILED,
- "Failed to set dictionary value:key = %s",
- POSIX_ACL_DEFAULT_XATTR);
- }
-
- return;
-}
int
dht_lookup (call_frame_t *frame, xlator_t *this,
@@ -1963,225 +770,131 @@ 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;
+ dht_conf_t *conf = NULL;
int ret = -1;
int op_errno = -1;
- dht_layout_t *layout = NULL;
- int i = 0;
- int call_cnt = 0;
- loc_t new_loc = {0,};
+ 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);
- conf = this->private;
- if (!conf)
- goto err;
-
- local = dht_local_init (frame, loc, NULL, GF_FOP_LOOKUP);
- if (!local) {
- op_errno = ENOMEM;
- goto err;
- }
+ conf = this->private;
- 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 (ret == -1) {
- op_errno = errno;
- gf_msg_debug (this->name, 0,
- "copying location failed for path=%s",
- loc->path);
- goto err;
- }
- }
+ local = dht_local_init (frame);
+ if (!local) {
+ op_errno = ENOMEM;
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory");
+ goto err;
+ }
- if (xattr_req) {
- local->xattr_req = dict_ref (xattr_req);
- } else {
- local->xattr_req = dict_new ();
+ 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 {
+ 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;
- }
+ hashed_subvol = dht_subvol_get_hashed (this, loc);
+ cached_subvol = dht_subvol_get_cached (this, loc->inode);
- if (!hashed_subvol)
- hashed_subvol = dht_subvol_get_hashed (this, loc);
- local->hashed_subvol = hashed_subvol;
+ 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_msg_debug (this->name, 0,
- "Revalidate lookup without cache."
- " path=%s", loc->path);
+ gf_log (this->name, GF_LOG_DEBUG,
+ "revalidate without cache. path=%s",
+ loc->path);
op_errno = EINVAL;
goto err;
}
- if (layout->gen && (layout->gen < conf->gen)) {
- gf_msg_trace (this->name, 0,
- "incomplete layout failure for path=%s",
- loc->path);
+ if (layout->gen && (layout->gen < conf->gen)) {
+ gf_log (this->name, GF_LOG_TRACE,
+ "incomplete layout failure for path=%s",
+ loc->path);
dht_layout_unref (this, local->layout);
local->layout = NULL;
- local->cached_subvol = NULL;
-
- gf_msg_debug(this->name, 0,
- "Called revalidate lookup for %s, "
- "but layout->gen (%d) is less than "
- "conf->gen (%d), calling fresh_lookup",
- loc->path, layout->gen, conf->gen);
-
- goto do_fresh_lookup;
- }
-
- local->inode = inode_ref (loc->inode);
-
- ret = dict_set_uint32 (local->xattr_req,
- conf->xattr_name, 4 * 4);
- if (ret) {
- gf_msg (this->name, GF_LOG_WARNING, ENOMEM,
- DHT_MSG_DICT_SET_FAILED,
- "Failed to set dictionary value:key = %s for "
- "path %s", conf->xattr_name, loc->path);
- goto err;
- }
- /* need it in case file is not found on cached file
- * on revalidate path and we may encounter linkto files on
- * with dht_lookup_everywhere*/
- ret = dict_set_uint32 (local->xattr_req,
- conf->link_xattr_name, 256);
- if (ret < 0) {
- gf_msg (this->name, GF_LOG_WARNING, ENOMEM,
- DHT_MSG_DICT_SET_FAILED,
- "Failed to set dictionary value:key = %s for "
- "path %s", conf->link_xattr_name, loc->path);
- goto err;
- }
- 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);
- if (ret) {
- gf_msg (this->name, GF_LOG_WARNING, ENOMEM,
- DHT_MSG_DICT_SET_FAILED,
- "Failed to set dictionary value:key = %s for "
- "path %s", GLUSTERFS_OPEN_FD_COUNT, loc->path);
- goto err;
- }
- /* need it for dir self-heal */
- dht_check_and_set_acl_xattr_req (loc->inode, local->xattr_req);
+ goto do_fresh_lookup;
+ }
- for (i = 0; i < call_cnt; i++) {
+ local->inode = inode_ref (loc->inode);
+ local->st_ino = loc->inode->ino;
+
+ 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.
+ */
+ ret = dict_set_uint32 (local->xattr_req,
+ "trusted.glusterfs.dht", 4 * 4);
+
+ for (i = 0; i < layout->cnt; i++) {
subvol = layout->list[i].xlator;
-
- gf_msg_debug (this->name, 0, "calling "
- "revalidate lookup for %s at %s",
- loc->path, subvol->name);
-
+
STACK_WIND (frame, dht_revalidate_cbk,
subvol, subvol->fops->lookup,
- &local->loc, local->xattr_req);
+ loc, local->xattr_req);
+ if (!--call_cnt)
+ break;
}
} else {
do_fresh_lookup:
- /* TODO: remove the hard-coding */
- ret = dict_set_uint32 (local->xattr_req,
- conf->xattr_name, 4 * 4);
- if (ret) {
- gf_msg (this->name, GF_LOG_WARNING, ENOMEM,
- DHT_MSG_DICT_SET_FAILED,
- "Failed to set dictionary value:key = %s for "
- "path %s", conf->xattr_name, loc->path);
- goto err;
- }
+ /* TODO: remove the hard-coding */
+ ret = dict_set_uint32 (local->xattr_req,
+ "trusted.glusterfs.dht", 4 * 4);
- ret = dict_set_uint32 (local->xattr_req,
- conf->link_xattr_name, 256);
- if (ret) {
- gf_msg (this->name, GF_LOG_WARNING, ENOMEM,
- DHT_MSG_DICT_SET_FAILED,
- "Failed to set dictionary value:key = %s for "
- "path %s", conf->link_xattr_name, loc->path);
- goto err;
- }
- /* need it for self-healing linkfiles which is
- 'in-migration' state */
- ret = dict_set_uint32 (local->xattr_req,
- GLUSTERFS_OPEN_FD_COUNT, 4);
- if (ret) {
- gf_msg (this->name, GF_LOG_WARNING, ENOMEM,
- DHT_MSG_DICT_SET_FAILED,
- "Failed to set dictionary value:key = %s for "
- "path %s", GLUSTERFS_OPEN_FD_COUNT, loc->path);
- goto err;
- }
- /* need it for dir self-heal */
- dht_check_and_set_acl_xattr_req (loc->inode, local->xattr_req);
+ ret = dict_set_uint32 (local->xattr_req,
+ "trusted.glusterfs.dht.linkto", 256);
if (!hashed_subvol) {
-
- gf_msg_debug (this->name, 0,
- "no subvolume in layout for path=%s, "
- "checking on all the subvols to see if "
- "it is a directory", loc->path);
-
- call_cnt = conf->subvolume_cnt;
- local->call_cnt = call_cnt;
-
- local->layout = dht_layout_new (this,
+ gf_log (this->name, GF_LOG_DEBUG,
+ "no subvolume in layout for path=%s, "
+ "checking on all the subvols to see if "
+ "it is a directory", loc->path);
+ call_cnt = conf->subvolume_cnt;
+ local->call_cnt = call_cnt;
+
+ local->layout = dht_layout_new (this,
conf->subvolume_cnt);
- if (!local->layout) {
- op_errno = ENOMEM;
- goto err;
- }
-
- gf_msg_debug (this->name, 0,
- "Found null hashed subvol. Calling lookup"
- " on all nodes.");
-
- for (i = 0; i < call_cnt; i++) {
- STACK_WIND (frame, dht_lookup_dir_cbk,
- conf->subvolumes[i],
- conf->subvolumes[i]->fops->lookup,
- &local->loc, local->xattr_req);
- }
- return 0;
+ if (!local->layout) {
+ op_errno = ENOMEM;
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory");
+ goto err;
+ }
+
+ for (i = 0; i < call_cnt; i++) {
+ STACK_WIND (frame, dht_lookup_dir_cbk,
+ conf->subvolumes[i],
+ conf->subvolumes[i]->fops->lookup,
+ &local->loc, local->xattr_req);
+ }
+ return 0;
}
- gf_msg_debug (this->name, 0, "Calling fresh lookup for %s on"
- " %s", loc->path, hashed_subvol->name);
-
STACK_WIND (frame, dht_lookup_cbk,
hashed_subvol, hashed_subvol->fops->lookup,
loc, local->xattr_req);
@@ -2190,1691 +903,1199 @@ dht_lookup (call_frame_t *frame, xlator_t *this,
return 0;
err:
- op_errno = (op_errno == -1) ? errno : op_errno;
- DHT_STACK_UNWIND (lookup, frame, -1, op_errno, NULL, NULL, NULL,
- NULL);
+ op_errno = (op_errno == -1) ? errno : op_errno;
+ DHT_STACK_UNWIND (lookup, frame, -1, op_errno, NULL, NULL, NULL, NULL);
return 0;
}
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)
+dht_truncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int op_ret, int op_errno, struct stat *prebuf,
+ struct stat *postbuf)
{
- dht_local_t *local = NULL;
- call_frame_t *prev = NULL;
-
- local = frame->local;
- prev = cookie;
+ dht_local_t *local = NULL;
+ int this_call_cnt = 0;
+ call_frame_t *prev = NULL;
- LOCK (&frame->lock);
- {
- if (op_ret == -1) {
- local->op_ret = -1;
- local->op_errno = op_errno;
- gf_msg_debug (this->name, 0,
- "Unlink: subvolume %s returned -1 (%s)",
- prev->this->name, strerror (op_errno));
- goto unlock;
- }
- local->op_ret = 0;
+ 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;
+ }
- local->postparent = *postparent;
- local->preparent = *preparent;
+ dht_stat_merge (this, &local->prebuf, prebuf, prev->this);
+ dht_stat_merge (this, &local->stbuf, postbuf, prev->this);
- if (local->loc.parent) {
- dht_inode_ctx_time_update (local->loc.parent, this,
- &local->preparent, 0);
- dht_inode_ctx_time_update (local->loc.parent, this,
- &local->postparent, 1);
+ if (local->inode) {
+ local->stbuf.st_ino = local->inode->ino;
+ local->prebuf.st_ino = local->inode->ino;
}
- }
+
+ local->op_ret = 0;
+ }
unlock:
- UNLOCK (&frame->lock);
+ UNLOCK (&frame->lock);
- DHT_STACK_UNWIND (unlink, frame, local->op_ret, local->op_errno,
- &local->preparent, &local->postparent, NULL);
+ 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);
return 0;
}
+
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)
+dht_attr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int op_ret, int op_errno, struct stat *stbuf)
{
- dht_local_t *local = NULL;
- call_frame_t *prev = NULL;
+ dht_local_t *local = NULL;
+ int this_call_cnt = 0;
+ call_frame_t *prev = NULL;
- xlator_t *cached_subvol = NULL;
- local = frame->local;
- prev = cookie;
-
- LOCK (&frame->lock);
- {
- if ((op_ret == -1) && !((op_errno == ENOENT) ||
- (op_errno == ENOTCONN))) {
- local->op_errno = op_errno;
- gf_msg_debug (this->name, 0,
- "Unlink link: subvolume %s"
- " returned -1 (%s)",
- prev->this->name, strerror (op_errno));
- goto unlock;
- }
+ 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;
+ }
- local->op_ret = 0;
- }
+ dht_stat_merge (this, &local->stbuf, stbuf, prev->this);
+
+ if (local->inode)
+ local->stbuf.st_ino = local->inode->ino;
+ local->op_ret = 0;
+ }
unlock:
- UNLOCK (&frame->lock);
-
- if (local->op_ret == -1)
- goto err;
-
- cached_subvol = dht_subvol_get_cached (this, local->loc.inode);
- if (!cached_subvol) {
- gf_msg_debug (this->name, 0,
- "no cached subvolume for path=%s",
- local->loc.path);
- local->op_errno = EINVAL;
- goto err;
- }
-
- STACK_WIND (frame, dht_unlink_cbk,
- cached_subvol, cached_subvol->fops->unlink,
- &local->loc, local->flags, NULL);
+ UNLOCK (&frame->lock);
- return 0;
+ 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:
- DHT_STACK_UNWIND (unlink, frame, -1, local->op_errno,
- NULL, NULL, NULL);
return 0;
}
+
int
-dht_err_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int op_ret, int op_errno, dict_t *xdata)
+dht_stat (call_frame_t *frame, xlator_t *this,
+ loc_t *loc)
{
- dht_local_t *local = NULL;
- int this_call_cnt = 0;
- call_frame_t *prev = NULL;
+ xlator_t *subvol = NULL;
+ int op_errno = -1;
+ dht_local_t *local = NULL;
+ dht_layout_t *layout = NULL;
+ int i = 0;
- local = frame->local;
- prev = cookie;
- LOCK (&frame->lock);
- {
- if (op_ret == -1) {
- local->op_errno = op_errno;
- gf_msg_debug (this->name, 0,
- "subvolume %s returned -1 (%s)",
- prev->this->name, strerror (op_errno));
- goto unlock;
- }
+ 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->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);
- }
+ local = dht_local_init (frame);
+ if (!local) {
+ op_errno = ENOMEM;
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory");
+ goto err;
+ }
- return 0;
-}
+ 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;
+ }
-static void
-fill_layout_info (dht_layout_t *layout, char *buf)
-{
- int i = 0;
- char tmp_buf[128] = {0,};
-
- for (i = 0; i < layout->cnt; i++) {
- snprintf (tmp_buf, 128, "(%s %u %u)",
- layout->list[i].xlator->name,
- layout->list[i].start,
- layout->list[i].stop);
- if (i)
- strcat (buf, " ");
- strcat (buf, tmp_buf);
- }
-}
+ local->inode = inode_ref (loc->inode);
+ local->call_cnt = layout->cnt;
-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);
-}
+ for (i = 0; i < layout->cnt; i++) {
+ subvol = layout->list[i].xlator;
-int
-dht_vgetxattr_alloc_and_fill (dht_local_t *local, dict_t *xattr, xlator_t *this,
- int op_errno)
-{
- int ret = -1;
- char *value = NULL;
- int32_t plen = 0;
+ STACK_WIND (frame, dht_attr_cbk,
+ subvol, subvol->fops->stat,
+ loc);
+ }
- ret = dict_get_str (xattr, local->xsel, &value);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Subvolume %s returned -1 (%s)", this->name,
- strerror (op_errno));
- local->op_ret = -1;
- local->op_errno = op_errno;
- goto out;
- }
+ return 0;
- local->alloc_len += strlen(value);
+err:
+ op_errno = (op_errno == -1) ? errno : op_errno;
+ DHT_STACK_UNWIND (stat, frame, -1, op_errno, NULL);
- if (!local->xattr_val) {
- local->alloc_len += (strlen (DHT_PATHINFO_HEADER) + 10);
- local->xattr_val = GF_CALLOC (local->alloc_len, sizeof (char),
- gf_common_mt_char);
- if (!local->xattr_val) {
- ret = -1;
- goto out;
- }
- }
+ return 0;
+}
- if (local->xattr_val) {
- plen = strlen (local->xattr_val);
- if (plen) {
- /* extra byte(s) for \0 to be safe */
- local->alloc_len += (plen + 2);
- local->xattr_val = GF_REALLOC (local->xattr_val,
- local->alloc_len);
- if (!local->xattr_val) {
- ret = -1;
- goto out;
- }
- }
- (void) strcat (local->xattr_val, value);
- (void) strcat (local->xattr_val, " ");
- local->op_ret = 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;
- ret = 0;
- out:
- return ret;
-}
+ VALIDATE_OR_GOTO (frame, err);
+ VALIDATE_OR_GOTO (this, err);
+ VALIDATE_OR_GOTO (fd, err);
-int
-dht_vgetxattr_fill_and_set (dht_local_t *local, dict_t **dict, xlator_t *this,
- gf_boolean_t flag)
-{
- int ret = -1;
- char *xattr_buf = NULL;
- char layout_buf[8192] = {0,};
+ local = dht_local_init (frame);
+ if (!local) {
+ op_errno = ENOMEM;
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory");
+ goto err;
+ }
- if (flag)
- fill_layout_info (local->layout, layout_buf);
+ 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;
+ }
- *dict = dict_new ();
- if (!*dict)
- goto out;
+ local->inode = inode_ref (fd->inode);
+ local->call_cnt = layout->cnt;;
- local->xattr_val[strlen (local->xattr_val) - 1] = '\0';
-
- /* we would need max this many bytes to create xattr string
- * extra 40 bytes is just an estimated amount of additional
- * space required as we include translator name and some
- * spaces, brackets etc. when forming the pathinfo string.
- *
- * For node-uuid we just don't have all the pretty formatting,
- * but since this is a generic routine for pathinfo & node-uuid
- * we dont have conditional space allocation and try to be
- * generic
- */
- local->alloc_len += (2 * strlen (this->name))
- + strlen (layout_buf)
- + 40;
- xattr_buf = GF_CALLOC (local->alloc_len, sizeof (char),
- gf_common_mt_char);
- if (!xattr_buf)
- goto out;
+ for (i = 0; i < layout->cnt; i++) {
+ subvol = layout->list[i].xlator;
+ STACK_WIND (frame, dht_attr_cbk,
+ subvol, subvol->fops->fstat,
+ fd);
+ }
- if (XATTR_IS_PATHINFO (local->xsel)) {
- (void) dht_fill_pathinfo_xattr (this, local, xattr_buf,
- local->alloc_len, flag,
- layout_buf);
- } else if (XATTR_IS_NODE_UUID (local->xsel)) {
- (void) snprintf (xattr_buf, local->alloc_len, "%s",
- local->xattr_val);
- } else {
- gf_log (this->name, GF_LOG_WARNING,
- "Unknown local->xsel (%s)", local->xsel);
- GF_FREE (xattr_buf);
- goto out;
- }
+ return 0;
- ret = dict_set_dynstr (*dict, local->xsel, xattr_buf);
- if (ret)
- GF_FREE (xattr_buf);
- GF_FREE (local->xattr_val);
+err:
+ op_errno = (op_errno == -1) ? errno : op_errno;
+ DHT_STACK_UNWIND (fstat, frame, -1, op_errno, NULL);
- out:
- return ret;
+ return 0;
}
+
int
-dht_vgetxattr_dir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int op_ret, int op_errno, dict_t *xattr, dict_t *xdata)
+dht_truncate (call_frame_t *frame, xlator_t *this,
+ loc_t *loc, off_t offset)
{
- int ret = 0;
- dht_local_t *local = NULL;
- int this_call_cnt = 0;
- dict_t *dict = NULL;
-
- VALIDATE_OR_GOTO (frame, out);
- VALIDATE_OR_GOTO (frame->local, out);
-
- local = frame->local;
+ xlator_t *subvol = NULL;
+ int op_errno = -1;
+ dht_local_t *local = NULL;
- LOCK (&frame->lock);
- {
- this_call_cnt = --local->call_cnt;
- if (op_ret < 0) {
- if (op_errno != ENOTCONN) {
- gf_log (this->name, GF_LOG_ERROR,
- "getxattr err (%s) for dir",
- strerror (op_errno));
- local->op_ret = -1;
- local->op_errno = op_errno;
- }
- goto unlock;
- }
+ 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);
- ret = dht_vgetxattr_alloc_and_fill (local, xattr, this,
- op_errno);
- if (ret)
- gf_log (this->name, GF_LOG_ERROR,
- "alloc or fill failure");
- }
- unlock:
- UNLOCK (&frame->lock);
+ 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;
+ }
- if (!is_last_call (this_call_cnt))
- goto out;
+ local = dht_local_init (frame);
+ if (!local) {
+ op_errno = ENOMEM;
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory");
+ goto err;
+ }
- /* -- last call: do patch ups -- */
+ local->inode = inode_ref (loc->inode);
+ local->call_cnt = 1;
- if (local->op_ret == -1) {
- goto unwind;
- }
+ STACK_WIND (frame, dht_truncate_cbk,
+ subvol, subvol->fops->truncate,
+ loc, offset);
- ret = dht_vgetxattr_fill_and_set (local, &dict, this, _gf_true);
- if (ret)
- goto unwind;
+ return 0;
- DHT_STACK_UNWIND (getxattr, frame, 0, 0, dict, xdata);
- goto cleanup;
+err:
+ op_errno = (op_errno == -1) ? errno : op_errno;
+ DHT_STACK_UNWIND (truncate, frame, -1, op_errno, NULL, NULL);
- unwind:
- DHT_STACK_UNWIND (getxattr, frame, -1, local->op_errno, NULL, NULL);
- cleanup:
- if (dict)
- dict_unref (dict);
- out:
- return 0;
+ return 0;
}
+
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_ftruncate (call_frame_t *frame, xlator_t *this,
+ fd_t *fd, off_t offset)
{
- dht_local_t *local = NULL;
- int ret = 0;
- dict_t *dict = NULL;
- call_frame_t *prev = NULL;
- gf_boolean_t flag = _gf_true;
+ xlator_t *subvol = NULL;
+ int op_errno = -1;
+ dht_local_t *local = NULL;
- local = frame->local;
- prev = cookie;
- if (op_ret < 0) {
- local->op_ret = -1;
- local->op_errno = op_errno;
- gf_log (this->name, GF_LOG_ERROR,
- "vgetxattr: Subvolume %s returned -1 (%s)",
- prev->this->name, strerror (op_errno));
- goto unwind;
- }
+ VALIDATE_OR_GOTO (frame, err);
+ VALIDATE_OR_GOTO (this, err);
+ VALIDATE_OR_GOTO (fd, err);
- ret = dht_vgetxattr_alloc_and_fill (local, xattr, this,
- op_errno);
- if (ret) {
- gf_msg (this->name, GF_LOG_ERROR, 0,
- DHT_MSG_NO_MEMORY,
- "Allocation or fill failure");
- goto unwind;
- }
+ 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;
+ }
- flag = (local->layout->cnt > 1) ? _gf_true : _gf_false;
+ local = dht_local_init (frame);
+ if (!local) {
+ op_errno = ENOMEM;
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory");
+ goto err;
+ }
- ret = dht_vgetxattr_fill_and_set (local, &dict, this, flag);
- if (ret)
- goto unwind;
+ local->inode = inode_ref (fd->inode);
+ local->call_cnt = 1;
- DHT_STACK_UNWIND (getxattr, frame, 0, 0, dict, xdata);
- goto cleanup;
+ STACK_WIND (frame, dht_truncate_cbk,
+ subvol, subvol->fops->ftruncate,
+ fd, offset);
- unwind:
- DHT_STACK_UNWIND (getxattr, frame, -1, local->op_errno,
- NULL, NULL);
- cleanup:
- if (dict)
- dict_unref (dict);
+ return 0;
- return 0;
+err:
+ op_errno = (op_errno == -1) ? errno : op_errno;
+ DHT_STACK_UNWIND (ftruncate, frame, -1, op_errno, NULL, NULL);
+
+ 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)
+dht_unlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int op_ret, int op_errno, struct stat *preparent,
+ struct stat *postparent)
{
- int ret = 0;
- char *value = NULL;
+ dht_local_t *local = NULL;
+ int this_call_cnt = 0;
+ call_frame_t *prev = NULL;
- if (op_ret != -1) {
- ret = dict_get_str (xattr, GF_XATTR_PATHINFO_KEY, &value);
- if (!ret) {
- ret = dict_set_str (xattr, GF_XATTR_LINKINFO_KEY, value);
- if (!ret)
- gf_msg_trace (this->name, 0,
- "failed to set linkinfo");
- }
- }
- DHT_STACK_UNWIND (getxattr, frame, op_ret, op_errno, xattr, xdata);
+ 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;
+ }
+
+ local->op_ret = 0;
+ local->postparent = *postparent;
+ local->preparent = *preparent;
+ }
+unlock:
+ UNLOCK (&frame->lock);
+
+ this_call_cnt = dht_frame_return (frame);
+ if (is_last_call (this_call_cnt))
+ DHT_STACK_UNWIND (unlink, frame, local->op_ret, local->op_errno,
+ &local->preparent, &local->postparent);
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)
+dht_fsync_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int op_ret,
+ int op_errno, struct stat *prebuf, struct stat *postbuf)
{
- int this_call_cnt = 0;
- dht_local_t *local = NULL;
- dht_conf_t *conf = NULL;
+ dht_local_t *local = NULL;
+ int this_call_cnt = 0;
+ call_frame_t *prev = NULL;
- VALIDATE_OR_GOTO (frame, out);
- VALIDATE_OR_GOTO (frame->local, out);
- VALIDATE_OR_GOTO (this->private, out);
- conf = this->private;
- local = frame->local;
-
- this_call_cnt = dht_frame_return (frame);
-
- if (!xattr || (op_ret == -1))
- goto 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;
+ }
- if (dict_get (xattr, conf->xattr_name)) {
- dict_del (xattr, conf->xattr_name);
- }
+ local->op_ret = 0;
+ }
+unlock:
+ UNLOCK (&frame->lock);
- if (frame->root->pid >= 0 ) {
- GF_REMOVE_INTERNAL_XATTR("trusted.glusterfs.quota*", xattr);
- GF_REMOVE_INTERNAL_XATTR("trusted.pgfid*", xattr);
+ if (local && (op_ret == 0)) {
+ prebuf->st_ino = local->st_ino;
+ postbuf->st_ino = local->st_ino;
}
- local->op_ret = 0;
+ 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);
- if (!local->xattr) {
- local->xattr = dict_copy_with_ref (xattr, NULL);
- } else {
- dht_aggregate_xattr (local->xattr, xattr);
- }
-out:
- if (is_last_call (this_call_cnt)) {
- DHT_STACK_UNWIND (getxattr, frame, local->op_ret, op_errno,
- local->xattr, NULL);
- }
return 0;
}
-int32_t
-dht_getxattr_unwind (call_frame_t *frame,
- int op_ret, int op_errno, dict_t *dict, dict_t *xdata)
-{
- DHT_STACK_UNWIND (getxattr, frame, op_ret, op_errno, dict, xdata);
- return 0;
-}
int
-dht_getxattr_get_real_filename_cbk (call_frame_t *frame, void *cookie,
- xlator_t *this, int op_ret, int op_errno,
- dict_t *xattr, dict_t *xdata)
+dht_err_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int op_ret, int op_errno)
{
- int this_call_cnt = 0;
- dht_local_t *local = NULL;
+ dht_local_t *local = NULL;
+ int this_call_cnt = 0;
+ call_frame_t *prev = NULL;
- local = frame->local;
+ 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;
+ }
- LOCK (&frame->lock);
- {
- if (local->op_errno == ENODATA ||
- local->op_errno == EOPNOTSUPP) {
- /* Nothing to do here, we have already found
- * a subvol which does not have the get_real_filename
- * optimization. If condition is for simple logic.
- */
- goto unlock;
- }
+ local->op_ret = 0;
+ }
+unlock:
+ UNLOCK (&frame->lock);
- if (op_ret == -1) {
-
- if (op_errno == ENODATA || op_errno == EOPNOTSUPP) {
- /* This subvol does not have the optimization.
- * Better let the user know we don't support it.
- * Remove previous results if any.
- */
-
- if (local->xattr) {
- dict_unref (local->xattr);
- local->xattr = NULL;
- }
-
- if (local->xattr_req) {
- dict_unref (local->xattr_req);
- local->xattr_req = NULL;
- }
-
- local->op_ret = op_ret;
- local->op_errno = op_errno;
- gf_log (this->name, GF_LOG_WARNING, "At least "
- "one of the bricks does not support "
- "this operation. Please upgrade all "
- "bricks.");
- goto 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);
+ }
- if (op_errno == ENOENT) {
- /* Do nothing, our defaults are set to this.
- */
- goto unlock;
- }
+ return 0;
+}
- /* This is a place holder for every other error
- * case. I am not sure of how to interpret
- * ENOTCONN etc. As of now, choosing to ignore
- * down subvol and return a good result(if any)
- * from other subvol.
- */
- gf_log (this->name, GF_LOG_WARNING,
- "Failed to get real filename. "
- "error:%s", strerror (op_errno));
- goto unlock;
- }
+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;
- /* This subvol has the required file.
- * There could be other subvols which have returned
- * success already, choosing to return the latest good
- * result.
- */
- if (local->xattr)
- dict_unref (local->xattr);
- local->xattr = dict_ref (xattr);
+ 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);
- if (local->xattr_req) {
- dict_unref (local->xattr_req);
- local->xattr_req = NULL;
- }
- if (xdata)
- local->xattr_req = dict_ref (xdata);
+ 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->op_ret = op_ret;
- local->op_errno = 0;
- gf_log (this->name, GF_LOG_DEBUG, "Found a matching "
- "file.");
- }
-unlock:
- UNLOCK (&frame->lock);
+ local = dht_local_init (frame);
+ if (!local) {
+ op_errno = ENOMEM;
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory");
+ goto err;
+ }
+ local->call_cnt = 1;
- this_call_cnt = dht_frame_return (frame);
- if (is_last_call (this_call_cnt)) {
- DHT_STACK_UNWIND (getxattr, frame, local->op_ret,
- local->op_errno, local->xattr,
- local->xattr_req);
- }
+ 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_getxattr_get_real_filename (call_frame_t *frame, xlator_t *this,
- loc_t *loc, const char *key, dict_t *xdata)
+dht_readlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int op_ret, int op_errno, const char *path, struct stat *sbuf)
{
- dht_local_t *local = NULL;
- int i = 0;
- dht_layout_t *layout = NULL;
- int cnt = 0;
- xlator_t *subvol = NULL;
-
-
- local = frame->local;
- layout = local->layout;
+ dht_local_t *local = NULL;
- cnt = local->call_cnt = layout->cnt;
+ local = frame->local;
+ if (op_ret == -1)
+ goto err;
- local->op_ret = -1;
- local->op_errno = ENOENT;
+ if (local) {
+ sbuf->st_ino = local->st_ino;
+ } else {
+ op_ret = -1;
+ op_errno = EINVAL;
+ }
- for (i = 0; i < cnt; i++) {
- subvol = layout->list[i].xlator;
- STACK_WIND (frame, dht_getxattr_get_real_filename_cbk,
- subvol, subvol->fops->getxattr,
- loc, key, xdata);
- }
+err:
+ DHT_STACK_UNWIND (readlink, frame, op_ret, op_errno, path, sbuf);
- return 0;
+ return 0;
}
int
-dht_getxattr (call_frame_t *frame, xlator_t *this,
- loc_t *loc, const char *key, dict_t *xdata)
-#define DHT_IS_DIR(layout) (layout->cnt > 1)
+dht_readlink (call_frame_t *frame, xlator_t *this,
+ loc_t *loc, size_t size)
{
-
- xlator_t *subvol = NULL;
- xlator_t *hashed_subvol = NULL;
- xlator_t *cached_subvol = NULL;
- dht_conf_t *conf = NULL;
- dht_local_t *local = NULL;
- dht_layout_t *layout = NULL;
- xlator_t **sub_volumes = NULL;
- int op_errno = -1;
- int i = 0;
- int cnt = 0;
+ 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 (this->private, err);
-
- conf = this->private;
-
- local = dht_local_init (frame, loc, NULL, GF_FOP_GETXATTR);
- if (!local) {
- op_errno = ENOMEM;
-
- goto err;
- }
-
- layout = local->layout;
- if (!layout) {
- gf_msg (this->name, GF_LOG_ERROR, 0,
- DHT_MSG_LAYOUT_NULL,
- "Layout is NULL");
- op_errno = ENOENT;
- goto err;
- }
-
- if (key) {
- local->key = gf_strdup (key);
- if (!local->key) {
- op_errno = ENOMEM;
- goto err;
- }
- }
+ VALIDATE_OR_GOTO (loc->path, err);
- if (key &&
- (strncmp (key, GF_XATTR_GET_REAL_FILENAME_KEY,
- strlen (GF_XATTR_GET_REAL_FILENAME_KEY)) == 0)
- && DHT_IS_DIR(layout)) {
- dht_getxattr_get_real_filename (frame, this, loc, key, xdata);
- return 0;
+ 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 file use cached subvolume (obviously!): see if {}
- * below
- * for directory:
- * wind to all subvolumes and exclude subvolumes which
- * return ENOTCONN (in callback)
- *
- * NOTE: Don't trust inode here, as that may not be valid
- * (until inode_link() happens)
- */
- if (key && DHT_IS_DIR(layout) &&
- (XATTR_IS_PATHINFO (key)
- || (strcmp (key, GF_XATTR_NODE_UUID_KEY) == 0))) {
- (void) strncpy (local->xsel, key, 256);
- cnt = local->call_cnt = layout->cnt;
- for (i = 0; i < cnt; i++) {
- subvol = layout->list[i].xlator;
- STACK_WIND (frame, dht_vgetxattr_dir_cbk,
- subvol, subvol->fops->getxattr,
- loc, key, NULL);
- }
- return 0;
- }
+ local = dht_local_init (frame);
+ if (!local) {
+ op_errno = ENOMEM;
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory");
+ goto err;
+ }
- /* node-uuid or pathinfo for files */
- if (key && ((strcmp (key, GF_XATTR_NODE_UUID_KEY) == 0)
- || XATTR_IS_PATHINFO (key))) {
- cached_subvol = local->cached_subvol;
- (void) strncpy (local->xsel, key, 256);
+ local->st_ino = loc->inode->ino;
+
+ STACK_WIND (frame, dht_readlink_cbk,
+ subvol, subvol->fops->readlink,
+ loc, size);
- local->call_cnt = 1;
- STACK_WIND (frame, dht_vgetxattr_cbk, cached_subvol,
- cached_subvol->fops->getxattr, loc, key, NULL);
+ return 0;
- return 0;
- }
+err:
+ op_errno = (op_errno == -1) ? errno : op_errno;
+ DHT_STACK_UNWIND (readlink, frame, -1, op_errno, NULL, NULL);
- if (key && (strcmp (key, GF_XATTR_LINKINFO_KEY) == 0)) {
- hashed_subvol = dht_subvol_get_hashed (this, loc);
- if (!hashed_subvol) {
- gf_msg (this->name, GF_LOG_ERROR, 0,
- DHT_MSG_HASHED_SUBVOL_GET_FAILED,
- "Failed to get hashed subvol for %s",
- loc->path);
- op_errno = EINVAL;
- goto err;
- }
+ return 0;
+}
- cached_subvol = dht_subvol_get_cached (this, loc->inode);
- if (!cached_subvol) {
- gf_msg (this->name, GF_LOG_ERROR, 0,
- DHT_MSG_CACHED_SUBVOL_GET_FAILED,
- "Failed to get cached subvol for %s",
- loc->path);
- op_errno = EINVAL;
- goto err;
- }
- if (hashed_subvol == cached_subvol) {
- op_errno = ENODATA;
- goto err;
- }
- if (hashed_subvol) {
- STACK_WIND (frame, dht_linkinfo_getxattr_cbk, hashed_subvol,
- hashed_subvol->fops->getxattr, loc,
- GF_XATTR_PATHINFO_KEY, NULL);
- return 0;
+int
+dht_getxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int op_ret, int op_errno, dict_t *xattr)
+{
+ if (op_ret != -1) {
+ if (dict_get (xattr, "trusted.glusterfs.dht")) {
+ dict_del (xattr, "trusted.glusterfs.dht");
}
- op_errno = ENODATA;
- goto err;
}
- if (key && (!strcmp (GF_XATTR_MARKER_KEY, key))
- && (GF_CLIENT_PID_GSYNCD == frame->root->pid)) {
- if (DHT_IS_DIR(layout)) {
- cnt = layout->cnt;
- } else {
- cnt = 1;
- }
+ DHT_STACK_UNWIND (getxattr, frame, op_ret, op_errno, xattr);
- sub_volumes = alloca ( cnt * sizeof (xlator_t *));
- for (i = 0; i < cnt; i++)
- *(sub_volumes + i) = layout->list[i].xlator;
+ return 0;
+}
- if (cluster_getmarkerattr (frame, this, loc, key,
- local, dht_getxattr_unwind,
- sub_volumes, cnt,
- MARKER_UUID_TYPE, marker_uuid_default_gauge,
- conf->vol_uuid)) {
- op_errno = EINVAL;
- goto err;
- }
- return 0;
- }
+int
+dht_getxattr (call_frame_t *frame, xlator_t *this,
+ loc_t *loc, const char *key)
+{
+ xlator_t *subvol = NULL;
+ int op_errno = -1;
- if (key && !strcmp (GF_XATTR_QUOTA_LIMIT_LIST, key)) {
- /* quota hardlimit and aggregated size of a directory is stored
- * in inode contexts of each brick. Hence its good enough that
- * we send getxattr for this key to any brick.
- */
- local->call_cnt = 1;
- subvol = dht_first_up_subvol (this);
- STACK_WIND (frame, dht_getxattr_cbk, subvol,
- subvol->fops->getxattr, loc, key, xdata);
- return 0;
- }
- if (key && *conf->vol_uuid) {
- if ((match_uuid_local (key, conf->vol_uuid) == 0) &&
- (GF_CLIENT_PID_GSYNCD == frame->root->pid)) {
- if (DHT_IS_DIR(layout)) {
- cnt = layout->cnt;
- } else {
- cnt = 1;
- }
- sub_volumes = alloca ( cnt * sizeof (xlator_t *));
- for (i = 0; i < cnt; i++)
- sub_volumes[i] = layout->list[i].xlator;
-
- if (cluster_getmarkerattr (frame, this, loc, key,
- local, dht_getxattr_unwind,
- sub_volumes, cnt,
- MARKER_XTIME_TYPE,
- marker_xtime_default_gauge,
- conf->vol_uuid)) {
- op_errno = EINVAL;
- goto err;
- }
+ 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);
- return 0;
- }
- }
+ 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;
+ }
- if (DHT_IS_DIR(layout)) {
- cnt = local->call_cnt = layout->cnt;
- } else {
- cnt = local->call_cnt = 1;
- }
+ STACK_WIND (frame, dht_getxattr_cbk,
+ subvol, subvol->fops->getxattr,
+ loc, key);
- 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;
+ return 0;
err:
- op_errno = (op_errno == -1) ? errno : op_errno;
- DHT_STACK_UNWIND (getxattr, frame, -1, op_errno, NULL, NULL);
+ op_errno = (op_errno == -1) ? errno : op_errno;
+ DHT_STACK_UNWIND (getxattr, frame, -1, op_errno, NULL);
- return 0;
+ return 0;
}
-#undef DHT_IS_DIR
+
int
-dht_fgetxattr (call_frame_t *frame, xlator_t *this,
- fd_t *fd, const char *key, dict_t *xdata)
+dht_setxattr (call_frame_t *frame, xlator_t *this,
+ loc_t *loc, dict_t *xattr, int flags)
{
- xlator_t *subvol = NULL;
- dht_local_t *local = NULL;
- dht_layout_t *layout = NULL;
- int op_errno = -1;
- int i = 0;
- int cnt = 0;
+ 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);
- VALIDATE_OR_GOTO (fd->inode, err);
- VALIDATE_OR_GOTO (this->private, err);
-
- local = dht_local_init (frame, NULL, fd, GF_FOP_FGETXATTR);
- if (!local) {
- op_errno = ENOMEM;
+ VALIDATE_OR_GOTO (loc, err);
+ VALIDATE_OR_GOTO (loc->inode, err);
+ VALIDATE_OR_GOTO (loc->path, err);
- goto 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;
+ }
- layout = local->layout;
- if (!layout) {
- gf_msg (this->name, GF_LOG_ERROR, 0,
- DHT_MSG_LAYOUT_NULL,
- "Layout is NULL");
- op_errno = ENOENT;
- goto err;
- }
+ local = dht_local_init (frame);
+ if (!local) {
+ op_errno = ENOMEM;
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory");
+ goto err;
+ }
- if (key) {
- local->key = gf_strdup (key);
- if (!local->key) {
- op_errno = ENOMEM;
- goto err;
- }
- }
+ local->call_cnt = 1;
- if ((fd->inode->ia_type == IA_IFDIR)
- && key
- && (strncmp (key, GF_XATTR_LOCKINFO_KEY,
- strlen (GF_XATTR_LOCKINFO_KEY) != 0))) {
- cnt = local->call_cnt = layout->cnt;
- } else {
- cnt = local->call_cnt = 1;
- }
+ STACK_WIND (frame, dht_err_cbk,
+ subvol, subvol->fops->setxattr,
+ loc, xattr, flags);
- for (i = 0; i < cnt; i++) {
- subvol = layout->list[i].xlator;
- STACK_WIND (frame, dht_getxattr_cbk,
- subvol, subvol->fops->fgetxattr,
- fd, key, NULL);
- }
- return 0;
+ return 0;
err:
- op_errno = (op_errno == -1) ? errno : op_errno;
- DHT_STACK_UNWIND (fgetxattr, frame, -1, op_errno, NULL, NULL);
+ op_errno = (op_errno == -1) ? errno : op_errno;
+ DHT_STACK_UNWIND (setxattr, frame, -1, op_errno);
- return 0;
+ return 0;
}
+
int
-dht_fsetxattr (call_frame_t *frame, xlator_t *this,
- fd_t *fd, dict_t *xattr, int flags, dict_t *xdata)
+dht_removexattr (call_frame_t *frame, xlator_t *this,
+ loc_t *loc, const char *key)
{
- xlator_t *subvol = NULL;
- dht_local_t *local = NULL;
- int op_errno = EINVAL;
- dht_conf_t *conf = NULL;
+ 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);
- VALIDATE_OR_GOTO (fd->inode, err);
- VALIDATE_OR_GOTO (this->private, err);
-
- conf = this->private;
-
- GF_IF_INTERNAL_XATTR_GOTO (conf->wild_xattr_name, xattr,
- op_errno, err);
+ VALIDATE_OR_GOTO (loc, err);
+ VALIDATE_OR_GOTO (loc->inode, err);
+ VALIDATE_OR_GOTO (loc->path, err);
- local = dht_local_init (frame, NULL, fd, GF_FOP_FSETXATTR);
- if (!local) {
- op_errno = ENOMEM;
- goto 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;
+ }
- subvol = local->cached_subvol;
- if (!subvol) {
- gf_msg_debug (this->name, 0,
- "no cached subvolume for fd=%p", fd);
- op_errno = EINVAL;
- goto err;
- }
+ local = dht_local_init (frame);
+ if (!local) {
+ op_errno = ENOMEM;
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory");
+ goto err;
+ }
- local->call_cnt = 1;
+ local->call_cnt = 1;
- STACK_WIND (frame, dht_err_cbk, subvol, subvol->fops->fsetxattr,
- fd, xattr, flags, NULL);
+ STACK_WIND (frame, dht_err_cbk,
+ subvol, subvol->fops->removexattr,
+ loc, key);
- return 0;
+ return 0;
err:
- op_errno = (op_errno == -1) ? errno : op_errno;
- DHT_STACK_UNWIND (fsetxattr, frame, -1, op_errno, NULL);
+ op_errno = (op_errno == -1) ? errno : op_errno;
+ DHT_STACK_UNWIND (removexattr, frame, -1, op_errno);
- return 0;
+ 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)
+dht_fd_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int op_ret, int op_errno, fd_t *fd)
{
- 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;
+ dht_local_t *local = NULL;
+ int this_call_cnt = 0;
+ call_frame_t *prev = NULL;
- local = frame->local;
- prev = cookie;
- conf = this->private;
-
- if (op_ret == -1)
- goto 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;
+ }
- ret = dict_get_str (xattr, GF_XATTR_PATHINFO_KEY, &value);
- if (ret)
- goto out;
+ local->op_ret = 0;
+ }
+unlock:
+ UNLOCK (&frame->lock);
- 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;
- }
- }
+ 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);
-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)
+dht_open (call_frame_t *frame, xlator_t *this,
+ loc_t *loc, int flags, fd_t *fd, int wbflags)
{
- xlator_t *subvol = NULL;
- dht_local_t *local = NULL;
- dht_conf_t *conf = NULL;
- 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;
+ xlator_t *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);
- VALIDATE_OR_GOTO (loc->inode, err);
-
- conf = this->private;
-
- GF_IF_INTERNAL_XATTR_GOTO (conf->wild_xattr_name, xattr,
- op_errno, err);
+ VALIDATE_OR_GOTO (fd, err);
- local = dht_local_init (frame, loc, NULL, GF_FOP_SETXATTR);
- if (!local) {
- op_errno = ENOMEM;
- goto 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;
+ }
- subvol = local->cached_subvol;
- if (!subvol) {
- gf_msg_debug (this->name, 0,
- "no cached subvolume for path=%s",
- loc->path);
- op_errno = EINVAL;
- goto err;
- }
+ local = dht_local_init (frame);
+ if (!local) {
+ op_errno = ENOMEM;
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory");
+ goto err;
+ }
- layout = local->layout;
- if (!layout) {
- gf_msg_debug (this->name, 0,
- "no layout for path=%s", loc->path);
- op_errno = EINVAL;
- goto err;
- }
+ local->fd = fd_ref (fd);
+ ret = loc_dup (loc, &local->loc);
+ if (ret == -1) {
+ op_errno = ENOMEM;
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory");
+ goto err;
+ }
- local->call_cnt = call_cnt = layout->cnt;
+ local->call_cnt = 1;
- tmp = dict_get (xattr, "distribute.migrate-data");
- if (tmp) {
- if (IA_ISDIR (loc->inode->ia_type)) {
- op_errno = ENOTSUP;
- goto err;
- }
+ STACK_WIND (frame, dht_fd_cbk,
+ subvol, subvol->fops->open,
+ loc, flags, fd, wbflags);
- /* 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;
-
- if (conf->decommission_in_progress)
- forced_rebalance = GF_DHT_MIGRATE_HARDLINK;
-
- local->rebalance.target_node = dht_subvol_get_hashed (this, loc);
- if (!local->rebalance.target_node) {
- gf_msg (this->name, GF_LOG_ERROR, 0,
- DHT_MSG_HASHED_SUBVOL_GET_FAILED,
- "Failed to get hashed subvol for %s",
- loc->path);
- op_errno = EINVAL;
- goto err;
- }
+ return 0;
- local->rebalance.from_subvol = local->cached_subvol;
+err:
+ op_errno = (op_errno == -1) ? errno : op_errno;
+ DHT_STACK_UNWIND (open, frame, -1, op_errno, NULL);
- if (local->rebalance.target_node == local->rebalance.from_subvol) {
- op_errno = EEXIST;
- goto err;
- }
- if (local->rebalance.target_node) {
- local->flags = forced_rebalance;
+ return 0;
+}
- ret = dht_start_rebalance_task (this, frame);
- if (!ret)
- return 0;
- gf_msg (this->name, GF_LOG_ERROR, 0,
- DHT_MSG_REBALANCE_START_FAILED,
- "%s: failed to create a new rebalance synctask",
- loc->path);
- }
- op_errno = EINVAL;
- goto err;
-
- }
+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 stat *stbuf,
+ struct iobref *iobref)
+{
+ DHT_STACK_UNWIND (readv, frame, op_ret, op_errno, vector, count, stbuf,
+ iobref);
- 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;
- }
+ return 0;
+}
- memcpy (value, tmp->data, ((tmp->len < 4095) ? tmp->len : 4095));
- local->key = gf_strdup (value);
- local->call_cnt = conf->subvolume_cnt;
- 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;
- }
+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;
- 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);
- ret = dht_fix_directory_layout (frame, dht_common_setxattr_cbk,
- layout);
- if (ret) {
- op_errno = ENOTCONN;
- goto err;
- }
- return ret;
- }
+ VALIDATE_OR_GOTO (frame, err);
+ VALIDATE_OR_GOTO (this, err);
+ VALIDATE_OR_GOTO (fd, 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;
-
- ret = dht_fix_directory_layout (frame,
- dht_common_setxattr_cbk,
- layout);
- if (ret) {
- op_errno = ENOTCONN;
- goto err;
- }
- return ret;
- }
- gf_log (this->name, GF_LOG_ERROR,
- "wrong 'directory-spread-count' value (%s)", value);
- op_errno = ENOTSUP;
- goto 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;
+ }
- for (i = 0; i < call_cnt; i++) {
- STACK_WIND (frame, dht_err_cbk,
- layout->list[i].xlator,
- layout->list[i].xlator->fops->setxattr,
- loc, xattr, flags, xdata);
- }
+ STACK_WIND (frame, dht_readv_cbk,
+ subvol, subvol->fops->readv,
+ fd, size, off);
- return 0;
+ return 0;
err:
- op_errno = (op_errno == -1) ? errno : op_errno;
- DHT_STACK_UNWIND (setxattr, frame, -1, op_errno, NULL);
+ op_errno = (op_errno == -1) ? errno : op_errno;
+ DHT_STACK_UNWIND (readv, frame, -1, op_errno, NULL, 0, NULL, NULL);
- return 0;
+ 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_writev_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int op_ret, int op_errno, struct stat *prebuf,
+ struct stat *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_errno = op_errno;
- gf_msg_debug (this->name, 0,
- "subvolume %s returned -1 (%s)",
- prev->this->name, strerror (op_errno));
- goto unlock;
- }
+ dht_local_t *local = NULL;
- local->op_ret = 0;
+ if (op_ret == -1) {
+ goto out;
}
-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);
- }
+ local = frame->local;
+ if (!local) {
+ op_ret = -1;
+ op_errno = EINVAL;
+ goto out;
+ }
+
+ prebuf->st_ino = local->st_ino;
+ postbuf->st_ino = local->st_ino;
+
+out:
+ DHT_STACK_UNWIND (writev, frame, op_ret, op_errno, prebuf, postbuf);
return 0;
}
int
-dht_removexattr (call_frame_t *frame, xlator_t *this,
- loc_t *loc, const char *key, dict_t *xdata)
+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;
+ xlator_t *subvol = NULL;
int op_errno = -1;
dht_local_t *local = NULL;
- dht_layout_t *layout = NULL;
- int call_cnt = 0;
- dht_conf_t *conf = NULL;
- int i;
+ VALIDATE_OR_GOTO (frame, err);
VALIDATE_OR_GOTO (this, err);
- VALIDATE_OR_GOTO (this->private, err);
-
- conf = this->private;
-
- GF_IF_NATIVE_XATTR_GOTO (conf->wild_xattr_name, key, op_errno, err);
+ VALIDATE_OR_GOTO (fd, err);
- VALIDATE_OR_GOTO (frame, err);
- VALIDATE_OR_GOTO (loc, err);
- VALIDATE_OR_GOTO (loc->inode, 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) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory");
op_errno = ENOMEM;
goto err;
}
- subvol = local->cached_subvol;
- if (!subvol) {
- gf_msg_debug (this->name, 0,
- "no cached subvolume for path=%s", loc->path);
- op_errno = EINVAL;
- goto err;
- }
-
- layout = local->layout;
- if (!local->layout) {
- gf_msg_debug (this->name, 0,
- "no layout for path=%s", loc->path);
- op_errno = EINVAL;
- goto err;
- }
-
- local->call_cnt = call_cnt = layout->cnt;
- local->key = gf_strdup (key);
+ local->st_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->removexattr,
- loc, key, NULL);
- }
+ STACK_WIND (frame, dht_writev_cbk,
+ subvol, subvol->fops->writev,
+ fd, vector, count, off, iobref);
- return 0;
+ return 0;
err:
- op_errno = (op_errno == -1) ? errno : op_errno;
- DHT_STACK_UNWIND (removexattr, frame, -1, op_errno, NULL);
+ op_errno = (op_errno == -1) ? errno : op_errno;
+ DHT_STACK_UNWIND (writev, frame, -1, op_errno, NULL, NULL);
- return 0;
+ 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;
+ xlator_t *subvol = NULL;
int op_errno = -1;
- dht_local_t *local = NULL;
- dht_layout_t *layout = NULL;
- int call_cnt = 0;
- dht_conf_t *conf = 0;
-
- int i;
+ dht_local_t *local = NULL;
- VALIDATE_OR_GOTO (this, err);
- VALIDATE_OR_GOTO (this->private, err);
-
- conf = this->private;
-
- GF_IF_NATIVE_XATTR_GOTO (conf->wild_xattr_name, key, op_errno, err);
VALIDATE_OR_GOTO (frame, err);
+ VALIDATE_OR_GOTO (this, err);
+ VALIDATE_OR_GOTO (fd, err);
- local = dht_local_init (frame, NULL, fd, GF_FOP_FREMOVEXATTR);
- if (!local) {
- op_errno = ENOMEM;
- goto err;
- }
-
- subvol = local->cached_subvol;
- if (!subvol) {
- gf_msg_debug (this->name, 0,
- "no cached subvolume for inode=%s",
- uuid_utoa (fd->inode->gfid));
- op_errno = EINVAL;
- goto 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;
+ }
- layout = local->layout;
- if (!local->layout) {
- gf_msg_debug (this->name, 0,
- "no layout for inode=%s",
- uuid_utoa (fd->inode->gfid));
- op_errno = EINVAL;
- goto err;
- }
+ local = dht_local_init (frame);
+ if (!local) {
+ op_errno = ENOMEM;
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory");
+ goto err;
+ }
- local->call_cnt = call_cnt = layout->cnt;
- local->key = gf_strdup (key);
+ local->fd = fd_ref (fd);
+ local->call_cnt = 1;
- 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_err_cbk,
+ subvol, subvol->fops->flush, fd);
- return 0;
+ return 0;
err:
- op_errno = (op_errno == -1) ? errno : op_errno;
- DHT_STACK_UNWIND (fremovexattr, frame, -1, op_errno, NULL);
+ op_errno = (op_errno == -1) ? errno : op_errno;
+ DHT_STACK_UNWIND (flush, frame, -1, op_errno);
- return 0;
+ 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_fsync (call_frame_t *frame, xlator_t *this,
+ fd_t *fd, int datasync)
{
- dht_local_t *local = NULL;
- int this_call_cnt = 0;
- call_frame_t *prev = NULL;
+ xlator_t *subvol = NULL;
+ int op_errno = -1;
+ dht_local_t *local = NULL;
- local = frame->local;
- prev = cookie;
- LOCK (&frame->lock);
- {
- if (op_ret == -1) {
- local->op_errno = op_errno;
- gf_msg_debug (this->name, 0,
- "subvolume %s returned -1 (%s)",
- prev->this->name, strerror (op_errno));
- goto unlock;
- }
+ VALIDATE_OR_GOTO (frame, err);
+ VALIDATE_OR_GOTO (this, err);
+ VALIDATE_OR_GOTO (fd, err);
- local->op_ret = 0;
- }
-unlock:
- UNLOCK (&frame->lock);
+ 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;
+ }
- 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);
+ local = dht_local_init (frame);
+ if (!local) {
+ op_errno = ENOMEM;
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory");
+ goto err;
+ }
+ local->call_cnt = 1;
- return 0;
-}
+ local->st_ino = fd->inode->ino;
-/*
- * dht_normalize_stats -
- */
-static void
-dht_normalize_stats (struct statvfs *buf, unsigned long bsize,
- unsigned long frsize)
-{
- double factor = 0;
+ STACK_WIND (frame, dht_fsync_cbk,
+ subvol, subvol->fops->fsync,
+ fd, datasync);
- if (buf->f_bsize != bsize) {
- buf->f_bsize = bsize;
- }
+ return 0;
- if (buf->f_frsize != frsize) {
- factor = ((double) buf->f_frsize) / frsize;
- buf->f_frsize = frsize;
- buf->f_blocks = (fsblkcnt_t) (factor * buf->f_blocks);
- buf->f_bfree = (fsblkcnt_t) (factor * buf->f_bfree);
- buf->f_bavail = (fsblkcnt_t) (factor * buf->f_bavail);
+err:
+ op_errno = (op_errno == -1) ? errno : op_errno;
+ DHT_STACK_UNWIND (fsync, frame, -1, op_errno, NULL, NULL);
- }
+ return 0;
}
+
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)
+dht_lk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int op_ret, int op_errno, struct flock *flock)
{
+ DHT_STACK_UNWIND (lk, frame, op_ret, op_errno, flock);
- gf_boolean_t event = _gf_false;
- qdstatfs_action_t action = qdstatfs_action_OFF;
- dht_local_t * local = NULL;
- int this_call_cnt = 0;
- int bsize = 0;
- int frsize = 0;
- GF_UNUSED int ret = 0;
- unsigned long new_usage = 0;
- unsigned long cur_usage = 0;
+ return 0;
+}
- local = frame->local;
- GF_ASSERT (local);
- if (xdata)
- ret = dict_get_int8 (xdata, "quota-deem-statfs",
- (int8_t *)&event);
+int
+dht_lk (call_frame_t *frame, xlator_t *this,
+ fd_t *fd, int cmd, struct flock *flock)
+{
+ xlator_t *subvol = NULL;
+ int op_errno = -1;
- LOCK (&frame->lock);
- {
- if (op_ret == -1) {
- local->op_errno = op_errno;
- goto unlock;
- }
- if (!statvfs) {
- op_errno = EINVAL;
- local->op_ret = -1;
- goto unlock;
- }
- local->op_ret = 0;
-
- switch (local->quota_deem_statfs) {
- case _gf_true:
- if (event == _gf_true)
- action = qdstatfs_action_COMPARE;
- else
- action = qdstatfs_action_NEGLECT;
- break;
- case _gf_false:
- if (event == _gf_true) {
- action = qdstatfs_action_REPLACE;
- local->quota_deem_statfs = _gf_true;
- }
- break;
+ VALIDATE_OR_GOTO (frame, err);
+ VALIDATE_OR_GOTO (this, err);
+ VALIDATE_OR_GOTO (fd, err);
- default:
- gf_log (this->name, GF_LOG_ERROR, "Encountered third "
- "value for boolean variable %d",
- local->quota_deem_statfs);
- break;
- }
+ 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;
+ }
- if (local->quota_deem_statfs) {
- switch (action) {
- case qdstatfs_action_NEGLECT:
- goto unlock;
+ STACK_WIND (frame, dht_lk_cbk,
+ subvol, subvol->fops->lk,
+ fd, cmd, flock);
- case qdstatfs_action_REPLACE:
- local->statvfs = *statvfs;
- goto unlock;
+ return 0;
- case qdstatfs_action_COMPARE:
- new_usage = statvfs->f_blocks -
- statvfs->f_bfree;
- cur_usage = local->statvfs.f_blocks -
- local->statvfs.f_bfree;
+err:
+ op_errno = (op_errno == -1) ? errno : op_errno;
+ DHT_STACK_UNWIND (lk, frame, -1, op_errno, NULL);
- /* Take the max of the usage from subvols */
- if (new_usage >= cur_usage)
- local->statvfs = *statvfs;
- goto unlock;
+ return 0;
+}
- default:
- break;
- }
- }
- if (local->statvfs.f_bsize != 0) {
- bsize = max(local->statvfs.f_bsize, statvfs->f_bsize);
- frsize = max(local->statvfs.f_frsize, statvfs->f_frsize);
- dht_normalize_stats(&local->statvfs, bsize, frsize);
- dht_normalize_stats(statvfs, bsize, frsize);
- } else {
- local->statvfs.f_bsize = statvfs->f_bsize;
- local->statvfs.f_frsize = statvfs->f_frsize;
- }
+int
+dht_statfs_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int op_ret, int op_errno, struct statvfs *statvfs)
+{
+ dht_local_t *local = NULL;
+ int this_call_cnt = 0;
- local->statvfs.f_blocks += statvfs->f_blocks;
- local->statvfs.f_bfree += statvfs->f_bfree;
- local->statvfs.f_bavail += statvfs->f_bavail;
- local->statvfs.f_files += statvfs->f_files;
- local->statvfs.f_ffree += statvfs->f_ffree;
- local->statvfs.f_favail += statvfs->f_favail;
- local->statvfs.f_fsid = statvfs->f_fsid;
- local->statvfs.f_flag = statvfs->f_flag;
- local->statvfs.f_namemax = statvfs->f_namemax;
+ local = frame->local;
- }
+ LOCK (&frame->lock);
+ {
+ if (op_ret == -1) {
+ local->op_errno = op_errno;
+ goto unlock;
+ }
+ local->op_ret = 0;
+
+ /* TODO: normalize sizes */
+ local->statvfs.f_bsize = statvfs->f_bsize;
+ local->statvfs.f_frsize = statvfs->f_frsize;
+
+ local->statvfs.f_blocks += statvfs->f_blocks;
+ local->statvfs.f_bfree += statvfs->f_bfree;
+ local->statvfs.f_bavail += statvfs->f_bavail;
+ local->statvfs.f_files += statvfs->f_files;
+ local->statvfs.f_ffree += statvfs->f_ffree;
+ local->statvfs.f_favail += statvfs->f_favail;
+ local->statvfs.f_fsid = statvfs->f_fsid;
+ local->statvfs.f_flag = statvfs->f_flag;
+ local->statvfs.f_namemax = statvfs->f_namemax;
+
+ }
unlock:
- UNLOCK (&frame->lock);
+ UNLOCK (&frame->lock);
- 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);
+ 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);
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;
+ dht_local_t *local = NULL;
+ dht_conf_t *conf = NULL;
int op_errno = -1;
- int i = -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 (this->private, err);
-
- 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;
- }
+ VALIDATE_OR_GOTO (loc->path, err);
- subvol = dht_subvol_get_cached (this, loc->inode);
- if (!subvol) {
- gf_msg_debug (this->name, 0,
- "no cached subvolume for path=%s", loc->path);
- op_errno = EINVAL;
- goto err;
- }
+ conf = this->private;
- local->call_cnt = 1;
+ local = dht_local_init (frame);
+ local->call_cnt = conf->subvolume_cnt;
- STACK_WIND (frame, dht_statfs_cbk,
- subvol, subvol->fops->statfs, loc, xdata);
+ for (i = 0; i < conf->subvolume_cnt; i++) {
+ STACK_WIND (frame, dht_statfs_cbk,
+ conf->subvolumes[i],
+ conf->subvolumes[i]->fops->statfs, loc);
+ }
- return 0;
+ return 0;
err:
- op_errno = (op_errno == -1) ? errno : op_errno;
- DHT_STACK_UNWIND (statfs, frame, -1, op_errno, NULL, NULL);
+ op_errno = (op_errno == -1) ? errno : op_errno;
+ DHT_STACK_UNWIND (statfs, frame, -1, op_errno, NULL);
- return 0;
+ 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;
+ dht_local_t *local = NULL;
+ dht_conf_t *conf = NULL;
+ int ret = -1;
int op_errno = -1;
- int i = -1;
+ int i = -1;
+
VALIDATE_OR_GOTO (frame, err);
VALIDATE_OR_GOTO (this, err);
VALIDATE_OR_GOTO (fd, err);
- VALIDATE_OR_GOTO (this->private, err);
- conf = this->private;
+ conf = this->private;
- local = dht_local_init (frame, loc, fd, GF_FOP_OPENDIR);
- if (!local) {
- op_errno = ENOMEM;
+ local = dht_local_init (frame);
+ if (!local) {
+ op_errno = ENOMEM;
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory");
+ goto err;
+ }
- goto err;
- }
+ local->fd = fd_ref (fd);
+ ret = loc_dup (loc, &local->loc);
+ if (ret == -1) {
+ op_errno = ENOMEM;
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory");
+ goto err;
+ }
- local->call_cnt = conf->subvolume_cnt;
+ 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);
- }
+ for (i = 0; i < conf->subvolume_cnt; i++) {
+ STACK_WIND (frame, dht_fd_cbk,
+ conf->subvolumes[i],
+ conf->subvolumes[i]->fops->opendir,
+ loc, fd);
+ }
- return 0;
+ return 0;
err:
- op_errno = (op_errno == -1) ? errno : op_errno;
- DHT_STACK_UNWIND (opendir, frame, -1, op_errno, NULL, NULL);
+ op_errno = (op_errno == -1) ? errno : op_errno;
+ DHT_STACK_UNWIND (opendir, frame, -1, op_errno, NULL);
- return 0;
+ return 0;
}
+
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;
- gf_dirent_t *orig_entry = NULL;
- gf_dirent_t *entry = NULL;
- call_frame_t *prev = NULL;
- xlator_t *next_subvol = NULL;
+ dht_local_t *local = NULL;
+ gf_dirent_t entries;
+ gf_dirent_t *orig_entry = NULL;
+ gf_dirent_t *entry = NULL;
+ call_frame_t *prev = NULL;
+ xlator_t *next_subvol = NULL;
off_t next_offset = 0;
- int count = 0;
+ int count = 0;
dht_layout_t *layout = 0;
dht_conf_t *conf = NULL;
xlator_t *subvol = 0;
- xlator_t *hashed_subvol = 0;
- int ret = 0;
- int readdir_optimize = 0;
- INIT_LIST_HEAD (&entries.list);
- prev = cookie;
- local = frame->local;
- conf = this->private;
+ INIT_LIST_HEAD (&entries.list);
+ prev = cookie;
+ local = frame->local;
+ conf = this->private;
- if (op_ret < 0)
- goto done;
+ if (op_ret < 0)
+ goto done;
if (!local->layout)
- local->layout = dht_layout_get (this, local->fd->inode);
-
- layout = local->layout;
-
- if (conf->readdir_optimize == _gf_true)
- readdir_optimize = 1;
+ local->layout = layout = dht_layout_get (this, local->fd->inode);
+ else
+ layout = local->layout;
- list_for_each_entry (orig_entry, (&orig_entries->list), list) {
+ 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)) {
-
- /*Directory entries filtering :
- * a) If rebalance is running, pick from first_up_subvol
- * b) (rebalance not running)hashed subvolume is NULL or
- * down then filter in first_up_subvolume. Other wise the
- * corresponding hashed subvolume will take care of the
- * directory entry.
- */
-
- if (readdir_optimize) {
- if (prev->this == local->first_up_subvol)
- goto list;
- else
- continue;
-
- }
-
- hashed_subvol = dht_layout_search (this, layout, \
- orig_entry->d_name);
-
- if (prev->this == hashed_subvol)
- goto list;
- if ((hashed_subvol
- && dht_subvol_status (conf, hashed_subvol))
- ||(prev->this != local->first_up_subvol))
- continue;
-
- goto list;
- }
- if (check_is_linkfile (NULL, (&orig_entry->d_stat),
- orig_entry->dict,
- conf->link_xattr_name)) {
+ 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;
}
-list:
+
entry = gf_dirent_for_name (orig_entry->d_name);
if (!entry) {
-
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory");
goto unwind;
}
@@ -3884,54 +2105,29 @@ list:
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.st_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) && orig_entry->inode) {
- ret = dht_layout_preset (this, prev->this,
- orig_entry->inode);
- if (ret)
- gf_msg (this->name, GF_LOG_WARNING, 0,
- DHT_MSG_LAYOUT_SET_FAILED,
- "failed to link the layout in inode");
- entry->inode = inode_ref (orig_entry->inode);
- } else if (orig_entry->inode) {
- dht_inode_ctx_time_update (orig_entry->inode, this,
- &entry->d_stat, 1);
- }
-
list_add_tail (&entry->list, &entries.list);
count++;
- }
- op_ret = count;
- /* We need to ensure that only the last subvolume's end-of-directory
- * notification is respected so that directory reading does not stop
- * before all subvolumes have been read. That could happen because the
- * posix for each subvolume sends a ENOENT on end-of-directory but in
- * distribute we're not concerned only with a posix's view of the
- * directory but the aggregated namespace' view of the directory.
- */
- if (prev->this != dht_last_up_subvol (this))
- op_errno = 0;
+ }
+ op_ret = count;
done:
- if (count == 0) {
+ if (count == 0) {
/* non-zero next_offset means that
EOF is not yet hit on the current subvol
*/
@@ -3941,40 +2137,23 @@ done:
next_subvol = prev->this;
}
- if (!next_subvol) {
- goto unwind;
- }
-
- if (conf->readdir_optimize == _gf_true) {
- if (next_subvol != local->first_up_subvol) {
- ret = dict_set_int32 (local->xattr,
- GF_READDIR_SKIP_DIRS, 1);
- if (ret)
- gf_msg (this->name, GF_LOG_ERROR, 0,
- DHT_MSG_DICT_SET_FAILED,
- "Failed to set dictionary value"
- ":key = %s",
- GF_READDIR_SKIP_DIRS );
- } else {
- dict_del (local->xattr,
- GF_READDIR_SKIP_DIRS);
- }
- }
+ if (!next_subvol) {
+ goto unwind;
+ }
- STACK_WIND (frame, dht_readdirp_cbk,
- next_subvol, next_subvol->fops->readdirp,
- local->fd, local->size, next_offset,
- local->xattr);
- return 0;
- }
+ STACK_WIND (frame, dht_readdirp_cbk,
+ next_subvol, next_subvol->fops->readdirp,
+ local->fd, local->size, next_offset);
+ return 0;
+ }
unwind:
- if (op_ret < 0)
- op_ret = 0;
+ 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);
+ gf_dirent_free (&entries);
return 0;
}
@@ -3983,33 +2162,34 @@ 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;
- gf_dirent_t *orig_entry = NULL;
- gf_dirent_t *entry = NULL;
- call_frame_t *prev = NULL;
- xlator_t *next_subvol = NULL;
+ dht_local_t *local = NULL;
+ gf_dirent_t entries;
+ gf_dirent_t *orig_entry = NULL;
+ gf_dirent_t *entry = NULL;
+ call_frame_t *prev = NULL;
+ xlator_t *next_subvol = NULL;
off_t next_offset = 0;
- int count = 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;
+ INIT_LIST_HEAD (&entries.list);
+ prev = cookie;
+ local = frame->local;
+ conf = this->private;
- if (op_ret < 0)
- goto done;
+ if (op_ret < 0)
+ goto done;
if (!local->layout)
- local->layout = dht_layout_get (this, local->fd->inode);
-
- layout = local->layout;
+ local->layout = layout = dht_layout_get (this, local->fd->inode);
+ else
+ layout = local->layout;
- list_for_each_entry (orig_entry, (&orig_entries->list), list) {
+ list_for_each_entry (orig_entry, (&orig_entries->list), list) {
next_offset = orig_entry->d_off;
subvol = dht_layout_search (this, layout, orig_entry->d_name);
@@ -4017,36 +2197,27 @@ dht_readdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
if (!subvol || (subvol == prev->this)) {
entry = gf_dirent_for_name (orig_entry->d_name);
if (!entry) {
- gf_msg (this->name, GF_LOG_ERROR, 0,
- DHT_MSG_NO_MEMORY,
- "Memory allocation failed ");
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory");
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;
list_add_tail (&entry->list, &entries.list);
count++;
}
- }
- op_ret = count;
- /* We need to ensure that only the last subvolume's end-of-directory
- * notification is respected so that directory reading does not stop
- * before all subvolumes have been read. That could happen because the
- * posix for each subvolume sends a ENOENT on end-of-directory but in
- * distribute we're not concerned only with a posix's view of the
- * directory but the aggregated namespace' view of the directory.
- */
- if (prev->this != dht_last_up_subvol (this))
- op_errno = 0;
+ }
+ op_ret = count;
done:
- if (count == 0) {
+ if (count == 0) {
/* non-zero next_offset means that
EOF is not yet hit on the current subvol
*/
@@ -4056,23 +2227,23 @@ done:
next_subvol = prev->this;
}
- if (!next_subvol) {
- goto unwind;
- }
+ if (!next_subvol) {
+ goto unwind;
+ }
- STACK_WIND (frame, dht_readdir_cbk,
- next_subvol, next_subvol->fops->readdir,
- local->fd, local->size, next_offset, NULL);
- return 0;
- }
+ STACK_WIND (frame, dht_readdir_cbk,
+ next_subvol, next_subvol->fops->readdir,
+ local->fd, local->size, next_offset);
+ return 0;
+ }
unwind:
- if (op_ret < 0)
- op_ret = 0;
+ 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);
+ gf_dirent_free (&entries);
return 0;
}
@@ -4080,99 +2251,61 @@ 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_local_t *local = NULL;
+ dht_conf_t *conf = NULL;
int op_errno = -1;
- xlator_t *xvol = NULL;
- off_t xoff = 0;
- int ret = 0;
- dht_conf_t *conf = NULL;
+ xlator_t *xvol = NULL;
+ off_t xoff = 0;
+
VALIDATE_OR_GOTO (frame, err);
VALIDATE_OR_GOTO (this, err);
VALIDATE_OR_GOTO (fd, err);
- VALIDATE_OR_GOTO (this->private, err);
- conf = this->private;
+ conf = this->private;
- local = dht_local_init (frame, NULL, NULL, whichop);
- if (!local) {
- op_errno = ENOMEM;
- goto err;
- }
+ local = dht_local_init (frame);
+ if (!local) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory");
+ op_errno = ENOMEM;
+ goto err;
+ }
- local->fd = fd_ref (fd);
- local->size = size;
- local->xattr_req = (dict)? dict_ref (dict) : NULL;
- local->first_up_subvol = dht_first_up_subvol (this);
-
- 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,
- conf->link_xattr_name, 256);
- if (ret)
- gf_msg (this->name, GF_LOG_WARNING, 0,
- DHT_MSG_DICT_SET_FAILED,
- "Failed to set dictionary value"
- " : key = %s",
- conf->link_xattr_name);
-
- if (conf->readdir_optimize == _gf_true) {
- if (xvol != local->first_up_subvol) {
- ret = dict_set_int32 (local->xattr,
- GF_READDIR_SKIP_DIRS, 1);
- if (ret)
- gf_msg (this->name,
- GF_LOG_ERROR, 0,
- DHT_MSG_DICT_SET_FAILED,
- "Failed to set "
- "dictionary value: "
- "key = %s",
- GF_READDIR_SKIP_DIRS);
- } else {
- dict_del (local->xattr,
- GF_READDIR_SKIP_DIRS);
- }
- }
- }
+ local->fd = fd_ref (fd);
+ local->size = size;
- STACK_WIND (frame, dht_readdirp_cbk, xvol, xvol->fops->readdirp,
- fd, size, xoff, local->xattr);
- } else {
+ dht_deitransform (this, yoff, &xvol, (uint64_t *)&xoff);
+
+ /* TODO: do proper readdir */
+ 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;
+ return 0;
err:
- op_errno = (op_errno == -1) ? errno : op_errno;
- DHT_STACK_UNWIND (readdir, frame, -1, op_errno, NULL, NULL);
+ op_errno = (op_errno == -1) ? errno : op_errno;
+ DHT_STACK_UNWIND (readdir, frame, -1, op_errno, NULL);
- return 0;
+ return 0;
}
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;
int i = 0;
conf = this->private;
- if (!conf)
- goto out;
for (i = 0; i < conf->subvolume_cnt; i++) {
if (!conf->subvolume_status[i]) {
@@ -4184,16 +2317,15 @@ dht_readdir (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
if (conf->use_readdirp)
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;
}
@@ -4201,88 +2333,88 @@ 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;
+ dht_local_t *local = NULL;
+ int this_call_cnt = 0;
- local = frame->local;
+ local = frame->local;
- LOCK (&frame->lock);
- {
- if (op_ret == -1)
- local->op_errno = op_errno;
+ LOCK (&frame->lock);
+ {
+ if (op_ret == -1)
+ local->op_errno = op_errno;
- if (op_ret == 0)
- local->op_ret = 0;
- }
- UNLOCK (&frame->lock);
+ if (op_ret == 0)
+ local->op_ret = 0;
+ }
+ UNLOCK (&frame->lock);
- 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);
+ 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);
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;
+ dht_local_t *local = NULL;
+ dht_conf_t *conf = NULL;
int op_errno = -1;
- int i = -1;
+ int i = -1;
+
VALIDATE_OR_GOTO (frame, err);
VALIDATE_OR_GOTO (this, err);
VALIDATE_OR_GOTO (fd, err);
- VALIDATE_OR_GOTO (this->private, err);
- conf = this->private;
+ conf = this->private;
- local = dht_local_init (frame, NULL, NULL, GF_FOP_FSYNCDIR);
- if (!local) {
- op_errno = ENOMEM;
- goto err;
- }
+ local = dht_local_init (frame);
+ if (!local) {
+ op_errno = ENOMEM;
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory");
+ goto err;
+ }
- local->fd = fd_ref (fd);
- local->call_cnt = conf->subvolume_cnt;
+ local->fd = fd_ref (fd);
+ local->call_cnt = conf->subvolume_cnt;
- for (i = 0; i < conf->subvolume_cnt; i++) {
- STACK_WIND (frame, dht_fsyncdir_cbk,
- conf->subvolumes[i],
- conf->subvolumes[i]->fops->fsyncdir,
- fd, datasync, xdata);
- }
+ for (i = 0; i < conf->subvolume_cnt; i++) {
+ STACK_WIND (frame, dht_fsyncdir_cbk,
+ conf->subvolumes[i],
+ conf->subvolumes[i]->fops->fsyncdir,
+ fd, datasync);
+ }
- return 0;
+ return 0;
err:
- op_errno = (op_errno == -1) ? errno : op_errno;
- DHT_STACK_UNWIND (fsyncdir, frame, -1, op_errno, NULL);
+ op_errno = (op_errno == -1) ? errno : op_errno;
+ DHT_STACK_UNWIND (fsyncdir, frame, -1, op_errno);
- return 0;
+ return 0;
}
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 op_ret, int op_errno,
+ inode_t *inode, struct stat *stbuf, struct stat *preparent,
+ struct stat *postparent)
{
- xlator_t *prev = NULL;
- int ret = -1;
+ call_frame_t *prev = NULL;
+ int ret = -1;
dht_local_t *local = NULL;
- if (op_ret == -1)
- goto out;
+ if (op_ret == -1)
+ goto out;
local = frame->local;
if (!local) {
@@ -4291,418 +2423,421 @@ dht_newfile_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
goto out;
}
- prev = cookie;
+ prev = cookie;
+ dht_itransform (this, prev->this, stbuf->st_ino, &stbuf->st_ino);
if (local->loc.parent) {
-
- dht_inode_ctx_time_update (local->loc.parent, this,
- preparent, 0);
- dht_inode_ctx_time_update (local->loc.parent, this,
- postparent, 1);
+ preparent->st_ino = local->loc.parent->ino;
+ postparent->st_ino = local->loc.parent->ino;
}
- ret = dht_layout_preset (this, prev, inode);
- if (ret < 0) {
- gf_msg_debug (this->name, 0,
- "could not set pre-set layout for subvolume %s",
- prev? prev->name: NULL);
- op_ret = -1;
- op_errno = EINVAL;
- goto out;
- }
- if (local->linked == _gf_true)
- dht_linkfile_attr_heal (frame, this);
+ ret = dht_layout_preset (this, prev->this, inode);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "could not set pre-set layout for subvolume %s",
+ prev->this->name);
+ op_ret = -1;
+ op_errno = EINVAL;
+ goto out;
+ }
out:
- /*
- * FIXME: ia_size and st_blocks of preparent and postparent do not have
+ /*
+ * FIXME: st_size and st_blocks of preparent and postparent do not have
* correct values. since, preparent and postparent buffers correspond
* to a directory these two members should have values equal to sum of
* corresponding values from each of the subvolume.
- * 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);
- return 0;
+ * See dht_stat_merge for reference.
+ */
+
+ DHT_STACK_UNWIND (mknod, frame, op_ret, op_errno, inode, stbuf, preparent,
+ postparent);
+ return 0;
}
int
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)
+ inode_t *inode, struct stat *stbuf,
+ struct stat *preparent, struct stat *postparent)
{
- dht_local_t *local = NULL;
- xlator_t *cached_subvol = NULL;
+ dht_local_t *local = NULL;
+ xlator_t *cached_subvol = NULL;
if (op_ret == -1)
goto err;
- local = frame->local;
- if (!local || !local->cached_subvol) {
- op_errno = EINVAL;
- goto err;
- }
-
- cached_subvol = local->cached_subvol;
+ local = frame->local;
+ cached_subvol = local->cached_subvol;
- STACK_WIND_COOKIE (frame, dht_newfile_cbk, (void *)cached_subvol,
- cached_subvol, cached_subvol->fops->mknod,
- &local->loc, local->mode, local->rdev, local->umask,
- local->params);
+ STACK_WIND (frame, dht_newfile_cbk,
+ cached_subvol, cached_subvol->fops->mknod,
+ &local->loc, local->mode, local->rdev);
return 0;
-err:
- DHT_STACK_UNWIND (mknod, frame, -1, op_errno, NULL, NULL, NULL, NULL,
- NULL);
- return 0;
+ err:
+ 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)
{
- xlator_t *subvol = NULL;
- int op_errno = -1;
+ xlator_t *subvol = NULL;
+ int op_errno = -1;
+ int ret = -1;
xlator_t *avail_subvol = NULL;
- dht_local_t *local = 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);
+ 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);
- if (!local) {
- op_errno = ENOMEM;
- goto err;
- }
+ local = dht_local_init (frame);
+ if (!local) {
+ op_errno = ENOMEM;
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory");
+ goto err;
+ }
- subvol = dht_subvol_get_hashed (this, loc);
- if (!subvol) {
- gf_msg_debug (this->name, 0,
- "no subvolume in layout for path=%s",
- loc->path);
- op_errno = ENOENT;
+ subvol = dht_subvol_get_hashed (this, loc);
+ if (!subvol) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "no subvolume in layout for path=%s",
+ loc->path);
+ op_errno = ENOENT;
+ goto err;
+ }
+
+ ret = loc_dup (loc, &local->loc);
+ if (ret == -1) {
+ op_errno = ENOMEM;
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory");
goto err;
}
if (!dht_is_subvol_filled (this, subvol)) {
- gf_msg_trace (this->name, 0,
- "creating %s on %s", loc->path,
- subvol->name);
-
- STACK_WIND_COOKIE (frame, dht_newfile_cbk, (void *)subvol,
- subvol, subvol->fops->mknod, loc, mode,
- rdev, umask, params);
+ 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);
} else {
-
- avail_subvol = dht_free_disk_available_subvol (this, subvol,
- local);
+ avail_subvol = dht_free_disk_available_subvol (this, subvol);
if (avail_subvol != subvol) {
- /* Choose the minimum filled volume, and create the
+ /* Choose the minimum filled volume, and create the
files there */
- local->params = dict_ref (params);
local->cached_subvol = avail_subvol;
- local->mode = mode;
+ local->mode = mode;
local->rdev = rdev;
- local->umask = umask;
- dht_linkfile_create (frame,
+
+ dht_linkfile_create (frame,
dht_mknod_linkfile_create_cbk,
- this, avail_subvol, subvol, loc);
+ avail_subvol, subvol, loc);
} else {
- gf_msg_trace (this->name, 0,
- "creating %s on %s", loc->path,
- subvol->name);
-
- STACK_WIND_COOKIE (frame, dht_newfile_cbk,
- (void *)subvol, subvol,
- subvol->fops->mknod, loc, mode,
- rdev, umask, params);
+ 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);
}
}
- return 0;
+ return 0;
err:
- op_errno = (op_errno == -1) ? errno : op_errno;
- DHT_STACK_UNWIND (mknod, frame, -1, op_errno,
- NULL, NULL, NULL, NULL, NULL);
+ op_errno = (op_errno == -1) ? errno : op_errno;
+ DHT_STACK_UNWIND (mknod, frame, -1, op_errno,
+ NULL, NULL, NULL, NULL);
- return 0;
+ return 0;
}
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)
{
- xlator_t *subvol = NULL;
- int op_errno = -1;
+ 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);
- local = dht_local_init (frame, loc, NULL, GF_FOP_SYMLINK);
- if (!local) {
- op_errno = ENOMEM;
- goto err;
- }
+ VALIDATE_OR_GOTO (frame, err);
+ VALIDATE_OR_GOTO (this, err);
+ VALIDATE_OR_GOTO (loc, err);
- subvol = dht_subvol_get_hashed (this, loc);
- if (!subvol) {
- gf_msg_debug (this->name, 0,
- "no subvolume in layout for path=%s",
- loc->path);
- op_errno = ENOENT;
- goto err;
- }
+ local = dht_local_init (frame);
+ if (!local) {
+ op_errno = ENOMEM;
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory");
+ goto err;
+ }
- gf_msg_trace (this->name, 0,
- "creating %s on %s", loc->path, subvol->name);
+ subvol = dht_subvol_get_hashed (this, loc);
+ if (!subvol) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "no subvolume in layout for path=%s",
+ loc->path);
+ op_errno = ENOENT;
+ goto err;
+ }
- STACK_WIND_COOKIE (frame, dht_newfile_cbk, (void *)subvol, subvol,
- subvol->fops->symlink, linkname, loc, umask,
- params);
+ gf_log (this->name, GF_LOG_TRACE,
+ "creating %s on %s", loc->path, subvol->name);
- return 0;
+ STACK_WIND (frame, dht_newfile_cbk,
+ subvol, subvol->fops->symlink,
+ linkname, loc);
+
+ return 0;
err:
- op_errno = (op_errno == -1) ? errno : op_errno;
- DHT_STACK_UNWIND (link, frame, -1, op_errno,
- NULL, NULL, NULL, NULL, NULL);
+ op_errno = (op_errno == -1) ? errno : op_errno;
+ DHT_STACK_UNWIND (link, frame, -1, op_errno,
+ NULL, NULL, NULL, NULL);
- return 0;
+ 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 op_errno = -1;
- dht_local_t *local = NULL;
+ 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);
- if (dht_filter_loc_subvol_key (this, loc, &local->loc,
- &cached_subvol)) {
- gf_log (this->name, GF_LOG_INFO,
- "unlinking %s on %s (given path %s)",
- local->loc.path, cached_subvol->name, loc->path);
- STACK_WIND (frame, dht_unlink_cbk,
- cached_subvol, cached_subvol->fops->unlink,
- &local->loc, xflag, xdata);
- goto done;
- }
+ VALIDATE_OR_GOTO (frame, err);
+ VALIDATE_OR_GOTO (this, err);
+ VALIDATE_OR_GOTO (loc, err);
- 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;
+ }
- goto err;
- }
+ hashed_subvol = dht_subvol_get_hashed (this, loc);
+ if (!hashed_subvol) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "no subvolume in layout for path=%s",
+ loc->path);
+ op_errno = EINVAL;
+ goto err;
+ }
- hashed_subvol = dht_subvol_get_hashed (this, loc);
- /* Dont fail unlink if hashed_subvol is NULL which can be the result
- * of layout anomaly */
- if (!hashed_subvol) {
- gf_msg_debug (this->name, 0,
- "no subvolume in layout for path=%s",
- loc->path);
- }
+ local = dht_local_init (frame);
+ if (!local) {
+ op_errno = ENOMEM;
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory");
+ goto err;
+ }
- cached_subvol = local->cached_subvol;
- if (!cached_subvol) {
- gf_msg_debug (this->name, 0,
- "no cached subvolume for path=%s", loc->path);
- op_errno = EINVAL;
- goto err;
- }
+ ret = loc_copy (&local->loc, loc);
+ if (ret == -1) {
+ op_errno = ENOMEM;
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory");
+ goto err;
+ }
+
+ local->call_cnt = 1;
+ if (hashed_subvol != cached_subvol)
+ local->call_cnt++;
+
+ STACK_WIND (frame, dht_unlink_cbk,
+ cached_subvol, cached_subvol->fops->unlink, loc);
+
+ if (hashed_subvol != cached_subvol)
+ STACK_WIND (frame, dht_unlink_cbk,
+ hashed_subvol, hashed_subvol->fops->unlink, loc);
+
+ return 0;
- local->flags = xflag;
- if (hashed_subvol && hashed_subvol != cached_subvol) {
- STACK_WIND (frame, dht_unlink_linkfile_cbk,
- hashed_subvol, hashed_subvol->fops->unlink, loc,
- xflag, xdata);
- } else {
- STACK_WIND (frame, dht_unlink_cbk,
- cached_subvol, cached_subvol->fops->unlink, loc,
- xflag, xdata);
- }
-done:
- return 0;
err:
- op_errno = (op_errno == -1) ? errno : op_errno;
- DHT_STACK_UNWIND (unlink, frame, -1, op_errno, NULL, NULL, NULL);
+ op_errno = (op_errno == -1) ? errno : op_errno;
+ DHT_STACK_UNWIND (link, frame, -1, op_errno, NULL, NULL, NULL, NULL);
- return 0;
+ return 0;
}
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)
+ int op_ret, int op_errno,
+ inode_t *inode, struct stat *stbuf, struct stat *preparent,
+ struct stat *postparent)
{
call_frame_t *prev = NULL;
- dht_layout_t *layout = NULL;
- dht_local_t *local = NULL;
+ dht_layout_t *layout = NULL;
+ dht_local_t *local = NULL;
prev = cookie;
-
- local = frame->local;
+ local = frame->local;
if (op_ret == -1)
goto out;
- layout = dht_layout_for_subvol (this, prev->this);
- if (!layout) {
- gf_msg_debug (this->name, 0,
- "no pre-set layout for subvolume %s",
- prev->this->name);
- op_ret = -1;
- op_errno = EINVAL;
- goto out;
- }
+ layout = dht_layout_for_subvol (this, prev->this);
+ if (!layout) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "no pre-set layout for subvolume %s",
+ prev->this->name);
+ op_ret = -1;
+ op_errno = EINVAL;
+ goto out;
+ }
+
+ stbuf->st_ino = local->loc.inode->ino;
+
+ preparent->st_ino = local->loc2.parent->ino;
+ postparent->st_ino = local->loc2.parent->ino;
- if (local->loc.parent) {
- dht_inode_ctx_time_update (local->loc.parent, this,
- preparent, 0);
- dht_inode_ctx_time_update (local->loc.parent, this,
- postparent, 1);
- }
- if (local->linked == _gf_true) {
- local->stbuf = *stbuf;
- dht_linkfile_attr_heal (frame, this);
- }
out:
- DHT_STRIP_PHASE1_FLAGS (stbuf);
DHT_STACK_UNWIND (link, frame, op_ret, op_errno, inode, stbuf, preparent,
- postparent, NULL);
+ postparent);
- return 0;
+ return 0;
}
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)
+ int op_ret, int op_errno,
+ inode_t *inode, struct stat *stbuf,
+ struct stat *preparent, struct stat *postparent)
{
- dht_local_t *local = NULL;
- xlator_t *srcvol = NULL;
+ dht_local_t *local = NULL;
+ xlator_t *srcvol = NULL;
- if (op_ret == -1)
- goto err;
- local = frame->local;
- srcvol = local->linkfile.srcvol;
+ if (op_ret == -1)
+ goto err;
- STACK_WIND (frame, dht_link_cbk, srcvol, srcvol->fops->link,
- &local->loc, &local->loc2, xdata);
+ local = frame->local;
+ srcvol = local->linkfile.srcvol;
- return 0;
+ 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);
+ DHT_STACK_UNWIND (link, frame, op_ret, op_errno, inode, stbuf, preparent,
+ postparent);
- return 0;
+ return 0;
}
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;
- int op_errno = -1;
- 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;
+ xlator_t *cached_subvol = NULL;
+ xlator_t *hashed_subvol = NULL;
+ int op_errno = -1;
+ 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);
+
+ 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);
+ op_errno = EINVAL;
+ goto err;
+ }
- goto err;
- }
+ hashed_subvol = dht_subvol_get_hashed (this, newloc);
+ if (!hashed_subvol) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "no subvolume in layout for path=%s",
+ newloc->path);
+ op_errno = EINVAL;
+ goto err;
+ }
- cached_subvol = local->cached_subvol;
- if (!cached_subvol) {
- gf_msg_debug (this->name, 0,
- "no cached subvolume for path=%s", oldloc->path);
- op_errno = ENOENT;
- goto err;
- }
+ local = dht_local_init (frame);
+ if (!local) {
+ op_errno = ENOMEM;
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory");
+ goto err;
+ }
- hashed_subvol = dht_subvol_get_hashed (this, newloc);
- if (!hashed_subvol) {
- gf_msg_debug (this->name, 0,
- "no subvolume in layout for path=%s",
- newloc->path);
- op_errno = ENOENT;
- goto err;
- }
+ ret = loc_copy (&local->loc, oldloc);
+ if (ret == -1) {
+ op_errno = ENOMEM;
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory");
+ goto err;
+ }
- ret = loc_copy (&local->loc2, newloc);
- if (ret == -1) {
- op_errno = ENOMEM;
- goto err;
- }
+ ret = loc_copy (&local->loc2, newloc);
+ if (ret == -1) {
+ op_errno = ENOMEM;
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory");
+ goto err;
+ }
- if (hashed_subvol != cached_subvol) {
- uuid_copy (local->gfid, oldloc->inode->gfid);
- dht_linkfile_create (frame, dht_link_linkfile_cbk, this,
- cached_subvol, hashed_subvol, newloc);
- } else {
- STACK_WIND (frame, dht_link_cbk,
- cached_subvol, cached_subvol->fops->link,
- oldloc, newloc, xdata);
- }
+ if (hashed_subvol != cached_subvol) {
+ 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);
+ }
- return 0;
+ return 0;
err:
- op_errno = (op_errno == -1) ? errno : op_errno;
- DHT_STACK_UNWIND (link, frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL);
+ op_errno = (op_errno == -1) ? errno : op_errno;
+ DHT_STACK_UNWIND (link, frame, -1, op_errno, NULL, NULL, NULL, NULL);
- return 0;
+ return 0;
}
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 op_ret, int op_errno,
+ fd_t *fd, inode_t *inode, struct stat *stbuf,
+ struct stat *preparent, struct stat *postparent)
{
- call_frame_t *prev = NULL;
- int ret = -1;
+ call_frame_t *prev = NULL;
+ int ret = -1;
dht_local_t *local = NULL;
- if (op_ret == -1)
- goto out;
+ if (op_ret == -1)
+ goto out;
local = frame->local;
if (!local) {
@@ -4711,268 +2846,244 @@ dht_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
goto out;
}
- prev = cookie;
+ prev = cookie;
+ dht_itransform (this, prev->this, stbuf->st_ino, &stbuf->st_ino);
if (local->loc.parent) {
- dht_inode_ctx_time_update (local->loc.parent, this,
- preparent, 0);
-
- dht_inode_ctx_time_update (local->loc.parent, this,
- postparent, 1);
+ preparent->st_ino = local->loc.parent->ino;
+ postparent->st_ino = local->loc.parent->ino;
}
ret = dht_layout_preset (this, prev->this, inode);
- if (ret != 0) {
- gf_msg_debug (this->name, 0,
- "could not set preset layout for subvol %s",
- prev->this->name);
- op_ret = -1;
- op_errno = EINVAL;
- goto out;
- }
- if (local->linked == _gf_true) {
- local->stbuf = *stbuf;
- dht_linkfile_attr_heal (frame, this);
- }
+ if (ret != 0) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "could not set preset layout for subvol %s",
+ prev->this->name);
+ op_ret = -1;
+ op_errno = EINVAL;
+ goto out;
+ }
+
out:
- DHT_STRIP_PHASE1_FLAGS (stbuf);
- DHT_STACK_UNWIND (create, frame, op_ret, op_errno, fd, inode, stbuf, preparent,
- postparent, xdata);
- return 0;
+ DHT_STACK_UNWIND (create, frame, op_ret, op_errno, fd, inode, stbuf, preparent,
+ postparent);
+ return 0;
}
int
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)
+ xlator_t *this,
+ int32_t op_ret, int32_t op_errno,
+ inode_t *inode, struct stat *stbuf,
+ struct stat *preparent, struct stat *postparent)
{
- dht_local_t *local = NULL;
- xlator_t *cached_subvol = NULL;
+ dht_local_t *local = NULL;
+ xlator_t *cached_subvol = NULL;
if (op_ret == -1)
goto err;
- local = frame->local;
- cached_subvol = local->cached_subvol;
+ local = frame->local;
+ cached_subvol = local->cached_subvol;
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->loc, local->flags, local->mode, local->fd);
return 0;
-err:
- DHT_STACK_UNWIND (create, frame, -1, op_errno, NULL, NULL, NULL,
- NULL, NULL, NULL);
- return 0;
+ err:
+ 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)
+ loc_t *loc, int32_t flags, mode_t mode, fd_t *fd)
{
- int op_errno = -1;
- xlator_t *subvol = NULL;
+ 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;
- VALIDATE_OR_GOTO (frame, err);
- VALIDATE_OR_GOTO (this, err);
- VALIDATE_OR_GOTO (loc, err);
+ 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, fd, GF_FOP_CREATE);
- if (!local) {
- op_errno = ENOMEM;
- goto err;
- }
+ local = dht_local_init (frame);
+ if (!local) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory");
+ op_errno = ENOMEM;
+ goto err;
+ }
- if (dht_filter_loc_subvol_key (this, loc, &local->loc,
- &subvol)) {
- gf_log (this->name, GF_LOG_INFO,
- "creating %s on %s (got create on %s)",
- local->loc.path, subvol->name, loc->path);
- STACK_WIND (frame, dht_create_cbk,
- subvol, subvol->fops->create,
- &local->loc, flags, mode, umask, fd, params);
- goto done;
- }
+ subvol = dht_subvol_get_hashed (this, loc);
+ if (!subvol) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "no subvolume in layout for path=%s",
+ loc->path);
+ op_errno = ENOENT;
+ goto err;
+ }
- subvol = dht_subvol_get_hashed (this, loc);
- if (!subvol) {
- gf_msg_debug (this->name, 0,
- "no subvolume in layout for path=%s",
- loc->path);
- op_errno = ENOENT;
+ ret = loc_dup (loc, &local->loc);
+ if (ret == -1) {
+ op_errno = ENOMEM;
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory");
goto err;
}
if (!dht_is_subvol_filled (this, subvol)) {
- gf_msg_trace (this->name, 0,
- "creating %s on %s", loc->path,
- subvol->name);
+ gf_log (this->name, GF_LOG_TRACE,
+ "creating %s on %s", loc->path, subvol->name);
STACK_WIND (frame, dht_create_cbk,
subvol, subvol->fops->create,
- loc, flags, mode, umask, fd, params);
- goto done;
- }
- /* Choose the minimum filled volume, and create the
- files there */
- avail_subvol = dht_free_disk_available_subvol (this, subvol, local);
- if (avail_subvol != subvol) {
- local->params = dict_ref (params);
- local->flags = flags;
- local->mode = mode;
- local->umask = umask;
- local->cached_subvol = avail_subvol;
- local->hashed_subvol = subvol;
- gf_msg_trace (this->name, 0,
- "creating %s on %s (link at %s)", loc->path,
- avail_subvol->name, subvol->name);
- dht_linkfile_create (frame, dht_create_linkfile_create_cbk,
- this, avail_subvol, subvol, loc);
- goto done;
+ loc, flags, mode, fd);
+ } else {
+ /* 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->flags = flags;
+ local->mode = mode;
+
+ local->cached_subvol = avail_subvol;
+ local->hashed_subvol = subvol;
+ gf_log (this->name, GF_LOG_TRACE,
+ "creating %s on %s (link at %s)", loc->path,
+ avail_subvol->name, subvol->name);
+ dht_linkfile_create (frame,
+ dht_create_linkfile_create_cbk,
+ avail_subvol, subvol, loc);
+ } else {
+ gf_log (this->name, GF_LOG_TRACE,
+ "creating %s on %s", loc->path, subvol->name);
+ STACK_WIND (frame, dht_create_cbk,
+ subvol, subvol->fops->create,
+ loc, flags, mode, fd);
+
+ }
}
- gf_msg_trace (this->name, 0,
- "creating %s on %s", loc->path, subvol->name);
- STACK_WIND (frame, dht_create_cbk,
- subvol, subvol->fops->create,
- loc, flags, mode, umask, fd, params);
-done:
- return 0;
+
+ 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);
+ op_errno = (op_errno == -1) ? errno : op_errno;
+ DHT_STACK_UNWIND (create, frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL);
- return 0;
+ return 0;
}
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)
+ xlator_t *this,
+ int32_t op_ret, int32_t op_errno)
{
- dht_local_t *local = NULL;
- dht_layout_t *layout = NULL;
+ dht_local_t *local = NULL;
+ dht_layout_t *layout = NULL;
- local = frame->local;
- layout = local->selfheal.layout;
- if (op_ret == 0) {
+ local = frame->local;
+ layout = local->selfheal.layout;
+
+ if (op_ret == 0) {
dht_layout_set (this, local->inode, layout);
+ local->stbuf.st_ino = local->st_ino;
+ local->stbuf.st_dev = local->st_dev;
if (local->loc.parent) {
- dht_inode_ctx_time_update (local->loc.parent, this,
- &local->preparent, 0);
-
- dht_inode_ctx_time_update (local->loc.parent, this,
- &local->postparent, 1);
+ local->preparent.st_ino = local->loc.parent->ino;
+ local->postparent.st_ino = local->loc.parent->ino;
}
- }
+ }
- DHT_STACK_UNWIND (mkdir, frame, op_ret, op_errno,
- local->inode, &local->stbuf, &local->preparent,
- &local->postparent, NULL);
+ DHT_STACK_UNWIND (mkdir, frame, op_ret, op_errno,
+ local->inode, &local->stbuf, &local->preparent,
+ &local->postparent);
- return 0;
+ return 0;
}
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)
+ int op_ret, int op_errno, inode_t *inode, struct stat *stbuf,
+ struct stat *preparent, struct stat *postparent)
{
- dht_local_t *local = NULL;
- int this_call_cnt = 0;
- int ret = -1;
- gf_boolean_t subvol_filled = _gf_false;
- call_frame_t *prev = NULL;
- dht_layout_t *layout = NULL;
+ dht_local_t *local = NULL;
+ int this_call_cnt = 0;
+ int ret = -1;
+ int subvol_filled = 0;
+ call_frame_t *prev = NULL;
+ dht_layout_t *layout = NULL;
+ dht_conf_t *conf = NULL;
- local = frame->local;
- prev = cookie;
- layout = local->layout;
+ conf = this->private;
+ local = frame->local;
+ prev = cookie;
+ layout = local->layout;
subvol_filled = dht_is_subvol_filled (this, prev->this);
- LOCK (&frame->lock);
- {
+ LOCK (&frame->lock);
+ {
if (subvol_filled && (op_ret != -1)) {
ret = dht_layout_merge (this, layout, prev->this,
-1, ENOSPC, NULL);
} else {
- if (op_ret == -1 && op_errno == EEXIST)
- /* Very likely just a race between mkdir and
- self-heal (from lookup of a concurrent mkdir
- attempt).
- Ignore error for now. layout setting will
- anyways fail if this was a different (old)
- pre-existing different directory.
- */
- op_ret = 0;
ret = dht_layout_merge (this, layout, prev->this,
op_ret, op_errno, NULL);
}
- if (ret)
- gf_msg (this->name, GF_LOG_WARNING, 0,
- DHT_MSG_LAYOUT_MERGE_FAILED,
- "%s: failed to merge layouts for subvol %s",
- local->loc.path, prev->this->name);
-
- if (op_ret == -1) {
- local->op_errno = op_errno;
- goto unlock;
- }
- dht_iatt_merge (this, &local->stbuf, stbuf, prev->this);
- dht_iatt_merge (this, &local->preparent, preparent, prev->this);
- dht_iatt_merge (this, &local->postparent, postparent,
+
+ if (op_ret == -1) {
+ local->op_errno = op_errno;
+ goto unlock;
+ }
+ dht_stat_merge (this, &local->stbuf, stbuf, prev->this);
+ dht_stat_merge (this, &local->preparent, preparent, prev->this);
+ dht_stat_merge (this, &local->postparent, postparent,
prev->this);
- }
+ }
unlock:
- UNLOCK (&frame->lock);
+ UNLOCK (&frame->lock);
- this_call_cnt = dht_frame_return (frame);
- if (is_last_call (this_call_cnt)) {
- dht_selfheal_new_directory (frame, dht_mkdir_selfheal_cbk,
- layout);
- }
+ this_call_cnt = dht_frame_return (frame);
+ if (is_last_call (this_call_cnt)) {
+ dht_selfheal_new_directory (frame, dht_mkdir_selfheal_cbk,
+ layout);
+ }
return 0;
}
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)
+dht_mkdir_hashed_cbk (call_frame_t *frame, void *cookie,
+ xlator_t *this, int op_ret, int op_errno,
+ inode_t *inode, struct stat *stbuf,
+ struct stat *preparent, struct stat *postparent)
{
- dht_local_t *local = NULL;
- int ret = -1;
- call_frame_t *prev = NULL;
- dht_layout_t *layout = NULL;
- dht_conf_t *conf = NULL;
- int i = 0;
- xlator_t *hashed_subvol = NULL;
-
- VALIDATE_OR_GOTO (this->private, err);
-
- local = frame->local;
- prev = cookie;
- layout = local->layout;
- conf = this->private;
- hashed_subvol = local->hashed_subvol;
+ dht_local_t *local = NULL;
+ int ret = -1;
+ call_frame_t *prev = NULL;
+ dht_layout_t *layout = NULL;
+ dht_conf_t *conf = NULL;
+ int i = 0;
+ xlator_t *hashed_subvol = NULL;
- if (uuid_is_null (local->loc.gfid) && !op_ret)
- uuid_copy (local->loc.gfid, stbuf->ia_gfid);
+ local = frame->local;
+ prev = cookie;
+ layout = local->layout;
+ conf = this->private;
+ hashed_subvol = local->hashed_subvol;
if (dht_is_subvol_filled (this, hashed_subvol))
ret = dht_layout_merge (this, layout, prev->this,
@@ -4980,57 +3091,49 @@ dht_mkdir_hashed_cbk (call_frame_t *frame, void *cookie,
else
ret = dht_layout_merge (this, layout, prev->this,
op_ret, op_errno, NULL);
+
+ if (op_ret == -1) {
+ local->op_errno = op_errno;
+ goto err;
+ }
+ local->op_ret = 0;
- /* TODO: we may have to return from the function
- if layout merge fails. For now, lets just log an error */
- if (ret)
- gf_msg (this->name, GF_LOG_WARNING, 0,
- DHT_MSG_LAYOUT_MERGE_FAILED,
- "%s: failed to merge layouts for subvol %s",
- local->loc.path, prev->this->name);
-
- if (op_ret == -1) {
- local->op_errno = op_errno;
- goto err;
- }
- local->op_ret = 0;
-
- dht_iatt_merge (this, &local->stbuf, stbuf, prev->this);
- dht_iatt_merge (this, &local->preparent, preparent, prev->this);
- dht_iatt_merge (this, &local->postparent, postparent, prev->this);
+ dht_stat_merge (this, &local->stbuf, stbuf, prev->this);
+ dht_stat_merge (this, &local->preparent, preparent, prev->this);
+ dht_stat_merge (this, &local->postparent, postparent, prev->this);
- local->call_cnt = conf->subvolume_cnt - 1;
+ local->st_ino = local->stbuf.st_ino;
+ local->st_dev = local->stbuf.st_dev;
- 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);
- }
- for (i = 0; i < conf->subvolume_cnt; i++) {
- if (conf->subvolumes[i] == hashed_subvol)
- continue;
- STACK_WIND (frame, dht_mkdir_cbk,
- conf->subvolumes[i],
- conf->subvolumes[i]->fops->mkdir, &local->loc,
- local->mode, local->umask, local->params);
- }
- return 0;
+ local->call_cnt = conf->subvolume_cnt - 1;
+
+ if (local->call_cnt == 0) {
+ dht_selfheal_directory (frame, dht_mkdir_selfheal_cbk,
+ &local->loc, layout);
+ }
+ for (i = 0; i < conf->subvolume_cnt; i++) {
+ if (conf->subvolumes[i] == hashed_subvol)
+ continue;
+ STACK_WIND (frame, dht_mkdir_cbk,
+ conf->subvolumes[i],
+ conf->subvolumes[i]->fops->mkdir,
+ &local->loc, local->mode);
+ }
+ 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)
{
- dht_local_t *local = NULL;
- dht_conf_t *conf = NULL;
+ dht_local_t *local = NULL;
+ dht_conf_t *conf = NULL;
int op_errno = -1;
- xlator_t *hashed_subvol = NULL;
+ int ret = -1;
+ xlator_t *hashed_subvol = NULL;
VALIDATE_OR_GOTO (frame, err);
@@ -5038,244 +3141,144 @@ dht_mkdir (call_frame_t *frame, xlator_t *this,
VALIDATE_OR_GOTO (loc, err);
VALIDATE_OR_GOTO (loc->inode, err);
VALIDATE_OR_GOTO (loc->path, err);
- VALIDATE_OR_GOTO (this->private, err);
- conf = this->private;
+ conf = this->private;
dht_get_du_info (frame, this, loc);
- local = dht_local_init (frame, loc, NULL, GF_FOP_MKDIR);
- if (!local) {
- op_errno = ENOMEM;
- goto err;
- }
-
- hashed_subvol = dht_subvol_get_hashed (this, loc);
- if (hashed_subvol == NULL) {
- gf_msg_debug (this->name, 0,
- "hashed subvol not found for %s",
- loc->path);
- op_errno = ENOENT;
- goto err;
- }
-
- local->hashed_subvol = hashed_subvol;
- local->mode = mode;
- local->umask = umask;
- 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;
- }
+ local = dht_local_init (frame);
+ if (!local) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory");
+ op_errno = ENOMEM;
+ goto err;
+ }
- STACK_WIND (frame, dht_mkdir_hashed_cbk,
- hashed_subvol,
- hashed_subvol->fops->mkdir,
- loc, mode, umask, params);
+ hashed_subvol = dht_subvol_get_hashed (this, loc);
- return 0;
+ if (hashed_subvol == NULL) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "hashed subvol not found for %s",
+ loc->path);
+ op_errno = EINVAL;
+ goto err;
+ }
-err:
- op_errno = (op_errno == -1) ? errno : op_errno;
- DHT_STACK_UNWIND (mkdir, frame, -1, op_errno, NULL, NULL, NULL,
- NULL, NULL);
+ local->hashed_subvol = hashed_subvol;
+ local->inode = inode_ref (loc->inode);
+ ret = loc_copy (&local->loc, loc);
+ local->mode = mode;
- return 0;
-}
+ if (ret == -1) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory");
+ op_errno = ENOMEM;
+ goto err;
+ }
+ local->layout = dht_layout_new (this, conf->subvolume_cnt);
+ if (!local->layout) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory");
+ op_errno = ENOMEM;
+ goto err;
+ }
-int
-dht_rmdir_selfheal_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int op_ret, int op_errno, dict_t *xdata)
-{
- dht_local_t *local = NULL;
+ STACK_WIND (frame, dht_mkdir_hashed_cbk,
+ hashed_subvol,
+ hashed_subvol->fops->mkdir,
+ loc, mode);
- local = frame->local;
+ return 0;
- DHT_STACK_UNWIND (rmdir, frame, local->op_ret, local->op_errno,
- &local->preparent, &local->postparent, NULL);
+err:
+ op_errno = (op_errno == -1) ? errno : op_errno;
+ DHT_STACK_UNWIND (mkdir, frame, -1, op_errno, NULL, NULL, NULL, NULL);
- return 0;
+ 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_rmdir_selfheal_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;
- char gfid[GF_UUID_BUF_SIZE] ={0};
-
- local = frame->local;
- prev = cookie;
-
- uuid_unparse(local->loc.gfid, gfid);
+ dht_local_t *local = NULL;
- 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_msg_debug (this->name, 0,
- "rmdir on %s for %s failed "
- "(gfid = %s) (%s)",
- prev->this->name, local->loc.path,
- gfid, strerror (op_errno));
- goto unlock;
- }
-
- dht_iatt_merge (this, &local->preparent, preparent, prev->this);
- dht_iatt_merge (this, &local->postparent, postparent,
- prev->this);
+ local = frame->local;
+ if (local->loc.parent) {
+ local->preparent.st_ino = local->loc.parent->ino;
+ local->postparent.st_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 {
+ DHT_STACK_UNWIND (rmdir, frame, local->op_ret, local->op_errno,
+ &local->preparent, &local->postparent);
- if (local->loc.parent) {
- dht_inode_ctx_time_update (local->loc.parent,
- this,
- &local->preparent,
- 0);
-
- dht_inode_ctx_time_update (local->loc.parent,
- this,
- &local->postparent,
- 1);
- }
-
- DHT_STACK_UNWIND (rmdir, frame, local->op_ret,
- local->op_errno, &local->preparent,
- &local->postparent, NULL);
- }
- }
-
- return 0;
+ return 0;
}
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)
+ int op_ret, int op_errno, struct stat *preparent,
+ struct stat *postparent)
{
- dht_local_t *local = NULL;
- int this_call_cnt = 0;
- call_frame_t *prev = NULL;
- int done = 0;
- char gfid[GF_UUID_BUF_SIZE] ={0};
-
- local = frame->local;
- prev = cookie;
-
-
- LOCK (&frame->lock);
- {
- if (op_ret == -1) {
- if ((op_errno != ENOENT) && (op_errno != ESTALE)) {
- local->op_errno = op_errno;
- local->op_ret = -1;
+ dht_local_t *local = NULL;
+ int this_call_cnt = 0;
+ call_frame_t *prev = NULL;
- if (op_errno != EACCES)
- local->need_selfheal = 1;
- }
-
- uuid_unparse(local->loc.gfid, gfid);
-
- gf_msg_debug (this->name, 0,
- "rmdir on %s for %s failed."
- "(gfid = %s) (%s)",
- prev->this->name, local->loc.path,
- gfid, strerror (op_errno));
- goto unlock;
- }
+ 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)
+ 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;
+ }
- /* 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,
+ dht_stat_merge (this, &local->preparent, preparent, prev->this);
+ dht_stat_merge (this, &local->postparent, postparent,
prev->this);
- }
+ }
unlock:
- UNLOCK (&frame->lock);
+ UNLOCK (&frame->lock);
- 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) {
+ 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 (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 */
+ /* TODO: neater interface needed below */
+ local->stbuf.st_mode = local->loc.inode->st_mode;
+ dht_selfheal_restore (frame, dht_rmdir_selfheal_cbk,
+ &local->loc, local->layout);
+ } else {
if (local->loc.parent) {
-
- dht_inode_ctx_time_update (local->loc.parent,
- this,
- &local->preparent,
- 0);
-
- dht_inode_ctx_time_update (local->loc.parent,
- this,
- &local->postparent,
- 1);
-
+ local->preparent.st_ino =
+ local->loc.parent->ino;
+ local->postparent.st_ino =
+ local->loc.parent->ino;
}
- 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;
}
@@ -5284,70 +3287,38 @@ unlock:
int
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;
- char gfid[GF_UUID_BUF_SIZE] ={0};
-
- VALIDATE_OR_GOTO (this->private, err);
-
- conf = this->private;
- local = frame->local;
-
- if (local->op_ret == -1)
- goto err;
-
- local->call_cnt = conf->subvolume_cnt;
-
-
- /* first remove from non-hashed_subvol */
- hashed_subvol = dht_subvol_get_hashed (this, &local->loc);
-
- if (!hashed_subvol) {
- uuid_unparse(local->loc.gfid, gfid);
+ dht_local_t *local = NULL;
+ dht_conf_t *conf = NULL;
+ int i = 0;
- gf_msg (this->name, GF_LOG_WARNING, 0,
- DHT_MSG_HASHED_SUBVOL_GET_FAILED,
- "Failed to get hashed subvol for %s (gfid = %s)",
- local->loc.path, gfid);
- } else {
- local->hashed_subvol = hashed_subvol;
- }
+ conf = this->private;
+ local = frame->local;
- /* 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;
- }
+ if (local->op_ret == -1)
+ goto err;
- for (i = 0; i < conf->subvolume_cnt; i++) {
- if (hashed_subvol &&
- (hashed_subvol == conf->subvolumes[i]))
- continue;
+ local->call_cnt = conf->subvolume_cnt;
- STACK_WIND (frame, dht_rmdir_cbk,
- conf->subvolumes[i],
- conf->subvolumes[i]->fops->rmdir,
- &local->loc, local->flags, NULL);
- }
+ for (i = 0; i < conf->subvolume_cnt; i++) {
+ STACK_WIND (frame, dht_rmdir_cbk,
+ conf->subvolumes[i],
+ conf->subvolumes[i]->fops->rmdir,
+ &local->loc);
+ }
- return 0;
+ return 0;
err:
- DHT_STACK_UNWIND (rmdir, frame, local->op_ret, local->op_errno,
- &local->preparent, &local->postparent, NULL);
- return 0;
+ DHT_STACK_UNWIND (rmdir, frame, local->op_ret, local->op_errno,
+ &local->preparent, &local->postparent);
+ return 0;
}
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)
+ int op_ret, int op_errno, struct stat *preparent,
+ struct stat *postparent)
{
dht_local_t *local = NULL;
call_frame_t *prev = NULL;
@@ -5355,8 +3326,6 @@ dht_rmdir_linkfile_unlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this
call_frame_t *main_frame = NULL;
dht_local_t *main_local = NULL;
int this_call_cnt = 0;
- char gfid[GF_UUID_BUF_SIZE] ={0};
-
local = frame->local;
prev = cookie;
@@ -5365,19 +3334,16 @@ dht_rmdir_linkfile_unlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this
main_frame = local->main_frame;
main_local = main_frame->local;
- uuid_unparse(local->loc.gfid, gfid);
-
if (op_ret == 0) {
- gf_msg_trace (this->name, 0,
- "Unlinked linkfile %s on %s, gfid = %s",
- local->loc.path, src->name, gfid);
+ gf_log (this->name, GF_LOG_TRACE,
+ "unlinked linkfile %s on %s",
+ local->loc.path, src->name);
} else {
main_local->op_ret = -1;
main_local->op_errno = op_errno;
- gf_msg_debug (this->name, 0,
- "Unlink of %s on %s failed. (gfid = %s) (%s)",
- local->loc.path, src->name, gfid,
- strerror (op_errno));
+ gf_log (this->name, GF_LOG_DEBUG,
+ "unlink of %s on %s failed (%s)",
+ local->loc.path, src->name, strerror (op_errno));
}
this_call_cnt = dht_frame_return (main_frame);
@@ -5392,7 +3358,7 @@ dht_rmdir_linkfile_unlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this
int
dht_rmdir_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)
+ struct stat *stbuf, dict_t *xattr, struct stat *parent)
{
dht_local_t *local = NULL;
call_frame_t *prev = NULL;
@@ -5400,8 +3366,6 @@ dht_rmdir_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
call_frame_t *main_frame = NULL;
dht_local_t *main_local = NULL;
int this_call_cnt = 0;
- dht_conf_t *conf = this->private;
- char gfid[GF_UUID_BUF_SIZE] = {0};
local = frame->local;
prev = cookie;
@@ -5413,89 +3377,18 @@ dht_rmdir_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
if (op_ret != 0)
goto err;
- if (!check_is_linkfile (inode, stbuf, xattr, conf->link_xattr_name)) {
+ if (check_is_linkfile (inode, stbuf, xattr) == 0) {
main_local->op_ret = -1;
main_local->op_errno = ENOTEMPTY;
- uuid_unparse(local->loc.gfid, gfid);
-
gf_log (this->name, GF_LOG_WARNING,
- "%s on %s is not a linkfile (type=0%o, gfid = %s)",
- local->loc.path, src->name, stbuf->ia_type, gfid);
+ "%s on %s found to be not a linkfile (mode=0%o)",
+ local->loc.path, src->name, stbuf->st_mode);
goto err;
}
STACK_WIND (frame, dht_rmdir_linkfile_unlink_cbk,
- src, src->fops->unlink, &local->loc, 0, NULL);
- return 0;
-err:
-
- this_call_cnt = dht_frame_return (main_frame);
- if (is_last_call (this_call_cnt))
- dht_rmdir_do (main_frame, this);
-
- DHT_STACK_DESTROY (frame);
- return 0;
-}
-
-
-int
-dht_rmdir_cached_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)
-{
- dht_local_t *local = NULL;
- xlator_t *src = NULL;
- call_frame_t *main_frame = NULL;
- dht_local_t *main_local = NULL;
- int this_call_cnt = 0;
- dht_conf_t *conf = this->private;
- dict_t *xattrs = NULL;
- int ret = 0;
-
- local = frame->local;
- src = local->hashed_subvol;
-
- main_frame = local->main_frame;
- main_local = main_frame->local;
-
- if (op_ret == 0) {
- main_local->op_ret = -1;
- main_local->op_errno = ENOTEMPTY;
-
- gf_log (this->name, GF_LOG_WARNING,
- "%s found on cached subvol %s",
- local->loc.path, src->name);
- goto err;
- } else if (op_errno != ENOENT) {
- main_local->op_ret = -1;
- main_local->op_errno = op_errno;
- goto err;
- }
-
- xattrs = dict_new ();
- if (!xattrs) {
- gf_log (this->name, GF_LOG_ERROR, "dict_new failed");
- goto err;
- }
-
- ret = dict_set_uint32 (xattrs, conf->link_xattr_name, 256);
- if (ret) {
- gf_msg (this->name, GF_LOG_ERROR, 0,
- DHT_MSG_DICT_SET_FAILED,
- "Failed to set dictionary value: key = %s",
- conf->link_xattr_name);
- if (xattrs)
- dict_unref (xattrs);
- goto err;
- }
-
- STACK_WIND (frame, dht_rmdir_lookup_cbk,
- src, src->fops->lookup, &local->loc, xattrs);
- if (xattrs)
- dict_unref (xattrs);
-
+ src, src->fops->unlink, &local->loc);
return 0;
err:
@@ -5512,16 +3405,12 @@ int
dht_rmdir_is_subvol_empty (call_frame_t *frame, xlator_t *this,
gf_dirent_t *entries, xlator_t *src)
{
- int ret = 0;
- int build_ret = 0;
- gf_dirent_t *trav = NULL;
+ int ret = 0;
+ int build_ret = 0;
+ gf_dirent_t *trav = NULL;
call_frame_t *lookup_frame = NULL;
dht_local_t *lookup_local = NULL;
- dht_local_t *local = NULL;
- dict_t *xattrs = NULL;
- dht_conf_t *conf = this->private;
- xlator_t *subvol = NULL;
- char gfid[GF_UUID_BUF_SIZE] = {0};
+ dht_local_t *local = NULL;
local = frame->local;
@@ -5530,8 +3419,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,
- conf->link_xattr_name)) {
+ if (check_is_linkfile (NULL, (&trav->d_stat), NULL) == 1) {
ret++;
continue;
}
@@ -5543,24 +3431,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, conf->link_xattr_name, 256);
- if (ret) {
- gf_msg (this->name, GF_LOG_ERROR, 0,
- DHT_MSG_DICT_SET_FAILED,
- "Failed to set dictionary value: key = %s",
- conf->link_xattr_name);
-
- if (xattrs)
- dict_unref (xattrs);
- return -1;
- }
-
list_for_each_entry (trav, &entries->list, list) {
if (strcmp (trav->d_name, ".") == 0)
continue;
@@ -5572,32 +3442,31 @@ dht_rmdir_is_subvol_empty (call_frame_t *frame, xlator_t *this,
lookup_frame = copy_frame (frame);
if (!lookup_frame) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of Memory");
/* out of memory, let the rmdir fail
(as non-empty, unfortunately) */
goto err;
}
- lookup_local = mem_get0 (this->local_pool);
+ lookup_local = CALLOC (sizeof (*local), 1);
if (!lookup_local) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of Memory");
goto err;
}
lookup_frame->local = lookup_local;
lookup_local->main_frame = frame;
- lookup_local->hashed_subvol = src;
build_ret = dht_build_child_loc (this, &lookup_local->loc,
&local->loc, trav->d_name);
if (build_ret != 0)
goto err;
- uuid_copy (lookup_local->loc.gfid, trav->d_stat.ia_gfid);
-
- uuid_unparse(lookup_local->loc.gfid, gfid);
-
- gf_msg_trace (this->name, 0,
- "looking up %s on subvolume %s, gfid = %s",
- lookup_local->loc.path, src->name, gfid);
+ gf_log (this->name, GF_LOG_TRACE,
+ "looking up %s on %s",
+ lookup_local->loc.path, src->name);
LOCK (&frame->lock);
{
@@ -5605,32 +3474,14 @@ dht_rmdir_is_subvol_empty (call_frame_t *frame, xlator_t *this,
}
UNLOCK (&frame->lock);
- subvol = dht_linkfile_subvol (this, NULL, &trav->d_stat,
- trav->dict);
- if (!subvol) {
- gf_log (this->name, GF_LOG_INFO,
- "Linkfile does not have link subvolume. "
- "path = %s, gfid = %s",
- lookup_local->loc.path, gfid);
- STACK_WIND (lookup_frame, dht_rmdir_lookup_cbk,
- src, src->fops->lookup,
- &lookup_local->loc, xattrs);
- } else {
- STACK_WIND (lookup_frame, dht_rmdir_cached_lookup_cbk,
- subvol, subvol->fops->lookup,
- &lookup_local->loc, xattrs);
- }
+ STACK_WIND (lookup_frame, dht_rmdir_lookup_cbk,
+ src, src->fops->lookup,
+ &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;
}
@@ -5638,663 +3489,738 @@ 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;
- call_frame_t *prev = NULL;
+ dht_local_t *local = NULL;
+ int this_call_cnt = -1;
+ call_frame_t *prev = NULL;
xlator_t *src = NULL;
int ret = 0;
- local = frame->local;
- prev = cookie;
+ local = frame->local;
+ prev = cookie;
src = prev->this;
- if (op_ret > 2) {
+ if (op_ret > 2) {
ret = dht_rmdir_is_subvol_empty (frame, this, entries, src);
switch (ret) {
case 0: /* non linkfiles exist */
- gf_msg_trace (this->name, 0,
- "readdir on %s for %s returned %d "
- "entries", prev->this->name,
- local->loc.path, op_ret);
+ gf_log (this->name, GF_LOG_TRACE,
+ "readdir on %s for %s returned %d entries",
+ prev->this->name, local->loc.path, op_ret);
local->op_ret = -1;
local->op_errno = ENOTEMPTY;
break;
default:
/* @ret number of linkfiles are getting unlinked */
- gf_msg_trace (this->name, 0,
- "readdir on %s for %s found %d "
- "linkfiles", prev->this->name,
- local->loc.path, ret);
+ gf_log (this->name, GF_LOG_TRACE,
+ "readdir on %s for %s found %d linkfiles",
+ prev->this->name, local->loc.path, ret);
break;
}
- }
+ }
- this_call_cnt = dht_frame_return (frame);
+ this_call_cnt = dht_frame_return (frame);
- if (is_last_call (this_call_cnt)) {
- dht_rmdir_do (frame, this);
- }
+ if (is_last_call (this_call_cnt)) {
+ dht_rmdir_do (frame, this);
+ }
- return 0;
+ return 0;
}
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;
- dht_conf_t *conf = this->private;
- int i = 0;
- char gfid[GF_UUID_BUF_SIZE] = {0};
-
- local = frame->local;
- prev = cookie;
+ dht_local_t *local = NULL;
+ int this_call_cnt = -1;
+ call_frame_t *prev = NULL;
- this_call_cnt = dht_frame_return (frame);
- if (op_ret == -1) {
- uuid_unparse(local->loc.gfid, gfid);
-
- gf_msg_debug (this->name, 0,
- "opendir on %s for %s failed, "
- "gfid = %s, (%s)",
- prev->this->name, local->loc.path, gfid,
- strerror (op_errno));
- if ((op_errno != ENOENT) && (op_errno != ESTALE)) {
- local->op_ret = -1;
- local->op_errno = op_errno;
- }
- goto err;
- }
-
- if (!is_last_call (this_call_cnt))
- return 0;
-
- if (local->op_ret == -1)
- goto err;
-
- dict = dict_new ();
- if (!dict) {
- local->op_ret = -1;
- local->op_errno = ENOMEM;
- goto err;
- }
-
- ret = dict_set_uint32 (dict, conf->link_xattr_name, 256);
- if (ret)
- gf_msg (this->name, GF_LOG_WARNING, 0,
- DHT_MSG_DICT_SET_FAILED,
- "%s: Failed to set dictionary value:key = %s",
- local->loc.path, conf->link_xattr_name);
-
- local->call_cnt = conf->subvolume_cnt;
- for (i = 0; i < conf->subvolume_cnt; i++) {
- STACK_WIND (frame, dht_rmdir_readdirp_cbk,
- conf->subvolumes[i],
- conf->subvolumes[i]->fops->readdirp,
- local->fd, 4096, 0, dict);
- }
+ local = frame->local;
+ prev = cookie;
+
+ if (op_ret == -1) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "opendir on %s for %s failed (%s)",
+ prev->this->name, local->loc.path,
+ strerror (op_errno));
+ goto err;
+ }
- if (dict)
- dict_unref (dict);
+ STACK_WIND (frame, dht_rmdir_readdirp_cbk,
+ prev->this, prev->this->fops->readdirp,
+ local->fd, 4096, 0);
- return 0;
+ return 0;
err:
- if (is_last_call (this_call_cnt)) {
- dht_rmdir_do (frame, this);
- }
+ this_call_cnt = dht_frame_return (frame);
- return 0;
+ if (is_last_call (this_call_cnt)) {
+ dht_rmdir_do (frame, this);
+ }
+
+ return 0;
}
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)
{
- dht_local_t *local = NULL;
- dht_conf_t *conf = NULL;
+ dht_local_t *local = NULL;
+ dht_conf_t *conf = NULL;
int op_errno = -1;
- int i = -1;
+ int i = -1;
+ int ret = -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);
- VALIDATE_OR_GOTO (this->private, err);
- conf = this->private;
+ conf = this->private;
- local = dht_local_init (frame, loc, NULL, GF_FOP_RMDIR);
- if (!local) {
- op_errno = ENOMEM;
- goto err;
- }
-
- local->call_cnt = conf->subvolume_cnt;
- local->op_ret = 0;
- local->fop_succeeded = 0;
+ local = dht_local_init (frame);
+ if (!local) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory");
+ op_errno = ENOMEM;
+ goto err;
+ }
- local->flags = flags;
+ local->call_cnt = conf->subvolume_cnt;
+ local->op_ret = 0;
- local->fd = fd_create (local->loc.inode, frame->root->pid);
- if (!local->fd) {
+ ret = loc_copy (&local->loc, loc);
+ if (ret == -1) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory");
+ op_errno = ENOMEM;
+ goto err;
+ }
- op_errno = ENOMEM;
- goto err;
- }
+ local->fd = fd_create (local->loc.inode, frame->root->pid);
+ if (!local->fd) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory");
+ op_errno = ENOMEM;
+ goto err;
+ }
- for (i = 0; i < conf->subvolume_cnt; i++) {
- STACK_WIND (frame, dht_rmdir_opendir_cbk,
- conf->subvolumes[i],
- conf->subvolumes[i]->fops->opendir,
- loc, local->fd, NULL);
- }
+ for (i = 0; i < conf->subvolume_cnt; i++) {
+ STACK_WIND (frame, dht_rmdir_opendir_cbk,
+ conf->subvolumes[i],
+ conf->subvolumes[i]->fops->opendir,
+ loc, local->fd);
+ }
- return 0;
+ return 0;
err:
- op_errno = (op_errno == -1) ? errno : op_errno;
- DHT_STACK_UNWIND (rmdir, frame, -1, op_errno,
- NULL, NULL, NULL);
+ op_errno = (op_errno == -1) ? errno : op_errno;
+ DHT_STACK_UNWIND (rmdir, frame, -1, op_errno,
+ NULL, NULL);
- return 0;
+ 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)
+int
+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 (entrylk, frame, op_ret, op_errno, xdata);
- return 0;
+ DHT_STACK_UNWIND (xattrop, frame, op_ret, op_errno, dict);
+ 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_xattrop (call_frame_t *frame, xlator_t *this, loc_t *loc,
+ gf_xattrop_flags_t flags, dict_t *dict)
{
- xlator_t *subvol = NULL;
+ xlator_t *subvol = NULL;
int op_errno = -1;
- dht_local_t *local = NULL;
- char gfid[GF_UUID_BUF_SIZE] = {0};
+ 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);
- if (!local) {
- op_errno = ENOMEM;
- goto 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;
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory");
+ goto err;
+ }
- subvol = local->cached_subvol;
- if (!subvol) {
- uuid_unparse(loc->gfid, gfid);
+ local->inode = inode_ref (loc->inode);
+ local->call_cnt = 1;
- gf_msg_debug (this->name, 0,
- "no cached subvolume for path=%s, "
- "gfid = %s", loc->path, gfid);
- op_errno = EINVAL;
- goto err;
- }
+ STACK_WIND (frame,
+ dht_xattrop_cbk,
+ subvol, subvol->fops->xattrop,
+ loc, flags, dict);
- local->call_cnt = 1;
+ return 0;
- STACK_WIND (frame, dht_entrylk_cbk,
- subvol, subvol->fops->entrylk,
- volume, loc, basename, cmd, type, xdata);
+err:
+ op_errno = (op_errno == -1) ? errno : op_errno;
+ DHT_STACK_UNWIND (xattrop, frame, -1, op_errno, NULL);
- return 0;
+ 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)
+{
+ 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 (entrylk, frame, -1, op_errno, NULL);
+ op_errno = (op_errno == -1) ? errno : op_errno;
+ DHT_STACK_UNWIND (fxattrop, frame, -1, op_errno, NULL);
- return 0;
+ return 0;
}
int
-dht_fentrylk_cbk (call_frame_t *frame, void *cookie,
- xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata)
+dht_inodelk_cbk (call_frame_t *frame, void *cookie,
+ xlator_t *this, int32_t op_ret, int32_t op_errno)
{
- DHT_STACK_UNWIND (fentrylk, frame, op_ret, op_errno, NULL);
- return 0;
+ DHT_STACK_UNWIND (inodelk, frame, op_ret, op_errno);
+ return 0;
}
-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)
+int32_t
+dht_inodelk (call_frame_t *frame, xlator_t *this,
+ const char *volume, loc_t *loc, int32_t cmd, struct flock *lock)
{
- xlator_t *subvol = NULL;
+ xlator_t *subvol = NULL;
int op_errno = -1;
- char gfid[GF_UUID_BUF_SIZE] = {0};
+ dht_local_t *local = NULL;
VALIDATE_OR_GOTO (frame, err);
VALIDATE_OR_GOTO (this, err);
- VALIDATE_OR_GOTO (fd, err);
- VALIDATE_OR_GOTO(fd->inode, err);
+ VALIDATE_OR_GOTO (loc, err);
+ VALIDATE_OR_GOTO (loc->inode, err);
+ VALIDATE_OR_GOTO (loc->path, err);
- uuid_unparse(fd->inode->gfid, gfid);
+ 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;
+ }
- subvol = dht_subvol_get_cached (this, fd->inode);
- if (!subvol) {
- gf_msg_debug (this->name, 0,
- "No cached subvolume for fd=%p,"
- " gfid = %s", fd, gfid);
- op_errno = EINVAL;
- goto err;
- }
+ local = dht_local_init (frame);
+ if (!local) {
+ op_errno = ENOMEM;
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory");
+ goto err;
+ }
- STACK_WIND (frame, dht_fentrylk_cbk,
- subvol, subvol->fops->fentrylk,
- volume, fd, basename, cmd, type, xdata);
+ local->inode = inode_ref (loc->inode);
+ local->call_cnt = 1;
- return 0;
+ 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 (fentrylk, frame, -1, op_errno, NULL);
+ op_errno = (op_errno == -1) ? errno : op_errno;
+ DHT_STACK_UNWIND (inodelk, frame, -1, op_errno);
- return 0;
+ return 0;
}
int
-dht_forget (xlator_t *this, inode_t *inode)
+dht_finodelk_cbk (call_frame_t *frame, void *cookie,
+ xlator_t *this, int32_t op_ret, int32_t op_errno)
+
{
- uint64_t ctx_int = 0;
- dht_inode_ctx_t *ctx = NULL;
- dht_layout_t *layout = NULL;
+ DHT_STACK_UNWIND (finodelk, frame, op_ret, op_errno);
+ return 0;
+}
- inode_ctx_del (inode, this, &ctx_int);
- if (!ctx_int)
- return 0;
+int
+dht_finodelk (call_frame_t *frame, xlator_t *this,
+ const char *volume, fd_t *fd, int32_t cmd, struct flock *lock)
+{
+ xlator_t *subvol = NULL;
+ int op_errno = -1;
- ctx = (dht_inode_ctx_t *) (long) ctx_int;
+ VALIDATE_OR_GOTO (frame, err);
+ VALIDATE_OR_GOTO (this, err);
+ VALIDATE_OR_GOTO (fd, err);
- layout = ctx->layout;
- ctx->layout = NULL;
- dht_layout_unref (this, layout);
- GF_FREE (ctx);
+ 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;
+ }
- return 0;
+
+ 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_notify (xlator_t *this, int event, void *data, ...)
+dht_entrylk_cbk (call_frame_t *frame, void *cookie,
+ xlator_t *this, int32_t op_ret, int32_t op_errno)
+
{
- 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;
+ DHT_STACK_UNWIND (entrylk, frame, op_ret, op_errno);
+ return 0;
+}
- conf = this->private;
- if (!conf)
- return ret;
+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;
- /* had all subvolumes reported status once till now? */
- had_heard_from_all = 1;
- for (i = 0; i < conf->subvolume_cnt; i++) {
- if (!conf->last_event[i]) {
- had_heard_from_all = 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);
- switch (event) {
- case GF_EVENT_CHILD_UP:
- subvol = data;
+ 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;
+ }
- conf->gen++;
+ local = dht_local_init (frame);
+ if (!local) {
+ op_errno = ENOMEM;
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory");
+ goto err;
+ }
- for (i = 0; i < conf->subvolume_cnt; i++) {
- if (subvol == conf->subvolumes[i]) {
- cnt = i;
- break;
- }
- }
+ local->inode = inode_ref (loc->inode);
+ local->call_cnt = 1;
- if (cnt == -1) {
- gf_msg_debug (this->name, 0,
- "got GF_EVENT_CHILD_UP bad "
- "subvolume %s",
- subvol->name);
- break;
- }
+ STACK_WIND (frame, dht_entrylk_cbk,
+ subvol, subvol->fops->entrylk,
+ volume, loc, basename, cmd, type);
- 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);
+ return 0;
- /* one of the node came back up, do a stat update */
- dht_get_du_info_for_subvol (this, cnt);
+err:
+ op_errno = (op_errno == -1) ? errno : op_errno;
+ DHT_STACK_UNWIND (entrylk, frame, -1, op_errno);
- break;
+ return 0;
+}
- case GF_EVENT_CHILD_MODIFIED:
- subvol = data;
- conf->gen++;
- propagate = 1;
+int
+dht_fentrylk_cbk (call_frame_t *frame, void *cookie,
+ xlator_t *this, int32_t op_ret, int32_t op_errno)
- break;
+{
+ DHT_STACK_UNWIND (fentrylk, frame, op_ret, op_errno);
+ return 0;
+}
- case GF_EVENT_CHILD_DOWN:
- subvol = 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,
- GF_DEFRAG_STATUS_FAILED, NULL);
- } else {
- kill (getpid(), SIGTERM);
- }
- }
+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)
+{
+ xlator_t *subvol = NULL;
+ int op_errno = -1;
- for (i = 0; i < conf->subvolume_cnt; i++) {
- if (subvol == conf->subvolumes[i]) {
- cnt = i;
- break;
- }
- }
+ VALIDATE_OR_GOTO (frame, err);
+ VALIDATE_OR_GOTO (this, err);
+ VALIDATE_OR_GOTO (fd, err);
- if (cnt == -1) {
- gf_msg_debug (this->name, 0,
- "got GF_EVENT_CHILD_DOWN bad "
- "subvolume %s", subvol->name);
- break;
- }
+ 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;
+ }
- LOCK (&conf->subvolume_lock);
- {
- conf->subvolume_status[cnt] = 0;
- conf->last_event[cnt] = event;
- conf->subvol_up_time[cnt] = 0;
- }
- UNLOCK (&conf->subvolume_lock);
+ STACK_WIND (frame, dht_fentrylk_cbk,
+ subvol, subvol->fops->fentrylk,
+ volume, fd, basename, cmd, type);
- break;
+ return 0;
- case GF_EVENT_CHILD_CONNECTING:
- subvol = data;
+err:
+ op_errno = (op_errno == -1) ? errno : op_errno;
+ DHT_STACK_UNWIND (fentrylk, frame, -1, op_errno);
- for (i = 0; i < conf->subvolume_cnt; i++) {
- if (subvol == conf->subvolumes[i]) {
- cnt = i;
- break;
- }
- }
+ return 0;
+}
- if (cnt == -1) {
- gf_msg_debug (this->name, 0,
- "got GF_EVENT_CHILD_CONNECTING"
- " bad subvolume %s",
- subvol->name);
- break;
- }
- LOCK (&conf->subvolume_lock);
- {
- conf->last_event[cnt] = event;
- }
- UNLOCK (&conf->subvolume_lock);
+int
+dht_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int op_ret, int op_errno, struct stat *statpre,
+ struct stat *statpost)
+{
+ dht_local_t *local = NULL;
+ int this_call_cnt = 0;
+ call_frame_t *prev = NULL;
- 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*);
+ 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;
+ }
- 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,
- GF_DEFRAG_STATUS_STOPPED, output);
+ dht_stat_merge (this, &local->prebuf, statpre, prev->this);
+ dht_stat_merge (this, &local->stbuf, statpost, prev->this);
+
+ if (local->inode) {
+ local->prebuf.st_ino = local->inode->ino;
+ local->stbuf.st_ino = local->inode->ino;
}
+
+ local->op_ret = 0;
+ }
unlock:
- UNLOCK (&defrag->lock);
- return 0;
- break;
- }
+ UNLOCK (&frame->lock);
- default:
- propagate = 1;
- break;
- }
+ 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;
+}
- /* have all subvolumes reported status once by now? */
- have_heard_from_all = 1;
- for (i = 0; i < conf->subvolume_cnt; i++) {
- if (!conf->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;
+int
+dht_setattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
+ struct stat *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);
- 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;
+ local = dht_local_init (frame);
+ if (!local) {
+ op_errno = ENOMEM;
+ gf_log (this->name, GF_LOG_DEBUG,
+ "memory allocation failed :(");
+ goto err;
+ }
- for (i = 0; i < conf->subvolume_cnt; i++) {
- if (conf->last_event[i] == GF_EVENT_CHILD_UP) {
- event = GF_EVENT_CHILD_UP;
- break;
- }
+ 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 (conf->last_event[i] == GF_EVENT_CHILD_CONNECTING) {
- event = GF_EVENT_CHILD_CONNECTING;
- /* continue to check other events for CHILD_UP */
- }
- }
+ 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;
+ }
- /* rebalance is started with assert_no_child_down. So we do
- * not need to handle CHILD_DOWN event here.
- */
- if (conf->defrag) {
- ret = gf_thread_create (&conf->defrag->th, NULL,
- gf_defrag_start, this);
- if (ret) {
- conf->defrag = NULL;
- GF_FREE (conf->defrag);
- kill (getpid(), SIGTERM);
- }
- }
- }
+ local->inode = inode_ref (loc->inode);
+ local->call_cnt = layout->cnt;
- ret = 0;
- if (propagate)
- ret = default_notify (this, event, data);
+ 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 ret;
+ 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_inode_ctx_layout_get (inode_t *inode, xlator_t *this, dht_layout_t **layout)
+dht_fsetattr (call_frame_t *frame, xlator_t *this, fd_t *fd, struct stat *stbuf,
+ int32_t valid)
{
- dht_inode_ctx_t *ctx = NULL;
- int ret = -1;
+ dht_layout_t *layout = NULL;
+ dht_local_t *local = NULL;
+ int op_errno = -1;
+ int i = -1;
- ret = dht_inode_ctx_get (inode, this, &ctx);
- if (!ret && ctx) {
- if (ctx->layout) {
- if (layout)
- *layout = ctx->layout;
- ret = 0;
- } else {
- ret = -1;
- }
- }
+ VALIDATE_OR_GOTO (frame, err);
+ VALIDATE_OR_GOTO (this, err);
+ VALIDATE_OR_GOTO (fd, err);
- return ret;
+ local = dht_local_init (frame);
+ if (!local) {
+ op_errno = ENOMEM;
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory");
+ 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;
}
-void
-dht_log_new_layout_for_dir_selfheal (xlator_t *this, loc_t *loc,
- dht_layout_t *layout)
+
+int
+dht_forget (xlator_t *this, inode_t *inode)
{
+ uint64_t tmp_layout = 0;
+ dht_layout_t *layout = NULL;
- char string[2048] = {0};
- char *output_string = NULL;
- int len = 0;
- int off = 0;
- int i = 0;
- gf_loglevel_t log_level = gf_log_get_loglevel();
- int ret = 0;
- int max_string_len = 0;
+ inode_ctx_get (inode, this, &tmp_layout);
- if (log_level < GF_LOG_INFO)
- return;
+ if (!tmp_layout)
+ return 0;
- if (!layout)
- return;
+ layout = (dht_layout_t *)(long)tmp_layout;
+ dht_layout_unref (this, layout);
- if (!layout->cnt)
- return;
+ return 0;
+}
- if (!loc)
- return;
- if (!loc->path)
- return;
- max_string_len = sizeof (string);
+int
+dht_init_subvolumes (xlator_t *this, dht_conf_t *conf)
+{
+ xlator_list_t *subvols = NULL;
+ int cnt = 0;
- ret = snprintf (string, max_string_len, "Setting layout of %s with ",
- loc->path);
- if (ret < 0)
- return;
+ for (subvols = this->children; subvols; subvols = subvols->next)
+ cnt++;
- len += ret;
+ conf->subvolumes = CALLOC (cnt, sizeof (xlator_t *));
+ if (!conf->subvolumes) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory");
+ return -1;
+ }
+ conf->subvolume_cnt = cnt;
- /* Calculation of total length of the string required to calloc
- * output_string. Log includes subvolume-name, start-range, end-range and
- * err value.
- *
- * This log will help to debug cases where:
- * a) Different processes set different layout of a directory.
- * b) Error captured in lookup, which will be filled in layout->err
- * (like ENOENT, ESTALE etc)
- */
+ cnt = 0;
+ for (subvols = this->children; subvols; subvols = subvols->next)
+ conf->subvolumes[cnt++] = subvols->xlator;
- for (i = 0; i < layout->cnt; i++) {
+ conf->subvolume_status = CALLOC (cnt, sizeof (char));
+ if (!conf->subvolume_status) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory");
+ return -1;
+ }
- ret = snprintf (string, max_string_len,
- "[Subvol_name: %s, Err: %d , Start: "
- "%"PRIu32 " , Stop: %"PRIu32 " ], ",
- layout->list[i].xlator->name,
- layout->list[i].err, layout->list[i].start,
- layout->list[i].stop);
+ return 0;
+}
- if (ret < 0)
- return;
- len += ret;
+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;
- }
- len++;
+ conf = this->private;
- output_string = GF_CALLOC (len, sizeof (char), gf_common_mt_char);
+ switch (event) {
+ case GF_EVENT_CHILD_UP:
+ subvol = data;
- if (!output_string)
- return;
+ conf->gen++;
- ret = snprintf (output_string, len, "Setting layout of %s with ",
- loc->path);
+ for (i = 0; i < conf->subvolume_cnt; i++) {
+ if (subvol == conf->subvolumes[i]) {
+ cnt = i;
+ break;
+ }
+ }
- if (ret < 0)
- goto err;
+ if (cnt == -1) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "got GF_EVENT_CHILD_UP bad subvolume %s",
+ subvol->name);
+ break;
+ }
- off += ret;
+ LOCK (&conf->subvolume_lock);
+ {
+ conf->subvolume_status[cnt] = 1;
+ }
+ UNLOCK (&conf->subvolume_lock);
+ /* one of the node came back up, do a stat update */
+ dht_get_du_info_for_subvol (this, cnt);
- for (i = 0; i < layout->cnt; i++) {
+ break;
- ret = snprintf (output_string + off, len - off,
- "[Subvol_name: %s, Err: %d , Start: "
- "%"PRIu32 " , Stop: %"PRIu32 " ], ",
- layout->list[i].xlator->name,
- layout->list[i].err, layout->list[i].start,
- layout->list[i].stop);
+ case GF_EVENT_CHILD_DOWN:
+ subvol = data;
- if (ret < 0)
- goto err;
+ for (i = 0; i < conf->subvolume_cnt; i++) {
+ if (subvol == conf->subvolumes[i]) {
+ cnt = i;
+ break;
+ }
+ }
- off += ret;
+ if (cnt == -1) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "got GF_EVENT_CHILD_DOWN bad subvolume %s",
+ subvol->name);
+ break;
+ }
- }
+ LOCK (&conf->subvolume_lock);
+ {
+ conf->subvolume_status[cnt] = 0;
+ }
+ UNLOCK (&conf->subvolume_lock);
- gf_msg (this->name, GF_LOG_INFO, 0, DHT_MSG_LOG_FIXED_LAYOUT,
- "%s", output_string);
+ break;
+ }
-err:
- GF_FREE (output_string);
+ 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 0a0ce52f3da..bcbf0026a18 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>
- 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-2009 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
@@ -13,884 +22,255 @@
#include "config.h"
#endif
-#include <regex.h>
-#include <signal.h>
-
-#include "dht-mem-types.h"
-#include "dht-messages.h"
-#include "libxlator.h"
-#include "syncop.h"
-
#ifndef _DHT_H
#define _DHT_H
-#define GF_XATTR_FIX_LAYOUT_KEY "distribute.fix.layout"
#define GF_DHT_LOOKUP_UNHASHED_ON 1
#define GF_DHT_LOOKUP_UNHASHED_AUTO 2
-#define DHT_PATHINFO_HEADER "DISTRIBUTE:"
-#define DHT_FILE_MIGRATE_DOMAIN "dht.file.migrate"
-
-#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 */
- gf_boolean_t 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;
- } list[];
-};
-typedef struct dht_layout dht_layout_t;
-
-struct dht_stat_time {
- uint32_t atime;
- uint32_t atime_nsec;
- uint32_t ctime;
- uint32_t ctime_nsec;
- uint32_t mtime;
- uint32_t mtime_nsec;
-};
-
-typedef struct dht_stat_time dht_stat_time_t;
-
-struct dht_inode_ctx {
- dht_layout_t *layout;
- dht_stat_time_t time;
+ 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_inode_ctx dht_inode_ctx_t;
+typedef struct dht_layout dht_layout_t;
typedef enum {
- DHT_HASH_TYPE_DM,
- DHT_HASH_TYPE_DM_USER,
+ DHT_HASH_TYPE_DM,
} 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;
-};
-
-/**
- * Enum to store decided action based on the qdstatfs (quota-deem-statfs)
- * events
- **/
-typedef enum {
- qdstatfs_action_OFF = 0,
- qdstatfs_action_REPLACE,
- qdstatfs_action_NEGLECT,
- qdstatfs_action_COMPARE,
-} qdstatfs_action_t;
-
-struct dht_skip_linkto_unlink {
-
- gf_boolean_t handle_valid_link;
- int opend_fd_count;
- xlator_t *hash_links_to;
- uuid_t cached_gfid;
- uuid_t hashed_gfid;
-};
-
-typedef struct {
- xlator_t *xl;
- loc_t loc; /* contains/points to inode to lock on. */
- short type; /* read/write lock. */
- char *domain; /* Only locks within a single domain
- * contend with each other
- */
- gf_boolean_t locked;
-} dht_lock_t;
struct dht_local {
- int call_cnt;
- loc_t loc;
- loc_t loc2;
- int op_ret;
- int op_errno;
- int layout_mismatch;
+ int call_cnt;
+ loc_t loc;
+ loc_t loc2;
+ int op_ret;
+ int op_errno;
+ int layout_mismatch;
/* Use stbuf as the postbuf, when we require both
* pre and post attrs */
- struct iatt stbuf;
- struct iatt prebuf;
- struct iatt preoldparent;
- struct iatt postoldparent;
- struct iatt preparent;
- struct iatt postparent;
- struct statvfs statvfs;
- fd_t *fd;
- inode_t *inode;
- dict_t *params;
- dict_t *xattr;
- dict_t *xattr_req;
- dht_layout_t *layout;
- size_t size;
- ino_t ia_ino;
- xlator_t *src_hashed, *src_cached;
- xlator_t *dst_hashed, *dst_cached;
- xlator_t *cached_subvol;
- xlator_t *hashed_subvol;
- char need_selfheal;
+ struct stat stbuf;
+ struct stat prebuf;
+ struct stat preoldparent;
+ struct stat postoldparent;
+ struct stat preparent;
+ struct stat postparent;
+ struct statvfs statvfs;
+ fd_t *fd;
+ inode_t *inode;
+ dict_t *xattr;
+ dict_t *xattr_req;
+ dht_layout_t *layout;
+ size_t size;
+ ino_t st_ino;
+ ino_t st_dev;
+ xlator_t *src_hashed, *src_cached;
+ xlator_t *dst_hashed, *dst_cached;
+ xlator_t *cached_subvol;
+ xlator_t *hashed_subvol;
+ char need_selfheal;
int file_count;
int dir_count;
call_frame_t *main_frame;
- int fop_succeeded;
- struct {
- fop_mknod_cbk_t linkfile_cbk;
- struct iatt stbuf;
- loc_t loc;
- inode_t *inode;
- dict_t *xattr;
- xlator_t *srcvol;
- } linkfile;
- struct {
- uint32_t hole_cnt;
- uint32_t overlaps_cnt;
- uint32_t down;
- uint32_t misc;
- dht_selfheal_dir_cbk_t dir_cbk;
- dht_layout_t *layout;
- } selfheal;
- uint32_t uid;
- uint32_t gid;
-
- /* needed by nufa */
- int32_t flags;
- mode_t mode;
- dev_t rdev;
- mode_t umask;
-
- /* need for file-info */
- char *xattr_val;
- char *key;
-
- /* which xattr request? */
- char xsel[256];
- int32_t alloc_len;
-
- char *newpath;
-
- /* gfid related */
- uuid_t gfid;
-
- /*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;
-
- gf_boolean_t linked;
- xlator_t *link_subvol;
-
- struct dht_rebalance_ rebalance;
- xlator_t *first_up_subvol;
-
- gf_boolean_t quota_deem_statfs;
-
- gf_boolean_t added_link;
- gf_boolean_t is_linkfile;
-
- struct dht_skip_linkto_unlink skip_unlink;
-
- struct {
- fop_inodelk_cbk_t inodelk_cbk;
- dht_lock_t **locks;
- int lk_count;
-
- /* whether locking failed on _any_ of the "locks" above */
- int op_ret;
- int op_errno;
- } lock;
+ struct {
+ fop_mknod_cbk_t linkfile_cbk;
+ struct stat stbuf;
+ loc_t loc;
+ inode_t *inode;
+ dict_t *xattr;
+ xlator_t *srcvol;
+ } linkfile;
+ struct {
+ uint32_t hole_cnt;
+ uint32_t overlaps_cnt;
+ uint32_t missing;
+ uint32_t down;
+ uint32_t misc;
+ dht_selfheal_dir_cbk_t dir_cbk;
+ dht_layout_t *layout;
+ } selfheal;
+
+ /* needed by nufa */
+ int32_t flags;
+ mode_t mode;
+ dev_t rdev;
};
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;
- uint32_t chunks;
};
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,
- GF_DEFRAG_STATUS_LAYOUT_FIX_STARTED,
- GF_DEFRAG_STATUS_LAYOUT_FIX_STOPPED,
- GF_DEFRAG_STATUS_LAYOUT_FIX_COMPLETE,
- GF_DEFRAG_STATUS_LAYOUT_FIX_FAILED,
-};
-typedef enum gf_defrag_status_t gf_defrag_status_t;
-
-typedef struct gf_defrag_pattern_list gf_defrag_pattern_list_t;
-
-struct gf_defrag_pattern_list {
- char path_pattern[256];
- uint64_t size;
- gf_defrag_pattern_list_t *next;
-};
-
-struct gf_defrag_info_ {
- uint64_t total_files;
- uint64_t total_data;
- uint64_t num_files_lookedup;
- uint64_t total_failures;
- uint64_t skipped;
- 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;
- gf_defrag_pattern_list_t *defrag_pattern;
-};
-
-typedef struct gf_defrag_info_ gf_defrag_info_t;
-
struct dht_conf {
- gf_lock_t subvolume_lock;
+ gf_lock_t subvolume_lock;
int subvolume_cnt;
xlator_t **subvolumes;
- char *subvolume_status;
- int *last_event;
- dht_layout_t **file_layouts;
- dht_layout_t **dir_layouts;
- gf_boolean_t search_unhashed;
- int gen;
+ char *subvolume_status;
+ 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;
- double min_free_disk;
- double min_free_inodes;
+ uint64_t min_free_disk;
char disk_unit;
int32_t refresh_interval;
gf_boolean_t unhashed_sticky_bit;
- struct timeval last_stat_fetch;
+ struct timeval last_stat_fetch;
gf_lock_t layout_lock;
void *private; /* Can be used by wrapper xlators over
dht */
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;
- int decommission_subvols_cnt;
-
- /* defrag related */
- gf_defrag_info_t *defrag;
-
- /* Request to filter directory entries in readdir request */
-
- gf_boolean_t readdir_optimize;
-
- /* Support regex-based name reinterpretation. */
- regex_t rsync_regex;
- gf_boolean_t rsync_regex_valid;
- regex_t extra_regex;
- gf_boolean_t extra_regex_valid;
-
- /* Support variable xattr names. */
- char *xattr_name;
- char *link_xattr_name;
- char *wild_xattr_name;
-
- /* Support size-weighted rebalancing (heterogeneous bricks). */
- gf_boolean_t do_weighting;
- gf_boolean_t randomize_by_gfid;
-
- struct mem_pool *lock_pool;
};
typedef struct dht_conf dht_conf_t;
struct dht_disk_layout {
- uint32_t cnt;
- uint32_t type;
- struct {
- uint32_t start;
- uint32_t stop;
- } list[1];
+ uint32_t cnt;
+ uint32_t type;
+ struct {
+ uint32_t start;
+ uint32_t stop;
+ } list[1];
};
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 ENTRY_MISSING(op_ret, op_errno) (op_ret == -1 && op_errno == ENOENT)
-#define is_revalidate(loc) (dht_inode_ctx_layout_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 check_is_linkfile(i,s,x,n) (IS_DHT_LINKFILE_MODE (s) && dict_get (x, n))
+#define is_fs_root(loc) (strcmp (loc->path, "/") == 0)
-#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_revalidate(loc) (inode_ctx_get (loc->inode, this, NULL) == 0)
-#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)
+#define is_last_call(cnt) (cnt == 0)
-#define dht_inode_missing(op_errno) (op_errno == ENOENT || op_errno == ESTALE)
+#define DHT_LINKFILE_MODE (S_ISVTX)
+#define check_is_linkfile(i,s,x) ( \
+ ((s->st_mode & ~S_IFMT) == DHT_LINKFILE_MODE) && \
+ (s->st_size == 0))
-#define check_is_dir(i,s,x) (IA_ISDIR(s->ia_type))
+#define check_is_dir(i,s,x) (S_ISDIR(s->st_mode))
#define layout_is_sane(layout) ((layout) && (layout->cnt > 0))
#define DHT_STACK_UNWIND(fop, frame, params ...) do { \
- dht_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); \
- 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); \
- } while (0)
-
-#define DHT_UPDATE_TIME(ctx_sec, ctx_nsec, new_sec, new_nsec, inode, post) do {\
- LOCK (&inode->lock); \
- { \
- if (ctx_sec == new_sec) \
- new_nsec = max (new_nsec, ctx_nsec); \
- else if (ctx_sec > new_sec) { \
- new_sec = ctx_sec; \
- new_nsec = ctx_nsec; \
- } \
- if (post) { \
- ctx_sec = new_sec; \
- ctx_nsec = new_nsec; \
- } \
- } \
- UNLOCK (&inode->lock); \
- } while (0)
-
-#define is_greater_time(a, an, b, bn) (((a) < (b)) || (((a) == (b)) && ((an) < (bn))))
-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, uint32_t *no_space_p);
-int dht_layout_dir_mismatch (xlator_t *this, dht_layout_t *layout,
- xlator_t *subvol, loc_t *loc, dict_t *xattr);
+ dht_local_t *__local = NULL; \
+ xlator_t *__xl = NULL; \
+ __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); \
+ } 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,
+ 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);
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);
+ struct stat *buf, dict_t *xattr);
+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, int32_t *disk_layout);
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);
+ 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_stat_merge (xlator_t *this, struct stat *to, struct stat *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);
-xlator_t *dht_subvol_next_available (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 (xlator_t *this, int type, const char *name, uint32_t *hash_p);
+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 *this, 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);
-
-int
-dht_selfheal_directory_for_nameless_lookup (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);
+ 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);
-xlator_t *dht_free_disk_available_subvol (xlator_t *this, xlator_t *subvol,
- dht_local_t *layout);
-int dht_get_du_info_for_subvol (xlator_t *this, int subvol_idx);
+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_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);
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,
- xlator_t **subvol);
-
-int dht_rename_cleanup (call_frame_t *frame);
-int dht_rename_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);
-
-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_fallocate(call_frame_t *frame, xlator_t *this, fd_t *fd,
- int32_t mode, off_t offset, size_t len, dict_t *xdata);
-int32_t dht_discard(call_frame_t *frame, xlator_t *this, fd_t *fd,
- off_t offset, size_t len, dict_t *xdata);
-int32_t dht_zerofill(call_frame_t *frame, xlator_t *this, fd_t *fd,
- off_t offset, off_t len, dict_t *xdata);
-
-int32_t dht_init (xlator_t *this);
-void dht_fini (xlator_t *this);
-int dht_reconfigure (xlator_t *this, dict_t *options);
-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, gf_defrag_status_t status,
- 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);
-int
-dht_inode_ctx_layout_get (inode_t *inode, xlator_t *this,
- dht_layout_t **layout_int);
-int
-dht_inode_ctx_layout_set (inode_t *inode, xlator_t *this,
- dht_layout_t* layout_int);
-int
-dht_inode_ctx_time_update (inode_t *inode, xlator_t *this, struct iatt *stat,
- int32_t update_ctx);
-void dht_inode_ctx_time_set (inode_t *inode, xlator_t *this, struct iatt *stat);
-
-int dht_inode_ctx_get (inode_t *inode, xlator_t *this, dht_inode_ctx_t **ctx);
-int dht_inode_ctx_set (inode_t *inode, xlator_t *this, dht_inode_ctx_t *ctx);
-int
-dht_dir_attr_heal (void *data);
-int
-dht_dir_attr_heal_done (int ret, call_frame_t *sync_frame, void *data);
-int
-dht_dir_has_layout (dict_t *xattr, char *name);
-gf_boolean_t
-dht_is_subvol_in_layout (dht_layout_t *layout, xlator_t *xlator);
-xlator_t *
-dht_subvol_with_free_space_inodes (xlator_t *this, xlator_t *subvol,
- dht_layout_t *layout);
-xlator_t *
-dht_subvol_maxspace_nonzeroinode (xlator_t *this, xlator_t *subvol,
- dht_layout_t *layout);
-int
-dht_linkfile_attr_heal (call_frame_t *frame, xlator_t *this);
-
-void
-dht_layout_dump (dht_layout_t *layout, const char *prefix);
-int32_t
-dht_priv_dump (xlator_t *this);
-int32_t
-dht_inodectx_dump (xlator_t *this, inode_t *inode);
-
-int
-dht_inode_ctx_get1 (xlator_t *this, inode_t *inode, xlator_t **subvol);
-
-int
-dht_subvol_status (dht_conf_t *conf, xlator_t *subvol);
-
-void
-dht_log_new_layout_for_dir_selfheal (xlator_t *this, loc_t *loc,
- dht_layout_t *layout);
-int
-dht_lookup_everywhere_done (call_frame_t *frame, xlator_t *this);
-
-int
-dht_fill_dict_to_avoid_unlink_of_migrating_file (dict_t *dict);
-
-
-/* Acquire non-blocking inodelk on a list of xlators.
- *
- * @lk_array: array of lock requests lock on.
- *
- * @lk_count: number of locks in @lk_array
- *
- * @inodelk_cbk: will be called after inodelk replies are received
- *
- * @retval: -1 if stack_winding inodelk fails. 0 otherwise.
- * inodelk_cbk is called with appropriate error on errors.
- * On failure to acquire lock on all members of list, successful
- * locks are unlocked before invoking cbk.
- */
-
-int
-dht_nonblocking_inodelk (call_frame_t *frame, dht_lock_t **lk_array,
- int lk_count, fop_inodelk_cbk_t inodelk_cbk);
-
-/* same as dht_nonblocking_inodelk, but issues sequential blocking locks on
- * @lk_array directly. locks are issued on some order which remains same
- * for a list of xlators (irrespective of order of xlators within list).
- */
-int
-dht_blocking_inodelk (call_frame_t *frame, dht_lock_t **lk_array,
- int lk_count, fop_inodelk_cbk_t inodelk_cbk);
-
-int32_t
-dht_unlock_inodelk (call_frame_t *frame, dht_lock_t **lk_array, int lk_count,
- fop_inodelk_cbk_t inodelk_cbk);
-
-dht_lock_t *
-dht_lock_new (xlator_t *this, xlator_t *xl, loc_t *loc, short type,
- const char *domain);
-void
-dht_lock_array_free (dht_lock_t **lk_array, int count);
-
-#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 a2dc43c32aa..a7acf8e41f1 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>
- 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) 2009 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/>.
*/
@@ -19,92 +28,58 @@
#include "glusterfs.h"
#include "xlator.h"
#include "dht-common.h"
-#include "dht-messages.h"
#include "defaults.h"
#include <sys/time.h>
+static int gf_log_subvol_full;
-int
+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;
+ dht_local_t *local = 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;
- uint32_t bpc; /* blocks per chunk */
- uint32_t chunks = 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_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);
- /*
- * A 32-bit count of 1MB chunks allows a maximum brick size of
- * ~4PB. It's possible that we could see a single local FS
- * bigger than that some day, but this code is likely to be
- * irrelevant by then. Meanwhile, it's more important to keep
- * the chunk size small so the layout-calculation code that
- * uses this value can be tested on normal machines.
- */
- bpc = (1 << 20) / statvfs->f_bsize;
- chunks = (statvfs->f_blocks + bpc - 1) / bpc;
- }
-
- 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. The rationale is that distribute need not
- * worry about total inodes; rather, let the 'create()' be
- * scheduled on the hashed subvol regardless of the total
- * inodes.
- */
- 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;
- conf->du_stats[i].chunks = chunks;
- gf_msg_debug (this->name, 0,
- "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);
- break; /* no point in looping further */
- }
- }
- UNLOCK (&conf->subvolume_lock);
-
-out:
+ local = frame->local;
+ conf = this->private;
+ prev = cookie;
+
+ if (op_ret == -1)
+ goto out;
+
+ if (statvfs && statvfs->f_blocks) {
+ percent = (statvfs->f_bfree * 100) / statvfs->f_blocks;
+ bytes = (statvfs->f_bfree * statvfs->f_bsize);
+ }
+
+ 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);
- return 0;
+ return 0;
}
int
@@ -113,335 +88,178 @@ 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,};
+ call_pool_t *pool = NULL;
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;
-err:
+ pool = this->ctx->pool;
+
+ statfs_frame = create_frame (this, pool);
+ if (!statfs_frame) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory");
+ goto err;
+ }
+
+ statfs_local = dht_local_init (statfs_frame);
+ if (!statfs_local) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory");
+ 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);
-
- return -1;
+
+ return -1;
}
int
dht_get_du_info (call_frame_t *frame, xlator_t *this, loc_t *loc)
{
- int i = 0;
- int ret = -1;
+ 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,};
+ struct timeval tv = {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
+ 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->params = dict_new ();
- if (!statfs_local->params)
+ statfs_frame = copy_frame (frame);
+ if (!statfs_frame) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory");
goto err;
+ }
- ret = dict_set_int8 (statfs_local->params,
- GF_INTERNAL_IGNORE_DEEM_STATFS, 1);
- if (ret) {
+ statfs_local = dht_local_init (statfs_frame);
+ if (!statfs_local) {
gf_log (this->name, GF_LOG_ERROR,
- "Failed to set "
- GF_INTERNAL_IGNORE_DEEM_STATFS" in dict");
+ "Out of memory");
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, statfs_local->params);
- }
-
- conf->last_stat_fetch.tv_sec = tv.tv_sec;
- }
- return 0;
+ 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);
- 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_msg (this->name, GF_LOG_WARNING, 0,
- DHT_MSG_SUBVOL_INSUFF_SPACE,
- "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_msg (this->name, GF_LOG_CRITICAL, 0,
- DHT_MSG_SUBVOL_INSUFF_INODES,
- "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;
-}
-
-
-/*Get the best subvolume to create the file in*/
-xlator_t *
-dht_free_disk_available_subvol (xlator_t *this, xlator_t *subvol,
- dht_local_t *local)
-{
- xlator_t *avail_subvol = NULL;
+ int i = 0;
+ int subvol_filled = 0;
dht_conf_t *conf = NULL;
- dht_layout_t *layout = NULL;
- loc_t *loc = NULL;
-
- conf = this->private;
- if (!local)
- goto out;
- loc = &local->loc;
- if (!local->layout) {
- layout = dht_layout_get (this, loc->parent);
-
- if (!layout) {
- gf_msg_debug (this->name, 0,
- "Missing layout. path=%s,"
- " parent gfid = %s", loc->path,
- uuid_utoa (loc->parent->gfid));
- goto out;
- }
- } else {
- layout = dht_layout_ref (this, local->layout);
- }
-
- LOCK (&conf->subvolume_lock);
- {
- avail_subvol = dht_subvol_with_free_space_inodes(this, subvol,
- layout);
- if(!avail_subvol)
- {
- avail_subvol = dht_subvol_maxspace_nonzeroinode(this,
- subvol,
- layout);
- }
-
- }
- UNLOCK (&conf->subvolume_lock);
-out:
- if (!avail_subvol) {
- gf_msg_debug (this->name, 0,
- "No subvolume has enough free space \
- and/or inodes to create");
- avail_subvol = subvol;
- }
-
- if (layout)
- dht_layout_unref (this, layout);
- return avail_subvol;
-}
-
-static inline
-int32_t dht_subvol_has_err (xlator_t *this, dht_layout_t *layout)
-{
- int ret = -1;
- int i = 0;
-
- if (!this || !layout)
- goto out;
-
- /* check if subvol has layout errors, before selecting it */
- for (i = 0; i < layout->cnt; i++) {
- if (!strcmp (layout->list[i].xlator->name, this->name) &&
- (layout->list[i].err != 0)) {
- ret = -1;
- goto out;
- }
- }
- ret = 0;
-out:
- return ret;
-}
-
-/*Get subvolume which has both space and inodes more than the min criteria*/
-xlator_t *
-dht_subvol_with_free_space_inodes(xlator_t *this, xlator_t *subvol,
- dht_layout_t *layout)
-{
- int i = 0;
- double max = 0;
- double max_inodes = 0;
- int ignore_subvol = 0;
-
- xlator_t *avail_subvol = NULL;
- dht_conf_t *conf = NULL;
conf = this->private;
- for(i=0; i < conf->subvolume_cnt; i++) {
- /* check if subvol has layout errors, before selecting it */
- ignore_subvol = dht_subvol_has_err (conf->subvolumes[i],
- layout);
- if (ignore_subvol)
- continue;
-
- if ((conf->disk_unit == 'p') &&
- (conf->du_stats[i].avail_percent > conf->min_free_disk) &&
- (conf->du_stats[i].avail_inodes > conf->min_free_inodes)) {
- if ((conf->du_stats[i].avail_inodes > max_inodes) ||
- (conf->du_stats[i].avail_percent > max)) {
- max = conf->du_stats[i].avail_percent;
- max_inodes = conf->du_stats[i].avail_inodes;
- avail_subvol = conf->subvolumes[i];
+ /* 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;
+ }
+ }
}
}
-
- if ((conf->disk_unit != 'p') &&
- (conf->du_stats[i].avail_space > conf->min_free_disk) &&
- (conf->du_stats[i].avail_inodes > conf->min_free_inodes)) {
- if ((conf->du_stats[i].avail_inodes > max_inodes) ||
- (conf->du_stats[i].avail_space > max)) {
- 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 (subvol_filled && conf->subvolume_status[i]) {
+ if (!(conf->du_stats[i].log++ % (GF_UNIVERSAL_ANSWER * 10))) {
+ GF_LOG_OCCASIONALLY (gf_log_subvol_full,
+ 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 avail_subvol;
+ return subvol_filled;
}
-
-/* Get subvol which has atleast one inode and maximum space */
xlator_t *
-dht_subvol_maxspace_nonzeroinode (xlator_t *this, xlator_t *subvol,
- dht_layout_t *layout)
+dht_free_disk_available_subvol (xlator_t *this, xlator_t *subvol)
{
int i = 0;
- double max = 0;
- int ignore_subvol = 0;
-
+ double max= 0;
xlator_t *avail_subvol = NULL;
- dht_conf_t *conf = NULL;
+ dht_conf_t *conf = NULL;
conf = this->private;
+ avail_subvol = subvol;
- for (i = 0; i < conf->subvolume_cnt; i++) {
- /* check if subvol has layout errors, before selecting it */
- ignore_subvol = dht_subvol_has_err (conf->subvolumes[i],
- layout);
- if (ignore_subvol)
- continue;
-
- if (conf->disk_unit == 'p') {
- if ((conf->du_stats[i].avail_percent > max)
- && (conf->du_stats[i].avail_inodes > 0 )) {
- max = conf->du_stats[i].avail_percent;
- avail_subvol = conf->subvolumes[i];
+ 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];
+ }
}
- } else {
- if ((conf->du_stats[i].avail_space > max)
- && (conf->du_stats[i].avail_inodes > 0)) {
- max = conf->du_stats[i].avail_space;
- avail_subvol = conf->subvolumes[i];
- }
- }
+ }
}
+ UNLOCK (&conf->subvolume_lock);
+
+ if (max < conf->min_free_disk)
+ avail_subvol = subvol;
+ if (avail_subvol == subvol) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "no subvolume has enough free space to create");
+ }
+
return avail_subvol;
}
diff --git a/xlators/cluster/dht/src/dht-hashfn.c b/xlators/cluster/dht/src/dht-hashfn.c
index 72b3df022da..dfc1541fa1e 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>
- 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-2009 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
@@ -23,89 +32,50 @@
int
dht_hash_compute_internal (int type, const char *name, uint32_t *hash_p)
{
- int ret = 0;
- uint32_t hash = 0;
-
- switch (type) {
- case DHT_HASH_TYPE_DM:
- case DHT_HASH_TYPE_DM_USER:
- hash = gf_dm_hashfn (name, strlen (name));
- break;
- default:
- ret = -1;
- break;
- }
-
- if (ret == 0) {
- *hash_p = hash;
- }
-
- return ret;
+ int ret = 0;
+ uint32_t hash = 0;
+
+ switch (type) {
+ case DHT_HASH_TYPE_DM:
+ hash = gf_dm_hashfn (name, strlen (name));
+ break;
+ default:
+ ret = -1;
+ break;
+ }
+
+ if (ret == 0) {
+ *hash_p = hash;
+ }
+
+ return ret;
}
-static inline
-gf_boolean_t
-dht_munge_name (const char *original, char *modified, size_t len, regex_t *re)
-{
- regmatch_t matches[2];
- size_t new_len;
-
- if (regexec(re,original,2,matches,0) != REG_NOMATCH) {
- if (matches[1].rm_so != -1) {
- new_len = matches[1].rm_eo - matches[1].rm_so;
- /* Equal would fail due to the NUL at the end. */
- if (new_len < len) {
- memcpy (modified,original+matches[1].rm_so,
- new_len);
- modified[new_len] = '\0';
- return _gf_true;
- }
- }
- }
-
- /* This is guaranteed safe because of how the dest was allocated. */
- strcpy(modified,original);
- return _gf_false;
-}
+#define MAKE_RSYNC_FRIENDLY_NAME(rsync_frndly_name, name) do { \
+ rsync_frndly_name = (char *) name; \
+ if (name[0] == '.') { \
+ char *dot = 0; \
+ int namelen = 0; \
+ \
+ dot = strrchr (name, '.'); \
+ if (dot && dot > (name + 1) && *(dot + 1)) { \
+ namelen = (dot - name); \
+ rsync_frndly_name = alloca (namelen); \
+ strncpy (rsync_frndly_name, name + 1, \
+ namelen); \
+ rsync_frndly_name[namelen - 1] = 0; \
+ } \
+ } \
+ } while (0);
+
int
-dht_hash_compute (xlator_t *this, int type, const char *name, uint32_t *hash_p)
+dht_hash_compute (int type, const char *name, uint32_t *hash_p)
{
- char *rsync_friendly_name = NULL;
- dht_conf_t *priv = this->private;
- size_t len = 0;
- gf_boolean_t munged = _gf_false;
-
- /*
- * It wouldn't be safe to use alloca in an inline function that doesn't
- * actually get inlined, and it wouldn't be efficient to do a real
- * allocation, so we use alloca here (if needed) and pass that to the
- * inline.
- */
-
- if (priv->extra_regex_valid) {
- len = strlen(name) + 1;
- rsync_friendly_name = alloca(len);
- munged = dht_munge_name (name, rsync_friendly_name, len,
- &priv->extra_regex);
- }
-
- if (!munged && priv->rsync_regex_valid) {
- len = strlen(name) + 1;
- rsync_friendly_name = alloca(len);
- gf_msg_trace (this->name, 0, "trying regex for %s", name);
- munged = dht_munge_name (name, rsync_friendly_name, len,
- &priv->rsync_regex);
- if (munged) {
- gf_msg_debug (this->name, 0,
- "munged down to %s", rsync_friendly_name);
- }
- }
-
- if (!munged) {
- rsync_friendly_name = (char *)name;
- }
-
- return dht_hash_compute_internal (type, rsync_friendly_name, hash_p);
+ char *rsync_friendly_name = NULL;
+
+ MAKE_RSYNC_FRIENDLY_NAME (rsync_friendly_name, name);
+
+ return dht_hash_compute_internal (type, rsync_friendly_name, hash_p);
}
diff --git a/xlators/cluster/dht/src/dht-helper.c b/xlators/cluster/dht/src/dht-helper.c
index c3cfc7d6066..5a89ba58489 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>
- 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-2009 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
@@ -17,603 +26,215 @@
#include "glusterfs.h"
#include "xlator.h"
#include "dht-common.h"
-#include "dht-helper.h"
-
-static inline int
-dht_inode_ctx_set1 (xlator_t *this, inode_t *inode, xlator_t *subvol)
-{
- uint64_t tmp_subvol = 0;
-
- tmp_subvol = (long)subvol;
- return inode_ctx_set1 (inode, this, &tmp_subvol);
-}
-
-int
-dht_inode_ctx_get1 (xlator_t *this, inode_t *inode, xlator_t **subvol)
-{
- int ret = -1;
- uint64_t tmp_subvol = 0;
-
- ret = inode_ctx_get1 (inode, this, &tmp_subvol);
- if (tmp_subvol && subvol)
- *subvol = (xlator_t *)tmp_subvol;
-
- return ret;
-}
int
dht_frame_return (call_frame_t *frame)
{
- dht_local_t *local = NULL;
- int this_call_cnt = -1;
-
- if (!frame)
- return -1;
-
- local = frame->local;
+ dht_local_t *local = NULL;
+ int this_call_cnt = -1;
- LOCK (&frame->lock);
- {
- this_call_cnt = --local->call_cnt;
- }
- UNLOCK (&frame->lock);
-
- return this_call_cnt;
-}
+ if (!frame)
+ return -1;
+ local = frame->local;
-static uint64_t
-dht_bits_for (uint64_t num)
-{
- uint64_t bits = 0, ctrl = 1;
-
- while (ctrl < num) {
- ctrl *= 2;
- bits ++;
+ LOCK (&frame->lock);
+ {
+ this_call_cnt = --local->call_cnt;
}
+ UNLOCK (&frame->lock);
- return bits;
+ return this_call_cnt;
}
-/*
- * A slightly "updated" version of the algorithm described in the commit log
- * is used here.
- *
- * The only enhancement is that:
- *
- * - The number of bits used by the backend filesystem for HUGE d_off which
- * is described as 63, and
- * - The number of bits used by the d_off presented by the transformation
- * upwards which is described as 64, are both made "configurable."
- */
-
-
-#define BACKEND_D_OFF_BITS 63
-#define PRESENT_D_OFF_BITS 63
-
-#define ONE 1ULL
-#define MASK (~0ULL)
-#define PRESENT_MASK (MASK >> (64 - PRESENT_D_OFF_BITS))
-#define BACKEND_MASK (MASK >> (64 - BACKEND_D_OFF_BITS))
-
-#define TOP_BIT (ONE << (PRESENT_D_OFF_BITS - 1))
-#define SHIFT_BITS (max (0, (BACKEND_D_OFF_BITS - PRESENT_D_OFF_BITS + 1)))
int
dht_itransform (xlator_t *this, xlator_t *subvol, uint64_t x, uint64_t *y_p)
{
- dht_conf_t *conf = NULL;
- int cnt = 0;
- int max = 0;
- uint64_t y = 0;
- uint64_t hi_mask = 0;
- uint64_t off_mask = 0;
- int max_bits = 0;
-
- if (x == ((uint64_t) -1)) {
- y = (uint64_t) -1;
- goto out;
- }
+ dht_conf_t *conf = NULL;
+ int cnt = 0;
+ int max = 0;
+ uint64_t y = 0;
- conf = this->private;
- if (!conf)
- goto out;
-
- max = conf->subvolume_cnt;
- cnt = dht_subvol_cnt (this, subvol);
- if (max == 1) {
- y = x;
+ if (x == ((uint64_t) -1)) {
+ y = (uint64_t) -1;
goto out;
}
- max_bits = dht_bits_for (max);
+ conf = this->private;
- hi_mask = ~(PRESENT_MASK >> (max_bits + 1));
+ max = conf->subvolume_cnt;
+ cnt = dht_subvol_cnt (this, subvol);
- if (x & hi_mask) {
- /* HUGE d_off */
- off_mask = MASK << max_bits;
- y = TOP_BIT | ((x >> SHIFT_BITS) & off_mask) | cnt;
- } else {
- /* small d_off */
- y = ((x * max) + cnt);
- }
+ y = ((x * max) + cnt);
out:
- if (y_p)
- *y_p = y;
+ if (y_p)
+ *y_p = y;
- return 0;
+ return 0;
}
-int
-dht_filter_loc_subvol_key (xlator_t *this, loc_t *loc, loc_t *new_loc,
- xlator_t **subvol)
-{
- char *new_name = NULL;
- char *new_path = NULL;
- xlator_list_t *trav = NULL;
- char key[1024] = {0,};
- 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, '@'))
- goto out;
-
- trav = this->children;
- while (trav) {
- snprintf (key, 1024, "*@%s:%s", this->name, trav->xlator->name);
- if (fnmatch (key, loc->name, FNM_NOESCAPE) == 0) {
- new_name = GF_CALLOC(strlen (loc->name),
- sizeof (char),
- gf_common_mt_char);
- if (!new_name)
- goto out;
- if (fnmatch (key, loc->path, FNM_NOESCAPE) == 0) {
- new_path = GF_CALLOC(strlen (loc->path),
- sizeof (char),
- gf_common_mt_char);
- if (!new_path)
- goto out;
- strncpy (new_path, loc->path, (strlen (loc->path) -
- strlen (key) + 1));
- }
- strncpy (new_name, loc->name, (strlen (loc->name) -
- strlen (key) + 1));
-
- if (new_loc) {
- new_loc->path = ((new_path) ? new_path:
- gf_strdup (loc->path));
- new_loc->name = new_name;
- new_loc->inode = inode_ref (loc->inode);
- new_loc->parent = inode_ref (loc->parent);
- }
- *subvol = trav->xlator;
- ret = 1; /* success */
- goto out;
- }
- trav = trav->next;
- }
-out:
- if (!ret) {
- /* !success */
- GF_FREE (new_path);
- GF_FREE (new_name);
- }
- return ret;
-}
int
dht_deitransform (xlator_t *this, uint64_t y, xlator_t **subvol_p,
- uint64_t *x_p)
+ uint64_t *x_p)
{
- dht_conf_t *conf = NULL;
- int cnt = 0;
- int max = 0;
- uint64_t x = 0;
- xlator_t *subvol = 0;
- int max_bits = 0;
- uint64_t off_mask = 0;
- uint64_t host_mask = 0;
-
- if (!this->private)
- return -1;
-
- conf = this->private;
- max = conf->subvolume_cnt;
-
- if (max == 1) {
- x = y;
- cnt = 0;
- goto out;
- }
-
- if (y & TOP_BIT) {
- /* HUGE d_off */
- max_bits = dht_bits_for (max);
- off_mask = (MASK << max_bits);
- host_mask = ~(off_mask);
-
- x = ((y & ~TOP_BIT) & off_mask) << SHIFT_BITS;
+ dht_conf_t *conf = NULL;
+ int cnt = 0;
+ int max = 0;
+ uint64_t x = 0;
+ xlator_t *subvol = 0;
- cnt = y & host_mask;
- } else {
- /* small d_off */
- cnt = y % max;
- x = y / max;
- }
-
-out:
- subvol = conf->subvolumes[cnt];
-
- if (subvol_p)
- *subvol_p = subvol;
- if (x_p)
- *x_p = x;
+ conf = this->private;
+ max = conf->subvolume_cnt;
- return 0;
-}
-
-char *
-dht_lock_asprintf (dht_lock_t *lock)
-{
- char *lk_buf = NULL;
- char gfid[GF_UUID_BUF_SIZE] = {0, };
+ cnt = y % max;
+ x = y / max;
- if (lock == NULL)
- goto out;
+ subvol = conf->subvolumes[cnt];
- uuid_utoa_r (lock->loc.gfid, gfid);
+ if (subvol_p)
+ *subvol_p = subvol;
- gf_asprintf (&lk_buf, "%s:%s", lock->xl->name, gfid);
+ if (x_p)
+ *x_p = x;
-out:
- return lk_buf;
+ return 0;
}
-void
-dht_log_lk_array (char *name, gf_loglevel_t log_level, dht_lock_t **lk_array,
- int count)
-{
- int i = 0;
- char *lk_buf = NULL;
-
- if ((lk_array == NULL) || (count == 0))
- goto out;
-
- for (i = 0; i < count; i++) {
- lk_buf = dht_lock_asprintf (lk_array[i]);
- gf_log (name, log_level, "%d. %s", i, lk_buf);
- GF_FREE (lk_buf);
- }
-
-out:
- return;
-}
-
-void
-dht_lock_stack_destroy (call_frame_t *lock_frame)
-{
- dht_local_t *local = NULL;
-
- local = lock_frame->local;
-
- local->lock.locks = NULL;
- local->lock.lk_count = 0;
-
- DHT_STACK_DESTROY (lock_frame);
- return;
-}
-
-void
-dht_lock_free (dht_lock_t *lock)
-{
- if (lock == NULL)
- goto out;
-
- loc_wipe (&lock->loc);
- GF_FREE (lock->domain);
- mem_put (lock);
-
-out:
- return;
-}
-
-void
-dht_lock_array_free (dht_lock_t **lk_array, int count)
-{
- int i = 0;
- dht_lock_t *lock = NULL;
-
- if (lk_array == NULL)
- goto out;
-
- for (i = 0; i < count; i++) {
- lock = lk_array[i];
- lk_array[i] = NULL;
- dht_lock_free (lock);
- }
-
-out:
- return;
-}
-
-dht_lock_t *
-dht_lock_new (xlator_t *this, xlator_t *xl, loc_t *loc, short type,
- const char *domain)
-{
- dht_conf_t *conf = NULL;
- dht_lock_t *lock = NULL;
-
- conf = this->private;
-
- lock = mem_get0 (conf->lock_pool);
- if (lock == NULL)
- goto out;
-
- lock->xl = xl;
- lock->type = type;
- lock->domain = gf_strdup (domain);
- if (lock->domain == NULL) {
- dht_lock_free (lock);
- lock = NULL;
- goto out;
- }
-
- /* Fill only inode and gfid.
- posix and protocol/server give preference to pargfid/basename over
- gfid/inode for resolution if all the three parameters of loc_t are
- present. I want to avoid the following hypothetical situation:
-
- 1. rebalance did a lookup on a dentry and got a gfid.
- 2. rebalance acquires lock on loc_t which was filled with gfid and
- path (pargfid/bname) from step 1.
- 3. somebody deleted and recreated the same file
- 4. rename on the same path acquires lock on loc_t which now points
- to a different inode (and hence gets the lock).
- 5. rebalance continues to migrate file (note that not all fops done
- by rebalance during migration are inode/gfid based Eg., unlink)
- 6. rename continues.
- */
- lock->loc.inode = inode_ref (loc->inode);
- loc_gfid (loc, lock->loc.gfid);
-
-out:
- return lock;
-}
-
-int
-dht_local_lock_init (call_frame_t *frame, dht_lock_t **lk_array,
- int lk_count, fop_inodelk_cbk_t inodelk_cbk)
-{
- int ret = -1;
- dht_local_t *local = NULL;
-
- local = frame->local;
-
- if (local == NULL) {
- local = dht_local_init (frame, NULL, NULL, 0);
- }
-
- if (local == NULL) {
- goto out;
- }
-
- local->lock.inodelk_cbk = inodelk_cbk;
- local->lock.locks = lk_array;
- local->lock.lk_count = lk_count;
-
- ret = dht_lock_order_requests (local->lock.locks,
- local->lock.lk_count);
- if (ret < 0)
- goto out;
-
- ret = 0;
-out:
- return ret;
-}
void
dht_local_wipe (xlator_t *this, dht_local_t *local)
{
- if (!local)
- return;
+ if (!local)
+ return;
- loc_wipe (&local->loc);
- loc_wipe (&local->loc2);
+ loc_wipe (&local->loc);
+ loc_wipe (&local->loc2);
- if (local->xattr)
- dict_unref (local->xattr);
+ if (local->xattr)
+ dict_unref (local->xattr);
- if (local->inode)
- inode_unref (local->inode);
+ if (local->inode)
+ inode_unref (local->inode);
- if (local->layout) {
- dht_layout_unref (this, local->layout);
+ if (local->layout) {
+ dht_layout_unref (this, local->layout);
local->layout = NULL;
}
- loc_wipe (&local->linkfile.loc);
-
- if (local->linkfile.xattr)
- dict_unref (local->linkfile.xattr);
+ loc_wipe (&local->linkfile.loc);
- if (local->linkfile.inode)
- inode_unref (local->linkfile.inode);
+ if (local->linkfile.xattr)
+ dict_unref (local->linkfile.xattr);
- if (local->fd) {
- fd_unref (local->fd);
- local->fd = NULL;
- }
+ if (local->linkfile.inode)
+ inode_unref (local->linkfile.inode);
- if (local->params) {
- dict_unref (local->params);
- local->params = NULL;
- }
+ if (local->fd) {
+ fd_unref (local->fd);
+ local->fd = NULL;
+ }
- if (local->xattr_req)
- dict_unref (local->xattr_req);
+ if (local->xattr_req)
+ dict_unref (local->xattr_req);
if (local->selfheal.layout) {
dht_layout_unref (this, local->selfheal.layout);
local->selfheal.layout = NULL;
}
- dht_lock_array_free (local->lock.locks, local->lock.lk_count);
- GF_FREE (local->lock.locks);
-
- GF_FREE (local->newpath);
-
- GF_FREE (local->key);
-
- GF_FREE (local->rebalance.vector);
-
- if (local->rebalance.iobref)
- iobref_unref (local->rebalance.iobref);
-
- mem_put (local);
+ 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;
+ dht_local_t *local = NULL;
- if (loc) {
- ret = loc_copy (&local->loc, loc);
- if (ret)
- goto out;
-
- inode = loc->inode;
- }
-
- if (fd) {
- local->fd = fd_ref (fd);
- if (!inode)
- inode = fd->inode;
- }
+ /* TODO: use mem-pool */
+ local = CALLOC (1, sizeof (*local));
- local->op_ret = -1;
- local->op_errno = EUCLEAN;
- local->fop = fop;
+ if (!local)
+ return NULL;
- if (inode) {
- local->layout = dht_layout_get (frame->this, inode);
- local->cached_subvol = dht_subvol_get_cached (frame->this,
- inode);
- }
+ local->op_ret = -1;
+ local->op_errno = EUCLEAN;
- frame->local = local;
+ frame->local = local;
-out:
- if (ret) {
- if (local)
- mem_put (local);
- local = NULL;
- }
- return local;
+ return local;
}
-xlator_t *
-dht_first_up_subvol (xlator_t *this)
+
+char *
+basestr (const char *str)
{
- dht_conf_t *conf = NULL;
- xlator_t *child = NULL;
- int i = 0;
- time_t time = 0;
+ char *basestr = NULL;
- conf = this->private;
- if (!conf)
- goto out;
+ basestr = strrchr (str, '/');
+ if (basestr)
+ basestr ++;
- 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];
- }
- }
- }
- }
- UNLOCK (&conf->subvolume_lock);
-
-out:
- return child;
+ return basestr;
}
+
xlator_t *
-dht_last_up_subvol (xlator_t *this)
+dht_first_up_subvol (xlator_t *this)
{
- dht_conf_t *conf = NULL;
- xlator_t *child = NULL;
- int i = 0;
+ dht_conf_t *conf = NULL;
+ xlator_t *child = NULL;
+ int i = 0;
- conf = this->private;
- if (!conf)
- goto out;
+ conf = this->private;
- LOCK (&conf->subvolume_lock);
- {
- for (i = conf->subvolume_cnt-1; i >= 0; i--) {
- if (conf->subvolume_status[i]) {
- child = conf->subvolumes[i];
- break;
- }
- }
- }
- UNLOCK (&conf->subvolume_lock);
+ LOCK (&conf->subvolume_lock);
+ {
+ for (i = 0; i < conf->subvolume_cnt; i++) {
+ if (conf->subvolume_status[i]) {
+ child = conf->subvolumes[i];
+ break;
+ }
+ }
+ }
+ UNLOCK (&conf->subvolume_lock);
-out:
- return child;
+ return child;
}
+
xlator_t *
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_msg_debug (this->name, 0,
- "Missing layout. path=%s, parent gfid =%s",
- loc->path, uuid_utoa (loc->parent->gfid));
+ gf_log (this->name, GF_LOG_DEBUG,
+ "layout missing path=%s parent=%"PRId64,
+ loc->path, loc->parent->ino);
goto out;
}
subvol = dht_layout_search (this, layout, loc->name);
if (!subvol) {
- gf_msg_debug (this->name, 0,
- "No hashed subvolume for path=%s",
- loc->path);
+ gf_log (this->name, GF_LOG_DEBUG,
+ "could not find subvolume for path=%s",
+ loc->path);
goto out;
}
@@ -632,8 +253,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);
@@ -641,7 +260,7 @@ dht_subvol_get_cached (xlator_t *this, inode_t *inode)
goto out;
}
- subvol = layout->list[0].xlator;
+ subvol = layout->list[0].xlator;
out:
if (layout) {
@@ -655,126 +274,79 @@ out:
xlator_t *
dht_subvol_next (xlator_t *this, xlator_t *prev)
{
- dht_conf_t *conf = NULL;
- int i = 0;
- xlator_t *next = NULL;
+ dht_conf_t *conf = NULL;
+ int i = 0;
+ xlator_t *next = NULL;
- conf = this->private;
- if (!conf)
- goto out;
+ conf = this->private;
- for (i = 0; i < conf->subvolume_cnt; i++) {
- if (conf->subvolumes[i] == prev) {
- if ((i + 1) < conf->subvolume_cnt)
- next = conf->subvolumes[i + 1];
- break;
- }
- }
+ for (i = 0; i < conf->subvolume_cnt; i++) {
+ if (conf->subvolumes[i] == prev) {
+ if ((i + 1) < conf->subvolume_cnt)
+ next = conf->subvolumes[i + 1];
+ break;
+ }
+ }
-out:
- return next;
+ return next;
}
-/* This func wraps around, if prev is actually the last subvol.
- */
-xlator_t *
-dht_subvol_next_available (xlator_t *this, xlator_t *prev)
-{
- dht_conf_t *conf = NULL;
- int i = 0;
- xlator_t *next = NULL;
-
- conf = this->private;
- if (!conf)
- goto out;
-
- for (i = 0; i < conf->subvolume_cnt; i++) {
- if (conf->subvolumes[i] == prev) {
- /* if prev is last in conf->subvolumes, then wrap
- * around.
- */
- if ((i + 1) < conf->subvolume_cnt) {
- next = conf->subvolumes[i + 1];
- } else {
- next = conf->subvolumes[0];
- }
- break;
- }
- }
-out:
- return next;
-}
int
dht_subvol_cnt (xlator_t *this, xlator_t *subvol)
{
- int i = 0;
- int ret = -1;
- dht_conf_t *conf = NULL;
+ int i = 0;
+ int ret = -1;
+ dht_conf_t *conf = NULL;
- conf = this->private;
- if (!conf)
- goto out;
- for (i = 0; i < conf->subvolume_cnt; i++) {
- if (subvol == conf->subvolumes[i]) {
- ret = i;
- break;
- }
- }
-
-out:
- return ret;
-}
+ conf = this->private;
+ for (i = 0; i < conf->subvolume_cnt; i++) {
+ if (subvol == conf->subvolumes[i]) {
+ ret = i;
+ break;
+ }
+ }
-#define set_if_greater(a, b) do { \
- if ((a) < (b)) \
- (a) = (b); \
- } while (0)
-
+ return ret;
+}
-#define set_if_greater_time(a, an, b, bn) do { \
- if (((a) < (b)) || (((a) == (b)) && ((an) < (bn)))){ \
- (a) = (b); \
- (an) = (bn); \
- } \
- } while (0) \
+#define set_if_greater(a, b) do { \
+ if ((a) < (b)) \
+ (a) = (b); \
+ } while (0)
int
-dht_iatt_merge (xlator_t *this, struct iatt *to,
- struct iatt *from, xlator_t *subvol)
+dht_stat_merge (xlator_t *this, struct stat *to,
+ struct stat *from, xlator_t *subvol)
{
if (!from || !to)
return 0;
- to->ia_dev = from->ia_dev;
+ to->st_dev = from->st_dev;
- uuid_copy (to->ia_gfid, from->ia_gfid);
+ dht_itransform (this, subvol, from->st_ino, &to->st_ino);
- to->ia_ino = from->ia_ino;
- to->ia_prot = from->ia_prot;
- to->ia_type = from->ia_type;
- to->ia_nlink = from->ia_nlink;
- to->ia_rdev = from->ia_rdev;
- to->ia_size += from->ia_size;
- to->ia_blksize = from->ia_blksize;
- to->ia_blocks += from->ia_blocks;
+ to->st_mode = from->st_mode;
+ to->st_nlink = from->st_nlink;
+ to->st_rdev = from->st_rdev;
+ to->st_size += from->st_size;
+ to->st_blksize = from->st_blksize;
+ to->st_blocks += from->st_blocks;
- set_if_greater (to->ia_uid, from->ia_uid);
- set_if_greater (to->ia_gid, from->ia_gid);
+ set_if_greater (to->st_uid, from->st_uid);
+ set_if_greater (to->st_gid, from->st_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->st_atime, from->st_atime);
+ set_if_greater (to->st_mtime, from->st_mtime);
+ set_if_greater (to->st_ctime, from->st_ctime);
- return 0;
+ return 0;
}
+
int
dht_build_child_loc (xlator_t *this, loc_t *child, loc_t *parent, char *name)
{
@@ -783,11 +355,13 @@ dht_build_child_loc (xlator_t *this, loc_t *child, loc_t *parent, char *name)
}
if (strcmp (parent->path, "/") == 0)
- gf_asprintf ((char **)&child->path, "/%s", name);
+ asprintf ((char **)&child->path, "/%s", name);
else
- gf_asprintf ((char **)&child->path, "%s/%s", parent->path, name);
+ asprintf ((char **)&child->path, "%s/%s", parent->path, name);
if (!child->path) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory");
goto err;
}
@@ -799,6 +373,8 @@ dht_build_child_loc (xlator_t *this, loc_t *child, loc_t *parent, char *name)
child->inode = inode_new (parent->inode->table);
if (!child->inode) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory");
goto err;
}
@@ -807,988 +383,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;
- dht_conf_t *conf = NULL;
- inode_t *inode = NULL;
- fd_t *iter_fd = NULL;
- uint64_t tmp_subvol = 0;
- int open_failed = 0;
-
- this = THIS;
- frame = data;
- local = frame->local;
- conf = this->private;
-
- src_node = local->cached_subvol;
-
- if (!local->loc.inode && !local->fd) {
- local->op_errno = EINVAL;
- goto out;
- }
-
- inode = (!local->fd) ? local->loc.inode : local->fd->inode;
-
- /* getxattr on cached_subvol for 'linkto' value. Do path based getxattr
- * as root:root. If a fd is already open, access check wont be done*/
-
- if (!local->loc.inode) {
- ret = syncop_fgetxattr (src_node, local->fd, &dict,
- conf->link_xattr_name);
- } else {
- SYNCTASK_SETID (0, 0);
- ret = syncop_getxattr (src_node, &local->loc, &dict,
- conf->link_xattr_name);
- SYNCTASK_SETID (frame->root->uid, frame->root->gid);
- }
-
- if (!ret)
- dst_node = dht_linkfile_subvol (this, NULL, NULL, dict);
-
- if (ret) {
- if (!dht_inode_missing(-ret) || (!local->loc.inode)) {
- local->op_errno = -ret;
- gf_log (this->name, GF_LOG_ERROR,
- "%s: failed to get the 'linkto' xattr %s",
- local->loc.path, strerror (-ret));
- ret = -1;
- 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) {
- local->op_errno = -ret;
- ret = -1;
- 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;
- local->op_errno = EINVAL;
- 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);
- local->op_errno = -ret;
- ret = -1;
- goto out;
- }
-
- if (uuid_compare (stbuf.ia_gfid, local->loc.inode->gfid)) {
- gf_msg (this->name, GF_LOG_ERROR, 0,
- DHT_MSG_GFID_MISMATCH,
- "%s: gfid different on the target file on %s",
- local->loc.path, dst_node->name);
- ret = -1;
- local->op_errno = EIO;
- goto out;
- }
- }
-
- /* update inode ctx (the layout) */
- dht_layout_unref (this, local->layout);
-
- ret = dht_layout_preset (this, dst_node, inode);
- if (ret != 0) {
- gf_msg_debug (this->name, 0,
- "%s: could not set preset layout "
- "for subvol %s", local->loc.path,
- dst_node->name);
- ret = -1;
- local->op_errno = EINVAL;
- 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;
- local->op_errno = EINVAL;
- goto out;
- }
-
- ret = dht_layout_set (this, inode, layout);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "%s: failed to set the new layout",
- local->loc.path);
- local->op_errno = EINVAL;
- goto out;
- }
-
- local->cached_subvol = dst_node;
- ret = 0;
-
- /* once we detect the migration complete, the inode-ctx2 is no more
- required.. delete the ctx and also, it means, open() already
- done on all the fd of inode */
- ret = inode_ctx_reset1 (inode, this, &tmp_subvol);
- if (tmp_subvol)
- goto out;
-
- if (list_empty (&inode->fd_list))
- goto out;
-
- /* perform open as root:root. There is window between linkfile
- * creation(root:root) and setattr with the correct uid/gid
- */
- SYNCTASK_SETID(0, 0);
-
- /* perform 'open()' on all the fd's present on the inode */
- tmp_loc.inode = inode;
- inode_path (inode, NULL, &path);
- if (path)
- tmp_loc.path = path;
- list_for_each_entry (iter_fd, &inode->fd_list, inode_list) {
- if (fd_is_anonymous (iter_fd))
- continue;
-
- /* flags for open are stripped down to allow following the
- * new location of the file, otherwise we can get EEXIST or
- * truncate the file again as rebalance is moving the data */
- ret = syncop_open (dst_node, &tmp_loc,
- (iter_fd->flags &
- ~(O_CREAT | O_EXCL | O_TRUNC)), iter_fd);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR, "failed to open "
- "the fd (%p, flags=0%o) on file %s @ %s",
- iter_fd, iter_fd->flags, path, dst_node->name);
- open_failed = 1;
- local->op_errno = -ret;
- ret = -1;
- }
- }
- GF_FREE (path);
-
- SYNCTASK_SETID (frame->root->uid, frame->root->gid);
-
- if (open_failed) {
- ret = -1;
- goto out;
- }
- 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,};
- dht_conf_t *conf = NULL;
- inode_t *inode = NULL;
- fd_t *iter_fd = NULL;
- int open_failed = 0;
-
- this = THIS;
- frame = data;
- local = frame->local;
- conf = this->private;
-
- src_node = local->cached_subvol;
-
- if (!local->loc.inode && !local->fd)
- goto out;
-
- inode = (!local->fd) ? local->loc.inode : local->fd->inode;
-
- /* getxattr on cached_subvol for 'linkto' value. Do path based getxattr
- * as root:root. If a fd is already open, access check wont be done*/
- if (local->loc.inode) {
- SYNCTASK_SETID (0, 0);
- ret = syncop_getxattr (src_node, &local->loc, &dict,
- conf->link_xattr_name);
- SYNCTASK_SETID (frame->root->uid, frame->root->gid);
- } else {
- ret = syncop_fgetxattr (src_node, local->fd, &dict,
- conf->link_xattr_name);
- }
-
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "%s: failed to get the 'linkto' xattr %s",
- local->loc.path, strerror (-ret));
- ret = -1;
- 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);
- ret = -1;
- goto out;
- }
-
- if (uuid_compare (stbuf.ia_gfid, local->loc.inode->gfid)) {
- gf_msg (this->name, GF_LOG_ERROR, 0,
- DHT_MSG_GFID_MISMATCH,
- "%s: gfid different on the target file on %s",
- local->loc.path, dst_node->name);
- ret = -1;
- goto out;
- }
- }
-
- ret = 0;
-
- if (list_empty (&inode->fd_list))
- goto done;
-
- /* perform open as root:root. There is window between linkfile
- * creation(root:root) and setattr with the correct uid/gid
- */
- SYNCTASK_SETID (0, 0);
-
- tmp_loc.inode = inode;
- inode_path (inode, NULL, &path);
- if (path)
- tmp_loc.path = path;
-
- list_for_each_entry (iter_fd, &inode->fd_list, inode_list) {
- if (fd_is_anonymous (iter_fd))
- continue;
-
- /* flags for open are stripped down to allow following the
- * new location of the file, otherwise we can get EEXIST or
- * truncate the file again as rebalance is moving the data */
- ret = syncop_open (dst_node, &tmp_loc,
- (iter_fd->flags &
- ~(O_CREAT | O_EXCL | O_TRUNC)), iter_fd);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR, "failed to send open "
- "the fd (%p, flags=0%o) on file %s @ %s",
- iter_fd, iter_fd->flags, path, dst_node->name);
- ret = -1;
- open_failed = 1;
- }
- }
- GF_FREE (path);
-
- SYNCTASK_SETID (frame->root->uid, frame->root->gid);
-
- if (open_failed) {
- ret = -1;
- goto out;
- }
-
-done:
- ret = dht_inode_ctx_set1 (this, inode, dst_node);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "%s: failed to set inode-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;
-}
-
-int
-dht_inode_ctx_layout_set (inode_t *inode, xlator_t *this,
- dht_layout_t *layout_int)
-{
- dht_inode_ctx_t *ctx = NULL;
- int ret = -1;
-
- ret = dht_inode_ctx_get (inode, this, &ctx);
- if (!ret && ctx) {
- ctx->layout = layout_int;
- } else {
- ctx = GF_CALLOC (1, sizeof (*ctx), gf_dht_mt_inode_ctx_t);
- if (!ctx)
- return ret;
- ctx->layout = layout_int;
- }
-
- ret = dht_inode_ctx_set (inode, this, ctx);
-
- return ret;
-}
-
-
-void
-dht_inode_ctx_time_set (inode_t *inode, xlator_t *this, struct iatt *stat)
-{
- dht_inode_ctx_t *ctx = NULL;
- dht_stat_time_t *time = 0;
- int ret = -1;
-
- ret = dht_inode_ctx_get (inode, this, &ctx);
-
- if (ret)
- return;
-
- time = &ctx->time;
-
- time->mtime = stat->ia_mtime;
- time->mtime_nsec = stat->ia_mtime_nsec;
-
- time->ctime = stat->ia_ctime;
- time->ctime_nsec = stat->ia_ctime_nsec;
-
- time->atime = stat->ia_atime;
- time->atime_nsec = stat->ia_atime_nsec;
-
- return;
-}
-
-
-int
-dht_inode_ctx_time_update (inode_t *inode, xlator_t *this, struct iatt *stat,
- int32_t post)
-{
- dht_inode_ctx_t *ctx = NULL;
- dht_stat_time_t *time = 0;
- int ret = -1;
-
- GF_VALIDATE_OR_GOTO (this->name, stat, out);
- GF_VALIDATE_OR_GOTO (this->name, inode, out);
-
- ret = dht_inode_ctx_get (inode, this, &ctx);
-
- if (ret) {
- ctx = GF_CALLOC (1, sizeof (*ctx), gf_dht_mt_inode_ctx_t);
- if (!ctx)
- return -1;
- }
-
- time = &ctx->time;
-
- DHT_UPDATE_TIME(time->mtime, time->mtime_nsec,
- stat->ia_mtime, stat->ia_mtime_nsec, inode, post);
- DHT_UPDATE_TIME(time->ctime, time->ctime_nsec,
- stat->ia_ctime, stat->ia_ctime_nsec, inode, post);
- DHT_UPDATE_TIME(time->atime, time->atime_nsec,
- stat->ia_atime, stat->ia_atime_nsec, inode, post);
-
- ret = dht_inode_ctx_set (inode, this, ctx);
-out:
- return 0;
-}
-
-int
-dht_inode_ctx_get (inode_t *inode, xlator_t *this, dht_inode_ctx_t **ctx)
-{
- int ret = -1;
- uint64_t ctx_int = 0;
-
- GF_VALIDATE_OR_GOTO ("dht", this, out);
- GF_VALIDATE_OR_GOTO (this->name, inode, out);
-
- ret = inode_ctx_get (inode, this, &ctx_int);
-
- if (ret)
- return ret;
-
- if (ctx)
- *ctx = (dht_inode_ctx_t *) ctx_int;
-out:
- return ret;
-}
-
-int dht_inode_ctx_set (inode_t *inode, xlator_t *this, dht_inode_ctx_t *ctx)
-{
- int ret = -1;
- uint64_t ctx_int = 0;
-
- GF_VALIDATE_OR_GOTO ("dht", this, out);
- GF_VALIDATE_OR_GOTO (this->name, inode, out);
- GF_VALIDATE_OR_GOTO (this->name, ctx, out);
-
- ctx_int = (long)ctx;
- ret = inode_ctx_set (inode, this, &ctx_int);
-out:
- return ret;
-}
-
-int
-dht_subvol_status (dht_conf_t *conf, xlator_t *subvol)
-{
- int i;
-
- for (i=0 ; i < conf->subvolume_cnt; i++) {
- if (conf->subvolumes[i] == subvol) {
- return conf->subvolume_status[i];
- }
- }
- return 0;
-}
-
-void
-dht_inodelk_done (call_frame_t *lock_frame)
-{
- fop_inodelk_cbk_t inodelk_cbk = NULL;
- call_frame_t *main_frame = NULL;
- dht_local_t *local = NULL;
-
- local = lock_frame->local;
- main_frame = local->main_frame;
-
- local->lock.locks = NULL;
- local->lock.lk_count = 0;
-
- inodelk_cbk = local->lock.inodelk_cbk;
- local->lock.inodelk_cbk = NULL;
-
- inodelk_cbk (main_frame, NULL, main_frame->this, local->lock.op_ret,
- local->lock.op_errno, NULL);
-
- dht_lock_stack_destroy (lock_frame);
- return;
-}
-
-int
-dht_inodelk_cleanup_cbk (call_frame_t *frame, void *cookie,
- xlator_t *this, int32_t op_ret, int32_t op_errno,
- dict_t *xdata)
-{
- dht_inodelk_done (frame);
- return 0;
-}
-
-inline int32_t
-dht_lock_count (dht_lock_t **lk_array, int lk_count)
-{
- int i = 0, locked = 0;
-
- if ((lk_array == NULL) || (lk_count == 0))
- goto out;
-
- for (i = 0; i < lk_count; i++) {
- if (lk_array[i]->locked)
- locked++;
- }
-out:
- return locked;
-}
-
-void
-dht_inodelk_cleanup (call_frame_t *lock_frame)
-{
- dht_lock_t **lk_array = NULL;
- int lk_count = 0, lk_acquired = 0;
- dht_local_t *local = NULL;
-
- local = lock_frame->local;
-
- lk_array = local->lock.locks;
- lk_count = local->lock.lk_count;
-
- lk_acquired = dht_lock_count (lk_array, lk_count);
- if (lk_acquired != 0) {
- dht_unlock_inodelk (lock_frame, lk_array, lk_count,
- dht_inodelk_cleanup_cbk);
- } else {
- dht_inodelk_done (lock_frame);
- }
-
- return;
-}
-
-int32_t
-dht_unlock_inodelk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
-{
- dht_local_t *local = NULL;
- int lk_index = 0, call_cnt = 0;
- char gfid[GF_UUID_BUF_SIZE] = {0};
-
- lk_index = (long) cookie;
-
- local = frame->local;
- if (op_ret < 0) {
- uuid_utoa_r (local->lock.locks[lk_index]->loc.gfid,
- gfid);
-
- gf_log (this->name, GF_LOG_WARNING,
- "unlocking failed on %s:%s (%s)",
- local->lock.locks[lk_index]->xl->name,
- gfid, strerror (op_errno));
- } else {
- local->lock.locks[lk_index]->locked = 0;
- }
-
- call_cnt = dht_frame_return (frame);
- if (is_last_call (call_cnt)) {
- dht_inodelk_done (frame);
- }
-
- return 0;
-}
-
-call_frame_t *
-dht_lock_frame (call_frame_t *parent_frame)
-{
- call_frame_t *lock_frame = NULL;
-
- lock_frame = copy_frame (parent_frame);
- if (lock_frame == NULL)
- goto out;
-
- set_lk_owner_from_ptr (&lock_frame->root->lk_owner, parent_frame->root);
-
-out:
- return lock_frame;
-}
-
-int32_t
-dht_unlock_inodelk (call_frame_t *frame, dht_lock_t **lk_array, int lk_count,
- fop_inodelk_cbk_t inodelk_cbk)
-{
- dht_local_t *local = NULL;
- struct gf_flock flock = {0,};
- int ret = -1 , i = 0;
- call_frame_t *lock_frame = NULL;
- int call_cnt = 0;
-
- GF_VALIDATE_OR_GOTO ("dht-locks", frame, done);
- GF_VALIDATE_OR_GOTO (frame->this->name, lk_array, done);
- GF_VALIDATE_OR_GOTO (frame->this->name, inodelk_cbk, done);
-
- call_cnt = dht_lock_count (lk_array, lk_count);
- if (call_cnt == 0) {
- ret = 0;
- goto done;
- }
-
- lock_frame = dht_lock_frame (frame);
- if (lock_frame == NULL) {
- gf_log (frame->this->name, GF_LOG_WARNING,
- "cannot allocate a frame, not unlocking following "
- "locks:");
-
- dht_log_lk_array (frame->this->name, GF_LOG_WARNING, lk_array,
- lk_count);
- goto done;
- }
-
- ret = dht_local_lock_init (lock_frame, lk_array, lk_count, inodelk_cbk);
- if (ret < 0) {
- gf_log (frame->this->name, GF_LOG_WARNING,
- "storing locks in local failed, not unlocking "
- "following locks:");
-
- dht_log_lk_array (frame->this->name, GF_LOG_WARNING, lk_array,
- lk_count);
-
- goto done;
- }
-
- local = lock_frame->local;
- local->main_frame = frame;
- local->call_cnt = call_cnt;
-
- flock.l_type = F_UNLCK;
-
- for (i = 0; i < local->lock.lk_count; i++) {
- if (!local->lock.locks[i]->locked)
- continue;
-
- STACK_WIND_COOKIE (lock_frame, dht_unlock_inodelk_cbk,
- (void *)(long)i,
- local->lock.locks[i]->xl,
- local->lock.locks[i]->xl->fops->inodelk,
- local->lock.locks[i]->domain,
- &local->lock.locks[i]->loc, F_SETLK,
- &flock, NULL);
- }
-
- return 0;
-
-done:
- if (lock_frame)
- dht_lock_stack_destroy (lock_frame);
-
- /* no locks acquired, invoke inodelk_cbk */
- if (ret == 0)
- inodelk_cbk (frame, NULL, frame->this, 0, 0, NULL);
-
- return ret;
-}
-
-int32_t
-dht_nonblocking_inodelk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
-{
- dht_local_t *local = NULL;
- int lk_index = 0, call_cnt = 0;
- char gfid[GF_UUID_BUF_SIZE] = {0};
-
- local = frame->local;
- lk_index = (long) cookie;
-
- if (op_ret == -1) {
- local->lock.op_ret = -1;
- local->lock.op_errno = op_errno;
-
- if (local && local->lock.locks[lk_index]) {
- uuid_utoa_r (local->lock.locks[lk_index]->loc.inode->gfid,
- gfid);
-
- gf_log (this->name, GF_LOG_DEBUG,
- "inodelk failed on gfid: %s "
- "subvolume: %s (%s)", gfid,
- local->lock.locks[lk_index]->xl->name,
- strerror (op_errno));
- }
-
- goto out;
- }
-
- local->lock.locks[lk_index]->locked = _gf_true;
-
-out:
- call_cnt = dht_frame_return (frame);
- if (is_last_call (call_cnt)) {
- if (local->lock.op_ret < 0) {
- dht_inodelk_cleanup (frame);
- return 0;
- }
-
- dht_inodelk_done (frame);
- }
-
- return 0;
-}
-
-int
-dht_nonblocking_inodelk (call_frame_t *frame, dht_lock_t **lk_array,
- int lk_count, fop_inodelk_cbk_t inodelk_cbk)
-{
- struct gf_flock flock = {0,};
- int i = 0, ret = 0;
- dht_local_t *local = NULL;
- call_frame_t *lock_frame = NULL;
-
- GF_VALIDATE_OR_GOTO ("dht-locks", frame, out);
- GF_VALIDATE_OR_GOTO (frame->this->name, lk_array, out);
- GF_VALIDATE_OR_GOTO (frame->this->name, inodelk_cbk, out);
-
- lock_frame = dht_lock_frame (frame);
- if (lock_frame == NULL)
- goto out;
-
- ret = dht_local_lock_init (lock_frame, lk_array, lk_count, inodelk_cbk);
- if (ret < 0) {
- goto out;
- }
-
- local = lock_frame->local;
- local->main_frame = frame;
-
- local->call_cnt = lk_count;
-
- for (i = 0; i < local->lock.lk_count; i++) {
- flock.l_type = local->lock.locks[i]->type;
-
- STACK_WIND_COOKIE (lock_frame, dht_nonblocking_inodelk_cbk,
- (void *) (long) i,
- local->lock.locks[i]->xl,
- local->lock.locks[i]->xl->fops->inodelk,
- local->lock.locks[i]->domain,
- &local->lock.locks[i]->loc, F_SETLK,
- &flock, NULL);
- }
-
- return 0;
-
-out:
- if (lock_frame)
- dht_lock_stack_destroy (lock_frame);
-
- return -1;
-}
-
-int32_t
-dht_blocking_inodelk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
-{
- int lk_index = 0;
- dht_local_t *local = NULL;
-
- lk_index = (long) cookie;
-
- local = frame->local;
-
- if (op_ret == 0) {
- local->lock.locks[lk_index]->locked = _gf_true;
- } else {
- local->lock.op_ret = -1;
- local->lock.op_errno = op_errno;
- goto cleanup;
- }
-
- if (lk_index == (local->lock.lk_count - 1)) {
- dht_inodelk_done (frame);
- } else {
- dht_blocking_inodelk_rec (frame, ++lk_index);
- }
-
- return 0;
-
-cleanup:
- dht_inodelk_cleanup (frame);
-
- return 0;
-}
-
-void
-dht_blocking_inodelk_rec (call_frame_t *frame, int i)
-{
- dht_local_t *local = NULL;
- struct gf_flock flock = {0,};
-
- local = frame->local;
-
- flock.l_type = local->lock.locks[i]->type;
-
- STACK_WIND_COOKIE (frame, dht_blocking_inodelk_cbk,
- (void *) (long) i,
- local->lock.locks[i]->xl,
- local->lock.locks[i]->xl->fops->inodelk,
- local->lock.locks[i]->domain,
- &local->lock.locks[i]->loc, F_SETLKW, &flock, NULL);
-
- return;
-}
-
-int
-dht_lock_request_cmp (const void *val1, const void *val2)
-{
- dht_lock_t *lock1 = NULL;
- dht_lock_t *lock2 = NULL;
- int ret = 0;
-
- lock1 = *(dht_lock_t **)val1;
- lock2 = *(dht_lock_t **)val2;
-
- GF_VALIDATE_OR_GOTO ("dht-locks", lock1, out);
- GF_VALIDATE_OR_GOTO ("dht-locks", lock2, out);
-
- ret = strcmp (lock1->xl->name, lock2->xl->name);
-
- if (ret == 0) {
- ret = uuid_compare (lock1->loc.gfid, lock2->loc.gfid);
- }
-
-out:
- return ret;
-}
-
-int
-dht_lock_order_requests (dht_lock_t **locks, int count)
-{
- int ret = -1;
-
- if (!locks || !count)
- goto out;
-
- qsort (locks, count, sizeof (*locks), dht_lock_request_cmp);
- ret = 0;
-
-out:
- return ret;
-}
-
-int
-dht_blocking_inodelk (call_frame_t *frame, dht_lock_t **lk_array,
- int lk_count, fop_inodelk_cbk_t inodelk_cbk)
-{
- int ret = -1;
- call_frame_t *lock_frame = NULL;
- dht_local_t *local = NULL;
-
- GF_VALIDATE_OR_GOTO ("dht-locks", frame, out);
- GF_VALIDATE_OR_GOTO (frame->this->name, lk_array, out);
- GF_VALIDATE_OR_GOTO (frame->this->name, inodelk_cbk, out);
-
- lock_frame = dht_lock_frame (frame);
- if (lock_frame == NULL)
- goto out;
-
- ret = dht_local_lock_init (lock_frame, lk_array, lk_count, inodelk_cbk);
- if (ret < 0) {
- goto out;
- }
-
- local = lock_frame->local;
- local->main_frame = frame;
-
- dht_blocking_inodelk_rec (lock_frame, 0);
-
- return 0;
-out:
- if (lock_frame)
- dht_lock_stack_destroy (lock_frame);
-
- return -1;
-}
diff --git a/xlators/cluster/dht/src/dht-helper.h b/xlators/cluster/dht/src/dht-helper.h
deleted file mode 100644
index e3ab9c4d93b..00000000000
--- a/xlators/cluster/dht/src/dht-helper.h
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- Copyright (c) 2008-2014 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 _DHT_HELPER_H
-#define _DHT_HELPER_H
-
-int
-dht_lock_order_requests (dht_lock_t **lk_array, int count);
-
-void
-dht_blocking_inodelk_rec (call_frame_t *frame, int i);
-
-#endif
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 d78dd2ea0ef..00000000000
--- a/xlators/cluster/dht/src/dht-inode-read.c
+++ /dev/null
@@ -1,1140 +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) && !dht_inode_missing(op_errno)) {
- gf_msg_debug (this->name, 0,
- "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_msg_debug (this->name, 0,
- "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)
-{
- xlator_t *subvol = 0;
- dht_local_t *local = NULL;
- call_frame_t *prev = NULL;
- int ret = -1;
- inode_t *inode = 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;
-
- if ((op_ret == -1) && !dht_inode_missing(op_errno)) {
- local->op_errno = op_errno;
- gf_msg_debug (this->name, 0,
- "subvolume %s returned -1 (%s)",
- prev->this->name, strerror (op_errno));
- goto out;
- }
-
- if (local->call_cnt != 1)
- goto out;
-
- local->op_errno = op_errno;
- /* Check if the rebalance phase2 is true */
- if ((op_ret == -1) || IS_DHT_MIGRATION_PHASE2 (stbuf)) {
- inode = (local->fd) ? local->fd->inode : local->loc.inode;
- ret = dht_inode_ctx_get1 (this, inode, &subvol);
- if (!subvol) {
- /* Phase 2 of migration */
- local->rebalance.target_op_fn = dht_attr2;
- ret = dht_rebalance_complete_check (this, frame);
- if (!ret)
- return 0;
- } 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);
- 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_msg_debug (this->name, 0,
- "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_msg_debug (this->name, 0,
- "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_msg_debug (this->name, 0,
- "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;
- inode_t *inode = NULL;
- xlator_t *subvol = 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) && !dht_inode_missing(op_errno))
- goto out;
-
- local->op_errno = op_errno;
- if ((op_ret == -1) || IS_DHT_MIGRATION_PHASE2 (stbuf)) {
- /* File would be migrated to other node */
- ret = dht_inode_ctx_get1 (this, inode, &subvol);
- if (!subvol) {
- local->rebalance.target_op_fn = dht_readv2;
- ret = dht_rebalance_complete_check (this, frame);
- if (!ret)
- return 0;
- } 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);
- 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_msg_debug (this->name, 0,
- "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;
- xlator_t *subvol = NULL;
- call_frame_t *prev = NULL;
-
- local = frame->local;
- prev = cookie;
-
- if (!prev || !prev->this)
- goto out;
- if (local->call_cnt != 1)
- goto out;
- if ((op_ret == -1) && ((op_errno == ENOTCONN) ||
- dht_inode_missing(op_errno)) &&
- IA_ISDIR(local->loc.inode->ia_type)) {
- subvol = dht_subvol_next_available (this, prev->this);
- if (!subvol)
- goto out;
-
- /* check if we are done with visiting every node */
- if (subvol == local->cached_subvol) {
- goto out;
- }
-
- STACK_WIND (frame, dht_access_cbk, subvol, subvol->fops->access,
- &local->loc, local->rebalance.flags, NULL);
- return 0;
- }
- if ((op_ret == -1) && dht_inode_missing(op_errno) &&
- !(IA_ISDIR(local->loc.inode->ia_type))) {
- /* File would be migrated to other node */
- local->op_errno = op_errno;
- 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_msg_debug (this->name, 0,
- "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;
- inode_t *inode = NULL;
- xlator_t *subvol = 0;
-
- 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 */
- dht_inode_ctx_get1 (this, inode, &subvol);
- if (subvol) {
- 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;
-
- local = frame->local;
-
- dht_inode_ctx_get1 (this, local->fd->inode, &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_msg_debug (this->name, 0,
- "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;
- inode_t *inode = NULL;
- xlator_t *subvol = 0;
-
- local = frame->local;
- prev = cookie;
-
- local->op_errno = op_errno;
- if (op_ret == -1 && !dht_inode_missing(op_errno)) {
- gf_msg_debug (this->name, 0,
- "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->op_errno = op_errno;
- dht_inode_ctx_get1 (this, inode, &subvol);
- if (!subvol) {
- 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);
- }
- if (!ret)
- return 0;
- } else {
- dht_fsync2 (this, frame, 0);
- 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;
-
- local = frame->local;
-
- dht_inode_ctx_get1 (this, local->fd->inode, &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_msg_debug (this->name, 0,
- "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_msg_debug (this->name, 0,
- "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_msg_debug (this->name, 0,
- "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_msg_debug (this->name, 0,
- "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_msg_debug (this->name, 0,
- "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_msg_debug (this->name, 0,
- "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 2bfd80af3cd..00000000000
--- a/xlators/cluster/dht/src/dht-inode-write.c
+++ /dev/null
@@ -1,1017 +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_fallocate2(xlator_t *this, call_frame_t *frame, int op_ret);
-int dht_discard2(xlator_t *this, call_frame_t *frame, int op_ret);
-int dht_zerofill2(xlator_t *this, call_frame_t *frame, int op_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;
- xlator_t *subvol = NULL;
-
- if (op_ret == -1 && !dht_inode_missing(op_errno)) {
- 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;
-
- local->op_errno = op_errno;
- /* 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 = dht_inode_ctx_get1 (this, local->fd->inode, &subvol);
- if (subvol) {
- 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;
-
- local = frame->local;
-
- dht_inode_ctx_get1 (this, local->fd->inode, &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_msg_debug (this->name, 0,
- "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;
- xlator_t *subvol = NULL;
- inode_t *inode = 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;
-
- if ((op_ret == -1) && !dht_inode_missing(op_errno)) {
- local->op_errno = op_errno;
- local->op_ret = -1;
- gf_msg_debug (this->name, 0,
- "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;
-
- local->op_errno = op_errno;
- /* 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);
- inode = (local->fd) ? local->fd->inode : local->loc.inode;
- dht_inode_ctx_get1 (this, inode, &subvol);
- if (subvol) {
- 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;
- inode_t *inode = NULL;
-
- local = frame->local;
-
- inode = local->fd ? local->fd->inode : local->loc.inode;
-
- dht_inode_ctx_get1 (this, inode, &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_msg_debug (this->name, 0,
- "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_msg_debug (this->name, 0,
- "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;
-}
-
-
-int
-dht_fallocate_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;
- xlator_t *subvol = 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;
-
- if ((op_ret == -1) && !dht_inode_missing(op_errno)) {
- local->op_errno = op_errno;
- local->op_ret = -1;
- gf_msg_debug (this->name, 0,
- "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_fallocate2;
-
- /* 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);
- dht_inode_ctx_get1 (this, local->fd->inode, &subvol);
- if (subvol) {
- dht_fallocate2 (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 (fallocate, frame, op_ret, op_errno,
- prebuf, postbuf, xdata);
-err:
- return 0;
-}
-
-int
-dht_fallocate2(xlator_t *this, call_frame_t *frame, int op_ret)
-{
- dht_local_t *local = NULL;
- xlator_t *subvol = NULL;
-
- local = frame->local;
-
- dht_inode_ctx_get1 (this, local->fd->inode, &subvol);
-
- if (!subvol)
- subvol = local->cached_subvol;
-
- local->call_cnt = 2; /* This is the second attempt */
-
- STACK_WIND(frame, dht_fallocate_cbk, subvol, subvol->fops->fallocate,
- local->fd, local->rebalance.flags, local->rebalance.offset,
- local->rebalance.size, NULL);
-
- return 0;
-}
-
-int
-dht_fallocate(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t mode,
- off_t offset, size_t len, 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_FALLOCATE);
- if (!local) {
- op_errno = ENOMEM;
- goto err;
- }
-
- local->rebalance.flags = mode;
- local->rebalance.offset = offset;
- local->rebalance.size = len;
-
- local->call_cnt = 1;
- subvol = local->cached_subvol;
- if (!subvol) {
- gf_msg_debug (this->name, 0,
- "no cached subvolume for fd=%p", fd);
- op_errno = EINVAL;
- goto err;
- }
-
- STACK_WIND (frame, dht_fallocate_cbk,
- subvol, subvol->fops->fallocate,
- fd, mode, offset, len, xdata);
-
- return 0;
-
-err:
- op_errno = (op_errno == -1) ? errno : op_errno;
- DHT_STACK_UNWIND (fallocate, frame, -1, op_errno, NULL, NULL, NULL);
-
- return 0;
-}
-
-
-int
-dht_discard_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;
- xlator_t *subvol = 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;
-
- if ((op_ret == -1) && !dht_inode_missing(op_errno)) {
- local->op_errno = op_errno;
- local->op_ret = -1;
- gf_msg_debug (this->name, 0,
- "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_discard2;
-
- /* 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);
- dht_inode_ctx_get1 (this, local->fd->inode, &subvol);
- if (subvol) {
- dht_discard2 (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 (discard, frame, op_ret, op_errno,
- prebuf, postbuf, xdata);
-err:
- return 0;
-}
-
-int
-dht_discard2(xlator_t *this, call_frame_t *frame, int op_ret)
-{
- dht_local_t *local = NULL;
- xlator_t *subvol = NULL;
-
- local = frame->local;
-
- dht_inode_ctx_get1 (this, local->fd->inode, &subvol);
-
- if (!subvol)
- subvol = local->cached_subvol;
-
- local->call_cnt = 2; /* This is the second attempt */
-
- STACK_WIND(frame, dht_discard_cbk, subvol, subvol->fops->discard,
- local->fd, local->rebalance.offset, local->rebalance.size,
- NULL);
-
- return 0;
-}
-
-int
-dht_discard(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
- size_t len, 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_DISCARD);
- if (!local) {
- op_errno = ENOMEM;
- goto err;
- }
-
- local->rebalance.offset = offset;
- local->rebalance.size = len;
-
- local->call_cnt = 1;
- subvol = local->cached_subvol;
- if (!subvol) {
- gf_msg_debug (this->name, 0,
- "no cached subvolume for fd=%p", fd);
- op_errno = EINVAL;
- goto err;
- }
-
- STACK_WIND (frame, dht_discard_cbk, subvol, subvol->fops->discard,
- fd, offset, len, xdata);
-
- return 0;
-
-err:
- op_errno = (op_errno == -1) ? errno : op_errno;
- DHT_STACK_UNWIND (discard, frame, -1, op_errno, NULL, NULL, NULL);
-
- return 0;
-}
-
-int
-dht_zerofill_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) && !dht_inode_missing(op_errno)) {
- local->op_errno = op_errno;
- local->op_ret = -1;
- gf_msg_debug (this->name, 0,
- "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_zerofill2;
- /* 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_zerofill2 (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 (zerofill, frame, op_ret, op_errno,
- prebuf, postbuf, xdata);
-err:
- return 0;
-}
-
-int
-dht_zerofill2(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 */
-
- STACK_WIND(frame, dht_zerofill_cbk, subvol, subvol->fops->zerofill,
- local->fd, local->rebalance.offset, local->rebalance.size,
- NULL);
-
- return 0;
-}
-
-int
-dht_zerofill(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
- off_t len, 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_ZEROFILL);
- if (!local) {
- op_errno = ENOMEM;
- goto err;
- }
-
- local->rebalance.offset = offset;
- local->rebalance.size = len;
-
- local->call_cnt = 1;
- subvol = local->cached_subvol;
- if (!subvol) {
- gf_msg_debug (this->name, 0,
- "no cached subvolume for fd=%p", fd);
- op_errno = EINVAL;
- goto err;
- }
-
- STACK_WIND (frame, dht_zerofill_cbk, subvol, subvol->fops->zerofill,
- fd, offset, len, xdata);
-
- return 0;
-
-err:
- op_errno = (op_errno == -1) ? errno : op_errno;
- DHT_STACK_UNWIND (zerofill, 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) && !dht_inode_missing(op_errno)) {
- gf_msg_debug (this->name, 0,
- "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;
- inode_t *inode = NULL;
-
- local = frame->local;
-
- inode = (local->fd) ? local->fd->inode : local->loc.inode;
-
- dht_inode_ctx_get1 (this, inode, &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_msg_debug (this->name, 0,
- "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)) {
- if (local->op_ret == 0)
- dht_inode_ctx_time_set (local->loc.inode, this,
- &local->stbuf);
- 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_msg_debug (this->name, 0,
- "no layout for path=%s", loc->path);
- op_errno = EINVAL;
- goto err;
- }
-
- if (!layout_is_sane (layout)) {
- gf_msg_debug (this->name, 0,
- "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_msg_debug (this->name, 0,
- "no layout for fd=%p", fd);
- op_errno = EINVAL;
- goto err;
- }
-
- if (!layout_is_sane (layout)) {
- gf_msg_debug (this->name, 0,
- "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 34892983a55..e43be876a6b 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>
- 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-2009 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
@@ -18,8 +27,6 @@
#include "xlator.h"
#include "dht-common.h"
#include "byte-order.h"
-#include "dht-messages.h"
-
#define layout_base_size (sizeof (dht_layout_t))
@@ -27,32 +34,31 @@
#define layout_size(cnt) (layout_base_size + (cnt * layout_entry_size))
+
dht_layout_t *
dht_layout_new (xlator_t *this, int cnt)
{
- dht_layout_t *layout = NULL;
+ dht_layout_t *layout = NULL;
dht_conf_t *conf = NULL;
+
conf = this->private;
- layout = GF_CALLOC (1, layout_size (cnt),
- gf_dht_mt_dht_layout_t);
- if (!layout) {
- goto out;
- }
+ layout = CALLOC (1, layout_size (cnt));
+ if (!layout) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory");
+ goto out;
+ }
layout->type = DHT_HASH_TYPE_DM;
- layout->cnt = cnt;
-
- if (conf) {
- layout->spread_cnt = conf->dir_spread_cnt;
+ layout->cnt = cnt;
+ if (conf)
layout->gen = conf->gen;
- }
layout->ref = 1;
-
out:
- return layout;
+ return layout;
}
@@ -60,22 +66,21 @@ dht_layout_t *
dht_layout_get (xlator_t *this, inode_t *inode)
{
dht_conf_t *conf = NULL;
+ uint64_t layout_int = 0;
dht_layout_t *layout = NULL;
+ int ret = -1;
conf = this->private;
- if (!conf)
- goto out;
-
LOCK (&conf->layout_lock);
{
- dht_inode_ctx_layout_get (inode, this, &layout);
- if (layout) {
+ ret = inode_ctx_get (inode, this, &layout_int);
+ if (ret == 0) {
+ layout = (dht_layout_t *) (unsigned long) layout_int;
layout->ref++;
}
}
UNLOCK (&conf->layout_lock);
-out:
return layout;
}
@@ -87,24 +92,24 @@ dht_layout_set (xlator_t *this, inode_t *inode, dht_layout_t *layout)
int oldret = -1;
int ret = 0;
dht_layout_t *old_layout;
+ uint64_t old_layout_int;
conf = this->private;
- if (!conf)
- goto out;
-
LOCK (&conf->layout_lock);
{
- oldret = dht_inode_ctx_layout_get (inode, this, &old_layout);
+ oldret = inode_ctx_get (inode, this, &old_layout_int);
+
layout->ref++;
- dht_inode_ctx_layout_set (inode, this, layout);
+ ret = inode_ctx_put (inode, this, (uint64_t) (unsigned long)
+ layout);
}
UNLOCK (&conf->layout_lock);
- if (!oldret) {
+ if (oldret == 0) {
+ old_layout = (dht_layout_t *) (unsigned long) old_layout_int;
dht_layout_unref (this, old_layout);
}
-out:
return ret;
}
@@ -115,11 +120,10 @@ dht_layout_unref (xlator_t *this, dht_layout_t *layout)
dht_conf_t *conf = NULL;
int ref = 0;
- if (!layout || layout->preset || !this->private)
+ if (layout->preset)
return;
conf = this->private;
-
LOCK (&conf->layout_lock);
{
ref = --layout->ref;
@@ -127,7 +131,7 @@ dht_layout_unref (xlator_t *this, dht_layout_t *layout)
UNLOCK (&conf->layout_lock);
if (!ref)
- GF_FREE (layout);
+ FREE (layout);
}
@@ -136,7 +140,7 @@ dht_layout_ref (xlator_t *this, dht_layout_t *layout)
{
dht_conf_t *conf = NULL;
- if (layout->preset || !this->private)
+ if (layout->preset)
return layout;
conf = this->private;
@@ -153,639 +157,527 @@ dht_layout_ref (xlator_t *this, dht_layout_t *layout)
xlator_t *
dht_layout_search (xlator_t *this, dht_layout_t *layout, const char *name)
{
- uint32_t hash = 0;
+ uint32_t hash = 0;
xlator_t *subvol = NULL;
- int i = 0;
- int ret = 0;
+ int i = 0;
+ int ret = 0;
- ret = dht_hash_compute (this, layout->type, name, &hash);
- if (ret != 0) {
- gf_log (this->name, GF_LOG_WARNING,
- "hash computation failed for type=%d name=%s",
- layout->type, name);
- goto out;
- }
+ ret = dht_hash_compute (layout->type, name, &hash);
+ if (ret != 0) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "hash computation failed for type=%d name=%s",
+ layout->type, name);
+ goto out;
+ }
- for (i = 0; i < layout->cnt; i++) {
- if (layout->list[i].start <= hash
- && layout->list[i].stop >= hash) {
- subvol = layout->list[i].xlator;
- break;
- }
- }
+ for (i = 0; i < layout->cnt; i++) {
+ if (layout->list[i].start <= hash
+ && layout->list[i].stop >= hash) {
+ subvol = layout->list[i].xlator;
+ break;
+ }
+ }
- if (!subvol) {
- gf_log (this->name, GF_LOG_WARNING,
- "no subvolume for hash (value) = %u", hash);
- }
+ if (!subvol) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "no subvolume for hash (value) = %u", hash);
+ }
out:
- return subvol;
+ return subvol;
}
dht_layout_t *
dht_layout_for_subvol (xlator_t *this, xlator_t *subvol)
{
- dht_conf_t *conf = NULL;
- dht_layout_t *layout = NULL;
- int i = 0;
+ dht_conf_t *conf = NULL;
+ dht_layout_t *layout = NULL;
+ int i = 0;
- conf = this->private;
- if (!conf)
- goto out;
- for (i = 0; i < conf->subvolume_cnt; i++) {
- if (conf->subvolumes[i] == subvol) {
- layout = conf->file_layouts[i];
- break;
- }
- }
+ conf = this->private;
-out:
- return layout;
+ for (i = 0; i < conf->subvolume_cnt; i++) {
+ if (conf->subvolumes[i] == subvol) {
+ layout = conf->file_layouts[i];
+ break;
+ }
+ }
+
+ return layout;
}
int
dht_layouts_init (xlator_t *this, dht_conf_t *conf)
{
- dht_layout_t *layout = NULL;
- int i = 0;
- int ret = -1;
-
- if (!conf)
- goto out;
+ dht_layout_t *layout = NULL;
+ int i = 0;
+ int ret = -1;
+
+
+ conf->file_layouts = CALLOC (conf->subvolume_cnt,
+ sizeof (dht_layout_t *));
+ if (!conf->file_layouts) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory");
+ goto out;
+ }
- conf->file_layouts = GF_CALLOC (conf->subvolume_cnt,
- sizeof (dht_layout_t *),
- gf_dht_mt_dht_layout_t);
- if (!conf->file_layouts) {
- goto out;
- }
+ for (i = 0; i < conf->subvolume_cnt; i++) {
+ layout = dht_layout_new (this, 1);
- for (i = 0; i < conf->subvolume_cnt; i++) {
- layout = dht_layout_new (this, 1);
+ if (!layout) {
+ goto out;
+ }
- if (!layout) {
- goto out;
- }
+ layout->preset = 1;
- layout->preset = 1;
+ layout->list[0].xlator = conf->subvolumes[i];
- layout->list[0].xlator = conf->subvolumes[i];
-
- conf->file_layouts[i] = layout;
- }
+ conf->file_layouts[i] = layout;
+ }
- ret = 0;
+ ret = 0;
out:
- return ret;
+ return ret;
}
int
dht_disk_layout_extract (xlator_t *this, dht_layout_t *layout,
- int pos, int32_t **disk_layout_p)
+ int pos, int32_t **disk_layout_p)
{
- int ret = -1;
- int32_t *disk_layout = NULL;
-
- disk_layout = GF_CALLOC (5, sizeof (int),
- gf_dht_mt_int32_t);
- if (!disk_layout) {
- goto out;
- }
+ int ret = -1;
+ int32_t *disk_layout = NULL;
+
+ disk_layout = CALLOC (5, sizeof (int));
+ if (!disk_layout) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory");
+ goto out;
+ }
- disk_layout[0] = hton32 (1);
- disk_layout[1] = hton32 (layout->type);
- disk_layout[2] = hton32 (layout->list[pos].start);
- disk_layout[3] = hton32 (layout->list[pos].stop);
+ disk_layout[0] = hton32 (1);
+ disk_layout[1] = hton32 (layout->type);
+ disk_layout[2] = hton32 (layout->list[pos].start);
+ disk_layout[3] = hton32 (layout->list[pos].stop);
- if (disk_layout_p)
- *disk_layout_p = disk_layout;
- else
- GF_FREE (disk_layout);
-
- ret = 0;
+ if (disk_layout_p)
+ *disk_layout_p = disk_layout;
+ ret = 0;
out:
- return ret;
+ return ret;
}
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)
{
- int cnt = 0;
- int type = 0;
- int start_off = 0;
- int stop_off = 0;
- int disk_layout[4];
-
- if (!disk_layout_raw) {
- gf_msg (this->name, GF_LOG_CRITICAL, 0,
- DHT_MSG_LAYOUT_MERGE_FAILED,
- "error no layout on disk for merge");
- return -1;
- }
+ int cnt = 0;
+ int type = 0;
+ int start_off = 0;
+ int stop_off = 0;
- 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);
-
- cnt = ntoh32 (disk_layout[0]);
- if (cnt != 1) {
- gf_msg (this->name, GF_LOG_ERROR, 0,
- DHT_MSG_INVALID_DISK_LAYOUT,
- "Invalid disk layout: Invalid count %d", cnt);
- return -1;
- }
-
- type = ntoh32 (disk_layout[1]);
- switch (type) {
- case DHT_HASH_TYPE_DM_USER:
- gf_msg_debug (this->name, 0, "found user-set layout");
- layout->type = type;
- /* Fall through. */
- case DHT_HASH_TYPE_DM:
- break;
- default:
- gf_msg (this->name, GF_LOG_CRITICAL, 0,
- DHT_MSG_INVALID_DISK_LAYOUT,
- "Invalid disk layout: "
- "Catastrophic error layout with unknown type found %d",
- disk_layout[1]);
+ cnt = ntoh32 (disk_layout[0]);
+ if (cnt != 1) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "disk layout has invalid count %d", cnt);
return -1;
}
- start_off = ntoh32 (disk_layout[2]);
- stop_off = ntoh32 (disk_layout[3]);
+ /* TODO: assert type is compatible */
+ type = ntoh32 (disk_layout[1]);
+ start_off = ntoh32 (disk_layout[2]);
+ stop_off = ntoh32 (disk_layout[3]);
- layout->list[pos].start = start_off;
- layout->list[pos].stop = stop_off;
+ layout->list[pos].start = start_off;
+ layout->list[pos].stop = stop_off;
- gf_msg_trace (this->name, 0,
- "merged to layout: %u - %u (type %d) from %s",
- start_off, stop_off, type,
- layout->list[pos].xlator->name);
+ gf_log (this->name, GF_LOG_TRACE,
+ "merged to layout: %u - %u (type %d) from %s",
+ start_off, stop_off, type,
+ layout->list[pos].xlator->name);
- return 0;
+ return 0;
}
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 i = 0;
- int ret = -1;
- int err = -1;
- void *disk_layout_raw = NULL;
- int disk_layout_len = 0;
- dht_conf_t *conf = this->private;
-
- if (op_ret != 0) {
- err = op_errno;
- }
+ int i = 0;
+ int ret = -1;
+ int err = -1;
+ int32_t *disk_layout = NULL;
- for (i = 0; i < layout->cnt; i++) {
- if (layout->list[i].xlator == NULL) {
- layout->list[i].err = err;
- layout->list[i].xlator = subvol;
- break;
- }
- }
- if (op_ret != 0) {
- ret = 0;
- goto out;
- }
+ if (op_ret != 0) {
+ err = op_errno;
+ }
- if (xattr) {
- /* during lookup and not mkdir */
- ret = dict_get_ptr_and_len (xattr, conf->xattr_name,
- &disk_layout_raw, &disk_layout_len);
- }
+ for (i = 0; i < layout->cnt; i++) {
+ if (layout->list[i].xlator == NULL) {
+ layout->list[i].err = err;
+ layout->list[i].xlator = subvol;
+ break;
+ }
+ }
- if (ret != 0) {
- layout->list[i].err = 0;
- gf_msg_trace (this->name, 0,
- "Missing disk layout on %s. err = %d",
- subvol->name, err);
- ret = 0;
- goto out;
- }
+ if (op_ret != 0) {
+ ret = 0;
+ goto out;
+ }
- ret = dht_disk_layout_merge (this, layout, i, disk_layout_raw,
- disk_layout_len);
- if (ret != 0) {
- gf_msg (this->name, GF_LOG_WARNING, 0,
- DHT_MSG_LAYOUT_MERGE_FAILED,
- "layout merge from subvolume %s failed",
- subvol->name);
- goto out;
- }
- layout->list[i].err = 0;
+ if (xattr) {
+ /* during lookup and not mkdir */
+ ret = dict_get_ptr (xattr, "trusted.glusterfs.dht",
+ VOID(&disk_layout));
+ }
+
+ if (ret != 0) {
+ layout->list[i].err = -1;
+ gf_log (this->name, GF_LOG_TRACE,
+ "missing disk layout on %s. err = %d",
+ subvol->name, err);
+ ret = 0;
+ goto out;
+ }
+
+ ret = dht_disk_layout_merge (this, layout, i, disk_layout);
+ if (ret != 0) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "layout merge from subvolume %s failed",
+ subvol->name);
+ goto out;
+ }
+ layout->list[i].err = 0;
out:
- return ret;
+ return ret;
}
void
dht_layout_entry_swap (dht_layout_t *layout, int i, int j)
{
- uint32_t start_swap = 0;
- uint32_t stop_swap = 0;
- xlator_t *xlator_swap = 0;
- int err_swap = 0;
-
- start_swap = layout->list[i].start;
- stop_swap = layout->list[i].stop;
- xlator_swap = layout->list[i].xlator;
- err_swap = layout->list[i].err;
-
- layout->list[i].start = layout->list[j].start;
- layout->list[i].stop = layout->list[j].stop;
- layout->list[i].xlator = layout->list[j].xlator;
- layout->list[i].err = layout->list[j].err;
-
- layout->list[j].start = start_swap;
- layout->list[j].stop = stop_swap;
- layout->list[j].xlator = xlator_swap;
- layout->list[j].err = err_swap;
-}
-
-void
-dht_layout_range_swap (dht_layout_t *layout, int i, int j)
-{
- uint32_t start_swap = 0;
- uint32_t stop_swap = 0;
-
- start_swap = layout->list[i].start;
- stop_swap = layout->list[i].stop;
-
- layout->list[i].start = layout->list[j].start;
- layout->list[i].stop = layout->list[j].stop;
-
- layout->list[j].start = start_swap;
- layout->list[j].stop = stop_swap;
+ uint32_t start_swap = 0;
+ uint32_t stop_swap = 0;
+ xlator_t *xlator_swap = 0;
+ int err_swap = 0;
+
+
+ start_swap = layout->list[i].start;
+ stop_swap = layout->list[i].stop;
+ xlator_swap = layout->list[i].xlator;
+ err_swap = layout->list[i].err;
+
+ layout->list[i].start = layout->list[j].start;
+ layout->list[i].stop = layout->list[j].stop;
+ layout->list[i].xlator = layout->list[j].xlator;
+ layout->list[i].err = layout->list[j].err;
+
+ layout->list[j].start = start_swap;
+ layout->list[j].stop = stop_swap;
+ layout->list[j].xlator = xlator_swap;
+ layout->list[j].err = err_swap;
}
int64_t
dht_layout_entry_cmp_volname (dht_layout_t *layout, int i, int j)
{
- return (strcmp (layout->list[i].xlator->name,
- layout->list[j].xlator->name));
-}
-
-gf_boolean_t
-dht_is_subvol_in_layout (dht_layout_t *layout, xlator_t *xlator)
-{
- int i = 0;
-
- for (i = 0; i < layout->cnt; i++) {
- /* Check if xlator is already part of layout, and layout is
- * non-zero. */
- if (!strcmp (layout->list[i].xlator->name, xlator->name)) {
- if (layout->list[i].start != layout->list[i].stop)
- return _gf_true;
- break;
- }
- }
- return _gf_false;
+ return (strcmp (layout->list[i].xlator->name,
+ layout->list[j].xlator->name));
}
int64_t
dht_layout_entry_cmp (dht_layout_t *layout, int i, int j)
{
- int64_t diff = 0;
+ int64_t diff = 0;
- /* swap zero'ed out layouts to front, if needed */
- if (!layout->list[j].start && !layout->list[j].stop) {
- diff = (int64_t) layout->list[i].stop
- - (int64_t) layout->list[j].stop;
- goto out;
- }
- diff = (int64_t) layout->list[i].start
- - (int64_t) layout->list[j].start;
+ if (layout->list[i].err || layout->list[j].err)
+ diff = layout->list[i].err - layout->list[j].err;
+ else
+ diff = (int64_t) layout->list[i].start
+ - (int64_t) layout->list[j].start;
-out:
- return diff;
+ return diff;
}
int
dht_layout_sort (dht_layout_t *layout)
{
- int i = 0;
- int j = 0;
- int64_t ret = 0;
-
- /* TODO: O(n^2) -- bad bad */
-
- for (i = 0; i < layout->cnt - 1; i++) {
- for (j = i + 1; j < layout->cnt; j++) {
- ret = dht_layout_entry_cmp (layout, i, j);
- if (ret > 0)
- dht_layout_entry_swap (layout, i, j);
- }
- }
+ int i = 0;
+ int j = 0;
+ int64_t ret = 0;
+
+ /* TODO: O(n^2) -- bad bad */
+
+ for (i = 0; i < layout->cnt - 1; i++) {
+ for (j = i + 1; j < layout->cnt; j++) {
+ ret = dht_layout_entry_cmp (layout, i, j);
+ if (ret > 0)
+ dht_layout_entry_swap (layout, i, j);
+ }
+ }
- return 0;
+ return 0;
}
int
dht_layout_sort_volname (dht_layout_t *layout)
{
- int i = 0;
- int j = 0;
- int64_t ret = 0;
-
- /* TODO: O(n^2) -- bad bad */
-
- for (i = 0; i < layout->cnt - 1; i++) {
- for (j = i + 1; j < layout->cnt; j++) {
- ret = dht_layout_entry_cmp_volname (layout, i, j);
- if (ret > 0)
- dht_layout_entry_swap (layout, i, j);
- }
- }
+ int i = 0;
+ int j = 0;
+ int64_t ret = 0;
+
+ /* TODO: O(n^2) -- bad bad */
+
+ for (i = 0; i < layout->cnt - 1; i++) {
+ for (j = i + 1; j < layout->cnt; j++) {
+ ret = dht_layout_entry_cmp_volname (layout, i, j);
+ if (ret > 0)
+ dht_layout_entry_swap (layout, i, j);
+ }
+ }
- return 0;
+ return 0;
}
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,
- uint32_t *no_space_p)
+ uint32_t *holes_p, uint32_t *overlaps_p,
+ uint32_t *missing_p, uint32_t *down_p, uint32_t *misc_p)
{
- uint32_t overlaps = 0;
- uint32_t missing = 0;
- uint32_t down = 0;
- uint32_t misc = 0;
- uint32_t hole_cnt = 0;
- uint32_t overlap_cnt = 0;
- int i = 0;
- int ret = 0;
- uint32_t prev_stop = 0;
- uint32_t last_stop = 0;
- char is_virgin = 1;
- uint32_t no_space = 0;
-
- /* This funtion scans through the layout spread of a directory to
- check if there are any anomalies. Prior to calling this function
- the layout entries should be sorted in the ascending order.
-
- If the layout entry has err != 0
- then increment the corresponding anomaly.
- else
- if (start of the current layout entry > stop + 1 of previous
- non erroneous layout entry)
- then it indicates a hole in the layout
- if (start of the current layout entry < stop + 1 of previous
- non erroneous layout entry)
- then it indicates an overlap in the layout
- */
- last_stop = layout->list[0].start - 1;
- prev_stop = last_stop;
-
- for (i = 0; i < layout->cnt; i++) {
- switch (layout->list[i].err) {
- case -1:
- case ENOENT:
- case ESTALE:
- missing++;
- continue;
- case ENOTCONN:
- down++;
- continue;
- case ENOSPC:
- no_space++;
- continue;
- case 0:
- /* if err == 0 and start == stop, then it is a non misc++;
- * participating subvolume(spread-cnt). Then, do not
- * check for anomalies. If start != stop, then treat it
- * as misc err */
- if (layout->list[i].start == layout->list[i].stop) {
- continue;
- }
- break;
- default:
- misc++;
- continue;
- }
-
- is_virgin = 0;
-
- if ((prev_stop + 1) < layout->list[i].start) {
- hole_cnt++;
- }
-
- if ((prev_stop + 1) > layout->list[i].start) {
- overlap_cnt++;
- overlaps += ((prev_stop + 1) - layout->list[i].start);
- }
- prev_stop = layout->list[i].stop;
- }
-
- if ((last_stop - prev_stop) || is_virgin)
- hole_cnt++;
+ dht_conf_t *conf = NULL;
+ uint32_t holes = 0;
+ uint32_t overlaps = 0;
+ uint32_t missing = 0;
+ uint32_t down = 0;
+ uint32_t misc = 0;
+ uint32_t hole_cnt = 0;
+ uint32_t overlap_cnt = 0;
+ int i = 0;
+ int ret = 0;
+ uint32_t prev_stop = 0;
+ uint32_t last_stop = 0;
+ char is_virgin = 1;
+
+
+ conf = this->private;
+
+ /* TODO: explain WTF is happening */
+
+ last_stop = layout->list[0].start - 1;
+ prev_stop = last_stop;
+
+ for (i = 0; i < layout->cnt; i++) {
+ if (layout->list[i].err) {
+ switch (layout->list[i].err) {
+ case -1:
+ case ENOENT:
+ missing++;
+ break;
+ case ENOTCONN:
+ down++;
+ break;
+ case ENOSPC:
+ down++;
+ break;
+ default:
+ misc++;
+ }
+ continue;
+ }
+
+ is_virgin = 0;
+
+ if ((prev_stop + 1) < layout->list[i].start) {
+ hole_cnt++;
+ holes += (layout->list[i].start - (prev_stop + 1));
+ }
+
+ if ((prev_stop + 1) > layout->list[i].start) {
+ overlap_cnt++;
+ overlaps += ((prev_stop + 1) - layout->list[i].start);
+ }
+ prev_stop = layout->list[i].stop;
+ }
- if (holes_p)
- *holes_p = hole_cnt;
+ if ((last_stop - prev_stop) || is_virgin)
+ hole_cnt++;
+ holes += (last_stop - prev_stop);
- if (overlaps_p)
- *overlaps_p = overlap_cnt;
+ if (holes_p)
+ *holes_p = hole_cnt;
- if (missing_p)
- *missing_p = missing;
+ if (overlaps_p)
+ *overlaps_p = overlap_cnt;
- if (down_p)
- *down_p = down;
+ if (missing_p)
+ *missing_p = missing;
- if (misc_p)
- *misc_p = misc;
+ if (down_p)
+ *down_p = down;
- if (no_space_p)
- *no_space_p = no_space;
+ if (misc_p)
+ *misc_p = misc;
- return ret;
+ return ret;
}
int
dht_layout_normalize (xlator_t *this, loc_t *loc, dht_layout_t *layout)
{
- int ret = 0;
- int i = 0;
- uint32_t holes = 0;
- uint32_t overlaps = 0;
- uint32_t missing = 0;
- uint32_t down = 0;
- uint32_t misc = 0;
- char gfid[GF_UUID_BUF_SIZE] = {0};
-
- ret = dht_layout_sort (layout);
- if (ret == -1) {
- gf_log (this->name, GF_LOG_WARNING,
- "sort failed?! how the ....");
- goto out;
- }
-
- uuid_unparse(loc->gfid, gfid);
-
- ret = dht_layout_anomalies (this, loc, layout,
- &holes, &overlaps,
- &missing, &down, &misc, NULL);
- if (ret == -1) {
- gf_log (this->name, GF_LOG_WARNING,
- "Error finding anomalies in %s, gfid = %s",
- loc->path, gfid);
- goto out;
- }
+ int ret = 0;
+ int i = 0;
+ uint32_t holes = 0;
+ uint32_t overlaps = 0;
+ uint32_t missing = 0;
+ uint32_t down = 0;
+ uint32_t misc = 0;
+
+
+ ret = dht_layout_sort (layout);
+ if (ret == -1) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "sort failed?! how the ....");
+ goto out;
+ }
- if (holes || overlaps) {
- if (missing == layout->cnt) {
- gf_msg_debug (this->name, 0,
- "Directory %s looked up first time"
- " gfid = %s", loc->path, gfid);
- } else {
- gf_log (this->name, GF_LOG_INFO,
- "Found anomalies in %s (gfid = %s). "
- "Holes=%d overlaps=%d",
- loc->path, gfid, holes, overlaps );
- }
- ret = -1;
- }
+ ret = dht_layout_anomalies (this, loc, layout,
+ &holes, &overlaps,
+ &missing, &down, &misc);
+ if (ret == -1) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "error while finding anomalies in %s -- not good news",
+ loc->path);
+ goto out;
+ }
- 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()
- */
- 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++;
- }
- }
- }
+ if (holes || overlaps) {
+ if (missing == layout->cnt) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "directory %s looked up first time",
+ loc->path);
+ } else {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "found anomalies in %s. holes=%d overlaps=%d",
+ loc->path, holes, overlaps);
+ }
+ 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()
+ */
+ if (layout->list[i].err > 0) {
+ 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;
+ return ret;
}
-int
-dht_dir_has_layout (dict_t *xattr, char *name)
-{
-
- void *disk_layout_raw = NULL;
-
- return dict_get_ptr (xattr, name, &disk_layout_raw);
-}
int
dht_layout_dir_mismatch (xlator_t *this, dht_layout_t *layout, xlator_t *subvol,
- loc_t *loc, dict_t *xattr)
+ loc_t *loc, dict_t *xattr)
{
- int idx = 0;
- int pos = -1;
- int ret = 0;
- int err = 0;
- int dict_ret = 0;
- int32_t disk_layout[4];
- void *disk_layout_raw = NULL;
- int32_t count = -1;
- uint32_t start_off = -1;
- uint32_t stop_off = -1;
- dht_conf_t *conf = this->private;
- char gfid[GF_UUID_BUF_SIZE] = {0};
-
- if(loc && loc->inode)
- uuid_unparse(loc->inode->gfid, gfid);
-
- for (idx = 0; idx < layout->cnt; idx++) {
- if (layout->list[idx].xlator == subvol) {
- pos = idx;
- break;
- }
- }
-
- if (pos == -1) {
- gf_msg_debug (this->name, 0,
- "%s - no layout info for subvolume %s",
- loc->path, subvol->name);
- ret = 1;
- goto out;
- }
+ int idx = 0;
+ int pos = -1;
+ int ret = 0;
+ int err = 0;
+ int dict_ret = 0;
+ int32_t *disk_layout = NULL;
+ int32_t count = -1;
+ uint32_t start_off = -1;
+ uint32_t stop_off = -1;
+
+
+ for (idx = 0; idx < layout->cnt; idx++) {
+ if (layout->list[idx].xlator == subvol) {
+ pos = idx;
+ break;
+ }
+ }
+
+ if (pos == -1) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "%s - no layout info for subvolume %s",
+ loc->path, subvol->name);
+ ret = 1;
+ goto out;
+ }
err = layout->list[pos].err;
- if (!xattr) {
+ if (!xattr) {
if (err == 0) {
- gf_log (this->name, GF_LOG_INFO,
- "%s: xattr dictionary is NULL",
+ gf_log (this->name, GF_LOG_DEBUG,
+ "%s - xattr dictionary is NULL",
loc->path);
ret = -1;
}
- goto out;
- }
-
- dict_ret = dict_get_ptr (xattr, conf->xattr_name,
- &disk_layout_raw);
+ goto out;
+ }
- if (dict_ret < 0) {
- if (err == 0 && layout->list[pos].stop) {
- gf_log (this->name, GF_LOG_INFO,
- "%s: Disk layout missing, gfid = %s",
- loc->path, gfid);
+ dict_ret = dict_get_ptr (xattr, "trusted.glusterfs.dht",
+ VOID(&disk_layout));
+
+ if (dict_ret < 0) {
+ if (err == 0) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "%s - disk layout missing", loc->path);
ret = -1;
}
- goto out;
- }
-
- memcpy (disk_layout, disk_layout_raw, sizeof (disk_layout));
-
- count = ntoh32 (disk_layout[0]);
- if (count != 1) {
- gf_msg (this->name, GF_LOG_ERROR, 0,
- DHT_MSG_INVALID_DISK_LAYOUT,
- "Invalid disk layout: invalid count %d,"
- "path = %s, gfid = %s ", count, loc->path, gfid);
- ret = -1;
- goto out;
- }
+ goto out;
+ }
+
+ count = ntoh32 (disk_layout[0]);
+ if (count != 1) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "%s - disk layout has invalid count %d",
+ loc->path, count);
+ ret = -1;
+ goto out;
+ }
- start_off = ntoh32 (disk_layout[2]);
- stop_off = ntoh32 (disk_layout[3]);
-
- if ((layout->list[pos].start != start_off)
- || (layout->list[pos].stop != stop_off)) {
- gf_log (this->name, GF_LOG_INFO,
- "subvol: %s; inode layout - %"PRIu32" - %"PRIu32"; "
- "disk layout - %"PRIu32" - %"PRIu32,
- layout->list[pos].xlator->name,
- layout->list[pos].start, layout->list[pos].stop,
- start_off, stop_off);
- ret = 1;
- } else {
- ret = 0;
- }
+ start_off = ntoh32 (disk_layout[2]);
+ stop_off = ntoh32 (disk_layout[3]);
+
+ if ((layout->list[pos].start != start_off)
+ || (layout->list[pos].stop != stop_off)) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "subvol: %s; inode layout - %"PRId32" - %"PRId32"; "
+ "disk layout - %"PRId32" - %"PRId32,
+ layout->list[pos].xlator->name,
+ layout->list[pos].start, layout->list[pos].stop,
+ start_off, stop_off);
+ ret = 1;
+ } else {
+ ret = 0;
+ }
out:
- return ret;
+ return ret;
}
@@ -797,21 +689,19 @@ dht_layout_preset (xlator_t *this, xlator_t *subvol, inode_t *inode)
dht_conf_t *conf = NULL;
conf = this->private;
- if (!conf)
- goto out;
-
- layout = dht_layout_for_subvol (this, subvol);
- if (!layout) {
- gf_log (this->name, GF_LOG_INFO,
- "no pre-set layout for subvolume %s",
- subvol ? subvol->name : "<nil>");
- ret = -1;
- goto out;
- }
+
+ layout = dht_layout_for_subvol (this, subvol);
+ if (!layout) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "no pre-set layout for subvolume %s",
+ subvol ? subvol->name : "<nil>");
+ ret = -1;
+ goto out;
+ }
LOCK (&conf->layout_lock);
{
- dht_inode_ctx_layout_set (inode, this, layout);
+ inode_ctx_put (inode, this, (uint64_t)(long)layout);
}
UNLOCK (&conf->layout_lock);
diff --git a/xlators/cluster/dht/src/dht-linkfile.c b/xlators/cluster/dht/src/dht-linkfile.c
index 90892a8a9bd..77e7818ef85 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>
- 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-2009 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
@@ -18,338 +27,200 @@
#include "xlator.h"
#include "compat.h"
#include "dht-common.h"
-#include "dht-messages.h"
+
+
int
-dht_linkfile_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)
+dht_linkfile_xattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int op_ret, int op_errno)
{
- char is_linkfile = 0;
- dht_conf_t *conf = NULL;
- dht_local_t *local = NULL;
- call_frame_t *prev = NULL;
- char gfid[GF_UUID_BUF_SIZE] = {0};
-
- local = frame->local;
- prev = cookie;
- conf = this->private;
-
- if (op_ret)
- goto out;
-
- uuid_unparse(local->loc.gfid, gfid);
-
- is_linkfile = check_is_linkfile (inode, stbuf, xattr,
- conf->link_xattr_name);
- if (!is_linkfile)
- gf_log (this->name, GF_LOG_WARNING,
- "got non-linkfile %s:%s, gfid = %s",
- prev->this->name, local->loc.path, gfid);
-out:
- local->linkfile.linkfile_cbk (frame, cookie, this, op_ret, op_errno,
- inode, stbuf, postparent, postparent,
- xattr);
- return 0;
+ 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;
}
-#define is_equal(a, b) ((a) == (b))
+
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 stat *stbuf, struct stat *preparent,
+ struct stat *postparent)
{
- dht_local_t *local = NULL;
- xlator_t *subvol = NULL;
- call_frame_t *prev = NULL;
- dict_t *xattrs = NULL;
- dht_conf_t *conf = NULL;
- int ret = -1;
-
- local = frame->local;
-
- if (!op_ret)
- local->linked = _gf_true;
-
- FRAME_SU_UNDO (frame, dht_local_t);
-
- if (op_ret && (op_errno == EEXIST)) {
- conf = this->private;
- prev = cookie;
- subvol = prev->this;
- if (!subvol)
- goto out;
- xattrs = dict_new ();
- if (!xattrs)
- goto out;
- ret = dict_set_uint32 (xattrs, conf->link_xattr_name, 256);
- if (ret) {
- gf_msg (this->name, GF_LOG_ERROR, 0,
- DHT_MSG_DICT_SET_FAILED,
- "Failed to set dictionary value. key : %s",
- conf->link_xattr_name);
- goto out;
- }
-
- STACK_WIND (frame, dht_linkfile_lookup_cbk, subvol,
- subvol->fops->lookup, &local->loc, xattrs);
- if (xattrs)
- dict_unref (xattrs);
- return 0;
- }
-out:
+ 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)
+ goto err;
+
+ xattr = get_new_dict ();
+ if (!xattr) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory");
+ 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) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory");
+ op_errno = ENOMEM;
+ goto err;
+ }
+
+ ret = dict_set (xattr, "trusted.glusterfs.dht.linkto", str_data);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "failed to initialize linkfile data");
+ op_errno = EINVAL;
+ }
+ 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);
- if (xattrs)
- dict_unref (xattrs);
- return 0;
+ inode, stbuf, preparent, postparent);
+ return 0;
}
int
dht_linkfile_create (call_frame_t *frame, fop_mknod_cbk_t linkfile_cbk,
- xlator_t *this,
- xlator_t *tovol, xlator_t *fromvol, loc_t *loc)
+ xlator_t *tovol, xlator_t *fromvol, loc_t *loc)
{
- dht_local_t *local = NULL;
- dict_t *dict = NULL;
- int need_unref = 0;
- int ret = 0;
- dht_conf_t *conf = this->private;
- char gfid[GF_UUID_BUF_SIZE] = {0};
-
- local = frame->local;
- local->linkfile.linkfile_cbk = linkfile_cbk;
- local->linkfile.srcvol = tovol;
-
- local->linked = _gf_false;
-
- dict = local->params;
- if (!dict) {
- dict = dict_new ();
- if (!dict)
- goto out;
- need_unref = 1;
- }
-
-
- if (!uuid_is_null (local->gfid)) {
- uuid_unparse(local->gfid, gfid);
-
- ret = dict_set_static_bin (dict, "gfid-req", local->gfid, 16);
- if (ret)
- gf_msg ("dht-linkfile", GF_LOG_INFO, 0,
- DHT_MSG_DICT_SET_FAILED,
- "%s: Failed to set dictionary value: "
- "key = gfid-req, gfid = %s ", loc->path, gfid);
- } else {
- uuid_unparse(loc->gfid, gfid);
- }
-
- ret = dict_set_str (dict, GLUSTERFS_INTERNAL_FOP_KEY, "yes");
- if (ret)
- gf_msg ("dht-linkfile", GF_LOG_INFO, 0,
- DHT_MSG_DICT_SET_FAILED,
- "%s: Failed to set dictionary value: key = %s,"
- " gfid = %s", loc->path,
- GLUSTERFS_INTERNAL_FOP_KEY, gfid);
-
- ret = dict_set_str (dict, conf->link_xattr_name, tovol->name);
-
- if (ret < 0) {
- gf_msg (frame->this->name, GF_LOG_INFO, 0,
- DHT_MSG_CREATE_LINK_FAILED,
- "%s: failed to initialize linkfile data, gfid = %s",
- loc->path, gfid);
- goto out;
- }
-
- local->link_subvol = fromvol;
- /* Always create as root:root. dht_linkfile_attr_heal fixes the
- * ownsership */
- FRAME_SU_DO (frame, dht_local_t);
- STACK_WIND (frame, dht_linkfile_create_cbk,
- fromvol, fromvol->fops->mknod, loc,
- S_IFREG | DHT_LINKFILE_MODE, 0, 0, dict);
-
- if (need_unref && dict)
- dict_unref (dict);
-
- return 0;
-out:
- local->linkfile.linkfile_cbk (frame, NULL, frame->this, -1, ENOMEM,
- loc->inode, NULL, NULL, NULL, NULL);
+ dht_local_t *local = NULL;
+
+
+ local = frame->local;
+ local->linkfile.linkfile_cbk = linkfile_cbk;
+ local->linkfile.srcvol = tovol;
+ loc_copy (&local->linkfile.loc, loc);
- if (need_unref && dict)
- dict_unref (dict);
+ STACK_WIND (frame, dht_linkfile_create_cbk,
+ fromvol, fromvol->fops->mknod, loc,
+ S_IFREG | DHT_LINKFILE_MODE, 0);
- return 0;
+ return 0;
}
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)
+ int32_t op_ret, int32_t op_errno,
+ struct stat *preparent, struct stat *postparent)
{
- dht_local_t *local = NULL;
- call_frame_t *prev = NULL;
- xlator_t *subvol = NULL;
- char gfid[GF_UUID_BUF_SIZE] = {0};
+ dht_local_t *local = NULL;
+ call_frame_t *prev = NULL;
+ xlator_t *subvol = NULL;
- local = frame->local;
- prev = cookie;
- subvol = prev->this;
+ local = frame->local;
+ prev = cookie;
+ subvol = prev->this;
+ if (op_ret == -1) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "unlinking linkfile %s on %s failed (%s)",
+ local->loc.path, subvol->name, strerror (op_errno));
+ }
- if (op_ret == -1) {
+ DHT_STACK_DESTROY (frame);
- uuid_unparse(local->loc.gfid, gfid);
- gf_msg (this->name, GF_LOG_INFO, op_errno,
- DHT_MSG_UNLINK_FAILED,
- "Unlinking linkfile %s (gfid = %s)on "
- "subvolume %s failed ",
- local->loc.path, gfid, subvol->name);
- }
-
- DHT_STACK_DESTROY (frame);
-
- return 0;
+ return 0;
}
int
dht_linkfile_unlink (call_frame_t *frame, xlator_t *this,
- xlator_t *subvol, loc_t *loc)
+ xlator_t *subvol, loc_t *loc)
{
- call_frame_t *unlink_frame = NULL;
- dht_local_t *unlink_local = NULL;
-
- unlink_frame = copy_frame (frame);
- if (!unlink_frame) {
- 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);
- if (!unlink_local) {
- goto err;
- }
-
- STACK_WIND (unlink_frame, dht_linkfile_unlink_cbk,
- subvol, subvol->fops->unlink,
- &unlink_local->loc, 0, NULL);
-
- return 0;
+ call_frame_t *unlink_frame = NULL;
+ dht_local_t *unlink_local = NULL;
+
+ unlink_frame = copy_frame (frame);
+ if (!unlink_frame) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory");
+ goto err;
+ }
+
+ unlink_local = dht_local_init (unlink_frame);
+ if (!unlink_local) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory");
+ goto err;
+ }
+
+ loc_copy (&unlink_local->loc, loc);
+
+ STACK_WIND (unlink_frame, dht_linkfile_unlink_cbk,
+ subvol, subvol->fops->unlink,
+ &unlink_local->loc);
+
+ return 0;
err:
- if (unlink_frame)
- DHT_STACK_DESTROY (unlink_frame);
+ if (unlink_frame)
+ DHT_STACK_DESTROY (unlink_frame);
- return -1;
+ return -1;
}
xlator_t *
-dht_linkfile_subvol (xlator_t *this, inode_t *inode, struct iatt *stbuf,
- dict_t *xattr)
+dht_linkfile_subvol (xlator_t *this, inode_t *inode, struct stat *stbuf,
+ dict_t *xattr)
{
- dht_conf_t *conf = NULL;
- xlator_t *subvol = NULL;
- void *volname = NULL;
- int i = 0, ret = 0;
-
- conf = this->private;
-
- if (!xattr)
- goto out;
-
- ret = dict_get_ptr (xattr, conf->link_xattr_name, &volname);
+ dht_conf_t *conf = NULL;
+ xlator_t *subvol = NULL;
+ void *volname = NULL;
+ int i = 0, ret = 0;
- if ((-1 == ret) || !volname)
- goto out;
- for (i = 0; i < conf->subvolume_cnt; i++) {
- if (strcmp (conf->subvolumes[i]->name, (char *)volname) == 0) {
- subvol = conf->subvolumes[i];
- break;
- }
- }
+ conf = this->private;
-out:
- return subvol;
-}
-
-int
-dht_linkfile_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;
- loc_t *loc = NULL;
+ if (!xattr)
+ goto out;
- local = frame->local;
- loc = &local->loc;
+ ret = dict_get_ptr (xattr, "trusted.glusterfs.dht.linkto", &volname);
- if (op_ret)
- gf_msg (this->name, GF_LOG_ERROR, op_errno,
- DHT_MSG_SETATTR_FAILED,
- "Failed to set attr uid/gid on %s"
- " :<gfid:%s> ",
- (loc->path? loc->path: "NULL"),
- uuid_utoa(local->gfid));
+ if ((-1 == ret) || !volname)
+ goto out;
- DHT_STACK_DESTROY (frame);
+ for (i = 0; i < conf->subvolume_cnt; i++) {
+ if (strcmp (conf->subvolumes[i]->name, (char *)volname) == 0) {
+ subvol = conf->subvolumes[i];
+ break;
+ }
+ }
- return 0;
+out:
+ return subvol;
}
-int
-dht_linkfile_attr_heal (call_frame_t *frame, xlator_t *this)
-{
- int ret = -1;
- call_frame_t *copy = NULL;
- dht_local_t *local = NULL;
- dht_local_t *copy_local = NULL;
- xlator_t *subvol = NULL;
- struct iatt stbuf = {0,};
-
- local = frame->local;
-
- GF_VALIDATE_OR_GOTO ("dht", local, out);
- GF_VALIDATE_OR_GOTO ("dht", local->link_subvol, out);
-
- if (local->stbuf.ia_type == IA_INVAL)
- return 0;
- uuid_copy (local->loc.gfid, local->stbuf.ia_gfid);
-
- copy = copy_frame (frame);
-
- if (!copy)
- goto out;
-
- copy_local = dht_local_init (copy, &local->loc, NULL, 0);
-
- if (!copy_local)
- goto out;
-
- stbuf = local->stbuf;
- subvol = local->link_subvol;
-
- copy->local = copy_local;
-
- FRAME_SU_DO (copy, dht_local_t);
-
- STACK_WIND (copy, dht_linkfile_setattr_cbk, subvol,
- subvol->fops->setattr, &copy_local->loc,
- &stbuf, (GF_SET_ATTR_UID | GF_SET_ATTR_GID), NULL);
- ret = 0;
-out:
- return ret;
-}
diff --git a/xlators/cluster/dht/src/dht-mem-types.h b/xlators/cluster/dht/src/dht-mem-types.h
deleted file mode 100644
index e893eb48fd8..00000000000
--- a/xlators/cluster/dht/src/dht-mem-types.h
+++ /dev/null
@@ -1,35 +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 __DHT_MEM_TYPES_H__
-#define __DHT_MEM_TYPES_H__
-
-#include "mem-types.h"
-
-enum gf_dht_mem_types_ {
- gf_dht_mt_dht_du_t = gf_common_mt_end + 1,
- gf_dht_mt_dht_conf_t,
- gf_dht_mt_char,
- gf_dht_mt_int32_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_inode_ctx_t,
- gf_dht_mt_ctx_stat_time_t,
- gf_dht_mt_end
-};
-#endif
diff --git a/xlators/cluster/dht/src/dht-messages.h b/xlators/cluster/dht/src/dht-messages.h
deleted file mode 100644
index 80b20a61efd..00000000000
--- a/xlators/cluster/dht/src/dht-messages.h
+++ /dev/null
@@ -1,452 +0,0 @@
-/*Copyright (c) 2013 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 _DHT_MESSAGES_H_
-#define _DHT_MESSAGES_H_
-
-#ifndef _CONFIG_H
-#define _CONFIG_H
-#include "config.h"
-#endif
-
-#include "glfs-message-id.h"
-
-/*! \file dht-messages.h
- * \brief DHT log-message IDs and their descriptions
- *
- */
-
-/* NOTE: Rules for message additions
- * 1) Each instance of a message is _better_ left with a unique message ID, even
- * if the message format is the same. Reasoning is that, if the message
- * format needs to change in one instance, the other instances are not
- * impacted or the new change does not change the ID of the instance being
- * modified.
- * 2) Addition of a message,
- * - Should increment the GLFS_NUM_MESSAGES
- * - Append to the list of messages defined, towards the end
- * - Retain macro naming as glfs_msg_X (for redability across developers)
- * NOTE: Rules for message format modifications
- * 3) Check acorss the code if the message ID macro in question is reused
- * anywhere. If reused then then the modifications should ensure correctness
- * everywhere, or needs a new message ID as (1) above was not adhered to. If
- * not used anywhere, proceed with the required modification.
- * NOTE: Rules for message deletion
- * 4) Check (3) and if used anywhere else, then cannot be deleted. If not used
- * anywhere, then can be deleted, but will leave a hole by design, as
- * addition rules specify modification to the end of the list and not filling
- * holes.
- */
-
-#define GLFS_DHT_BASE GLFS_MSGID_COMP_DHT
-#define GLFS_DHT_NUM_MESSAGES 36
-#define GLFS_MSGID_END (GLFS_DHT_BASE + GLFS_DHT_NUM_MESSAGES + 1)
-
-/* Messages with message IDs */
-#define glfs_msg_start_x GLFS_DHT_BASE, "Invalid: Start of messages"
-
-
-
-
-/*!
- * @messageid 109001
- * @diagnosis Cached subvolume could not be found for the specified
- * path
- * @recommendedaction None
- *
- */
-
-#define DHT_MSG_CACHED_SUBVOL_GET_FAILED (GLFS_DHT_BASE + 1)
-
-/*!
- * @messageid 109002
- * @diagnosis Linkfile creation failed
- * @recommendedaction None
- *
- */
-
-#define DHT_MSG_CREATE_LINK_FAILED (GLFS_DHT_BASE + 2)
-
-/*!
- * @messageid 109003
- * @diagnosis The value could not be set for the specified key in
- * the dictionary
- *
- * @recommendedaction None
- *
- */
-
-#define DHT_MSG_DICT_SET_FAILED (GLFS_DHT_BASE + 3)
-
-/*!
- * @messageid 109004
- * @diagnosis Directory attributes could not be healed
- * @recommendedaction None
- *
- */
-
-#define DHT_MSG_DIR_ATTR_HEAL_FAILED (GLFS_DHT_BASE + 4)
-
-/*!
- * @messageid 109005
- * @diagnosis Self-heal failed for the specified directory
- * @recommendedaction Ensure that all subvolumes are online
- * and reachable and perform a lookup operation
- * on the directory again.
- *
- */
-
-#define DHT_MSG_DIR_SELFHEAL_FAILED (GLFS_DHT_BASE + 5)
-
-/*!
- * @messageid 109006
- * @diagnosis The extended attributes could not be healed for
- * the specified directory on the specified subvolume
- *
- * @recommendedaction None
- *
- */
-
-#define DHT_MSG_DIR_SELFHEAL_XATTR_FAILED (GLFS_DHT_BASE + 6)
-
-/*!
- * @messageid 109007
- * @diagnosis A lookup operation found the file with the same path
- * on multiple subvolumes.
- * @recommendedaction
- * 1. Create backups of the file on other subvolumes.
- * 2. Inspect the content of the files to identify
- * and retain the most appropriate file.
- *
- */
-
-#define DHT_MSG_FILE_ON_MULT_SUBVOL (GLFS_DHT_BASE + 7)
-
-/*!
- * @messageid 109008
- * @diagnosis A path resolves to a file on one subvolume and a directory
- * on another
- * @recommendedaction
- * 1. Create a backup of the file with a different name
- * and delete the original file.
- * 2. In the newly created back up file, remove the "trusted.gfid"
- * extended attribute.
- * - Command: setfattr -x "trusted.gfid" \<path to the newly created backup file\>
- * 3. Perform a new lookup operation on both the new and old paths.
- * 4. From the mount point, inspect both the paths and retain the
- * relevant file or directory.
- *
- */
-
-#define DHT_MSG_FILE_TYPE_MISMATCH (GLFS_DHT_BASE + 8)
-
-/*!
- * @messageid 109009
- * @diagnosis The GFID of the file/directory is different on different subvolumes
- * @recommendedaction None
- *
- */
-
-#define DHT_MSG_GFID_MISMATCH (GLFS_DHT_BASE + 9)
-
-/*!
- * @messageid 109010
- * @diagnosis The GFID of the specified file/directory is NULL.
- * @recommendedaction None
- *
- */
-
-#define DHT_MSG_GFID_NULL (GLFS_DHT_BASE + 10)
-
-/*!
- * @messageid 109011
- * @diagnosis The hashed subvolume could not be found for the specified
- * file/directory
- * @recommendedaction None
- *
- */
-
-#define DHT_MSG_HASHED_SUBVOL_GET_FAILED (GLFS_DHT_BASE + 11)
-
-/*!
- * @messageid 109012
- * @diagnosis The Distributed Hash Table Translator could not be initiated as the
- * system is out of memory.
- * @recommendedaction None
- *
- */
-
-#define DHT_MSG_INIT_FAILED (GLFS_DHT_BASE + 12)
-
-/*!
- * @messageid 109013
- * @diagnosis Invalid DHT configuration in the volfile
- * @recommendedaction None
- *
- */
-
-#define DHT_MSG_INVALID_CONFIGURATION (GLFS_DHT_BASE + 13)
-
-/*!
- * @messageid 109014
- * @diagnosis Invalid disk layout
- * @recommendedaction None
- *
- */
-
-#define DHT_MSG_INVALID_DISK_LAYOUT (GLFS_DHT_BASE + 14)
-
-/*!
- * @messageid 109015
- * @diagnosis Invalid DHT configuration option.
- * @recommendedaction
- * 1. Reset the option with a valid value using the volume
- * set command.
- * 2. Restart the process that logged the message in the
- * log file.
- *
- */
-
-#define DHT_MSG_INVALID_OPTION (GLFS_DHT_BASE + 15)
-
-/*!
- * @messageid 109016
- * @diagnosis The fix layout operation failed
- * @recommendedaction None
- *
- */
-
-#define DHT_MSG_LAYOUT_FIX_FAILED (GLFS_DHT_BASE + 16)
-
-/*!
- * @messageid 109017
- * @diagnosis Layout merge failed
- * @recommendedaction None
- *
- */
-
-#define DHT_MSG_LAYOUT_MERGE_FAILED (GLFS_DHT_BASE + 17)
-
-/*!
- * @messageid 109018
- * @diagnosis The layout for the specified directory does not match
- that on the disk.
- * @recommendedaction None
- *
- */
-
-#define DHT_MSG_LAYOUT_MISMATCH (GLFS_DHT_BASE + 18)
-
-/*!
- * @messageid 109019
- * @diagnosis No layout is present for the specified file/directory
- * @recommendedaction None
- *
- */
-
-#define DHT_MSG_LAYOUT_NULL (GLFS_DHT_BASE + 19)
-
-/*!
- * @messageid 109020
- * @diagnosis Informational message: Migration of data from the cached
- * subvolume to the hashed subvolume is complete
- * @recommendedaction None
- *
- */
-
-#define DHT_MSG_MIGRATE_DATA_COMPLETE (GLFS_DHT_BASE + 20)
-
-/*!
- * @messageid 109021
- * @diagnosis Migration of data failed during the rebalance operation
- * \n Cause: Directories could not be read to identify the files for the
- * migration process.
- * @recommendedaction
- * The log message would indicate the reason for the failure and
- * the corrective action depends on the specific error that is
- * encountered. The error is one of the standard UNIX errors.
- *
- */
-
-#define DHT_MSG_MIGRATE_DATA_FAILED (GLFS_DHT_BASE + 21)
-
-/*!
- * @messageid 109022
- * @diagnosis Informational message: The file was migrated successfully during
- * the rebalance operation.
- * @recommendedaction None
- *
- */
-
-#define DHT_MSG_MIGRATE_FILE_COMPLETE (GLFS_DHT_BASE + 22)
-
-/*!
- * @messageid 109023
- * @diagnosis File migration failed during the rebalance operation
- * \n Cause: Rebalance moves data from the cached subvolume to
- * the hashed subvolume. Migrating a single file is a multi-step operation
- * which involves opening, reading, and writing the data and metadata.
- * Any failures in this multi-step operation can result in a file
- * migration failure.
- * @recommendedaction The log message would indicate the reason for the failure and the
- * corrective action depends on the specific error that is encountered.
- * The error is one of the standard UNIX errors.
- *
- */
-
-#define DHT_MSG_MIGRATE_FILE_FAILED (GLFS_DHT_BASE + 23)
-
-/*!
- * @messageid 109024
- * @diagnosis Out of memory
- * @recommendedaction None
- *
- */
-
-#define DHT_MSG_NO_MEMORY (GLFS_DHT_BASE + 24)
-
-/*!
- * @messageid 109025
- * @diagnosis The opendir() call failed on the specified directory
- * \n Cause: When a directory is renamed, the Distribute Hash
- * table translator checks whether the destination directory
- * is empty. This message indicates that the opendir() call
- * on the destination directory has failed.
- * @recommendedaction The log message would indicate the reason for the
- * failure and the corrective action depends on the specific
- * error that is encountered. The error is one of the standard
- * UNIX errors.
- *
- */
-
-#define DHT_MSG_OPENDIR_FAILED (GLFS_DHT_BASE + 25)
-
-/*!
- * @messageid 109026
- * @diagnosis The rebalance operation failed.
- * @recommendedaction Check the log file for details about the failure.
- * Possible causes:
- * - A subvolume is down: Restart the rebalance operation after
- * bringing up all subvolumes.
- *
- */
-
-#define DHT_MSG_REBALANCE_FAILED (GLFS_DHT_BASE + 26)
-
-/*!
- * @messageid 109027
- * @diagnosis Failed to start the rebalance process.
- * @recommendedaction Check the log file for details about the failure.
- *
- */
-
-#define DHT_MSG_REBALANCE_START_FAILED (GLFS_DHT_BASE + 27)
-
-/*!
- * @messageid 109028
- * @diagnosis Informational message that indicates the status of the
- * rebalance operation and details as to how many files were
- * migrated, skipped, failed etc
- * @recommendedaction None
- *
- */
-
-#define DHT_MSG_REBALANCE_STATUS (GLFS_DHT_BASE + 28)
-
-/*!
- * @messageid 109029
- * @diagnosis The rebalance operation was aborted by the user.
- * @recommendedaction None
- *
- */
-
-#define DHT_MSG_REBALANCE_STOPPED (GLFS_DHT_BASE + 29)
-
-/*!
- * @messageid 109030
- * @diagnosis The file or directory could not be renamed
- * @recommendedaction Ensure that all the subvolumes are
- * online and reachable and try renaming
- * the file or directory again.
- *
- */
-
-#define DHT_MSG_RENAME_FAILED (GLFS_DHT_BASE + 30)
-
-/*!
- * @messageid 109031
- * @diagnosis Attributes could not be set for the specified file or
- * directory.
- * @recommendedaction None
- *
- */
-
-#define DHT_MSG_SETATTR_FAILED (GLFS_DHT_BASE + 31)
-
-/*!
- * @messageid 109032
- * @diagnosis The specified subvolume is running out of file system inodes.
- If all subvolumes run out of inodes, then new files cannot be created.
- * @recommendedaction Consider adding more nodes to the cluster if all subvolumes
- * run out of inodes
- *
- */
-
-#define DHT_MSG_SUBVOL_INSUFF_INODES (GLFS_DHT_BASE + 32)
-
-/*!
- * @messageid 109033
- * @diagnosis The specified subvolume is running out of disk space. If all
- subvolumes run out of space, new files cannot be created.
- * @recommendedaction Consider adding more nodes to the cluster if all subvolumes
- * run out of disk space.
- *
- */
-
-#define DHT_MSG_SUBVOL_INSUFF_SPACE (GLFS_DHT_BASE + 33)
-
-/*!
- * @messageid 109034
- * @diagnosis Failed to unlink the specified file/directory
- * @recommendedaction The log message would indicate the reason
- for the failure and the corrective action depends on
- the specific error that is encountered.
- */
-
-#define DHT_MSG_UNLINK_FAILED (GLFS_DHT_BASE + 34)
-
-
-
-/*!
- * @messageid 109035
- * @diagnosis The layout information could not be set in the inode
- * @recommendedaction None
- *
- */
-
-#define DHT_MSG_LAYOUT_SET_FAILED (GLFS_DHT_BASE + 35)
-
-/*!
- * @messageid 109036
- * @diagnosis Informational message regarding layout range distribution
- * for a directory across subvolumes
- * @recommendedaction None
- */
-
-#define DHT_MSG_LOG_FIXED_LAYOUT (GLFS_DHT_BASE + 36)
-
-/*------------*/
-#define glfs_msg_end_x GLFS_MSGID_END, "Invalid: End of messages"
-
-
-#endif /* _DHT_MESSAGES_H_ */
-
-
-
-
diff --git a/xlators/cluster/dht/src/dht-rebalance.c b/xlators/cluster/dht/src/dht-rebalance.c
deleted file mode 100644
index 65354bb721a..00000000000
--- a/xlators/cluster/dht/src/dht-rebalance.c
+++ /dev/null
@@ -1,2145 +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"
-#include <signal.h>
-#include <fnmatch.h>
-#include <signal.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 (-ret));
- ret = -1;
- 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 (-ret));
- ret = -1;
- goto out;
- }
- }
-
- size_pending = (size - buf_len);
- if (!size_pending)
- break;
- }
-
- ret = size;
-out:
- return ret;
-
-}
-
-/*
- return values:
- -1 : failure
- -2 : success
-
-Hard link migration is carried out in three stages.
-
-(Say there are n hardlinks)
-Stage 1: Setting the new hashed subvol information on the 1st hardlink
- encountered (linkto setxattr)
-
-Stage 2: Creating hardlinks on new hashed subvol for the 2nd to (n-1)th
- hardlink
-
-Stage 3: Physical migration of the data file for nth hardlink
-
-Why to deem "-2" as success and not "0":
-
- dht_migrate_file expects return value "0" from _is_file_migratable if
-the file has to be migrated.
-
- _is_file_migratable returns zero only when it is called with the
-flag "GF_DHT_MIGRATE_HARDLINK_IN_PROGRESS".
-
- gf_defrag_handle_hardlink calls dht_migrate_file for physical migration
-of the data file with the flag "GF_DHT_MIGRATE_HARDLINK_IN_PROGRESS"
-
-Hence, gf_defrag_handle_hardlink returning "0" for success will force
-"dht_migrate_file" to migrate each of the hardlink which is not intended.
-
-For each of the three stage mentioned above "-2" will be returned and will
-be converted to "0" in dht_migrate_file.
-
-*/
-
-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;
- dht_conf_t *conf = NULL;
- gf_loglevel_t loglevel = 0;
- dict_t *link_xattr = NULL;
-
- 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);
- GF_VALIDATE_OR_GOTO ("defrag", this->private, out);
-
- conf = this->private;
-
- if (uuid_is_null (loc->pargfid)) {
- gf_msg ("", GF_LOG_ERROR, 0,
- DHT_MSG_MIGRATE_FILE_FAILED,
- "Migrate file failed :"
- "loc->pargfid is NULL for %s", loc->path);
- goto out;
- }
-
- if (uuid_is_null (loc->gfid)) {
- gf_msg ("", GF_LOG_ERROR, 0,
- DHT_MSG_MIGRATE_FILE_FAILED,
- "Migrate file failed :"
- "loc->gfid is NULL for %s", loc->path);
- goto out;
- }
-
- link_xattr = dict_new ();
- if (!link_xattr) {
- ret = -1;
- errno = ENOMEM;
- goto out;
- }
-
- cached_subvol = dht_subvol_get_cached (this, loc->inode);
- if (!cached_subvol) {
- gf_msg (this->name, GF_LOG_ERROR, 0,
- DHT_MSG_MIGRATE_FILE_FAILED,
- "Migrate file failed :"
- "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_msg (this->name, GF_LOG_ERROR, 0,
- DHT_MSG_MIGRATE_FILE_FAILED,
- "Migrate file failed :"
- "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, conf->link_xattr_name);
- /* set linkto on cached -> hashed if not present, else link it */
- if (!data) {
- ret = dict_set_str (link_xattr, conf->link_xattr_name,
- hashed_subvol->name);
- if (ret) {
- gf_msg (this->name, GF_LOG_ERROR, 0,
- DHT_MSG_MIGRATE_FILE_FAILED,
- "Migrate file failed :"
- "Failed to set dictionary value:"
- " key = %s for %s",
- conf->link_xattr_name, loc->name);
- goto out;
- }
-
- ret = syncop_setxattr (cached_subvol, loc, link_xattr, 0);
- if (ret) {
- gf_msg (this->name, GF_LOG_ERROR, 0,
- DHT_MSG_MIGRATE_FILE_FAILED,
- "Migrate file failed :"
- "Linkto setxattr failed %s -> %s (%s)",
- cached_subvol->name,
- loc->name, strerror (-ret));
- ret = -1;
- goto out;
- }
- ret = -2;
- 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 = -ret;
- ret = -1;
-
- loglevel = (op_errno == EEXIST) ? GF_LOG_DEBUG : \
- GF_LOG_ERROR;
- gf_log (this->name, loglevel, "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_msg (this->name, GF_LOG_ERROR, -ret,
- DHT_MSG_MIGRATE_FILE_FAILED,
- "Migrate file failed :Failed lookup %s on %s ",
- loc->name, hashed_subvol->name);
-
- ret = -1;
- 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 = -2;
-out:
- if (link_xattr)
- dict_unref (link_xattr);
- return ret;
-}
-
-/*
- return values
- 0 : File will be migrated
- -2 : File will not be migrated
- (This is the return value from gf_defrag_handle_hardlink. Checkout
- gf_defrag_handle_hardlink for description of "returning -2")
- -1 : failure
-*/
-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_msg (this->name, GF_LOG_WARNING, 0,
- DHT_MSG_MIGRATE_FILE_FAILED,
- "Migrate file failed:"
- "%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);
-
- /*
- Returning zero will force the file to be remigrated.
- Checkout gf_defrag_handle_hardlink for more information.
- */
- if (ret && ret != -2) {
- gf_msg (this->name, GF_LOG_WARNING, 0,
- DHT_MSG_MIGRATE_FILE_FAILED,
- "Migrate file failed:"
- "%s: failed to migrate file with link",
- loc->path);
- }
- } else {
- gf_msg (this->name, GF_LOG_WARNING, 0,
- DHT_MSG_MIGRATE_FILE_FAILED,
- "Migrate file failed:"
- "%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, dict_t *xattr)
-{
- xlator_t *this = NULL;
- int ret = -1;
- fd_t *fd = NULL;
- struct iatt new_stbuf = {0,};
- struct iatt check_stbuf= {0,};
- dht_conf_t *conf = NULL;
-
- this = THIS;
- conf = this->private;
-
- ret = dict_set_static_bin (dict, "gfid-req", stbuf->ia_gfid, 16);
- if (ret) {
- gf_msg (this->name, GF_LOG_ERROR, 0,
- DHT_MSG_DICT_SET_FAILED,
- "%s: failed to set dictionary value: key = gfid-req",
- loc->path);
- goto out;
- }
-
- ret = dict_set_str (dict, conf->link_xattr_name, from->name);
- if (ret) {
- gf_msg (this->name, GF_LOG_ERROR, 0,
- DHT_MSG_DICT_SET_FAILED,
- "%s: failed to set dictionary value: key = %s ",
- loc->path, conf->link_xattr_name);
- goto out;
- }
-
- fd = fd_create (loc->inode, DHT_REBALANCE_PID);
- if (!fd) {
- gf_msg (this->name, GF_LOG_ERROR, 0,
- DHT_MSG_MIGRATE_FILE_FAILED,
- "%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_msg (this->name, GF_LOG_ERROR, 0,
- DHT_MSG_GFID_MISMATCH,
- "file %s exists in %s with different gfid",
- loc->path, to->name);
- fd_unref (fd);
- goto out;
- }
- }
- if ((ret < 0) && (-ret != ENOENT)) {
- /* File exists in destination, but not accessible */
- gf_msg (THIS->name, GF_LOG_WARNING, 0,
- DHT_MSG_MIGRATE_FILE_FAILED,
- "%s: failed to lookup file (%s)",
- loc->path, strerror (-ret));
- ret = -1;
- 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, &new_stbuf);
- if (ret < 0) {
- gf_msg (this->name, GF_LOG_ERROR, 0,
- DHT_MSG_MIGRATE_FILE_FAILED,
- "failed to create %s on %s (%s)",
- loc->path, to->name, strerror (-ret));
- ret = -1;
- goto out;
- }
-
-
- /*Reason of doing lookup after create again:
- *In the create, there is some time-gap between opening fd at the
- *server (posix_layer) and binding it in server (incrementing fd count),
- *so if in that time-gap, if other process sends unlink considering it
- *as a linkto file, because inode->fd count will be 0, so file will be
- *unlinked at the backend. And because furthur operations are performed
- *on fd, so though migration will be done but will end with no file
- *at the backend.
- */
-
-
- ret = syncop_lookup (to, loc, NULL, &check_stbuf, NULL, NULL);
- if (!ret) {
-
- if (uuid_compare (stbuf->ia_gfid, check_stbuf.ia_gfid) != 0) {
- gf_msg (this->name, GF_LOG_ERROR, 0,
- DHT_MSG_GFID_MISMATCH,
- "file %s exists in %s with different gfid,"
- "found in lookup after create",
- loc->path, to->name);
- ret = -1;
- fd_unref (fd);
- goto out;
- }
-
- }
-
- if (-ret == ENOENT) {
- gf_msg (this->name, GF_LOG_ERROR, 0,
- DHT_MSG_MIGRATE_FILE_FAILED, "%s: file does not exists"
- "on %s (%s)", loc->path, to->name, strerror (-ret));
- ret = -1;
- fd_unref (fd);
- goto out;
- }
-
- ret = syncop_fsetxattr (to, fd, xattr, 0);
- if (ret < 0)
- gf_msg (this->name, GF_LOG_WARNING, 0,
- DHT_MSG_MIGRATE_FILE_FAILED,
- "%s: failed to set xattr on %s (%s)",
- loc->path, to->name, strerror (-ret));
-
- ret = syncop_ftruncate (to, fd, stbuf->ia_size);
- if (ret < 0)
- gf_msg (this->name, GF_LOG_ERROR, 0,
- DHT_MSG_MIGRATE_FILE_FAILED,
- "ftruncate failed for %s on %s (%s)",
- loc->path, to->name, strerror (-ret));
-
- ret = syncop_fsetattr (to, fd, stbuf,
- (GF_SET_ATTR_UID | GF_SET_ATTR_GID),
- NULL, NULL);
- if (ret < 0)
- gf_msg (this->name, GF_LOG_ERROR, 0,
- DHT_MSG_MIGRATE_FILE_FAILED,
- "chown failed for %s on %s (%s)",
- loc->path, to->name, strerror (-ret));
-
- 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;
-
- uint64_t src_statfs_blocks = 1;
- uint64_t dst_statfs_blocks = 1;
-
- this = THIS;
-
- ret = syncop_statfs (from, loc, &src_statfs);
- if (ret) {
- gf_msg (this->name, GF_LOG_ERROR, 0,
- DHT_MSG_MIGRATE_FILE_FAILED,
- "failed to get statfs of %s on %s (%s)",
- loc->path, from->name, strerror (-ret));
- ret = -1;
- goto out;
- }
-
- ret = syncop_statfs (to, loc, &dst_statfs);
- if (ret) {
- gf_msg (this->name, GF_LOG_ERROR, 0,
- DHT_MSG_MIGRATE_FILE_FAILED,
- "failed to get statfs of %s on %s (%s)",
- loc->path, to->name, strerror (-ret));
- ret = -1;
- 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;
-
- /* Check:
- During rebalance `migrate-data` - Destination subvol experiences
- a `reduction` in 'blocks' of free space, at the same time source
- subvol gains certain 'blocks' of free space. A valid check is
- necessary here to avoid errorneous move to destination where
- the space could be scantily available.
- */
- if (stbuf) {
- dst_statfs_blocks = ((dst_statfs.f_bavail *
- dst_statfs.f_bsize) /
- GF_DISK_SECTOR_SIZE);
- src_statfs_blocks = ((src_statfs.f_bavail *
- src_statfs.f_bsize) /
- GF_DISK_SECTOR_SIZE);
- if ((dst_statfs_blocks - stbuf->ia_blocks) <
- (src_statfs_blocks + stbuf->ia_blocks)) {
-
- gf_msg (this->name, GF_LOG_WARNING, 0,
- DHT_MSG_MIGRATE_FILE_FAILED,
- "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_msg (this->name, GF_LOG_ERROR, 0,
- DHT_MSG_MIGRATE_FILE_FAILED,
- "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;
- else
- ret = -1;
-
- 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,};
- dht_conf_t *conf = NULL;
-
- this = THIS;
- conf = this->private;
-
- fd = fd_create (loc->inode, DHT_REBALANCE_PID);
- if (!fd) {
- gf_msg (this->name, GF_LOG_ERROR, 0,
- DHT_MSG_MIGRATE_FILE_FAILED,
- "%s: fd create failed (source)", loc->path);
- ret = -1;
- goto out;
- }
-
- ret = syncop_open (from, loc, O_RDWR, fd);
- if (ret < 0) {
- gf_msg (this->name, GF_LOG_ERROR, 0,
- DHT_MSG_MIGRATE_FILE_FAILED,
- "failed to open file %s on %s (%s)",
- loc->path, from->name, strerror (-ret));
- ret = -1;
- goto out;
- }
-
- ret = -1;
- dict = dict_new ();
- if (!dict)
- goto out;
-
- ret = dict_set_str (dict, conf->link_xattr_name, 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_msg (this->name, GF_LOG_ERROR, 0,
- DHT_MSG_MIGRATE_FILE_FAILED,
- "failed to set xattr on %s in %s (%s)",
- loc->path, from->name, strerror (-ret));
- ret = -1;
- 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_msg (this->name, GF_LOG_ERROR, 0,
- DHT_MSG_MIGRATE_FILE_FAILED,
- "failed to set mode on %s in %s (%s)",
- loc->path, from->name, strerror (-ret));
- ret = -1;
- 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,};
- dht_conf_t *conf = this->private;
-
- dict = dict_new ();
- if (!dict)
- goto out;
-
- ret = dict_set_int32 (dict, conf->link_xattr_name, 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 < 0) && (-ret != ENOENT)) {
- gf_msg (this->name, GF_LOG_WARNING, 0,
- DHT_MSG_MIGRATE_FILE_FAILED,
- "%s: lookup failed (%s)",
- loc->path, strerror (-ret));
- ret = -1;
- goto out;
- }
-
- /* we no more require this key */
- dict_del (dict, conf->link_xattr_name);
-
- /* 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,
- conf->link_xattr_name)) {
- gf_msg (this->name, GF_LOG_WARNING, 0,
- DHT_MSG_MIGRATE_FILE_FAILED,
- "%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_msg (this->name, GF_LOG_WARNING, 0,
- DHT_MSG_MIGRATE_FILE_FAILED,
- "%s: failed to delete the linkfile (%s)",
- loc->path, strerror (-ret));
- ret = -1;
- 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_msg (this->name, GF_LOG_WARNING, 0,
- DHT_MSG_MIGRATE_FILE_FAILED,
- "%s: readlink on symlink failed (%s)",
- loc->path, strerror (-ret));
- ret = -1;
- goto out;
- }
-
- ret = syncop_symlink (to, loc, link, dict, 0);
- if (ret) {
- gf_msg (this->name, GF_LOG_WARNING, 0,
- DHT_MSG_MIGRATE_FILE_FAILED,
- "%s: creating symlink failed (%s)",
- loc->path, strerror (-ret));
- ret = -1;
- 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, 0);
- if (ret) {
- gf_msg (this->name, GF_LOG_WARNING, 0,
- DHT_MSG_MIGRATE_FILE_FAILED,
- "%s: mknod failed (%s)",
- loc->path, strerror (-ret));
- ret = -1;
- goto out;
- }
-
-done:
- ret = syncop_setattr (to, loc, buf,
- (GF_SET_ATTR_UID | GF_SET_ATTR_GID |
- GF_SET_ATTR_MODE), NULL, NULL);
- if (ret) {
- gf_msg (this->name, GF_LOG_WARNING, 0,
- DHT_MSG_MIGRATE_FILE_FAILED,
- "%s: failed to perform setattr on %s (%s)",
- loc->path, to->name, strerror (-ret));
- ret = -1;
- }
-
- ret = syncop_unlink (from, loc);
- if (ret) {
- gf_msg (this->name, GF_LOG_WARNING, 0,
- DHT_MSG_MIGRATE_FILE_FAILED,
- "%s: unlink failed (%s)",
- loc->path, strerror (-ret));
- ret = -1;
- }
-
-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;
- dht_conf_t *conf = this->private;
- int rcvd_enoent_from_src = 0;
- struct gf_flock flock = {0, };
- loc_t tmp_loc = {0, };
- gf_boolean_t locked = _gf_false;
-
- 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, conf->link_xattr_name, 256);
- if (ret) {
- gf_msg (this->name, GF_LOG_ERROR, 0,
- DHT_MSG_MIGRATE_FILE_FAILED,
- "Migrate file failed:"
- "%s: failed to set 'linkto' key in dict", loc->path);
- goto out;
- }
-
- flock.l_type = F_WRLCK;
-
- tmp_loc.inode = inode_ref (loc->inode);
- uuid_copy (tmp_loc.gfid, loc->gfid);
-
- ret = syncop_inodelk (from, DHT_FILE_MIGRATE_DOMAIN, &tmp_loc, F_SETLKW,
- &flock, NULL, NULL);
- if (ret < 0) {
- gf_msg (this->name, GF_LOG_WARNING, 0,
- DHT_MSG_MIGRATE_FILE_FAILED,
- "migrate file failed: "
- "%s: failed to lock file on %s (%s)",
- loc->path, from->name, strerror (-ret));
- ret = -1;
- goto out;
- }
-
- locked = _gf_true;
-
- /* Phase 1 - Data migration is in progress from now on */
- ret = syncop_lookup (from, loc, dict, &stbuf, &xattr_rsp, NULL);
- if (ret) {
- gf_msg (this->name, GF_LOG_ERROR, 0,
- DHT_MSG_MIGRATE_FILE_FAILED,
- "Migrate file failed:"
- "%s: lookup failed on %s (%s)",
- loc->path, from->name, strerror (-ret));
- ret = -1;
- goto out;
- }
-
- /* we no more require this key */
- dict_del (dict, conf->link_xattr_name);
-
- /* 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) {
- if (ret == -2)
- ret = 0;
- 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;
- }
-
- /* TODO: move all xattr related operations to fd based operations */
- ret = syncop_listxattr (from, loc, &xattr);
- if (ret < 0) {
- gf_msg (this->name, GF_LOG_WARNING, 0,
- DHT_MSG_MIGRATE_FILE_FAILED,
- "Migrate file failed:"
- "%s: failed to get xattr from %s (%s)",
- loc->path, from->name, strerror (-ret));
- ret = -1;
- }
-
- /* create the destination, with required modes/xattr */
- ret = __dht_rebalance_create_dst_file (to, from, loc, &stbuf,
- dict, &dst_fd, xattr);
- 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_msg (this->name, GF_LOG_ERROR, 0,
- DHT_MSG_MIGRATE_FILE_FAILED,
- "Migrate file failed: failed to open %s on %s",
- loc->path, from->name);
- goto out;
- }
-
-
- ret = syncop_fstat (from, src_fd, &stbuf);
- if (ret) {
- gf_msg (this->name, GF_LOG_ERROR, -ret,
- DHT_MSG_MIGRATE_FILE_FAILED,
- "Migrate file failed:failed to lookup %s on %s ",
- loc->path, from->name);
- ret = -1;
- 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_msg (this->name, GF_LOG_ERROR, 0,
- DHT_MSG_MIGRATE_FILE_FAILED,
- "Migrate file failed: %s: failed to migrate data",
- loc->path);
- /* reset the destination back to 0 */
- ret = syncop_ftruncate (to, dst_fd, 0);
- if (ret) {
- gf_msg (this->name, GF_LOG_ERROR, 0,
- DHT_MSG_MIGRATE_FILE_FAILED,
- "Migrate file failed: "
- "%s: failed to reset target size back to 0 (%s)",
- loc->path, strerror (-ret));
- }
-
- ret = -1;
- goto out;
- }
-
- /* TODO: Sync the locks */
-
- ret = syncop_fsync (to, dst_fd, 0);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING,
- "%s: failed to fsync on %s (%s)",
- loc->path, to->name, strerror (-ret));
- ret = -1;
- }
-
-
- /* 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_msg ( this->name, GF_LOG_ERROR, -ret,
- DHT_MSG_MIGRATE_FILE_FAILED,
- "Migrate file failed: failed to fstat file %s on %s ",
- loc->path, from->name);
- ret = -1;
- 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_msg (this->name, GF_LOG_WARNING, -ret,
- DHT_MSG_MIGRATE_FILE_FAILED,
- "Migrate file failed:"
- "%s: failed to perform setattr on %s ",
- loc->path, to->name);
- ret = -1;
- 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 ",
- loc->path, to->name);
- ret = -1;
- }
-
- /* 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_msg (this->name, GF_LOG_WARNING, -ret,
- DHT_MSG_MIGRATE_FILE_FAILED,
- "Migrate file failed:"
- "%s: failed to perform setattr on %s ",
- loc->path, from->name);
- ret = -1;
- 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 (-ret));
- ret = -1;
- }
-
- /* remove the 'linkto' xattr from the destination */
- ret = syncop_fremovexattr (to, dst_fd, conf->link_xattr_name, 0);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING,
- "%s: failed to perform removexattr on %s (%s)",
- loc->path, to->name, strerror (-ret));
- ret = -1;
- }
-
- /* Do a stat and check the gfid before unlink */
-
- /*
- * Cached file changes its state from non-linkto to linkto file after
- * migrating data. If lookup from any other mount-point is performed,
- * converted-linkto-cached file will be treated as a stale and will be
- * unlinked. But by this time, file is already migrated. So further
- * failure because of ENOENT should not be treated as error
- */
-
- ret = syncop_stat (from, loc, &empty_iatt);
- if (ret) {
- gf_msg (this->name, GF_LOG_WARNING, 0,
- DHT_MSG_MIGRATE_FILE_FAILED,
- "%s: failed to do a stat on %s (%s)",
- loc->path, from->name, strerror (-ret));
-
- if (-ret != ENOENT) {
- ret = -1;
- goto out;
- }
-
- rcvd_enoent_from_src = 1;
- }
-
- if ((uuid_compare (empty_iatt.ia_gfid, loc->gfid) == 0 ) &&
- (!rcvd_enoent_from_src)) {
- /* take out the source from namespace */
- ret = syncop_unlink (from, loc);
- if (ret) {
- gf_msg (this->name, GF_LOG_WARNING, 0,
- DHT_MSG_MIGRATE_FILE_FAILED,
- "%s: failed to perform unlink on %s (%s)",
- loc->path, from->name, strerror (-ret));
- ret = -1;
- goto out;
- }
- }
-
- ret = syncop_lookup (this, loc, NULL, NULL, NULL, NULL);
- if (ret) {
- gf_msg_debug (this->name, 0,
- "%s: failed to lookup the file on subvolumes (%s)",
- loc->path, strerror (-ret));
- ret = -1;
- }
-
- gf_msg (this->name, GF_LOG_INFO, 0,
- DHT_MSG_MIGRATE_FILE_COMPLETE,
- "completed migration of %s from subvolume %s to %s",
- loc->path, from->name, to->name);
-
- ret = 0;
-out:
- if (locked) {
- flock.l_type = F_UNLCK;
-
- ret = syncop_inodelk (from, DHT_FILE_MIGRATE_DOMAIN, &tmp_loc,
- F_SETLK, &flock, NULL, NULL);
- if (ret < 0) {
- gf_msg (this->name, GF_LOG_WARNING, 0,
- DHT_MSG_MIGRATE_FILE_FAILED,
- "%s: failed to unlock file on %s (%s)",
- loc->path, from->name, strerror (-ret));
- }
- }
-
- 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);
-
- loc_wipe (&tmp_loc);
-
- 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 ((op_errno != ENOSPC) || (op_errno != ENOTCONN))
- return 1;
-
- if (op_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 (op_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;
-}
-
-static gf_boolean_t
-gf_defrag_pattern_match (gf_defrag_info_t *defrag, char *name, uint64_t size)
-{
- gf_defrag_pattern_list_t *trav = NULL;
- gf_boolean_t match = _gf_false;
- gf_boolean_t ret = _gf_false;
-
- GF_VALIDATE_OR_GOTO ("dht", defrag, out);
-
- trav = defrag->defrag_pattern;
- while (trav) {
- if (!fnmatch (trav->path_pattern, name, FNM_NOESCAPE)) {
- match = _gf_true;
- break;
- }
- trav = trav->next;
- }
-
- if ((match == _gf_true) && (size >= trav->size))
- ret = _gf_true;
-
- out:
- return ret;
-}
-
-/* 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,};
- struct timeval dir_start = {0,};
- struct timeval end = {0,};
- double elapsed = {0,};
- struct timeval start = {0,};
- int loglevel = GF_LOG_TRACE;
-
- 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_msg (this->name, GF_LOG_ERROR, 0,
- DHT_MSG_MIGRATE_DATA_FAILED,
- "Migrate data failed: 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) {
-
- gf_msg (this->name, GF_LOG_ERROR, 0,
- DHT_MSG_MIGRATE_DATA_FAILED,
- "%s: Migrate data failed: Readdir returned"
- " %s. Aborting migrate-data", loc->path,
- strerror(-ret));
- ret = -1;
- goto out;
- }
-
- if (list_empty (&entries.list))
- break;
-
- free_entries = _gf_true;
-
- list_for_each_entry_safe (entry, tmp, &entries.list, list) {
-
- if (dict) {
- dict_unref (dict);
- dict = NULL;
- }
-
- 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);
- }
- if (defrag->defrag_pattern &&
- (gf_defrag_pattern_match (defrag, entry->d_name,
- entry->d_stat.ia_size)
- == _gf_false)) {
- 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_msg (this->name, GF_LOG_ERROR, 0,
- DHT_MSG_GFID_NULL,
- "%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_msg (this->name, GF_LOG_ERROR, 0,
- DHT_MSG_GFID_NULL,
- "%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_msg (this->name, GF_LOG_ERROR, 0,
- DHT_MSG_MIGRATE_FILE_FAILED,
- "Migrate file failed:%s lookup failed",
- entry_loc.path);
- ret = -1;
- continue;
- }
-
- ret = syncop_getxattr (this, &entry_loc, &dict,
- GF_XATTR_NODE_UUID_KEY);
- if(ret < 0) {
- gf_msg (this->name, GF_LOG_ERROR, 0,
- DHT_MSG_MIGRATE_FILE_FAILED,
- "Migrate file failed:"
- "Failed to get node-uuid for %s",
- entry_loc.path);
- ret = -1;
- 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);
- ret = -1;
- 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_msg_trace (this->name, 0, "%s does not"
- "belong to this node",
- entry_loc.path);
- continue;
- }
-
- uuid_str = NULL;
-
- /* if distribute is present, it will honor this key.
- * -1, ENODATA 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, NULL,
- GF_XATTR_LINKINFO_KEY);
- if (ret < 0) {
- if (-ret != ENODATA) {
- loglevel = GF_LOG_ERROR;
- defrag->total_failures += 1;
- } else {
- loglevel = GF_LOG_TRACE;
- }
- gf_log (this->name, loglevel, "%s: failed to "
- "get "GF_XATTR_LINKINFO_KEY" key - %s",
- entry_loc.path, strerror (-ret));
- ret = -1;
- continue;
- }
-
- ret = syncop_setxattr (this, &entry_loc, migrate_data,
- 0);
- if (ret < 0) {
- op_errno = -ret;
- /* errno is overloaded. See
- * rebalance_task_completion () */
- if (op_errno == ENOSPC) {
- gf_msg_debug (this->name, 0,
- "migrate-data skipped for"
- " %s due to space "
- "constraints",
- entry_loc.path);
- defrag->skipped +=1;
- } else{
- gf_msg (this->name, GF_LOG_ERROR, 0,
- DHT_MSG_MIGRATE_FILE_FAILED,
- "migrate-data failed for %s",
- entry_loc.path);
- defrag->total_failures +=1;
- }
-
- ret = gf_defrag_handle_migrate_error (op_errno,
- defrag);
-
- if (!ret)
- gf_msg_debug (this->name, 0,
- "migrate-data on %s "
- "failed: %s",
- entry_loc.path,
- strerror (op_errno));
- else if (ret == 1)
- continue;
- else if (ret == -1)
- goto out;
- } else if (ret > 0) {
- gf_msg (this->name, GF_LOG_ERROR, 0,
- DHT_MSG_MIGRATE_FILE_FAILED,
- "migrate-data failed for %s",
- entry_loc.path);
- defrag->total_failures +=1;
- }
-
- 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);
- }
-
- 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,};
- inode_t *linked_inode = NULL, *inode = NULL;
-
- ret = syncop_lookup (this, loc, NULL, &iatt, NULL, NULL);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Lookup failed on %s",
- loc->path);
- ret = -1;
- 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_msg_trace (this->name, 0, "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) {
- gf_log (this->name, GF_LOG_ERROR, "Readdir returned %s"
- ". Aborting fix-layout",strerror(-ret));
- ret = -1;
- goto out;
- }
-
- if (list_empty (&entries.list))
- break;
-
- free_entries = _gf_true;
-
- 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;
- }
-
-
- uuid_copy (entry_loc.gfid, entry->d_stat.ia_gfid);
-
- /*In case the gfid stored in the inode by inode_link
- * and the gfid obtained in the lookup differs, then
- * client3_3_lookup_cbk will return ESTALE and proper
- * error will be captured
- */
-
- linked_inode = inode_link (entry_loc.inode, loc->inode,
- entry->d_name,
- &entry->d_stat);
-
- inode = entry_loc.inode;
- entry_loc.inode = linked_inode;
- inode_unref (inode);
-
- 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);
- ret = -1;
- 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;
- defrag->total_failures ++;
- ret = -1;
- goto out;
- }
- ret = gf_defrag_fix_layout (this, defrag, &entry_loc,
- fix_layout, migrate_data);
-
- if (ret) {
- gf_msg (this->name, GF_LOG_ERROR, 0,
- DHT_MSG_LAYOUT_FIX_FAILED,
- "Fix layout failed for %s",
- entry_loc.path);
- defrag->total_failures++;
- 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_msg (this->name, GF_LOG_ERROR, 0,
- DHT_MSG_REBALANCE_START_FAILED,
- "Failed to start rebalance: look up on / failed");
- ret = -1;
- 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_msg (this->name, GF_LOG_ERROR, 0,
- DHT_MSG_REBALANCE_START_FAILED,
- "Failed to start rebalance:"
- "Failed to set dictionary value: key = %s",
- GF_XATTR_FIX_LAYOUT_KEY);
-
- goto out;
- }
-
- ret = syncop_setxattr (this, &loc, fix_layout, 0);
- if (ret) {
- gf_msg (this->name, GF_LOG_ERROR, 0,
- DHT_MSG_REBALANCE_FAILED,
- "fix layout on %s failed",
- loc.path);
- defrag->total_failures++;
- ret = -1;
- 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 && 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_msg (this->name, GF_LOG_ERROR, 0,
- DHT_MSG_REBALANCE_START_FAILED,
- "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;
- uint64_t skipped = 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;
- skipped = defrag->skipped;
-
- 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);
- if (ret)
- gf_log (THIS->name, GF_LOG_WARNING,
- "failed to set failure count");
-
- ret = dict_set_uint64 (dict, "skipped", skipped);
- if (ret)
- gf_log (THIS->name, GF_LOG_WARNING,
- "failed to set skipped file count");
-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;
- default:
- break;
- }
-
- gf_msg (THIS->name, GF_LOG_INFO, 0, DHT_MSG_REBALANCE_STATUS,
- "Rebalance is %s. Time taken is %.2f secs",
- status, elapsed);
- gf_msg (THIS->name, GF_LOG_INFO, 0, DHT_MSG_REBALANCE_STATUS,
- "Files migrated: %"PRIu64", size: %"
- PRIu64", lookups: %"PRIu64", failures: %"PRIu64", skipped: "
- "%"PRIu64, files, size, lookup, failures, skipped);
-
-
-out:
- return 0;
-}
-
-int
-gf_defrag_stop (gf_defrag_info_t *defrag, gf_defrag_status_t status,
- 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_msg ("", GF_LOG_INFO, 0, DHT_MSG_REBALANCE_STOPPED,
- "Received stop command on rebalance");
- defrag->defrag_status = status;
-
- if (output)
- gf_defrag_status_get (defrag, output);
- ret = 0;
-out:
- gf_msg_debug ("", 0, "Returning %d", ret);
- return ret;
-}
diff --git a/xlators/cluster/dht/src/dht-rename.c b/xlators/cluster/dht/src/dht-rename.c
index eac3975ccbe..1c870365eea 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>
- 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-2009 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/>.
*/
/* TODO: link(oldpath, newpath) fails if newpath already exists. DHT should
@@ -24,958 +33,429 @@
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)
+ int32_t op_ret, int32_t op_errno, struct stat *stbuf,
+ struct stat *preoldparent, struct stat *postoldparent,
+ struct stat *prenewparent, struct stat *postnewparent)
{
- dht_local_t *local = NULL;
- int this_call_cnt = 0;
- call_frame_t *prev = NULL;
- char gfid[GF_UUID_BUF_SIZE] = {0};
-
- local = frame->local;
- prev = cookie;
-
-
- if (op_ret == -1) {
- /* TODO: undo the damage */
- uuid_unparse(local->loc.inode->gfid, gfid);
-
- gf_msg (this->name, GF_LOG_INFO, op_errno,
- DHT_MSG_RENAME_FAILED,
- "Rename %s -> %s on %s failed, (gfid = %s)",
- local->loc.path, local->loc2.path,
- prev->this->name, gfid);
-
- 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);
-
-
-unwind:
- this_call_cnt = dht_frame_return (frame);
- if (is_last_call (this_call_cnt)) {
- 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);
- }
-
- return 0;
-}
-
+ dht_local_t *local = NULL;
+ int this_call_cnt = 0;
+ call_frame_t *prev = NULL;
-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_conf_t *conf = NULL;
- dht_local_t *local = NULL;
- int call_cnt = 0;
- call_frame_t *prev = NULL;
- int i = 0;
- char gfid[GF_UUID_BUF_SIZE] = {0};
- conf = this->private;
- local = frame->local;
- prev = cookie;
+ local = frame->local;
+ prev = cookie;
+ if (op_ret == -1) {
+ /* TODO: undo the damage */
- if (op_ret == -1) {
- /* TODO: undo the damage */
+ gf_log (this->name, GF_LOG_DEBUG,
+ "rename %s -> %s on %s failed (%s)",
+ local->loc.path, local->loc2.path,
+ prev->this->name, strerror (op_errno));
- uuid_unparse(local->loc.inode->gfid, gfid);
+ local->op_ret = op_ret;
+ local->op_errno = op_errno;
+ } else {
+ /* TODO: construct proper stbuf for dir */
+ /*
+ * FIXME: is this the correct way to build stbuf and
+ * parent bufs?
+ */
+ dht_stat_merge (this, &local->stbuf, stbuf, prev->this);
+ dht_stat_merge (this, &local->preoldparent, preoldparent,
+ prev->this);
+ dht_stat_merge (this, &local->postoldparent, postoldparent,
+ prev->this);
+ dht_stat_merge (this, &local->preparent, prenewparent,
+ prev->this);
+ dht_stat_merge (this, &local->postparent, postnewparent,
+ prev->this);
+ }
- gf_msg (this->name, GF_LOG_INFO, op_errno,
- DHT_MSG_RENAME_FAILED,
- "rename %s -> %s on %s failed, (gfid = %s) ",
- local->loc.path, local->loc2.path,
- prev->this->name, gfid );
+ this_call_cnt = dht_frame_return (frame);
+ if (is_last_call (this_call_cnt)) {
+ local->stbuf.st_ino = local->loc.inode->ino;
- 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->call_cnt)
- goto unwind;
+ local->preoldparent.st_ino = local->loc.parent->ino;
+ local->postoldparent.st_ino = local->loc.parent->ino;
- 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->preparent.st_ino = local->loc2.parent->ino;
+ local->postparent.st_ino = local->loc2.parent->ino;
+ DHT_STACK_UNWIND (rename, frame, local->op_ret, local->op_errno,
+ &local->stbuf, &local->preoldparent,
+ &local->postoldparent,
+ &local->preparent, &local->postparent);
+ }
- 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;
+ return 0;
}
+
int
dht_rename_dir_do (call_frame_t *frame, xlator_t *this)
{
- dht_local_t *local = NULL;
+ dht_local_t *local = NULL;
+ dht_conf_t *conf = NULL;
+ int i = 0;
- local = frame->local;
+ conf = this->private;
+ local = frame->local;
- if (local->op_ret == -1)
- goto err;
+ if (local->op_ret == -1)
+ goto err;
- local->op_ret = 0;
+ local->call_cnt = conf->subvolume_cnt;
+ 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;
+ for (i = 0; i < conf->subvolume_cnt; i++) {
+ STACK_WIND (frame, dht_rename_dir_cbk,
+ conf->subvolumes[i],
+ conf->subvolumes[i]->fops->rename,
+ &local->loc, &local->loc2);
+ }
+
+ return 0;
err:
- DHT_STACK_UNWIND (rename, frame, local->op_ret, local->op_errno, NULL, NULL,
- NULL, NULL, NULL, NULL);
- return 0;
+ DHT_STACK_UNWIND (rename, frame, local->op_ret, local->op_errno, 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;
- call_frame_t *prev = NULL;
-
- local = frame->local;
- prev = cookie;
-
- if (op_ret > 2) {
- gf_msg_trace (this->name, 0,
- "readdir on %s for %s returned %d entries",
- prev->this->name, local->loc.path, op_ret);
- local->op_ret = -1;
- local->op_errno = ENOTEMPTY;
- }
+ dht_local_t *local = NULL;
+ int this_call_cnt = -1;
+ call_frame_t *prev = NULL;
- this_call_cnt = dht_frame_return (frame);
+ local = frame->local;
+ prev = cookie;
+
+ if (op_ret > 2) {
+ gf_log (this->name, GF_LOG_TRACE,
+ "readdir on %s for %s returned %d entries",
+ prev->this->name, local->loc.path, op_ret);
+ local->op_ret = -1;
+ local->op_errno = ENOTEMPTY;
+ }
- if (is_last_call (this_call_cnt)) {
- dht_rename_dir_do (frame, this);
- }
+ this_call_cnt = dht_frame_return (frame);
- return 0;
+ if (is_last_call (this_call_cnt)) {
+ dht_rename_dir_do (frame, this);
+ }
+
+ return 0;
}
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;
- call_frame_t *prev = NULL;
- char gfid[GF_UUID_BUF_SIZE] = {0};
-
- local = frame->local;
- prev = cookie;
-
+ dht_local_t *local = NULL;
+ int this_call_cnt = -1;
+ call_frame_t *prev = NULL;
- if (op_ret == -1) {
- uuid_unparse(local->loc.inode->gfid, gfid);
- gf_msg (this->name, GF_LOG_INFO, op_errno,
- DHT_MSG_OPENDIR_FAILED,
- "opendir on %s for %s failed,(gfid = %s) ",
- prev->this->name, local->loc.path, gfid);
- goto err;
- }
+ local = frame->local;
+ prev = cookie;
+
+ if (op_ret == -1) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "opendir on %s for %s failed (%s)",
+ prev->this->name, local->loc.path,
+ strerror (op_errno));
+ goto err;
+ }
- STACK_WIND (frame, dht_rename_readdir_cbk,
- prev->this, prev->this->fops->readdir,
- local->fd, 4096, 0, NULL);
+ STACK_WIND (frame, dht_rename_readdir_cbk,
+ prev->this, prev->this->fops->readdir,
+ local->fd, 4096, 0);
- return 0;
+ return 0;
err:
- this_call_cnt = dht_frame_return (frame);
+ this_call_cnt = dht_frame_return (frame);
- if (is_last_call (this_call_cnt)) {
- dht_rename_dir_do (frame, this);
- }
+ if (is_last_call (this_call_cnt)) {
+ dht_rename_dir_do (frame, this);
+ }
- return 0;
+ return 0;
}
int
dht_rename_dir (call_frame_t *frame, xlator_t *this)
{
- dht_conf_t *conf = NULL;
- dht_local_t *local = NULL;
- int i = 0;
- int op_errno = -1;
+ dht_conf_t *conf = NULL;
+ dht_local_t *local = NULL;
+ int i = 0;
+ int op_errno = -1;
- conf = frame->this->private;
- local = frame->local;
+ conf = frame->this->private;
+ local = frame->local;
- local->call_cnt = conf->subvolume_cnt;
+ local->call_cnt = conf->subvolume_cnt;
for (i = 0; i < conf->subvolume_cnt; i++) {
if (!conf->subvolume_status[i]) {
- gf_msg (this->name, GF_LOG_INFO, 0,
- DHT_MSG_RENAME_FAILED,
- "Rename dir failed: subvolume down (%s)",
- conf->subvolumes[i]->name);
op_errno = ENOTCONN;
goto err;
}
}
- local->fd = fd_create (local->loc.inode, frame->root->pid);
- if (!local->fd) {
- op_errno = ENOMEM;
- goto err;
- }
+ local->fd = fd_create (local->loc.inode, frame->root->pid);
+ if (!local->fd) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory");
+ op_errno = ENOMEM;
+ goto err;
+ }
- local->op_ret = 0;
+ local->op_ret = 0;
- if (!local->dst_cached) {
- dht_rename_dir_do (frame, this);
- return 0;
- }
+ if (!local->dst_cached) {
+ dht_rename_dir_do (frame, this);
+ return 0;
+ }
- for (i = 0; i < conf->subvolume_cnt; i++) {
- STACK_WIND (frame, dht_rename_opendir_cbk,
- conf->subvolumes[i],
- conf->subvolumes[i]->fops->opendir,
- &local->loc2, local->fd, NULL);
- }
+ for (i = 0; i < conf->subvolume_cnt; i++) {
+ STACK_WIND (frame, dht_rename_opendir_cbk,
+ conf->subvolumes[i],
+ conf->subvolumes[i]->fops->opendir,
+ &local->loc2, local->fd);
+ }
- return 0;
+ 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);
- return 0;
-}
-#define DHT_MARK_FOP_INTERNAL(xattr) do { \
- int tmp = -1; \
- if (!xattr) { \
- xattr = dict_new (); \
- if (!xattr) \
- break; \
- } \
- tmp = dict_set_str (xattr, GLUSTERFS_INTERNAL_FOP_KEY, "yes"); \
- if (tmp) { \
- gf_msg (this->name, GF_LOG_ERROR, 0, \
- DHT_MSG_DICT_SET_FAILED, \
- "Failed to set dictionary value: key = %s," \
- " path = %s", GLUSTERFS_INTERNAL_FOP_KEY, \
- local->loc.path); \
- } \
- }while (0)
-
-#define DHT_MARKER_DONT_ACCOUNT(xattr) do { \
- int tmp = -1; \
- if (!xattr) { \
- xattr = dict_new (); \
- if (!xattr) \
- break; \
- } \
- tmp = dict_set_str (xattr, GLUSTERFS_MARKER_DONT_ACCOUNT_KEY, \
- "yes"); \
- if (tmp) { \
- gf_msg (this->name, GF_LOG_ERROR, 0, \
- DHT_MSG_DICT_SET_FAILED, \
- "Failed to set dictionary value: key = %s," \
- " path = %s",GLUSTERFS_MARKER_DONT_ACCOUNT_KEY, \
- local->loc.path); \
- } \
- }while (0)
-
-int
-dht_rename_unlock_cbk (call_frame_t *frame, void *cookie,
- xlator_t *this, int32_t op_ret, int32_t op_errno,
- dict_t *xdata)
-{
- dht_local_t *local = NULL;
-
- local = frame->local;
-
- 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;
+ op_errno = (op_errno == -1) ? errno : op_errno;
+ DHT_STACK_UNWIND (rename, frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL);
+ return 0;
}
-int
-dht_rename_unlock (call_frame_t *frame, xlator_t *this)
-{
- dht_local_t *local = NULL;
- int op_ret = -1;
- char src_gfid[GF_UUID_BUF_SIZE] = {0};
- char dst_gfid[GF_UUID_BUF_SIZE] = {0};
-
- local = frame->local;
-
- op_ret = dht_unlock_inodelk (frame, local->lock.locks,
- local->lock.lk_count,
- dht_rename_unlock_cbk);
- if (op_ret < 0) {
- uuid_utoa_r (local->loc.inode->gfid, src_gfid);
-
- if (local->loc2.inode)
- uuid_utoa_r (local->loc2.inode->gfid, dst_gfid);
-
- gf_log (this->name, GF_LOG_WARNING,
- "winding unlock inodelk failed "
- "rename (%s:%s:%s %s:%s:%s), "
- "stale locks left on bricks",
- local->loc.path, src_gfid, local->src_cached->name,
- local->loc2.path, dst_gfid,
- local->dst_cached ? local->dst_cached->name : NULL);
-
- dht_rename_unlock_cbk (frame, NULL, this, 0, 0, NULL);
- }
-
- return 0;
-}
-
-int
-dht_rename_done (call_frame_t *frame, xlator_t *this)
-{
- dht_local_t *local = NULL;
-
- local = frame->local;
-
- if (local->linked == _gf_true) {
- local->linked = _gf_false;
- dht_linkfile_attr_heal (frame, this);
- }
-
- dht_rename_unlock (frame, this);
- return 0;
-}
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)
+ int32_t op_ret, int32_t op_errno, struct stat *preparent,
+ struct stat *postparent)
{
- dht_local_t *local = NULL;
- call_frame_t *prev = NULL;
- int this_call_cnt = 0;
-
- local = frame->local;
- prev = cookie;
-
- if (!local) {
- gf_log (this->name, GF_LOG_ERROR,
- "!local, should not happen");
- goto out;
- }
-
- this_call_cnt = dht_frame_return (frame);
-
- if (op_ret == -1) {
- gf_msg (this->name, GF_LOG_WARNING, op_errno,
- DHT_MSG_UNLINK_FAILED,
- "%s: Rename: unlink on %s failed ",
- local->loc.path, prev->this->name);
- }
-
- WIPE (&local->preoldparent);
- WIPE (&local->postoldparent);
- WIPE (&local->preparent);
- WIPE (&local->postparent);
-
- if (is_last_call (this_call_cnt)) {
- dht_rename_done (frame, this);
- }
-
-out:
- return 0;
-}
-
-
-int
-dht_rename_cleanup (call_frame_t *frame)
-{
- dht_local_t *local = NULL;
- xlator_t *this = NULL;
- xlator_t *src_hashed = NULL;
- xlator_t *src_cached = NULL;
- xlator_t *dst_hashed = NULL;
- xlator_t *dst_cached = NULL;
- int call_cnt = 0;
- dict_t *xattr = NULL;
- char gfid[GF_UUID_BUF_SIZE] = {0};
-
- local = frame->local;
- this = frame->this;
-
- src_hashed = local->src_hashed;
- src_cached = local->src_cached;
- dst_hashed = local->dst_hashed;
- dst_cached = local->dst_cached;
-
- if (src_cached == dst_cached)
- goto nolinks;
-
- if (local->linked && (dst_hashed != src_hashed )&&
- (dst_hashed != src_cached)) {
- call_cnt++;
- }
-
- if (local->added_link && (src_cached != dst_hashed)) {
- call_cnt++;
- }
-
- local->call_cnt = call_cnt;
-
- if (!call_cnt)
- goto nolinks;
-
- DHT_MARK_FOP_INTERNAL (xattr);
-
- uuid_unparse(local->loc.inode->gfid, gfid);
-
- if (local->linked && (dst_hashed != src_hashed) &&
- (dst_hashed != src_cached)) {
- dict_t *xattr_new = NULL;
-
- gf_msg_trace (this->name, 0,
- "unlinking linkfile %s @ %s => %s, (gfid = %s)",
- local->loc.path, dst_hashed->name,
- src_cached->name, gfid);
-
- xattr_new = dict_copy_with_ref (xattr, NULL);
-
-
- DHT_MARKER_DONT_ACCOUNT(xattr_new);
-
- STACK_WIND (frame, dht_rename_unlink_cbk,
- dst_hashed, dst_hashed->fops->unlink,
- &local->loc, 0, xattr_new);
-
- dict_unref (xattr_new);
- xattr_new = NULL;
- }
-
- if (local->added_link && (src_cached != dst_hashed)) {
- dict_t *xattr_new = NULL;
-
- gf_msg_trace (this->name, 0,
- "unlinking link %s => %s (%s), (gfid = %s)",
- local->loc.path, local->loc2.path,
- src_cached->name, gfid);
-
- xattr_new = dict_copy_with_ref (xattr, NULL);
-
- if (uuid_compare (local->loc.pargfid,
- local->loc2.pargfid) == 0) {
- DHT_MARKER_DONT_ACCOUNT(xattr_new);
- }
-
- STACK_WIND (frame, dht_rename_unlink_cbk,
- src_cached, src_cached->fops->unlink,
- &local->loc2, 0, xattr_new);
-
- dict_unref (xattr_new);
- xattr_new = NULL;
- }
-
- if (xattr)
- dict_unref (xattr);
-
- return 0;
-
-nolinks:
- WIPE (&local->preoldparent);
- WIPE (&local->postoldparent);
- WIPE (&local->preparent);
- WIPE (&local->postparent);
-
- dht_rename_unlock (frame, this);
- return 0;
-}
-
+ dht_local_t *local = NULL;
+ call_frame_t *prev = NULL;
+ int this_call_cnt = 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;
+ local = frame->local;
+ prev = cookie;
- prev = cookie;
- local = frame->local;
+ this_call_cnt = dht_frame_return (frame);
- 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));
- }
+ if (op_ret == -1) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "unlink on %s failed (%s)",
+ prev->this->name, strerror (op_errno));
+ }
- if (local->linked == _gf_true) {
- local->linked = _gf_false;
- dht_linkfile_attr_heal (frame, this);
- }
- DHT_STACK_DESTROY (frame);
+ if (is_last_call (this_call_cnt))
+ DHT_STACK_UNWIND (rename, frame, local->op_ret, local->op_errno,
+ &local->stbuf, &local->preoldparent,
+ &local->postoldparent, &local->preparent,
+ &local->postparent);
- return 0;
+ return 0;
}
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)
+ int32_t op_ret, int32_t op_errno, struct stat *stbuf,
+ struct stat *preoldparent, struct stat *postoldparent,
+ struct stat *prenewparent, struct stat *postnewparent)
{
- dht_local_t *local = NULL;
- call_frame_t *prev = NULL;
- xlator_t *src_hashed = NULL;
- xlator_t *src_cached = NULL;
- 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;
- dict_t *xattr = NULL;
-
- local = frame->local;
- prev = cookie;
-
- src_hashed = local->src_hashed;
- src_cached = local->src_cached;
- dst_hashed = local->dst_hashed;
- dst_cached = local->dst_cached;
-
- if (local->linked == _gf_true)
- FRAME_SU_UNDO (frame, dht_local_t);
-
- /* It is a critical failure iff we fail to rename the cached file
- * if the rename of the linkto failed, it is not a critical failure,
- * and we do not want to lose the created hard link for the new
- * name as that could have been read by other clients.
- *
- * NOTE: If another client is attempting the same oldname -> newname
- * rename, and finds both file names as existing, and are hard links
- * to each other, then FUSE would send in an unlink for oldname. In
- * this time duration if we treat the linkto as a critical error and
- * unlink the newname we created, we would have effectively lost the
- * file to rename operations.
- *
- * Repercussions of treating this as a non-critical error is that
- * we could leave behind a stale linkto file and/or not create the new
- * linkto file, the second case would be rectified by a subsequent
- * lookup, the first case by a rebalance, like for all stale linkto
- * files */
-
- if (op_ret == -1) {
- /* Critical failure: unable to rename the cached file */
- if (src_cached == dst_cached) {
- gf_msg (this->name, GF_LOG_WARNING, op_errno,
- DHT_MSG_RENAME_FAILED,
- "%s: Rename on %s failed, (gfid = %s) ",
- local->loc.path, prev->this->name,
- local->loc.inode ?
- uuid_utoa(local->loc.inode->gfid):"");
- local->op_ret = op_ret;
- local->op_errno = op_errno;
- goto cleanup;
- } else {
- /* Non-critical failure, unable to rename the linkto
- * file
- */
- gf_msg (this->name, GF_LOG_INFO, op_errno,
- DHT_MSG_RENAME_FAILED,
- "%s: Rename (linkto file) on %s failed, "
- "(gfid = %s) ",
- local->loc.path, prev->this->name,
- local->loc.inode ?
- uuid_utoa(local->loc.inode->gfid):"");
- }
- }
-
- 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,
- this, src_cached, dst_hashed,
- &link_local->loc);
- }
-
-err:
- /* Merge attrs only from src_cached. In case there of src_cached !=
- * dst_hashed, this ignores linkfile attrs. */
- if (prev->this == src_cached) {
- 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);
- }
-
-
- /* 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)
- * on rename_subvol. */
- if (src_cached == dst_cached)
- rename_subvol = src_cached;
- else
- rename_subvol = dst_hashed;
-
- /* TODO: delete files in background */
-
- if (src_cached != dst_hashed && src_cached != dst_cached)
- local->call_cnt++;
+ dht_local_t *local = NULL;
+ call_frame_t *prev = NULL;
+ xlator_t *src_hashed = NULL;
+ xlator_t *src_cached = NULL;
+ xlator_t *dst_hashed = NULL;
+ xlator_t *dst_cached = NULL;
+ xlator_t *rename_subvol = NULL;
- if (src_hashed != rename_subvol && src_hashed != src_cached)
- local->call_cnt++;
+ local = frame->local;
+ prev = cookie;
- if (dst_cached && dst_cached != dst_hashed && dst_cached != src_cached)
- local->call_cnt++;
+ src_hashed = local->src_hashed;
+ src_cached = local->src_cached;
+ dst_hashed = local->dst_hashed;
+ dst_cached = local->dst_cached;
- if (local->call_cnt == 0)
- goto unwind;
+ if (op_ret == -1) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "rename on %s failed (%s)", prev->this->name,
+ strerror (op_errno));
+ local->op_ret = op_ret;
+ local->op_errno = op_errno;
+ goto unwind;
+ }
- DHT_MARK_FOP_INTERNAL (xattr);
+ dht_stat_merge (this, &local->stbuf, stbuf, prev->this);
+ dht_stat_merge (this, &local->preoldparent, preoldparent, prev->this);
+ dht_stat_merge (this, &local->postoldparent, postoldparent, prev->this);
+ dht_stat_merge (this, &local->preparent, prenewparent, prev->this);
+ dht_stat_merge (this, &local->postparent, postnewparent, prev->this);
- if (src_cached != dst_hashed && src_cached != dst_cached) {
- dict_t *xattr_new = NULL;
+ local->stbuf.st_ino = local->loc.inode->ino;
- xattr_new = dict_copy_with_ref (xattr, NULL);
+ local->preoldparent.st_ino = local->loc.parent->ino;
+ local->postoldparent.st_ino = local->loc.parent->ino;
- gf_msg_trace (this->name, 0,
- "deleting old src datafile %s @ %s",
- local->loc.path, src_cached->name);
+ local->preparent.st_ino = local->loc2.parent->ino;
+ local->postparent.st_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)
+ * on rename_subvol. */
+ if (src_cached == dst_cached)
+ rename_subvol = src_cached;
+ else
+ rename_subvol = dst_hashed;
- if (uuid_compare (local->loc.pargfid,
- local->loc2.pargfid) == 0) {
- DHT_MARKER_DONT_ACCOUNT(xattr_new);
- }
+ /* TODO: delete files in background */
- STACK_WIND (frame, dht_rename_unlink_cbk,
- src_cached, src_cached->fops->unlink,
- &local->loc, 0, xattr_new);
+ if (src_cached != dst_hashed && src_cached != dst_cached)
+ local->call_cnt++;
- dict_unref (xattr_new);
- xattr_new = NULL;
- }
+ if (src_hashed != rename_subvol && src_hashed != src_cached)
+ local->call_cnt++;
- if (src_hashed != rename_subvol && src_hashed != src_cached) {
- dict_t *xattr_new = NULL;
+ if (dst_cached && dst_cached != dst_hashed && dst_cached != src_cached)
+ local->call_cnt++;
- xattr_new = dict_copy_with_ref (xattr, NULL);
+ if (local->call_cnt == 0)
+ goto unwind;
- gf_msg_trace (this->name, 0,
- "deleting old src linkfile %s @ %s",
- local->loc.path, src_hashed->name);
+ if (src_cached != dst_hashed && src_cached != dst_cached) {
+ gf_log (this->name, GF_LOG_TRACE,
+ "deleting old src datafile %s @ %s",
+ local->loc.path, src_cached->name);
- DHT_MARKER_DONT_ACCOUNT(xattr_new);
+ STACK_WIND (frame, dht_rename_unlink_cbk,
+ src_cached, src_cached->fops->unlink,
+ &local->loc);
+ }
- STACK_WIND (frame, dht_rename_unlink_cbk,
- src_hashed, src_hashed->fops->unlink,
- &local->loc, 0, xattr_new);
+ if (src_hashed != rename_subvol && src_hashed != src_cached) {
+ gf_log (this->name, GF_LOG_TRACE,
+ "deleting old src linkfile %s @ %s",
+ local->loc.path, src_hashed->name);
- dict_unref (xattr_new);
- xattr_new = NULL;
- }
+ STACK_WIND (frame, dht_rename_unlink_cbk,
+ src_hashed, src_hashed->fops->unlink,
+ &local->loc);
+ }
- if (dst_cached
- && (dst_cached != dst_hashed)
- && (dst_cached != src_cached)) {
- gf_msg_trace (this->name, 0,
- "deleting old dst datafile %s @ %s",
- local->loc2.path, dst_cached->name);
+ if (dst_cached
+ && (dst_cached != dst_hashed)
+ && (dst_cached != src_cached)) {
+ gf_log (this->name, GF_LOG_TRACE,
+ "deleting old dst datafile %s @ %s",
+ local->loc2.path, dst_cached->name);
- STACK_WIND (frame, dht_rename_unlink_cbk,
- dst_cached, dst_cached->fops->unlink,
- &local->loc2, 0, xattr);
- }
- if (xattr)
- dict_unref (xattr);
- return 0;
+ STACK_WIND (frame, dht_rename_unlink_cbk,
+ dst_cached, dst_cached->fops->unlink,
+ &local->loc2);
+ }
+ return 0;
unwind:
- WIPE (&local->preoldparent);
- WIPE (&local->postoldparent);
- WIPE (&local->preparent);
- WIPE (&local->postparent);
- if (xattr)
- dict_unref (xattr);
-
- dht_rename_done (frame, this);
-
- return 0;
-
-cleanup:
- if (xattr)
- dict_unref (xattr);
- dht_rename_cleanup (frame);
+ DHT_STACK_UNWIND (rename, frame, local->op_ret, local->op_errno,
+ &local->stbuf, &local->preoldparent,
+ &local->postoldparent, &local->preparent,
+ &local->postparent);
- return 0;
+ return 0;
}
int
dht_do_rename (call_frame_t *frame)
{
- dht_local_t *local = NULL;
- xlator_t *dst_hashed = NULL;
- xlator_t *src_cached = NULL;
- xlator_t *dst_cached = NULL;
- xlator_t *this = NULL;
- xlator_t *rename_subvol = NULL;
- dict_t *dict = NULL;
-
- local = frame->local;
- this = frame->this;
-
- dst_hashed = local->dst_hashed;
- dst_cached = local->dst_cached;
- src_cached = local->src_cached;
-
- if (src_cached == dst_cached)
- rename_subvol = src_cached;
- else
- rename_subvol = dst_hashed;
-
- if ((src_cached != dst_hashed) && (rename_subvol == dst_hashed)) {
- DHT_MARKER_DONT_ACCOUNT(dict);
- }
+ dht_local_t *local = NULL;
+ xlator_t *dst_hashed = NULL;
+ xlator_t *src_cached = NULL;
+ xlator_t *dst_cached = NULL;
+ xlator_t *this = NULL;
+ xlator_t *rename_subvol = NULL;
- gf_msg_trace (this->name, 0,
- "renaming %s => %s (%s)",
- local->loc.path, local->loc2.path, rename_subvol->name);
- if (local->linked == _gf_true)
- FRAME_SU_DO (frame, dht_local_t);
- STACK_WIND (frame, dht_rename_cbk,
- rename_subvol, rename_subvol->fops->rename,
- &local->loc, &local->loc2, dict);
-
- return 0;
-}
-
-int
-dht_rename_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)
-{
- dht_local_t *local = NULL;
- call_frame_t *prev = NULL;
-
- local = frame->local;
- prev = cookie;
-
- if (op_ret == -1) {
- gf_msg_debug (this->name, 0,
- "link/file on %s failed (%s)",
- prev->this->name, strerror (op_errno));
- local->op_ret = -1;
- local->op_errno = op_errno;
- local->added_link = _gf_false;
- } else
- dht_iatt_merge (this, &local->stbuf, stbuf, prev->this);
+ local = frame->local;
+ this = frame->this;
- if (local->op_ret == -1)
- goto cleanup;
+ dst_hashed = local->dst_hashed;
+ dst_cached = local->dst_cached;
+ src_cached = local->src_cached;
- dht_do_rename (frame);
+ if (src_cached == dst_cached)
+ rename_subvol = src_cached;
+ else
+ rename_subvol = dst_hashed;
- return 0;
+ gf_log (this->name, GF_LOG_TRACE,
+ "renaming %s => %s (%s)",
+ local->loc.path, local->loc2.path, rename_subvol->name);
-cleanup:
- dht_rename_cleanup (frame);
+ STACK_WIND (frame, dht_rename_cbk,
+ rename_subvol, rename_subvol->fops->rename,
+ &local->loc, &local->loc2);
- return 0;
+ return 0;
}
-int
-dht_rename_linkto_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)
-{
- dht_local_t *local = NULL;
- call_frame_t *prev = NULL;
- xlator_t *src_cached = NULL;
- dict_t *xattr = NULL;
-
- DHT_MARK_FOP_INTERNAL (xattr);
-
- local = frame->local;
- prev = cookie;
-
- src_cached = local->src_cached;
-
- if (op_ret == -1) {
- gf_msg_debug (this->name, 0,
- "link/file on %s failed (%s)",
- prev->this->name, strerror (op_errno));
- local->op_ret = -1;
- local->op_errno = op_errno;
- }
-
- /* If linkto creation failed move to failure cleanup code,
- * instead of continuing with creating the link file */
- if (local->op_ret != 0) {
- goto cleanup;
- }
-
- gf_msg_trace (this->name, 0,
- "link %s => %s (%s)", local->loc.path,
- local->loc2.path, src_cached->name);
- if (uuid_compare (local->loc.pargfid,
- local->loc2.pargfid) == 0) {
- DHT_MARKER_DONT_ACCOUNT(xattr);
- }
-
- local->added_link = _gf_true;
-
- STACK_WIND (frame, dht_rename_link_cbk,
- src_cached, src_cached->fops->link,
- &local->loc, &local->loc2, xattr);
-
- if (xattr)
- dict_unref (xattr);
-
- return 0;
-
-cleanup:
- dht_rename_cleanup (frame);
-
- if (xattr)
- dict_unref (xattr);
-
- return 0;
-}
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_rename_links_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno,
+ inode_t *inode, struct stat *stbuf,
+ struct stat *preparent, struct stat *postparent)
{
dht_local_t *local = NULL;
call_frame_t *prev = NULL;
+ int this_call_cnt = 0;
local = frame->local;
prev = cookie;
-
- if ((op_ret == -1) && (op_errno != ENOENT)) {
- gf_msg_debug (this->name, 0,
- "unlink of %s on %s failed (%s)",
- local->loc2.path, prev->this->name,
- strerror (op_errno));
+
+ if (op_ret == -1) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "link/file on %s failed (%s)",
+ 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);
+ this_call_cnt = dht_frame_return (frame);
+ if (is_last_call (this_call_cnt)) {
+ if (local->op_ret == -1)
+ goto unwind;
+
+ dht_do_rename (frame);
+ }
return 0;
-cleanup:
- dht_rename_cleanup (frame);
+unwind:
+ DHT_STACK_UNWIND (rename, frame, local->op_ret, local->op_errno,
+ &local->stbuf, &local->preoldparent,
+ &local->postoldparent, &local->preparent,
+ &local->postparent);
return 0;
}
@@ -984,380 +464,155 @@ cleanup:
int
dht_rename_create_links (call_frame_t *frame)
{
- dht_local_t *local = NULL;
- xlator_t *this = NULL;
- xlator_t *src_hashed = NULL;
- xlator_t *src_cached = NULL;
- xlator_t *dst_hashed = NULL;
- xlator_t *dst_cached = NULL;
- int call_cnt = 0;
- dict_t *xattr = NULL;
-
-
- local = frame->local;
- this = frame->this;
-
- src_hashed = local->src_hashed;
- src_cached = local->src_cached;
- dst_hashed = local->dst_hashed;
- dst_cached = local->dst_cached;
-
- DHT_MARK_FOP_INTERNAL (xattr);
+ dht_local_t *local = NULL;
+ xlator_t *this = NULL;
+ xlator_t *src_hashed = NULL;
+ xlator_t *src_cached = NULL;
+ xlator_t *dst_hashed = NULL;
+ xlator_t *dst_cached = NULL;
+ int call_cnt = 0;
- if (src_cached == dst_cached) {
- dict_t *xattr_new = NULL;
- if (dst_hashed == dst_cached)
- goto nolinks;
-
- xattr_new = dict_copy_with_ref (xattr, NULL);
-
- gf_msg_trace (this->name, 0,
- "unlinking dst linkfile %s @ %s",
- local->loc2.path, dst_hashed->name);
-
- DHT_MARKER_DONT_ACCOUNT(xattr_new);
+ local = frame->local;
+ this = frame->this;
- STACK_WIND (frame, dht_rename_unlink_links_cbk,
- dst_hashed, dst_hashed->fops->unlink,
- &local->loc2, 0, xattr_new);
+ src_hashed = local->src_hashed;
+ src_cached = local->src_cached;
+ dst_hashed = local->dst_hashed;
+ dst_cached = local->dst_cached;
- dict_unref (xattr_new);
- return 0;
- }
+ if (src_cached == dst_cached)
+ goto nolinks;
- if (src_cached != dst_hashed) {
- /* needed to create the link file */
- call_cnt++;
- if (dst_hashed != src_hashed)
- /* needed to create the linkto file */
- call_cnt ++;
- }
+ if (dst_hashed != src_hashed && dst_hashed != src_cached)
+ call_cnt++;
- /* We should not have any failures post the link creation, as this
- * introduces the newname into the namespace. Clients could have cached
- * the existence of the newname and may start taking actions based on
- * the same. Hence create the linkto first, and then attempt the link.
- *
- * NOTE: If another client is attempting the same oldname -> newname
- * rename, and finds both file names as existing, and are hard links
- * to each other, then FUSE would send in an unlink for oldname. In
- * this time duration if we treat the linkto as a critical error and
- * unlink the newname we created, we would have effectively lost the
- * file to rename operations. */
- if (dst_hashed != src_hashed && src_cached != dst_hashed) {
- gf_msg_trace (this->name, 0,
- "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_linkto_cbk, this,
- src_cached, dst_hashed, &local->loc);
- } else if (src_cached != dst_hashed) {
- dict_t *xattr_new = NULL;
-
- xattr_new = dict_copy_with_ref (xattr, NULL);
-
- gf_msg_trace (this->name, 0,
- "link %s => %s (%s)", local->loc.path,
- local->loc2.path, src_cached->name);
- if (uuid_compare (local->loc.pargfid,
- local->loc2.pargfid) == 0) {
- DHT_MARKER_DONT_ACCOUNT(xattr_new);
- }
+ if (src_cached != dst_hashed)
+ call_cnt++;
- local->added_link = _gf_true;
+ local->call_cnt = call_cnt;
- STACK_WIND (frame, dht_rename_link_cbk,
- src_cached, src_cached->fops->link,
- &local->loc, &local->loc2, xattr_new);
+ if (dst_hashed != src_hashed && dst_hashed != src_cached) {
+ gf_log (this->name, GF_LOG_TRACE,
+ "linkfile %s @ %s => %s",
+ local->loc.path, dst_hashed->name, src_cached->name);
+ dht_linkfile_create (frame, dht_rename_links_cbk,
+ src_cached, dst_hashed, &local->loc);
+ }
- dict_unref (xattr_new);
- }
+ 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) {
- /* skip to next step */
- dht_do_rename (frame);
- }
- if (xattr)
- dict_unref (xattr);
-
- return 0;
-}
-
-int
-dht_rename_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)
-{
- dht_local_t *local = NULL;
- int call_cnt = 0;
- dht_conf_t *conf = NULL;
-
- local = frame->local;
- conf = this->private;
-
- if (op_ret < 0) {
- /* The meaning of is_linkfile is overloaded here. For locking
- * to work properly both rebalance and rename should acquire
- * lock on datafile. The reason for sending this lookup is to
- * find out whether we've acquired a lock on data file.
- * Between the lookup before rename and this rename, the
- * file could be migrated by a rebalance process and now this
- * file this might be a linkto file. We verify that by sending
- * this lookup. However, if this lookup fails we cannot really
- * say whether we've acquired lock on a datafile or linkto file.
- * So, we act conservatively and _assume_
- * that this is a linkfile and fail the rename operation.
- */
- local->is_linkfile = _gf_true;
- } else if (xattr && check_is_linkfile (inode, stbuf, xattr,
- conf->link_xattr_name)) {
- local->is_linkfile = _gf_true;
- }
-
- call_cnt = dht_frame_return (frame);
- if (is_last_call (call_cnt)) {
- if (local->is_linkfile) {
- local->op_ret = -1;
- local->op_errno = EBUSY;
- goto fail;
- }
-
- dht_rename_create_links (frame);
- }
-
- return 0;
-fail:
- dht_rename_unlock (frame, this);
- return 0;
-}
-
-int32_t
-dht_rename_lock_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
-{
- dht_local_t *local = NULL;
- char src_gfid[GF_UUID_BUF_SIZE] = {0};
- char dst_gfid[GF_UUID_BUF_SIZE] = {0};
- dict_t *xattr_req = NULL;
- dht_conf_t *conf = NULL;
- int i = 0;
-
- local = frame->local;
- conf = this->private;
-
- if (op_ret < 0) {
- uuid_utoa_r (local->loc.inode->gfid, src_gfid);
-
- if (local->loc2.inode)
- uuid_utoa_r (local->loc2.inode->gfid, dst_gfid);
-
- gf_log (this->name, GF_LOG_WARNING,
- "acquiring inodelk failed (%s) "
- "rename (%s:%s:%s %s:%s:%s), returning EBUSY",
- strerror (op_errno),
- local->loc.path, src_gfid, local->src_cached->name,
- local->loc2.path, dst_gfid,
- local->dst_cached ? local->dst_cached->name : NULL);
-
- local->op_ret = -1;
- local->op_errno = (op_errno == EAGAIN) ? EBUSY : op_errno;
-
- goto done;
- }
-
- xattr_req = dict_new ();
- if (xattr_req == NULL) {
- local->op_ret = -1;
- local->op_errno = ENOMEM;
- goto done;
- }
-
- op_ret = dict_set_uint32 (xattr_req,
- conf->link_xattr_name, 256);
- if (op_ret < 0) {
- local->op_ret = -1;
- local->op_errno = -op_ret;
- goto done;
- }
-
- local->call_cnt = local->lock.lk_count;
-
- for (i = 0; i < local->lock.lk_count; i++) {
- STACK_WIND (frame, dht_rename_lookup_cbk,
- local->lock.locks[i]->xl,
- local->lock.locks[i]->xl->fops->lookup,
- &local->lock.locks[i]->loc, xattr_req);
- }
-
- dict_unref (xattr_req);
- return 0;
-
-done:
- /* Its fine to call unlock even when no locks are acquired, as we check
- * for lock->locked before winding a unlock call.
- */
- dht_rename_unlock (frame, this);
-
- if (xattr_req)
- dict_unref (xattr_req);
+ if (!call_cnt) {
+ /* skip to next step */
+ dht_do_rename (frame);
+ }
- return 0;
+ return 0;
}
-int
-dht_rename_lock (call_frame_t *frame)
-{
- dht_local_t *local = NULL;
- int count = 1, ret = -1;
- dht_lock_t **lk_array = NULL;
-
- local = frame->local;
-
- if (local->dst_cached)
- count++;
-
- lk_array = GF_CALLOC (count, sizeof (*lk_array), gf_common_mt_char);
- if (lk_array == NULL)
- goto err;
-
- lk_array[0] = dht_lock_new (frame->this, local->src_cached, &local->loc,
- F_WRLCK, DHT_FILE_MIGRATE_DOMAIN);
- if (lk_array[0] == NULL)
- goto err;
-
- if (local->dst_cached) {
- lk_array[1] = dht_lock_new (frame->this, local->dst_cached,
- &local->loc2, F_WRLCK,
- DHT_FILE_MIGRATE_DOMAIN);
- if (lk_array[1] == NULL)
- goto err;
- }
-
- local->lock.locks = lk_array;
- local->lock.lk_count = count;
-
- ret = dht_nonblocking_inodelk (frame, lk_array, count,
- dht_rename_lock_cbk);
- if (ret < 0) {
- local->lock.locks = NULL;
- local->lock.lk_count = 0;
- goto err;
- }
-
- return 0;
-err:
- if (lk_array != NULL) {
- int tmp_count = 0, i = 0;
-
- for (i = 0; (i < count) && (lk_array[i]); i++, tmp_count++);
-
- dht_lock_array_free (lk_array, tmp_count);
- GF_FREE (lk_array);
- }
-
- return -1;
-}
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;
- xlator_t *dst_cached = NULL;
- xlator_t *dst_hashed = NULL;
- int op_errno = -1;
- int ret = -1;
- dht_local_t *local = NULL;
- char gfid[GF_UUID_BUF_SIZE] = {0};
-
- VALIDATE_OR_GOTO (frame, err);
- VALIDATE_OR_GOTO (this, err);
- VALIDATE_OR_GOTO (oldloc, err);
- VALIDATE_OR_GOTO (newloc, err);
-
- uuid_unparse(oldloc->inode->gfid, gfid);
-
- src_hashed = dht_subvol_get_hashed (this, oldloc);
- if (!src_hashed) {
- gf_msg (this->name, GF_LOG_INFO, 0,
- DHT_MSG_RENAME_FAILED,
- "No hashed subvolume in layout for path=%s,"
- "(gfid = %s)", oldloc->path, gfid);
- op_errno = EINVAL;
- goto err;
- }
+ xlator_t *src_cached = NULL;
+ xlator_t *src_hashed = NULL;
+ xlator_t *dst_cached = NULL;
+ xlator_t *dst_hashed = NULL;
+ int op_errno = -1;
+ 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);
+
+ src_hashed = dht_subvol_get_hashed (this, oldloc);
+ if (!src_hashed) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "no subvolume in layout for path=%s",
+ oldloc->path);
+ op_errno = EINVAL;
+ goto err;
+ }
- src_cached = dht_subvol_get_cached (this, oldloc->inode);
- if (!src_cached) {
- gf_msg (this->name, GF_LOG_INFO, 0,
- DHT_MSG_RENAME_FAILED,
- "No cached subvolume for path = %s,"
- "(gfid = %s)", oldloc->path, gfid);
+ src_cached = dht_subvol_get_cached (this, oldloc->inode);
+ if (!src_cached) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "no cached subvolume for path=%s", oldloc->path);
+ op_errno = EINVAL;
+ goto err;
+ }
- op_errno = EINVAL;
- goto err;
- }
+ dst_hashed = dht_subvol_get_hashed (this, newloc);
+ if (!dst_hashed) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "no subvolume in layout for path=%s",
+ newloc->path);
+ op_errno = EINVAL;
+ goto err;
+ }
- dst_hashed = dht_subvol_get_hashed (this, newloc);
- if (!dst_hashed) {
- gf_msg (this->name, GF_LOG_INFO, 0,
- DHT_MSG_RENAME_FAILED,
- "No hashed subvolume in layout for path=%s",
- newloc->path);
- op_errno = EINVAL;
- goto err;
- }
+ if (newloc->inode)
+ dst_cached = dht_subvol_get_cached (this, newloc->inode);
- if (newloc->inode)
- dst_cached = dht_subvol_get_cached (this, newloc->inode);
+ local = dht_local_init (frame);
+ if (!local) {
+ op_errno = ENOMEM;
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory");
+ goto err;
+ }
- local = dht_local_init (frame, oldloc, NULL, GF_FOP_RENAME);
- 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->loc2, newloc);
- if (ret == -1) {
- op_errno = ENOMEM;
- goto err;
- }
+ ret = loc_copy (&local->loc, oldloc);
+ if (ret == -1) {
+ op_errno = ENOMEM;
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory");
+ goto err;
+ }
- local->src_hashed = src_hashed;
- local->src_cached = src_cached;
- local->dst_hashed = dst_hashed;
- local->dst_cached = dst_cached;
-
- gf_log (this->name, GF_LOG_INFO,
- "renaming %s (hash=%s/cache=%s) => %s (hash=%s/cache=%s)",
- oldloc->path, src_hashed->name, src_cached->name,
- newloc->path, dst_hashed->name,
- dst_cached ? dst_cached->name : "<nul>");
-
- if (IA_ISDIR (oldloc->inode->ia_type)) {
- dht_rename_dir (frame, this);
- } else {
- local->op_ret = 0;
- ret = dht_rename_lock (frame);
- if (ret < 0)
- goto err;
- }
+ ret = loc_copy (&local->loc2, newloc);
+ if (ret == -1) {
+ op_errno = ENOMEM;
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory");
+ goto err;
+ }
- return 0;
+ local->src_hashed = src_hashed;
+ local->src_cached = src_cached;
+ local->dst_hashed = dst_hashed;
+ local->dst_cached = dst_cached;
+
+ gf_log (this->name, GF_LOG_TRACE,
+ "renaming %s (hash=%s/cache=%s) => %s (hash=%s/cache=%s)",
+ oldloc->path, src_hashed->name, src_cached->name,
+ newloc->path, dst_hashed->name,
+ dst_cached ? dst_cached->name : "<nul>");
+
+ if (S_ISDIR (oldloc->inode->st_mode)) {
+ dht_rename_dir (frame, this);
+ } else {
+ local->op_ret = 0;
+ dht_rename_create_links (frame);
+ }
+
+ 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);
+ op_errno = (op_errno == -1) ? errno : op_errno;
+ DHT_STACK_UNWIND (rename, frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL);
- return 0;
+ return 0;
}
diff --git a/xlators/cluster/dht/src/dht-selfheal.c b/xlators/cluster/dht/src/dht-selfheal.c
index a92dba89d2b..8afa0632b89 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>
- 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-2009 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
@@ -17,721 +26,271 @@
#include "glusterfs.h"
#include "xlator.h"
#include "dht-common.h"
-#include "dht-messages.h"
-#include "glusterfs-acl.h"
-
-#define DHT_SET_LAYOUT_RANGE(layout,i,srt,chunk,path) do { \
- layout->list[i].start = srt; \
- layout->list[i].stop = srt + chunk - 1; \
- \
- gf_msg_trace (this->name, 0, \
- "gave fix: %u - %u on %s for %s", \
- layout->list[i].start, \
- layout->list[i].stop, \
- layout->list[i].xlator->name, path); \
- } while (0)
-
-#define DHT_RESET_LAYOUT_RANGE(layout) do { \
- int cnt = 0; \
- for (cnt = 0; cnt < layout->cnt; cnt++ ) { \
- layout->list[cnt].start = 0; \
- layout->list[cnt].stop = 0; \
- } \
- } while (0)
-
-static uint32_t
-dht_overlap_calc (dht_layout_t *old, int o, dht_layout_t *new, int n)
-{
- if (o >= old->cnt || n >= new->cnt)
- return 0;
-
- if (old->list[o].err > 0 || new->list[n].err > 0)
- return 0;
-
- if (old->list[o].start == old->list[o].stop) {
- return 0;
- }
-
- if (new->list[n].start == new->list[n].stop) {
- return 0;
- }
-
- if ((old->list[o].start > new->list[n].stop) ||
- (old->list[o].stop < new->list[n].start))
- return 0;
-
- return min (old->list[o].stop, new->list[n].stop) -
- max (old->list[o].start, new->list[n].start) + 1;
-}
int
dht_selfheal_dir_finish (call_frame_t *frame, xlator_t *this, int ret)
{
- dht_local_t *local = NULL;
+ dht_local_t *local = NULL;
- local = frame->local;
- local->selfheal.dir_cbk (frame, NULL, frame->this, ret,
- local->op_errno, NULL);
- return 0;
+ local = frame->local;
+ local->selfheal.dir_cbk (frame, NULL, frame->this, ret,
+ local->op_errno);
+
+ return 0;
}
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;
- xlator_t *subvol = NULL;
- int i = 0;
- dht_layout_t *layout = NULL;
- int err = 0;
- int this_call_cnt = 0;
-
- local = frame->local;
- layout = local->selfheal.layout;
- prev = cookie;
- subvol = prev->this;
-
- if (op_ret == 0)
- err = 0;
- else
- err = op_errno;
-
- for (i = 0; i < layout->cnt; i++) {
- if (layout->list[i].xlator == subvol) {
- layout->list[i].err = err;
- break;
- }
- }
+ dht_local_t *local = NULL;
+ call_frame_t *prev = NULL;
+ xlator_t *subvol = NULL;
+ int i = 0;
+ dht_layout_t *layout = NULL;
+ int err = 0;
+ int this_call_cnt = 0;
+
+ local = frame->local;
+ layout = local->selfheal.layout;
+ prev = cookie;
+ subvol = prev->this;
+
+ if (op_ret == 0)
+ err = 0;
+ else
+ err = op_errno;
+
+ for (i = 0; i < layout->cnt; i++) {
+ if (layout->list[i].xlator == subvol) {
+ layout->list[i].err = err;
+ break;
+ }
+ }
- this_call_cnt = dht_frame_return (frame);
+ this_call_cnt = dht_frame_return (frame);
- if (is_last_call (this_call_cnt)) {
- dht_selfheal_dir_finish (frame, this, 0);
- }
+ if (is_last_call (this_call_cnt)) {
+ dht_selfheal_dir_finish (frame, this, 0);
+ }
- return 0;
+ return 0;
}
int
dht_selfheal_dir_xattr_persubvol (call_frame_t *frame, loc_t *loc,
- dht_layout_t *layout, int i,
- xlator_t *req_subvol)
+ dht_layout_t *layout, int i)
{
- xlator_t *subvol = NULL;
- dict_t *xattr = NULL;
- int ret = 0;
- xlator_t *this = NULL;
- int32_t *disk_layout = NULL;
- dht_local_t *local = NULL;
- dht_conf_t *conf = NULL;
- data_t *data = NULL;
- char gfid[GF_UUID_BUF_SIZE] = {0};
-
- local = frame->local;
- if (req_subvol)
- subvol = req_subvol;
- else
- 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);
- VALIDATE_OR_GOTO (this->private, err);
+ xlator_t *subvol = NULL;
+ dict_t *xattr = NULL;
+ int ret = 0;
+ xlator_t *this = NULL;
+ int32_t *disk_layout = NULL;
- conf = this->private;
-
- xattr = get_new_dict ();
- if (!xattr) {
- goto err;
- }
-
- uuid_unparse(loc->inode->gfid, gfid);
-
- ret = dht_disk_layout_extract (this, layout, i, &disk_layout);
- if (ret == -1) {
- gf_msg (this->name, GF_LOG_WARNING, 0,
- DHT_MSG_DIR_SELFHEAL_XATTR_FAILED,
- "Directory self heal xattr failed:"
- " %s: (subvol %s) Failed to extract disk layout,"
- " gfid = %s", loc->path, subvol->name, gfid);
- goto err;
- }
- ret = dict_set_bin (xattr, conf->xattr_name, disk_layout, 4 * 4);
- if (ret == -1) {
- gf_msg (this->name, GF_LOG_WARNING, 0,
- DHT_MSG_DIR_SELFHEAL_XATTR_FAILED,
- "Directory self heal xattr failed:"
- "%s: (subvol %s) Failed to set xattr dictionary,"
- " gfid = %s", loc->path, subvol->name, gfid);
- goto err;
- }
- disk_layout = NULL;
-
- gf_msg_trace (this->name, 0,
- "setting hash range %u - %u (type %d) on subvolume %s"
- " for %s", layout->list[i].start, layout->list[i].stop,
- layout->type, subvol->name, loc->path);
-
- dict_ref (xattr);
- if (local->xattr) {
- data = dict_get (local->xattr, QUOTA_LIMIT_KEY);
- if (data) {
- ret = dict_add (xattr, QUOTA_LIMIT_KEY, data);
- if (ret) {
- gf_msg (this->name, GF_LOG_ERROR, 0,
- DHT_MSG_DICT_SET_FAILED,
- "%s: Failed to set dictionary value:"
- " key = %s",
- loc->path, QUOTA_LIMIT_KEY);
- }
- }
- }
- if (!uuid_is_null (local->gfid))
- uuid_copy (loc->gfid, local->gfid);
+ subvol = layout->list[i].xlator;
+ this = frame->this;
- STACK_WIND (frame, dht_selfheal_dir_xattr_cbk,
- subvol, subvol->fops->setxattr,
- loc, xattr, 0, NULL);
+ xattr = get_new_dict ();
+ if (!xattr) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory");
+ goto err;
+ }
- dict_unref (xattr);
+ ret = dht_disk_layout_extract (this, layout, i, &disk_layout);
+ if (ret == -1) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "failed to extract disk layout");
+ goto err;
+ }
- return 0;
+ ret = dict_set_bin (xattr, "trusted.glusterfs.dht",
+ disk_layout, 4 * 4);
+ if (ret == -1) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "failed to set xattr dictionary");
+ goto err;
+ }
+ disk_layout = NULL;
-err:
- if (xattr)
- dict_destroy (xattr);
+ gf_log (this->name, GF_LOG_TRACE,
+ "setting hash range %u - %u (type %d) on subvolume %s for %s",
+ layout->list[i].start, layout->list[i].stop,
+ layout->type, subvol->name, loc->path);
- GF_FREE (disk_layout);
+ dict_ref (xattr);
- dht_selfheal_dir_xattr_cbk (frame, subvol, frame->this,
- -1, ENOMEM, NULL);
- 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;
- dht_conf_t *conf = NULL;
- dht_layout_t *dummy = NULL;
-
- local = frame->local;
- this = frame->this;
- conf = this->private;
+ STACK_WIND (frame, dht_selfheal_dir_xattr_cbk,
+ subvol, subvol->fops->setxattr,
+ loc, xattr, 0);
- gf_msg_debug (this->name, 0,
- "%s: Writing the new range for all subvolumes",
- loc->path);
+ dict_unref (xattr);
- local->call_cnt = count = conf->subvolume_cnt;
+ return 0;
- dht_log_new_layout_for_dir_selfheal (this, loc, layout);
-
- for (i = 0; i < layout->cnt; i++) {
- dht_selfheal_dir_xattr_persubvol (frame, loc, layout, i, NULL);
+err:
+ if (xattr)
+ dict_destroy (xattr);
- if (--count == 0)
- goto out;
- }
- /* if we are here, subvolcount > layout_count. subvols-per-directory
- * option might be set here. We need to clear out layout from the
- * non-participating subvolumes, else it will result in overlaps */
- dummy = dht_layout_new (this, 1);
- if (!dummy)
- goto out;
- for (i = 0; i < conf->subvolume_cnt; i++) {
- if (_gf_false ==
- dht_is_subvol_in_layout (layout, conf->subvolumes[i])) {
- dht_selfheal_dir_xattr_persubvol (frame, loc, dummy, 0,
- conf->subvolumes[i]);
- if (--count == 0)
- break;
- }
- }
+ if (disk_layout)
+ FREE (disk_layout);
- dht_layout_unref (this, dummy);
-out:
- return 0;
+ dht_selfheal_dir_xattr_cbk (frame, subvol, frame->this,
+ -1, ENOMEM);
+ return 0;
}
+
int
dht_selfheal_dir_xattr (call_frame_t *frame, loc_t *loc, dht_layout_t *layout)
{
- dht_local_t *local = NULL;
- int missing_xattr = 0;
- int i = 0;
- xlator_t *this = NULL;
- dht_conf_t *conf = NULL;
- dht_layout_t *dummy = NULL;
-
- local = frame->local;
- this = frame->this;
- conf = this->private;
-
- 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.
- * !layout->list[i].stop would mean layout absent
- */
-
- continue;
- }
- missing_xattr++;
- }
- /* Also account for subvolumes with no-layout. Used for zero'ing out
- * the layouts and for setting quota key's if present */
- for (i = 0; i < conf->subvolume_cnt; i++) {
- if (_gf_false ==
- dht_is_subvol_in_layout (layout, conf->subvolumes[i])) {
- missing_xattr++;
- }
- }
- gf_msg_trace (this->name, 0,
- "%d subvolumes missing xattr for %s",
- missing_xattr, loc->path);
-
- if (missing_xattr == 0) {
- dht_selfheal_dir_finish (frame, this, 0);
- return 0;
- }
+ dht_local_t *local = NULL;
+ int missing_xattr = 0;
+ int i = 0;
+ int ret = 0;
+ xlator_t *this = NULL;
+
+ local = frame->local;
+ this = frame->this;
+
+ 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 itself non existant.
+ * !layout->list[i].stop would mean layout absent
+ */
+ continue;
+ }
+ missing_xattr++;
+ }
- local->call_cnt = missing_xattr;
+ gf_log (this->name, GF_LOG_TRACE,
+ "%d subvolumes missing xattr for %s",
+ missing_xattr, loc->path);
- dht_log_new_layout_for_dir_selfheal (this, loc, layout);
+ if (missing_xattr == 0) {
+ dht_selfheal_dir_finish (frame, this, 0);
+ return 0;
+ }
- for (i = 0; i < layout->cnt; i++) {
- if (layout->list[i].err != -1 || !layout->list[i].stop)
- continue;
+ local->call_cnt = missing_xattr;
- dht_selfheal_dir_xattr_persubvol (frame, loc, layout, i, NULL);
+ for (i = 0; i < layout->cnt; i++) {
+ if (layout->list[i].err != -1 || !layout->list[i].stop)
+ continue;
- if (--missing_xattr == 0)
- break;
- }
- dummy = dht_layout_new (this, 1);
- if (!dummy)
- goto out;
- for (i = 0; i < conf->subvolume_cnt && missing_xattr; i++) {
- if (_gf_false ==
- dht_is_subvol_in_layout (layout, conf->subvolumes[i])) {
- dht_selfheal_dir_xattr_persubvol (frame, loc, dummy, 0,
- conf->subvolumes[i]);
- missing_xattr--;
- }
- }
+ ret = dht_selfheal_dir_xattr_persubvol (frame, loc, layout, i);
- dht_layout_unref (this, dummy);
-out:
- return 0;
+ if (--missing_xattr == 0)
+ break;
+ }
+ return 0;
}
-gf_boolean_t
-dht_is_subvol_part_of_layout (dht_layout_t *layout, xlator_t *xlator)
-{
- int i = 0;
- gf_boolean_t ret = _gf_false;
-
- for (i = 0; i < layout->cnt; i++) {
- if (!strcmp (layout->list[i].xlator->name, xlator->name)) {
- ret = _gf_true;
- break;
-
- }
- }
-
- return ret;
-}
int
-dht_layout_index_from_conf (dht_layout_t *layout, xlator_t *xlator)
-{
- int i = -1;
- int j = 0;
-
- for (j = 0; j < layout->cnt; j++) {
- if (!strcmp (layout->list[j].xlator->name, xlator->name)) {
- i = j;
- break;
- }
- }
-
- return i;
-}
-
-
-static int
-dht_selfheal_dir_xattr_for_nameless_lookup (call_frame_t *frame, loc_t *loc,
- dht_layout_t *layout)
+dht_selfheal_dir_mkdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int op_ret, int op_errno,
+ inode_t *inode, struct stat *stbuf,
+ struct stat *preparent, struct stat *postparent)
{
- dht_local_t *local = NULL;
- int missing_xattr = 0;
- int i = 0;
- xlator_t *this = NULL;
- dht_conf_t *conf = NULL;
- dht_layout_t *dummy = NULL;
- int j = 0;
-
- local = frame->local;
- this = frame->this;
- conf = this->private;
-
- 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.
- !layout->list[i].stop would mean layout absent
- */
-
- continue;
- }
- missing_xattr++;
- }
-
- /* Also account for subvolumes with no-layout. Used for zero'ing out
- the layouts and for setting quota key's if present */
-
- /* Send where either the subvol is not part of layout,
- * or it is part of the layout but error is non-zero but error
- * is not equal to -1 or ENOENT.
- */
-
- for (i = 0; i < conf->subvolume_cnt; i++) {
- if (dht_is_subvol_part_of_layout (layout, conf->subvolumes[i])
- == _gf_false) {
- missing_xattr++;
- continue;
- }
-
- j = dht_layout_index_from_conf (layout, conf->subvolumes[i]);
-
- if ((j != -1) && (layout->list[j].err != -1) &&
- (layout->list[j].err != 0) &&
- (layout->list[j].err != ENOENT)) {
- missing_xattr++;
- }
-
- }
+ dht_local_t *local = NULL;
+ dht_layout_t *layout = NULL;
+ call_frame_t *prev = NULL;
+ xlator_t *subvol = NULL;
+ int i = 0;
+ int this_call_cnt = 0;
- gf_log (this->name, GF_LOG_TRACE,
- "%d subvolumes missing xattr for %s",
- missing_xattr, loc->path);
+ local = frame->local;
+ layout = local->selfheal.layout;
+ prev = cookie;
+ subvol = prev->this;
- if (missing_xattr == 0) {
- dht_selfheal_dir_finish (frame, this, 0);
- return 0;
- }
-
- local->call_cnt = missing_xattr;
-
- dht_log_new_layout_for_dir_selfheal (this, loc, layout);
-
- for (i = 0; i < layout->cnt; i++) {
- if (layout->list[i].err != -1 || !layout->list[i].stop)
- continue;
-
- dht_selfheal_dir_xattr_persubvol (frame, loc, layout, i, NULL);
-
- if (--missing_xattr == 0)
- break;
- }
-
- dummy = dht_layout_new (this, 1);
- if (!dummy)
- goto out;
-
- for (i = 0; i < conf->subvolume_cnt && missing_xattr; i++) {
- if (dht_is_subvol_part_of_layout (layout, conf->subvolumes[i])
- == _gf_false) {
- dht_selfheal_dir_xattr_persubvol (frame, loc, dummy, 0,
- conf->subvolumes[i]);
- missing_xattr--;
- continue;
- }
-
- j = dht_layout_index_from_conf (layout, conf->subvolumes[i]);
-
- if ((j != -1) && (layout->list[j].err != -1) &&
- (layout->list[j].err != ENOENT) &&
- (layout->list[j].err != 0)) {
- dht_selfheal_dir_xattr_persubvol (frame, loc, dummy, 0,
- conf->subvolumes[i]);
- missing_xattr--;
- }
- }
+ dht_stat_merge (this, &local->stbuf, stbuf, prev->this);
+ if (prev->this == local->hashed_subvol)
+ local->st_ino = local->stbuf.st_ino;
- dht_layout_unref (this, dummy);
-out:
- return 0;
+ dht_stat_merge (this, &local->preparent, preparent, prev->this);
+ dht_stat_merge (this, &local->postparent, postparent, prev->this);
-}
-
-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)
-{
- dht_local_t *local = NULL;
- dht_layout_t *layout = NULL;
- int this_call_cnt = 0;
-
- local = frame->local;
- layout = local->selfheal.layout;
+ if ((op_ret == 0) || (op_errno == EEXIST)) {
+ for (i = 0; i < layout->cnt; i++) {
+ if (layout->list[i].xlator == subvol) {
+ layout->list[i].err = -1;
+ break;
+ }
+ }
+ }
- this_call_cnt = dht_frame_return (frame);
+ this_call_cnt = dht_frame_return (frame);
- if (is_last_call (this_call_cnt)) {
- dht_selfheal_dir_xattr (frame, &local->loc, layout);
- }
+ if (is_last_call (this_call_cnt)) {
+ dht_selfheal_dir_xattr (frame, &local->loc, layout);
+ }
- return 0;
+ return 0;
}
int
-dht_selfheal_dir_setattr (call_frame_t *frame, loc_t *loc, struct iatt *stbuf,
- int32_t valid, dht_layout_t *layout)
+dht_selfheal_dir_mkdir (call_frame_t *frame, loc_t *loc,
+ dht_layout_t *layout, int force)
{
- int missing_attr = 0;
- int i = 0;
- dht_local_t *local = NULL;
- xlator_t *this = NULL;
-
- local = frame->local;
- this = frame->this;
-
- for (i = 0; i < layout->cnt; i++) {
- if (layout->list[i].err == -1)
- missing_attr++;
- }
-
- if (missing_attr == 0) {
- dht_selfheal_dir_xattr (frame, loc, layout);
- return 0;
- }
+ int missing_dirs = 0;
+ int i = 0;
+ dht_local_t *local = NULL;
+ xlator_t *this = NULL;
- 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) {
- gf_msg_trace (this->name, 0,
- "%s: setattr on subvol %s, gfid = %s",
- loc->path, layout->list[i].xlator->name,
- uuid_utoa(loc->gfid));
-
- STACK_WIND (frame, dht_selfheal_dir_setattr_cbk,
- layout->list[i].xlator,
- layout->list[i].xlator->fops->setattr,
- loc, stbuf, valid, NULL);
- }
- }
-
- return 0;
-}
-
-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)
-{
- dht_local_t *local = NULL;
- dht_layout_t *layout = NULL;
- call_frame_t *prev = NULL;
- xlator_t *subvol = NULL;
- int i = 0;
- int this_call_cnt = 0;
- char gfid[GF_UUID_BUF_SIZE] = {0};
-
- local = frame->local;
- layout = local->selfheal.layout;
- prev = cookie;
- subvol = prev->this;
-
- if ((op_ret == 0) || ((op_ret == -1) && (op_errno == EEXIST))) {
- for (i = 0; i < layout->cnt; i++) {
- if (layout->list[i].xlator == subvol) {
- layout->list[i].err = -1;
- break;
- }
- }
- }
- if (op_ret) {
+ local = frame->local;
+ this = frame->this;
- uuid_unparse(local->loc.gfid, gfid);
- gf_msg (this->name, ((op_errno == EEXIST) ? GF_LOG_DEBUG :
- GF_LOG_WARNING),
- op_errno, DHT_MSG_DIR_SELFHEAL_FAILED,
- "Directory selfheal failed: path = %s, gfid = %s",
- local->loc.path, gfid );
- goto out;
- }
-
- dht_iatt_merge (this, &local->stbuf, stbuf, prev->this);
- dht_iatt_merge (this, &local->preparent, preparent, prev->this);
- dht_iatt_merge (this, &local->postparent, postparent, prev->this);
+ for (i = 0; i < layout->cnt; i++) {
+ if (layout->list[i].err == ENOENT || force)
+ missing_dirs++;
+ }
-out:
- this_call_cnt = dht_frame_return (frame);
+ if (missing_dirs == 0) {
+ dht_selfheal_dir_xattr (frame, loc, layout);
+ return 0;
+ }
- if (is_last_call (this_call_cnt)) {
- dht_selfheal_dir_setattr (frame, &local->loc, &local->stbuf, 0xffffff, layout);
- }
+ local->call_cnt = missing_dirs;
+ for (i = 0; i < layout->cnt; i++) {
+ if (layout->list[i].err == ENOENT || force) {
+ gf_log (this->name, GF_LOG_TRACE,
+ "creating directory %s on subvol %s",
+ loc->path, layout->list[i].xlator->name);
+
+ STACK_WIND (frame, dht_selfheal_dir_mkdir_cbk,
+ layout->list[i].xlator,
+ layout->list[i].xlator->fops->mkdir,
+ loc, local->stbuf.st_mode);
+ }
+ }
- return 0;
+ 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_msg_debug (this->name, 0,
- "ACL_DEFAULT xattr not present");
- goto cont;
- }
- ret = dict_set (dict, POSIX_ACL_DEFAULT_XATTR, acl_default);
- if (ret)
- gf_msg (this->name, GF_LOG_WARNING, 0,
- DHT_MSG_DICT_SET_FAILED,
- "Failed to set dictionary value.key = %s",
- POSIX_ACL_DEFAULT_XATTR);
-cont:
- acl_access = dict_get (xattr, POSIX_ACL_ACCESS_XATTR);
- if (!acl_access) {
- gf_msg_debug (this->name, 0,
- "ACL_ACCESS xattr not present");
- goto out;
- }
- ret = dict_set (dict, POSIX_ACL_ACCESS_XATTR, acl_access);
- if (ret)
- gf_msg (this->name, GF_LOG_WARNING, 0,
- DHT_MSG_DICT_SET_FAILED,
- "Failed to set dictionary value.key = %s",
- POSIX_ACL_ACCESS_XATTR);
-
-out:
- return;
-}
-
-int
-dht_selfheal_dir_mkdir (call_frame_t *frame, loc_t *loc,
- dht_layout_t *layout, int force)
-{
- int missing_dirs = 0;
- int i = 0;
- int ret = -1;
- dht_local_t *local = NULL;
- xlator_t *this = NULL;
- dict_t *dict = NULL;
-
- local = frame->local;
- this = frame->this;
-
- for (i = 0; i < layout->cnt; i++) {
- if (layout->list[i].err == ENOENT || force)
- missing_dirs++;
- }
-
- if (missing_dirs == 0) {
- dht_selfheal_dir_setattr (frame, loc, &local->stbuf, 0xffffffff, layout);
- return 0;
- }
-
- local->call_cnt = missing_dirs;
- if (!uuid_is_null (local->gfid)) {
- dict = dict_new ();
- if (!dict)
- return -1;
-
- ret = dict_set_static_bin (dict, "gfid-req", local->gfid, 16);
- if (ret)
- gf_msg (this->name, GF_LOG_WARNING, 0,
- DHT_MSG_DICT_SET_FAILED,
- "%s: Failed to set dictionary value:"
- " key = gfid-req", 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");
-
- for (i = 0; i < layout->cnt; i++) {
- if (layout->list[i].err == ENOENT || force) {
- gf_msg_debug (this->name, 0,
- "Creating directory %s on subvol %s",
- loc->path, layout->list[i].xlator->name);
-
- STACK_WIND (frame, dht_selfheal_dir_mkdir_cbk,
- layout->list[i].xlator,
- layout->list[i].xlator->fops->mkdir,
- loc,
- st_mode_from_ia (local->stbuf.ia_prot,
- local->stbuf.ia_type),
- 0, dict);
- }
- }
-
- if (dict)
- dict_unref (dict);
-
- return 0;
-}
int
dht_selfheal_layout_alloc_start (xlator_t *this, loc_t *loc,
dht_layout_t *layout)
{
- int start = 0;
- uint32_t hashval = 0;
- int ret = 0;
- const char *str = NULL;
- dht_conf_t *conf = NULL;
- char buf[UUID_CANONICAL_FORM_LEN + 1] = {0, };
+ int start = 0;
+ dht_conf_t *conf = NULL;
+ uint32_t hashval = 0;
+ int ret = 0;
conf = this->private;
- if (conf->randomize_by_gfid) {
- str = uuid_utoa_r (loc->gfid, buf);
- } else {
- str = loc->path;
- }
-
- ret = dht_hash_compute (this, layout->type, str, &hashval);
+ ret = dht_hash_compute (layout->type, loc->path, &hashval);
if (ret == 0) {
start = (hashval % layout->cnt);
}
@@ -739,656 +298,237 @@ 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;
+ 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;
+ conf = this->private;
- for (i = 0; i < layout->cnt; i++) {
- err = layout->list[i].err;
- if (err == -1 || err == 0 || err == ENOENT) {
- /* Setting list[i].err = -1 is an indication for
- dht_selfheal_layout_new_directory() to assign
- a range. We set it to -1 based on any one of
- the three criteria:
-
- - err == -1 already, which means directory
- existed but layout was not set on it.
-
- - err == 0, which means directory exists and
- has an old layout piece which will be
- overwritten now.
-
- - err == ENOENT, which means directory does
- not exist (possibly racing with mkdir or
- finishing half done mkdir). The missing
- directory will be attempted to be recreated.
-
- It is important to note that it is safe
- to race with mkdir() as self-heal and
- mkdir are idempotent operations. Both will
- strive to set the directory and layouts to
- the same final state.
- */
- count++;
- if (!err)
- layout->list[i].err = -1;
- }
- }
+ for (i = 0; i < layout->cnt; i++) {
+ err = layout->list[i].err;
+ if (err == -1 || err == 0) {
+ layout->list[i].err = -1;
+ 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++;
+ cnt++;
}
}
}
- /* if layout->spread_cnt is set, check if it is <= available
- * subvolumes (down brick and decommissioned bricks are considered
- * un-availbale). Else return count (available up bricks) */
- count = ((layout->spread_cnt &&
- (layout->spread_cnt <= count)) ?
- layout->spread_cnt : ((count) ? count : 1));
-
- return count;
-}
+ chunk = ((unsigned long) 0xffffffff) / cnt;
+ start_subvol = dht_selfheal_layout_alloc_start (this, loc, layout);
-void dht_selfheal_layout_new_directory (call_frame_t *frame, loc_t *loc,
- dht_layout_t *new_layout);
-
-void dht_layout_entry_swap (dht_layout_t *layout, int i, int j);
-void dht_layout_range_swap (dht_layout_t *layout, int i, int j);
-
-/*
- * It's a bit icky using local variables in a macro, but it makes the rest
- * of the code a lot clearer.
- */
-#define OV_ENTRY(x,y) table[x*new->cnt+y]
-
-void
-dht_selfheal_layout_maximize_overlap (call_frame_t *frame, loc_t *loc,
- dht_layout_t *new, dht_layout_t *old)
-{
- int i = 0;
- int j = 0;
- uint32_t curr_overlap = 0;
- uint32_t max_overlap = 0;
- int max_overlap_idx = -1;
- uint32_t overlap = 0;
- uint32_t *table = NULL;
-
- dht_layout_sort_volname (old);
- /* Now both old_layout->list[] and new_layout->list[]
- are match the same xlators/subvolumes. i.e,
- old_layout->[i] and new_layout->[i] are referring
- to the same subvolumes
- */
-
- /* Build a table of overlaps between new[i] and old[j]. */
- table = alloca(sizeof(overlap)*old->cnt*new->cnt);
- if (!table) {
- return;
- }
- memset(table,0,sizeof(overlap)*old->cnt*new->cnt);
- for (i = 0; i < new->cnt; ++i) {
- for (j = 0; j < old->cnt; ++j) {
- OV_ENTRY(i,j) = dht_overlap_calc(old,j,new,i);
- }
- }
+ for (i = start_subvol; i < layout->cnt; i++) {
+ err = layout->list[i].err;
+ if (err == -1) {
+ layout->list[i].start = start;
+ layout->list[i].stop = start + chunk - 1;
+
+ start = start + chunk;
- for (i = 0; i < new->cnt; i++) {
- if (new->list[i].err > 0) {
- /* Subvol might be marked for decommission
- with EINVAL, or some other serious error
- marked with positive errno.
- */
- continue;
- }
-
- max_overlap = 0;
- max_overlap_idx = i;
- for (j = (i + 1); j < new->cnt; ++j) {
- if (new->list[j].err > 0) {
- /* Subvol might be marked for decommission
- with EINVAL, or some other serious error
- marked with positive errno.
- */
- continue;
- }
- /* Calculate the overlap now. */
- curr_overlap = OV_ENTRY(i,i) + OV_ENTRY(j,j);
- /* Calculate the overlap after the proposed swap. */
- overlap = OV_ENTRY(i,j) + OV_ENTRY(j,i);
- /* Are we better than status quo? */
- if (overlap > curr_overlap) {
- overlap -= curr_overlap;
- /* Are we better than the previous choice? */
- if (overlap > max_overlap) {
- max_overlap = overlap;
- max_overlap_idx = j;
- }
- }
- }
-
- if (max_overlap_idx != i) {
- dht_layout_range_swap (new, i, max_overlap_idx);
- /* Need to swap the table values too. */
- for (j = 0; j < old->cnt; ++j) {
- overlap = OV_ENTRY(i,j);
- OV_ENTRY(i,j) = OV_ENTRY(max_overlap_idx,j);
- OV_ENTRY(max_overlap_idx,j) = overlap;
- }
- }
+ 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;
+ break;
+ }
+ }
}
-}
-
-
-dht_layout_t *
-dht_fix_layout_of_directory (call_frame_t *frame, loc_t *loc,
- dht_layout_t *layout)
-{
- int i = 0;
- xlator_t *this = NULL;
- dht_layout_t *new_layout = NULL;
- dht_conf_t *priv = NULL;
- dht_local_t *local = NULL;
- uint32_t subvol_down = 0;
- int ret = 0;
-
- this = frame->this;
- priv = this->private;
- local = frame->local;
-
- if (layout->type == DHT_HASH_TYPE_DM_USER) {
- gf_msg_debug (THIS->name, 0, "leaving %s alone",
- loc->path);
- goto done;
- }
-
- new_layout = dht_layout_new (this, priv->subvolume_cnt);
- if (!new_layout)
- goto done;
-
- /* If a subvolume is down, do not re-write the layout. */
- ret = dht_layout_anomalies (this, loc, layout, NULL, NULL, NULL,
- &subvol_down, NULL, NULL);
-
- if (subvol_down || (ret == -1)) {
- gf_msg (this->name, GF_LOG_WARNING, 0,
- DHT_MSG_LAYOUT_FIX_FAILED,
- "Layout fix failed: %u subvolume(s) are down"
- ". Skipping fix layout.", subvol_down);
- GF_FREE (new_layout);
- return NULL;
- }
-
- for (i = 0; i < new_layout->cnt; i++) {
- if (layout->list[i].err != ENOSPC)
- new_layout->list[i].err = layout->list[i].err;
- else
- new_layout->list[i].err = -1;
-
- new_layout->list[i].xlator = layout->list[i].xlator;
- }
-
- if (priv->du_stats) {
- for (i = 0; i < priv->subvolume_cnt; ++i) {
- gf_log (this->name, GF_LOG_INFO,
- "subvolume %d (%s): %u chunks", i,
- priv->subvolumes[i]->name,
- priv->du_stats[i].chunks);
- }
- }
- else {
- gf_log (this->name, GF_LOG_WARNING, "no du stats ?!?");
- }
-
- /* First give it a layout as though it is a new directory. This
- ensures rotation to kick in */
- dht_layout_sort_volname (new_layout);
- dht_selfheal_layout_new_directory (frame, loc, new_layout);
-
- /* Now selectively re-assign ranges only when it helps */
- dht_selfheal_layout_maximize_overlap (frame, loc, new_layout, layout);
-
-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;
- }
-
- return local->layout;
-}
-
-
-/*
- * Having to call this 2x for each entry in the layout is pretty horrible, but
- * that's what all of this layout-sorting nonsense gets us.
- */
-uint32_t
-dht_get_chunks_from_xl (xlator_t *parent, xlator_t *child)
-{
- dht_conf_t *priv = parent->private;
- xlator_list_t *trav;
- uint32_t index = 0;
-
- if (!priv->du_stats) {
- return 0;
- }
- for (trav = parent->children; trav; trav = trav->next) {
- if (trav->xlator == child) {
- return priv->du_stats[index].chunks;
- }
- ++index;
- }
-
- return 0;
+ for (i = 0; i < start_subvol; i++) {
+ err = layout->list[i].err;
+ if (err == -1) {
+ 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;
+ break;
+ }
+ }
+ }
}
-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 bricks_to_use = 0;
- int err = 0;
- int start_subvol = 0;
- uint32_t curr_size;
- uint32_t total_size = 0;
- int real_i;
- dht_conf_t *priv;
- gf_boolean_t weight_by_size;
- int bricks_used = 0;
-
- this = frame->this;
- priv = this->private;
- weight_by_size = priv->do_weighting;
-
- bricks_to_use = dht_get_layout_count (this, layout, 1);
- GF_ASSERT (bricks_to_use > 0);
-
- bricks_used = 0;
- for (i = 0; i < layout->cnt; ++i) {
- err = layout->list[i].err;
- if ((err != -1) && (err != ENOENT)) {
- continue;
- }
- curr_size = dht_get_chunks_from_xl (this,
- layout->list[i].xlator);
- if (!curr_size) {
- weight_by_size = _gf_false;
- break;
- }
- total_size += curr_size;
- if (++bricks_used >= bricks_to_use) {
- break;
- }
- }
-
- if (weight_by_size) {
- /* We know total_size is not zero. */
- chunk = ((unsigned long) 0xffffffff) / total_size;
- gf_log (this->name, GF_LOG_INFO,
- "chunk size = 0xffffffff / %u = 0x%x",
- total_size, chunk);
- }
- else {
- chunk = ((unsigned long) 0xffffffff) / bricks_used;
- }
-
- start_subvol = dht_selfheal_layout_alloc_start (this, loc, layout);
-
- /* clear out the range, as we are re-computing here */
- DHT_RESET_LAYOUT_RANGE (layout);
-
- /*
- * OK, what's this "real_i" stuff about? This used to be two loops -
- * from start_subvol to layout->cnt-1, then from 0 to start_subvol-1.
- * That way is practically an open invitation to bugs when only one
- * of the loops is updated. Using real_i and modulo operators to make
- * it one loop avoids this problem. Remember, folks: it's everyone's
- * responsibility to help stamp out copy/paste abuse.
- */
- bricks_used = 0;
- for (real_i = 0; real_i < layout->cnt; real_i++) {
- i = (real_i + start_subvol) % layout->cnt;
- err = layout->list[i].err;
- if ((err != -1) && (err != ENOENT)) {
- continue;
- }
- if (weight_by_size) {
- curr_size = dht_get_chunks_from_xl (this,
- layout->list[i].xlator);
- if (!curr_size) {
- continue;
- }
- }
- else {
- curr_size = 1;
- }
- gf_log (this->name, GF_LOG_INFO,
- "assigning range size 0x%x to %s", chunk * curr_size,
- layout->list[i].xlator->name);
- DHT_SET_LAYOUT_RANGE(layout, i, start, chunk * curr_size,
- loc->path);
- if (++bricks_used >= bricks_to_use) {
- layout->list[i].stop = 0xffffffff;
- goto done;
- }
- start += (chunk * curr_size);
- }
-
-done:
- return;
-}
-
int
dht_selfheal_dir_getafix (call_frame_t *frame, loc_t *loc,
- dht_layout_t *layout)
+ dht_layout_t *layout)
{
- dht_local_t *local = NULL;
- uint32_t holes = 0;
- int ret = -1;
- int i = -1;
- uint32_t overlaps = 0;
-
- local = frame->local;
-
- holes = local->selfheal.hole_cnt;
- overlaps = local->selfheal.overlaps_cnt;
-
- if (holes || overlaps) {
- dht_selfheal_layout_new_directory (frame, loc, layout);
- ret = 0;
- }
-
- for (i = 0; i < layout->cnt; i++) {
- /* directory not present */
- if (layout->list[i].err == ENOENT) {
- ret = 0;
- break;
- }
- }
-
- /* TODO: give a fix to these non-virgins */
+ dht_conf_t *conf = NULL;
+ xlator_t *this = NULL;
+ dht_local_t *local = NULL;
+ int missing = -1;
+ int down = -1;
+ int holes = -1;
+ int ret = -1;
+ int i = -1;
+ int overlaps = -1;
+
+ this = frame->this;
+ conf = this->private;
+ local = frame->local;
+
+ missing = local->selfheal.missing;
+ down = local->selfheal.down;
+ holes = local->selfheal.hole_cnt;
+ overlaps = local->selfheal.overlaps_cnt;
+
+ if ((missing + down) == conf->subvolume_cnt) {
+ dht_selfheal_layout_new_directory (frame, loc, layout);
+ ret = 0;
+ }
- return ret;
-}
+ if (holes <= down) {
+ /* the down subvol might fill up the holes */
+ ret = 0;
+ }
-int
-dht_selfheal_new_directory (call_frame_t *frame,
- dht_selfheal_dir_cbk_t dir_cbk,
- dht_layout_t *layout)
-{
- dht_local_t *local = NULL;
+ if (holes || overlaps) {
+ dht_selfheal_layout_new_directory (frame, loc, layout);
+ ret = 0;
+ }
- local = frame->local;
+ for (i = 0; i < layout->cnt; i++) {
+ /* directory not present */
+ if (layout->list[i].err == ENOENT) {
+ ret = 0;
+ break;
+ }
+ }
- local->selfheal.dir_cbk = dir_cbk;
- local->selfheal.layout = dht_layout_ref (frame->this, layout);
+ /* TODO: give a fix to these non-virgins */
- dht_layout_sort_volname (layout);
- dht_selfheal_layout_new_directory (frame, &local->loc, layout);
- dht_selfheal_dir_xattr (frame, &local->loc, layout);
- return 0;
+ return ret;
}
int
-dht_fix_directory_layout (call_frame_t *frame,
- dht_selfheal_dir_cbk_t dir_cbk,
- dht_layout_t *layout)
+dht_selfheal_new_directory (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;
+ dht_local_t *local = NULL;
- local = frame->local;
+ 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);
- if (!tmp_layout) {
- return -1;
- }
- dht_fix_dir_xattr (frame, &local->loc, tmp_layout);
+ local->selfheal.dir_cbk = dir_cbk;
+ local->selfheal.layout = dht_layout_ref (frame->this, layout);
- return 0;
+ dht_layout_sort_volname (layout);
+ dht_selfheal_layout_new_directory (frame, &local->loc, layout);
+ dht_selfheal_dir_xattr (frame, &local->loc, 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)
+ loc_t *loc, dht_layout_t *layout)
{
- dht_local_t *local = NULL;
- uint32_t down = 0;
- uint32_t misc = 0;
- int ret = 0;
- xlator_t *this = NULL;
- char gfid[GF_UUID_BUF_SIZE] = {0};
-
- local = frame->local;
- this = frame->this;
-
- uuid_unparse(loc->gfid, gfid);
-
-
- dht_layout_anomalies (this, loc, layout,
- &local->selfheal.hole_cnt,
- &local->selfheal.overlaps_cnt,
- NULL, &local->selfheal.down,
- &local->selfheal.misc, NULL);
-
- down = local->selfheal.down;
- misc = local->selfheal.misc;
-
- local->selfheal.dir_cbk = dir_cbk;
- local->selfheal.layout = dht_layout_ref (this, layout);
-
- if (down) {
- gf_msg (this->name, GF_LOG_WARNING, 0,
- DHT_MSG_DIR_SELFHEAL_FAILED,
- "Directory selfheal failed: %d subvolumes down."
- "Not fixing. path = %s, gfid = %s",
- down, loc->path, gfid);
- ret = 0;
- goto sorry_no_fix;
- }
-
- if (misc) {
- gf_msg (this->name, GF_LOG_WARNING, 0,
- DHT_MSG_DIR_SELFHEAL_FAILED,
- "Directory selfheal failed : %d subvolumes "
- "have unrecoverable errors. path = %s, gfid = %s",
- misc, loc->path, gfid);
+ dht_local_t *local = NULL;
+ uint32_t holes = 0;
+ uint32_t overlaps = 0;
+ uint32_t missing = 0;
+ uint32_t down = 0;
+ uint32_t misc = 0;
+ int ret = 0;
+ xlator_t *this = NULL;
+
+ local = frame->local;
+ this = frame->this;
+
+ ret = dht_layout_anomalies (this, loc, layout,
+ &local->selfheal.hole_cnt,
+ &local->selfheal.overlaps_cnt,
+ &local->selfheal.missing,
+ &local->selfheal.down,
+ &local->selfheal.misc);
+
+ holes = local->selfheal.hole_cnt;
+ overlaps = local->selfheal.overlaps_cnt;
+ missing = local->selfheal.missing;
+ down = local->selfheal.down;
+ misc = local->selfheal.misc;
+
+ local->selfheal.dir_cbk = dir_cbk;
+ local->selfheal.layout = dht_layout_ref (this, layout);
+
+ if (down) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "%d subvolumes down -- not fixing", down);
+ ret = 0;
+ goto sorry_no_fix;
+ }
- ret = 0;
- goto sorry_no_fix;
- }
+ if (misc) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "%d subvolumes have unrecoverable errors", misc);
+ ret = 0;
+ goto sorry_no_fix;
+ }
- dht_layout_sort_volname (layout);
- ret = dht_selfheal_dir_getafix (frame, loc, layout);
+ dht_layout_sort_volname (layout);
+ ret = dht_selfheal_dir_getafix (frame, loc, layout);
- if (ret == -1) {
- gf_msg (this->name, GF_LOG_WARNING, 0,
- DHT_MSG_DIR_SELFHEAL_FAILED,
- "Directory selfheal failed: "
- "Unable to form layout for directory %s",
- loc->path);
- goto sorry_no_fix;
- }
+ if (ret == -1) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "not able to form layout for the directory");
+ goto sorry_no_fix;
+ }
- dht_selfheal_dir_mkdir (frame, loc, layout, 0);
+ dht_selfheal_dir_mkdir (frame, loc, layout, 0);
- return 0;
+ return 0;
sorry_no_fix:
- /* TODO: need to put appropriate local->op_errno */
- dht_selfheal_dir_finish (frame, this, ret);
+ /* TODO: need to put appropriate local->op_errno */
+ dht_selfheal_dir_finish (frame, this, ret);
- return 0;
+ return 0;
}
-int
-dht_selfheal_directory_for_nameless_lookup (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 down = 0;
- uint32_t misc = 0;
- int ret = 0;
- xlator_t *this = NULL;
-
- local = frame->local;
- this = frame->this;
- dht_layout_anomalies (this, loc, layout,
- &local->selfheal.hole_cnt,
- &local->selfheal.overlaps_cnt,
- NULL, &local->selfheal.down,
- &local->selfheal.misc, NULL);
-
- down = local->selfheal.down;
- misc = local->selfheal.misc;
-
- local->selfheal.dir_cbk = dir_cbk;
- local->selfheal.layout = dht_layout_ref (this, layout);
-
- if (down) {
- gf_log (this->name, GF_LOG_WARNING,
- "%d subvolumes down -- not fixing", down);
- ret = 0;
- goto sorry_no_fix;
- }
-
- if (misc) {
- gf_log (this->name, GF_LOG_WARNING,
- "%d subvolumes have unrecoverable errors", misc);
- ret = 0;
- goto sorry_no_fix;
- }
-
- dht_layout_sort_volname (layout);
- ret = dht_selfheal_dir_getafix (frame, loc, layout);
-
- if (ret == -1) {
- gf_log (this->name, GF_LOG_WARNING,
- "not able to form layout for the directory");
- goto sorry_no_fix;
- }
-
- dht_selfheal_dir_xattr_for_nameless_lookup (frame, &local->loc, layout);
- return 0;
-
-sorry_no_fix:
- /* TODO: need to put appropriate local->op_errno */
- dht_selfheal_dir_finish (frame, this, ret);
-
- return 0;
-
-
-}
int
dht_selfheal_restore (call_frame_t *frame, dht_selfheal_dir_cbk_t dir_cbk,
- loc_t *loc, dht_layout_t *layout)
+ loc_t *loc, dht_layout_t *layout)
{
- int ret = 0;
- dht_local_t *local = NULL;
-
- local = frame->local;
+ int ret = 0;
+ dht_local_t *local = NULL;
- local->selfheal.dir_cbk = dir_cbk;
- local->selfheal.layout = dht_layout_ref (frame->this, layout);
- ret = dht_selfheal_dir_mkdir (frame, loc, layout, 1);
+ local = frame->local;
- return ret;
-}
+ local->selfheal.dir_cbk = dir_cbk;
+ local->selfheal.layout = dht_layout_ref (frame->this, layout);
-int
-dht_dir_attr_heal (void *data)
-{
- call_frame_t *frame = NULL;
- dht_local_t *local = NULL;
- xlator_t *subvol = NULL;
- xlator_t *this = NULL;
- dht_conf_t *conf = NULL;
- int call_cnt = 0;
- int ret = -1;
- int i = 0;
- char gfid[GF_UUID_BUF_SIZE] = {0};
-
-
- GF_VALIDATE_OR_GOTO ("dht", data, out);
-
- frame = data;
- local = frame->local;
- this = frame->this;
- GF_VALIDATE_OR_GOTO ("dht", this, out);
- GF_VALIDATE_OR_GOTO ("dht", local, out);
- conf = this->private;
- GF_VALIDATE_OR_GOTO ("dht", conf, out);
-
- call_cnt = conf->subvolume_cnt;
-
- for (i = 0; i < call_cnt; i++) {
- subvol = conf->subvolumes[i];
- if (!subvol || (subvol == dht_first_up_subvol (this)))
- continue;
- ret = syncop_setattr (subvol, &local->loc, &local->stbuf,
- (GF_SET_ATTR_UID | GF_SET_ATTR_GID),
- NULL, NULL);
- if (ret) {
- uuid_unparse(local->loc.gfid, gfid);
-
- gf_msg ("dht", GF_LOG_ERROR, -ret,
- DHT_MSG_DIR_ATTR_HEAL_FAILED,
- "Directory attr heal failed. Failed to set"
- " uid/gid on path %s on subvol %s, gfid = %s ",
- local->loc.path, subvol->name, gfid);
- }
- }
-out:
- return 0;
-}
+ ret = dht_selfheal_dir_mkdir (frame, loc, layout, 1);
-int
-dht_dir_attr_heal_done (int ret, call_frame_t *sync_frame, void *data)
-{
- DHT_STACK_DESTROY (sync_frame);
- return 0;
+ return 0;
}
diff --git a/xlators/cluster/dht/src/dht-shared.c b/xlators/cluster/dht/src/dht-shared.c
deleted file mode 100644
index 22a7260f829..00000000000
--- a/xlators/cluster/dht/src/dht-shared.c
+++ /dev/null
@@ -1,840 +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
-
-/* TODO: add NS locking */
-
-#include "statedump.h"
-#include "dht-common.h"
-#include "dht-messages.h"
-
-
-/* TODO:
- - use volumename in xattr instead of "dht"
- - use NS locks
- - 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)
-{
-
- char key[GF_DUMP_MAX_BUF_LEN];
- int i = 0;
-
- if (!layout)
- goto out;
- if (!prefix)
- goto out;
-
- gf_proc_dump_build_key(key, prefix, "cnt");
- gf_proc_dump_write(key, "%d", layout->cnt);
- gf_proc_dump_build_key(key, prefix, "preset");
- gf_proc_dump_write(key, "%d", layout->preset);
- gf_proc_dump_build_key(key, prefix, "gen");
- gf_proc_dump_write(key, "%d", layout->gen);
- if (layout->type != IA_INVAL) {
- gf_proc_dump_build_key(key, prefix, "inode type");
- gf_proc_dump_write(key, "%d", layout->type);
- }
-
- if (!IA_ISDIR (layout->type))
- goto out;
-
- for (i = 0; i < layout->cnt; i++) {
- gf_proc_dump_build_key(key, prefix,"list[%d].err", i);
- gf_proc_dump_write(key, "%d", layout->list[i].err);
- gf_proc_dump_build_key(key, prefix,"list[%d].start", i);
- gf_proc_dump_write(key, "%u", layout->list[i].start);
- gf_proc_dump_build_key(key, prefix,"list[%d].stop", i);
- gf_proc_dump_write(key, "%u", layout->list[i].stop);
- if (layout->list[i].xlator) {
- gf_proc_dump_build_key(key, prefix,
- "list[%d].xlator.type", i);
- gf_proc_dump_write(key, "%s",
- layout->list[i].xlator->type);
- gf_proc_dump_build_key(key, prefix,
- "list[%d].xlator.name", i);
- gf_proc_dump_write(key, "%s",
- layout->list[i].xlator->name);
- }
- }
-
-out:
- return;
-}
-
-
-int32_t
-dht_priv_dump (xlator_t *this)
-{
- char key_prefix[GF_DUMP_MAX_BUF_LEN];
- char key[GF_DUMP_MAX_BUF_LEN];
- int i = 0;
- dht_conf_t *conf = NULL;
- int ret = -1;
-
- if (!this)
- goto out;
-
- conf = this->private;
- if (!conf)
- goto out;
-
- ret = TRY_LOCK(&conf->subvolume_lock);
- if (ret != 0) {
- return ret;
- }
-
- 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);
- for (i = 0; i < conf->subvolume_cnt; i++) {
- snprintf (key, sizeof (key), "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]){
- snprintf (key, sizeof (key), "file_layouts[%d]", i);
- dht_layout_dump(conf->file_layouts[i], key);
- }
- if (conf->dir_layouts && conf->dir_layouts[i]) {
- snprintf (key, sizeof (key), "dir_layouts[%d]", i);
- dht_layout_dump(conf->dir_layouts[i], key);
- }
- if (conf->subvolume_status) {
-
- snprintf (key, sizeof (key), "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", "%lf", conf->min_free_disk);
- gf_proc_dump_write("min_free_inodes", "%lf", 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);
-
- if (conf->du_stats) {
- for (i = 0; i < conf->subvolume_cnt; i++) {
- if (!conf->subvolume_status[i])
- continue;
-
- snprintf (key, sizeof (key), "subvolumes[%d]", i);
- gf_proc_dump_write (key, "%s",
- conf->subvolumes[i]->name);
-
- snprintf (key, sizeof (key),
- "du_stats[%d].avail_percent", i);
- gf_proc_dump_write (key, "%lf",
- conf->du_stats[i].avail_percent);
-
- snprintf (key, sizeof (key), "du_stats[%d].avail_space",
- i);
- gf_proc_dump_write (key, "%lu",
- conf->du_stats[i].avail_space);
-
- snprintf (key, sizeof (key),
- "du_stats[%d].avail_inodes", i);
- gf_proc_dump_write (key, "%lf",
- conf->du_stats[i].avail_inodes);
-
- snprintf (key, sizeof (key), "du_stats[%d].log", i);
- gf_proc_dump_write (key, "%lu",
- conf->du_stats[i].log);
- }
- }
-
- if (conf->last_stat_fetch.tv_sec)
- gf_proc_dump_write("last_stat_fetch", "%s",
- ctime(&conf->last_stat_fetch.tv_sec));
-
- UNLOCK(&conf->subvolume_lock);
-
-out:
- return ret;
-}
-
-int32_t
-dht_inodectx_dump (xlator_t *this, inode_t *inode)
-{
- int ret = -1;
- dht_layout_t *layout = NULL;
-
- if (!this)
- goto out;
- if (!inode)
- goto out;
-
- ret = dht_inode_ctx_layout_get (inode, this, &layout);
-
- if ((ret != 0) || !layout)
- return ret;
-
- gf_proc_dump_add_section("xlator.cluster.dht.%s.inode", this->name);
- dht_layout_dump(layout, "layout");
-
-out:
- return ret;
-}
-
-void
-dht_fini (xlator_t *this)
-{
- int i = 0;
- dht_conf_t *conf = NULL;
-
- GF_VALIDATE_OR_GOTO ("dht", this, out);
-
- conf = this->private;
- this->private = NULL;
- if (conf) {
- if (conf->file_layouts) {
- for (i = 0; i < conf->subvolume_cnt; i++) {
- GF_FREE (conf->file_layouts[i]);
- }
- GF_FREE (conf->file_layouts);
- }
-
- GF_FREE (conf->subvolumes);
-
- GF_FREE (conf->subvolume_status);
-
- if (conf->lock_pool)
- mem_pool_destroy (conf->lock_pool);
-
- GF_FREE (conf);
- }
-out:
- return;
-}
-
-int32_t
-mem_acct_init (xlator_t *this)
-{
- int ret = -1;
-
- GF_VALIDATE_OR_GOTO ("dht", this, out);
-
- ret = xlator_mem_acct_init (this, gf_dht_mt_end + 1);
-
- if (ret != 0) {
- gf_log (this->name, GF_LOG_ERROR, "Memory accounting init"
- "failed");
- return ret;
- }
-out:
- return ret;
-}
-
-
-int
-dht_parse_decommissioned_bricks (xlator_t *this, dht_conf_t *conf,
- const char *bricks)
-{
- int i = 0;
- int ret = -1;
- char *tmpstr = NULL;
- char *dup_brick = NULL;
- char *node = NULL;
-
- if (!conf || !bricks)
- 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];
- conf->decommission_subvols_cnt++;
- 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);
- }
-
- ret = 0;
- conf->decommission_in_progress = 1;
-out:
- GF_FREE (dup_brick);
-
- return ret;
-}
-
-
-int
-dht_decommissioned_remove (xlator_t *this, dht_conf_t *conf)
-{
- int i = 0;
- int ret = -1;
-
- if (!conf)
- goto out;
-
- for (i = 0; i < conf->subvolume_cnt; i++) {
- if (conf->decommissioned_bricks[i]) {
- conf->decommissioned_bricks[i] = NULL;
- conf->decommission_subvols_cnt--;
- }
- }
-
- ret = 0;
-out:
-
- return ret;
-}
-void
-dht_init_regex (xlator_t *this, dict_t *odict, char *name,
- regex_t *re, gf_boolean_t *re_valid)
-{
- char *temp_str;
-
- if (dict_get_str (odict, name, &temp_str) != 0) {
- if (strcmp(name,"rsync-hash-regex")) {
- return;
- }
- temp_str = "^\\.(.+)\\.[^.]+$";
- }
-
- if (*re_valid) {
- regfree(re);
- *re_valid = _gf_false;
- }
-
- if (!strcmp(temp_str,"none")) {
- return;
- }
-
- if (regcomp(re,temp_str,REG_EXTENDED) == 0) {
- gf_log (this->name, GF_LOG_INFO,
- "using regex %s = %s", name, temp_str);
- *re_valid = _gf_true;
- }
- else {
- gf_log (this->name, GF_LOG_WARNING,
- "compiling regex %s failed", temp_str);
- }
-}
-
-int
-dht_reconfigure (xlator_t *this, dict_t *options)
-{
- dht_conf_t *conf = NULL;
- char *temp_str = NULL;
- gf_boolean_t search_unhashed;
- int ret = -1;
-
- GF_VALIDATE_OR_GOTO ("dht", this, out);
- GF_VALIDATE_OR_GOTO ("dht", options, out);
-
- conf = this->private;
- if (!conf)
- return 0;
-
- if (dict_get_str (options, "lookup-unhashed", &temp_str) == 0) {
- /* If option is not "auto", other options _should_ be boolean*/
- if (strcasecmp (temp_str, "auto")) {
- if (!gf_string2boolean (temp_str, &search_unhashed)) {
- gf_msg_debug(this->name, 0, "Reconfigure: "
- "lookup-unhashed reconfigured(%s)",
- temp_str);
- conf->search_unhashed = search_unhashed;
- } else {
- gf_msg(this->name, GF_LOG_ERROR, 0,
- DHT_MSG_INVALID_OPTION,
- "Invalid option: Reconfigure: "
- "lookup-unhashed should be boolean,"
- " not (%s), defaulting to (%d)",
- temp_str, conf->search_unhashed);
- ret = -1;
- goto out;
- }
- } else {
- gf_msg_debug(this->name, 0, "Reconfigure:"
- " lookup-unhashed 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);
- /* option can be any one of percent or bytes */
- conf->disk_unit = 0;
- if (conf->min_free_disk < 100.0)
- conf->disk_unit = 'p';
-
- 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);
-
- GF_OPTION_RECONF ("readdir-optimize", conf->readdir_optimize, options,
- bool, out);
- GF_OPTION_RECONF ("randomize-hash-range-by-gfid",
- conf->randomize_by_gfid,
- options, bool, out);
-
- if (conf->defrag) {
- GF_OPTION_RECONF ("rebalance-stats", conf->defrag->stats,
- options, bool, out);
- }
-
- if (dict_get_str (options, "decommissioned-bricks", &temp_str) == 0) {
- ret = dht_parse_decommissioned_bricks (this, conf, temp_str);
- if (ret == -1)
- goto out;
- } else {
- ret = dht_decommissioned_remove (this, conf);
- if (ret == -1)
- goto out;
- }
-
- dht_init_regex (this, options, "rsync-hash-regex",
- &conf->rsync_regex, &conf->rsync_regex_valid);
- dht_init_regex (this, options, "extra-hash-regex",
- &conf->extra_regex, &conf->extra_regex_valid);
-
- GF_OPTION_RECONF ("weighted-rebalance", conf->do_weighting, options,
- bool, out);
-
- ret = 0;
-out:
- return ret;
-}
-
-static int
-gf_defrag_pattern_list_fill (xlator_t *this, gf_defrag_info_t *defrag, char *data)
-{
- int ret = -1;
- char *tmp_str = NULL;
- char *tmp_str1 = NULL;
- char *dup_str = NULL;
- char *num = NULL;
- char *pattern_str = NULL;
- char *pattern = NULL;
- gf_defrag_pattern_list_t *temp_list = NULL;
- gf_defrag_pattern_list_t *pattern_list = NULL;
-
- if (!this || !defrag || !data)
- goto out;
-
- /* Get the pattern for pattern list. "pattern:<optional-size>"
- * eg: *avi, *pdf:10MB, *:1TB
- */
- pattern_str = strtok_r (data, ",", &tmp_str);
- while (pattern_str) {
- dup_str = gf_strdup (pattern_str);
- pattern_list = GF_CALLOC (1, sizeof (gf_defrag_pattern_list_t),
- 1);
- if (!pattern_list) {
- goto out;
- }
- pattern = strtok_r (dup_str, ":", &tmp_str1);
- num = strtok_r (NULL, ":", &tmp_str1);
- if (!pattern)
- goto out;
- if (!num) {
- if (gf_string2bytesize_uint64(pattern, &pattern_list->size)
- == 0) {
- pattern = "*";
- }
- } else if (gf_string2bytesize_uint64 (num, &pattern_list->size) != 0) {
- gf_msg (this->name, GF_LOG_ERROR, 0,
- DHT_MSG_INVALID_OPTION,
- "Invalid option. Defrag pattern:"
- " Invalid number format \"%s\"", num);
- goto out;
- }
- memcpy (pattern_list->path_pattern, pattern, strlen (dup_str));
-
- if (!defrag->defrag_pattern)
- temp_list = NULL;
- else
- temp_list = defrag->defrag_pattern;
-
- pattern_list->next = temp_list;
-
- defrag->defrag_pattern = pattern_list;
- pattern_list = NULL;
-
- GF_FREE (dup_str);
- dup_str = NULL;
-
- pattern_str = strtok_r (NULL, ",", &tmp_str);
- }
-
- ret = 0;
-out:
- if (ret)
- GF_FREE (pattern_list);
- GF_FREE (dup_str);
-
- return ret;
-}
-
-int
-dht_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;
-
-
- GF_VALIDATE_OR_GOTO ("dht", this, err);
-
- if (!this->children) {
- gf_msg (this->name, GF_LOG_CRITICAL, 0,
- DHT_MSG_INVALID_CONFIGURATION,
- "Distribute needs more than one subvolume");
- return -1;
- }
-
- if (!this->parents) {
- gf_msg (this->name, GF_LOG_WARNING, 0,
- DHT_MSG_INVALID_CONFIGURATION,
- "dangling volume. check volfile");
- }
-
- conf = GF_CALLOC (1, sizeof (*conf), gf_dht_mt_dht_conf_t);
- if (!conf) {
- 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_msg (this->name, GF_LOG_ERROR, 0,
- DHT_MSG_INVALID_CONFIGURATION,
- "Invalid volume configuration: "
- "node-uuid not specified");
- goto err;
- }
-
- if (uuid_parse (node_uuid, defrag->node_uuid)) {
- gf_msg (this->name, GF_LOG_ERROR, 0,
- DHT_MSG_INVALID_OPTION, "Invalid option:"
- " 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 */
- if (strcasecmp (temp_str, "auto"))
- gf_string2boolean (temp_str, &conf->search_unhashed);
- else
- conf->search_unhashed = GF_DHT_LOOKUP_UNHASHED_AUTO;
- }
-
- GF_OPTION_INIT ("unhashed-sticky-bit", conf->unhashed_sticky_bit, bool,
- err);
-
- GF_OPTION_INIT ("use-readdirp", conf->use_readdirp, bool, err);
-
- GF_OPTION_INIT ("min-free-disk", conf->min_free_disk, percent_or_size,
- err);
-
- GF_OPTION_INIT ("min-free-inodes", conf->min_free_inodes, percent,
- err);
-
- conf->dir_spread_cnt = conf->subvolume_cnt;
- GF_OPTION_INIT ("directory-layout-spread", conf->dir_spread_cnt,
- uint32, err);
-
- GF_OPTION_INIT ("assert-no-child-down", conf->assert_no_child_down,
- bool, err);
-
- GF_OPTION_INIT ("readdir-optimize", conf->readdir_optimize, bool, err);
-
- if (defrag) {
- GF_OPTION_INIT ("rebalance-stats", defrag->stats, bool, err);
- if (dict_get_str (this->options, "rebalance-filter", &temp_str)
- == 0) {
- if (gf_defrag_pattern_list_fill (this, defrag, temp_str)
- == -1) {
- gf_msg (this->name, GF_LOG_ERROR, 0,
- DHT_MSG_INVALID_OPTION,
- "Invalid option:"
- " Cannot parse rebalance-filter (%s)",
- temp_str);
-
- goto err;
- }
- }
- }
-
- /* option can be any one of percent or bytes */
- conf->disk_unit = 0;
- if (conf->min_free_disk < 100)
- conf->disk_unit = 'p';
-
- ret = dht_init_subvolumes (this, conf);
- if (ret == -1) {
- 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;
- }
-
- dht_init_regex (this, this->options, "rsync-hash-regex",
- &conf->rsync_regex, &conf->rsync_regex_valid);
- dht_init_regex (this, this->options, "extra-hash-regex",
- &conf->extra_regex, &conf->extra_regex_valid);
-
- ret = dht_layouts_init (this, conf);
- if (ret == -1) {
- 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_msg (this->name, GF_LOG_ERROR, 0,
- DHT_MSG_INIT_FAILED,
- " DHT initialisation failed. "
- "failed to create local_t's memory pool");
- goto err;
- }
-
- GF_OPTION_INIT ("randomize-hash-range-by-gfid",
- conf->randomize_by_gfid, bool, err);
-
- GF_OPTION_INIT ("xattr-name", conf->xattr_name, str, err);
- gf_asprintf (&conf->link_xattr_name, "%s."DHT_LINKFILE_STR,
- conf->xattr_name);
- gf_asprintf (&conf->wild_xattr_name, "%s*", conf->xattr_name);
- if (!conf->link_xattr_name || !conf->wild_xattr_name) {
- goto err;
- }
-
- GF_OPTION_INIT ("weighted-rebalance", conf->do_weighting, bool, err);
-
- conf->lock_pool = mem_pool_new (dht_lock_t, 512);
- if (!conf->lock_pool) {
- gf_msg (this->name, GF_LOG_ERROR, 0, DHT_MSG_INIT_FAILED,
- "failed to create lock mem_pool, failing "
- "initialization");
- goto err;
- }
-
- this->private = conf;
-
- return 0;
-
-err:
- if (conf) {
- if (conf->file_layouts) {
- for (i = 0; i < conf->subvolume_cnt; i++) {
- GF_FREE (conf->file_layouts[i]);
- }
- GF_FREE (conf->file_layouts);
- }
-
- GF_FREE (conf->subvolumes);
-
- GF_FREE (conf->subvolume_status);
-
- GF_FREE (conf->du_stats);
-
- GF_FREE (conf->defrag);
-
- GF_FREE (conf->xattr_name);
- GF_FREE (conf->link_xattr_name);
- GF_FREE (conf->wild_xattr_name);
-
- if (conf->lock_pool)
- mem_pool_destroy (conf->lock_pool);
-
- GF_FREE (conf);
- }
-
- return -1;
-}
-
-
-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",
- .description = "This option if set to ON, does a lookup through "
- "all the sub-volumes, in case a lookup didn't return any result "
- "from the hash subvolume. If set to OFF, it does not do a lookup "
- "on the remaining subvolumes."
- },
- { .key = {"min-free-disk"},
- .type = GF_OPTION_TYPE_PERCENT_OR_SIZET,
- .default_value = "10%",
- .description = "Percentage/Size of disk space, after which the "
- "process starts balancing out the cluster, and logs will appear "
- "in log files",
- },
- { .key = {"min-free-inodes"},
- .type = GF_OPTION_TYPE_PERCENT,
- .default_value = "5%",
- .description = "after system has only N% of inodes, warnings "
- "starts to appear in log files",
- },
- { .key = {"unhashed-sticky-bit"},
- .type = GF_OPTION_TYPE_BOOL,
- .default_value = "off",
- },
- { .key = {"use-readdirp"},
- .type = GF_OPTION_TYPE_BOOL,
- .default_value = "on",
- .description = "This option if set to ON, forces the use of "
- "readdirp, and hence also displays the stats of the files."
- },
- { .key = {"assert-no-child-down"},
- .type = GF_OPTION_TYPE_BOOL,
- .default_value = "off",
- .description = "This option if set to ON, in the event of "
- "CHILD_DOWN, will call exit."
- },
- { .key = {"directory-layout-spread"},
- .type = GF_OPTION_TYPE_INT,
- .min = 1,
- .validate = GF_OPT_VALIDATE_MIN,
- .description = "Specifies the directory layout spread. Takes number "
- "of subvolumes as default value."
- },
- { .key = {"decommissioned-bricks"},
- .type = GF_OPTION_TYPE_ANY,
- .description = "This option if set to ON, decommissions "
- "the brick, so that no new data is allowed to be created "
- "on that brick."
- },
- { .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",
- .description = "This option if set to ON displays and logs the "
- " time taken for migration of each file, during the rebalance "
- "process. If set to OFF, the rebalance logs will only display the "
- "time spent in each directory."
- },
- { .key = {"readdir-optimize"},
- .type = GF_OPTION_TYPE_BOOL,
- .default_value = "off",
- .description = "This option if set to ON enables the optimization "
- "that allows DHT to requests non-first subvolumes to filter out "
- "directory entries."
- },
- { .key = {"rsync-hash-regex"},
- .type = GF_OPTION_TYPE_STR,
- /* Setting a default here doesn't work. See dht_init_regex. */
- .description = "Regular expression for stripping temporary-file "
- "suffix and prefix used by rsync, to prevent relocation when the "
- "file is renamed."
- },
- { .key = {"extra-hash-regex"},
- .type = GF_OPTION_TYPE_STR,
- /* Setting a default here doesn't work. See dht_init_regex. */
- .description = "Regular expression for stripping temporary-file "
- "suffix and prefix used by an application, to prevent relocation when "
- "the file is renamed."
- },
- { .key = {"rebalance-filter"},
- .type = GF_OPTION_TYPE_STR,
- },
-
- { .key = {"xattr-name"},
- .type = GF_OPTION_TYPE_STR,
- .default_value = "trusted.glusterfs.dht",
- .description = "Base for extended attributes used by this "
- "translator instance, to avoid conflicts with others above or "
- "below it."
- },
-
- { .key = {"weighted-rebalance"},
- .type = GF_OPTION_TYPE_BOOL,
- .default_value = "on",
- .description = "When enabled, files will be allocated to bricks "
- "with a probability proportional to their size. Otherwise, all "
- "bricks will have the same probability (legacy behavior)."
- },
-
- /* NUFA option */
- { .key = {"local-volume-name"},
- .type = GF_OPTION_TYPE_XLATOR
- },
-
- /* switch option */
- { .key = {"pattern.switch.case"},
- .type = GF_OPTION_TYPE_ANY
- },
-
- { .key = {"randomize-hash-range-by-gfid"},
- .type = GF_OPTION_TYPE_BOOL,
- .default_value = "off",
- .description = "Use gfid of directory to determine the subvolume "
- "from which hash ranges are allocated starting with 0. "
- "Note that we still use a directory/file's name to determine the "
- "subvolume to which it hashes"
- },
-
- { .key = {NULL} },
-};
diff --git a/xlators/cluster/dht/src/dht.c b/xlators/cluster/dht/src/dht.c
index fc0ca2f7735..72207b9645f 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>
- This file is part of GlusterFS.
+ Copyright (c) 2008-2009 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 General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that 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/>.
*/
@@ -14,65 +23,384 @@
#include "config.h"
#endif
+/* TODO: add NS locking */
+
#include "statedump.h"
-#include "dht-common.h"
+#include "dht-common.c"
+
+/* TODO:
+ - use volumename in xattr instead of "dht"
+ - use NS locks
+ - handle all cases in self heal layout reconstruction
+ - complete linkfile selfheal
+*/
+
+
+void
+dht_layout_dump (dht_layout_t *layout, const char *prefix)
+{
+
+ char key[GF_DUMP_MAX_BUF_LEN];
+ int i = 0;
+
+ if (!layout)
+ return;
+
+ gf_proc_dump_build_key(key, prefix, "cnt");
+ gf_proc_dump_write(key, "%d", layout->cnt);
+ gf_proc_dump_build_key(key, prefix, "preset");
+ gf_proc_dump_write(key, "%d", layout->preset);
+ gf_proc_dump_build_key(key, prefix, "gen");
+ gf_proc_dump_write(key, "%d", layout->gen);
+ gf_proc_dump_build_key(key, prefix, "type");
+ gf_proc_dump_write(key, "%d", layout->type);
+
+ for (i = 0; i < layout->cnt; i++) {
+ gf_proc_dump_build_key(key, prefix,"list[%d].err", i);
+ gf_proc_dump_write(key, "%d", layout->list[i].err);
+ gf_proc_dump_build_key(key, prefix,"list[%d].start", i);
+ gf_proc_dump_write(key, "%u", layout->list[i].start);
+ gf_proc_dump_build_key(key, prefix,"list[%d].stop", i);
+ gf_proc_dump_write(key, "%u", layout->list[i].stop);
+ if (layout->list[i].xlator) {
+ gf_proc_dump_build_key(key, prefix,
+ "list[%d].xlator.type", i);
+ gf_proc_dump_write(key, "%s",
+ layout->list[i].xlator->type);
+ gf_proc_dump_build_key(key, prefix,
+ "list[%d].xlator.name", i);
+ gf_proc_dump_write(key, "%s",
+ layout->list[i].xlator->name);
+ }
+ }
+}
+
+
+int32_t
+dht_priv_dump (xlator_t *this)
+{
+ char key_prefix[GF_DUMP_MAX_BUF_LEN];
+ char key[GF_DUMP_MAX_BUF_LEN];
+ int i = 0;
+ dht_conf_t *conf = NULL;
+ int ret = 0;
+
+ if (!this)
+ return -1;
+
+ conf = this->private;
+
+ if (!conf)
+ return -1;
+
+ ret = TRY_LOCK(&conf->subvolume_lock);
+
+ if (ret != 0) {
+ gf_log("", GF_LOG_WARNING, "Unable to lock dht subvolume %s",
+ this->name);
+ return ret;
+ }
+
+ 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_build_key(key, key_prefix, "subvolume_cnt");
+ gf_proc_dump_write(key,"%d", conf->subvolume_cnt);
+ for (i = 0; i < conf->subvolume_cnt; 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]){
+ 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]) {
+ gf_proc_dump_build_key(key, key_prefix,
+ "dir_layouts[%d]",i);
+ dht_layout_dump(conf->dir_layouts[i], key);
+ }
+ if (conf->subvolume_status) {
+ 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_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_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);
+ }
+ 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);
+
+ return 0;
+}
+
+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;
+
+ if (!inode)
+ return -1;
+
+ ret = inode_ctx_get (inode, this, &tmp_layout);
+
+ if (ret != 0)
+ return ret;
+
+ layout = (dht_layout_t *)(long)tmp_layout;
+
+ if (!layout)
+ return -1;
+
+ gf_proc_dump_build_key(key_prefix, "xlator.cluster.dht",
+ "%s.inode.%ld", this->name, inode->ino);
+ dht_layout_dump(layout, key_prefix);
+
+ return 0;
+}
+
+int
+notify (xlator_t *this, int event, void *data, ...)
+{
+ int ret = -1;
+
+ ret = dht_notify (this, event, data);
+
+ return ret;
+}
+
+void
+fini (xlator_t *this)
+{
+ int i = 0;
+ dht_conf_t *conf = NULL;
+
+ conf = this->private;
+
+ if (conf) {
+ if (conf->file_layouts) {
+ for (i = 0; i < conf->subvolume_cnt; i++) {
+ FREE (conf->file_layouts[i]);
+ }
+ FREE (conf->file_layouts);
+ }
+
+ if (conf->default_dir_layout)
+ FREE (conf->default_dir_layout);
+
+ if (conf->subvolumes)
+ FREE (conf->subvolumes);
+
+ if (conf->subvolume_status)
+ FREE (conf->subvolume_status);
+
+ FREE (conf);
+ }
+
+ return;
+}
+
+int
+init (xlator_t *this)
+{
+ dht_conf_t *conf = NULL;
+ char *temp_str = NULL;
+ int ret = -1;
+ int i = 0;
+ uint32_t temp_free_disk = 0;
+
+ if (!this->children) {
+ gf_log (this->name, GF_LOG_CRITICAL,
+ "Distribute needs more than one subvolume");
+ return -1;
+ }
+
+ if (!this->parents) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "dangling volume. check volfile");
+ }
+
+ conf = CALLOC (1, sizeof (*conf));
+ if (!conf) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory");
+ goto err;
+ }
+
+ conf->search_unhashed = GF_DHT_LOOKUP_UNHASHED_AUTO;
+ if (dict_get_str (this->options, "lookup-unhashed", &temp_str) == 0) {
+ /* If option is not "auto", other options _should_ be boolean */
+ if (strcasecmp (temp_str, "auto"))
+ gf_string2boolean (temp_str, &conf->search_unhashed);
+ }
+
+ conf->unhashed_sticky_bit = 0;
+
+ if (dict_get_str (this->options, "unhashed-sticky-bit",
+ &temp_str) == 0) {
+ gf_string2boolean (temp_str, &conf->unhashed_sticky_bit);
+ }
+
+ conf->use_readdirp = 0;
+
+ if (dict_get_str (this->options, "use-readdirp",
+ &temp_str) == 0) {
+ gf_string2boolean (temp_str, &conf->use_readdirp);
+ }
+
+ conf->disk_unit = 'p';
+ conf->min_free_disk = 10;
+
+ 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';
+ }
+ }
+
+
+ ret = dht_init_subvolumes (this, conf);
+ if (ret == -1) {
+ goto err;
+ }
+
+ ret = dht_layouts_init (this, conf);
+ if (ret == -1) {
+ goto err;
+ }
+
+ conf->du_stats = CALLOC (conf->subvolume_cnt, sizeof (dht_du_t));
+ if (!conf->du_stats) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory");
+ goto err;
+ }
+
+ LOCK_INIT (&conf->subvolume_lock);
+ LOCK_INIT (&conf->layout_lock);
+
+ conf->gen = 1;
+
+ this->private = conf;
+
+ return 0;
+
+err:
+ if (conf) {
+ if (conf->file_layouts) {
+ for (i = 0; i < conf->subvolume_cnt; i++) {
+ FREE (conf->file_layouts[i]);
+ }
+ FREE (conf->file_layouts);
+ }
+
+ if (conf->default_dir_layout)
+ FREE (conf->default_dir_layout);
+
+ if (conf->subvolumes)
+ FREE (conf->subvolumes);
+
+ if (conf->subvolume_status)
+ FREE (conf->subvolume_status);
+
+ if (conf->du_stats)
+ FREE (conf->du_stats);
+
+ FREE (conf);
+ }
+
+ return -1;
+}
-class_methods_t class_methods = {
- .init = dht_init,
- .fini = dht_fini,
- .reconfigure = dht_reconfigure,
- .notify = dht_notify
-};
struct xlator_fops fops = {
- .lookup = dht_lookup,
- .mknod = dht_mknod,
- .create = dht_create,
-
- .open = dht_open,
- .statfs = dht_statfs,
- .opendir = dht_opendir,
- .readdir = dht_readdir,
- .readdirp = dht_readdirp,
- .fsyncdir = dht_fsyncdir,
- .symlink = dht_symlink,
- .unlink = dht_unlink,
- .link = dht_link,
- .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,
- .xattrop = dht_xattrop,
- .fxattrop = dht_fxattrop,
- .setattr = dht_setattr,
+ .lookup = dht_lookup,
+ .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,
+ .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,
+ .fsyncdir = dht_fsyncdir,
+ .symlink = dht_symlink,
+ .unlink = dht_unlink,
+ .link = dht_link,
+ .mkdir = dht_mkdir,
+ .rmdir = dht_rmdir,
+ .rename = dht_rename,
+ .inodelk = dht_inodelk,
+ .finodelk = dht_finodelk,
+ .entrylk = dht_entrylk,
+ .fentrylk = dht_fentrylk,
+ .xattrop = dht_xattrop,
+ .fxattrop = dht_fxattrop,
+ .setattr = dht_setattr,
.fsetattr = dht_fsetattr,
- .fallocate = dht_fallocate,
- .discard = dht_discard,
- .zerofill = dht_zerofill,
+#if 0
+ .setdents = dht_setdents,
+ .getdents = dht_getdents,
+ .checksum = dht_checksum,
+#endif
+};
+
+
+struct xlator_mops mops = {
};
struct xlator_dumpops dumpops = {
@@ -82,8 +410,26 @@ struct xlator_dumpops dumpops = {
struct xlator_cbks cbks = {
-// .release = dht_release,
+// .release = dht_release,
// .releasedir = dht_releasedir,
- .forget = dht_forget
+ .forget = dht_forget
+};
+
+
+struct volume_options options[] = {
+ { .key = {"lookup-unhashed"},
+ .value = {"auto", "yes", "no", "enable", "disable", "1", "0",
+ "on", "off"},
+ .type = GF_OPTION_TYPE_STR
+ },
+ { .key = {"min-free-disk"},
+ .type = GF_OPTION_TYPE_PERCENT_OR_SIZET,
+ },
+ { .key = {"unhashed-sticky-bit"},
+ .type = GF_OPTION_TYPE_BOOL
+ },
+ { .key = {"use-readdirp"},
+ .type = GF_OPTION_TYPE_BOOL
+ },
+ { .key = {NULL} },
};
-;
diff --git a/xlators/cluster/dht/src/nufa.c b/xlators/cluster/dht/src/nufa.c
index f188a5479f4..96cc5fe3e2e 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>
- 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-2009 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/>.
*/
@@ -14,17 +23,15 @@
#include "config.h"
#endif
-#include "dht-common.h"
+#include "dht-common.c"
/* TODO: all 'TODO's in dht.c holds good */
-extern struct volume_options options[];
-
int
nufa_local_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 op_ret, int op_errno,
+ inode_t *inode, struct stat *stbuf, dict_t *xattr,
+ struct stat *postparent)
{
xlator_t *subvol = NULL;
char is_linkfile = 0;
@@ -34,61 +41,67 @@ nufa_local_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
loc_t *loc = NULL;
int i = 0;
call_frame_t *prev = NULL;
- int call_cnt = 0;
+ int call_cnt = 0;
int ret = 0;
+
conf = this->private;
prev = cookie;
local = frame->local;
loc = &local->loc;
- if (ENTRY_MISSING (op_ret, op_errno)) {
- if (conf->search_unhashed) {
- local->op_errno = ENOENT;
- dht_lookup_everywhere (frame, this, loc);
- return 0;
- }
- }
+ if (ENTRY_MISSING (op_ret, op_errno)) {
+ if (conf->search_unhashed) {
+ local->op_errno = ENOENT;
+ dht_lookup_everywhere (frame, this, loc);
+ return 0;
+ }
+ }
if (op_ret == -1)
goto out;
- is_linkfile = check_is_linkfile (inode, stbuf, xattr,
- conf->link_xattr_name);
+ is_linkfile = check_is_linkfile (inode, stbuf, xattr);
is_dir = check_is_dir (inode, stbuf, xattr);
if (!is_dir && !is_linkfile) {
/* non-directory and not a linkfile */
- ret = dht_layout_preset (this, prev->this, inode);
- if (ret < 0) {
- gf_msg_debug (this->name, 0,
- "could not set pre-set layout for subvol"
- " %s", prev->this->name);
- op_ret = -1;
- op_errno = EINVAL;
- goto err;
- }
+
+ dht_itransform (this, prev->this, stbuf->st_ino,
+ &stbuf->st_ino);
+
+ ret = dht_layout_preset (this, prev->this, inode);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "could not set pre-set layout for subvol %s",
+ prev->this->name);
+ op_ret = -1;
+ op_errno = EINVAL;
+ goto err;
+ }
goto out;
}
if (is_dir) {
call_cnt = conf->subvolume_cnt;
- local->call_cnt = call_cnt;
+ local->call_cnt = call_cnt;
local->inode = inode_ref (inode);
local->xattr = dict_ref (xattr);
- local->op_ret = 0;
- local->op_errno = 0;
+ local->op_ret = 0;
+ local->op_errno = 0;
- local->layout = dht_layout_new (this, conf->subvolume_cnt);
- if (!local->layout) {
- op_ret = -1;
- op_errno = ENOMEM;
- goto err;
- }
+ local->layout = dht_layout_new (this, conf->subvolume_cnt);
+ if (!local->layout) {
+ op_ret = -1;
+ op_errno = ENOMEM;
+ gf_log (this->name, GF_LOG_DEBUG,
+ "memory allocation failed :(");
+ goto err;
+ }
for (i = 0; i < call_cnt; i++) {
STACK_WIND (frame, dht_lookup_dir_cbk,
@@ -102,55 +115,55 @@ nufa_local_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
subvol = dht_linkfile_subvol (this, inode, stbuf, xattr);
if (!subvol) {
- gf_msg_debug (this->name, 0,
- "linkfile has no link subvolume. path=%s",
- loc->path);
- dht_lookup_everywhere (frame, this, loc);
- return 0;
+ gf_log (this->name, GF_LOG_DEBUG,
+ "linkfile not having link subvolume. path=%s",
+ loc->path);
+ dht_lookup_everywhere (frame, this, loc);
+ return 0;
}
- STACK_WIND (frame, dht_lookup_linkfile_cbk,
- subvol, subvol->fops->lookup,
- &local->loc, local->xattr_req);
+ STACK_WIND (frame, dht_lookup_linkfile_cbk,
+ subvol, subvol->fops->lookup,
+ &local->loc, local->xattr_req);
}
return 0;
out:
- if (!local->hashed_subvol) {
- gf_msg_debug (this->name, 0,
- "no subvolume in layout for path=%s",
- local->loc.path);
- local->op_errno = ENOENT;
- dht_lookup_everywhere (frame, this, loc);
- return 0;
- }
+ if (!local->hashed_subvol) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "no subvolume in layout for path=%s",
+ local->loc.path);
+ op_errno = EINVAL;
+ goto err;
+ }
- STACK_WIND (frame, dht_lookup_cbk,
- local->hashed_subvol, local->hashed_subvol->fops->lookup,
- &local->loc, local->xattr_req);
+ STACK_WIND (frame, dht_lookup_cbk,
+ local->hashed_subvol, local->hashed_subvol->fops->lookup,
+ &local->loc, local->xattr_req);
- return 0;
+ return 0;
-err:
+ err:
DHT_STACK_UNWIND (lookup, frame, op_ret, op_errno,
- inode, stbuf, xattr, postparent);
+ inode, stbuf, xattr, NULL);
return 0;
}
int
nufa_lookup (call_frame_t *frame, xlator_t *this,
- loc_t *loc, dict_t *xattr_req)
+ 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;
+ dht_conf_t *conf = NULL;
int ret = -1;
int op_errno = -1;
- dht_layout_t *layout = NULL;
- int i = 0;
- int call_cnt = 0;
+ dht_layout_t *layout = NULL;
+ int i = 0;
+ int call_cnt = 0;
VALIDATE_OR_GOTO (frame, err);
@@ -159,518 +172,577 @@ nufa_lookup (call_frame_t *frame, xlator_t *this,
VALIDATE_OR_GOTO (loc->inode, err);
VALIDATE_OR_GOTO (loc->path, err);
- conf = this->private;
-
- local = dht_local_init (frame, loc, NULL, GF_FOP_LOOKUP);
- if (!local) {
- op_errno = ENOMEM;
+ conf = this->private;
+
+ local = dht_local_init (frame);
+ if (!local) {
+ op_errno = ENOMEM;
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory");
+ 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 {
- local->xattr_req = dict_new ();
- }
+ if (xattr_req) {
+ local->xattr_req = dict_ref (xattr_req);
+ } else {
+ local->xattr_req = dict_new ();
+ }
- hashed_subvol = dht_subvol_get_hashed (this, &local->loc);
+ hashed_subvol = dht_subvol_get_hashed (this, &local->loc);
+ cached_subvol = dht_subvol_get_cached (this, local->loc.inode);
- local->hashed_subvol = hashed_subvol;
+ 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_msg_debug (this->name, 0,
- "revalidate lookup without cache. "
- "path=%s", loc->path);
+ gf_log (this->name, GF_LOG_DEBUG,
+ "revalidate without cache. path=%s",
+ loc->path);
op_errno = EINVAL;
goto err;
}
- if (layout->gen && (layout->gen < conf->gen)) {
- gf_msg_debug (this->name, 0,
- "incomplete layout failure for path=%s",
- loc->path);
+ if (layout->gen && (layout->gen < conf->gen)) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "incomplete layout failure for path=%s",
+ loc->path);
dht_layout_unref (this, local->layout);
- goto do_fresh_lookup;
- }
+ goto do_fresh_lookup;
+ }
- local->inode = inode_ref (loc->inode);
+ local->inode = inode_ref (loc->inode);
+ local->st_ino = loc->inode->ino;
- local->call_cnt = layout->cnt;
- call_cnt = local->call_cnt;
+ 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.
- */
- ret = dict_set_uint32 (local->xattr_req,
- conf->xattr_name, 4 * 4);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to set dict value.");
- op_errno = -1;
- goto err;
- }
+ /* NOTE: we don't require 'trusted.glusterfs.dht.linkto' attribute,
+ * revalidates directly go to the cached-subvolume.
+ */
+ ret = dict_set_uint32 (local->xattr_req,
+ "trusted.glusterfs.dht", 4 * 4);
- for (i = 0; i < layout->cnt; i++) {
- subvol = layout->list[i].xlator;
+ for (i = 0; i < layout->cnt; i++) {
+ subvol = layout->list[i].xlator;
- STACK_WIND (frame, dht_revalidate_cbk,
- subvol, subvol->fops->lookup,
- loc, local->xattr_req);
+ STACK_WIND (frame, dht_revalidate_cbk,
+ subvol, subvol->fops->lookup,
+ loc, local->xattr_req);
- if (!--call_cnt)
- break;
- }
- } else {
+ if (!--call_cnt)
+ break;
+ }
+ } else {
do_fresh_lookup:
- ret = dict_set_uint32 (local->xattr_req,
- conf->xattr_name, 4 * 4);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to set dict value.");
- op_errno = -1;
- goto err;
- }
+ ret = dict_set_uint32 (local->xattr_req,
+ "trusted.glusterfs.dht", 4 * 4);
- ret = dict_set_uint32 (local->xattr_req,
- conf->link_xattr_name, 256);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to set dict value.");
- op_errno = -1;
- goto err;
- }
+ ret = dict_set_uint32 (local->xattr_req,
+ "trusted.glusterfs.dht.linkto", 256);
- /* Send it to only local volume */
- STACK_WIND (frame, nufa_local_lookup_cbk,
- (xlator_t *)conf->private,
- ((xlator_t *)conf->private)->fops->lookup,
- loc, local->xattr_req);
- }
+ /* Send it to only local volume */
+ STACK_WIND (frame, nufa_local_lookup_cbk,
+ (xlator_t *)conf->private,
+ ((xlator_t *)conf->private)->fops->lookup,
+ loc, local->xattr_req);
+ }
return 0;
err:
- op_errno = (op_errno == -1) ? errno : op_errno;
- DHT_STACK_UNWIND (lookup, frame, -1, op_errno, NULL, NULL, NULL,
- NULL);
- return 0;
+ op_errno = (op_errno == -1) ? errno : op_errno;
+ DHT_STACK_UNWIND (lookup, frame, -1, op_errno, NULL, NULL, NULL, NULL);
+ return 0;
}
int
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)
+ xlator_t *this, int op_ret, int op_errno,
+ inode_t *inode, struct stat *stbuf,
+ struct stat *preparent,
+ struct stat *postparent)
{
- dht_local_t *local = NULL;
+ dht_local_t *local = NULL;
+ call_frame_t *prev = NULL;
+ dht_conf_t *conf = NULL;
- local = frame->local;
+ local = frame->local;
+ prev = cookie;
+ conf = this->private;
- if (op_ret == -1)
- goto err;
+ if (op_ret == -1)
+ goto err;
- 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);
+ STACK_WIND (frame, dht_create_cbk,
+ local->cached_subvol, local->cached_subvol->fops->create,
+ &local->loc, local->flags, local->mode, local->fd);
- return 0;
+ return 0;
-err:
- DHT_STACK_UNWIND (create, frame, -1, op_errno,
- NULL, NULL, NULL, NULL, NULL, NULL);
- return 0;
+ err:
+ DHT_STACK_UNWIND (create, frame, -1, op_errno,
+ 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)
+ loc_t *loc, int32_t flags, mode_t mode, fd_t *fd)
{
- dht_local_t *local = NULL;
- dht_conf_t *conf = NULL;
- xlator_t *subvol = NULL;
+ dht_local_t *local = NULL;
+ dht_conf_t *conf = NULL;
+ xlator_t *subvol = NULL;
xlator_t *avail_subvol = NULL;
- int op_errno = -1;
+ int op_errno = -1;
+ int ret = -1;
- VALIDATE_OR_GOTO (frame, err);
- VALIDATE_OR_GOTO (this, err);
- VALIDATE_OR_GOTO (loc, err);
+ VALIDATE_OR_GOTO (frame, err);
+ VALIDATE_OR_GOTO (this, err);
+ VALIDATE_OR_GOTO (loc, err);
- conf = this->private;
+ conf = this->private;
dht_get_du_info (frame, this, loc);
- local = dht_local_init (frame, loc, fd, GF_FOP_CREATE);
- if (!local) {
- op_errno = ENOMEM;
- goto err;
- }
-
- subvol = dht_subvol_get_hashed (this, loc);
- if (!subvol) {
- gf_msg_debug (this->name, 0,
- "no subvolume in layout for path=%s",
- loc->path);
- op_errno = ENOENT;
- goto err;
- }
+ local = dht_local_init (frame);
+ if (!local) {
+ op_errno = ENOMEM;
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory");
+ goto err;
+ }
+
+ subvol = dht_subvol_get_hashed (this, loc);
+ if (!subvol) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "no subvolume in layout for path=%s",
+ loc->path);
+ op_errno = ENOENT;
+ goto err;
+ }
avail_subvol = conf->private;
if (dht_is_subvol_filled (this, (xlator_t *)conf->private)) {
avail_subvol =
dht_free_disk_available_subvol (this,
- (xlator_t *)conf->private,
- local);
+ (xlator_t *)conf->private);
}
if (subvol != avail_subvol) {
/* create a link file instead of actual file */
- local->params = dict_ref (params);
+ ret = loc_copy (&local->loc, loc);
+ if (ret == -1) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory");
+ 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, nufa_create_linkfile_create_cbk,
- this, avail_subvol, subvol, loc);
+ dht_linkfile_create (frame,
+ nufa_create_linkfile_create_cbk,
+ avail_subvol, subvol, loc);
return 0;
}
- gf_msg_trace (this->name, 0,
- "creating %s on %s", loc->path, subvol->name);
+ gf_log (this->name, GF_LOG_TRACE,
+ "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);
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);
+ op_errno = (op_errno == -1) ? errno : op_errno;
+ DHT_STACK_UNWIND (create, frame, -1, op_errno,
+ NULL, NULL, NULL, NULL, NULL);
- return 0;
+ return 0;
}
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 stat *stbuf, struct stat *preparent,
+ struct stat *postparent)
{
- dht_local_t *local = NULL;
-
- local = frame->local;
- if (!local || !local->cached_subvol) {
- op_errno = EINVAL;
- op_ret = -1;
- goto err;
- }
-
- if (op_ret >= 0) {
- STACK_WIND_COOKIE (frame, dht_newfile_cbk,
- (void *)local->cached_subvol, local->cached_subvol,
- local->cached_subvol->fops->mknod,
- &local->loc, local->mode, local->rdev,
- local->umask, local->params);
-
- return 0;
- }
-err:
- WIPE (postparent);
- WIPE (preparent);
-
- DHT_STACK_UNWIND (link, frame, op_ret, op_errno,
- inode, stbuf, preparent, postparent, xdata);
- return 0;
+ dht_local_t *local = NULL;
+ call_frame_t *prev = NULL;
+ dht_conf_t *conf = NULL;
+
+ local = frame->local;
+ prev = cookie;
+ conf = this->private;
+
+ if (op_ret >= 0) {
+ STACK_WIND (frame, dht_newfile_cbk,
+ local->cached_subvol,
+ local->cached_subvol->fops->mknod,
+ &local->loc, local->mode, local->rdev);
+
+ return 0;
+ }
+
+ DHT_STACK_UNWIND (link, frame, op_ret, op_errno,
+ 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)
{
- dht_local_t *local = NULL;
- dht_conf_t *conf = NULL;
- xlator_t *subvol = NULL;
+ dht_local_t *local = NULL;
+ dht_conf_t *conf = NULL;
+ xlator_t *subvol = NULL;
xlator_t *avail_subvol = NULL;
- int op_errno = -1;
+ int op_errno = -1;
+ int ret = -1;
- VALIDATE_OR_GOTO (frame, err);
- VALIDATE_OR_GOTO (this, err);
- VALIDATE_OR_GOTO (loc, err);
+ VALIDATE_OR_GOTO (frame, err);
+ VALIDATE_OR_GOTO (this, err);
+ VALIDATE_OR_GOTO (loc, err);
- conf = this->private;
+ conf = this->private;
dht_get_du_info (frame, this, loc);
- local = dht_local_init (frame, loc, NULL, GF_FOP_MKNOD);
- if (!local) {
- op_errno = ENOMEM;
- goto err;
- }
-
- subvol = dht_subvol_get_hashed (this, loc);
- if (!subvol) {
- gf_msg_debug (this->name, 0,
- "no subvolume in layout for path=%s",
- loc->path);
- op_errno = ENOENT;
- goto err;
- }
+ local = dht_local_init (frame);
+ if (!local) {
+ op_errno = ENOMEM;
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory");
+ goto err;
+ }
+
+ subvol = dht_subvol_get_hashed (this, loc);
+ if (!subvol) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "no subvolume in layout for path=%s",
+ loc->path);
+ op_errno = ENOENT;
+ goto err;
+ }
/* Consider the disksize in consideration */
avail_subvol = conf->private;
if (dht_is_subvol_filled (this, (xlator_t *)conf->private)) {
avail_subvol =
dht_free_disk_available_subvol (this,
- (xlator_t *)conf->private,
- local);
+ (xlator_t *)conf->private);
}
- if (avail_subvol != subvol) {
- /* Create linkfile first */
-
- local->params = dict_ref (params);
- local->mode = mode;
- local->umask = umask;
- local->rdev = rdev;
- local->cached_subvol = avail_subvol;
-
- dht_linkfile_create (frame, nufa_mknod_linkfile_cbk, this,
+ if (avail_subvol != subvol) {
+ /* Create linkfile first */
+ ret = loc_copy (&local->loc, loc);
+ if (ret == -1) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory");
+ op_errno = ENOMEM;
+ goto err;
+ }
+
+ local->mode = mode;
+ local->rdev = rdev;
+ local->cached_subvol = avail_subvol;
+
+ dht_linkfile_create (frame, nufa_mknod_linkfile_cbk,
avail_subvol, subvol, loc);
- return 0;
- }
+ return 0;
+ }
- gf_msg_trace (this->name, 0,
- "creating %s on %s", loc->path, subvol->name);
+ gf_log (this->name, GF_LOG_TRACE,
+ "creating %s on %s", loc->path, subvol->name);
- STACK_WIND_COOKIE (frame, dht_newfile_cbk, (void *)subvol, subvol,
- subvol->fops->mknod, loc, mode, rdev, umask,
- params);
+ STACK_WIND (frame, dht_newfile_cbk,
+ subvol, subvol->fops->mknod,
+ loc, mode, rdev);
- return 0;
+ return 0;
err:
- op_errno = (op_errno == -1) ? errno : op_errno;
- DHT_STACK_UNWIND (mknod, frame, -1, op_errno,
- NULL, NULL, NULL, NULL, NULL);
+ op_errno = (op_errno == -1) ? errno : op_errno;
+ DHT_STACK_UNWIND (mknod, frame, -1, op_errno,
+ NULL, NULL, NULL, NULL);
- return 0;
-}
-
-
-gf_boolean_t
-same_first_part (char *str1, char term1, char *str2, char term2)
-{
- gf_boolean_t ended1;
- gf_boolean_t ended2;
-
- for (;;) {
- ended1 = ((*str1 == '\0') || (*str1 == term1));
- ended2 = ((*str2 == '\0') || (*str2 == term2));
- if (ended1 && ended2) {
- return _gf_true;
- }
- if (ended1 || ended2 || (*str1 != *str2)) {
- return _gf_false;
- }
- ++str1;
- ++str2;
- }
+ return 0;
}
-typedef struct nufa_args {
- xlator_t *this;
- char *volname;
- gf_boolean_t addr_match;
-} nufa_args_t;
-static void
-nufa_find_local_brick (xlator_t *xl, void *data)
+int
+notify (xlator_t *this, int event, void *data, ...)
{
- nufa_args_t *args = data;
- xlator_t *this = args->this;
- char *local_volname = args->volname;
- gf_boolean_t addr_match = args->addr_match;
- char *brick_host = NULL;
- dht_conf_t *conf = this->private;
- int ret = -1;
-
- /*This means a local subvol was already found. We pick the first brick
- * that is local*/
- if (conf->private)
- return;
-
- if (strcmp (xl->name, local_volname) == 0) {
- conf->private = xl;
- gf_log (this->name, GF_LOG_INFO, "Using specified subvol %s",
- local_volname);
- return;
- }
+ int ret = -1;
- if (!addr_match)
- return;
-
- ret = dict_get_str (xl->options, "remote-host", &brick_host);
- if ((ret == 0) &&
- (gf_is_same_address (local_volname, brick_host) ||
- gf_is_local_addr (brick_host))) {
- conf->private = xl;
- gf_log (this->name, GF_LOG_INFO, "Using the first local "
- "subvol %s", xl->name);
- return;
- }
+ ret = dht_notify (this, event, data);
+ return ret;
}
-static void
-nufa_to_dht (xlator_t *this)
+void
+fini (xlator_t *this)
{
- GF_ASSERT (this);
- GF_ASSERT (this->fops);
-
- this->fops->lookup = dht_lookup;
- this->fops->create = dht_create;
- this->fops->mknod = dht_mknod;
-}
+ int i = 0;
+ dht_conf_t *conf = NULL;
-int
-nufa_find_local_subvol (xlator_t *this,
- void (*fn) (xlator_t *each, void* data), void *data)
-{
- int ret = -1;
- dht_conf_t *conf = this->private;
- xlator_list_t *trav = NULL;
- xlator_t *parent = NULL;
- xlator_t *candidate = NULL;
-
- xlator_foreach_depth_first (this, fn, data);
- if (!conf->private) {
- gf_log (this->name, GF_LOG_ERROR, "Couldn't find a local "
- "brick");
- return -1;
- }
+ conf = this->private;
- candidate = conf->private;
- trav = candidate->parents;
- while (trav) {
-
- parent = trav->xlator;
- if (strcmp (parent->type, "cluster/nufa") == 0) {
- gf_log (this->name, GF_LOG_INFO, "Found local subvol, "
- "%s", candidate->name);
- ret = 0;
- conf->private = candidate;
- break;
+ if (conf) {
+ if (conf->file_layouts) {
+ for (i = 0; i < conf->subvolume_cnt; i++) {
+ FREE (conf->file_layouts[i]);
+ }
+ FREE (conf->file_layouts);
}
- candidate = parent;
- trav = parent->parents;
+ if (conf->default_dir_layout)
+ FREE (conf->default_dir_layout);
+
+ if (conf->subvolumes)
+ FREE (conf->subvolumes);
+
+ if (conf->subvolume_status)
+ FREE (conf->subvolume_status);
+
+ FREE (conf);
}
- return ret;
+ return;
}
int
-nufa_init (xlator_t *this)
+init (xlator_t *this)
{
- data_t *data = NULL;
- char *local_volname = NULL;
+ dht_conf_t *conf = NULL;
+ xlator_list_t *trav = NULL;
+ data_t *data = NULL;
+ char *local_volname = NULL;
+ char *temp_str = NULL;
int ret = -1;
- char my_hostname[256];
- gf_boolean_t addr_match = _gf_false;
- nufa_args_t args = {0, };
-
- ret = dht_init(this);
- if (ret) {
- return ret;
+ int i = 0;
+ char my_hostname[256];
+ uint32_t temp_free_disk = 0;
+
+ if (!this->children) {
+ gf_log (this->name, GF_LOG_CRITICAL,
+ "NUFA needs more than one subvolume");
+ return -1;
+ }
+
+ if (!this->parents) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "dangling volume. check volfile");
+ }
+
+ conf = CALLOC (1, sizeof (*conf));
+ if (!conf) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory");
+ goto err;
}
- if ((data = dict_get (this->options, "local-volume-name"))) {
- local_volname = data->data;
+ conf->search_unhashed = GF_DHT_LOOKUP_UNHASHED_AUTO;
+ if (dict_get_str (this->options, "lookup-unhashed", &temp_str) == 0) {
+ /* If option is not "auto", other options _should_ be boolean */
+ if (strcasecmp (temp_str, "auto"))
+ gf_string2boolean (temp_str, &conf->search_unhashed);
+ }
- } else {
- addr_match = _gf_true;
- local_volname = "localhost";
- ret = gethostname (my_hostname, 256);
- if (ret == 0)
- local_volname = my_hostname;
+ ret = dht_init_subvolumes (this, conf);
+ if (ret == -1) {
+ goto err;
+ }
- else
- gf_log (this->name, GF_LOG_WARNING,
- "could not find hostname (%s)",
- strerror (errno));
+ ret = dht_layouts_init (this, conf);
+ if (ret == -1) {
+ goto err;
+ }
+ LOCK_INIT (&conf->subvolume_lock);
+ LOCK_INIT (&conf->layout_lock);
+
+ conf->gen = 1;
+
+ local_volname = "localhost";
+ ret = gethostname (my_hostname, 256);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "could not find hostname (%s)",
+ strerror (errno));
+ }
+
+ if (ret == 0)
+ local_volname = my_hostname;
+
+ data = dict_get (this->options, "local-volume-name");
+ if (data) {
+ local_volname = data->data;
+ }
+
+ trav = this->children;
+ while (trav) {
+ if (strcmp (trav->xlator->name, local_volname) == 0)
+ break;
+ trav = trav->next;
+ }
+
+ if (!trav) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Could not find subvolume named '%s'. "
+ "Please define volume with the name as the hostname "
+ "or override it with 'option local-volume-name'",
+ local_volname);
+ goto err;
+ }
+ /* The volume specified exists */
+ conf->private = trav->xlator;
+
+ conf->min_free_disk = 10;
+ conf->disk_unit = 'p';
+
+ 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;
+ conf->disk_unit = 'p';
+ }
+ } else {
+ gf_string2bytesize (temp_str,
+ &conf->min_free_disk);
+ conf->disk_unit = 'b';
+ }
}
- args.this = this;
- args.volname = local_volname;
- args.addr_match = addr_match;
- ret = nufa_find_local_subvol (this, nufa_find_local_brick, &args);
- if (ret) {
- gf_log (this->name, GF_LOG_INFO,
- "Unable to find local subvolume, switching "
- "to dht mode");
- nufa_to_dht (this);
+ conf->du_stats = CALLOC (conf->subvolume_cnt, sizeof (dht_du_t));
+ if (!conf->du_stats) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory");
+ goto err;
}
+
+ this->private = conf;
+
return 0;
-}
+err:
+ if (conf) {
+ if (conf->file_layouts) {
+ for (i = 0; i < conf->subvolume_cnt; i++) {
+ FREE (conf->file_layouts[i]);
+ }
+ FREE (conf->file_layouts);
+ }
-class_methods_t class_methods = {
- .init = nufa_init,
- .fini = dht_fini,
- .reconfigure = dht_reconfigure,
- .notify = dht_notify
-};
+ if (conf->default_dir_layout)
+ FREE (conf->default_dir_layout);
+
+ if (conf->subvolumes)
+ FREE (conf->subvolumes);
+
+ if (conf->subvolume_status)
+ FREE (conf->subvolume_status);
+
+ if (conf->du_stats)
+ FREE (conf->du_stats);
+
+ FREE (conf);
+ }
+
+ return -1;
+}
struct xlator_fops fops = {
- .lookup = nufa_lookup,
- .create = nufa_create,
- .mknod = nufa_mknod,
-
- .stat = dht_stat,
- .fstat = dht_fstat,
- .truncate = dht_truncate,
- .ftruncate = dht_ftruncate,
- .access = dht_access,
- .readlink = dht_readlink,
- .setxattr = dht_setxattr,
- .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,
- .fsyncdir = dht_fsyncdir,
- .symlink = dht_symlink,
- .unlink = dht_unlink,
- .link = dht_link,
- .mkdir = dht_mkdir,
- .rmdir = dht_rmdir,
- .rename = dht_rename,
- .inodelk = dht_inodelk,
- .finodelk = dht_finodelk,
- .entrylk = dht_entrylk,
- .fentrylk = dht_fentrylk,
- .xattrop = dht_xattrop,
- .fxattrop = dht_fxattrop,
+ .lookup = nufa_lookup,
+ .create = nufa_create,
+ .mknod = nufa_mknod,
+
+ .stat = dht_stat,
+ .fstat = dht_fstat,
+ .truncate = dht_truncate,
+ .ftruncate = dht_ftruncate,
+ .access = dht_access,
+ .readlink = dht_readlink,
+ .setxattr = dht_setxattr,
+ .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,
+ .fsyncdir = dht_fsyncdir,
+ .symlink = dht_symlink,
+ .unlink = dht_unlink,
+ .link = dht_link,
+ .mkdir = dht_mkdir,
+ .rmdir = dht_rmdir,
+ .rename = dht_rename,
+ .inodelk = dht_inodelk,
+ .finodelk = dht_finodelk,
+ .entrylk = dht_entrylk,
+ .fentrylk = dht_fentrylk,
+ .xattrop = dht_xattrop,
+ .fxattrop = dht_fxattrop,
.setattr = dht_setattr,
+#if 0
+ .setdents = dht_setdents,
+ .getdents = dht_getdents,
+ .checksum = dht_checksum,
+#endif
+};
+
+
+struct xlator_mops mops = {
};
struct xlator_cbks cbks = {
- .forget = dht_forget
+ .forget = dht_forget
+};
+
+
+struct volume_options options[] = {
+ { .key = {"lookup-unhashed"},
+ .value = {"auto", "yes", "no", "enable", "disable", "1", "0",
+ "on", "off"},
+ .type = GF_OPTION_TYPE_STR
+ },
+ { .key = {"local-volume-name"},
+ .type = GF_OPTION_TYPE_XLATOR
+ },
+ { .key = {"min-free-disk"},
+ .type = GF_OPTION_TYPE_PERCENT_OR_SIZET,
+ },
+ { .key = {NULL} },
};
diff --git a/xlators/cluster/dht/src/switch.c b/xlators/cluster/dht/src/switch.c
index 0071dfa265d..5a36f8dab04 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>
- 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) 2009 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/>.
*/
@@ -14,31 +23,28 @@
#include "config.h"
#endif
-#include "dht-common.h"
-#include "dht-mem-types.h"
+#include "dht-common.c"
#include <sys/time.h>
#include <stdlib.h>
#include <fnmatch.h>
#include <string.h>
-extern struct volume_options options[];
-
struct switch_sched_array {
- xlator_t *xl;
- int32_t eligible;
- int32_t considered;
+ xlator_t *xl;
+ int32_t eligible;
+ int32_t considered;
};
/* Select one of this struct based on the path's pattern match */
struct switch_struct {
- struct switch_struct *next;
+ struct switch_struct *next;
struct switch_sched_array *array;
- int32_t node_index; /* Index of the node in
+ int32_t node_index; /* Index of the node in
this pattern. */
- int32_t num_child; /* Total num of child nodes
+ int32_t num_child; /* Total num of child nodes
with this pattern. */
- char path_pattern[256];
+ char path_pattern[256];
};
/* TODO: all 'TODO's in dht.c holds good */
@@ -67,47 +73,39 @@ get_switch_matching_subvol (const char *path, dht_conf_t *conf,
xlator_t *hashed_subvol)
{
struct switch_struct *cond = NULL;
- struct switch_struct *trav = NULL;
- char *pathname = NULL;
- int idx = 0;
- xlator_t *subvol = NULL;
+ struct switch_struct *trav = NULL;
+ char *pathname = 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;
- while (trav) {
- if (fnmatch (trav->path_pattern,
- pathname, FNM_NOESCAPE) == 0) {
+ pathname = 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;
- }
- trav = trav->next;
- }
-out:
- GF_FREE (pathname);
-
- return subvol;
+ return trav->array[idx].xl;
+ }
+ trav = trav->next;
+ }
+ free (pathname);
+ return hashed_subvol;
}
int
switch_local_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)
+ inode_t *inode, struct stat *stbuf, dict_t *xattr,
+ struct stat *postparent)
{
xlator_t *subvol = NULL;
char is_linkfile = 0;
@@ -117,7 +115,7 @@ switch_local_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
loc_t *loc = NULL;
int i = 0;
call_frame_t *prev = NULL;
- int call_cnt = 0;
+ int call_cnt = 0;
int ret = 0;
conf = this->private;
@@ -126,56 +124,57 @@ switch_local_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
local = frame->local;
loc = &local->loc;
- if (ENTRY_MISSING (op_ret, op_errno)) {
- if (conf->search_unhashed) {
- local->op_errno = ENOENT;
- dht_lookup_everywhere (frame, this, loc);
- return 0;
- }
- }
+ if (ENTRY_MISSING (op_ret, op_errno)) {
+ if (conf->search_unhashed) {
+ local->op_errno = ENOENT;
+ dht_lookup_everywhere (frame, this, loc);
+ return 0;
+ }
+ }
if (op_ret == -1)
goto out;
- is_linkfile = check_is_linkfile (inode, stbuf, xattr,
- conf->link_xattr_name);
+ is_linkfile = check_is_linkfile (inode, stbuf, xattr);
is_dir = check_is_dir (inode, stbuf, xattr);
if (!is_dir && !is_linkfile) {
/* non-directory and not a linkfile */
- ret = dht_layout_preset (this, prev->this, inode);
- if (ret < 0) {
- gf_msg_debug (this->name, 0,
- "could not set pre-set layout "
- "for subvol %s",
- prev->this->name);
- op_ret = -1;
- op_errno = EINVAL;
- goto err;
- }
+ dht_itransform (this, prev->this, stbuf->st_ino,
+ &stbuf->st_ino);
+
+ ret = dht_layout_preset (this, prev->this, inode);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "could not set pre-set layout for subvol %s",
+ prev->this->name);
+ op_ret = -1;
+ op_errno = EINVAL;
+ goto err;
+ }
goto out;
}
if (is_dir) {
call_cnt = conf->subvolume_cnt;
- local->call_cnt = call_cnt;
+ local->call_cnt = call_cnt;
local->inode = inode_ref (inode);
local->xattr = dict_ref (xattr);
- local->op_ret = 0;
- local->op_errno = 0;
+ local->op_ret = 0;
+ local->op_errno = 0;
- local->layout = dht_layout_new (this, conf->subvolume_cnt);
- if (!local->layout) {
- op_ret = -1;
- op_errno = ENOMEM;
- gf_msg_debug (this->name, 0,
- "memory allocation failed :(");
- goto err;
- }
+ local->layout = dht_layout_new (this, conf->subvolume_cnt);
+ if (!local->layout) {
+ op_ret = -1;
+ op_errno = ENOMEM;
+ gf_log (this->name, GF_LOG_DEBUG,
+ "memory allocation failed :(");
+ goto err;
+ }
for (i = 0; i < call_cnt; i++) {
STACK_WIND (frame, dht_lookup_dir_cbk,
@@ -189,37 +188,36 @@ switch_local_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
subvol = dht_linkfile_subvol (this, inode, stbuf, xattr);
if (!subvol) {
- gf_msg_debug (this->name, 0,
- "linkfile has no link subvolume.path=%s",
- loc->path);
- dht_lookup_everywhere (frame, this, loc);
- return 0;
+ gf_log (this->name, GF_LOG_DEBUG,
+ "linkfile not having link subvolume. path=%s",
+ loc->path);
+ dht_lookup_everywhere (frame, this, loc);
+ return 0;
}
- STACK_WIND (frame, dht_lookup_linkfile_cbk,
- subvol, subvol->fops->lookup,
- &local->loc, local->xattr_req);
+ STACK_WIND (frame, dht_lookup_linkfile_cbk,
+ subvol, subvol->fops->lookup,
+ &local->loc, local->xattr_req);
}
return 0;
out:
- if (!local->hashed_subvol) {
- gf_msg_debug (this->name, 0,
- "no subvolume in layout for path=%s",
- local->loc.path);
- local->op_errno = ENOENT;
- dht_lookup_everywhere (frame, this, loc);
- return 0;
- }
+ if (!local->hashed_subvol) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "no subvolume in layout for path=%s",
+ local->loc.path);
+ op_errno = EINVAL;
+ goto err;
+ }
- STACK_WIND (frame, dht_lookup_cbk,
- local->hashed_subvol, local->hashed_subvol->fops->lookup,
- &local->loc, local->xattr_req);
+ STACK_WIND (frame, dht_lookup_cbk,
+ local->hashed_subvol, local->hashed_subvol->fops->lookup,
+ &local->loc, local->xattr_req);
- return 0;
+ return 0;
-err:
+ err:
DHT_STACK_UNWIND (lookup, frame, op_ret, op_errno,
inode, stbuf, xattr, NULL);
return 0;
@@ -227,18 +225,18 @@ err:
int
switch_lookup (call_frame_t *frame, xlator_t *this,
- loc_t *loc, dict_t *xattr_req)
+ 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;
+ dht_conf_t *conf = NULL;
int ret = -1;
int op_errno = -1;
- dht_layout_t *layout = NULL;
- int i = 0;
- int call_cnt = 0;
+ dht_layout_t *layout = NULL;
+ int i = 0;
+ int call_cnt = 0;
VALIDATE_OR_GOTO (frame, err);
@@ -247,109 +245,113 @@ switch_lookup (call_frame_t *frame, xlator_t *this,
VALIDATE_OR_GOTO (loc->inode, err);
VALIDATE_OR_GOTO (loc->path, err);
- conf = this->private;
-
- local = dht_local_init (frame, loc, NULL, GF_FOP_LOOKUP);
- if (!local) {
- op_errno = ENOMEM;
+ conf = this->private;
+
+ local = dht_local_init (frame);
+ if (!local) {
+ op_errno = ENOMEM;
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory");
+ 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 {
- local->xattr_req = dict_new ();
- }
+ if (xattr_req) {
+ local->xattr_req = dict_ref (xattr_req);
+ } else {
+ local->xattr_req = dict_new ();
+ }
- hashed_subvol = dht_subvol_get_hashed (this, &local->loc);
- cached_subvol = local->cached_subvol;
+ hashed_subvol = dht_subvol_get_hashed (this, &local->loc);
+ cached_subvol = dht_subvol_get_cached (this, local->loc.inode);
- local->hashed_subvol = hashed_subvol;
+ 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_msg_debug(this->name, 0,
- "revalidate lookup without cache. path=%s",
- loc->path);
+ gf_log (this->name, GF_LOG_DEBUG,
+ "revalidate without cache. path=%s",
+ loc->path);
op_errno = EINVAL;
goto err;
}
- if (layout->gen && (layout->gen < conf->gen)) {
- gf_msg_debug (this->name, 0,
- "incomplete layout failure for path=%s",
- loc->path);
+ if (layout->gen && (layout->gen < conf->gen)) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "incomplete layout failure for path=%s",
+ loc->path);
dht_layout_unref (this, local->layout);
- goto do_fresh_lookup;
- }
+ goto do_fresh_lookup;
+ }
- local->inode = inode_ref (loc->inode);
+ local->inode = inode_ref (loc->inode);
+ local->st_ino = loc->inode->ino;
- local->call_cnt = layout->cnt;
- call_cnt = local->call_cnt;
+ local->call_cnt = layout->cnt;
+ call_cnt = local->call_cnt;
- /* NOTE: we don't require 'trusted.glusterfs.dht.linkto'
+ /* NOTE: we don't require 'trusted.glusterfs.dht.linkto'
* attribute, revalidates directly go to the cached-subvolume.
- */
- ret = dict_set_uint32 (local->xattr_req,
- conf->xattr_name, 4 * 4);
- if (ret < 0)
- gf_log (this->name, GF_LOG_WARNING,
- "failed to set dict value for %s",
- conf->xattr_name);
-
- for (i = 0; i < layout->cnt; i++) {
- subvol = layout->list[i].xlator;
-
- STACK_WIND (frame, dht_revalidate_cbk,
- subvol, subvol->fops->lookup,
- loc, local->xattr_req);
+ */
+ ret = dict_set_uint32 (local->xattr_req,
+ "trusted.glusterfs.dht", 4 * 4);
- if (!--call_cnt)
- break;
- }
- } else {
+ for (i = 0; i < layout->cnt; i++) {
+ subvol = layout->list[i].xlator;
+
+ STACK_WIND (frame, dht_revalidate_cbk,
+ subvol, subvol->fops->lookup,
+ loc, local->xattr_req);
+
+ if (!--call_cnt)
+ break;
+ }
+ } else {
do_fresh_lookup:
- ret = dict_set_uint32 (local->xattr_req,
- conf->xattr_name, 4 * 4);
- if (ret < 0)
- gf_log (this->name, GF_LOG_WARNING,
- "failed to set dict value for %s",
- conf->xattr_name);
-
- ret = dict_set_uint32 (local->xattr_req,
- conf->link_xattr_name, 256);
- if (ret < 0)
- gf_log (this->name, GF_LOG_WARNING,
- "failed to set dict value for %s",
- conf->link_xattr_name);
+ ret = dict_set_uint32 (local->xattr_req,
+ "trusted.glusterfs.dht", 4 * 4);
+
+ ret = dict_set_uint32 (local->xattr_req,
+ "trusted.glusterfs.dht.linkto", 256);
if (!hashed_subvol) {
- gf_msg_debug (this->name, 0,
- "no subvolume in layout for path=%s, "
- "checking on all the subvols to see if "
- "it is a directory", loc->path);
- call_cnt = conf->subvolume_cnt;
- local->call_cnt = call_cnt;
-
- local->layout = dht_layout_new (this,
+ gf_log (this->name, GF_LOG_DEBUG,
+ "no subvolume in layout for path=%s, "
+ "checking on all the subvols to see if "
+ "it is a directory", loc->path);
+ call_cnt = conf->subvolume_cnt;
+ local->call_cnt = call_cnt;
+
+ local->layout = dht_layout_new (this,
conf->subvolume_cnt);
- if (!local->layout) {
- op_errno = ENOMEM;
- goto err;
- }
-
- for (i = 0; i < call_cnt; i++) {
- STACK_WIND (frame, dht_lookup_dir_cbk,
- conf->subvolumes[i],
- conf->subvolumes[i]->fops->lookup,
- &local->loc, local->xattr_req);
- }
- return 0;
+ if (!local->layout) {
+ op_errno = ENOMEM;
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory");
+ goto err;
+ }
+
+ for (i = 0; i < call_cnt; i++) {
+ STACK_WIND (frame, dht_lookup_dir_cbk,
+ conf->subvolumes[i],
+ conf->subvolumes[i]->fops->lookup,
+ &local->loc, local->xattr_req);
+ }
+ return 0;
}
- /* */
+ /* */
cached_subvol = get_switch_matching_subvol (loc->path, conf,
hashed_subvol);
if (cached_subvol == hashed_subvol) {
@@ -368,233 +370,281 @@ switch_lookup (call_frame_t *frame, xlator_t *this,
return 0;
err:
- op_errno = (op_errno == -1) ? errno : op_errno;
- DHT_STACK_UNWIND (lookup, frame, -1, op_errno,
- NULL, NULL, NULL, NULL);
- return 0;
+ op_errno = (op_errno == -1) ? errno : op_errno;
+ DHT_STACK_UNWIND (lookup, frame, -1, op_errno, NULL, NULL, NULL, NULL);
+ return 0;
}
int
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)
+ xlator_t *this, int op_ret, int op_errno,
+ inode_t *inode, struct stat *stbuf,
+ struct stat *preparent,
+ struct stat *postparent)
{
- dht_local_t *local = NULL;
+ dht_local_t *local = NULL;
+ call_frame_t *prev = NULL;
+ dht_conf_t *conf = NULL;
- local = frame->local;
+ local = frame->local;
+ prev = cookie;
+ conf = this->private;
- if (op_ret == -1)
- goto err;
+ if (op_ret == -1)
+ goto err;
- 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);
+ STACK_WIND (frame, dht_create_cbk,
+ local->cached_subvol, local->cached_subvol->fops->create,
+ &local->loc, local->flags, local->mode, local->fd);
- return 0;
+ return 0;
-err:
- DHT_STACK_UNWIND (create, frame, -1, op_errno,
- NULL, NULL, NULL, NULL, NULL, NULL);
- return 0;
+ err:
+ DHT_STACK_UNWIND (create, frame, -1, op_errno,
+ 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)
+ loc_t *loc, int32_t flags, mode_t mode, fd_t *fd)
{
- dht_local_t *local = NULL;
- dht_conf_t *conf = NULL;
- xlator_t *subvol = NULL;
+ dht_local_t *local = NULL;
+ dht_conf_t *conf = NULL;
+ xlator_t *subvol = NULL;
xlator_t *avail_subvol = NULL;
- int op_errno = -1;
+ int op_errno = -1;
+ int ret = -1;
- VALIDATE_OR_GOTO (frame, err);
- VALIDATE_OR_GOTO (this, err);
- VALIDATE_OR_GOTO (loc, err);
+ VALIDATE_OR_GOTO (frame, err);
+ VALIDATE_OR_GOTO (this, err);
+ VALIDATE_OR_GOTO (loc, err);
- conf = this->private;
+ conf = this->private;
dht_get_du_info (frame, this, loc);
- local = dht_local_init (frame, loc, fd, GF_FOP_CREATE);
- if (!local) {
- op_errno = ENOMEM;
- goto err;
- }
-
- subvol = dht_subvol_get_hashed (this, loc);
- if (!subvol) {
- gf_msg_debug (this->name, 0,
- "no subvolume in layout for path=%s",
- loc->path);
- op_errno = ENOENT;
- goto err;
- }
+ local = dht_local_init (frame);
+ if (!local) {
+ op_errno = ENOMEM;
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory");
+ goto err;
+ }
+
+ subvol = dht_subvol_get_hashed (this, loc);
+ if (!subvol) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "no subvolume in layout for path=%s",
+ loc->path);
+ op_errno = ENOENT;
+ goto err;
+ }
avail_subvol = get_switch_matching_subvol (loc->path, conf, subvol);
if (dht_is_subvol_filled (this, avail_subvol)) {
avail_subvol =
- dht_free_disk_available_subvol (this, avail_subvol,
- local);
+ dht_free_disk_available_subvol (this, avail_subvol);
}
if (subvol != avail_subvol) {
/* create a link file instead of actual file */
+ ret = loc_copy (&local->loc, loc);
+ if (ret == -1) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory");
+ 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,
- this, avail_subvol, subvol, loc);
+ dht_linkfile_create (frame,
+ switch_create_linkfile_create_cbk,
+ avail_subvol, subvol, loc);
return 0;
}
- gf_msg_trace (this->name, 0,
- "creating %s on %s", loc->path, subvol->name);
+ gf_log (this->name, GF_LOG_TRACE,
+ "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);
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);
+ op_errno = (op_errno == -1) ? errno : op_errno;
+ DHT_STACK_UNWIND (create, frame, -1, op_errno,
+ NULL, NULL, NULL, NULL, NULL);
- return 0;
+ return 0;
}
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)
+ int op_ret, int op_errno, inode_t *inode,
+ struct stat *stbuf, struct stat *preparent,
+ struct stat *postparent)
{
- dht_local_t *local = NULL;
-
- local = frame->local;
- if (!local || !local->cached_subvol) {
- op_errno = EINVAL;
- op_ret = -1;
- goto err;
- }
-
- if (op_ret >= 0) {
- STACK_WIND_COOKIE (frame, dht_newfile_cbk,
- (void *)local->cached_subvol, local->cached_subvol,
- local->cached_subvol->fops->mknod,
- &local->loc, local->mode, local->rdev,
- local->umask, local->params);
-
- return 0;
- }
-err:
- DHT_STACK_UNWIND (link, frame, op_ret, op_errno,
- inode, stbuf, preparent, postparent, xdata);
- return 0;
+ dht_local_t *local = NULL;
+ call_frame_t *prev = NULL;
+ dht_conf_t *conf = NULL;
+
+ local = frame->local;
+ prev = cookie;
+ conf = this->private;
+
+ if (op_ret >= 0) {
+ STACK_WIND (frame, dht_newfile_cbk,
+ local->cached_subvol,
+ local->cached_subvol->fops->mknod,
+ &local->loc, local->mode, local->rdev);
+
+ return 0;
+ }
+
+ DHT_STACK_UNWIND (link, frame, op_ret, op_errno,
+ 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)
{
- dht_local_t *local = NULL;
- dht_conf_t *conf = NULL;
- xlator_t *subvol = NULL;
+ dht_local_t *local = NULL;
+ dht_conf_t *conf = NULL;
+ xlator_t *subvol = NULL;
xlator_t *avail_subvol = NULL;
- int op_errno = -1;
+ int op_errno = -1;
+ int ret = -1;
- VALIDATE_OR_GOTO (frame, err);
- VALIDATE_OR_GOTO (this, err);
- VALIDATE_OR_GOTO (loc, err);
+ VALIDATE_OR_GOTO (frame, err);
+ VALIDATE_OR_GOTO (this, err);
+ VALIDATE_OR_GOTO (loc, err);
- conf = this->private;
+ conf = this->private;
dht_get_du_info (frame, this, loc);
- local = dht_local_init (frame, loc, NULL, GF_FOP_MKNOD);
- if (!local) {
- op_errno = ENOMEM;
- goto err;
- }
-
- subvol = dht_subvol_get_hashed (this, loc);
- if (!subvol) {
- gf_msg_debug (this->name, 0,
- "no subvolume in layout for path=%s",
- loc->path);
- op_errno = ENOENT;
- goto err;
- }
+ local = dht_local_init (frame);
+ if (!local) {
+ op_errno = ENOMEM;
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory");
+ goto err;
+ }
+
+ subvol = dht_subvol_get_hashed (this, loc);
+ if (!subvol) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "no subvolume in layout for path=%s",
+ loc->path);
+ op_errno = ENOENT;
+ goto err;
+ }
/* Consider the disksize in consideration */
avail_subvol = get_switch_matching_subvol (loc->path, conf, subvol);
if (dht_is_subvol_filled (this, avail_subvol)) {
avail_subvol =
- dht_free_disk_available_subvol (this, avail_subvol,
- local);
+ dht_free_disk_available_subvol (this, avail_subvol);
}
- if (avail_subvol != subvol) {
- /* Create linkfile first */
+ if (avail_subvol != subvol) {
+ /* Create linkfile first */
+ ret = loc_copy (&local->loc, loc);
+ if (ret == -1) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory");
+ op_errno = ENOMEM;
+ goto err;
+ }
- local->params = dict_ref (params);
- local->mode = mode;
- local->umask = umask;
- local->rdev = rdev;
- local->cached_subvol = avail_subvol;
+ local->mode = mode;
+ local->rdev = rdev;
+ local->cached_subvol = avail_subvol;
- dht_linkfile_create (frame, switch_mknod_linkfile_cbk,
- this, avail_subvol, subvol, loc);
- return 0;
- }
+ dht_linkfile_create (frame, switch_mknod_linkfile_cbk,
+ avail_subvol, subvol, loc);
+ return 0;
+ }
- gf_msg_trace (this->name, 0,
- "creating %s on %s", loc->path, subvol->name);
+ gf_log (this->name, GF_LOG_TRACE,
+ "creating %s on %s", loc->path, subvol->name);
- STACK_WIND_COOKIE (frame, dht_newfile_cbk, (void *)subvol, subvol,
- subvol->fops->mknod, loc, mode, rdev, umask,
- params);
+ STACK_WIND (frame, dht_newfile_cbk,
+ subvol, subvol->fops->mknod,
+ loc, mode, rdev);
- return 0;
+ return 0;
err:
- op_errno = (op_errno == -1) ? errno : op_errno;
- DHT_STACK_UNWIND (mknod, frame, -1, op_errno,
- NULL, NULL, NULL, NULL, NULL);
+ op_errno = (op_errno == -1) ? errno : op_errno;
+ DHT_STACK_UNWIND (mknod, frame, -1, op_errno,
+ NULL, NULL, NULL, NULL);
- return 0;
+ return 0;
}
+int
+notify (xlator_t *this, int event, void *data, ...)
+{
+ int ret = -1;
+
+ ret = dht_notify (this, event, data);
+
+ return ret;
+}
+
void
-switch_fini (xlator_t *this)
+fini (xlator_t *this)
{
+ int i = 0;
dht_conf_t *conf = NULL;
struct switch_struct *trav = NULL;
struct switch_struct *prev = NULL;
- conf = this->private;
+ conf = this->private;
if (conf) {
trav = (struct switch_struct *)conf->private;
conf->private = NULL;
while (trav) {
- GF_FREE (trav->array);
+ if (trav->array)
+ FREE (trav->array);
prev = trav;
trav = trav->next;
- GF_FREE (prev);
+ FREE (prev);
}
+
+ if (conf->file_layouts) {
+ for (i = 0; i < conf->subvolume_cnt; i++) {
+ FREE (conf->file_layouts[i]);
+ }
+ FREE (conf->file_layouts);
+ }
+
+ if (conf->default_dir_layout)
+ FREE (conf->default_dir_layout);
+
+ if (conf->subvolumes)
+ FREE (conf->subvolumes);
+
+ if (conf->subvolume_status)
+ FREE (conf->subvolume_status);
+
+ FREE (conf);
}
- dht_fini(this);
+ return;
}
int
@@ -619,62 +669,56 @@ set_switch_pattern (xlator_t *this, dht_conf_t *conf,
struct switch_struct *switch_buf = NULL;
struct switch_struct *switch_opt = NULL;
struct switch_struct *trav = NULL;
- struct switch_sched_array *switch_buf_array = NULL;
- xlator_list_t *trav_xl = NULL;
+ struct switch_sched_array *switch_buf_array = NULL;
+ xlator_list_t *trav_xl = NULL;
trav_xl = this->children;
- while (trav_xl) {
- index++;
- trav_xl = trav_xl->next;
- }
- child_count = index;
- switch_buf_array = GF_CALLOC ((index + 1),
- sizeof (struct switch_sched_array),
- gf_switch_mt_switch_sched_array);
+ while (trav_xl) {
+ index++;
+ trav_xl = trav_xl->next;
+ }
+ child_count = index;
+ switch_buf_array = CALLOC ((index + 1),
+ sizeof (struct switch_sched_array));
if (!switch_buf_array)
goto err;
- trav_xl = this->children;
- index = 0;
+ trav_xl = this->children;
+ index = 0;
- while (trav_xl) {
- switch_buf_array[index].xl = trav_xl->xlator;
- switch_buf_array[index].eligible = 1;
- trav_xl = trav_xl->next;
- index++;
- }
+ while (trav_xl) {
+ switch_buf_array[index].xl = trav_xl->xlator;
+ switch_buf_array[index].eligible = 1;
+ trav_xl = trav_xl->next;
+ index++;
+ }
- /* *jpg:child1,child2;*mpg:child3;*:child4,child5,child6 */
+ /* *jpg:child1,child2;*mpg:child3;*:child4,child5,child6 */
/* Get the pattern for considering switch case.
"option block-size *avi:10MB" etc */
- option_string = gf_strdup (pattern_str);
+ option_string = strdup (pattern_str);
switch_str = strtok_r (option_string, ";", &tmp_str);
while (switch_str) {
- 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);
+ dup_str = strdup (switch_str);
+ switch_opt = CALLOC (1, sizeof (struct switch_struct));
+ if (!switch_opt)
goto err;
- }
pattern = strtok_r (dup_str, ":", &tmp_str1);
childs = strtok_r (NULL, ":", &tmp_str1);
if (strncmp (pattern, "*", 2) == 0) {
- gf_log ("switch", GF_LOG_INFO,
+ gf_log ("switch", GF_LOG_NORMAL,
"'*' pattern will be taken by default "
"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);
+ free (dup_str);
continue;
}
- GF_FREE (dup_str);
memcpy (switch_opt->path_pattern, pattern, strlen (pattern));
if (childs) {
- dup_childs = gf_strdup (childs);
+ dup_childs = strdup (childs);
child = strtok_r (dup_childs, ",", &tmp);
while (child) {
if (gf_switch_valid_child (this, child)) {
@@ -689,12 +733,11 @@ set_switch_pattern (xlator_t *this, dht_conf_t *conf,
goto err;
}
}
- GF_FREE (dup_childs);
+ free (dup_childs);
child = strtok_r (childs, ",", &tmp1);
switch_opt->num_child = idx;
- switch_opt->array = GF_CALLOC (1, (idx *
- sizeof (struct switch_sched_array)),
- gf_switch_mt_switch_sched_array);
+ switch_opt->array = CALLOC (1, (idx *
+ sizeof (struct switch_sched_array)));
if (!switch_opt->array)
goto err;
idx = 0;
@@ -702,13 +745,13 @@ set_switch_pattern (xlator_t *this, dht_conf_t *conf,
for (index = 0; index < child_count; index++) {
if (strcmp (switch_buf_array[index].xl->name,
child) == 0) {
- gf_msg_debug ("switch", 0,
- "'%s' pattern will be "
- "scheduled to \"%s\"",
- switch_opt->path_pattern, child);
+ gf_log ("switch", GF_LOG_DEBUG,
+ "'%s' pattern will be "
+ "scheduled to \"%s\"",
+ switch_opt->path_pattern, child);
/*
if (switch_buf_array[index-1].considered) {
- gf_msg_debug ("switch", 0,
+ gf_log ("switch", GF_LOG_DEBUG,
"ambiguity found, exiting");
return -1;
}
@@ -728,7 +771,8 @@ set_switch_pattern (xlator_t *this, dht_conf_t *conf,
"option in unify volume. Exiting");
goto err;
}
-
+ free (dup_str);
+
/* Link it to the main structure */
if (switch_buf) {
/* there are already few entries */
@@ -740,167 +784,273 @@ 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);
}
- /* Now, all the pattern based considerations done, so for all the
- * remaining pattern, '*' to all the remaining child nodes
- */
- {
- for (index=0; index < child_count; index++) {
- /* check for considered flag */
- if (switch_buf_array[index].considered)
- continue;
- flag++;
- }
- if (!flag) {
- gf_log ("switch", GF_LOG_ERROR,
- "No nodes left for pattern '*'. Exiting");
- goto err;
- }
- switch_opt = GF_CALLOC (1, sizeof (struct switch_struct),
- gf_switch_mt_switch_struct);
+ /* Now, all the pattern based considerations done, so for all the
+ * remaining pattern, '*' to all the remaining child nodes
+ */
+ {
+ for (index=0; index < child_count; index++) {
+ /* check for considered flag */
+ if (switch_buf_array[index].considered)
+ continue;
+ flag++;
+ }
+ if (!flag) {
+ gf_log ("switch", GF_LOG_ERROR,
+ "No nodes left for pattern '*'. Exiting");
+ goto err;
+ }
+ switch_opt = CALLOC (1, sizeof (struct switch_struct));
if (!switch_opt)
goto err;
- /* Add the '*' pattern to the array */
- memcpy (switch_opt->path_pattern, "*", 2);
- switch_opt->num_child = flag;
- switch_opt->array =
- GF_CALLOC (1,
- flag * sizeof (struct switch_sched_array),
- gf_switch_mt_switch_sched_array);
+ /* Add the '*' pattern to the array */
+ memcpy (switch_opt->path_pattern, "*", 2);
+ switch_opt->num_child = flag;
+ switch_opt->array =
+ CALLOC (1, flag * sizeof (struct switch_sched_array));
if (!switch_opt->array)
goto err;
- flag = 0;
- for (index=0; index < child_count; index++) {
- /* check for considered flag */
- if (switch_buf_array[index].considered)
- continue;
- gf_msg_debug ("switch", 0, "'%s'"
- " pattern will be scheduled to \"%s\"",
- switch_opt->path_pattern,
- switch_buf_array[index].xl->name);
-
- switch_opt->array[flag].xl =
- switch_buf_array[index].xl;
- switch_buf_array[index].considered = 1;
- flag++;
+ flag = 0;
+ for (index=0; index < child_count; index++) {
+ /* check for considered flag */
+ if (switch_buf_array[index].considered)
+ continue;
+ gf_log ("switch", GF_LOG_DEBUG,
+ "'%s' pattern will be scheduled to \"%s\"",
+ switch_opt->path_pattern,
+ switch_buf_array[index].xl->name);
+ switch_opt->array[flag].xl =
+ switch_buf_array[index].xl;
+ switch_buf_array[index].considered = 1;
+ flag++;
}
- if (switch_buf) {
- /* there are already few entries */
- trav = switch_buf;
- while (trav->next)
- trav = trav->next;
- trav->next = switch_opt;
- } else {
- /* First entry */
- switch_buf = switch_opt;
- }
- switch_opt = NULL;
- }
+ if (switch_buf) {
+ /* there are already few entries */
+ trav = switch_buf;
+ while (trav->next)
+ trav = trav->next;
+ trav->next = switch_opt;
+ } else {
+ /* First entry */
+ switch_buf = switch_opt;
+ }
+ }
/* */
conf->private = switch_buf;
return 0;
err:
- GF_FREE (switch_buf_array);
- GF_FREE (switch_opt);
-
if (switch_buf) {
+ if (switch_buf_array)
+ FREE (switch_buf_array);
trav = switch_buf;
while (trav) {
- GF_FREE (trav->array);
+ if (trav->array)
+ FREE (trav->array);
switch_opt = trav;
trav = trav->next;
- GF_FREE (switch_opt);
+ FREE (switch_opt);
}
}
return -1;
}
-int32_t
-switch_init (xlator_t *this)
+int
+init (xlator_t *this)
{
dht_conf_t *conf = NULL;
- data_t *data = NULL;
+ data_t *data = NULL;
+ char *temp_str = NULL;
int ret = -1;
+ int i = 0;
+ uint32_t temp_free_disk = 0;
+
+ if (!this->children) {
+ gf_log (this->name, GF_LOG_CRITICAL,
+ "SWITCH needs more than one subvolume");
+ return -1;
+ }
+
+ if (!this->parents) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "dangling volume. check volfile");
+ }
+
+ conf = CALLOC (1, sizeof (*conf));
+ if (!conf) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory");
+ goto err;
+ }
- ret = dht_init(this);
- if (ret) {
- return ret;
+ conf->search_unhashed = GF_DHT_LOOKUP_UNHASHED_AUTO;
+ if (dict_get_str (this->options, "lookup-unhashed", &temp_str) == 0) {
+ /* If option is not "auto", other options _should_ be boolean */
+ if (strcasecmp (temp_str, "auto"))
+ gf_string2boolean (temp_str, &conf->search_unhashed);
+ }
+
+ conf->unhashed_sticky_bit = 0;
+ if (dict_get_str (this->options, "unhashed-sticky-bit",
+ &temp_str) == 0) {
+ gf_string2boolean (temp_str, &conf->unhashed_sticky_bit);
+ }
+
+ conf->min_free_disk = 10;
+ conf->disk_unit = 'p';
+
+ 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;
+ conf->disk_unit = 'p';
+ }
+ } else {
+ gf_string2bytesize (temp_str,
+ &conf->min_free_disk);
+ conf->disk_unit = 'b';
+ }
}
- conf = this->private;
- data = dict_get (this->options, "pattern.switch.case");
- if (data) {
+ data = dict_get (this->options, "pattern.switch.case");
+ if (data) {
/* TODO: */
ret = set_switch_pattern (this, conf, data->data);
if (ret) {
goto err;
}
+ }
+
+ ret = dht_init_subvolumes (this, conf);
+ if (ret == -1) {
+ goto err;
+ }
+
+ ret = dht_layouts_init (this, conf);
+ if (ret == -1) {
+ goto err;
+ }
+
+ LOCK_INIT (&conf->subvolume_lock);
+ LOCK_INIT (&conf->layout_lock);
+
+ conf->gen = 1;
+
+ conf->du_stats = CALLOC (conf->subvolume_cnt, sizeof (dht_du_t));
+ if (!conf->du_stats) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory");
+ goto err;
}
this->private = conf;
+
return 0;
err:
- dht_fini(this);
+ if (conf) {
+ if (conf->file_layouts) {
+ for (i = 0; i < conf->subvolume_cnt; i++) {
+ FREE (conf->file_layouts[i]);
+ }
+ FREE (conf->file_layouts);
+ }
+
+ if (conf->default_dir_layout)
+ FREE (conf->default_dir_layout);
+
+ if (conf->subvolumes)
+ FREE (conf->subvolumes);
+
+ if (conf->subvolume_status)
+ FREE (conf->subvolume_status);
+
+ if (conf->du_stats)
+ FREE (conf->du_stats);
+
+ FREE (conf);
+ }
+
return -1;
}
-class_methods_t class_methods = {
- .init = switch_init,
- .fini = switch_fini,
- .reconfigure = dht_reconfigure,
- .notify = dht_notify
+struct xlator_fops fops = {
+ .lookup = switch_lookup,
+ .create = switch_create,
+ .mknod = switch_mknod,
+
+ .stat = dht_stat,
+ .fstat = dht_fstat,
+ .truncate = dht_truncate,
+ .ftruncate = dht_ftruncate,
+ .access = dht_access,
+ .readlink = dht_readlink,
+ .setxattr = dht_setxattr,
+ .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,
+ .fsyncdir = dht_fsyncdir,
+ .symlink = dht_symlink,
+ .unlink = dht_unlink,
+ .link = dht_link,
+ .mkdir = dht_mkdir,
+ .rmdir = dht_rmdir,
+ .rename = dht_rename,
+ .inodelk = dht_inodelk,
+ .finodelk = dht_finodelk,
+ .entrylk = dht_entrylk,
+ .fentrylk = dht_fentrylk,
+ .xattrop = dht_xattrop,
+ .fxattrop = dht_fxattrop,
+ .setattr = dht_setattr,
+#if 0
+ .setdents = dht_setdents,
+ .getdents = dht_getdents,
+ .checksum = dht_checksum,
+#endif
};
-struct xlator_fops fops = {
- .lookup = switch_lookup,
- .create = switch_create,
- .mknod = switch_mknod,
-
- .stat = dht_stat,
- .fstat = dht_fstat,
- .truncate = dht_truncate,
- .ftruncate = dht_ftruncate,
- .access = dht_access,
- .readlink = dht_readlink,
- .setxattr = dht_setxattr,
- .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,
- .fsyncdir = dht_fsyncdir,
- .symlink = dht_symlink,
- .unlink = dht_unlink,
- .link = dht_link,
- .mkdir = dht_mkdir,
- .rmdir = dht_rmdir,
- .rename = dht_rename,
- .inodelk = dht_inodelk,
- .finodelk = dht_finodelk,
- .entrylk = dht_entrylk,
- .fentrylk = dht_fentrylk,
- .xattrop = dht_xattrop,
- .fxattrop = dht_fxattrop,
- .setattr = dht_setattr,
+struct xlator_mops mops = {
};
struct xlator_cbks cbks = {
- .forget = dht_forget
+ .forget = dht_forget
+};
+
+
+struct volume_options options[] = {
+ { .key = {"lookup-unhashed"},
+ .value = {"auto", "yes", "no", "enable", "disable", "1", "0",
+ "on", "off"},
+ .type = GF_OPTION_TYPE_STR
+ },
+ { .key = {"pattern.switch.case"},
+ .type = GF_OPTION_TYPE_ANY
+ },
+ { .key = {"min-free-disk"},
+ .type = GF_OPTION_TYPE_PERCENT_OR_SIZET,
+ },
+ { .key = {NULL} },
};
diff --git a/xlators/cluster/dht/src/unittest/dht_layout_mock.c b/xlators/cluster/dht/src/unittest/dht_layout_mock.c
deleted file mode 100644
index aa19ddc575d..00000000000
--- a/xlators/cluster/dht/src/unittest/dht_layout_mock.c
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- Copyright (c) 2014 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 "xlator.h"
-#include "dht-common.h"
-#include "byte-order.h"
-
-int
-dht_hash_compute (xlator_t *this, int type, const char *name, uint32_t *hash_p)
-{
- return 0;
-}
-
-int
-dht_inode_ctx_layout_get (inode_t *inode, xlator_t *this, dht_layout_t **layout)
-{
- return 0;
-}
-
-int
-dht_inode_ctx_layout_set (inode_t *inode, xlator_t *this,
- dht_layout_t *layout_int)
-{
- return 0;
-}
-
-int
-dict_get_ptr (dict_t *this, char *key, void **ptr)
-{
- return 0;
-}
-
-int
-dict_get_ptr_and_len (dict_t *this, char *key, void **ptr, int *len)
-{
- return 0;
-}
-
-int _gf_log (const char *domain, const char *file,
- const char *function, int32_t line, gf_loglevel_t level,
- const char *fmt, ...)
-{
- return 0;
-}
-
-int _gf_log_callingfn (const char *domain, const char *file,
- const char *function, int32_t line, gf_loglevel_t level,
- const char *fmt, ...)
-{
- return 0;
-}
diff --git a/xlators/cluster/dht/src/unittest/dht_layout_unittest.c b/xlators/cluster/dht/src/unittest/dht_layout_unittest.c
deleted file mode 100644
index b5233d235d0..00000000000
--- a/xlators/cluster/dht/src/unittest/dht_layout_unittest.c
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- Copyright (c) 2008-2014 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 "dht-common.h"
-#include "logging.h"
-#include "xlator.h"
-
-#include <stdarg.h>
-#include <stddef.h>
-#include <setjmp.h>
-#include <inttypes.h>
-#include <cmockery/pbc.h>
-#include <cmockery/cmockery.h>
-
-/*
- * Helper functions
- */
-
-static xlator_t *
-helper_xlator_init(uint32_t num_types)
-{
- xlator_t *xl;
- int i, ret;
-
- REQUIRE(num_types > 0);
-
- xl = test_calloc(1, sizeof(xlator_t));
- assert_non_null(xl);
- xl->mem_acct.num_types = num_types;
- xl->mem_acct.rec = test_calloc(num_types, sizeof(struct mem_acct_rec));
- assert_non_null(xl->mem_acct.rec);
-
- xl->ctx = test_calloc(1, sizeof(glusterfs_ctx_t));
- assert_non_null(xl->ctx);
-
- for (i = 0; i < num_types; i++) {
- ret = LOCK_INIT(&(xl->mem_acct.rec[i].lock));
- assert_false(ret);
- }
-
- ENSURE(num_types == xl->mem_acct.num_types);
- ENSURE(NULL != xl);
-
- return xl;
-}
-
-static int
-helper_xlator_destroy(xlator_t *xl)
-{
- int i, ret;
-
- for (i = 0; i < xl->mem_acct.num_types; i++) {
- ret = LOCK_DESTROY(&(xl->mem_acct.rec[i].lock));
- assert_int_equal(ret, 0);
- }
-
- free(xl->mem_acct.rec);
- free(xl->ctx);
- free(xl);
- return 0;
-}
-
-/*
- * Unit tests
- */
-static void
-test_dht_layout_new(void **state)
-{
- xlator_t *xl;
- dht_layout_t *layout;
- dht_conf_t *conf;
- int cnt;
-
- expect_assert_failure(dht_layout_new(NULL, 0));
- expect_assert_failure(dht_layout_new((xlator_t *)0x12345, -1));
- xl = helper_xlator_init(10);
-
- // xl->private is NULL
- assert_null(xl->private);
- cnt = 100;
- layout = dht_layout_new(xl, cnt);
- assert_non_null(layout);
- assert_int_equal(layout->type, DHT_HASH_TYPE_DM);
- assert_int_equal(layout->cnt, cnt);
- assert_int_equal(layout->ref, 1);
- assert_int_equal(layout->gen, 0);
- assert_int_equal(layout->spread_cnt, 0);
- free(layout);
-
- // xl->private is not NULL
- cnt = 110;
- conf = (dht_conf_t *)test_calloc(1, sizeof(dht_conf_t));
- assert_non_null(conf);
- conf->dir_spread_cnt = 12345;
- conf->gen = -123;
- xl->private = conf;
-
- layout = dht_layout_new(xl, cnt);
- assert_non_null(layout);
- assert_int_equal(layout->type, DHT_HASH_TYPE_DM);
- assert_int_equal(layout->cnt, cnt);
- assert_int_equal(layout->ref, 1);
- assert_int_equal(layout->gen, conf->gen);
- assert_int_equal(layout->spread_cnt, conf->dir_spread_cnt);
- free(layout);
-
- free(conf);
- helper_xlator_destroy(xl);
-}
-
-int main(void) {
- const UnitTest tests[] = {
- unit_test(test_dht_layout_new),
- };
-
- return run_tests(tests, "xlator_dht_layout");
-}
diff --git a/xlators/cluster/ec/src/Makefile.am b/xlators/cluster/ec/src/Makefile.am
deleted file mode 100644
index e2a9330a944..00000000000
--- a/xlators/cluster/ec/src/Makefile.am
+++ /dev/null
@@ -1,49 +0,0 @@
-xlator_LTLIBRARIES = ec.la
-xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/cluster
-
-ec_sources := ec.c
-ec_sources += ec-data.c
-ec_sources += ec-helpers.c
-ec_sources += ec-common.c
-ec_sources += ec-generic.c
-ec_sources += ec-locks.c
-ec_sources += ec-dir-read.c
-ec_sources += ec-dir-write.c
-ec_sources += ec-inode-read.c
-ec_sources += ec-inode-write.c
-ec_sources += ec-combine.c
-ec_sources += ec-gf.c
-ec_sources += ec-method.c
-ec_sources += ec-heal.c
-
-ec_headers := ec.h
-ec_headers += ec-mem-types.h
-ec_headers += ec-helpers.h
-ec_headers += ec-data.h
-ec_headers += ec-fops.h
-ec_headers += ec-common.h
-ec_headers += ec-combine.h
-ec_headers += ec-gf.h
-ec_headers += ec-method.h
-
-ec_ext_sources = $(top_builddir)/xlators/lib/src/libxlator.c
-
-ec_ext_headers = $(top_builddir)/xlators/lib/src/libxlator.h
-
-ec_la_LDFLAGS = -module -avoid-version
-ec_la_SOURCES = $(ec_sources) $(ec_headers) $(ec_ext_sources) $(ec_ext_headers)
-ec_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la
-
-AM_CPPFLAGS = $(GF_CPPFLAGS)
-AM_CPPFLAGS += -I$(top_srcdir)/libglusterfs/src
-AM_CPPFLAGS += -I$(top_srcdir)/xlators/lib/src
-
-AM_CFLAGS = -Wall $(GF_CFLAGS)
-
-CLEANFILES =
-
-install-data-hook:
- ln -sf ec.so $(DESTDIR)$(xlatordir)/disperse.so
-
-uninstall-local:
- rm -f $(DESTDIR)$(xlatordir)/disperse.so
diff --git a/xlators/cluster/ec/src/ec-combine.c b/xlators/cluster/ec/src/ec-combine.c
deleted file mode 100644
index 0f883d03fac..00000000000
--- a/xlators/cluster/ec/src/ec-combine.c
+++ /dev/null
@@ -1,872 +0,0 @@
-/*
- Copyright (c) 2012-2014 DataLab, s.l. <http://www.datalab.es>
- 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 "libxlator.h"
-#include "byte-order.h"
-
-#include "ec-data.h"
-#include "ec-helpers.h"
-#include "ec-common.h"
-#include "ec-combine.h"
-
-#define EC_QUOTA_PREFIX "trusted.glusterfs.quota."
-
-struct _ec_dict_info;
-typedef struct _ec_dict_info ec_dict_info_t;
-
-struct _ec_dict_combine;
-typedef struct _ec_dict_combine ec_dict_combine_t;
-
-struct _ec_dict_info
-{
- dict_t * dict;
- int32_t count;
-};
-
-struct _ec_dict_combine
-{
- ec_cbk_data_t * cbk;
- int32_t which;
-};
-
-void ec_iatt_time_merge(uint32_t * dst_sec, uint32_t * dst_nsec,
- uint32_t src_sec, uint32_t src_nsec)
-{
- if ((*dst_sec < src_sec) ||
- ((*dst_sec == src_sec) && (*dst_nsec < src_nsec)))
- {
- *dst_sec = src_sec;
- *dst_nsec = src_nsec;
- }
-}
-
-int32_t ec_iatt_combine(struct iatt * dst, struct iatt * src, int32_t count)
-{
- int32_t i;
-
- for (i = 0; i < count; i++)
- {
- if ((dst->ia_ino != src->ia_ino) ||
- (dst->ia_uid != src->ia_uid) ||
- (dst->ia_gid != src->ia_gid) ||
- (((dst->ia_type == IA_IFBLK) || (dst->ia_type == IA_IFCHR)) &&
- (dst->ia_rdev != src->ia_rdev)) ||
- ((dst->ia_type == IA_IFREG) && (dst->ia_size != src->ia_size)) ||
- (st_mode_from_ia(dst->ia_prot, dst->ia_type) !=
- st_mode_from_ia(src->ia_prot, src->ia_type)) ||
- (uuid_compare(dst->ia_gfid, src->ia_gfid) != 0))
- {
- gf_log(THIS->name, GF_LOG_WARNING,
- "Failed to combine iatt (inode: %lu-%lu, links: %u-%u, "
- "uid: %u-%u, gid: %u-%u, rdev: %lu-%lu, size: %lu-%lu, "
- "mode: %o-%o)",
- dst->ia_ino, src->ia_ino, dst->ia_nlink, src->ia_nlink,
- dst->ia_uid, src->ia_uid, dst->ia_gid, src->ia_gid,
- dst->ia_rdev, src->ia_rdev, dst->ia_size, src->ia_size,
- st_mode_from_ia(dst->ia_prot, dst->ia_type),
- st_mode_from_ia(src->ia_prot, dst->ia_type));
-
- return 0;
- }
- }
-
- while (count-- > 0)
- {
- dst->ia_blocks += src->ia_blocks;
- if (dst->ia_blksize < src->ia_blksize)
- {
- dst->ia_blksize = src->ia_blksize;
- }
-
- ec_iatt_time_merge(&dst->ia_atime, &dst->ia_atime_nsec, src->ia_atime,
- src->ia_atime_nsec);
- ec_iatt_time_merge(&dst->ia_mtime, &dst->ia_mtime_nsec, src->ia_mtime,
- src->ia_mtime_nsec);
- ec_iatt_time_merge(&dst->ia_ctime, &dst->ia_ctime_nsec, src->ia_ctime,
- src->ia_ctime_nsec);
- }
-
- return 1;
-}
-
-void ec_iatt_rebuild(ec_t * ec, struct iatt * iatt, int32_t count,
- int32_t answers)
-{
- uint64_t blocks;
-
- while (count-- > 0)
- {
- blocks = iatt[count].ia_blocks * ec->fragments + answers - 1;
- blocks /= answers;
- iatt[count].ia_blocks = blocks;
- }
-}
-
-int32_t ec_dict_data_compare(dict_t * dict, char * key, data_t * value,
- void * arg)
-{
- ec_dict_info_t * info = arg;
- data_t * data;
-
- data = dict_get(info->dict, key);
- if (data == NULL)
- {
- gf_log("ec", GF_LOG_DEBUG, "key '%s' found only on one dict", key);
-
- return -1;
- }
-
- info->count--;
-
- if ((strcmp(key, GF_CONTENT_KEY) == 0) ||
- (strcmp(key, GF_XATTR_PATHINFO_KEY) == 0) ||
- (strcmp(key, GF_XATTR_USER_PATHINFO_KEY) == 0) ||
- (strcmp(key, GF_XATTR_LOCKINFO_KEY) == 0) ||
- (strcmp(key, GLUSTERFS_OPEN_FD_COUNT) == 0) ||
- (strncmp(key, GF_XATTR_CLRLK_CMD, strlen(GF_XATTR_CLRLK_CMD)) == 0) ||
- (strncmp(key, EC_QUOTA_PREFIX, strlen(EC_QUOTA_PREFIX)) == 0) ||
- (fnmatch(GF_XATTR_STIME_PATTERN, key, 0) == 0) ||
- (fnmatch(MARKER_XATTR_PREFIX ".*." XTIME, key, 0) == 0) ||
- (XATTR_IS_NODE_UUID(key)))
- {
- return 0;
- }
-
- if ((data->len != value->len) ||
- (memcmp(data->data, value->data, data->len) != 0))
- {
- gf_log("ec", GF_LOG_DEBUG, "key '%s' is different (size: %u, %u)",
- key, data->len, value->len);
-
- return -1;
- }
-
- return 0;
-}
-
-int32_t ec_dict_data_show(dict_t * dict, char * key, data_t * value,
- void * arg)
-{
- if (dict_get(arg, key) == NULL)
- {
- gf_log("ec", GF_LOG_DEBUG, "key '%s' found only on one dict", key);
- }
-
- return 0;
-}
-
-int32_t ec_dict_compare(dict_t * dict1, dict_t * dict2)
-{
- ec_dict_info_t info;
- dict_t * dict;
-
- if (dict1 != NULL)
- {
- info.dict = dict1;
- info.count = dict1->count;
- dict = dict2;
- }
- else if (dict2 != NULL)
- {
- info.dict = dict2;
- info.count = dict2->count;
- dict = dict1;
- }
- else
- {
- return 1;
- }
-
- if (dict != NULL)
- {
- if (dict_foreach(dict, ec_dict_data_compare, &info) != 0)
- {
- return 0;
- }
- }
-
- if (info.count != 0)
- {
- dict_foreach(info.dict, ec_dict_data_show, dict);
- }
-
- return (info.count == 0);
-}
-
-int32_t ec_dict_list(data_t ** list, int32_t * count, ec_cbk_data_t * cbk,
- int32_t which, char * key)
-{
- ec_cbk_data_t * ans;
- dict_t * dict;
- int32_t i, max;
-
- max = *count;
- i = 0;
- for (ans = cbk; ans != NULL; ans = ans->next)
- {
- if (i >= max)
- {
- gf_log(cbk->fop->xl->name, GF_LOG_ERROR, "Unexpected number of "
- "dictionaries");
-
- return 0;
- }
-
- dict = (which == EC_COMBINE_XDATA) ? ans->xdata : ans->dict;
- list[i] = dict_get(dict, key);
- if (list[i] == NULL)
- {
- gf_log(cbk->fop->xl->name, GF_LOG_ERROR, "Unexpected missing "
- "dictionary entry");
-
- return 0;
- }
-
- i++;
- }
-
- *count = i;
-
- return 1;
-}
-
-char * ec_concat_prepare(xlator_t * xl, char ** sep, char ** post,
- const char * fmt, va_list args)
-{
- char * str, * tmp;
- int32_t len;
-
- len = gf_vasprintf(&str, fmt, args);
- if (len < 0)
- {
- return NULL;
- }
-
- tmp = strchr(str, '{');
- if (tmp == NULL)
- {
- goto out;
- }
- *tmp++ = 0;
- *sep = tmp;
- tmp = strchr(tmp, '}');
- if (tmp == NULL)
- {
- goto out;
- }
- *tmp++ = 0;
- *post = tmp;
-
- return str;
-
-out:
- gf_log(xl->name, GF_LOG_ERROR, "Invalid concat format");
-
- GF_FREE(str);
-
- return NULL;
-}
-
-int32_t ec_dict_data_concat(const char * fmt, ec_cbk_data_t * cbk,
- int32_t which, char * key, ...)
-{
- data_t * data[cbk->count];
- char * str = NULL, * pre = NULL, * sep, * post;
- dict_t * dict;
- va_list args;
- int32_t i, num, len, prelen, postlen, seplen, tmp;
- int32_t ret = -1;
-
- num = cbk->count;
- if (!ec_dict_list(data, &num, cbk, which, key))
- {
- return -1;
- }
-
- va_start(args, key);
- pre = ec_concat_prepare(cbk->fop->xl, &sep, &post, fmt, args);
- va_end(args);
-
- if (pre == NULL)
- {
- return -1;
- }
-
- prelen = strlen(pre);
- seplen = strlen(sep);
- postlen = strlen(post);
-
- len = prelen + (num - 1) * seplen + postlen + 1;
- for (i = 0; i < num; i++)
- {
- len += data[i]->len - 1;
- }
-
- str = GF_MALLOC(len, gf_common_mt_char);
- if (str == NULL)
- {
- goto out;
- }
-
- memcpy(str, pre, prelen);
- len = prelen;
- for (i = 0; i < num; i++)
- {
- if (i > 0) {
- memcpy(str + len, sep, seplen);
- len += seplen;
- }
- tmp = data[i]->len - 1;
- memcpy(str + len, data[i]->data, tmp);
- len += tmp;
- }
- memcpy(str + len, post, postlen + 1);
-
- dict = (which == EC_COMBINE_XDATA) ? cbk->xdata : cbk->dict;
- if (dict_set_dynstr(dict, key, str) != 0)
- {
- goto out;
- }
-
- str = NULL;
-
- ret = 0;
-
-out:
- GF_FREE(str);
- GF_FREE(pre);
-
- return ret;
-}
-
-int32_t ec_dict_data_merge(ec_cbk_data_t * cbk, int32_t which, char * key)
-{
- data_t * data[cbk->count];
- dict_t * dict, * lockinfo, * tmp;
- char * ptr = NULL;
- int32_t i, num, len;
- int32_t ret = -1;
-
- num = cbk->count;
- if (!ec_dict_list(data, &num, cbk, which, key))
- {
- return -1;
- }
-
- lockinfo = dict_new();
- if (lockinfo == NULL)
- {
- return -1;
- }
-
- if (dict_unserialize(data[0]->data, data[0]->len, &lockinfo) != 0)
- {
- goto out;
- }
-
- for (i = 1; i < num; i++)
- {
- tmp = dict_new();
- if (tmp == NULL)
- {
- goto out;
- }
- if ((dict_unserialize(data[i]->data, data[i]->len, &tmp) != 0) ||
- (dict_copy(tmp, lockinfo) == NULL))
- {
- dict_unref(tmp);
-
- goto out;
- }
-
- dict_unref(tmp);
- }
-
- len = dict_serialized_length(lockinfo);
- if (len < 0)
- {
- goto out;
- }
- ptr = GF_MALLOC(len, gf_common_mt_char);
- if (ptr == NULL)
- {
- goto out;
- }
- if (dict_serialize(lockinfo, ptr) != 0)
- {
- goto out;
- }
- dict = (which == EC_COMBINE_XDATA) ? cbk->xdata : cbk->dict;
- if (dict_set_dynptr(dict, key, ptr, len) != 0)
- {
- goto out;
- }
-
- ptr = NULL;
-
- ret = 0;
-
-out:
- GF_FREE(ptr);
- dict_unref(lockinfo);
-
- return ret;
-}
-
-int32_t ec_dict_data_uuid(ec_cbk_data_t * cbk, int32_t which, char * key)
-{
- ec_cbk_data_t * ans, * min;
- dict_t * src, * dst;
- data_t * data;
-
- min = cbk;
- for (ans = cbk->next; ans != NULL; ans = ans->next)
- {
- if (ans->idx < min->idx)
- {
- min = ans;
- }
- }
-
- if (min != cbk)
- {
- src = (which == EC_COMBINE_XDATA) ? min->xdata : min->dict;
- dst = (which == EC_COMBINE_XDATA) ? cbk->xdata : cbk->dict;
-
- data = dict_get(src, key);
- if (data == NULL)
- {
- return -1;
- }
- if (dict_set(dst, key, data) != 0)
- {
- return -1;
- }
- }
-
- return 0;
-}
-
-int32_t ec_dict_data_max32(ec_cbk_data_t *cbk, int32_t which, char *key)
-{
- data_t * data[cbk->count];
- dict_t * dict;
- int32_t i, num;
- uint32_t max, tmp;
-
- num = cbk->count;
- if (!ec_dict_list(data, &num, cbk, which, key))
- {
- return -1;
- }
-
- if (num <= 1)
- {
- return 0;
- }
-
- max = data_to_uint32(data[0]);
- for (i = 1; i < num; i++)
- {
- tmp = data_to_uint32(data[i]);
- if (max < tmp)
- {
- max = tmp;
- }
- }
-
- dict = (which == EC_COMBINE_XDATA) ? cbk->xdata : cbk->dict;
- if (dict_set_uint32(dict, key, max) != 0)
- {
- return -1;
- }
-
- return 0;
-}
-
-int32_t ec_dict_data_max64(ec_cbk_data_t *cbk, int32_t which, char *key)
-{
- data_t *data[cbk->count];
- dict_t *dict;
- int32_t i, num;
- uint64_t max, tmp;
-
- num = cbk->count;
- if (!ec_dict_list(data, &num, cbk, which, key)) {
- return -1;
- }
-
- if (num <= 1) {
- return 0;
- }
-
- max = data_to_uint64(data[0]);
- for (i = 1; i < num; i++) {
- tmp = data_to_uint64(data[i]);
- if (max < tmp) {
- max = tmp;
- }
- }
-
- dict = (which == EC_COMBINE_XDATA) ? cbk->xdata : cbk->dict;
- if (dict_set_uint64(dict, key, max) != 0) {
- return -1;
- }
-
- return 0;
-}
-
-int32_t ec_dict_data_quota(ec_cbk_data_t *cbk, int32_t which, char *key)
-{
- data_t *data[cbk->count];
- dict_t *dict;
- ec_t *ec;
- int32_t i, num;
- uint64_t max, tmp;
-
- num = cbk->count;
- if (!ec_dict_list(data, &num, cbk, which, key)) {
- return -1;
- }
-
- if (num == 0) {
- return 0;
- }
-
- /* Quota size xattr is managed outside of the control of the ec xlator.
- * This means that it might not be updated at the same time on all
- * bricks and we can receive slightly different values. If that's the
- * case, we take the maximum of all received values.
- */
- max = ntoh64(*(uint64_t *)data_to_ptr(data[0]));
- for (i = 1; i < num; i++) {
- tmp = ntoh64(*(uint64_t *)data_to_ptr(data[i]));
- if (max < tmp) {
- max = tmp;
- }
- }
-
- ec = cbk->fop->xl->private;
- max *= ec->fragments;
-
- dict = (which == EC_COMBINE_XDATA) ? cbk->xdata : cbk->dict;
- if (ec_dict_set_number(dict, key, max) != 0) {
- return -1;
- }
-
- return 0;
-}
-
-int32_t ec_dict_data_stime(ec_cbk_data_t * cbk, int32_t which, char * key)
-{
- data_t * data[cbk->count];
- dict_t * dict;
- int32_t i, num;
-
- num = cbk->count;
- if (!ec_dict_list(data, &num, cbk, which, key))
- {
- return -1;
- }
-
- dict = (which == EC_COMBINE_XDATA) ? cbk->xdata : cbk->dict;
- for (i = 1; i < num; i++)
- {
- if (gf_get_max_stime(cbk->fop->xl, dict, key, data[i]) != 0)
- {
- gf_log(cbk->fop->xl->name, GF_LOG_ERROR, "STIME combination "
- "failed");
-
- return -1;
- }
- }
-
- return 0;
-}
-
-int32_t ec_dict_data_combine(dict_t * dict, char * key, data_t * value,
- void * arg)
-{
- ec_dict_combine_t * data = arg;
-
- if ((strcmp(key, GF_XATTR_PATHINFO_KEY) == 0) ||
- (strcmp(key, GF_XATTR_USER_PATHINFO_KEY) == 0))
- {
- return ec_dict_data_concat("(<EC:%s> { })", data->cbk, data->which,
- key, data->cbk->fop->xl->name);
- }
-
- if (strncmp(key, GF_XATTR_CLRLK_CMD, strlen(GF_XATTR_CLRLK_CMD)) == 0)
- {
- return ec_dict_data_concat("{\n}", data->cbk, data->which, key);
- }
-
- if (strncmp(key, GF_XATTR_LOCKINFO_KEY,
- strlen(GF_XATTR_LOCKINFO_KEY)) == 0)
- {
- return ec_dict_data_merge(data->cbk, data->which, key);
- }
-
- if (strcmp(key, GLUSTERFS_OPEN_FD_COUNT) == 0)
- {
- return ec_dict_data_max32(data->cbk, data->which, key);
- }
-
- if (strcmp(key, QUOTA_SIZE_KEY) == 0) {
- return ec_dict_data_quota(data->cbk, data->which, key);
- }
- /* Ignore all other quota attributes */
- if (strncmp(key, EC_QUOTA_PREFIX, strlen(EC_QUOTA_PREFIX)) == 0) {
- return 0;
- }
-
- if (XATTR_IS_NODE_UUID(key))
- {
- return ec_dict_data_uuid(data->cbk, data->which, key);
- }
-
- if (fnmatch(GF_XATTR_STIME_PATTERN, key, FNM_NOESCAPE) == 0)
- {
- return ec_dict_data_stime(data->cbk, data->which, key);
- }
-
- if (fnmatch(MARKER_XATTR_PREFIX ".*." XTIME, key, FNM_NOESCAPE) == 0) {
- return ec_dict_data_max64(data->cbk, data->which, key);
- }
-
- return 0;
-}
-
-int32_t ec_dict_combine(ec_cbk_data_t * cbk, int32_t which)
-{
- dict_t * dict;
- ec_dict_combine_t data;
-
- data.cbk = cbk;
- data.which = which;
-
- dict = (which == EC_COMBINE_XDATA) ? cbk->xdata : cbk->dict;
- if ((dict != NULL) &&
- (dict_foreach(dict, ec_dict_data_combine, &data) != 0))
- {
- gf_log(cbk->fop->xl->name, GF_LOG_ERROR, "Dictionary combination "
- "failed");
-
- return 0;
- }
-
- return 1;
-}
-
-int32_t ec_vector_compare(struct iovec * dst_vector, int32_t dst_count,
- struct iovec * src_vector, int32_t src_count)
-{
- int32_t dst_size = 0, src_size = 0;
-
- if (dst_count > 0)
- {
- dst_size = iov_length(dst_vector, dst_count);
- }
- if (src_count > 0)
- {
- src_size = iov_length(src_vector, src_count);
- }
-
- return (dst_size == src_size);
-}
-
-int32_t ec_flock_compare(struct gf_flock * dst, struct gf_flock * src)
-{
- if ((dst->l_type != src->l_type) ||
- (dst->l_whence != src->l_whence) ||
- (dst->l_start != src->l_start) ||
- (dst->l_len != src->l_len) ||
- (dst->l_pid != src->l_pid) ||
- !is_same_lkowner(&dst->l_owner, &src->l_owner))
- {
- return 0;
- }
-
- return 1;
-}
-
-void ec_statvfs_combine(struct statvfs * dst, struct statvfs * src)
-{
- if (dst->f_bsize < src->f_bsize)
- {
- dst->f_bsize = src->f_bsize;
- }
-
- if (dst->f_frsize < src->f_frsize)
- {
- dst->f_blocks *= dst->f_frsize;
- dst->f_blocks /= src->f_frsize;
-
- dst->f_bfree *= dst->f_frsize;
- dst->f_bfree /= src->f_frsize;
-
- dst->f_bavail *= dst->f_frsize;
- dst->f_bavail /= src->f_frsize;
-
- dst->f_frsize = src->f_frsize;
- }
- else if (dst->f_frsize > src->f_frsize)
- {
- src->f_blocks *= src->f_frsize;
- src->f_blocks /= dst->f_frsize;
-
- src->f_bfree *= src->f_frsize;
- src->f_bfree /= dst->f_frsize;
-
- src->f_bavail *= src->f_frsize;
- src->f_bavail /= dst->f_frsize;
- }
- if (dst->f_blocks > src->f_blocks)
- {
- dst->f_blocks = src->f_blocks;
- }
- if (dst->f_bfree > src->f_bfree)
- {
- dst->f_bfree = src->f_bfree;
- }
- if (dst->f_bavail > src->f_bavail)
- {
- dst->f_bavail = src->f_bavail;
- }
-
- if (dst->f_files < src->f_files)
- {
- dst->f_files = src->f_files;
- }
- if (dst->f_ffree > src->f_ffree)
- {
- dst->f_ffree = src->f_ffree;
- }
- if (dst->f_favail > src->f_favail)
- {
- dst->f_favail = src->f_favail;
- }
- if (dst->f_namemax > src->f_namemax)
- {
- dst->f_namemax = src->f_namemax;
- }
-
- if (dst->f_flag != src->f_flag)
- {
- gf_log(THIS->name, GF_LOG_DEBUG, "Mismatching file system flags "
- "(%lX, %lX)",
- dst->f_flag, src->f_flag);
- }
- dst->f_flag &= src->f_flag;
-}
-
-int32_t ec_combine_check(ec_cbk_data_t * dst, ec_cbk_data_t * src,
- ec_combine_f combine)
-{
- ec_fop_data_t * fop = dst->fop;
-
- if (dst->op_ret != src->op_ret)
- {
- gf_log(fop->xl->name, GF_LOG_DEBUG, "Mismatching return code in "
- "answers of '%s': %d <-> %d",
- ec_fop_name(fop->id), dst->op_ret, src->op_ret);
-
- return 0;
- }
- if (dst->op_ret < 0)
- {
- if (dst->op_errno != src->op_errno)
- {
- gf_log(fop->xl->name, GF_LOG_DEBUG, "Mismatching errno code in "
- "answers of '%s': %d <-> %d",
- ec_fop_name(fop->id), dst->op_errno, src->op_errno);
-
- return 0;
- }
- }
-
- if (!ec_dict_compare(dst->xdata, src->xdata))
- {
- gf_log(fop->xl->name, GF_LOG_WARNING, "Mismatching xdata in answers "
- "of '%s'",
- ec_fop_name(fop->id));
-
- return 0;
- }
-
- if ((dst->op_ret >= 0) && (combine != NULL))
- {
- return combine(fop, dst, src);
- }
-
- return 1;
-}
-
-void ec_combine(ec_cbk_data_t * cbk, ec_combine_f combine)
-{
- ec_fop_data_t * fop = cbk->fop;
- ec_cbk_data_t * ans = NULL, * tmp = NULL;
- struct list_head * item = NULL;
- int32_t needed = 0, resume = 0;
- char str[32];
-
- LOCK(&fop->lock);
-
- item = fop->cbk_list.prev;
- list_for_each_entry(ans, &fop->cbk_list, list)
- {
- if (ec_combine_check(cbk, ans, combine))
- {
- cbk->count += ans->count;
- cbk->mask |= ans->mask;
-
- item = ans->list.prev;
- while (item != &fop->cbk_list)
- {
- tmp = list_entry(item, ec_cbk_data_t, list);
- if (tmp->count >= cbk->count)
- {
- break;
- }
- item = item->prev;
- }
- list_del(&ans->list);
-
- cbk->next = ans;
-
- break;
- }
- }
- list_add(&cbk->list, item);
-
- ec_trace("ANSWER", fop, "combine=%s[%d]",
- ec_bin(str, sizeof(str), cbk->mask, 0), cbk->count);
-
- if ((cbk->count == fop->expected) && (fop->answer == NULL)) {
- fop->answer = cbk;
-
- resume = 1;
- }
-
- ans = list_entry(fop->cbk_list.next, ec_cbk_data_t, list);
- needed = fop->minimum - ans->count - fop->winds + 1;
-
- UNLOCK(&fop->lock);
-
- if (needed > 0) {
- ec_dispatch_next(fop, cbk->idx);
- } else if (resume) {
- ec_update_bad(fop, cbk->mask);
-
- ec_resume(fop, 0);
- }
-}
diff --git a/xlators/cluster/ec/src/ec-combine.h b/xlators/cluster/ec/src/ec-combine.h
deleted file mode 100644
index 360844ccd71..00000000000
--- a/xlators/cluster/ec/src/ec-combine.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- Copyright (c) 2012-2014 DataLab, s.l. <http://www.datalab.es>
- 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 __EC_COMBINE_H__
-#define __EC_COMBINE_H__
-
-#define EC_COMBINE_DICT 0
-#define EC_COMBINE_XDATA 1
-
-typedef int32_t (* ec_combine_f)(ec_fop_data_t * fop, ec_cbk_data_t * dst,
- ec_cbk_data_t * src);
-
-void ec_iatt_rebuild(ec_t * ec, struct iatt * iatt, int32_t count,
- int32_t answers);
-
-int32_t ec_iatt_combine(struct iatt * dst, struct iatt * src, int32_t count);
-int32_t ec_dict_compare(dict_t * dict1, dict_t * dict2);
-int32_t ec_vector_compare(struct iovec * dst_vector, int32_t dst_count,
- struct iovec * src_vector, int32_t src_count);
-int32_t ec_flock_compare(struct gf_flock * dst, struct gf_flock * src);
-void ec_statvfs_combine(struct statvfs * dst, struct statvfs * src);
-
-int32_t ec_dict_combine(ec_cbk_data_t * cbk, int32_t which);
-
-void ec_combine(ec_cbk_data_t * cbk, ec_combine_f combine);
-
-#endif /* __EC_COMBINE_H__ */
diff --git a/xlators/cluster/ec/src/ec-common.c b/xlators/cluster/ec/src/ec-common.c
deleted file mode 100644
index bf34206d00e..00000000000
--- a/xlators/cluster/ec/src/ec-common.c
+++ /dev/null
@@ -1,1516 +0,0 @@
-/*
- Copyright (c) 2012-2014 DataLab, s.l. <http://www.datalab.es>
- 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 "byte-order.h"
-
-#include "ec-mem-types.h"
-#include "ec-data.h"
-#include "ec-helpers.h"
-#include "ec-combine.h"
-#include "ec-common.h"
-#include "ec-fops.h"
-#include "ec-method.h"
-#include "ec.h"
-
-int32_t ec_child_valid(ec_t * ec, ec_fop_data_t * fop, int32_t idx)
-{
- return (idx < ec->nodes) && (((fop->remaining >> idx) & 1) == 1);
-}
-
-int32_t ec_child_next(ec_t * ec, ec_fop_data_t * fop, int32_t idx)
-{
- while (!ec_child_valid(ec, fop, idx))
- {
- if (++idx >= ec->nodes)
- {
- idx = 0;
- }
- if (idx == fop->first)
- {
- return -1;
- }
- }
-
- return idx;
-}
-
-uintptr_t ec_inode_good(inode_t * inode, xlator_t * xl)
-{
- ec_inode_t * ctx;
- uintptr_t bad = 0;
-
- ctx = ec_inode_get(inode, xl);
- if (ctx != NULL)
- {
- bad = ctx->bad;
- }
-
- return ~bad;
-}
-
-uintptr_t ec_fd_good(fd_t * fd, xlator_t * xl)
-{
- ec_fd_t * ctx;
- uintptr_t bad = 0;
-
- ctx = ec_fd_get(fd, xl);
- if (ctx != NULL)
- {
- bad = ctx->bad;
- }
-
- return ~bad;
-}
-
-uintptr_t ec_update_inode(ec_fop_data_t * fop, inode_t * inode, uintptr_t good,
- uintptr_t bad)
-{
- ec_inode_t * ctx = NULL;
-
- if (inode != NULL)
- {
- LOCK(&inode->lock);
-
- ctx = __ec_inode_get(inode, fop->xl);
- if (ctx != NULL)
- {
- ctx->bad &= ~good;
- bad |= ctx->bad;
- ctx->bad = bad;
- }
-
- UNLOCK(&inode->lock);
- }
-
- return bad;
-}
-
-uintptr_t ec_update_fd(ec_fop_data_t * fop, fd_t * fd, uintptr_t good,
- uintptr_t bad)
-{
- ec_fd_t * ctx = NULL;
-
- LOCK(&fd->lock);
-
- ctx = __ec_fd_get(fd, fop->xl);
- if (ctx != NULL)
- {
- ctx->bad &= ~good;
- bad |= ctx->bad;
- ctx->bad = bad;
- }
-
- UNLOCK(&fd->lock);
-
- return bad;
-}
-
-int32_t ec_heal_report(call_frame_t * frame, void * cookie, xlator_t * this,
- int32_t op_ret, int32_t op_errno, uintptr_t mask,
- uintptr_t good, uintptr_t bad, dict_t * xdata)
-{
- if (op_ret < 0) {
- gf_log(this->name, GF_LOG_WARNING, "Heal failed (error %d)",
- op_errno);
- } else {
- if ((mask & ~good) != 0) {
- gf_log(this->name, GF_LOG_INFO, "Heal succeeded on %d/%d "
- "subvolumes",
- ec_bits_count(mask & ~(good | bad)),
- ec_bits_count(mask & ~good));
- }
- }
-
- return 0;
-}
-
-int32_t ec_fop_needs_heal(ec_fop_data_t *fop)
-{
- ec_t *ec = fop->xl->private;
-
- return (ec->xl_up & ~(fop->remaining | fop->good)) != 0;
-}
-
-void ec_check_status(ec_fop_data_t * fop)
-{
- ec_t * ec = fop->xl->private;
- int32_t partial = 0;
-
- if (fop->answer->op_ret >= 0) {
- if ((fop->id == GF_FOP_LOOKUP) ||
- (fop->id == GF_FOP_STAT) || (fop->id == GF_FOP_FSTAT)) {
- partial = fop->answer->iatt[0].ia_type == IA_IFDIR;
- } else if (fop->id == GF_FOP_OPENDIR) {
- partial = 1;
- }
- }
-
- if (!ec_fop_needs_heal(fop)) {
- return;
- }
-
- gf_log(fop->xl->name, GF_LOG_WARNING, "Operation failed on some "
- "subvolumes (up=%lX, mask=%lX, "
- "remaining=%lX, good=%lX, bad=%lX)",
- ec->xl_up, fop->mask, fop->remaining, fop->good, fop->bad);
-
- if (fop->use_fd)
- {
- if (fop->fd != NULL) {
- ec_fheal(NULL, fop->xl, -1, EC_MINIMUM_ONE, ec_heal_report, NULL,
- fop->fd, partial, NULL);
- }
- }
- else
- {
- ec_heal(NULL, fop->xl, -1, EC_MINIMUM_ONE, ec_heal_report, NULL,
- &fop->loc[0], partial, NULL);
-
- if (fop->loc[1].inode != NULL)
- {
- ec_heal(NULL, fop->xl, -1, EC_MINIMUM_ONE, ec_heal_report, NULL,
- &fop->loc[1], partial, NULL);
- }
- }
-}
-
-void ec_update_bad(ec_fop_data_t * fop, uintptr_t good)
-{
- ec_t *ec = fop->xl->private;
- uintptr_t bad;
-
- bad = ec->xl_up & ~(fop->remaining | good);
- fop->bad |= bad;
- fop->good |= good;
-
- if (fop->parent == NULL)
- {
- if ((fop->flags & EC_FLAG_UPDATE_LOC_PARENT) != 0)
- {
- ec_update_inode(fop, fop->loc[0].parent, good, bad);
- }
- if ((fop->flags & EC_FLAG_UPDATE_LOC_INODE) != 0)
- {
- ec_update_inode(fop, fop->loc[0].inode, good, bad);
- }
- ec_update_inode(fop, fop->loc[1].inode, good, bad);
- if ((fop->flags & EC_FLAG_UPDATE_FD_INODE) != 0)
- {
- ec_update_inode(fop, fop->fd->inode, good, bad);
- }
- if ((fop->flags & EC_FLAG_UPDATE_FD) != 0)
- {
- ec_update_fd(fop, fop->fd, good, bad);
- }
-
- ec_check_status(fop);
- }
-}
-
-
-void __ec_fop_set_error(ec_fop_data_t * fop, int32_t error)
-{
- if ((error != 0) && (fop->error == 0))
- {
- fop->error = error;
- }
-}
-
-void ec_fop_set_error(ec_fop_data_t * fop, int32_t error)
-{
- LOCK(&fop->lock);
-
- __ec_fop_set_error(fop, error);
-
- UNLOCK(&fop->lock);
-}
-
-void ec_sleep(ec_fop_data_t *fop)
-{
- LOCK(&fop->lock);
-
- fop->refs++;
- fop->jobs++;
-
- UNLOCK(&fop->lock);
-}
-
-int32_t ec_check_complete(ec_fop_data_t * fop, ec_resume_f resume)
-{
- int32_t error = -1;
-
- LOCK(&fop->lock);
-
- GF_ASSERT(fop->resume == NULL);
-
- if (fop->jobs != 0)
- {
- ec_trace("WAIT", fop, "resume=%p", resume);
-
- fop->resume = resume;
- }
- else
- {
- error = fop->error;
- fop->error = 0;
- }
-
- UNLOCK(&fop->lock);
-
- return error;
-}
-
-void ec_wait_winds(ec_fop_data_t * fop)
-{
- LOCK(&fop->lock);
-
- if (fop->winds > 0)
- {
- fop->jobs++;
- fop->refs++;
-
- fop->flags |= EC_FLAG_WAITING_WINDS;
- }
-
- UNLOCK(&fop->lock);
-}
-
-void ec_resume(ec_fop_data_t * fop, int32_t error)
-{
- ec_resume_f resume = NULL;
-
- LOCK(&fop->lock);
-
- __ec_fop_set_error(fop, error);
-
- if (--fop->jobs == 0)
- {
- resume = fop->resume;
- fop->resume = NULL;
- if (resume != NULL)
- {
- ec_trace("RESUME", fop, "error=%d", error);
-
- if (fop->error != 0)
- {
- error = fop->error;
- }
- fop->error = 0;
- }
- }
-
- UNLOCK(&fop->lock);
-
- if (resume != NULL)
- {
- resume(fop, error);
- }
-
- ec_fop_data_release(fop);
-}
-
-void ec_resume_parent(ec_fop_data_t * fop, int32_t error)
-{
- ec_fop_data_t * parent;
-
- parent = fop->parent;
- if (parent != NULL)
- {
- ec_trace("RESUME_PARENT", fop, "error=%u", error);
- fop->parent = NULL;
- ec_resume(parent, error);
- }
-}
-
-void ec_complete(ec_fop_data_t * fop)
-{
- ec_cbk_data_t * cbk = NULL;
- int32_t resume = 0, update = 0;
-
- LOCK(&fop->lock);
-
- ec_trace("COMPLETE", fop, "");
-
- if (--fop->winds == 0) {
- if (fop->answer == NULL) {
- if (!list_empty(&fop->cbk_list)) {
- cbk = list_entry(fop->cbk_list.next, ec_cbk_data_t, list);
- if ((cbk->count >= fop->minimum) &&
- ((cbk->op_ret >= 0) || (cbk->op_errno != ENOTCONN))) {
- fop->answer = cbk;
-
- update = 1;
- }
- }
-
- resume = 1;
- }
- else if ((fop->flags & EC_FLAG_WAITING_WINDS) != 0)
- {
- resume = 1;
- }
- }
-
- UNLOCK(&fop->lock);
-
- /* ec_update_bad() locks inode->lock. This may cause deadlocks with
- fop->lock when used in another order. Since ec_update_bad() will not
- be called more than once for each fop, it can be called from outside
- the fop->lock locked region. */
- if (update) {
- ec_update_bad(fop, cbk->mask);
- }
-
- if (resume)
- {
- ec_resume(fop, 0);
- }
-
- ec_fop_data_release(fop);
-}
-
-int32_t ec_child_select(ec_fop_data_t * fop)
-{
- ec_t * ec = fop->xl->private;
- uintptr_t mask = 0;
- int32_t first = 0, num = 0;
-
- fop->mask &= ec->node_mask;
-
- mask = ec->xl_up;
- if (fop->parent == NULL)
- {
- if (fop->loc[0].inode != NULL) {
- mask &= ec_inode_good(fop->loc[0].inode, fop->xl);
- }
- if (fop->loc[1].inode != NULL) {
- mask &= ec_inode_good(fop->loc[1].inode, fop->xl);
- }
- if (fop->fd != NULL) {
- if (fop->fd->inode != NULL) {
- mask &= ec_inode_good(fop->fd->inode, fop->xl);
- }
- mask &= ec_fd_good(fop->fd, fop->xl);
- }
- }
- if ((fop->mask & ~mask) != 0)
- {
- gf_log(fop->xl->name, GF_LOG_WARNING, "Executing operation with "
- "some subvolumes unavailable "
- "(%lX)", fop->mask & ~mask);
-
- fop->mask &= mask;
- }
-
- switch (fop->minimum)
- {
- case EC_MINIMUM_ALL:
- fop->minimum = ec_bits_count(fop->mask);
- if (fop->minimum >= ec->fragments)
- {
- break;
- }
- case EC_MINIMUM_MIN:
- fop->minimum = ec->fragments;
- break;
- case EC_MINIMUM_ONE:
- fop->minimum = 1;
- }
-
- first = ec->idx;
- if (++first >= ec->nodes)
- {
- first = 0;
- }
- ec->idx = first;
-
- fop->remaining = fop->mask;
-
- ec_trace("SELECT", fop, "");
-
- num = ec_bits_count(fop->mask);
- if ((num < fop->minimum) && (num < ec->fragments))
- {
- gf_log(ec->xl->name, GF_LOG_ERROR, "Insufficient available childs "
- "for this request (have %d, need "
- "%d)", num, fop->minimum);
-
- return 0;
- }
-
- ec_sleep(fop);
-
- return 1;
-}
-
-int32_t ec_dispatch_next(ec_fop_data_t * fop, int32_t idx)
-{
- ec_t * ec = fop->xl->private;
-
- LOCK(&fop->lock);
-
- idx = ec_child_next(ec, fop, idx);
- if (idx >= 0)
- {
- fop->remaining ^= 1ULL << idx;
-
- ec_trace("EXECUTE", fop, "idx=%d", idx);
-
- fop->winds++;
- fop->refs++;
- }
-
- UNLOCK(&fop->lock);
-
- if (idx >= 0)
- {
- fop->wind(ec, fop, idx);
- }
-
- return idx;
-}
-
-void ec_dispatch_mask(ec_fop_data_t * fop, uintptr_t mask)
-{
- ec_t * ec = fop->xl->private;
- int32_t count, idx;
-
- count = ec_bits_count(mask);
-
- LOCK(&fop->lock);
-
- ec_trace("EXECUTE", fop, "mask=%lX", mask);
-
- fop->remaining ^= mask;
-
- fop->winds += count;
- fop->refs += count;
-
- UNLOCK(&fop->lock);
-
- idx = 0;
- while (mask != 0)
- {
- if ((mask & 1) != 0)
- {
- fop->wind(ec, fop, idx);
- }
- idx++;
- mask >>= 1;
- }
-}
-
-void ec_dispatch_start(ec_fop_data_t * fop)
-{
- fop->answer = NULL;
- fop->good = 0;
- fop->bad = 0;
-
- INIT_LIST_HEAD(&fop->cbk_list);
-
- if (fop->lock_count > 0)
- {
- ec_owner_copy(fop->frame, &fop->req_frame->root->lk_owner);
- }
-}
-
-void ec_dispatch_one(ec_fop_data_t * fop)
-{
- ec_t * ec = fop->xl->private;
-
- ec_dispatch_start(fop);
-
- if (ec_child_select(fop))
- {
- fop->expected = 1;
- fop->first = ec->idx;
-
- ec_dispatch_next(fop, fop->first);
- }
-}
-
-int32_t ec_dispatch_one_retry(ec_fop_data_t * fop, int32_t idx, int32_t op_ret,
- int32_t op_errno)
-{
- if ((op_ret < 0) && (op_errno == ENOTCONN))
- {
- return (ec_dispatch_next(fop, idx) >= 0);
- }
-
- return 0;
-}
-
-void ec_dispatch_inc(ec_fop_data_t * fop)
-{
- ec_dispatch_start(fop);
-
- if (ec_child_select(fop))
- {
- fop->expected = ec_bits_count(fop->remaining);
- fop->first = 0;
-
- ec_dispatch_next(fop, 0);
- }
-}
-
-void ec_dispatch_all(ec_fop_data_t * fop)
-{
- ec_dispatch_start(fop);
-
- if (ec_child_select(fop))
- {
- fop->expected = ec_bits_count(fop->remaining);
- fop->first = 0;
-
- ec_dispatch_mask(fop, fop->remaining);
- }
-}
-
-void ec_dispatch_min(ec_fop_data_t * fop)
-{
- ec_t * ec = fop->xl->private;
- uintptr_t mask;
- int32_t idx, count;
-
- ec_dispatch_start(fop);
-
- if (ec_child_select(fop))
- {
- fop->expected = count = ec->fragments;
- fop->first = ec->idx;
- idx = fop->first - 1;
- mask = 0;
- while (count-- > 0)
- {
- idx = ec_child_next(ec, fop, idx + 1);
- mask |= 1ULL << idx;
- }
-
- ec_dispatch_mask(fop, mask);
- }
-}
-
-ec_lock_t * ec_lock_allocate(xlator_t * xl, int32_t kind, loc_t * loc)
-{
- ec_t * ec = xl->private;
- ec_lock_t * lock;
-
- if ((loc->inode == NULL) ||
- (uuid_is_null(loc->gfid) && uuid_is_null(loc->inode->gfid)))
- {
- gf_log(xl->name, GF_LOG_ERROR, "Trying to lock based on an invalid "
- "inode");
-
- return NULL;
- }
-
- lock = mem_get0(ec->lock_pool);
- if (lock != NULL)
- {
- lock->kind = kind;
- lock->good_mask = -1ULL;
- INIT_LIST_HEAD(&lock->waiting);
- if (ec_loc_from_loc(xl, &lock->loc, loc) != 0)
- {
- mem_put(lock);
- lock = NULL;
- }
- }
-
- return lock;
-}
-
-void ec_lock_destroy(ec_lock_t * lock)
-{
- loc_wipe(&lock->loc);
-
- mem_put(lock);
-}
-
-int32_t ec_lock_compare(ec_lock_t * lock1, ec_lock_t * lock2)
-{
- return uuid_compare(lock1->loc.gfid, lock2->loc.gfid);
-}
-
-ec_lock_link_t *ec_lock_insert(ec_fop_data_t *fop, ec_lock_t *lock,
- int32_t update)
-{
- ec_lock_t *new_lock, *tmp;
- ec_lock_link_t *link = NULL;
- int32_t tmp_update;
-
- new_lock = lock;
- if ((fop->lock_count > 0) &&
- (ec_lock_compare(fop->locks[0].lock, new_lock) > 0))
- {
- tmp = fop->locks[0].lock;
- fop->locks[0].lock = new_lock;
- new_lock = tmp;
-
- tmp_update = fop->locks_update;
- fop->locks_update = update;
- update = tmp_update;
- }
- fop->locks[fop->lock_count].lock = new_lock;
- fop->locks[fop->lock_count].fop = fop;
-
- fop->locks_update |= update << fop->lock_count;
-
- fop->lock_count++;
-
- if (lock->timer != NULL) {
- link = lock->timer->data;
- ec_trace("UNLOCK_CANCELLED", link->fop, "lock=%p", lock);
- gf_timer_call_cancel(fop->xl->ctx, lock->timer);
- lock->timer = NULL;
- } else {
- lock->refs++;
- }
-
- return link;
-}
-
-void ec_lock_prepare_entry(ec_fop_data_t *fop, loc_t *loc, int32_t update)
-{
- ec_lock_t * lock = NULL;
- ec_inode_t * ctx = NULL;
- ec_lock_link_t *link = NULL;
- loc_t tmp;
-
- if ((fop->parent != NULL) || (fop->error != 0))
- {
- return;
- }
-
- /* update is only 0 for 'opendir', which needs to lock the entry pointed
- * by loc instead of its parent.
- */
- if (update)
- {
- if (ec_loc_parent(fop->xl, loc, &tmp) != 0) {
- ec_fop_set_error(fop, EIO);
-
- return;
- }
-
- /* If there's another lock, make sure that it's not the same. Otherwise
- * do not insert it.
- *
- * This can only happen on renames where source and target names are
- * in the same directory. */
- if ((fop->lock_count > 0) &&
- (fop->locks[0].lock->loc.inode == tmp.inode)) {
- goto wipe;
- }
- } else {
- if (ec_loc_from_loc(fop->xl, &tmp, loc) != 0) {
- ec_fop_set_error(fop, EIO);
-
- return;
- }
- }
-
- LOCK(&tmp.inode->lock);
-
- ctx = __ec_inode_get(tmp.inode, fop->xl);
- if (ctx == NULL)
- {
- __ec_fop_set_error(fop, EIO);
-
- goto unlock;
- }
-
- if (ctx->entry_lock != NULL)
- {
- lock = ctx->entry_lock;
- ec_trace("LOCK_ENTRYLK", fop, "lock=%p, inode=%p, path=%s"
- "Lock already acquired",
- lock, tmp.inode, tmp.path);
-
- goto insert;
- }
-
- lock = ec_lock_allocate(fop->xl, EC_LOCK_ENTRY, &tmp);
- if (lock == NULL)
- {
- __ec_fop_set_error(fop, EIO);
-
- goto unlock;
- }
-
- ec_trace("LOCK_CREATE", fop, "lock=%p", lock);
-
- lock->type = ENTRYLK_WRLCK;
-
- lock->plock = &ctx->entry_lock;
- ctx->entry_lock = lock;
-
-insert:
- link = ec_lock_insert(fop, lock, update);
-
-unlock:
- UNLOCK(&tmp.inode->lock);
-
-wipe:
- loc_wipe(&tmp);
-
- if (link != NULL) {
- ec_resume(link->fop, 0);
- }
-}
-
-void ec_lock_prepare_inode(ec_fop_data_t *fop, loc_t *loc, int32_t update)
-{
- ec_lock_link_t *link = NULL;
- ec_lock_t * lock;
- ec_inode_t * ctx;
-
- if ((fop->parent != NULL) || (fop->error != 0) || (loc->inode == NULL))
- {
- return;
- }
-
- LOCK(&loc->inode->lock);
-
- ctx = __ec_inode_get(loc->inode, fop->xl);
- if (ctx == NULL)
- {
- __ec_fop_set_error(fop, EIO);
-
- goto unlock;
- }
-
- if (ctx->inode_lock != NULL)
- {
- lock = ctx->inode_lock;
- ec_trace("LOCK_INODELK", fop, "lock=%p, inode=%p. Lock already "
- "acquired", lock, loc->inode);
-
- goto insert;
- }
-
- lock = ec_lock_allocate(fop->xl, EC_LOCK_INODE, loc);
- if (lock == NULL)
- {
- __ec_fop_set_error(fop, EIO);
-
- goto unlock;
- }
-
- ec_trace("LOCK_CREATE", fop, "lock=%p", lock);
-
- lock->flock.l_type = F_WRLCK;
- lock->flock.l_whence = SEEK_SET;
-
- lock->plock = &ctx->inode_lock;
- ctx->inode_lock = lock;
-
-insert:
- link = ec_lock_insert(fop, lock, update);
-
-unlock:
- UNLOCK(&loc->inode->lock);
-
- if (link != NULL) {
- ec_resume(link->fop, 0);
- }
-}
-
-void ec_lock_prepare_fd(ec_fop_data_t *fop, fd_t *fd, int32_t update)
-{
- loc_t loc;
-
- if ((fop->parent != NULL) || (fop->error != 0))
- {
- return;
- }
-
- if (ec_loc_from_fd(fop->xl, &loc, fd) == 0)
- {
- ec_lock_prepare_inode(fop, &loc, update);
-
- loc_wipe(&loc);
- }
- else
- {
- ec_fop_set_error(fop, EIO);
- }
-}
-
-int32_t ec_locked(call_frame_t * frame, void * cookie, xlator_t * this,
- int32_t op_ret, int32_t op_errno, dict_t * xdata)
-{
- ec_fop_data_t * fop = cookie;
- ec_lock_t * lock = NULL;
-
- if (op_ret >= 0)
- {
- lock = fop->data;
- lock->mask = fop->good;
- lock->acquired = 1;
-
- fop->parent->mask &= fop->good;
- fop->parent->locked++;
-
- ec_trace("LOCKED", fop->parent, "lock=%p", lock);
-
- ec_lock(fop->parent);
- }
- else
- {
- gf_log(this->name, GF_LOG_WARNING, "Failed to complete preop lock");
- }
-
- return 0;
-}
-
-void ec_lock(ec_fop_data_t * fop)
-{
- ec_lock_t * lock;
-
- while (fop->locked < fop->lock_count)
- {
- lock = fop->locks[fop->locked].lock;
-
- LOCK(&lock->loc.inode->lock);
-
- if (lock->owner != NULL)
- {
- ec_trace("LOCK_WAIT", fop, "lock=%p", lock);
-
- list_add_tail(&fop->locks[fop->locked].wait_list, &lock->waiting);
-
- ec_sleep(fop);
-
- UNLOCK(&lock->loc.inode->lock);
-
- break;
- }
- lock->owner = fop;
-
- UNLOCK(&lock->loc.inode->lock);
-
- if (!lock->acquired)
- {
- ec_owner_set(fop->frame, lock);
-
- if (lock->kind == EC_LOCK_ENTRY)
- {
- ec_trace("LOCK_ACQUIRE", fop, "lock=%p, inode=%p, path=%s",
- lock, lock->loc.inode, lock->loc.path);
-
- ec_entrylk(fop->frame, fop->xl, -1, EC_MINIMUM_ALL, ec_locked,
- lock, fop->xl->name, &lock->loc, NULL,
- ENTRYLK_LOCK, lock->type, NULL);
- }
- else
- {
- ec_trace("LOCK_ACQUIRE", fop, "lock=%p, inode=%p", lock,
- lock->loc.inode);
-
- ec_inodelk(fop->frame, fop->xl, -1, EC_MINIMUM_ALL, ec_locked,
- lock, fop->xl->name, &lock->loc, F_SETLKW,
- &lock->flock, NULL);
- }
-
- break;
- }
-
- ec_trace("LOCK_REUSE", fop, "lock=%p", lock);
-
- if (lock->have_size)
- {
- fop->pre_size = fop->post_size = lock->size;
- fop->have_size = 1;
- }
- fop->mask &= lock->good_mask;
-
- fop->locked++;
- }
-}
-
-int32_t ec_get_size_version_set(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)
-{
- ec_t * ec;
- ec_fop_data_t * fop = cookie;
- ec_inode_t * ctx;
- ec_lock_t *lock = NULL;
-
- if (op_ret >= 0)
- {
- if (buf->ia_type == IA_IFREG)
- {
- if (ec_dict_del_config(xdata, EC_XATTR_CONFIG, &fop->config) < 0)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to get a valid "
- "config");
-
- ec_fop_set_error(fop, EIO);
-
- return 0;
- }
- ec = this->private;
- if ((fop->config.version != EC_CONFIG_VERSION) ||
- (fop->config.algorithm != EC_CONFIG_ALGORITHM) ||
- (fop->config.gf_word_size != EC_GF_BITS) ||
- (fop->config.bricks != ec->nodes) ||
- (fop->config.redundancy != ec->redundancy) ||
- (fop->config.chunk_size != EC_METHOD_CHUNK_SIZE))
- {
- uint32_t data_bricks;
-
- // This combination of version/algorithm requires the following
- // values. Incorrect values for these fields are a sign of
- // corruption:
- //
- // redundancy > 0
- // redundancy * 2 < bricks
- // gf_word_size must be a power of 2
- // chunk_size (in bits) must be a multiple of gf_word_size *
- // (bricks - redundancy)
-
- data_bricks = fop->config.bricks - fop->config.redundancy;
- if ((fop->config.redundancy < 1) ||
- (fop->config.redundancy * 2 >= fop->config.bricks) ||
- !ec_is_power_of_2(fop->config.gf_word_size) ||
- ((fop->config.chunk_size * 8) % (fop->config.gf_word_size *
- data_bricks) != 0))
- {
- gf_log(this->name, GF_LOG_ERROR, "Invalid or corrupted "
- "config (V=%u, A=%u, "
- "W=%u, N=%u, R=%u, S=%u)",
- fop->config.version, fop->config.algorithm,
- fop->config.gf_word_size, fop->config.bricks,
- fop->config.redundancy, fop->config.chunk_size);
- }
- else
- {
- gf_log(this->name, GF_LOG_ERROR, "Unsupported config "
- "(V=%u, A=%u, W=%u, "
- "N=%u, R=%u, S=%u)",
- fop->config.version, fop->config.algorithm,
- fop->config.gf_word_size, fop->config.bricks,
- fop->config.redundancy, fop->config.chunk_size);
- }
-
- ec_fop_set_error(fop, EIO);
-
- return 0;
- }
- }
-
- LOCK(&inode->lock);
-
- ctx = __ec_inode_get(inode, this);
- if (ctx != NULL) {
- if (ctx->inode_lock != NULL) {
- lock = ctx->inode_lock;
- lock->version = fop->answer->version;
-
- if (buf->ia_type == IA_IFREG) {
- lock->have_size = 1;
- lock->size = buf->ia_size;
- }
- }
- if (ctx->entry_lock != NULL) {
- lock = ctx->entry_lock;
- lock->version = fop->answer->version;
- }
- }
-
- UNLOCK(&inode->lock);
-
- if (lock != NULL)
- {
- // Only update parent mask if the lookup has been made with
- // inode locked.
- fop->parent->mask &= fop->good;
- }
-
- if (buf->ia_type == IA_IFREG) {
- fop->parent->pre_size = fop->parent->post_size = buf->ia_size;
- fop->parent->have_size = 1;
- }
- }
- else
- {
- gf_log(this->name, GF_LOG_WARNING, "Failed to get size and version "
- "(error %d)", op_errno);
- ec_fop_set_error(fop, op_errno);
- }
-
- return 0;
-}
-
-void ec_get_size_version(ec_fop_data_t * fop)
-{
- loc_t loc;
- dict_t * xdata;
- uid_t uid;
- gid_t gid;
- int32_t error = ENOMEM;
-
- if (fop->have_size)
- {
- return;
- }
-
- if ((fop->parent != NULL) && fop->parent->have_size)
- {
- fop->pre_size = fop->parent->pre_size;
- fop->post_size = fop->parent->post_size;
-
- fop->have_size = 1;
-
- return;
- }
-
- memset(&loc, 0, sizeof(loc));
-
- xdata = dict_new();
- if (xdata == NULL)
- {
- goto out;
- }
- if ((dict_set_uint64(xdata, EC_XATTR_VERSION, 0) != 0) ||
- (dict_set_uint64(xdata, EC_XATTR_SIZE, 0) != 0) ||
- (dict_set_uint64(xdata, EC_XATTR_CONFIG, 0) != 0))
- {
- goto out;
- }
-
- uid = fop->frame->root->uid;
- gid = fop->frame->root->gid;
-
- fop->frame->root->uid = 0;
- fop->frame->root->gid = 0;
-
- error = EIO;
-
- if (!fop->use_fd)
- {
- if (ec_loc_from_loc(fop->xl, &loc, &fop->loc[0]) != 0)
- {
- goto out;
- }
- if (uuid_is_null(loc.pargfid))
- {
- if (loc.parent != NULL)
- {
- inode_unref(loc.parent);
- loc.parent = NULL;
- }
- GF_FREE((char *)loc.path);
- loc.path = NULL;
- loc.name = NULL;
- }
- } else if (ec_loc_from_fd(fop->xl, &loc, fop->fd) != 0) {
- goto out;
- }
-
- /* For normal fops, ec_lookup() must succeed on at least EC_MINIMUM_MIN
- * bricks, however when this is called as part of a self-heal operation
- * the mask of target bricks (fop->mask) could contain less than
- * EC_MINIMUM_MIN bricks, causing the lookup to always fail. Thus we
- * always use the same minimum used for the main fop.
- */
- ec_lookup(fop->frame, fop->xl, fop->mask, fop->minimum,
- ec_get_size_version_set, NULL, &loc, xdata);
-
- fop->frame->root->uid = uid;
- fop->frame->root->gid = gid;
-
- error = 0;
-
-out:
- loc_wipe(&loc);
-
- if (xdata != NULL)
- {
- dict_unref(xdata);
- }
-
- ec_fop_set_error(fop, error);
-}
-
-int32_t ec_unlocked(call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
-{
- ec_fop_data_t *fop = cookie;
-
- if (op_ret < 0) {
- gf_log(this->name, GF_LOG_WARNING, "entry/inode unlocking failed (%s)",
- ec_fop_name(fop->parent->id));
- } else {
- ec_trace("UNLOCKED", fop->parent, "lock=%p", fop->data);
- }
-
- return 0;
-}
-
-void ec_unlock_lock(ec_fop_data_t *fop, ec_lock_t *lock)
-{
- if ((lock->mask != 0) && lock->acquired) {
- ec_owner_set(fop->frame, lock);
-
- switch (lock->kind) {
- case EC_LOCK_ENTRY:
- ec_trace("UNLOCK_ENTRYLK", fop, "lock=%p, inode=%p, path=%s", lock,
- lock->loc.inode, lock->loc.path);
-
- ec_entrylk(fop->frame, fop->xl, lock->mask, EC_MINIMUM_ALL,
- ec_unlocked, lock, fop->xl->name, &lock->loc, NULL,
- ENTRYLK_UNLOCK, lock->type, NULL);
-
- break;
-
- case EC_LOCK_INODE:
- lock->flock.l_type = F_UNLCK;
- ec_trace("UNLOCK_INODELK", fop, "lock=%p, inode=%p", lock,
- lock->loc.inode);
-
- ec_inodelk(fop->frame, fop->xl, lock->mask, EC_MINIMUM_ALL,
- ec_unlocked, lock, fop->xl->name, &lock->loc, F_SETLK,
- &lock->flock, NULL);
-
- break;
-
- default:
- gf_log(fop->xl->name, GF_LOG_ERROR, "Invalid lock type");
- }
- }
-
- ec_trace("LOCK_DESTROY", fop, "lock=%p", lock);
-
- ec_lock_destroy(lock);
-}
-
-int32_t ec_update_size_version_done(call_frame_t * frame, void * cookie,
- xlator_t * this, int32_t op_ret,
- int32_t op_errno, dict_t * xattr,
- dict_t * xdata)
-{
- ec_fop_data_t * fop = cookie;
-
- if (op_ret < 0)
- {
- gf_log(fop->xl->name, GF_LOG_ERROR, "Failed to update version and "
- "size (error %d)", op_errno);
- }
- else
- {
- fop->parent->mask &= fop->good;
- }
-
- if (fop->data != NULL) {
- ec_unlock_lock(fop->parent, fop->data);
- }
-
- return 0;
-}
-
-void ec_update_size_version(ec_fop_data_t *fop, loc_t *loc, uint64_t version,
- uint64_t size, ec_lock_t *lock)
-{
- dict_t * dict;
- uid_t uid;
- gid_t gid;
-
- if (fop->parent != NULL)
- {
- fop->parent->post_size = fop->post_size;
-
- return;
- }
-
- ec_trace("UPDATE", fop, "version=%ld, size=%ld", version, size);
-
- dict = dict_new();
- if (dict == NULL)
- {
- goto out;
- }
-
- if (ec_dict_set_number(dict, EC_XATTR_VERSION, version) != 0)
- {
- goto out;
- }
- if (size != 0)
- {
- if (ec_dict_set_number(dict, EC_XATTR_SIZE, size) != 0)
- {
- goto out;
- }
- }
-
- uid = fop->frame->root->uid;
- gid = fop->frame->root->gid;
-
- fop->frame->root->uid = 0;
- fop->frame->root->gid = 0;
-
- ec_xattrop(fop->frame, fop->xl, fop->mask, EC_MINIMUM_MIN,
- ec_update_size_version_done, lock, loc,
- GF_XATTROP_ADD_ARRAY64, dict, NULL);
-
- fop->frame->root->uid = uid;
- fop->frame->root->gid = gid;
-
- dict_unref(dict);
-
- return;
-
-out:
- if (dict != NULL)
- {
- dict_unref(dict);
- }
-
- ec_fop_set_error(fop, EIO);
-
- gf_log(fop->xl->name, GF_LOG_ERROR, "Unable to update version and size");
-}
-
-void ec_unlock_now(ec_fop_data_t *fop, ec_lock_t *lock)
-{
- ec_trace("UNLOCK_NOW", fop, "lock=%p", lock);
-
- if (lock->version_delta != 0) {
- ec_update_size_version(fop, &lock->loc, lock->version_delta,
- lock->size_delta, lock);
- } else {
- ec_unlock_lock(fop, lock);
- }
-
- ec_resume(fop, 0);
-}
-
-void ec_unlock_timer_cbk(void *data)
-{
- ec_lock_link_t *link = data;
- ec_lock_t *lock = link->lock;
- ec_fop_data_t *fop = NULL;
-
- LOCK(&lock->loc.inode->lock);
-
- if (lock->timer != NULL) {
- fop = link->fop;
-
- ec_trace("UNLOCK_DELAYED", fop, "lock=%p", lock);
-
- GF_ASSERT(lock->refs == 1);
-
- gf_timer_call_cancel(fop->xl->ctx, lock->timer);
- lock->timer = NULL;
- *lock->plock = NULL;
- }
-
- UNLOCK(&lock->loc.inode->lock);
-
- if (fop != NULL) {
- ec_unlock_now(fop, lock);
- }
-}
-
-void ec_unlock_timer_add(ec_lock_link_t *link)
-{
- struct timespec delay;
- ec_fop_data_t *fop = link->fop;
- ec_lock_t *lock = link->lock;
- int32_t refs = 1;
-
- LOCK(&lock->loc.inode->lock);
-
- GF_ASSERT(lock->timer == NULL);
-
- if (lock->refs != 1) {
- ec_trace("UNLOCK_SKIP", fop, "lock=%p", lock);
-
- lock->refs--;
-
- UNLOCK(&lock->loc.inode->lock);
- } else if (lock->acquired) {
- ec_sleep(fop);
-
- /* If healing is needed, do not delay lock release to let self-heal
- * start working as soon as possible. */
- if (!ec_fop_needs_heal(fop)) {
- ec_trace("UNLOCK_DELAY", fop, "lock=%p", lock);
-
- delay.tv_sec = 1;
- delay.tv_nsec = 0;
- lock->timer = gf_timer_call_after(fop->xl->ctx, delay,
- ec_unlock_timer_cbk, link);
- if (lock->timer == NULL) {
- gf_log(fop->xl->name, GF_LOG_WARNING, "Unable to delay an "
- "unlock");
-
- *lock->plock = NULL;
- refs = 0;
- }
- } else {
- ec_trace("UNLOCK_FORCE", fop, "lock=%p", lock);
- *lock->plock = NULL;
- refs = 0;
- }
-
- UNLOCK(&lock->loc.inode->lock);
-
- if (refs == 0) {
- ec_unlock_now(fop, lock);
- }
- } else {
- *lock->plock = NULL;
-
- UNLOCK(&lock->loc.inode->lock);
-
- ec_lock_destroy(lock);
- }
-}
-
-void ec_unlock(ec_fop_data_t *fop)
-{
- int32_t i;
-
- for (i = 0; i < fop->lock_count; i++) {
- ec_unlock_timer_add(&fop->locks[i]);
- }
-}
-
-void ec_flush_size_version(ec_fop_data_t * fop)
-{
- ec_lock_t * lock;
- uint64_t version, delta;
-
- GF_ASSERT(fop->lock_count == 1);
-
- lock = fop->locks[0].lock;
-
- LOCK(&lock->loc.inode->lock);
-
- GF_ASSERT(lock->owner == fop);
-
- version = lock->version_delta;
- delta = lock->size_delta;
- lock->version_delta = 0;
- lock->size_delta = 0;
-
- UNLOCK(&lock->loc.inode->lock);
-
- if (version > 0)
- {
- ec_update_size_version(fop, &lock->loc, version, delta, NULL);
- }
-}
-
-void ec_lock_reuse(ec_fop_data_t *fop)
-{
- ec_fop_data_t * wait_fop;
- ec_lock_t * lock;
- ec_lock_link_t * link;
- int32_t i;
-
- for (i = 0; i < fop->lock_count; i++)
- {
- wait_fop = NULL;
-
- lock = fop->locks[i].lock;
-
- LOCK(&lock->loc.inode->lock);
-
- ec_trace("LOCK_DONE", fop, "lock=%p", lock);
-
- GF_ASSERT(lock->owner == fop);
- lock->owner = NULL;
-
- if (((fop->locks_update >> i) & 1) != 0) {
- if (fop->error == 0)
- {
- lock->version_delta++;
- lock->size_delta += fop->post_size - fop->pre_size;
- if (fop->have_size) {
- lock->size = fop->post_size;
- lock->have_size = 1;
- }
- }
- }
-
- lock->good_mask &= fop->mask;
-
- if (!list_empty(&lock->waiting))
- {
- link = list_entry(lock->waiting.next, ec_lock_link_t, wait_list);
- list_del_init(&link->wait_list);
-
- wait_fop = link->fop;
-
- if (lock->kind == EC_LOCK_INODE)
- {
- wait_fop->pre_size = wait_fop->post_size = fop->post_size;
- wait_fop->have_size = fop->have_size;
- }
- wait_fop->mask &= fop->mask;
- }
-
- UNLOCK(&lock->loc.inode->lock);
-
- if (wait_fop != NULL)
- {
- ec_lock(wait_fop);
-
- ec_resume(wait_fop, 0);
- }
- }
-}
-
-void __ec_manager(ec_fop_data_t * fop, int32_t error)
-{
- ec_t *ec = fop->xl->private;
-
- do {
- ec_trace("MANAGER", fop, "error=%d", error);
-
- if (ec->xl_up_count < ec->fragments) {
- error = ENOTCONN;
- }
- if (error != 0) {
- fop->error = error;
- fop->state = -fop->state;
- }
-
- if ((fop->state == EC_STATE_END) || (fop->state == -EC_STATE_END)) {
- ec_fop_data_release(fop);
-
- break;
- }
-
- fop->state = fop->handler(fop, fop->state);
-
- error = ec_check_complete(fop, __ec_manager);
- } while (error >= 0);
-}
-
-void ec_manager(ec_fop_data_t * fop, int32_t error)
-{
- GF_ASSERT(fop->jobs == 0);
- GF_ASSERT(fop->winds == 0);
- GF_ASSERT(fop->error == 0);
-
- if (fop->state == EC_STATE_START)
- {
- fop->state = EC_STATE_INIT;
- }
-
- __ec_manager(fop, error);
-}
diff --git a/xlators/cluster/ec/src/ec-common.h b/xlators/cluster/ec/src/ec-common.h
deleted file mode 100644
index 2b1d9574cdf..00000000000
--- a/xlators/cluster/ec/src/ec-common.h
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- Copyright (c) 2012-2014 DataLab, s.l. <http://www.datalab.es>
- 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 __EC_COMMON_H__
-#define __EC_COMMON_H__
-
-#include "xlator.h"
-
-#include "ec-data.h"
-
-#define EC_CONFIG_VERSION 0
-
-#define EC_CONFIG_ALGORITHM 0
-
-#define EC_FLAG_UPDATE_LOC_PARENT 0x0001
-#define EC_FLAG_UPDATE_LOC_INODE 0x0002
-#define EC_FLAG_UPDATE_FD 0x0004
-#define EC_FLAG_UPDATE_FD_INODE 0x0008
-
-#define EC_FLAG_WAITING_WINDS 0x0010
-
-#define EC_MINIMUM_ONE -1
-#define EC_MINIMUM_MIN -2
-#define EC_MINIMUM_ALL -3
-
-#define EC_LOCK_ENTRY 0
-#define EC_LOCK_INODE 1
-
-#define EC_STATE_START 0
-#define EC_STATE_END 0
-#define EC_STATE_INIT 1
-#define EC_STATE_LOCK 2
-#define EC_STATE_GET_SIZE_AND_VERSION 3
-#define EC_STATE_DISPATCH 4
-#define EC_STATE_PREPARE_ANSWER 5
-#define EC_STATE_REPORT 6
-#define EC_STATE_LOCK_REUSE 7
-#define EC_STATE_UNLOCK 8
-
-#define EC_STATE_DELAYED_START 100
-
-#define EC_STATE_HEAL_ENTRY_LOOKUP 200
-#define EC_STATE_HEAL_ENTRY_PREPARE 201
-#define EC_STATE_HEAL_PRE_INODELK_LOCK 202
-#define EC_STATE_HEAL_PRE_INODE_LOOKUP 203
-#define EC_STATE_HEAL_XATTRIBUTES_REMOVE 204
-#define EC_STATE_HEAL_XATTRIBUTES_SET 205
-#define EC_STATE_HEAL_ATTRIBUTES 206
-#define EC_STATE_HEAL_OPEN 207
-#define EC_STATE_HEAL_REOPEN_FD 208
-#define EC_STATE_HEAL_UNLOCK 209
-#define EC_STATE_HEAL_UNLOCK_ENTRY 210
-#define EC_STATE_HEAL_DATA_LOCK 211
-#define EC_STATE_HEAL_DATA_COPY 212
-#define EC_STATE_HEAL_DATA_UNLOCK 213
-#define EC_STATE_HEAL_POST_INODELK_LOCK 214
-#define EC_STATE_HEAL_POST_INODE_LOOKUP 215
-#define EC_STATE_HEAL_SETATTR 216
-#define EC_STATE_HEAL_POST_INODELK_UNLOCK 217
-#define EC_STATE_HEAL_DISPATCH 218
-
-int32_t ec_dispatch_one_retry(ec_fop_data_t * fop, int32_t idx, int32_t op_ret,
- int32_t op_errno);
-int32_t ec_dispatch_next(ec_fop_data_t * fop, int32_t idx);
-
-void ec_complete(ec_fop_data_t * fop);
-
-void ec_update_bad(ec_fop_data_t * fop, uintptr_t good);
-
-void ec_fop_set_error(ec_fop_data_t * fop, int32_t error);
-
-void ec_lock_prepare_inode(ec_fop_data_t *fop, loc_t *loc, int32_t update);
-void ec_lock_prepare_entry(ec_fop_data_t *fop, loc_t *loc, int32_t update);
-void ec_lock_prepare_fd(ec_fop_data_t *fop, fd_t *fd, int32_t update);
-void ec_lock(ec_fop_data_t * fop);
-void ec_lock_reuse(ec_fop_data_t *fop);
-void ec_unlock(ec_fop_data_t * fop);
-
-void ec_get_size_version(ec_fop_data_t * fop);
-void ec_flush_size_version(ec_fop_data_t * fop);
-
-void ec_dispatch_all(ec_fop_data_t * fop);
-void ec_dispatch_inc(ec_fop_data_t * fop);
-void ec_dispatch_min(ec_fop_data_t * fop);
-void ec_dispatch_one(ec_fop_data_t * fop);
-
-void ec_wait_winds(ec_fop_data_t * fop);
-
-void ec_sleep(ec_fop_data_t *fop);
-void ec_resume(ec_fop_data_t * fop, int32_t error);
-void ec_resume_parent(ec_fop_data_t * fop, int32_t error);
-
-void ec_manager(ec_fop_data_t * fop, int32_t error);
-
-#endif /* __EC_COMMON_H__ */
diff --git a/xlators/cluster/ec/src/ec-data.c b/xlators/cluster/ec/src/ec-data.c
deleted file mode 100644
index fb47aea90a8..00000000000
--- a/xlators/cluster/ec/src/ec-data.c
+++ /dev/null
@@ -1,250 +0,0 @@
-/*
- Copyright (c) 2012-2014 DataLab, s.l. <http://www.datalab.es>
- 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 "ec-mem-types.h"
-#include "ec-helpers.h"
-#include "ec-common.h"
-#include "ec-data.h"
-
-ec_cbk_data_t * ec_cbk_data_allocate(call_frame_t * frame, xlator_t * this,
- ec_fop_data_t * fop, int32_t id,
- int32_t idx, int32_t op_ret,
- int32_t op_errno)
-{
- ec_cbk_data_t * cbk;
- ec_t * ec = this->private;
-
- if (fop->xl != this)
- {
- gf_log(this->name, GF_LOG_ERROR, "Mismatching xlators between request "
- "and answer (req=%s, ans=%s).",
- fop->xl->name, this->name);
-
- return NULL;
- }
- if (fop->frame != frame)
- {
- gf_log(this->name, GF_LOG_ERROR, "Mismatching frames between request "
- "and answer (req=%p, ans=%p).",
- fop->frame, frame);
-
- return NULL;
- }
- if (fop->id != id)
- {
- gf_log(this->name, GF_LOG_ERROR, "Mismatching fops between request "
- "and answer (req=%d, ans=%d).",
- fop->id, id);
-
- return NULL;
- }
-
- cbk = mem_get0(ec->cbk_pool);
- if (cbk == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to allocate memory for an "
- "answer.");
- }
-
- cbk->fop = fop;
- cbk->idx = idx;
- cbk->mask = 1ULL << idx;
- cbk->count = 1;
- cbk->op_ret = op_ret;
- cbk->op_errno = op_errno;
-
- LOCK(&fop->lock);
-
- list_add_tail(&cbk->answer_list, &fop->answer_list);
-
- UNLOCK(&fop->lock);
-
- return cbk;
-}
-
-void ec_cbk_data_destroy(ec_cbk_data_t * cbk)
-{
- if (cbk->xdata != NULL)
- {
- dict_unref(cbk->xdata);
- }
- if (cbk->dict != NULL)
- {
- dict_unref(cbk->dict);
- }
- if (cbk->inode != NULL)
- {
- inode_unref(cbk->inode);
- }
- if (cbk->fd != NULL)
- {
- fd_unref(cbk->fd);
- }
- if (cbk->buffers != NULL)
- {
- iobref_unref(cbk->buffers);
- }
- GF_FREE(cbk->vector);
-
- mem_put(cbk);
-}
-
-ec_fop_data_t * ec_fop_data_allocate(call_frame_t * frame, xlator_t * this,
- int32_t id, uint32_t flags,
- uintptr_t target, int32_t minimum,
- ec_wind_f wind, ec_handler_f handler,
- ec_cbk_t cbks, void * data)
-{
- ec_fop_data_t * fop, * parent;
- ec_t * ec = this->private;
-
- fop = mem_get0(ec->fop_pool);
- if (fop == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to allocate memory for a "
- "request.");
-
- return NULL;
- }
-
- fop->xl = this;
- fop->req_frame = frame;
-
- /* fops need a private frame to be able to execute some postop operations
- * even if the original fop has completed and reported back to the upper
- * xlator and it has destroyed the base frame.
- *
- * TODO: minimize usage of private frames. Reuse req_frame as much as
- * possible.
- */
- if (frame != NULL)
- {
- fop->frame = copy_frame(frame);
- }
- else
- {
- fop->frame = create_frame(this, this->ctx->pool);
- }
- if (fop->frame == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to create a private frame "
- "for a request");
-
- mem_put(fop);
-
- return NULL;
- }
- fop->id = id;
- fop->refs = 1;
-
- fop->flags = flags;
- fop->minimum = minimum;
- fop->mask = target;
-
- INIT_LIST_HEAD(&fop->cbk_list);
- INIT_LIST_HEAD(&fop->answer_list);
-
- fop->wind = wind;
- fop->handler = handler;
- fop->cbks = cbks;
- fop->data = data;
-
- LOCK_INIT(&fop->lock);
-
- fop->frame->local = fop;
-
- if (frame != NULL)
- {
- parent = frame->local;
- if (parent != NULL)
- {
- LOCK(&parent->lock);
-
- parent->jobs++;
- parent->refs++;
-
- UNLOCK(&parent->lock);
- }
-
- fop->parent = parent;
- }
-
- return fop;
-}
-
-void ec_fop_data_acquire(ec_fop_data_t * fop)
-{
- LOCK(&fop->lock);
-
- ec_trace("ACQUIRE", fop, "");
-
- fop->refs++;
-
- UNLOCK(&fop->lock);
-}
-
-void ec_fop_data_release(ec_fop_data_t * fop)
-{
- ec_cbk_data_t * cbk, * tmp;
- int32_t refs;
-
- LOCK(&fop->lock);
-
- ec_trace("RELEASE", fop, "");
-
- refs = --fop->refs;
-
- UNLOCK(&fop->lock);
-
- if (refs == 0)
- {
- fop->frame->local = NULL;
- STACK_DESTROY(fop->frame->root);
-
- LOCK_DESTROY(&fop->lock);
-
- if (fop->xdata != NULL)
- {
- dict_unref(fop->xdata);
- }
- if (fop->dict != NULL)
- {
- dict_unref(fop->dict);
- }
- if (fop->inode != NULL)
- {
- inode_unref(fop->inode);
- }
- if (fop->fd != NULL)
- {
- fd_unref(fop->fd);
- }
- if (fop->buffers != NULL)
- {
- iobref_unref(fop->buffers);
- }
- GF_FREE(fop->vector);
- GF_FREE(fop->str[0]);
- GF_FREE(fop->str[1]);
- loc_wipe(&fop->loc[0]);
- loc_wipe(&fop->loc[1]);
-
- ec_resume_parent(fop, fop->error);
-
- list_for_each_entry_safe(cbk, tmp, &fop->answer_list, answer_list)
- {
- list_del_init(&cbk->answer_list);
-
- ec_cbk_data_destroy(cbk);
- }
-
- mem_put(fop);
- }
-}
diff --git a/xlators/cluster/ec/src/ec-data.h b/xlators/cluster/ec/src/ec-data.h
deleted file mode 100644
index 2e892543eeb..00000000000
--- a/xlators/cluster/ec/src/ec-data.h
+++ /dev/null
@@ -1,295 +0,0 @@
-/*
- Copyright (c) 2012-2014 DataLab, s.l. <http://www.datalab.es>
- 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 __EC_DATA_H__
-#define __EC_DATA_H__
-
-#include "xlator.h"
-
-#include "ec.h"
-
-struct _ec_config;
-typedef struct _ec_config ec_config_t;
-
-struct _ec_fd;
-typedef struct _ec_fd ec_fd_t;
-
-struct _ec_inode;
-typedef struct _ec_inode ec_inode_t;
-
-union _ec_cbk;
-typedef union _ec_cbk ec_cbk_t;
-
-struct _ec_lock;
-typedef struct _ec_lock ec_lock_t;
-
-struct _ec_lock_link;
-typedef struct _ec_lock_link ec_lock_link_t;
-
-struct _ec_fop_data;
-typedef struct _ec_fop_data ec_fop_data_t;
-
-struct _ec_cbk_data;
-typedef struct _ec_cbk_data ec_cbk_data_t;
-
-struct _ec_heal;
-typedef struct _ec_heal ec_heal_t;
-
-typedef void (* ec_wind_f)(ec_t *, ec_fop_data_t *, int32_t);
-typedef int32_t (* ec_handler_f)(ec_fop_data_t *, int32_t);
-typedef void (* ec_resume_f)(ec_fop_data_t *, int32_t);
-
-struct _ec_config
-{
- uint32_t version;
- uint8_t algorithm;
- uint8_t gf_word_size;
- uint8_t bricks;
- uint8_t redundancy;
- uint32_t chunk_size;
-};
-
-struct _ec_fd
-{
- uintptr_t bad;
- loc_t loc;
- uintptr_t open;
- int32_t flags;
-};
-
-struct _ec_inode
-{
- uintptr_t bad;
- ec_lock_t *entry_lock;
- ec_lock_t *inode_lock;
- struct list_head heal;
-
-};
-
-typedef int32_t (* fop_heal_cbk_t)(call_frame_t *, void * cookie, xlator_t *,
- int32_t, int32_t, uintptr_t, uintptr_t,
- uintptr_t, dict_t *);
-typedef int32_t (* fop_fheal_cbk_t)(call_frame_t *, void * cookie, xlator_t *,
- int32_t, int32_t, uintptr_t, uintptr_t,
- uintptr_t, dict_t *);
-
-
-union _ec_cbk
-{
- fop_access_cbk_t access;
- fop_create_cbk_t create;
- fop_discard_cbk_t discard;
- fop_entrylk_cbk_t entrylk;
- fop_fentrylk_cbk_t fentrylk;
- fop_fallocate_cbk_t fallocate;
- fop_flush_cbk_t flush;
- fop_fsync_cbk_t fsync;
- fop_fsyncdir_cbk_t fsyncdir;
- fop_getxattr_cbk_t getxattr;
- fop_fgetxattr_cbk_t fgetxattr;
- fop_heal_cbk_t heal;
- fop_fheal_cbk_t fheal;
- fop_inodelk_cbk_t inodelk;
- fop_finodelk_cbk_t finodelk;
- fop_link_cbk_t link;
- fop_lk_cbk_t lk;
- fop_lookup_cbk_t lookup;
- fop_mkdir_cbk_t mkdir;
- fop_mknod_cbk_t mknod;
- fop_open_cbk_t open;
- fop_opendir_cbk_t opendir;
- fop_readdir_cbk_t readdir;
- fop_readdirp_cbk_t readdirp;
- fop_readlink_cbk_t readlink;
- fop_readv_cbk_t readv;
- fop_removexattr_cbk_t removexattr;
- fop_fremovexattr_cbk_t fremovexattr;
- fop_rename_cbk_t rename;
- fop_rmdir_cbk_t rmdir;
- fop_setattr_cbk_t setattr;
- fop_fsetattr_cbk_t fsetattr;
- fop_setxattr_cbk_t setxattr;
- fop_fsetxattr_cbk_t fsetxattr;
- fop_stat_cbk_t stat;
- fop_fstat_cbk_t fstat;
- fop_statfs_cbk_t statfs;
- fop_symlink_cbk_t symlink;
- fop_truncate_cbk_t truncate;
- fop_ftruncate_cbk_t ftruncate;
- fop_unlink_cbk_t unlink;
- fop_writev_cbk_t writev;
- fop_xattrop_cbk_t xattrop;
- fop_fxattrop_cbk_t fxattrop;
- fop_zerofill_cbk_t zerofill;
-};
-
-struct _ec_lock
-{
- ec_lock_t **plock;
- gf_timer_t *timer;
- struct list_head waiting;
- uintptr_t mask;
- uintptr_t good_mask;
- int32_t kind;
- int32_t refs;
- int32_t acquired;
- int32_t have_size;
- uint64_t size;
- uint64_t size_delta;
- uint64_t version;
- uint64_t version_delta;
- ec_fop_data_t *owner;
- loc_t loc;
- union
- {
- entrylk_type type;
- struct gf_flock flock;
- };
-};
-
-struct _ec_lock_link
-{
- ec_lock_t * lock;
- ec_fop_data_t * fop;
- struct list_head wait_list;
-};
-
-struct _ec_fop_data
-{
- int32_t id;
- int32_t refs;
- int32_t state;
- int32_t minimum;
- int32_t expected;
- int32_t winds;
- int32_t jobs;
- int32_t error;
- ec_fop_data_t * parent;
- xlator_t * xl;
- call_frame_t * req_frame; // frame of the calling xlator
- call_frame_t * frame; // frame used by this fop
- struct list_head cbk_list; // sorted list of groups of answers
- struct list_head answer_list; // list of answers
- ec_cbk_data_t * answer; // accepted answer
- int32_t lock_count;
- int32_t locked;
- ec_lock_link_t locks[2];
- int32_t locks_update;
- int32_t have_size;
- uint64_t pre_size;
- uint64_t post_size;
- gf_lock_t lock;
- ec_config_t config;
-
- uint32_t flags;
- uint32_t first;
- uintptr_t mask;
- uintptr_t remaining;
- uintptr_t good;
- uintptr_t bad;
-
- ec_wind_f wind;
- ec_handler_f handler;
- ec_resume_f resume;
- ec_cbk_t cbks;
- void * data;
- ec_heal_t * heal;
-
- uint64_t user_size;
- uint32_t head;
-
- int32_t use_fd;
-
- dict_t * xdata;
- dict_t * dict;
- int32_t int32;
- uint32_t uint32;
- uint64_t size;
- off_t offset;
- mode_t mode[2];
- entrylk_cmd entrylk_cmd;
- entrylk_type entrylk_type;
- gf_xattrop_flags_t xattrop_flags;
- dev_t dev;
- inode_t * inode;
- fd_t * fd;
- struct iatt iatt;
- char * str[2];
- loc_t loc[2];
- struct gf_flock flock;
- struct iovec * vector;
- struct iobref * buffers;
-};
-
-struct _ec_cbk_data
-{
- struct list_head list; // item in the sorted list of groups
- struct list_head answer_list; // item in the list of answers
- ec_fop_data_t * fop;
- ec_cbk_data_t * next; // next answer in the same group
- int32_t idx;
- int32_t op_ret;
- int32_t op_errno;
- int32_t count;
- uintptr_t mask;
-
- dict_t * xdata;
- dict_t * dict;
- int32_t int32;
- uintptr_t uintptr[3];
- uint64_t size;
- uint64_t version;
- inode_t * inode;
- fd_t * fd;
- struct statvfs statvfs;
- struct iatt iatt[5];
- struct gf_flock flock;
- struct iovec * vector;
- struct iobref * buffers;
-};
-
-struct _ec_heal
-{
- struct list_head list;
- gf_lock_t lock;
- xlator_t *xl;
- ec_fop_data_t *fop;
- void *data;
- ec_fop_data_t *lookup;
- loc_t loc;
- struct iatt iatt;
- char *symlink;
- fd_t *fd;
- int32_t partial;
- int32_t done;
- uintptr_t available;
- uintptr_t good;
- uintptr_t bad;
- uintptr_t open;
- uintptr_t fixed;
- uint64_t offset;
- uint64_t size;
- uint64_t version;
- uint64_t raw_size;
-};
-
-ec_cbk_data_t * ec_cbk_data_allocate(call_frame_t * frame, xlator_t * this,
- ec_fop_data_t * fop, int32_t id,
- int32_t idx, int32_t op_ret,
- int32_t op_errno);
-ec_fop_data_t * ec_fop_data_allocate(call_frame_t * frame, xlator_t * this,
- int32_t id, uint32_t flags,
- uintptr_t target, int32_t minimum,
- ec_wind_f wind, ec_handler_f handler,
- ec_cbk_t cbks, void * data);
-void ec_fop_data_acquire(ec_fop_data_t * fop);
-void ec_fop_data_release(ec_fop_data_t * fop);
-
-#endif /* __EC_DATA_H__ */
diff --git a/xlators/cluster/ec/src/ec-dir-read.c b/xlators/cluster/ec/src/ec-dir-read.c
deleted file mode 100644
index c705b80fe82..00000000000
--- a/xlators/cluster/ec/src/ec-dir-read.c
+++ /dev/null
@@ -1,635 +0,0 @@
-/*
- Copyright (c) 2012-2014 DataLab, s.l. <http://www.datalab.es>
- 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 "xlator.h"
-#include "defaults.h"
-
-#include "ec-helpers.h"
-#include "ec-common.h"
-#include "ec-combine.h"
-#include "ec-method.h"
-#include "ec-fops.h"
-
-/* FOP: opendir */
-
-int32_t ec_combine_opendir(ec_fop_data_t * fop, ec_cbk_data_t * dst,
- ec_cbk_data_t * src)
-{
- if (dst->fd != src->fd)
- {
- gf_log(fop->xl->name, GF_LOG_NOTICE, "Mismatching fd in answers "
- "of 'GF_FOP_OPENDIR': %p <-> %p",
- dst->fd, src->fd);
-
- return 0;
- }
-
- return 1;
-}
-
-int32_t ec_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)
-{
- ec_fop_data_t * fop = NULL;
- ec_cbk_data_t * cbk = NULL;
- int32_t idx = (int32_t)(uintptr_t)cookie;
-
- VALIDATE_OR_GOTO(this, out);
- GF_VALIDATE_OR_GOTO(this->name, frame, out);
- GF_VALIDATE_OR_GOTO(this->name, frame->local, out);
- GF_VALIDATE_OR_GOTO(this->name, this->private, out);
-
- fop = frame->local;
-
- ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx,
- frame, op_ret, op_errno);
-
- cbk = ec_cbk_data_allocate(frame, this, fop, GF_FOP_OPENDIR, idx, op_ret,
- op_errno);
- if (cbk != NULL)
- {
- if (op_ret >= 0)
- {
- if (fd != NULL)
- {
- cbk->fd = fd_ref(fd);
- if (cbk->fd == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
- "file descriptor.");
-
- goto out;
- }
- }
- }
- if (xdata != NULL)
- {
- cbk->xdata = dict_ref(xdata);
- if (cbk->xdata == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
- "dictionary.");
-
- goto out;
- }
- }
-
- ec_combine(cbk, ec_combine_opendir);
- }
-
-out:
- if (fop != NULL)
- {
- ec_complete(fop);
- }
-
- return 0;
-}
-
-void ec_wind_opendir(ec_t * ec, ec_fop_data_t * fop, int32_t idx)
-{
- ec_trace("WIND", fop, "idx=%d", idx);
-
- STACK_WIND_COOKIE(fop->frame, ec_opendir_cbk, (void *)(uintptr_t)idx,
- ec->xl_list[idx], ec->xl_list[idx]->fops->opendir,
- &fop->loc[0], fop->fd, fop->xdata);
-}
-
-int32_t ec_manager_opendir(ec_fop_data_t * fop, int32_t state)
-{
- ec_cbk_data_t * cbk;
- ec_fd_t *ctx;
-
- switch (state)
- {
- case EC_STATE_INIT:
- LOCK(&fop->fd->lock);
-
- ctx = __ec_fd_get(fop->fd, fop->xl);
- if ((ctx == NULL) ||
- (ec_loc_from_loc(fop->xl, &ctx->loc, &fop->loc[0])) != 0) {
- UNLOCK(&fop->fd->lock);
-
- fop->error = EIO;
-
- return EC_STATE_REPORT;
- }
-
- UNLOCK(&fop->fd->lock);
-
- /* Fall through */
-
- case EC_STATE_LOCK:
- ec_lock_prepare_entry(fop, &fop->loc[0], 0);
- ec_lock(fop);
-
- return EC_STATE_GET_SIZE_AND_VERSION;
-
- case EC_STATE_GET_SIZE_AND_VERSION:
- ec_get_size_version(fop);
-
- return EC_STATE_DISPATCH;
-
- case EC_STATE_DISPATCH:
- ec_dispatch_all(fop);
-
- return EC_STATE_PREPARE_ANSWER;
-
- case EC_STATE_PREPARE_ANSWER:
- cbk = fop->answer;
- if (cbk != NULL)
- {
- if (!ec_dict_combine(cbk, EC_COMBINE_XDATA))
- {
- if (cbk->op_ret >= 0)
- {
- cbk->op_ret = -1;
- cbk->op_errno = EIO;
- }
- }
- if (cbk->op_ret >= 0) {
- /* Save which subvolumes successfully opened the directory.
- * If ctx->open is 0, it means that readdir cannot be
- * processed in this directory.
- */
- LOCK(&fop->fd->lock);
-
- ctx = __ec_fd_get(fop->fd, fop->xl);
- if (ctx != NULL) {
- ctx->open |= cbk->mask;
- }
-
- UNLOCK(&fop->fd->lock);
- }
- if (cbk->op_ret < 0) {
- ec_fop_set_error(fop, cbk->op_errno);
- }
- }
- else
- {
- ec_fop_set_error(fop, EIO);
- }
-
- return EC_STATE_REPORT;
-
- case EC_STATE_REPORT:
- cbk = fop->answer;
-
- GF_ASSERT(cbk != NULL);
-
- if (fop->cbks.opendir != NULL)
- {
- fop->cbks.opendir(fop->req_frame, fop, fop->xl, cbk->op_ret,
- cbk->op_errno, cbk->fd, cbk->xdata);
- }
-
- return EC_STATE_LOCK_REUSE;
-
- case -EC_STATE_INIT:
- case -EC_STATE_LOCK:
- case -EC_STATE_GET_SIZE_AND_VERSION:
- case -EC_STATE_DISPATCH:
- case -EC_STATE_PREPARE_ANSWER:
- case -EC_STATE_REPORT:
- GF_ASSERT(fop->error != 0);
-
- if (fop->cbks.opendir != NULL)
- {
- fop->cbks.opendir(fop->req_frame, fop, fop->xl, -1, fop->error,
- NULL, NULL);
- }
-
- return EC_STATE_LOCK_REUSE;
-
- case -EC_STATE_LOCK_REUSE:
- case EC_STATE_LOCK_REUSE:
- ec_lock_reuse(fop);
-
- return EC_STATE_UNLOCK;
-
- case -EC_STATE_UNLOCK:
- case EC_STATE_UNLOCK:
- ec_unlock(fop);
-
- return EC_STATE_END;
-
- default:
- gf_log(fop->xl->name, GF_LOG_ERROR, "Unhandled state %d for %s",
- state, ec_fop_name(fop->id));
-
- return EC_STATE_END;
- }
-}
-
-void ec_opendir(call_frame_t * frame, xlator_t * this, uintptr_t target,
- int32_t minimum, fop_opendir_cbk_t func, void * data,
- loc_t * loc, fd_t * fd, dict_t * xdata)
-{
- ec_cbk_t callback = { .opendir = func };
- ec_fop_data_t * fop = NULL;
- int32_t error = EIO;
-
- gf_log("ec", GF_LOG_TRACE, "EC(OPENDIR) %p", frame);
-
- VALIDATE_OR_GOTO(this, out);
- GF_VALIDATE_OR_GOTO(this->name, frame, out);
- GF_VALIDATE_OR_GOTO(this->name, this->private, out);
-
- fop = ec_fop_data_allocate(frame, this, GF_FOP_OPENDIR, EC_FLAG_UPDATE_FD,
- target, minimum, ec_wind_opendir,
- ec_manager_opendir, callback, data);
- if (fop == NULL)
- {
- goto out;
- }
-
- if (loc != NULL)
- {
- if (loc_copy(&fop->loc[0], loc) != 0)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to copy a location.");
-
- goto out;
- }
- }
- if (fd != NULL)
- {
- fop->fd = fd_ref(fd);
- if (fop->fd == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
- "file descriptor.");
-
- goto out;
- }
- }
- if (xdata != NULL)
- {
- fop->xdata = dict_ref(xdata);
- if (fop->xdata == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
- "dictionary.");
-
- goto out;
- }
- }
-
- error = 0;
-
-out:
- if (fop != NULL)
- {
- ec_manager(fop, error);
- }
- else
- {
- func(frame, NULL, this, -1, EIO, NULL, NULL);
- }
-}
-
-/* FOP: readdir */
-
-void ec_adjust_readdir(ec_t * ec, int32_t idx, gf_dirent_t * entries)
-{
- gf_dirent_t * entry;
-
- list_for_each_entry(entry, &entries->list, list)
- {
- entry->d_off = ec_itransform(ec, idx, entry->d_off);
-
- if (entry->d_stat.ia_type == IA_IFREG)
- {
- if ((entry->dict == NULL) ||
- (ec_dict_del_number(entry->dict, EC_XATTR_SIZE,
- &entry->d_stat.ia_size) != 0))
- {
- gf_log(ec->xl->name, GF_LOG_WARNING, "Unable to get exact "
- "file size.");
-
- entry->d_stat.ia_size *= ec->fragments;
- }
-
- ec_iatt_rebuild(ec, &entry->d_stat, 1, 1);
- }
- }
-}
-
-int32_t ec_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)
-{
- ec_fop_data_t * fop = NULL;
- int32_t idx = (int32_t)(uintptr_t)cookie;
-
- VALIDATE_OR_GOTO(this, out);
- GF_VALIDATE_OR_GOTO(this->name, frame, out);
- GF_VALIDATE_OR_GOTO(this->name, frame->local, out);
- GF_VALIDATE_OR_GOTO(this->name, this->private, out);
-
- fop = frame->local;
-
- ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx,
- frame, op_ret, op_errno);
-
- if (op_ret > 0)
- {
- ec_adjust_readdir(fop->xl->private, idx, entries);
- }
-
- if (!ec_dispatch_one_retry(fop, idx, op_ret, op_errno))
- {
- if (fop->cbks.readdir != NULL)
- {
- fop->cbks.readdir(fop->req_frame, fop, this, op_ret, op_errno,
- entries, xdata);
- }
- }
-
-out:
- if (fop != NULL)
- {
- ec_complete(fop);
- }
-
- return 0;
-}
-
-void ec_wind_readdir(ec_t * ec, ec_fop_data_t * fop, int32_t idx)
-{
- ec_trace("WIND", fop, "idx=%d", idx);
-
- STACK_WIND_COOKIE(fop->frame, ec_readdir_cbk, (void *)(uintptr_t)idx,
- ec->xl_list[idx], ec->xl_list[idx]->fops->readdir,
- fop->fd, fop->size, fop->offset, fop->xdata);
-}
-
-int32_t ec_manager_readdir(ec_fop_data_t * fop, int32_t state)
-{
- ec_fd_t *ctx;
-
- switch (state)
- {
- case EC_STATE_INIT:
- /* Return error if opendir has not been successfully called on
- * any subvolume. */
- ctx = ec_fd_get(fop->fd, fop->xl);
- if ((ctx == NULL) || (ctx->open == 0)) {
- fop->error = EINVAL;
-
- return EC_STATE_REPORT;
- }
-
- if (fop->xdata == NULL)
- {
- fop->xdata = dict_new();
- if (fop->xdata == NULL)
- {
- gf_log(fop->xl->name, GF_LOG_ERROR, "Unable to prepare "
- "readdirp request");
-
- fop->error = EIO;
-
- return EC_STATE_REPORT;
- }
- }
- if (dict_set_uint64(fop->xdata, EC_XATTR_SIZE, 0) != 0)
- {
- gf_log(fop->xl->name, GF_LOG_ERROR, "Unable to prepare "
- "readdirp request");
-
- fop->error = EIO;
-
- return EC_STATE_REPORT;
- }
-
- if (fop->offset != 0)
- {
- int32_t idx;
-
- fop->offset = ec_deitransform(fop->xl->private, &idx,
- fop->offset);
- fop->mask &= 1ULL << idx;
- }
-
- /* Fall through */
-
- case EC_STATE_DISPATCH:
- ec_dispatch_one(fop);
-
- return EC_STATE_REPORT;
-
- case -EC_STATE_INIT:
- case -EC_STATE_REPORT:
- if (fop->id == GF_FOP_READDIR)
- {
- if (fop->cbks.readdir != NULL)
- {
- fop->cbks.readdir(fop->req_frame, fop, fop->xl, -1,
- fop->error, NULL, NULL);
- }
- }
- else
- {
- if (fop->cbks.readdirp != NULL)
- {
- fop->cbks.readdirp(fop->req_frame, fop, fop->xl, -1,
- fop->error, NULL, NULL);
- }
- }
-
- case EC_STATE_REPORT:
- return EC_STATE_END;
-
- default:
- gf_log(fop->xl->name, GF_LOG_ERROR, "Unhandled state %d for %s",
- state, ec_fop_name(fop->id));
-
- return EC_STATE_END;
- }
-}
-
-void ec_readdir(call_frame_t * frame, xlator_t * this, uintptr_t target,
- int32_t minimum, fop_readdir_cbk_t func, void * data,
- fd_t * fd, size_t size, off_t offset, dict_t * xdata)
-{
- ec_cbk_t callback = { .readdir = func };
- ec_fop_data_t * fop = NULL;
- int32_t error = EIO;
-
- gf_log("ec", GF_LOG_TRACE, "EC(READDIR) %p", frame);
-
- VALIDATE_OR_GOTO(this, out);
- GF_VALIDATE_OR_GOTO(this->name, frame, out);
- GF_VALIDATE_OR_GOTO(this->name, this->private, out);
-
- fop = ec_fop_data_allocate(frame, this, GF_FOP_READDIR, 0, target, minimum,
- ec_wind_readdir, ec_manager_readdir, callback,
- data);
- if (fop == NULL)
- {
- goto out;
- }
-
- fop->use_fd = 1;
-
- fop->size = size;
- fop->offset = offset;
-
- if (fd != NULL)
- {
- fop->fd = fd_ref(fd);
- if (fop->fd == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
- "file descriptor.");
-
- goto out;
- }
- }
- if (xdata != NULL)
- {
- fop->xdata = dict_ref(xdata);
- if (fop->xdata == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
- "dictionary.");
-
- goto out;
- }
- }
-
- error = 0;
-
-out:
- if (fop != NULL)
- {
- ec_manager(fop, error);
- }
- else
- {
- func(frame, NULL, this, -1, EIO, NULL, NULL);
- }
-}
-
-/* FOP: readdirp */
-
-int32_t ec_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)
-{
- ec_fop_data_t * fop = NULL;
- int32_t idx = (int32_t)(uintptr_t)cookie;
-
- VALIDATE_OR_GOTO(this, out);
- GF_VALIDATE_OR_GOTO(this->name, frame, out);
- GF_VALIDATE_OR_GOTO(this->name, frame->local, out);
- GF_VALIDATE_OR_GOTO(this->name, this->private, out);
-
- fop = frame->local;
-
- ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx,
- frame, op_ret, op_errno);
-
- if (op_ret > 0)
- {
- ec_adjust_readdir(fop->xl->private, idx, entries);
- }
-
- if (!ec_dispatch_one_retry(fop, idx, op_ret, op_errno))
- {
- if (fop->cbks.readdirp != NULL)
- {
- fop->cbks.readdirp(fop->req_frame, fop, this, op_ret, op_errno,
- entries, xdata);
- }
- }
-
-out:
- if (fop != NULL)
- {
- ec_complete(fop);
- }
-
- return 0;
-}
-
-void ec_wind_readdirp(ec_t * ec, ec_fop_data_t * fop, int32_t idx)
-{
- ec_trace("WIND", fop, "idx=%d", idx);
-
- STACK_WIND_COOKIE(fop->frame, ec_readdirp_cbk, (void *)(uintptr_t)idx,
- ec->xl_list[idx], ec->xl_list[idx]->fops->readdirp,
- fop->fd, fop->size, fop->offset, fop->xdata);
-}
-
-void ec_readdirp(call_frame_t * frame, xlator_t * this, uintptr_t target,
- int32_t minimum, fop_readdirp_cbk_t func, void * data,
- fd_t * fd, size_t size, off_t offset, dict_t * xdata)
-{
- ec_cbk_t callback = { .readdirp = func };
- ec_fop_data_t * fop = NULL;
- int32_t error = EIO;
-
- gf_log("ec", GF_LOG_TRACE, "EC(READDIRP) %p", frame);
-
- VALIDATE_OR_GOTO(this, out);
- GF_VALIDATE_OR_GOTO(this->name, frame, out);
- GF_VALIDATE_OR_GOTO(this->name, this->private, out);
-
- fop = ec_fop_data_allocate(frame, this, GF_FOP_READDIRP, 0, target,
- minimum, ec_wind_readdirp, ec_manager_readdir,
- callback, data);
- if (fop == NULL)
- {
- goto out;
- }
-
- fop->use_fd = 1;
-
- fop->size = size;
- fop->offset = offset;
-
- if (fd != NULL)
- {
- fop->fd = fd_ref(fd);
- if (fop->fd == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
- "file descriptor.");
-
- goto out;
- }
- }
- if (xdata != NULL)
- {
- fop->xdata = dict_ref(xdata);
- if (fop->xdata == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
- "dictionary.");
-
- goto out;
- }
- }
-
- error = 0;
-
-out:
- if (fop != NULL)
- {
- ec_manager(fop, error);
- }
- else
- {
- func(frame, NULL, this, -1, EIO, NULL, NULL);
- }
-}
diff --git a/xlators/cluster/ec/src/ec-dir-write.c b/xlators/cluster/ec/src/ec-dir-write.c
deleted file mode 100644
index d48be20470d..00000000000
--- a/xlators/cluster/ec/src/ec-dir-write.c
+++ /dev/null
@@ -1,2247 +0,0 @@
-/*
- Copyright (c) 2012-2014 DataLab, s.l. <http://www.datalab.es>
- 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 "xlator.h"
-#include "defaults.h"
-
-#include "ec-helpers.h"
-#include "ec-common.h"
-#include "ec-combine.h"
-#include "ec-method.h"
-#include "ec-fops.h"
-
-/* FOP: create */
-
-int32_t ec_combine_create(ec_fop_data_t * fop, ec_cbk_data_t * dst,
- ec_cbk_data_t * src)
-{
- if (dst->fd != src->fd)
- {
- gf_log(fop->xl->name, GF_LOG_NOTICE, "Mismatching fd in answers "
- "of 'GF_FOP_CREATE': %p <-> %p",
- dst->fd, src->fd);
-
- return 0;
- }
-
- if (!ec_iatt_combine(dst->iatt, src->iatt, 3))
- {
- gf_log(fop->xl->name, GF_LOG_NOTICE, "Mismatching iatt in "
- "answers of 'GF_FOP_CREATE'");
-
- return 0;
- }
-
- return 1;
-}
-
-int32_t ec_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)
-{
- ec_fop_data_t * fop = NULL;
- ec_cbk_data_t * cbk = NULL;
- int32_t idx = (int32_t)(uintptr_t)cookie;
-
- VALIDATE_OR_GOTO(this, out);
- GF_VALIDATE_OR_GOTO(this->name, frame, out);
- GF_VALIDATE_OR_GOTO(this->name, frame->local, out);
- GF_VALIDATE_OR_GOTO(this->name, this->private, out);
-
- fop = frame->local;
-
- ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx,
- frame, op_ret, op_errno);
-
- cbk = ec_cbk_data_allocate(frame, this, fop, GF_FOP_CREATE, idx, op_ret,
- op_errno);
- if (cbk != NULL)
- {
- if (op_ret >= 0)
- {
- if (fd != NULL)
- {
- cbk->fd = fd_ref(fd);
- if (cbk->fd == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
- "file descriptor.");
-
- goto out;
- }
- }
- if (inode != NULL)
- {
- cbk->inode = inode_ref(inode);
- if (cbk->inode == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR,
- "Failed to reference an inode.");
-
- goto out;
- }
- }
- if (buf != NULL)
- {
- cbk->iatt[0] = *buf;
- }
- if (preparent != NULL)
- {
- cbk->iatt[1] = *preparent;
- }
- if (postparent != NULL)
- {
- cbk->iatt[2] = *postparent;
- }
- }
- if (xdata != NULL)
- {
- cbk->xdata = dict_ref(xdata);
- if (cbk->xdata == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
- "dictionary.");
-
- goto out;
- }
- }
-
- ec_combine(cbk, ec_combine_create);
- }
-
-out:
- if (fop != NULL)
- {
- ec_complete(fop);
- }
-
- return 0;
-}
-
-void ec_wind_create(ec_t * ec, ec_fop_data_t * fop, int32_t idx)
-{
- ec_trace("WIND", fop, "idx=%d", idx);
-
- STACK_WIND_COOKIE(fop->frame, ec_create_cbk, (void *)(uintptr_t)idx,
- ec->xl_list[idx], ec->xl_list[idx]->fops->create,
- &fop->loc[0], fop->int32, fop->mode[0], fop->mode[1],
- fop->fd, fop->xdata);
-}
-
-int32_t ec_manager_create(ec_fop_data_t * fop, int32_t state)
-{
- ec_t * ec;
- ec_cbk_data_t * cbk;
- ec_fd_t * ctx;
-
- switch (state)
- {
- case EC_STATE_INIT:
- LOCK(&fop->fd->lock);
-
- ctx = __ec_fd_get(fop->fd, fop->xl);
- if ((ctx == NULL) ||
- (ec_loc_from_loc(fop->xl, &ctx->loc, &fop->loc[0])) != 0) {
- UNLOCK(&fop->fd->lock);
-
- fop->error = EIO;
-
- return EC_STATE_REPORT;
- }
-
- ctx->flags = fop->int32;
-
- UNLOCK(&fop->fd->lock);
-
- if (fop->xdata == NULL)
- {
- fop->xdata = dict_new();
- if (fop->xdata == NULL)
- {
- fop->error = EIO;
-
- return EC_STATE_REPORT;
- }
- }
-
- ec = fop->xl->private;
-
- fop->config.version = EC_CONFIG_VERSION;
- fop->config.algorithm = EC_CONFIG_ALGORITHM;
- fop->config.gf_word_size = EC_GF_BITS;
- fop->config.bricks = ec->nodes;
- fop->config.redundancy = ec->redundancy;
- fop->config.chunk_size = EC_METHOD_CHUNK_SIZE;
-
- if (ec_dict_set_config(fop->xdata, EC_XATTR_CONFIG,
- &fop->config) < 0)
- {
- fop->error = EIO;
-
- return EC_STATE_REPORT;
- }
-
- if (ec_dict_set_number(fop->xdata, EC_XATTR_VERSION, 0) != 0) {
- fop->error = EIO;
-
- return EC_STATE_REPORT;
- }
-
- if (ec_dict_set_number(fop->xdata, EC_XATTR_SIZE, 0) != 0) {
- fop->error = EIO;
-
- return EC_STATE_REPORT;
- }
-
- /* We need to write to specific offsets on the bricks, so we
- * need to remove O_APPEND from flags (if present) */
- fop->int32 &= ~O_APPEND;
-
- /* Fall through */
-
- case EC_STATE_LOCK:
- ec_lock_prepare_entry(fop, &fop->loc[0], 1);
- ec_lock(fop);
-
- return EC_STATE_DISPATCH;
-
- case EC_STATE_DISPATCH:
- ec_dispatch_all(fop);
-
- return EC_STATE_PREPARE_ANSWER;
-
- case EC_STATE_PREPARE_ANSWER:
- cbk = fop->answer;
- if (cbk != NULL)
- {
- if (!ec_dict_combine(cbk, EC_COMBINE_XDATA))
- {
- if (cbk->op_ret >= 0)
- {
- cbk->op_ret = -1;
- cbk->op_errno = EIO;
- }
- }
- if (cbk->op_ret >= 0) {
- ec_iatt_rebuild(fop->xl->private, cbk->iatt, 3,
- cbk->count);
-
- if (ec_loc_update(fop->xl, &fop->loc[0], cbk->inode,
- &cbk->iatt[0]) != 0) {
- cbk->op_ret = -1;
- cbk->op_errno = EIO;
- } else {
- LOCK(&fop->fd->lock);
-
- ctx = __ec_fd_get(fop->fd, fop->xl);
- if (ctx != NULL) {
- ctx->open |= cbk->mask;
- }
-
- UNLOCK(&fop->fd->lock);
- }
- }
- if (cbk->op_ret < 0) {
- ec_fop_set_error(fop, cbk->op_errno);
- }
- }
- else
- {
- ec_fop_set_error(fop, EIO);
- }
-
- return EC_STATE_REPORT;
-
- case EC_STATE_REPORT:
- cbk = fop->answer;
-
- GF_ASSERT(cbk != NULL);
-
- if (fop->cbks.create != NULL)
- {
- fop->cbks.create(fop->req_frame, fop, fop->xl, cbk->op_ret,
- cbk->op_errno, cbk->fd, cbk->inode,
- &cbk->iatt[0], &cbk->iatt[1], &cbk->iatt[2],
- cbk->xdata);
- }
-
- return EC_STATE_LOCK_REUSE;
-
- case -EC_STATE_INIT:
- case -EC_STATE_LOCK:
- case -EC_STATE_DISPATCH:
- case -EC_STATE_PREPARE_ANSWER:
- case -EC_STATE_REPORT:
- GF_ASSERT(fop->error != 0);
-
- if (fop->cbks.create != NULL)
- {
- fop->cbks.create(fop->req_frame, fop, fop->xl, -1, fop->error,
- NULL, NULL, NULL, NULL, NULL, NULL);
- }
-
- return EC_STATE_LOCK_REUSE;
-
- case -EC_STATE_LOCK_REUSE:
- case EC_STATE_LOCK_REUSE:
- ec_lock_reuse(fop);
-
- return EC_STATE_UNLOCK;
-
- case -EC_STATE_UNLOCK:
- case EC_STATE_UNLOCK:
- ec_unlock(fop);
-
- return EC_STATE_END;
-
- default:
- gf_log(fop->xl->name, GF_LOG_ERROR, "Unhandled state %d for %s",
- state, ec_fop_name(fop->id));
-
- return EC_STATE_END;
- }
-}
-
-void ec_create(call_frame_t * frame, xlator_t * this, uintptr_t target,
- int32_t minimum, fop_create_cbk_t func, void * data,
- loc_t * loc, int32_t flags, mode_t mode, mode_t umask,
- fd_t * fd, dict_t * xdata)
-{
- ec_cbk_t callback = { .create = func };
- ec_fop_data_t * fop = NULL;
- int32_t error = EIO;
-
- gf_log("ec", GF_LOG_TRACE, "EC(CREATE) %p", frame);
-
- VALIDATE_OR_GOTO(this, out);
- GF_VALIDATE_OR_GOTO(this->name, frame, out);
- GF_VALIDATE_OR_GOTO(this->name, this->private, out);
-
- fop = ec_fop_data_allocate(frame, this, GF_FOP_CREATE,
- EC_FLAG_UPDATE_LOC_PARENT |
- EC_FLAG_UPDATE_FD_INODE, target, minimum,
- ec_wind_create, ec_manager_create, callback,
- data);
- if (fop == NULL)
- {
- goto out;
- }
-
- fop->int32 = flags;
- fop->mode[0] = mode;
- fop->mode[1] = umask;
-
- if (loc != NULL)
- {
- if (loc_copy(&fop->loc[0], loc) != 0)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to copy a location.");
-
- goto out;
- }
- }
- if (fd != NULL)
- {
- fop->fd = fd_ref(fd);
- if (fop->fd == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
- "file descriptor.");
-
- goto out;
- }
- }
- if (xdata != NULL)
- {
- fop->xdata = dict_ref(xdata);
- if (fop->xdata == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
- "dictionary.");
-
- goto out;
- }
- }
-
- error = 0;
-
-out:
- if (fop != NULL)
- {
- ec_manager(fop, error);
- }
- else
- {
- func(frame, NULL, this, -1, EIO, NULL, NULL, NULL, NULL, NULL, NULL);
- }
-}
-
-/* FOP: link */
-
-int32_t ec_combine_link(ec_fop_data_t * fop, ec_cbk_data_t * dst,
- ec_cbk_data_t * src)
-{
- if (!ec_iatt_combine(dst->iatt, src->iatt, 3))
- {
- gf_log(fop->xl->name, GF_LOG_NOTICE, "Mismatching iatt in "
- "answers of 'GF_FOP_LINK'");
-
- return 0;
- }
-
- return 1;
-}
-
-int32_t ec_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)
-{
- ec_fop_data_t * fop = NULL;
- ec_cbk_data_t * cbk = NULL;
- int32_t idx = (int32_t)(uintptr_t)cookie;
-
- VALIDATE_OR_GOTO(this, out);
- GF_VALIDATE_OR_GOTO(this->name, frame, out);
- GF_VALIDATE_OR_GOTO(this->name, frame->local, out);
- GF_VALIDATE_OR_GOTO(this->name, this->private, out);
-
- fop = frame->local;
-
- ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx,
- frame, op_ret, op_errno);
-
- cbk = ec_cbk_data_allocate(frame, this, fop, GF_FOP_LINK, idx, op_ret,
- op_errno);
- if (cbk != NULL)
- {
- if (op_ret >= 0)
- {
- if (inode != NULL)
- {
- cbk->inode = inode_ref(inode);
- if (cbk->inode == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR,
- "Failed to reference an inode.");
-
- goto out;
- }
- }
- if (buf != NULL)
- {
- cbk->iatt[0] = *buf;
- }
- if (preparent != NULL)
- {
- cbk->iatt[1] = *preparent;
- }
- if (postparent != NULL)
- {
- cbk->iatt[2] = *postparent;
- }
- }
- if (xdata != NULL)
- {
- cbk->xdata = dict_ref(xdata);
- if (cbk->xdata == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
- "dictionary.");
-
- goto out;
- }
- }
-
- ec_combine(cbk, ec_combine_link);
- }
-
-out:
- if (fop != NULL)
- {
- ec_complete(fop);
- }
-
- return 0;
-}
-
-void ec_wind_link(ec_t * ec, ec_fop_data_t * fop, int32_t idx)
-{
- ec_trace("WIND", fop, "idx=%d", idx);
-
- STACK_WIND_COOKIE(fop->frame, ec_link_cbk, (void *)(uintptr_t)idx,
- ec->xl_list[idx], ec->xl_list[idx]->fops->link,
- &fop->loc[0], &fop->loc[1], fop->xdata);
-}
-
-int32_t ec_manager_link(ec_fop_data_t * fop, int32_t state)
-{
- ec_cbk_data_t * cbk;
-
- switch (state)
- {
- case EC_STATE_INIT:
- case EC_STATE_LOCK:
- // Parent entry of fop->loc[0] should be locked, but I don't
- // receive enough information to do it (fop->loc[0].parent is
- // NULL).
- ec_lock_prepare_entry(fop, &fop->loc[1], 1);
- ec_lock(fop);
-
- return EC_STATE_GET_SIZE_AND_VERSION;
-
- case EC_STATE_GET_SIZE_AND_VERSION:
- ec_get_size_version(fop);
-
- return EC_STATE_DISPATCH;
-
- case EC_STATE_DISPATCH:
- ec_dispatch_all(fop);
-
- return EC_STATE_PREPARE_ANSWER;
-
- case EC_STATE_PREPARE_ANSWER:
- cbk = fop->answer;
- if (cbk != NULL)
- {
- if (!ec_dict_combine(cbk, EC_COMBINE_XDATA))
- {
- if (cbk->op_ret >= 0)
- {
- cbk->op_ret = -1;
- cbk->op_errno = EIO;
- }
- }
- if (cbk->op_ret >= 0) {
- ec_iatt_rebuild(fop->xl->private, cbk->iatt, 3,
- cbk->count);
- if (cbk->iatt[0].ia_type == IA_IFREG) {
- cbk->iatt[0].ia_size = fop->pre_size;
- }
-
- if (ec_loc_update(fop->xl, &fop->loc[0], cbk->inode,
- &cbk->iatt[0]) != 0) {
- cbk->op_ret = -1;
- cbk->op_errno = EIO;
- }
- }
- if (cbk->op_ret < 0) {
- ec_fop_set_error(fop, cbk->op_errno);
- }
- }
- else
- {
- ec_fop_set_error(fop, EIO);
- }
-
- return EC_STATE_REPORT;
-
- case EC_STATE_REPORT:
- cbk = fop->answer;
-
- GF_ASSERT(cbk != NULL);
-
- if (fop->cbks.link != NULL)
- {
- fop->cbks.link(fop->req_frame, fop, fop->xl, cbk->op_ret,
- cbk->op_errno, cbk->inode, &cbk->iatt[0],
- &cbk->iatt[1], &cbk->iatt[2], cbk->xdata);
- }
-
- return EC_STATE_LOCK_REUSE;
-
- case -EC_STATE_INIT:
- case -EC_STATE_LOCK:
- case -EC_STATE_GET_SIZE_AND_VERSION:
- case -EC_STATE_DISPATCH:
- case -EC_STATE_PREPARE_ANSWER:
- case -EC_STATE_REPORT:
- GF_ASSERT(fop->error != 0);
-
- if (fop->cbks.link != NULL)
- {
- fop->cbks.link(fop->req_frame, fop, fop->xl, -1, fop->error,
- NULL, NULL, NULL, NULL, NULL);
- }
-
- return EC_STATE_LOCK_REUSE;
-
- case -EC_STATE_LOCK_REUSE:
- case EC_STATE_LOCK_REUSE:
- ec_lock_reuse(fop);
-
- return EC_STATE_UNLOCK;
-
- case -EC_STATE_UNLOCK:
- case EC_STATE_UNLOCK:
- ec_unlock(fop);
-
- return EC_STATE_END;
-
- default:
- gf_log(fop->xl->name, GF_LOG_ERROR, "Unhandled state %d for %s",
- state, ec_fop_name(fop->id));
-
- return EC_STATE_END;
- }
-}
-
-void ec_link(call_frame_t * frame, xlator_t * this, uintptr_t target,
- int32_t minimum, fop_link_cbk_t func, void * data, loc_t * oldloc,
- loc_t * newloc, dict_t * xdata)
-{
- ec_cbk_t callback = { .link = func };
- ec_fop_data_t * fop = NULL;
- int32_t error = EIO;
-
- gf_log("ec", GF_LOG_TRACE, "EC(LINK) %p", frame);
-
- VALIDATE_OR_GOTO(this, out);
- GF_VALIDATE_OR_GOTO(this->name, frame, out);
- GF_VALIDATE_OR_GOTO(this->name, this->private, out);
-
- fop = ec_fop_data_allocate(frame, this, GF_FOP_LINK, 0, target, minimum,
- ec_wind_link, ec_manager_link, callback, data);
- if (fop == NULL)
- {
- goto out;
- }
-
- if (oldloc != NULL)
- {
- if (loc_copy(&fop->loc[0], oldloc) != 0)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to copy a location.");
-
- goto out;
- }
- }
- if (newloc != NULL)
- {
- if (loc_copy(&fop->loc[1], newloc) != 0)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to copy a location.");
-
- goto out;
- }
- }
- if (xdata != NULL)
- {
- fop->xdata = dict_ref(xdata);
- if (fop->xdata == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
- "dictionary.");
-
- goto out;
- }
- }
-
- error = 0;
-
-out:
- if (fop != NULL)
- {
- ec_manager(fop, error);
- }
- else
- {
- func(frame, NULL, this, -1, EIO, NULL, NULL, NULL, NULL, NULL);
- }
-}
-
-/* FOP: mkdir */
-
-int32_t ec_combine_mkdir(ec_fop_data_t * fop, ec_cbk_data_t * dst,
- ec_cbk_data_t * src)
-{
- if (!ec_iatt_combine(dst->iatt, src->iatt, 3))
- {
- gf_log(fop->xl->name, GF_LOG_NOTICE, "Mismatching iatt in "
- "answers of 'GF_FOP_MKDIR'");
-
- return 0;
- }
-
- return 1;
-}
-
-int32_t ec_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)
-{
- ec_fop_data_t * fop = NULL;
- ec_cbk_data_t * cbk = NULL;
- int32_t idx = (int32_t)(uintptr_t)cookie;
-
- VALIDATE_OR_GOTO(this, out);
- GF_VALIDATE_OR_GOTO(this->name, frame, out);
- GF_VALIDATE_OR_GOTO(this->name, frame->local, out);
- GF_VALIDATE_OR_GOTO(this->name, this->private, out);
-
- fop = frame->local;
-
- ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx,
- frame, op_ret, op_errno);
-
- cbk = ec_cbk_data_allocate(frame, this, fop, GF_FOP_MKDIR, idx, op_ret,
- op_errno);
- if (cbk != NULL)
- {
- if (op_ret >= 0)
- {
- if (inode != NULL)
- {
- cbk->inode = inode_ref(inode);
- if (cbk->inode == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR,
- "Failed to reference an inode.");
-
- goto out;
- }
- }
- if (buf != NULL)
- {
- cbk->iatt[0] = *buf;
- }
- if (preparent != NULL)
- {
- cbk->iatt[1] = *preparent;
- }
- if (postparent != NULL)
- {
- cbk->iatt[2] = *postparent;
- }
- }
- if (xdata != NULL)
- {
- cbk->xdata = dict_ref(xdata);
- if (cbk->xdata == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
- "dictionary.");
-
- goto out;
- }
- }
-
- ec_combine(cbk, ec_combine_mkdir);
- }
-
-out:
- if (fop != NULL)
- {
- ec_complete(fop);
- }
-
- return 0;
-}
-
-void ec_wind_mkdir(ec_t * ec, ec_fop_data_t * fop, int32_t idx)
-{
- ec_trace("WIND", fop, "idx=%d", idx);
-
- STACK_WIND_COOKIE(fop->frame, ec_mkdir_cbk, (void *)(uintptr_t)idx,
- ec->xl_list[idx], ec->xl_list[idx]->fops->mkdir,
- &fop->loc[0], fop->mode[0], fop->mode[1], fop->xdata);
-}
-
-int32_t ec_manager_mkdir(ec_fop_data_t * fop, int32_t state)
-{
- ec_cbk_data_t * cbk;
-
- switch (state)
- {
- case EC_STATE_INIT:
- if (fop->xdata == NULL) {
- fop->xdata = dict_new();
- if (fop->xdata == NULL) {
- fop->error = EIO;
-
- return EC_STATE_REPORT;
- }
- }
-
- if (ec_dict_set_number(fop->xdata, EC_XATTR_VERSION, 0) != 0) {
- fop->error = EIO;
-
- return EC_STATE_REPORT;
- }
-
- /* Fall through */
-
- case EC_STATE_LOCK:
- ec_lock_prepare_entry(fop, &fop->loc[0], 1);
- ec_lock(fop);
-
- return EC_STATE_DISPATCH;
-
- case EC_STATE_DISPATCH:
- ec_dispatch_all(fop);
-
- return EC_STATE_PREPARE_ANSWER;
-
- case EC_STATE_PREPARE_ANSWER:
- cbk = fop->answer;
- if (cbk != NULL)
- {
- if (!ec_dict_combine(cbk, EC_COMBINE_XDATA))
- {
- if (cbk->op_ret >= 0)
- {
- cbk->op_ret = -1;
- cbk->op_errno = EIO;
- }
- }
- if (cbk->op_ret >= 0) {
- ec_iatt_rebuild(fop->xl->private, cbk->iatt, 3,
- cbk->count);
-
- if (ec_loc_update(fop->xl, &fop->loc[0], cbk->inode,
- &cbk->iatt[0]) != 0) {
- cbk->op_ret = -1;
- cbk->op_errno = EIO;
- }
- }
- if (cbk->op_ret < 0) {
- ec_fop_set_error(fop, cbk->op_errno);
- }
- }
- else
- {
- ec_fop_set_error(fop, EIO);
- }
-
- return EC_STATE_REPORT;
-
- case EC_STATE_REPORT:
- cbk = fop->answer;
-
- GF_ASSERT(cbk != NULL);
-
- if (fop->cbks.mkdir != NULL)
- {
- fop->cbks.mkdir(fop->req_frame, fop, fop->xl, cbk->op_ret,
- cbk->op_errno, cbk->inode, &cbk->iatt[0],
- &cbk->iatt[1], &cbk->iatt[2], cbk->xdata);
- }
-
- return EC_STATE_LOCK_REUSE;
-
- case -EC_STATE_INIT:
- case -EC_STATE_LOCK:
- case -EC_STATE_DISPATCH:
- case -EC_STATE_PREPARE_ANSWER:
- case -EC_STATE_REPORT:
- GF_ASSERT(fop->error != 0);
-
- if (fop->cbks.mkdir != NULL)
- {
- fop->cbks.mkdir(fop->req_frame, fop, fop->xl, -1, fop->error,
- NULL, NULL, NULL, NULL, NULL);
- }
-
- return EC_STATE_LOCK_REUSE;
-
- case -EC_STATE_LOCK_REUSE:
- case EC_STATE_LOCK_REUSE:
- ec_lock_reuse(fop);
-
- return EC_STATE_UNLOCK;
-
- case -EC_STATE_UNLOCK:
- case EC_STATE_UNLOCK:
- ec_unlock(fop);
-
- return EC_STATE_END;
-
- default:
- gf_log(fop->xl->name, GF_LOG_ERROR, "Unhandled state %d for %s",
- state, ec_fop_name(fop->id));
-
- return EC_STATE_END;
- }
-}
-
-void ec_mkdir(call_frame_t * frame, xlator_t * this, uintptr_t target,
- int32_t minimum, fop_mkdir_cbk_t func, void * data, loc_t * loc,
- mode_t mode, mode_t umask, dict_t * xdata)
-{
- ec_cbk_t callback = { .mkdir = func };
- ec_fop_data_t * fop = NULL;
- int32_t error = EIO;
-
- gf_log("ec", GF_LOG_TRACE, "EC(MKDIR) %p", frame);
-
- VALIDATE_OR_GOTO(this, out);
- GF_VALIDATE_OR_GOTO(this->name, frame, out);
- GF_VALIDATE_OR_GOTO(this->name, this->private, out);
-
- fop = ec_fop_data_allocate(frame, this, GF_FOP_MKDIR,
- EC_FLAG_UPDATE_LOC_PARENT, target, minimum,
- ec_wind_mkdir, ec_manager_mkdir, callback,
- data);
- if (fop == NULL)
- {
- goto out;
- }
-
- fop->mode[0] = mode;
- fop->mode[1] = umask;
-
- if (loc != NULL)
- {
- if (loc_copy(&fop->loc[0], loc) != 0)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to copy a location.");
-
- goto out;
- }
- }
- if (xdata != NULL)
- {
- fop->xdata = dict_ref(xdata);
- if (fop->xdata == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
- "dictionary.");
-
- goto out;
- }
- }
-
- error = 0;
-
-out:
- if (fop != NULL)
- {
- ec_manager(fop, error);
- }
- else
- {
- func(frame, NULL, this, -1, EIO, NULL, NULL, NULL, NULL, NULL);
- }
-}
-
-/* FOP: mknod */
-
-int32_t ec_combine_mknod(ec_fop_data_t * fop, ec_cbk_data_t * dst,
- ec_cbk_data_t * src)
-{
- if (!ec_iatt_combine(dst->iatt, src->iatt, 3))
- {
- gf_log(fop->xl->name, GF_LOG_NOTICE, "Mismatching iatt in "
- "answers of 'GF_FOP_MKNOD'");
-
- return 0;
- }
-
- return 1;
-}
-
-int32_t ec_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)
-{
- ec_fop_data_t * fop = NULL;
- ec_cbk_data_t * cbk = NULL;
- int32_t idx = (int32_t)(uintptr_t)cookie;
-
- VALIDATE_OR_GOTO(this, out);
- GF_VALIDATE_OR_GOTO(this->name, frame, out);
- GF_VALIDATE_OR_GOTO(this->name, frame->local, out);
- GF_VALIDATE_OR_GOTO(this->name, this->private, out);
-
- fop = frame->local;
-
- ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx,
- frame, op_ret, op_errno);
-
- cbk = ec_cbk_data_allocate(frame, this, fop, GF_FOP_MKNOD, idx, op_ret,
- op_errno);
- if (cbk != NULL)
- {
- if (op_ret >= 0)
- {
- if (inode != NULL)
- {
- cbk->inode = inode_ref(inode);
- if (cbk->inode == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR,
- "Failed to reference an inode.");
-
- goto out;
- }
- }
- if (buf != NULL)
- {
- cbk->iatt[0] = *buf;
- }
- if (preparent != NULL)
- {
- cbk->iatt[1] = *preparent;
- }
- if (postparent != NULL)
- {
- cbk->iatt[2] = *postparent;
- }
- }
- if (xdata != NULL)
- {
- cbk->xdata = dict_ref(xdata);
- if (cbk->xdata == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
- "dictionary.");
-
- goto out;
- }
- }
-
- ec_combine(cbk, ec_combine_mknod);
- }
-
-out:
- if (fop != NULL)
- {
- ec_complete(fop);
- }
-
- return 0;
-}
-
-void ec_wind_mknod(ec_t * ec, ec_fop_data_t * fop, int32_t idx)
-{
- ec_trace("WIND", fop, "idx=%d", idx);
-
- STACK_WIND_COOKIE(fop->frame, ec_mknod_cbk, (void *)(uintptr_t)idx,
- ec->xl_list[idx], ec->xl_list[idx]->fops->mknod,
- &fop->loc[0], fop->mode[0], fop->dev, fop->mode[1],
- fop->xdata);
-}
-
-int32_t ec_manager_mknod(ec_fop_data_t * fop, int32_t state)
-{
- ec_t *ec;
- ec_cbk_data_t * cbk;
-
- switch (state)
- {
- case EC_STATE_INIT:
- if (S_ISREG(fop->mode[0])) {
- if (fop->xdata == NULL) {
- fop->xdata = dict_new();
- if (fop->xdata == NULL) {
- fop->error = EIO;
-
- return EC_STATE_REPORT;
- }
- }
-
- ec = fop->xl->private;
-
- fop->config.version = EC_CONFIG_VERSION;
- fop->config.algorithm = EC_CONFIG_ALGORITHM;
- fop->config.gf_word_size = EC_GF_BITS;
- fop->config.bricks = ec->nodes;
- fop->config.redundancy = ec->redundancy;
- fop->config.chunk_size = EC_METHOD_CHUNK_SIZE;
-
- if (ec_dict_set_config(fop->xdata, EC_XATTR_CONFIG,
- &fop->config) < 0) {
- fop->error = EIO;
-
- return EC_STATE_REPORT;
- }
-
- if (ec_dict_set_number(fop->xdata, EC_XATTR_VERSION, 0) != 0) {
- fop->error = EIO;
-
- return EC_STATE_REPORT;
- }
-
- if (ec_dict_set_number(fop->xdata, EC_XATTR_SIZE, 0) != 0) {
- fop->error = EIO;
-
- return EC_STATE_REPORT;
- }
- }
-
- /* Fall through */
-
- case EC_STATE_LOCK:
- ec_lock_prepare_entry(fop, &fop->loc[0], 1);
- ec_lock(fop);
-
- return EC_STATE_DISPATCH;
-
- case EC_STATE_DISPATCH:
- ec_dispatch_all(fop);
-
- return EC_STATE_PREPARE_ANSWER;
-
- case EC_STATE_PREPARE_ANSWER:
- cbk = fop->answer;
- if (cbk != NULL)
- {
- if (!ec_dict_combine(cbk, EC_COMBINE_XDATA))
- {
- if (cbk->op_ret >= 0)
- {
- cbk->op_ret = -1;
- cbk->op_errno = EIO;
- }
- }
- if (cbk->op_ret >= 0) {
- ec_iatt_rebuild(fop->xl->private, cbk->iatt, 3,
- cbk->count);
-
- if (ec_loc_update(fop->xl, &fop->loc[0], cbk->inode,
- &cbk->iatt[0]) != 0) {
- cbk->op_ret = -1;
- cbk->op_errno = EIO;
- }
- }
- if (cbk->op_ret < 0) {
- ec_fop_set_error(fop, cbk->op_errno);
- }
- }
- else
- {
- ec_fop_set_error(fop, EIO);
- }
-
- return EC_STATE_REPORT;
-
- case EC_STATE_REPORT:
- cbk = fop->answer;
-
- GF_ASSERT(cbk != NULL);
-
- if (fop->cbks.mknod != NULL)
- {
- fop->cbks.mknod(fop->req_frame, fop, fop->xl, cbk->op_ret,
- cbk->op_errno, cbk->inode, &cbk->iatt[0],
- &cbk->iatt[1], &cbk->iatt[2], cbk->xdata);
- }
-
- return EC_STATE_LOCK_REUSE;
-
- case -EC_STATE_INIT:
- case -EC_STATE_LOCK:
- case -EC_STATE_DISPATCH:
- case -EC_STATE_PREPARE_ANSWER:
- case -EC_STATE_REPORT:
- GF_ASSERT(fop->error != 0);
-
- if (fop->cbks.mknod != NULL)
- {
- fop->cbks.mknod(fop->req_frame, fop, fop->xl, -1, fop->error,
- NULL, NULL, NULL, NULL, NULL);
- }
-
- return EC_STATE_LOCK_REUSE;
-
- case -EC_STATE_LOCK_REUSE:
- case EC_STATE_LOCK_REUSE:
- ec_lock_reuse(fop);
-
- return EC_STATE_UNLOCK;
-
- case -EC_STATE_UNLOCK:
- case EC_STATE_UNLOCK:
- ec_unlock(fop);
-
- return EC_STATE_END;
-
- default:
- gf_log(fop->xl->name, GF_LOG_ERROR, "Unhandled state %d for %s",
- state, ec_fop_name(fop->id));
-
- return EC_STATE_END;
- }
-}
-
-void ec_mknod(call_frame_t * frame, xlator_t * this, uintptr_t target,
- int32_t minimum, fop_mknod_cbk_t func, void * data, loc_t * loc,
- mode_t mode, dev_t rdev, mode_t umask, dict_t * xdata)
-{
- ec_cbk_t callback = { .mknod = func };
- ec_fop_data_t * fop = NULL;
- int32_t error = EIO;
-
- gf_log("ec", GF_LOG_TRACE, "EC(MKNOD) %p", frame);
-
- VALIDATE_OR_GOTO(this, out);
- GF_VALIDATE_OR_GOTO(this->name, frame, out);
- GF_VALIDATE_OR_GOTO(this->name, this->private, out);
-
- fop = ec_fop_data_allocate(frame, this, GF_FOP_MKNOD,
- EC_FLAG_UPDATE_LOC_PARENT, target, minimum,
- ec_wind_mknod, ec_manager_mknod, callback,
- data);
- if (fop == NULL)
- {
- goto out;
- }
-
- fop->mode[0] = mode;
- fop->dev = rdev;
- fop->mode[1] = umask;
-
- if (loc != NULL)
- {
- if (loc_copy(&fop->loc[0], loc) != 0)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to copy a location.");
-
- goto out;
- }
- }
- if (xdata != NULL)
- {
- fop->xdata = dict_ref(xdata);
- if (fop->xdata == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
- "dictionary.");
-
- goto out;
- }
- }
-
- error = 0;
-
-out:
- if (fop != NULL)
- {
- ec_manager(fop, error);
- }
- else
- {
- func(frame, NULL, this, -1, EIO, NULL, NULL, NULL, NULL, NULL);
- }
-}
-
-/* FOP: rename */
-
-int32_t ec_combine_rename(ec_fop_data_t * fop, ec_cbk_data_t * dst,
- ec_cbk_data_t * src)
-{
- if (!ec_iatt_combine(dst->iatt, src->iatt, 5))
- {
- gf_log(fop->xl->name, GF_LOG_NOTICE, "Mismatching iatt in "
- "answers of 'GF_FOP_RENAME'");
-
- return 0;
- }
-
- return 1;
-}
-
-int32_t ec_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)
-{
- ec_fop_data_t * fop = NULL;
- ec_cbk_data_t * cbk = NULL;
- int32_t idx = (int32_t)(uintptr_t)cookie;
-
- VALIDATE_OR_GOTO(this, out);
- GF_VALIDATE_OR_GOTO(this->name, frame, out);
- GF_VALIDATE_OR_GOTO(this->name, frame->local, out);
- GF_VALIDATE_OR_GOTO(this->name, this->private, out);
-
- fop = frame->local;
-
- ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx,
- frame, op_ret, op_errno);
-
- cbk = ec_cbk_data_allocate(frame, this, fop, GF_FOP_RENAME, idx, op_ret,
- op_errno);
- if (cbk != NULL)
- {
- if (op_ret >= 0)
- {
- if (buf != NULL)
- {
- cbk->iatt[0] = *buf;
- }
- if (preoldparent != NULL)
- {
- cbk->iatt[1] = *preoldparent;
- }
- if (postoldparent != NULL)
- {
- cbk->iatt[2] = *postoldparent;
- }
- if (prenewparent != NULL)
- {
- cbk->iatt[3] = *prenewparent;
- }
- if (postnewparent != NULL)
- {
- cbk->iatt[4] = *postnewparent;
- }
- }
- if (xdata != NULL)
- {
- cbk->xdata = dict_ref(xdata);
- if (cbk->xdata == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
- "dictionary.");
-
- goto out;
- }
- }
-
- ec_combine(cbk, ec_combine_rename);
- }
-
-out:
- if (fop != NULL)
- {
- ec_complete(fop);
- }
-
- return 0;
-}
-
-void ec_wind_rename(ec_t * ec, ec_fop_data_t * fop, int32_t idx)
-{
- ec_trace("WIND", fop, "idx=%d", idx);
-
- STACK_WIND_COOKIE(fop->frame, ec_rename_cbk, (void *)(uintptr_t)idx,
- ec->xl_list[idx], ec->xl_list[idx]->fops->rename,
- &fop->loc[0], &fop->loc[1], fop->xdata);
-}
-
-int32_t ec_manager_rename(ec_fop_data_t * fop, int32_t state)
-{
- ec_cbk_data_t * cbk;
-
- switch (state)
- {
- case EC_STATE_INIT:
- case EC_STATE_LOCK:
- ec_lock_prepare_entry(fop, &fop->loc[0], 1);
- ec_lock_prepare_entry(fop, &fop->loc[1], 1);
- ec_lock(fop);
-
- return EC_STATE_GET_SIZE_AND_VERSION;
-
- case EC_STATE_GET_SIZE_AND_VERSION:
- ec_get_size_version(fop);
-
- return EC_STATE_DISPATCH;
-
- case EC_STATE_DISPATCH:
- ec_dispatch_all(fop);
-
- return EC_STATE_PREPARE_ANSWER;
-
- case EC_STATE_PREPARE_ANSWER:
- cbk = fop->answer;
- if (cbk != NULL)
- {
- if (!ec_dict_combine(cbk, EC_COMBINE_XDATA))
- {
- if (cbk->op_ret >= 0)
- {
- cbk->op_ret = -1;
- cbk->op_errno = EIO;
- }
- }
- if (cbk->op_ret < 0)
- {
- ec_fop_set_error(fop, cbk->op_errno);
- }
- else
- {
- ec_iatt_rebuild(fop->xl->private, cbk->iatt, 5,
- cbk->count);
-
- if (cbk->iatt[0].ia_type == IA_IFREG)
- {
- cbk->iatt[0].ia_size = fop->pre_size;
- }
- }
- }
- else
- {
- ec_fop_set_error(fop, EIO);
- }
-
- return EC_STATE_REPORT;
-
- case EC_STATE_REPORT:
- cbk = fop->answer;
-
- GF_ASSERT(cbk != NULL);
-
- if (fop->cbks.rename != NULL)
- {
- fop->cbks.rename(fop->req_frame, fop, fop->xl, cbk->op_ret,
- cbk->op_errno, &cbk->iatt[0], &cbk->iatt[1],
- &cbk->iatt[2], &cbk->iatt[3], &cbk->iatt[4],
- cbk->xdata);
- }
-
- return EC_STATE_LOCK_REUSE;
-
- case -EC_STATE_INIT:
- case -EC_STATE_LOCK:
- case -EC_STATE_GET_SIZE_AND_VERSION:
- case -EC_STATE_DISPATCH:
- case -EC_STATE_PREPARE_ANSWER:
- case -EC_STATE_REPORT:
- GF_ASSERT(fop->error != 0);
-
- if (fop->cbks.rename != NULL)
- {
- fop->cbks.rename(fop->req_frame, fop, fop->xl, -1, fop->error,
- NULL, NULL, NULL, NULL, NULL, NULL);
- }
-
- return EC_STATE_LOCK_REUSE;
-
- case -EC_STATE_LOCK_REUSE:
- case EC_STATE_LOCK_REUSE:
- ec_lock_reuse(fop);
-
- return EC_STATE_UNLOCK;
-
- case -EC_STATE_UNLOCK:
- case EC_STATE_UNLOCK:
- ec_unlock(fop);
-
- return EC_STATE_END;
-
- default:
- gf_log(fop->xl->name, GF_LOG_ERROR, "Unhandled state %d for %s",
- state, ec_fop_name(fop->id));
-
- return EC_STATE_END;
- }
-}
-
-void ec_rename(call_frame_t * frame, xlator_t * this, uintptr_t target,
- int32_t minimum, fop_rename_cbk_t func, void * data,
- loc_t * oldloc, loc_t * newloc, dict_t * xdata)
-{
- ec_cbk_t callback = { .rename = func };
- ec_fop_data_t * fop = NULL;
- int32_t error = EIO;
-
- gf_log("ec", GF_LOG_TRACE, "EC(RENAME) %p", frame);
-
- VALIDATE_OR_GOTO(this, out);
- GF_VALIDATE_OR_GOTO(this->name, frame, out);
- GF_VALIDATE_OR_GOTO(this->name, this->private, out);
-
- fop = ec_fop_data_allocate(frame, this, GF_FOP_RENAME,
- EC_FLAG_UPDATE_LOC_PARENT, target, minimum,
- ec_wind_rename, ec_manager_rename, callback,
- data);
- if (fop == NULL)
- {
- goto out;
- }
-
- if (oldloc != NULL)
- {
- if (loc_copy(&fop->loc[0], oldloc) != 0)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to copy a location.");
-
- goto out;
- }
- }
- if (newloc != NULL)
- {
- if (loc_copy(&fop->loc[1], newloc) != 0)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to copy a location.");
-
- goto out;
- }
- }
- if (xdata != NULL)
- {
- fop->xdata = dict_ref(xdata);
- if (fop->xdata == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
- "dictionary.");
-
- goto out;
- }
- }
-
- error = 0;
-
-out:
- if (fop != NULL)
- {
- ec_manager(fop, error);
- }
- else
- {
- func(frame, NULL, this, -1, EIO, NULL, NULL, NULL, NULL, NULL, NULL);
- }
-}
-
-/* FOP: rmdir */
-
-int32_t ec_combine_rmdir(ec_fop_data_t * fop, ec_cbk_data_t * dst,
- ec_cbk_data_t * src)
-{
- if (!ec_iatt_combine(dst->iatt, src->iatt, 2))
- {
- gf_log(fop->xl->name, GF_LOG_NOTICE, "Mismatching iatt in "
- "answers of 'GF_FOP_RMDIR'");
-
- return 0;
- }
-
- return 1;
-}
-
-int32_t ec_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)
-{
- ec_fop_data_t * fop = NULL;
- ec_cbk_data_t * cbk = NULL;
- int32_t idx = (int32_t)(uintptr_t)cookie;
-
- VALIDATE_OR_GOTO(this, out);
- GF_VALIDATE_OR_GOTO(this->name, frame, out);
- GF_VALIDATE_OR_GOTO(this->name, frame->local, out);
- GF_VALIDATE_OR_GOTO(this->name, this->private, out);
-
- fop = frame->local;
-
- ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx,
- frame, op_ret, op_errno);
-
- cbk = ec_cbk_data_allocate(frame, this, fop, GF_FOP_RMDIR, idx, op_ret,
- op_errno);
- if (cbk != NULL)
- {
- if (op_ret >= 0)
- {
- if (preparent != NULL)
- {
- cbk->iatt[0] = *preparent;
- }
- if (postparent != NULL)
- {
- cbk->iatt[1] = *postparent;
- }
- }
- if (xdata != NULL)
- {
- cbk->xdata = dict_ref(xdata);
- if (cbk->xdata == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
- "dictionary.");
-
- goto out;
- }
- }
-
- ec_combine(cbk, ec_combine_rmdir);
- }
-
-out:
- if (fop != NULL)
- {
- ec_complete(fop);
- }
-
- return 0;
-}
-
-void ec_wind_rmdir(ec_t * ec, ec_fop_data_t * fop, int32_t idx)
-{
- ec_trace("WIND", fop, "idx=%d", idx);
-
- STACK_WIND_COOKIE(fop->frame, ec_rmdir_cbk, (void *)(uintptr_t)idx,
- ec->xl_list[idx], ec->xl_list[idx]->fops->rmdir,
- &fop->loc[0], fop->int32, fop->xdata);
-}
-
-int32_t ec_manager_rmdir(ec_fop_data_t * fop, int32_t state)
-{
- ec_cbk_data_t * cbk;
-
- switch (state)
- {
- case EC_STATE_INIT:
- case EC_STATE_LOCK:
- ec_lock_prepare_entry(fop, &fop->loc[0], 1);
- ec_lock(fop);
-
- return EC_STATE_DISPATCH;
-
- case EC_STATE_DISPATCH:
- ec_dispatch_all(fop);
-
- return EC_STATE_PREPARE_ANSWER;
-
- case EC_STATE_PREPARE_ANSWER:
- cbk = fop->answer;
- if (cbk != NULL)
- {
- if (!ec_dict_combine(cbk, EC_COMBINE_XDATA))
- {
- if (cbk->op_ret >= 0)
- {
- cbk->op_ret = -1;
- cbk->op_errno = EIO;
- }
- }
- if (cbk->op_ret < 0)
- {
- ec_fop_set_error(fop, cbk->op_errno);
- }
- }
- else
- {
- ec_fop_set_error(fop, EIO);
- }
-
- return EC_STATE_REPORT;
-
- case EC_STATE_REPORT:
- cbk = fop->answer;
-
- GF_ASSERT(cbk != NULL);
-
- if (fop->cbks.rmdir != NULL)
- {
- fop->cbks.rmdir(fop->req_frame, fop, fop->xl, cbk->op_ret,
- cbk->op_errno, &cbk->iatt[0], &cbk->iatt[1],
- cbk->xdata);
- }
-
- return EC_STATE_LOCK_REUSE;
-
- case -EC_STATE_INIT:
- case -EC_STATE_LOCK:
- case -EC_STATE_DISPATCH:
- case -EC_STATE_PREPARE_ANSWER:
- case -EC_STATE_REPORT:
- GF_ASSERT(fop->error != 0);
-
- if (fop->cbks.rmdir != NULL)
- {
- fop->cbks.rmdir(fop->req_frame, fop, fop->xl, -1, fop->error,
- NULL, NULL, NULL);
- }
-
- return EC_STATE_LOCK_REUSE;
-
- case -EC_STATE_LOCK_REUSE:
- case EC_STATE_LOCK_REUSE:
- ec_lock_reuse(fop);
-
- return EC_STATE_UNLOCK;
-
- case -EC_STATE_UNLOCK:
- case EC_STATE_UNLOCK:
- ec_unlock(fop);
-
- return EC_STATE_END;
-
- default:
- gf_log(fop->xl->name, GF_LOG_ERROR, "Unhandled state %d for %s",
- state, ec_fop_name(fop->id));
-
- return EC_STATE_END;
- }
-}
-
-void ec_rmdir(call_frame_t * frame, xlator_t * this, uintptr_t target,
- int32_t minimum, fop_rmdir_cbk_t func, void * data, loc_t * loc,
- int xflags, dict_t * xdata)
-{
- ec_cbk_t callback = { .rmdir = func };
- ec_fop_data_t * fop = NULL;
- int32_t error = EIO;
-
- gf_log("ec", GF_LOG_TRACE, "EC(RMDIR) %p", frame);
-
- VALIDATE_OR_GOTO(this, out);
- GF_VALIDATE_OR_GOTO(this->name, frame, out);
- GF_VALIDATE_OR_GOTO(this->name, this->private, out);
-
- fop = ec_fop_data_allocate(frame, this, GF_FOP_RMDIR,
- EC_FLAG_UPDATE_LOC_PARENT, target, minimum,
- ec_wind_rmdir, ec_manager_rmdir, callback,
- data);
- if (fop == NULL)
- {
- goto out;
- }
-
- fop->int32 = xflags;
-
- if (loc != NULL)
- {
- if (loc_copy(&fop->loc[0], loc) != 0)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to copy a location.");
-
- goto out;
- }
- }
- if (xdata != NULL)
- {
- fop->xdata = dict_ref(xdata);
- if (fop->xdata == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
- "dictionary.");
-
- goto out;
- }
- }
-
- error = 0;
-
-out:
- if (fop != NULL)
- {
- ec_manager(fop, error);
- }
- else
- {
- func(frame, NULL, this, -1, EIO, NULL, NULL, NULL);
- }
-}
-
-/* FOP: symlink */
-
-int32_t ec_combine_symlink(ec_fop_data_t * fop, ec_cbk_data_t * dst,
- ec_cbk_data_t * src)
-{
- if (!ec_iatt_combine(dst->iatt, src->iatt, 3))
- {
- gf_log(fop->xl->name, GF_LOG_NOTICE, "Mismatching iatt in "
- "answers of 'GF_FOP_SYMLINK'");
-
- return 0;
- }
-
- return 1;
-}
-
-int32_t ec_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)
-{
- ec_fop_data_t * fop = NULL;
- ec_cbk_data_t * cbk = NULL;
- int32_t idx = (int32_t)(uintptr_t)cookie;
-
- VALIDATE_OR_GOTO(this, out);
- GF_VALIDATE_OR_GOTO(this->name, frame, out);
- GF_VALIDATE_OR_GOTO(this->name, frame->local, out);
- GF_VALIDATE_OR_GOTO(this->name, this->private, out);
-
- fop = frame->local;
-
- ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx,
- frame, op_ret, op_errno);
-
- cbk = ec_cbk_data_allocate(frame, this, fop, GF_FOP_SYMLINK, idx, op_ret,
- op_errno);
- if (cbk != NULL)
- {
- if (op_ret >= 0)
- {
- if (inode != NULL)
- {
- cbk->inode = inode_ref(inode);
- if (cbk->inode == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR,
- "Failed to reference an inode.");
-
- goto out;
- }
- }
- if (buf != NULL)
- {
- cbk->iatt[0] = *buf;
- }
- if (preparent != NULL)
- {
- cbk->iatt[1] = *preparent;
- }
- if (postparent != NULL)
- {
- cbk->iatt[2] = *postparent;
- }
- }
- if (xdata != NULL)
- {
- cbk->xdata = dict_ref(xdata);
- if (cbk->xdata == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
- "dictionary.");
-
- goto out;
- }
- }
-
- ec_combine(cbk, ec_combine_symlink);
- }
-
-out:
- if (fop != NULL)
- {
- ec_complete(fop);
- }
-
- return 0;
-}
-
-void ec_wind_symlink(ec_t * ec, ec_fop_data_t * fop, int32_t idx)
-{
- ec_trace("WIND", fop, "idx=%d", idx);
-
- STACK_WIND_COOKIE(fop->frame, ec_symlink_cbk, (void *)(uintptr_t)idx,
- ec->xl_list[idx], ec->xl_list[idx]->fops->symlink,
- fop->str[0], &fop->loc[0], fop->mode[0], fop->xdata);
-}
-
-int32_t ec_manager_symlink(ec_fop_data_t * fop, int32_t state)
-{
- ec_cbk_data_t * cbk;
-
- switch (state)
- {
- case EC_STATE_INIT:
- case EC_STATE_LOCK:
- ec_lock_prepare_entry(fop, &fop->loc[0], 1);
- ec_lock(fop);
-
- return EC_STATE_DISPATCH;
-
- case EC_STATE_DISPATCH:
- ec_dispatch_all(fop);
-
- return EC_STATE_PREPARE_ANSWER;
-
- case EC_STATE_PREPARE_ANSWER:
- cbk = fop->answer;
- if (cbk != NULL)
- {
- if (!ec_dict_combine(cbk, EC_COMBINE_XDATA))
- {
- if (cbk->op_ret >= 0)
- {
- cbk->op_ret = -1;
- cbk->op_errno = EIO;
- }
- }
- if (cbk->op_ret >= 0) {
- ec_iatt_rebuild(fop->xl->private, cbk->iatt, 3,
- cbk->count);
-
- if (ec_loc_update(fop->xl, &fop->loc[0], cbk->inode,
- &cbk->iatt[0]) != 0) {
- cbk->op_ret = -1;
- cbk->op_errno = EIO;
- }
- }
- if (cbk->op_ret < 0) {
- ec_fop_set_error(fop, cbk->op_errno);
- }
- }
- else
- {
- ec_fop_set_error(fop, EIO);
- }
-
- return EC_STATE_REPORT;
-
- case EC_STATE_REPORT:
- cbk = fop->answer;
-
- GF_ASSERT(cbk != NULL);
-
- if (fop->cbks.symlink != NULL)
- {
- fop->cbks.symlink(fop->req_frame, fop, fop->xl, cbk->op_ret,
- cbk->op_errno, cbk->inode, &cbk->iatt[0],
- &cbk->iatt[1], &cbk->iatt[2], cbk->xdata);
- }
-
- return EC_STATE_LOCK_REUSE;
-
- case -EC_STATE_INIT:
- case -EC_STATE_LOCK:
- case -EC_STATE_DISPATCH:
- case -EC_STATE_PREPARE_ANSWER:
- case -EC_STATE_REPORT:
- GF_ASSERT(fop->error != 0);
-
- if (fop->cbks.symlink != NULL)
- {
- fop->cbks.symlink(fop->req_frame, fop, fop->xl, -1, fop->error,
- NULL, NULL, NULL, NULL, NULL);
- }
-
- return EC_STATE_LOCK_REUSE;
-
- case -EC_STATE_LOCK_REUSE:
- case EC_STATE_LOCK_REUSE:
- ec_lock_reuse(fop);
-
- return EC_STATE_UNLOCK;
-
- case -EC_STATE_UNLOCK:
- case EC_STATE_UNLOCK:
- ec_unlock(fop);
-
- return EC_STATE_END;
-
- default:
- gf_log(fop->xl->name, GF_LOG_ERROR, "Unhandled state %d for %s",
- state, ec_fop_name(fop->id));
-
- return EC_STATE_END;
- }
-}
-
-void ec_symlink(call_frame_t * frame, xlator_t * this, uintptr_t target,
- int32_t minimum, fop_symlink_cbk_t func, void * data,
- const char * linkname, loc_t * loc, mode_t umask,
- dict_t * xdata)
-{
- ec_cbk_t callback = { .symlink = func };
- ec_fop_data_t * fop = NULL;
- int32_t error = EIO;
-
- gf_log("ec", GF_LOG_TRACE, "EC(SYMLINK) %p", frame);
-
- VALIDATE_OR_GOTO(this, out);
- GF_VALIDATE_OR_GOTO(this->name, frame, out);
- GF_VALIDATE_OR_GOTO(this->name, this->private, out);
-
- fop = ec_fop_data_allocate(frame, this, GF_FOP_SYMLINK,
- EC_FLAG_UPDATE_LOC_PARENT, target, minimum,
- ec_wind_symlink, ec_manager_symlink, callback,
- data);
- if (fop == NULL)
- {
- goto out;
- }
-
- fop->mode[0] = umask;
-
- if (linkname != NULL)
- {
- fop->str[0] = gf_strdup(linkname);
- if (fop->str[0] == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to duplicate a string.");
-
- goto out;
- }
- }
- if (loc != NULL)
- {
- if (loc_copy(&fop->loc[0], loc) != 0)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to copy a location.");
-
- goto out;
- }
- }
- if (xdata != NULL)
- {
- fop->xdata = dict_ref(xdata);
- if (fop->xdata == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
- "dictionary.");
-
- goto out;
- }
- }
-
- error = 0;
-
-out:
- if (fop != NULL)
- {
- ec_manager(fop, error);
- }
- else
- {
- func(frame, NULL, this, -1, EIO, NULL, NULL, NULL, NULL, NULL);
- }
-}
-
-/* FOP: unlink */
-
-int32_t ec_combine_unlink(ec_fop_data_t * fop, ec_cbk_data_t * dst,
- ec_cbk_data_t * src)
-{
- if (!ec_iatt_combine(dst->iatt, src->iatt, 2))
- {
- gf_log(fop->xl->name, GF_LOG_NOTICE, "Mismatching iatt in "
- "answers of 'GF_FOP_UNLINK'");
-
- return 0;
- }
-
- return 1;
-}
-
-int32_t ec_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)
-{
- ec_fop_data_t * fop = NULL;
- ec_cbk_data_t * cbk = NULL;
- int32_t idx = (int32_t)(uintptr_t)cookie;
-
- VALIDATE_OR_GOTO(this, out);
- GF_VALIDATE_OR_GOTO(this->name, frame, out);
- GF_VALIDATE_OR_GOTO(this->name, frame->local, out);
- GF_VALIDATE_OR_GOTO(this->name, this->private, out);
-
- fop = frame->local;
-
- ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx,
- frame, op_ret, op_errno);
-
- cbk = ec_cbk_data_allocate(frame, this, fop, GF_FOP_UNLINK, idx, op_ret,
- op_errno);
- if (cbk != NULL)
- {
- if (op_ret >= 0)
- {
- if (preparent != NULL)
- {
- cbk->iatt[0] = *preparent;
- }
- if (postparent != NULL)
- {
- cbk->iatt[1] = *postparent;
- }
- }
- if (xdata != NULL)
- {
- cbk->xdata = dict_ref(xdata);
- if (cbk->xdata == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
- "dictionary.");
-
- goto out;
- }
- }
-
- ec_combine(cbk, ec_combine_unlink);
- }
-
-out:
- if (fop != NULL)
- {
- ec_complete(fop);
- }
-
- return 0;
-}
-
-void ec_wind_unlink(ec_t * ec, ec_fop_data_t * fop, int32_t idx)
-{
- ec_trace("WIND", fop, "idx=%d", idx);
-
- STACK_WIND_COOKIE(fop->frame, ec_unlink_cbk, (void *)(uintptr_t)idx,
- ec->xl_list[idx], ec->xl_list[idx]->fops->unlink,
- &fop->loc[0], fop->int32, fop->xdata);
-}
-
-int32_t ec_manager_unlink(ec_fop_data_t * fop, int32_t state)
-{
- ec_cbk_data_t * cbk;
-
- switch (state)
- {
- case EC_STATE_INIT:
- case EC_STATE_LOCK:
- ec_lock_prepare_entry(fop, &fop->loc[0], 1);
- ec_lock(fop);
-
- return EC_STATE_GET_SIZE_AND_VERSION;
-
- case EC_STATE_GET_SIZE_AND_VERSION:
- ec_get_size_version(fop);
-
- return EC_STATE_DISPATCH;
-
- case EC_STATE_DISPATCH:
- ec_dispatch_all(fop);
-
- return EC_STATE_PREPARE_ANSWER;
-
- case EC_STATE_PREPARE_ANSWER:
- cbk = fop->answer;
- if (cbk != NULL)
- {
- if (!ec_dict_combine(cbk, EC_COMBINE_XDATA))
- {
- if (cbk->op_ret >= 0)
- {
- cbk->op_ret = -1;
- cbk->op_errno = EIO;
- }
- }
- if (cbk->op_ret < 0)
- {
- ec_fop_set_error(fop, cbk->op_errno);
- }
- }
- else
- {
- ec_fop_set_error(fop, EIO);
- }
-
- return EC_STATE_REPORT;
-
- case EC_STATE_REPORT:
- cbk = fop->answer;
-
- GF_ASSERT(cbk != NULL);
-
- if (fop->cbks.unlink != NULL)
- {
- fop->cbks.unlink(fop->req_frame, fop, fop->xl, cbk->op_ret,
- cbk->op_errno, &cbk->iatt[0], &cbk->iatt[1],
- cbk->xdata);
- }
-
- return EC_STATE_LOCK_REUSE;
-
- case -EC_STATE_INIT:
- case -EC_STATE_LOCK:
- case -EC_STATE_GET_SIZE_AND_VERSION:
- case -EC_STATE_DISPATCH:
- case -EC_STATE_PREPARE_ANSWER:
- case -EC_STATE_REPORT:
- GF_ASSERT(fop->error != 0);
-
- if (fop->cbks.unlink != NULL)
- {
- fop->cbks.unlink(fop->req_frame, fop, fop->xl, -1, fop->error,
- NULL, NULL, NULL);
- }
-
- return EC_STATE_LOCK_REUSE;
-
- case -EC_STATE_LOCK_REUSE:
- case EC_STATE_LOCK_REUSE:
- ec_lock_reuse(fop);
-
- return EC_STATE_UNLOCK;
-
- case -EC_STATE_UNLOCK:
- case EC_STATE_UNLOCK:
- ec_unlock(fop);
-
- return EC_STATE_END;
-
- default:
- gf_log(fop->xl->name, GF_LOG_ERROR, "Unhandled state %d for %s",
- state, ec_fop_name(fop->id));
-
- return EC_STATE_END;
- }
-}
-
-void ec_unlink(call_frame_t * frame, xlator_t * this, uintptr_t target,
- int32_t minimum, fop_unlink_cbk_t func, void * data,
- loc_t * loc, int xflags, dict_t * xdata)
-{
- ec_cbk_t callback = { .unlink = func };
- ec_fop_data_t * fop = NULL;
- int32_t error = EIO;
-
- gf_log("ec", GF_LOG_TRACE, "EC(UNLINK) %p", frame);
-
- VALIDATE_OR_GOTO(this, out);
- GF_VALIDATE_OR_GOTO(this->name, frame, out);
- GF_VALIDATE_OR_GOTO(this->name, this->private, out);
-
- fop = ec_fop_data_allocate(frame, this, GF_FOP_UNLINK,
- EC_FLAG_UPDATE_LOC_PARENT, target, minimum,
- ec_wind_unlink, ec_manager_unlink, callback,
- data);
- if (fop == NULL)
- {
- goto out;
- }
-
- fop->int32 = xflags;
-
- if (loc != NULL)
- {
- if (loc_copy(&fop->loc[0], loc) != 0)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to copy a location.");
-
- goto out;
- }
- }
- if (xdata != NULL)
- {
- fop->xdata = dict_ref(xdata);
- if (fop->xdata == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
- "dictionary.");
-
- goto out;
- }
- }
-
- error = 0;
-
-out:
- if (fop != NULL)
- {
- ec_manager(fop, error);
- }
- else
- {
- func(frame, NULL, this, -1, EIO, NULL, NULL, NULL);
- }
-}
diff --git a/xlators/cluster/ec/src/ec-fops.h b/xlators/cluster/ec/src/ec-fops.h
deleted file mode 100644
index d6b9770f720..00000000000
--- a/xlators/cluster/ec/src/ec-fops.h
+++ /dev/null
@@ -1,201 +0,0 @@
-/*
- Copyright (c) 2012-2014 DataLab, s.l. <http://www.datalab.es>
- 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 __EC_FOPS_H__
-#define __EC_FOPS_H__
-
-#include "xlator.h"
-
-#include "ec-data.h"
-#include "ec-common.h"
-
-#define EC_FOP_HEAL -1
-#define EC_FOP_FHEAL -2
-
-void ec_access(call_frame_t * frame, xlator_t * this, uintptr_t target,
- int32_t minimum, fop_access_cbk_t func, void *data, loc_t * loc,
- int32_t mask, dict_t * xdata);
-
-void ec_create(call_frame_t * frame, xlator_t * this, uintptr_t target,
- int32_t minimum, fop_create_cbk_t func, void *data, loc_t * loc,
- int32_t flags, mode_t mode, mode_t umask, fd_t * fd,
- dict_t * xdata);
-
-void ec_entrylk(call_frame_t * frame, xlator_t * this, uintptr_t target,
- int32_t minimum, fop_entrylk_cbk_t func, void *data,
- const char * volume, loc_t * loc, const char * basename,
- entrylk_cmd cmd, entrylk_type type, dict_t * xdata);
-
-void ec_fentrylk(call_frame_t * frame, xlator_t * this, uintptr_t target,
- int32_t minimum, fop_fentrylk_cbk_t func, void *data,
- const char * volume, fd_t * fd, const char * basename,
- entrylk_cmd cmd, entrylk_type type, dict_t * xdata);
-
-void ec_flush(call_frame_t * frame, xlator_t * this, uintptr_t target,
- int32_t minimum, fop_flush_cbk_t func, void *data, fd_t * fd,
- dict_t * xdata);
-
-void ec_fsync(call_frame_t * frame, xlator_t * this, uintptr_t target,
- int32_t minimum, fop_fsync_cbk_t func, void *data, fd_t * fd,
- int32_t datasync, dict_t * xdata);
-
-void ec_fsyncdir(call_frame_t * frame, xlator_t * this, uintptr_t target,
- int32_t minimum, fop_fsyncdir_cbk_t func, void *data,
- fd_t * fd, int32_t datasync, dict_t * xdata);
-
-void ec_getxattr(call_frame_t * frame, xlator_t * this, uintptr_t target,
- int32_t minimum, fop_getxattr_cbk_t func, void *data,
- loc_t * loc, const char * name, dict_t * xdata);
-
-void ec_fgetxattr(call_frame_t * frame, xlator_t * this, uintptr_t target,
- int32_t minimum, fop_fgetxattr_cbk_t func, void *data,
- fd_t * fd, const char * name, dict_t * xdata);
-
-void ec_heal(call_frame_t * frame, xlator_t * this, uintptr_t target,
- int32_t minimum, fop_heal_cbk_t func, void *data, loc_t * loc,
- int32_t partial, dict_t *xdata);
-
-void ec_fheal(call_frame_t * frame, xlator_t * this, uintptr_t target,
- int32_t minimum, fop_fheal_cbk_t func, void *data, fd_t * fd,
- int32_t partial, dict_t *xdata);
-
-void ec_inodelk(call_frame_t * frame, xlator_t * this, uintptr_t target,
- int32_t minimum, fop_inodelk_cbk_t func, void *data,
- const char * volume, loc_t * loc, int32_t cmd,
- struct gf_flock * flock, dict_t * xdata);
-
-void ec_finodelk(call_frame_t * frame, xlator_t * this, uintptr_t target,
- int32_t minimum, fop_finodelk_cbk_t func, void *data,
- const char * volume, fd_t * fd, int32_t cmd,
- struct gf_flock * flock, dict_t * xdata);
-
-void ec_link(call_frame_t * frame, xlator_t * this, uintptr_t target,
- int32_t minimum, fop_link_cbk_t func, void *data, loc_t * oldloc,
- loc_t * newloc, dict_t * xdata);
-
-void ec_lk(call_frame_t * frame, xlator_t * this, uintptr_t target,
- int32_t minimum, fop_lk_cbk_t func, void *data, fd_t * fd,
- int32_t cmd, struct gf_flock * flock, dict_t * xdata);
-
-void ec_lookup(call_frame_t * frame, xlator_t * this, uintptr_t target,
- int32_t minimum, fop_lookup_cbk_t func, void *data, loc_t * loc,
- dict_t * xdata);
-
-void ec_mkdir(call_frame_t * frame, xlator_t * this, uintptr_t target,
- int32_t minimum, fop_mkdir_cbk_t func, void *data, loc_t * loc,
- mode_t mode, mode_t umask, dict_t * xdata);
-
-void ec_mknod(call_frame_t * frame, xlator_t * this, uintptr_t target,
- int32_t minimum, fop_mknod_cbk_t func, void *data, loc_t * loc,
- mode_t mode, dev_t rdev, mode_t umask, dict_t * xdata);
-
-void ec_open(call_frame_t * frame, xlator_t * this, uintptr_t target,
- int32_t minimum, fop_open_cbk_t func, void *data, loc_t * loc,
- int32_t flags, fd_t * fd, dict_t * xdata);
-
-void ec_opendir(call_frame_t * frame, xlator_t * this, uintptr_t target,
- int32_t minimum, fop_opendir_cbk_t func, void *data,
- loc_t * loc, fd_t * fd, dict_t * xdata);
-
-void ec_readdir(call_frame_t * frame, xlator_t * this, uintptr_t target,
- int32_t minimum, fop_readdir_cbk_t func, void *data, fd_t * fd,
- size_t size, off_t offset, dict_t * xdata);
-
-void ec_readdirp(call_frame_t * frame, xlator_t * this, uintptr_t target,
- int32_t minimum, fop_readdirp_cbk_t func, void *data,
- fd_t * fd, size_t size, off_t offset, dict_t * xdata);
-
-void ec_readlink(call_frame_t * frame, xlator_t * this, uintptr_t target,
- int32_t minimum, fop_readlink_cbk_t func, void *data,
- loc_t * loc, size_t size, dict_t * xdata);
-
-void ec_readv(call_frame_t * frame, xlator_t * this, uintptr_t target,
- int32_t minimum, fop_readv_cbk_t func, void *data, fd_t * fd,
- size_t size, off_t offset, uint32_t flags, dict_t * xdata);
-
-void ec_removexattr(call_frame_t * frame, xlator_t * this, uintptr_t target,
- int32_t minimum, fop_removexattr_cbk_t func, void *data,
- loc_t * loc, const char * name, dict_t * xdata);
-
-void ec_fremovexattr(call_frame_t * frame, xlator_t * this, uintptr_t target,
- int32_t minimum, fop_fremovexattr_cbk_t func, void *data,
- fd_t * fd, const char * name, dict_t * xdata);
-
-void ec_rename(call_frame_t * frame, xlator_t * this, uintptr_t target,
- int32_t minimum, fop_rename_cbk_t func, void *data,
- loc_t * oldloc, loc_t * newloc, dict_t * xdata);
-
-void ec_rmdir(call_frame_t * frame, xlator_t * this, uintptr_t target,
- int32_t minimum, fop_rmdir_cbk_t func, void *data, loc_t * loc,
- int xflags, dict_t * xdata);
-
-void ec_setattr(call_frame_t * frame, xlator_t * this, uintptr_t target,
- int32_t minimum, fop_setattr_cbk_t func, void *data,
- loc_t * loc, struct iatt * stbuf, int32_t valid,
- dict_t * xdata);
-
-void ec_fsetattr(call_frame_t * frame, xlator_t * this, uintptr_t target,
- int32_t minimum, fop_fsetattr_cbk_t func, void *data,
- fd_t * fd, struct iatt * stbuf, int32_t valid,
- dict_t * xdata);
-
-void ec_setxattr(call_frame_t * frame, xlator_t * this, uintptr_t target,
- int32_t minimum, fop_setxattr_cbk_t func, void *data,
- loc_t * loc, dict_t * dict, int32_t flags, dict_t * xdata);
-
-void ec_fsetxattr(call_frame_t * frame, xlator_t * this, uintptr_t target,
- int32_t minimum, fop_fsetxattr_cbk_t func, void *data,
- fd_t * fd, dict_t * dict, int32_t flags, dict_t * xdata);
-
-void ec_stat(call_frame_t * frame, xlator_t * this, uintptr_t target,
- int32_t minimum, fop_stat_cbk_t func, void *data, loc_t * loc,
- dict_t * xdata);
-
-void ec_fstat(call_frame_t * frame, xlator_t * this, uintptr_t target,
- int32_t minimum, fop_fstat_cbk_t func, void *data, fd_t * fd,
- dict_t * xdata);
-
-void ec_statfs(call_frame_t * frame, xlator_t * this, uintptr_t target,
- int32_t minimum, fop_statfs_cbk_t func, void *data, loc_t * loc,
- dict_t * xdata);
-
-void ec_symlink(call_frame_t * frame, xlator_t * this, uintptr_t target,
- int32_t minimum, fop_symlink_cbk_t func, void *data,
- const char * linkname, loc_t * loc, mode_t umask,
- dict_t * xdata);
-
-void ec_truncate(call_frame_t * frame, xlator_t * this, uintptr_t target,
- int32_t minimum, fop_truncate_cbk_t func, void *data,
- loc_t * loc, off_t offset, dict_t * xdata);
-
-void ec_ftruncate(call_frame_t * frame, xlator_t * this, uintptr_t target,
- int32_t minimum, fop_ftruncate_cbk_t func, void *data,
- fd_t * fd, off_t offset, dict_t * xdata);
-
-void ec_unlink(call_frame_t * frame, xlator_t * this, uintptr_t target,
- int32_t minimum, fop_unlink_cbk_t func, void *data, loc_t * loc,
- int xflags, dict_t * xdata);
-
-void ec_writev(call_frame_t * frame, xlator_t * this, uintptr_t target,
- int32_t minimum, fop_writev_cbk_t func, void *data, fd_t * fd,
- struct iovec * vector, int32_t count, off_t offset,
- uint32_t flags, struct iobref * iobref, dict_t * xdata);
-
-void ec_xattrop(call_frame_t * frame, xlator_t * this, uintptr_t target,
- int32_t minimum, fop_xattrop_cbk_t func, void *data,
- loc_t * loc, gf_xattrop_flags_t optype, dict_t * xattr,
- dict_t * xdata);
-
-void ec_fxattrop(call_frame_t * frame, xlator_t * this, uintptr_t target,
- int32_t minimum, fop_fxattrop_cbk_t func, void *data,
- fd_t * fd, gf_xattrop_flags_t optype, dict_t * xattr,
- dict_t * xdata);
-
-#endif /* __EC_FOPS_H__ */
diff --git a/xlators/cluster/ec/src/ec-generic.c b/xlators/cluster/ec/src/ec-generic.c
deleted file mode 100644
index bccbc009457..00000000000
--- a/xlators/cluster/ec/src/ec-generic.c
+++ /dev/null
@@ -1,1711 +0,0 @@
-/*
- Copyright (c) 2012-2014 DataLab, s.l. <http://www.datalab.es>
- 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 "xlator.h"
-#include "defaults.h"
-
-#include "ec-helpers.h"
-#include "ec-common.h"
-#include "ec-combine.h"
-#include "ec-method.h"
-#include "ec-fops.h"
-
-/* FOP: flush */
-
-int32_t ec_flush_cbk(call_frame_t * frame, void * cookie, xlator_t * this,
- int32_t op_ret, int32_t op_errno, dict_t * xdata)
-{
- ec_fop_data_t * fop = NULL;
- ec_cbk_data_t * cbk = NULL;
- int32_t idx = (int32_t)(uintptr_t)cookie;
-
- VALIDATE_OR_GOTO(this, out);
- GF_VALIDATE_OR_GOTO(this->name, frame, out);
- GF_VALIDATE_OR_GOTO(this->name, frame->local, out);
- GF_VALIDATE_OR_GOTO(this->name, this->private, out);
-
- fop = frame->local;
-
- ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx,
- frame, op_ret, op_errno);
-
- cbk = ec_cbk_data_allocate(frame, this, fop, GF_FOP_FLUSH, idx, op_ret,
- op_errno);
- if (cbk != NULL)
- {
- if (xdata != NULL)
- {
- cbk->xdata = dict_ref(xdata);
- if (cbk->xdata == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
- "dictionary.");
-
- goto out;
- }
- }
-
- ec_combine(cbk, NULL);
- }
-
-out:
- if (fop != NULL)
- {
- ec_complete(fop);
- }
-
- return 0;
-}
-
-void ec_wind_flush(ec_t * ec, ec_fop_data_t * fop, int32_t idx)
-{
- ec_trace("WIND", fop, "idx=%d", idx);
-
- STACK_WIND_COOKIE(fop->frame, ec_flush_cbk, (void *)(uintptr_t)idx,
- ec->xl_list[idx], ec->xl_list[idx]->fops->flush, fop->fd,
- fop->xdata);
-}
-
-int32_t ec_manager_flush(ec_fop_data_t * fop, int32_t state)
-{
- ec_cbk_data_t * cbk;
-
- switch (state)
- {
- case EC_STATE_INIT:
- case EC_STATE_LOCK:
- ec_lock_prepare_fd(fop, fop->fd, 0);
- ec_lock(fop);
-
- return EC_STATE_DISPATCH;
-
- case EC_STATE_DISPATCH:
- ec_flush_size_version(fop);
-
- return EC_STATE_DELAYED_START;
-
- case EC_STATE_DELAYED_START:
- ec_dispatch_all(fop);
-
- return EC_STATE_PREPARE_ANSWER;
-
- case EC_STATE_PREPARE_ANSWER:
- cbk = fop->answer;
- if (cbk != NULL)
- {
- if (!ec_dict_combine(cbk, EC_COMBINE_XDATA))
- {
- if (cbk->op_ret >= 0)
- {
- cbk->op_ret = -1;
- cbk->op_errno = EIO;
- }
- }
- if (cbk->op_ret < 0)
- {
- ec_fop_set_error(fop, cbk->op_errno);
- }
- }
- else
- {
- ec_fop_set_error(fop, EIO);
- }
-
- return EC_STATE_REPORT;
-
- case EC_STATE_REPORT:
- cbk = fop->answer;
-
- GF_ASSERT(cbk != NULL);
-
- if (fop->cbks.flush != NULL)
- {
- fop->cbks.flush(fop->req_frame, fop, fop->xl, cbk->op_ret,
- cbk->op_errno, cbk->xdata);
- }
-
- return EC_STATE_LOCK_REUSE;
-
- case -EC_STATE_INIT:
- case -EC_STATE_LOCK:
- case -EC_STATE_DISPATCH:
- case -EC_STATE_PREPARE_ANSWER:
- case -EC_STATE_REPORT:
- GF_ASSERT(fop->error != 0);
-
- if (fop->cbks.flush != NULL)
- {
- fop->cbks.flush(fop->req_frame, fop, fop->xl, -1, fop->error,
- NULL);
- }
-
- return EC_STATE_LOCK_REUSE;
-
- case -EC_STATE_LOCK_REUSE:
- case EC_STATE_LOCK_REUSE:
- ec_lock_reuse(fop);
-
- return EC_STATE_UNLOCK;
-
- case -EC_STATE_UNLOCK:
- case EC_STATE_UNLOCK:
- ec_unlock(fop);
-
- return EC_STATE_END;
-
- default:
- gf_log(fop->xl->name, GF_LOG_ERROR, "Unhandled state %d for %s",
- state, ec_fop_name(fop->id));
-
- return EC_STATE_END;
- }
-}
-
-void ec_flush(call_frame_t * frame, xlator_t * this, uintptr_t target,
- int32_t minimum, fop_flush_cbk_t func, void * data, fd_t * fd,
- dict_t * xdata)
-{
- ec_cbk_t callback = { .flush = func };
- ec_fop_data_t * fop = NULL;
- int32_t error = EIO;
-
- gf_log("ec", GF_LOG_TRACE, "EC(FLUSH) %p", frame);
-
- VALIDATE_OR_GOTO(this, out);
- GF_VALIDATE_OR_GOTO(this->name, frame, out);
- GF_VALIDATE_OR_GOTO(this->name, this->private, out);
-
- fop = ec_fop_data_allocate(frame, this, GF_FOP_FLUSH, EC_FLAG_UPDATE_FD,
- target, minimum, ec_wind_flush,
- ec_manager_flush, callback, data);
- if (fop == NULL)
- {
- goto out;
- }
-
- fop->use_fd = 1;
-
- if (fd != NULL)
- {
- fop->fd = fd_ref(fd);
- if (fop->fd == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
- "file descriptor.");
-
- goto out;
- }
- }
- if (xdata != NULL)
- {
- fop->xdata = dict_ref(xdata);
- if (fop->xdata == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
- "dictionary.");
-
- goto out;
- }
- }
-
- error = 0;
-
-out:
- if (fop != NULL)
- {
- ec_manager(fop, error);
- }
- else
- {
- func(frame, NULL, this, -1, EIO, NULL);
- }
-}
-
-/* FOP: fsync */
-
-int32_t ec_combine_fsync(ec_fop_data_t * fop, ec_cbk_data_t * dst,
- ec_cbk_data_t * src)
-{
- if (!ec_iatt_combine(dst->iatt, src->iatt, 2))
- {
- gf_log(fop->xl->name, GF_LOG_NOTICE, "Mismatching iatt in "
- "answers of 'GF_FOP_FSYNC'");
-
- return 0;
- }
-
- return 1;
-}
-
-int32_t ec_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)
-{
- ec_fop_data_t * fop = NULL;
- ec_cbk_data_t * cbk = NULL;
- int32_t idx = (int32_t)(uintptr_t)cookie;
-
- VALIDATE_OR_GOTO(this, out);
- GF_VALIDATE_OR_GOTO(this->name, frame, out);
- GF_VALIDATE_OR_GOTO(this->name, frame->local, out);
- GF_VALIDATE_OR_GOTO(this->name, this->private, out);
-
- fop = frame->local;
-
- ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx,
- frame, op_ret, op_errno);
-
- cbk = ec_cbk_data_allocate(frame, this, fop, GF_FOP_FSYNC, idx, op_ret,
- op_errno);
- if (cbk != NULL)
- {
- if (op_ret >= 0)
- {
- if (prebuf != NULL)
- {
- cbk->iatt[0] = *prebuf;
- }
- if (postbuf != NULL)
- {
- cbk->iatt[1] = *postbuf;
- }
- }
- if (xdata != NULL)
- {
- cbk->xdata = dict_ref(xdata);
- if (cbk->xdata == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
- "dictionary.");
-
- goto out;
- }
- }
-
- ec_combine(cbk, ec_combine_fsync);
- }
-
-out:
- if (fop != NULL)
- {
- ec_complete(fop);
- }
-
- return 0;
-}
-
-void ec_wind_fsync(ec_t * ec, ec_fop_data_t * fop, int32_t idx)
-{
- ec_trace("WIND", fop, "idx=%d", idx);
-
- STACK_WIND_COOKIE(fop->frame, ec_fsync_cbk, (void *)(uintptr_t)idx,
- ec->xl_list[idx], ec->xl_list[idx]->fops->fsync, fop->fd,
- fop->int32, fop->xdata);
-}
-
-int32_t ec_manager_fsync(ec_fop_data_t * fop, int32_t state)
-{
- ec_cbk_data_t * cbk;
-
- switch (state)
- {
- case EC_STATE_INIT:
- case EC_STATE_LOCK:
- ec_lock_prepare_fd(fop, fop->fd, 0);
- ec_lock(fop);
-
- return EC_STATE_GET_SIZE_AND_VERSION;
-
- case EC_STATE_GET_SIZE_AND_VERSION:
- ec_get_size_version(fop);
-
- return EC_STATE_DISPATCH;
-
- case EC_STATE_DISPATCH:
- ec_flush_size_version(fop);
-
- return EC_STATE_DELAYED_START;
-
- case EC_STATE_DELAYED_START:
- ec_dispatch_all(fop);
-
- return EC_STATE_PREPARE_ANSWER;
-
- case EC_STATE_PREPARE_ANSWER:
- cbk = fop->answer;
- if (cbk != NULL)
- {
- if (!ec_dict_combine(cbk, EC_COMBINE_XDATA))
- {
- if (cbk->op_ret >= 0)
- {
- cbk->op_ret = -1;
- cbk->op_errno = EIO;
- }
- }
- if (cbk->op_ret < 0)
- {
- ec_fop_set_error(fop, cbk->op_errno);
- }
- else
- {
- ec_iatt_rebuild(fop->xl->private, cbk->iatt, 2,
- cbk->count);
-
- cbk->iatt[0].ia_size = fop->pre_size;
- cbk->iatt[1].ia_size = fop->post_size;
- }
- }
- else
- {
- ec_fop_set_error(fop, EIO);
- }
-
- return EC_STATE_REPORT;
-
- case EC_STATE_REPORT:
- cbk = fop->answer;
-
- GF_ASSERT(cbk != NULL);
-
- if (fop->cbks.fsync != NULL)
- {
- fop->cbks.fsync(fop->req_frame, fop, fop->xl, cbk->op_ret,
- cbk->op_errno, &cbk->iatt[0], &cbk->iatt[1],
- cbk->xdata);
- }
-
- return EC_STATE_LOCK_REUSE;
-
- case -EC_STATE_INIT:
- case -EC_STATE_LOCK:
- case -EC_STATE_GET_SIZE_AND_VERSION:
- case -EC_STATE_DISPATCH:
- case -EC_STATE_PREPARE_ANSWER:
- case -EC_STATE_REPORT:
- GF_ASSERT(fop->error != 0);
-
- if (fop->cbks.fsync != NULL)
- {
- fop->cbks.fsync(fop->req_frame, fop, fop->xl, -1, fop->error,
- NULL, NULL, NULL);
- }
-
- return EC_STATE_LOCK_REUSE;
-
- case -EC_STATE_LOCK_REUSE:
- case EC_STATE_LOCK_REUSE:
- ec_lock_reuse(fop);
-
- return EC_STATE_UNLOCK;
-
- case -EC_STATE_UNLOCK:
- case EC_STATE_UNLOCK:
- ec_unlock(fop);
-
- return EC_STATE_END;
-
- default:
- gf_log(fop->xl->name, GF_LOG_ERROR, "Unhandled state %d for %s",
- state, ec_fop_name(fop->id));
-
- return EC_STATE_END;
- }
-}
-
-void ec_fsync(call_frame_t * frame, xlator_t * this, uintptr_t target,
- int32_t minimum, fop_fsync_cbk_t func, void * data, fd_t * fd,
- int32_t datasync, dict_t * xdata)
-{
- ec_cbk_t callback = { .fsync = func };
- ec_fop_data_t * fop = NULL;
- int32_t error = EIO;
-
- gf_log("ec", GF_LOG_TRACE, "EC(FSYNC) %p", frame);
-
- VALIDATE_OR_GOTO(this, out);
- GF_VALIDATE_OR_GOTO(this->name, frame, out);
- GF_VALIDATE_OR_GOTO(this->name, this->private, out);
-
- fop = ec_fop_data_allocate(frame, this, GF_FOP_FSYNC, EC_FLAG_UPDATE_FD,
- target, minimum, ec_wind_fsync,
- ec_manager_fsync, callback, data);
- if (fop == NULL)
- {
- goto out;
- }
-
- fop->use_fd = 1;
-
- fop->int32 = datasync;
-
- if (fd != NULL)
- {
- fop->fd = fd_ref(fd);
- if (fop->fd == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
- "file descriptor.");
-
- goto out;
- }
- }
- if (xdata != NULL)
- {
- fop->xdata = dict_ref(xdata);
- if (fop->xdata == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
- "dictionary.");
-
- goto out;
- }
- }
-
- error = 0;
-
-out:
- if (fop != NULL)
- {
- ec_manager(fop, error);
- }
- else
- {
- func(frame, NULL, this, -1, EIO, NULL, NULL, NULL);
- }
-}
-
-/* FOP: fsyncdir */
-
-int32_t ec_fsyncdir_cbk(call_frame_t * frame, void * cookie, xlator_t * this,
- int32_t op_ret, int32_t op_errno, dict_t * xdata)
-{
- ec_fop_data_t * fop = NULL;
- ec_cbk_data_t * cbk = NULL;
- int32_t idx = (int32_t)(uintptr_t)cookie;
-
- VALIDATE_OR_GOTO(this, out);
- GF_VALIDATE_OR_GOTO(this->name, frame, out);
- GF_VALIDATE_OR_GOTO(this->name, frame->local, out);
- GF_VALIDATE_OR_GOTO(this->name, this->private, out);
-
- fop = frame->local;
-
- ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx,
- frame, op_ret, op_errno);
-
- cbk = ec_cbk_data_allocate(frame, this, fop, GF_FOP_FSYNCDIR, idx, op_ret,
- op_errno);
- if (cbk != NULL)
- {
- if (xdata != NULL)
- {
- cbk->xdata = dict_ref(xdata);
- if (cbk->xdata == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
- "dictionary.");
-
- goto out;
- }
- }
-
- ec_combine(cbk, NULL);
- }
-
-out:
- if (fop != NULL)
- {
- ec_complete(fop);
- }
-
- return 0;
-}
-
-void ec_wind_fsyncdir(ec_t * ec, ec_fop_data_t * fop, int32_t idx)
-{
- ec_trace("WIND", fop, "idx=%d", idx);
-
- STACK_WIND_COOKIE(fop->frame, ec_fsyncdir_cbk, (void *)(uintptr_t)idx,
- ec->xl_list[idx], ec->xl_list[idx]->fops->fsyncdir,
- fop->fd, fop->int32, fop->xdata);
-}
-
-int32_t ec_manager_fsyncdir(ec_fop_data_t * fop, int32_t state)
-{
- ec_cbk_data_t * cbk;
-
- switch (state)
- {
- case EC_STATE_INIT:
- case EC_STATE_LOCK:
- ec_lock_prepare_fd(fop, fop->fd, 0);
- ec_lock(fop);
-
- return EC_STATE_DISPATCH;
-
- case EC_STATE_DISPATCH:
- ec_flush_size_version(fop);
-
- return EC_STATE_DELAYED_START;
-
- case EC_STATE_DELAYED_START:
- ec_dispatch_all(fop);
-
- return EC_STATE_PREPARE_ANSWER;
-
- case EC_STATE_PREPARE_ANSWER:
- cbk = fop->answer;
- if (cbk != NULL)
- {
- if (!ec_dict_combine(cbk, EC_COMBINE_XDATA))
- {
- if (cbk->op_ret >= 0)
- {
- cbk->op_ret = -1;
- cbk->op_errno = EIO;
- }
- }
- if (cbk->op_ret < 0)
- {
- ec_fop_set_error(fop, cbk->op_errno);
- }
- }
- else
- {
- ec_fop_set_error(fop, EIO);
- }
-
- return EC_STATE_REPORT;
-
- case EC_STATE_REPORT:
- cbk = fop->answer;
-
- GF_ASSERT(cbk != NULL);
-
- if (fop->cbks.fsyncdir != NULL)
- {
- fop->cbks.fsyncdir(fop->req_frame, fop, fop->xl, cbk->op_ret,
- cbk->op_errno, cbk->xdata);
- }
-
- return EC_STATE_LOCK_REUSE;
-
- case -EC_STATE_INIT:
- case -EC_STATE_LOCK:
- case -EC_STATE_DISPATCH:
- case -EC_STATE_PREPARE_ANSWER:
- case -EC_STATE_REPORT:
- GF_ASSERT(fop->error != 0);
-
- if (fop->cbks.fsyncdir != NULL)
- {
- fop->cbks.fsyncdir(fop->req_frame, fop, fop->xl, -1,
- fop->error, NULL);
- }
-
- return EC_STATE_LOCK_REUSE;
-
- case -EC_STATE_LOCK_REUSE:
- case EC_STATE_LOCK_REUSE:
- ec_lock_reuse(fop);
-
- return EC_STATE_UNLOCK;
-
- case -EC_STATE_UNLOCK:
- case EC_STATE_UNLOCK:
- ec_unlock(fop);
-
- return EC_STATE_END;
-
- default:
- gf_log(fop->xl->name, GF_LOG_ERROR, "Unhandled state %d for %s",
- state, ec_fop_name(fop->id));
-
- return EC_STATE_END;
- }
-}
-
-void ec_fsyncdir(call_frame_t * frame, xlator_t * this, uintptr_t target,
- int32_t minimum, fop_fsyncdir_cbk_t func, void * data,
- fd_t * fd, int32_t datasync, dict_t * xdata)
-{
- ec_cbk_t callback = { .fsyncdir = func };
- ec_fop_data_t * fop = NULL;
- int32_t error = EIO;
-
- gf_log("ec", GF_LOG_TRACE, "EC(FSYNCDIR) %p", frame);
-
- VALIDATE_OR_GOTO(this, out);
- GF_VALIDATE_OR_GOTO(this->name, frame, out);
- GF_VALIDATE_OR_GOTO(this->name, this->private, out);
-
- fop = ec_fop_data_allocate(frame, this, GF_FOP_FSYNCDIR, EC_FLAG_UPDATE_FD,
- target, minimum, ec_wind_fsyncdir,
- ec_manager_fsyncdir, callback, data);
- if (fop == NULL)
- {
- goto out;
- }
-
- fop->use_fd = 1;
-
- fop->int32 = datasync;
-
- if (fd != NULL)
- {
- fop->fd = fd_ref(fd);
- if (fop->fd == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
- "file descriptor.");
-
- goto out;
- }
- }
- if (xdata != NULL)
- {
- fop->xdata = dict_ref(xdata);
- if (fop->xdata == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
- "dictionary.");
-
- goto out;
- }
- }
-
- error = 0;
-
-out:
- if (fop != NULL)
- {
- ec_manager(fop, error);
- }
- else
- {
- func(frame, NULL, this, -1, EIO, NULL);
- }
-}
-
-/* FOP: lookup */
-
-void ec_lookup_rebuild(ec_t * ec, ec_fop_data_t * fop, ec_cbk_data_t * cbk)
-{
- ec_cbk_data_t * ans = NULL;
- ec_inode_t * ctx = NULL;
- ec_lock_t * lock = NULL;
- data_t * data = NULL;
- uint8_t * buff = NULL;
- uint64_t size = 0;
- int32_t i = 0, have_size = 0;
-
- if (cbk->op_ret < 0)
- {
- return;
- }
-
- ec_dict_del_number(cbk->xdata, EC_XATTR_VERSION, &cbk->version);
-
- if (ec_loc_update(fop->xl, &fop->loc[0], cbk->inode, &cbk->iatt[0]) != 0) {
- cbk->op_ret = -1;
- cbk->op_errno = EIO;
-
- return;
- }
-
- LOCK(&cbk->inode->lock);
-
- ctx = __ec_inode_get(cbk->inode, fop->xl);
- if ((ctx != NULL) && (ctx->inode_lock != NULL))
- {
- lock = ctx->inode_lock;
- cbk->version = lock->version;
- if (lock->have_size)
- {
- size = lock->size;
- have_size = 1;
- }
- }
-
- UNLOCK(&cbk->inode->lock);
-
- if (cbk->iatt[0].ia_type == IA_IFREG)
- {
- uint8_t * blocks[cbk->count];
- uint32_t values[cbk->count];
-
- cbk->size = cbk->iatt[0].ia_size;
- ec_dict_del_number(cbk->xdata, EC_XATTR_SIZE, &cbk->iatt[0].ia_size);
- if (have_size)
- {
- cbk->iatt[0].ia_size = size;
- }
-
- size = UINT64_MAX;
- for (i = 0, ans = cbk; (ans != NULL) && (i < ec->fragments);
- ans = ans->next)
- {
- data = dict_get(ans->xdata, GF_CONTENT_KEY);
- if (data != NULL)
- {
- values[i] = ans->idx;
- blocks[i] = (uint8_t *)data->data;
- if (size > data->len)
- {
- size = data->len;
- }
- i++;
- }
- }
-
- if (i >= ec->fragments)
- {
- size -= size % ec->fragment_size;
- if (size > 0)
- {
- buff = GF_MALLOC(size * ec->fragments, gf_common_mt_char);
- if (buff != NULL)
- {
- size = ec_method_decode(size, ec->fragments, values,
- blocks, buff);
- if (size > fop->size)
- {
- size = fop->size;
- }
- if (size > cbk->iatt[0].ia_size)
- {
- size = cbk->iatt[0].ia_size;
- }
-
- if (dict_set_bin(cbk->xdata, GF_CONTENT_KEY, buff,
- size) != 0)
- {
- GF_FREE(buff);
- buff = NULL;
- gf_log(fop->xl->name, GF_LOG_WARNING, "Lookup "
- "read-ahead "
- "failed");
- }
- }
- else
- {
- gf_log(fop->xl->name, GF_LOG_WARNING, "Lookup read-ahead "
- "failed");
- }
- }
- }
-
- if (buff == NULL)
- {
- dict_del(cbk->xdata, GF_CONTENT_KEY);
- }
- }
-}
-
-int32_t ec_combine_lookup(ec_fop_data_t * fop, ec_cbk_data_t * dst,
- ec_cbk_data_t * src)
-{
- if (!ec_iatt_combine(dst->iatt, src->iatt, 2))
- {
- gf_log(fop->xl->name, GF_LOG_NOTICE, "Mismatching iatt in "
- "answers of 'GF_FOP_LOOKUP'");
-
- return 0;
- }
-
- return 1;
-}
-
-int32_t ec_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)
-{
- ec_fop_data_t * fop = NULL;
- ec_cbk_data_t * cbk = NULL;
- int32_t idx = (int32_t)(uintptr_t)cookie;
-
- VALIDATE_OR_GOTO(this, out);
- GF_VALIDATE_OR_GOTO(this->name, frame, out);
- GF_VALIDATE_OR_GOTO(this->name, frame->local, out);
- GF_VALIDATE_OR_GOTO(this->name, this->private, out);
-
- fop = frame->local;
-
- ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx,
- frame, op_ret, op_errno);
-
- cbk = ec_cbk_data_allocate(frame, this, fop, GF_FOP_LOOKUP, idx, op_ret,
- op_errno);
- if (cbk != NULL)
- {
- if (op_ret >= 0)
- {
- if (inode != NULL)
- {
- cbk->inode = inode_ref(inode);
- if (cbk->inode == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR,
- "Failed to reference an inode.");
-
- goto out;
- }
- }
- if (buf != NULL)
- {
- cbk->iatt[0] = *buf;
- }
- if (postparent != NULL)
- {
- cbk->iatt[1] = *postparent;
- }
- }
- if (xdata != NULL)
- {
- cbk->xdata = dict_ref(xdata);
- if (cbk->xdata == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
- "dictionary.");
-
- goto out;
- }
- }
-
- ec_combine(cbk, ec_combine_lookup);
- }
-
-out:
- if (fop != NULL)
- {
- ec_complete(fop);
- }
-
- return 0;
-}
-
-void ec_wind_lookup(ec_t * ec, ec_fop_data_t * fop, int32_t idx)
-{
- ec_trace("WIND", fop, "idx=%d", idx);
-
- STACK_WIND_COOKIE(fop->frame, ec_lookup_cbk, (void *)(uintptr_t)idx,
- ec->xl_list[idx], ec->xl_list[idx]->fops->lookup,
- &fop->loc[0], fop->xdata);
-}
-
-int32_t ec_manager_lookup(ec_fop_data_t * fop, int32_t state)
-{
- ec_cbk_data_t * cbk;
-
- switch (state)
- {
- case EC_STATE_INIT:
- if (fop->xdata == NULL)
- {
- fop->xdata = dict_new();
- if (fop->xdata == NULL)
- {
- gf_log(fop->xl->name, GF_LOG_ERROR, "Unable to prepare "
- "lookup request");
-
- fop->error = EIO;
-
- return EC_STATE_REPORT;
- }
- }
- else
- {
- uint64_t size;
-
- if (dict_get_uint64(fop->xdata, GF_CONTENT_KEY, &size) == 0)
- {
- fop->size = size;
- size = ec_adjust_size(fop->xl->private, size, 1);
- if (dict_set_uint64(fop->xdata, GF_CONTENT_KEY, size) != 0)
- {
- gf_log("ec", GF_LOG_DEBUG, "Unable to update lookup "
- "content size");
- }
- }
- }
- if ((dict_set_uint64(fop->xdata, EC_XATTR_SIZE, 0) != 0) ||
- (dict_set_uint64(fop->xdata, EC_XATTR_VERSION, 0) != 0))
- {
- gf_log(fop->xl->name, GF_LOG_ERROR, "Unable to prepare lookup "
- "request");
-
- fop->error = EIO;
-
- return EC_STATE_REPORT;
- }
-
- /* Fall through */
-
- case EC_STATE_DISPATCH:
- ec_dispatch_all(fop);
-
- return EC_STATE_PREPARE_ANSWER;
-
- case EC_STATE_PREPARE_ANSWER:
- cbk = fop->answer;
- if (cbk != NULL)
- {
- if (!ec_dict_combine(cbk, EC_COMBINE_XDATA))
- {
- if (cbk->op_ret >= 0)
- {
- cbk->op_ret = -1;
- cbk->op_errno = EIO;
- }
- }
- if (cbk->op_ret < 0)
- {
- ec_fop_set_error(fop, cbk->op_errno);
- }
- else
- {
- ec_iatt_rebuild(fop->xl->private, cbk->iatt, 2,
- cbk->count);
-
- ec_lookup_rebuild(fop->xl->private, fop, cbk);
- }
- }
- else
- {
- ec_fop_set_error(fop, EIO);
- }
-
- return EC_STATE_REPORT;
-
- case EC_STATE_REPORT:
- cbk = fop->answer;
-
- GF_ASSERT(cbk != NULL);
-
- if (fop->cbks.lookup != NULL)
- {
- fop->cbks.lookup(fop->req_frame, fop, fop->xl, cbk->op_ret,
- cbk->op_errno, cbk->inode, &cbk->iatt[0],
- cbk->xdata, &cbk->iatt[1]);
- }
-
- return EC_STATE_END;
-
- case -EC_STATE_INIT:
- case -EC_STATE_DISPATCH:
- case -EC_STATE_PREPARE_ANSWER:
- case -EC_STATE_REPORT:
- GF_ASSERT(fop->error != 0);
-
- if (fop->cbks.lookup != NULL)
- {
- fop->cbks.lookup(fop->req_frame, fop, fop->xl, -1, fop->error,
- NULL, NULL, NULL, NULL);
- }
-
- return EC_STATE_END;
-
- default:
- gf_log(fop->xl->name, GF_LOG_ERROR, "Unhandled state %d for %s",
- state, ec_fop_name(fop->id));
-
- return EC_STATE_END;
- }
-}
-
-void ec_lookup(call_frame_t * frame, xlator_t * this, uintptr_t target,
- int32_t minimum, fop_lookup_cbk_t func, void * data,
- loc_t * loc, dict_t * xdata)
-{
- ec_cbk_t callback = { .lookup = func };
- ec_fop_data_t * fop = NULL;
- int32_t error = EIO;
-
- gf_log("ec", GF_LOG_TRACE, "EC(LOOKUP) %p", frame);
-
- VALIDATE_OR_GOTO(this, out);
- GF_VALIDATE_OR_GOTO(this->name, frame, out);
- GF_VALIDATE_OR_GOTO(this->name, this->private, out);
-
- fop = ec_fop_data_allocate(frame, this, GF_FOP_LOOKUP, 0, target, minimum,
- ec_wind_lookup, ec_manager_lookup, callback,
- data);
- if (fop == NULL)
- {
- goto out;
- }
-
- if (loc != NULL)
- {
- if (loc_copy(&fop->loc[0], loc) != 0)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to copy a location.");
-
- goto out;
- }
- }
- if (xdata != NULL)
- {
- fop->xdata = dict_ref(xdata);
- if (fop->xdata == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
- "dictionary.");
-
- goto out;
- }
- }
-
- error = 0;
-
-out:
- if (fop != NULL)
- {
- ec_manager(fop, error);
- }
- else
- {
- func(frame, NULL, this, -1, EIO, NULL, NULL, NULL, NULL);
- }
-}
-
-/* FOP: statfs */
-
-int32_t ec_combine_statfs(ec_fop_data_t * fop, ec_cbk_data_t * dst,
- ec_cbk_data_t * src)
-{
- ec_statvfs_combine(&dst->statvfs, &src->statvfs);
-
- return 1;
-}
-
-int32_t ec_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)
-{
- ec_fop_data_t * fop = NULL;
- ec_cbk_data_t * cbk = NULL;
- int32_t idx = (int32_t)(uintptr_t)cookie;
-
- VALIDATE_OR_GOTO(this, out);
- GF_VALIDATE_OR_GOTO(this->name, frame, out);
- GF_VALIDATE_OR_GOTO(this->name, frame->local, out);
- GF_VALIDATE_OR_GOTO(this->name, this->private, out);
-
- fop = frame->local;
-
- ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx,
- frame, op_ret, op_errno);
-
- cbk = ec_cbk_data_allocate(frame, this, fop, GF_FOP_STATFS, idx, op_ret,
- op_errno);
- if (cbk != NULL)
- {
- if (op_ret >= 0)
- {
- if (buf != NULL)
- {
- cbk->statvfs = *buf;
- }
- }
- if (xdata != NULL)
- {
- cbk->xdata = dict_ref(xdata);
- if (cbk->xdata == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
- "dictionary.");
-
- goto out;
- }
- }
-
- ec_combine(cbk, ec_combine_statfs);
- }
-
-out:
- if (fop != NULL)
- {
- ec_complete(fop);
- }
-
- return 0;
-}
-
-void ec_wind_statfs(ec_t * ec, ec_fop_data_t * fop, int32_t idx)
-{
- ec_trace("WIND", fop, "idx=%d", idx);
-
- STACK_WIND_COOKIE(fop->frame, ec_statfs_cbk, (void *)(uintptr_t)idx,
- ec->xl_list[idx], ec->xl_list[idx]->fops->statfs,
- &fop->loc[0], fop->xdata);
-}
-
-int32_t ec_manager_statfs(ec_fop_data_t * fop, int32_t state)
-{
- ec_cbk_data_t * cbk;
-
- switch (state)
- {
- case EC_STATE_INIT:
- case EC_STATE_DISPATCH:
- ec_dispatch_all(fop);
-
- return EC_STATE_PREPARE_ANSWER;
-
- case EC_STATE_PREPARE_ANSWER:
- cbk = fop->answer;
- if (cbk != NULL)
- {
- if (!ec_dict_combine(cbk, EC_COMBINE_XDATA))
- {
- if (cbk->op_ret >= 0)
- {
- cbk->op_ret = -1;
- cbk->op_errno = EIO;
- }
- }
- if (cbk->op_ret < 0)
- {
- ec_fop_set_error(fop, cbk->op_errno);
- }
- else
- {
- ec_t * ec = fop->xl->private;
-
- cbk->statvfs.f_blocks *= ec->fragments;
- cbk->statvfs.f_bfree *= ec->fragments;
- cbk->statvfs.f_bavail *= ec->fragments;
- }
- }
- else
- {
- ec_fop_set_error(fop, EIO);
- }
-
- return EC_STATE_REPORT;
-
- case EC_STATE_REPORT:
- cbk = fop->answer;
-
- GF_ASSERT(cbk != NULL);
-
- if (fop->cbks.statfs != NULL)
- {
- fop->cbks.statfs(fop->req_frame, fop, fop->xl, cbk->op_ret,
- cbk->op_errno, &cbk->statvfs, cbk->xdata);
- }
-
- return EC_STATE_END;
-
- case -EC_STATE_INIT:
- case -EC_STATE_DISPATCH:
- case -EC_STATE_PREPARE_ANSWER:
- case -EC_STATE_REPORT:
- GF_ASSERT(fop->error != 0);
-
- if (fop->cbks.statfs != NULL)
- {
- fop->cbks.statfs(fop->req_frame, fop, fop->xl, -1, fop->error,
- NULL, NULL);
- }
-
- return EC_STATE_END;
-
- default:
- gf_log(fop->xl->name, GF_LOG_ERROR, "Unhandled state %d for %s",
- state, ec_fop_name(fop->id));
-
- return EC_STATE_END;
- }
-}
-
-void ec_statfs(call_frame_t * frame, xlator_t * this, uintptr_t target,
- int32_t minimum, fop_statfs_cbk_t func, void * data,
- loc_t * loc, dict_t * xdata)
-{
- ec_cbk_t callback = { .statfs = func };
- ec_fop_data_t * fop = NULL;
- int32_t error = EIO;
-
- gf_log("ec", GF_LOG_TRACE, "EC(STATFS) %p", frame);
-
- VALIDATE_OR_GOTO(this, out);
- GF_VALIDATE_OR_GOTO(this->name, frame, out);
- GF_VALIDATE_OR_GOTO(this->name, this->private, out);
-
- fop = ec_fop_data_allocate(frame, this, GF_FOP_STATFS, 0, target, minimum,
- ec_wind_statfs, ec_manager_statfs, callback,
- data);
- if (fop == NULL)
- {
- goto out;
- }
-
- if (loc != NULL)
- {
- if (loc_copy(&fop->loc[0], loc) != 0)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to copy a location.");
-
- goto out;
- }
- }
- if (xdata != NULL)
- {
- fop->xdata = dict_ref(xdata);
- if (fop->xdata == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
- "dictionary.");
-
- goto out;
- }
- }
-
- error = 0;
-
-out:
- if (fop != NULL)
- {
- ec_manager(fop, error);
- }
- else
- {
- func(frame, NULL, this, -1, EIO, NULL, NULL);
- }
-}
-
-/* FOP: xattrop */
-
-int32_t ec_combine_xattrop(ec_fop_data_t * fop, ec_cbk_data_t * dst,
- ec_cbk_data_t * src)
-{
- if (!ec_dict_compare(dst->dict, src->dict))
- {
- gf_log(fop->xl->name, GF_LOG_NOTICE, "Mismatching dictionary in "
- "answers of 'GF_FOP_XATTROP'");
-
- return 0;
- }
-
- return 1;
-}
-
-int32_t ec_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)
-{
- ec_fop_data_t * fop = NULL;
- ec_cbk_data_t * cbk = NULL;
- int32_t idx = (int32_t)(uintptr_t)cookie;
-
- VALIDATE_OR_GOTO(this, out);
- GF_VALIDATE_OR_GOTO(this->name, frame, out);
- GF_VALIDATE_OR_GOTO(this->name, frame->local, out);
- GF_VALIDATE_OR_GOTO(this->name, this->private, out);
-
- fop = frame->local;
-
- ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx,
- frame, op_ret, op_errno);
-
- cbk = ec_cbk_data_allocate(frame, this, fop, GF_FOP_XATTROP, idx, op_ret,
- op_errno);
- if (cbk != NULL)
- {
- if (op_ret >= 0)
- {
- if (xattr != NULL)
- {
- cbk->dict = dict_ref(xattr);
- if (cbk->dict == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
- "dictionary.");
-
- goto out;
- }
- }
- }
- if (xdata != NULL)
- {
- cbk->xdata = dict_ref(xdata);
- if (cbk->xdata == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
- "dictionary.");
-
- goto out;
- }
- }
-
- ec_combine(cbk, ec_combine_xattrop);
- }
-
-out:
- if (fop != NULL)
- {
- ec_complete(fop);
- }
-
- return 0;
-}
-
-void ec_wind_xattrop(ec_t * ec, ec_fop_data_t * fop, int32_t idx)
-{
- ec_trace("WIND", fop, "idx=%d", idx);
-
- STACK_WIND_COOKIE(fop->frame, ec_xattrop_cbk, (void *)(uintptr_t)idx,
- ec->xl_list[idx], ec->xl_list[idx]->fops->xattrop,
- &fop->loc[0], fop->xattrop_flags, fop->dict, fop->xdata);
-}
-
-int32_t ec_manager_xattrop(ec_fop_data_t * fop, int32_t state)
-{
- ec_cbk_data_t * cbk;
-
- switch (state)
- {
- case EC_STATE_INIT:
- case EC_STATE_LOCK:
- if (fop->fd == NULL)
- {
- ec_lock_prepare_inode(fop, &fop->loc[0], 1);
- }
- else
- {
- ec_lock_prepare_fd(fop, fop->fd, 1);
- }
- ec_lock(fop);
-
- return EC_STATE_DISPATCH;
-
- case EC_STATE_DISPATCH:
- ec_dispatch_all(fop);
-
- return EC_STATE_PREPARE_ANSWER;
-
- case EC_STATE_PREPARE_ANSWER:
- cbk = fop->answer;
- if (cbk != NULL)
- {
- if (!ec_dict_combine(cbk, EC_COMBINE_XDATA) ||
- ((cbk->op_ret >= 0) && !ec_dict_combine(cbk,
- EC_COMBINE_DICT)))
- {
- if (cbk->op_ret >= 0)
- {
- cbk->op_ret = -1;
- cbk->op_errno = EIO;
- }
- }
- if (cbk->op_ret < 0)
- {
- ec_fop_set_error(fop, cbk->op_errno);
- }
- }
- else
- {
- ec_fop_set_error(fop, EIO);
- }
-
- return EC_STATE_REPORT;
-
- case EC_STATE_REPORT:
- cbk = fop->answer;
-
- GF_ASSERT(cbk != NULL);
-
- if (fop->id == GF_FOP_XATTROP)
- {
- if (fop->cbks.xattrop != NULL)
- {
- fop->cbks.xattrop(fop->req_frame, fop, fop->xl,
- cbk->op_ret, cbk->op_errno, cbk->dict,
- cbk->xdata);
- }
- }
- else
- {
- if (fop->cbks.fxattrop != NULL)
- {
- fop->cbks.fxattrop(fop->req_frame, fop, fop->xl,
- cbk->op_ret, cbk->op_errno, cbk->dict,
- cbk->xdata);
- }
- }
-
- return EC_STATE_LOCK_REUSE;
-
- case -EC_STATE_INIT:
- case -EC_STATE_LOCK:
- case -EC_STATE_DISPATCH:
- case -EC_STATE_PREPARE_ANSWER:
- case -EC_STATE_REPORT:
- GF_ASSERT(fop->error != 0);
-
- if (fop->id == GF_FOP_XATTROP)
- {
- if (fop->cbks.xattrop != NULL)
- {
- fop->cbks.xattrop(fop->req_frame, fop, fop->xl, -1,
- fop->error, NULL, NULL);
- }
- }
- else
- {
- if (fop->cbks.fxattrop != NULL)
- {
- fop->cbks.fxattrop(fop->req_frame, fop, fop->xl, -1,
- fop->error, NULL, NULL);
- }
- }
-
- return EC_STATE_LOCK_REUSE;
-
- case -EC_STATE_LOCK_REUSE:
- case EC_STATE_LOCK_REUSE:
- ec_lock_reuse(fop);
-
- return EC_STATE_UNLOCK;
-
- case -EC_STATE_UNLOCK:
- case EC_STATE_UNLOCK:
- ec_unlock(fop);
-
- return EC_STATE_END;
-
- default:
- gf_log(fop->xl->name, GF_LOG_ERROR, "Unhandled state %d for %s",
- state, ec_fop_name(fop->id));
-
- return EC_STATE_END;
- }
-}
-
-void ec_xattrop(call_frame_t * frame, xlator_t * this, uintptr_t target,
- int32_t minimum, fop_xattrop_cbk_t func, void * data,
- loc_t * loc, gf_xattrop_flags_t optype, dict_t * xattr,
- dict_t * xdata)
-{
- ec_cbk_t callback = { .xattrop = func };
- ec_fop_data_t * fop = NULL;
- int32_t error = EIO;
-
- gf_log("ec", GF_LOG_TRACE, "EC(XATTROP) %p", frame);
-
- VALIDATE_OR_GOTO(this, out);
- GF_VALIDATE_OR_GOTO(this->name, frame, out);
- GF_VALIDATE_OR_GOTO(this->name, this->private, out);
-
- fop = ec_fop_data_allocate(frame, this, GF_FOP_XATTROP,
- EC_FLAG_UPDATE_LOC_INODE, target, minimum,
- ec_wind_xattrop, ec_manager_xattrop, callback,
- data);
- if (fop == NULL)
- {
- goto out;
- }
-
- fop->xattrop_flags = optype;
-
- if (loc != NULL)
- {
- if (loc_copy(&fop->loc[0], loc) != 0)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to copy a location.");
-
- goto out;
- }
- }
- if (xattr != NULL)
- {
- fop->dict = dict_ref(xattr);
- if (fop->dict == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
- "dictionary.");
-
- goto out;
- }
- }
- if (xdata != NULL)
- {
- fop->xdata = dict_ref(xdata);
- if (fop->xdata == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
- "dictionary.");
-
- goto out;
- }
- }
-
- error = 0;
-
-out:
- if (fop != NULL)
- {
- ec_manager(fop, error);
- }
- else
- {
- func(frame, NULL, this, -1, EIO, NULL, NULL);
- }
-}
-
-/* FOP: fxattrop */
-
-int32_t ec_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)
-{
- ec_fop_data_t * fop = NULL;
- ec_cbk_data_t * cbk = NULL;
- int32_t idx = (int32_t)(uintptr_t)cookie;
-
- VALIDATE_OR_GOTO(this, out);
- GF_VALIDATE_OR_GOTO(this->name, frame, out);
- GF_VALIDATE_OR_GOTO(this->name, frame->local, out);
- GF_VALIDATE_OR_GOTO(this->name, this->private, out);
-
- fop = frame->local;
-
- ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx,
- frame, op_ret, op_errno);
-
- cbk = ec_cbk_data_allocate(frame, this, fop, GF_FOP_FXATTROP, idx, op_ret,
- op_errno);
- if (cbk != NULL)
- {
- if (op_ret >= 0)
- {
- if (xattr != NULL)
- {
- cbk->dict = dict_ref(xattr);
- if (cbk->dict == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
- "dictionary.");
-
- goto out;
- }
- }
- }
- if (xdata != NULL)
- {
- cbk->xdata = dict_ref(xdata);
- if (cbk->xdata == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
- "dictionary.");
-
- goto out;
- }
- }
-
- ec_combine(cbk, ec_combine_xattrop);
- }
-
-out:
- if (fop != NULL)
- {
- ec_complete(fop);
- }
-
- return 0;
-}
-
-void ec_wind_fxattrop(ec_t * ec, ec_fop_data_t * fop, int32_t idx)
-{
- ec_trace("WIND", fop, "idx=%d", idx);
-
- STACK_WIND_COOKIE(fop->frame, ec_fxattrop_cbk, (void *)(uintptr_t)idx,
- ec->xl_list[idx], ec->xl_list[idx]->fops->fxattrop,
- fop->fd, fop->xattrop_flags, fop->dict, fop->xdata);
-}
-
-void ec_fxattrop(call_frame_t * frame, xlator_t * this, uintptr_t target,
- int32_t minimum, fop_fxattrop_cbk_t func, void * data,
- fd_t * fd, gf_xattrop_flags_t optype, dict_t * xattr,
- dict_t * xdata)
-{
- ec_cbk_t callback = { .fxattrop = func };
- ec_fop_data_t * fop = NULL;
- int32_t error = EIO;
-
- gf_log("ec", GF_LOG_TRACE, "EC(FXATTROP) %p", frame);
-
- VALIDATE_OR_GOTO(this, out);
- GF_VALIDATE_OR_GOTO(this->name, frame, out);
- GF_VALIDATE_OR_GOTO(this->name, this->private, out);
-
- fop = ec_fop_data_allocate(frame, this, GF_FOP_FXATTROP,
- EC_FLAG_UPDATE_FD_INODE, target, minimum,
- ec_wind_fxattrop, ec_manager_xattrop, callback,
- data);
- if (fop == NULL)
- {
- goto out;
- }
-
- fop->use_fd = 1;
-
- fop->xattrop_flags = optype;
-
- if (fd != NULL)
- {
- fop->fd = fd_ref(fd);
- if (fop->fd == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
- "file descriptor.");
-
- goto out;
- }
- }
- if (xattr != NULL)
- {
- fop->dict = dict_ref(xattr);
- if (fop->dict == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
- "dictionary.");
-
- goto out;
- }
- }
- if (xdata != NULL)
- {
- fop->xdata = dict_ref(xdata);
- if (fop->xdata == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
- "dictionary.");
-
- goto out;
- }
- }
-
- error = 0;
-
-out:
- if (fop != NULL)
- {
- ec_manager(fop, error);
- }
- else
- {
- func(frame, NULL, this, -1, EIO, NULL, NULL);
- }
-}
diff --git a/xlators/cluster/ec/src/ec-gf.c b/xlators/cluster/ec/src/ec-gf.c
deleted file mode 100644
index 1ae8928f20b..00000000000
--- a/xlators/cluster/ec/src/ec-gf.c
+++ /dev/null
@@ -1,11635 +0,0 @@
-/*
- Copyright (c) 2012-2014 DataLab, s.l. <http://www.datalab.es>
- 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 <inttypes.h>
-#include <string.h>
-
-#include "ec-gf.h"
-
-static void gf8_muladd_00(uint8_t * out, uint8_t * in, unsigned int width)
-{
- memcpy(out, in, sizeof(uint64_t) * 8 * width);
-}
-
-static void gf8_muladd_01(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- out_ptr[0] ^= in_ptr[0];
- out_ptr[width] ^= in_ptr[width];
- out_ptr[width * 2] ^= in_ptr[width * 2];
- out_ptr[width * 3] ^= in_ptr[width * 3];
- out_ptr[width * 4] ^= in_ptr[width * 4];
- out_ptr[width * 5] ^= in_ptr[width * 5];
- out_ptr[width * 6] ^= in_ptr[width * 6];
- out_ptr[width * 7] ^= in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_02(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out0 = in7;
- out1 = in0;
- out7 = in6;
- out5 = in4;
- out6 = in5;
- out3 = in2 ^ in7;
- out4 = in3 ^ in7;
- out2 = in1 ^ in7;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_03(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out0 = in0 ^ in7;
- tmp0 = in2 ^ in7;
- out1 = in0 ^ in1;
- out7 = in6 ^ in7;
- out5 = in4 ^ in5;
- out6 = in5 ^ in6;
- out4 = in3 ^ in4 ^ in7;
- out2 = tmp0 ^ in1;
- out3 = tmp0 ^ in3;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_04(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out0 = in6;
- out1 = in7;
- out7 = in5;
- out6 = in4;
- tmp0 = in6 ^ in7;
- out2 = in0 ^ in6;
- out5 = in3 ^ in7;
- out3 = tmp0 ^ in1;
- out4 = tmp0 ^ in2;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_05(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out0 = in0 ^ in6;
- out1 = in1 ^ in7;
- out7 = in5 ^ in7;
- out6 = in4 ^ in6;
- out2 = out0 ^ in2;
- out3 = out1 ^ in3 ^ in6;
- out5 = out7 ^ in3;
- out4 = out6 ^ in2 ^ in7;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_06(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out0 = in6 ^ in7;
- tmp0 = in1 ^ in6;
- out1 = in0 ^ in7;
- out7 = in5 ^ in6;
- out6 = in4 ^ in5;
- out4 = in2 ^ in3 ^ in6;
- out5 = in3 ^ in4 ^ in7;
- out3 = tmp0 ^ in2;
- out2 = tmp0 ^ out1;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_07(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2, tmp3;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- tmp0 = in2 ^ in6;
- tmp1 = in5 ^ in6;
- tmp2 = in0 ^ in7;
- tmp3 = tmp0 ^ in3;
- out6 = tmp1 ^ in4;
- out7 = tmp1 ^ in7;
- out0 = tmp2 ^ in6;
- out1 = tmp2 ^ in1;
- out3 = tmp3 ^ in1;
- out4 = tmp3 ^ in4;
- out5 = out4 ^ out7 ^ in2;
- out2 = tmp0 ^ out1;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_08(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out0 = in5;
- out1 = in6;
- out7 = in4;
- out6 = in3 ^ in7;
- out3 = in0 ^ in5 ^ in6;
- out5 = in2 ^ in6 ^ in7;
- out2 = in5 ^ in7;
- out4 = out2 ^ in1 ^ in6;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_09(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out0 = in0 ^ in5;
- tmp0 = in3 ^ in6;
- out1 = in1 ^ in6;
- out7 = in4 ^ in7;
- out2 = in2 ^ in5 ^ in7;
- out3 = tmp0 ^ out0;
- out6 = tmp0 ^ in7;
- out4 = out1 ^ out7 ^ in5;
- out5 = out2 ^ in6;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_0A(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out0 = in5 ^ in7;
- out1 = in0 ^ in6;
- out7 = in4 ^ in6;
- out2 = in1 ^ in5;
- out6 = out0 ^ in3;
- out3 = out0 ^ out1 ^ in2;
- out5 = out7 ^ in2 ^ in7;
- out4 = out2 ^ in3 ^ in6;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_0B(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- tmp0 = in2 ^ in5;
- tmp1 = in0 ^ in6;
- tmp2 = in4 ^ in7;
- out0 = in0 ^ in5 ^ in7;
- out2 = tmp0 ^ in1;
- out1 = tmp1 ^ in1;
- out6 = tmp1 ^ out0 ^ in3;
- out7 = tmp2 ^ in6;
- out4 = tmp2 ^ out6 ^ in1;
- out3 = out6 ^ in0 ^ in2;
- out5 = tmp0 ^ out7;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_0C(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out0 = in5 ^ in6;
- out1 = in6 ^ in7;
- out7 = in4 ^ in5;
- tmp0 = in1 ^ in5;
- tmp1 = in0 ^ in7;
- out5 = in2 ^ in3 ^ in6;
- out6 = in3 ^ in4 ^ in7;
- out2 = tmp1 ^ out0;
- out4 = tmp0 ^ in2;
- out3 = tmp0 ^ tmp1;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_0D(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- tmp0 = in4 ^ in5;
- tmp1 = in5 ^ in6;
- out1 = in1 ^ in6 ^ in7;
- out7 = tmp0 ^ in7;
- out4 = tmp0 ^ in1 ^ in2;
- out0 = tmp1 ^ in0;
- tmp2 = tmp1 ^ in3;
- out6 = tmp2 ^ out7;
- out2 = out0 ^ in2 ^ in7;
- out3 = out0 ^ out1 ^ in3;
- out5 = tmp2 ^ in2;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_0E(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2, tmp3;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- tmp0 = in0 ^ in1;
- tmp1 = in2 ^ in5;
- tmp2 = in5 ^ in6;
- out1 = in0 ^ in6 ^ in7;
- out3 = tmp0 ^ tmp1;
- out2 = tmp0 ^ tmp2;
- tmp3 = tmp1 ^ in3;
- out7 = tmp2 ^ in4;
- out0 = tmp2 ^ in7;
- out4 = tmp3 ^ in1 ^ in7;
- out5 = tmp3 ^ out7;
- out6 = out0 ^ out5 ^ in2;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_0F(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2, tmp3;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- tmp0 = in6 ^ in7;
- tmp1 = tmp0 ^ in1;
- tmp2 = tmp0 ^ in5;
- out1 = tmp1 ^ in0;
- out7 = tmp2 ^ in4;
- out0 = tmp2 ^ in0;
- out6 = out7 ^ in3;
- out5 = out6 ^ in2 ^ in7;
- tmp3 = tmp1 ^ out0 ^ in2;
- out4 = tmp1 ^ out5;
- out2 = tmp3 ^ in6;
- out3 = tmp3 ^ in3;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_10(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out0 = in4;
- out1 = in5;
- out7 = in3 ^ in7;
- tmp0 = in6 ^ in7;
- out2 = in4 ^ in6;
- tmp1 = out2 ^ in5;
- out6 = tmp0 ^ in2;
- out3 = tmp0 ^ tmp1;
- out5 = out2 ^ out3 ^ in1;
- out4 = tmp1 ^ in0;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_11(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out7 = in3;
- out0 = in0 ^ in4;
- out1 = in1 ^ in5;
- out6 = in2 ^ in7;
- out4 = in0 ^ in5 ^ in6;
- out5 = in1 ^ in6 ^ in7;
- out2 = in2 ^ in4 ^ in6;
- out3 = in3 ^ in4 ^ in5 ^ in7;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_12(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out0 = in4 ^ in7;
- out1 = in0 ^ in5;
- out3 = in2 ^ in4 ^ in5;
- tmp0 = out0 ^ in6;
- out2 = tmp0 ^ in1;
- tmp1 = tmp0 ^ in3;
- out6 = tmp0 ^ out3;
- out5 = out2 ^ in5;
- out7 = tmp1 ^ in4;
- out4 = tmp1 ^ out1;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_13(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out7 = in3 ^ in6;
- tmp0 = in0 ^ in5;
- tmp1 = in4 ^ in7;
- out6 = in2 ^ in5 ^ in7;
- out4 = tmp0 ^ out7 ^ in7;
- out1 = tmp0 ^ in1;
- out0 = tmp1 ^ in0;
- out5 = tmp1 ^ in1 ^ in6;
- out3 = tmp1 ^ out6 ^ in3;
- out2 = out5 ^ in2;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_14(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out0 = in4 ^ in6;
- out1 = in5 ^ in7;
- out2 = in0 ^ in4;
- tmp0 = out0 ^ in5;
- out7 = out1 ^ in3;
- tmp1 = out1 ^ in2;
- out3 = tmp0 ^ in1;
- out6 = tmp0 ^ tmp1;
- out4 = tmp1 ^ out2;
- out5 = out3 ^ in3 ^ in4;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_15(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out7 = in3 ^ in5;
- tmp0 = in0 ^ in4;
- out1 = in1 ^ in5 ^ in7;
- out5 = in1 ^ in3 ^ in6;
- out0 = tmp0 ^ in6;
- out2 = tmp0 ^ in2;
- out3 = out5 ^ in4 ^ in5;
- out6 = out2 ^ in0 ^ in7;
- out4 = tmp0 ^ out6 ^ in5;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_16(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2, tmp3;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- tmp0 = in0 ^ in5;
- tmp1 = in4 ^ in7;
- tmp2 = in2 ^ in3 ^ in4;
- out1 = tmp0 ^ in7;
- out4 = tmp0 ^ tmp2;
- out0 = tmp1 ^ in6;
- tmp3 = tmp1 ^ in1;
- out6 = out0 ^ in2 ^ in5;
- out2 = tmp3 ^ in0;
- out3 = out6 ^ in1;
- out7 = tmp2 ^ out6;
- out5 = tmp3 ^ out7;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_17(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2, tmp3;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- tmp0 = in2 ^ in5;
- tmp1 = in3 ^ in6;
- tmp2 = tmp0 ^ in4;
- out4 = tmp0 ^ in0 ^ in3;
- out7 = tmp1 ^ in5;
- tmp3 = tmp1 ^ in1;
- out6 = tmp2 ^ in7;
- out5 = tmp3 ^ in4;
- out3 = tmp3 ^ out6;
- out0 = out3 ^ out4 ^ in1;
- out2 = out3 ^ out7 ^ in0;
- out1 = tmp2 ^ out2;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_18(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out0 = in4 ^ in5;
- out1 = in5 ^ in6;
- tmp0 = in4 ^ in7;
- out5 = in1 ^ in2 ^ in5;
- out6 = in2 ^ in3 ^ in6;
- out2 = tmp0 ^ out1;
- out7 = tmp0 ^ in3;
- tmp1 = tmp0 ^ in0;
- out3 = tmp1 ^ in6;
- out4 = tmp1 ^ in1;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_19(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out5 = in1 ^ in2;
- out7 = in3 ^ in4;
- tmp0 = in0 ^ in7;
- out6 = in2 ^ in3;
- out1 = in1 ^ in5 ^ in6;
- out0 = in0 ^ in4 ^ in5;
- out4 = tmp0 ^ in1;
- tmp1 = tmp0 ^ in6;
- out2 = tmp1 ^ out0 ^ in2;
- out3 = tmp1 ^ out7;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_1A(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2, tmp3;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- tmp0 = in4 ^ in5;
- tmp1 = in5 ^ in6;
- tmp2 = tmp0 ^ in1;
- out0 = tmp0 ^ in7;
- out1 = tmp1 ^ in0;
- tmp3 = tmp1 ^ in3;
- out5 = tmp2 ^ in2;
- out2 = tmp2 ^ in6;
- out7 = tmp3 ^ out0;
- out6 = tmp3 ^ in2;
- out4 = tmp3 ^ out2 ^ in0;
- out3 = tmp0 ^ out1 ^ in2;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_1B(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2, tmp3, tmp4;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- tmp0 = in2 ^ in4;
- tmp1 = in2 ^ in5;
- tmp2 = in3 ^ in6;
- out5 = tmp0 ^ in1;
- tmp3 = tmp0 ^ in0;
- out6 = tmp1 ^ in3;
- out0 = tmp1 ^ tmp3 ^ in7;
- out7 = tmp2 ^ in4;
- tmp4 = out5 ^ in6;
- out3 = tmp2 ^ tmp3;
- out2 = tmp4 ^ in5;
- out4 = tmp4 ^ out3;
- out1 = tmp3 ^ out2;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_1C(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2, tmp3, tmp4;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- tmp0 = in2 ^ in3;
- tmp1 = in4 ^ in6;
- tmp2 = in5 ^ in7;
- out6 = tmp0 ^ tmp1;
- out0 = tmp1 ^ in5;
- out1 = tmp2 ^ in6;
- tmp3 = tmp2 ^ in1;
- tmp4 = tmp2 ^ in4;
- out2 = tmp4 ^ in0;
- out7 = tmp4 ^ in3;
- out5 = tmp0 ^ tmp3;
- out3 = tmp3 ^ out2;
- out4 = out3 ^ in2 ^ in6;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_1D(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2, tmp3, tmp4;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- tmp0 = in1 ^ in3;
- tmp1 = in0 ^ in4;
- tmp2 = in3 ^ in4;
- tmp3 = in2 ^ in7;
- out3 = tmp0 ^ tmp1;
- out5 = tmp0 ^ tmp3;
- tmp4 = tmp1 ^ in5;
- out6 = tmp2 ^ in2;
- out7 = tmp2 ^ in5;
- out2 = tmp3 ^ tmp4;
- out4 = out3 ^ out6 ^ in6;
- out0 = tmp4 ^ in6;
- out1 = out2 ^ out4 ^ in4;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_1E(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2, tmp3;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- tmp0 = in0 ^ in4;
- tmp1 = in2 ^ in7;
- tmp2 = tmp0 ^ in1;
- out3 = tmp1 ^ tmp2;
- out2 = tmp2 ^ in5;
- out4 = out3 ^ in3 ^ in6;
- tmp3 = out4 ^ in7;
- out6 = tmp3 ^ out2 ^ in4;
- out7 = tmp1 ^ out6;
- out0 = out7 ^ in3;
- out1 = tmp0 ^ out0;
- out5 = tmp3 ^ out1;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_1F(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- tmp0 = in4 ^ in6;
- tmp1 = tmp0 ^ in5;
- out7 = tmp1 ^ in3;
- out0 = tmp1 ^ in0 ^ in7;
- out6 = out7 ^ in2 ^ in6;
- out1 = out0 ^ in1 ^ in4;
- out4 = out0 ^ out6 ^ in1;
- out3 = tmp0 ^ out4;
- out2 = out4 ^ out7 ^ in7;
- out5 = out3 ^ in0;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_20(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out1 = in4;
- out0 = in3 ^ in7;
- tmp0 = in3 ^ in4;
- tmp1 = in6 ^ in7;
- out2 = out0 ^ in5;
- out4 = tmp0 ^ in5;
- out3 = tmp0 ^ tmp1;
- out7 = tmp1 ^ in2;
- out6 = tmp1 ^ in1 ^ in5;
- out5 = out2 ^ out3 ^ in0;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_21(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out1 = in1 ^ in4;
- tmp0 = in4 ^ in6;
- out4 = in3 ^ in5;
- out7 = in2 ^ in6;
- out0 = in0 ^ in3 ^ in7;
- out6 = in1 ^ in5 ^ in7;
- out3 = tmp0 ^ in7;
- out5 = tmp0 ^ in0;
- out2 = out4 ^ in2 ^ in7;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_22(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out0 = in3;
- out1 = in0 ^ in4;
- out7 = in2 ^ in7;
- out4 = in4 ^ in5 ^ in7;
- out5 = in0 ^ in5 ^ in6;
- out6 = in1 ^ in6 ^ in7;
- out3 = in2 ^ in3 ^ in4 ^ in6;
- out2 = in1 ^ in3 ^ in5;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_23(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out7 = in2;
- out0 = in0 ^ in3;
- out4 = in5 ^ in7;
- out5 = in0 ^ in6;
- out6 = in1 ^ in7;
- out3 = in2 ^ in4 ^ in6;
- out1 = in0 ^ in1 ^ in4;
- out2 = out4 ^ out6 ^ in2 ^ in3;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_24(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out1 = in4 ^ in7;
- tmp0 = in3 ^ in4;
- out0 = in3 ^ in6 ^ in7;
- out3 = tmp0 ^ in1;
- tmp1 = out0 ^ in5;
- out6 = tmp1 ^ out3;
- out2 = tmp1 ^ in0;
- out7 = tmp1 ^ in2 ^ in3;
- out5 = out2 ^ in4;
- out4 = tmp0 ^ out7;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_25(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out3 = in1 ^ in4;
- tmp0 = in2 ^ in5;
- out1 = out3 ^ in7;
- out7 = tmp0 ^ in6;
- out6 = out1 ^ in5;
- out4 = out7 ^ in3 ^ in7;
- out2 = out4 ^ in0;
- out0 = tmp0 ^ out2;
- out5 = out0 ^ in4;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_26(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out0 = in3 ^ in6;
- tmp0 = in4 ^ in7;
- out7 = in2 ^ in5 ^ in7;
- tmp1 = out0 ^ in0 ^ in5;
- out1 = tmp0 ^ in0;
- tmp2 = tmp0 ^ in6;
- out2 = tmp1 ^ in1;
- out5 = tmp1 ^ in7;
- out6 = tmp2 ^ in1;
- out4 = tmp2 ^ out7;
- out3 = out0 ^ out6 ^ in2;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_27(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out7 = in2 ^ in5;
- out0 = in0 ^ in3 ^ in6;
- out6 = in1 ^ in4 ^ in7;
- out4 = out7 ^ in6;
- out2 = out0 ^ out7 ^ in1;
- out5 = out0 ^ in7;
- out1 = out6 ^ in0;
- out3 = out6 ^ in2;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_28(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out2 = in3;
- out1 = in4 ^ in6;
- out0 = in3 ^ in5 ^ in7;
- tmp0 = out1 ^ in7;
- tmp1 = out0 ^ in4;
- out7 = tmp0 ^ in2;
- tmp2 = tmp0 ^ in1;
- out3 = tmp1 ^ in0;
- out6 = tmp1 ^ tmp2;
- out4 = tmp2 ^ in3;
- out5 = out3 ^ in2 ^ in3;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_29(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out2 = in2 ^ in3;
- tmp0 = in1 ^ in3;
- tmp1 = in4 ^ in6;
- tmp2 = in0 ^ in4 ^ in7;
- out6 = tmp0 ^ in5;
- out4 = tmp0 ^ in6 ^ in7;
- out1 = tmp1 ^ in1;
- out7 = tmp1 ^ in2;
- out3 = tmp2 ^ in5;
- out5 = tmp2 ^ in2;
- out0 = out3 ^ in3 ^ in4;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_2A(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out0 = in3 ^ in5;
- tmp0 = in1 ^ in3;
- tmp1 = in0 ^ in4;
- out7 = in2 ^ in4 ^ in7;
- out3 = tmp1 ^ out0 ^ in2;
- out2 = tmp0 ^ in7;
- out6 = tmp0 ^ in6;
- out1 = tmp1 ^ in6;
- out5 = tmp1 ^ out7 ^ in5;
- out4 = out1 ^ in0 ^ in1;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_2B(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out4 = in1 ^ in6;
- out7 = in2 ^ in4;
- tmp0 = in0 ^ in5;
- tmp1 = in2 ^ in7;
- out6 = in1 ^ in3;
- out1 = out4 ^ in0 ^ in4;
- out3 = tmp0 ^ out7;
- out0 = tmp0 ^ in3;
- out5 = tmp1 ^ in0;
- out2 = tmp1 ^ out6;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_2C(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2, tmp3;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- tmp0 = in2 ^ in5;
- tmp1 = in2 ^ in3 ^ in4;
- tmp2 = tmp0 ^ in6;
- out4 = tmp1 ^ in1;
- out5 = tmp1 ^ in0 ^ in5;
- tmp3 = tmp2 ^ in4;
- out6 = tmp2 ^ out4;
- out7 = tmp3 ^ in7;
- out2 = tmp3 ^ out5;
- out3 = out6 ^ in0;
- out0 = tmp1 ^ out7;
- out1 = tmp0 ^ out7;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_2D(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2, tmp3;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- tmp0 = in2 ^ in3;
- out4 = tmp0 ^ in1;
- tmp1 = tmp0 ^ in0;
- out2 = tmp1 ^ in6;
- out5 = tmp1 ^ in4;
- tmp2 = out2 ^ in2;
- tmp3 = tmp2 ^ in5;
- out0 = tmp3 ^ in7;
- out7 = tmp3 ^ out5;
- out6 = out4 ^ out7 ^ in6;
- out3 = tmp2 ^ out6;
- out1 = out0 ^ out6 ^ in0;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_2E(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- tmp0 = in4 ^ in7;
- out0 = in3 ^ in5 ^ in6;
- tmp1 = tmp0 ^ in0;
- tmp2 = tmp0 ^ in2;
- out1 = tmp1 ^ in6;
- out4 = tmp2 ^ in1;
- out7 = tmp2 ^ in5;
- out3 = out0 ^ out4 ^ in0;
- out2 = out3 ^ out7 ^ in7;
- out6 = tmp1 ^ out2;
- out5 = tmp1 ^ out7 ^ in3;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_2F(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- tmp0 = in0 ^ in3;
- tmp1 = in2 ^ in5;
- out4 = in1 ^ in2 ^ in7;
- out6 = in1 ^ in3 ^ in4;
- out5 = tmp0 ^ in2;
- tmp2 = tmp0 ^ in6;
- out7 = tmp1 ^ in4;
- out0 = tmp2 ^ in5;
- out2 = tmp2 ^ out4;
- out1 = tmp2 ^ out6 ^ in7;
- out3 = tmp1 ^ out1;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_30(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out1 = in4 ^ in5;
- tmp0 = in3 ^ in6;
- tmp1 = in4 ^ in7;
- out6 = in1 ^ in2 ^ in5;
- out3 = tmp0 ^ in5;
- out4 = tmp0 ^ in0;
- out7 = tmp0 ^ in2;
- out0 = tmp1 ^ in3;
- out2 = tmp1 ^ out3;
- out5 = tmp1 ^ in0 ^ in1;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_31(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out3 = in5 ^ in6;
- tmp0 = in4 ^ in5;
- tmp1 = in0 ^ in3 ^ in4;
- tmp2 = out3 ^ in2;
- out1 = tmp0 ^ in1;
- out0 = tmp1 ^ in7;
- out4 = tmp1 ^ in6;
- out6 = tmp2 ^ in1;
- out2 = tmp2 ^ out0 ^ in0;
- out5 = out1 ^ in0 ^ in7;
- out7 = tmp0 ^ out2;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_32(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out0 = in3 ^ in4;
- out7 = in2 ^ in3;
- tmp0 = in5 ^ in6;
- tmp1 = in0 ^ in7;
- out6 = in1 ^ in2;
- out1 = in0 ^ in4 ^ in5;
- out2 = tmp0 ^ out0 ^ in1;
- out3 = tmp0 ^ out7 ^ in7;
- out4 = tmp1 ^ in6;
- out5 = tmp1 ^ in1;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_33(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2, tmp3, tmp4;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- tmp0 = in2 ^ in3;
- tmp1 = in0 ^ in4;
- tmp2 = in1 ^ in5;
- out6 = in1 ^ in2 ^ in6;
- out7 = tmp0 ^ in7;
- out0 = tmp1 ^ in3;
- out1 = tmp1 ^ tmp2;
- tmp3 = tmp2 ^ in7;
- tmp4 = tmp2 ^ in4 ^ in6;
- out5 = tmp3 ^ in0;
- out3 = tmp3 ^ out6;
- out4 = tmp4 ^ out5;
- out2 = tmp0 ^ tmp4;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_34(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2, tmp3, tmp4;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- tmp0 = in3 ^ in4;
- tmp1 = in4 ^ in5;
- tmp2 = tmp0 ^ in1;
- tmp3 = tmp0 ^ in6;
- out1 = tmp1 ^ in7;
- tmp4 = tmp1 ^ in2;
- out5 = tmp2 ^ in0;
- out3 = tmp2 ^ out1;
- out0 = tmp3 ^ in7;
- out7 = tmp3 ^ tmp4;
- out6 = tmp4 ^ in1;
- out2 = out3 ^ out5 ^ in3;
- out4 = tmp4 ^ out2;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_35(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- tmp0 = in2 ^ in6;
- tmp1 = in5 ^ in7;
- out7 = tmp0 ^ tmp1 ^ in3;
- out3 = tmp1 ^ in1;
- out1 = out3 ^ in4;
- tmp2 = out1 ^ in7;
- out5 = tmp2 ^ in0 ^ in3;
- out6 = tmp0 ^ tmp2;
- out0 = out3 ^ out5 ^ in6;
- out4 = tmp0 ^ out0;
- out2 = out4 ^ in5;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_36(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out4 = in0 ^ in2;
- tmp0 = in1 ^ in3;
- out0 = in3 ^ in4 ^ in6;
- out6 = in1 ^ in2 ^ in4;
- out5 = tmp0 ^ in0;
- tmp1 = out5 ^ in5;
- out2 = tmp1 ^ in4;
- out3 = tmp1 ^ out4;
- out1 = tmp0 ^ out2 ^ in7;
- out7 = out3 ^ in1;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_37(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2, tmp3;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- tmp0 = in1 ^ in2;
- tmp1 = in2 ^ in4;
- tmp2 = tmp0 ^ in6;
- out3 = tmp0 ^ in5;
- out4 = tmp1 ^ in0;
- out6 = tmp2 ^ in4;
- out1 = out3 ^ out4 ^ in7;
- tmp3 = out4 ^ in1 ^ in3;
- out7 = tmp3 ^ out1;
- out2 = tmp3 ^ in5;
- out5 = tmp1 ^ out2;
- out0 = tmp2 ^ tmp3;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_38(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out3 = in0 ^ in3;
- tmp0 = in3 ^ in4;
- tmp1 = in5 ^ in7;
- tmp2 = out3 ^ in1;
- out2 = tmp0 ^ in6;
- out0 = tmp0 ^ tmp1;
- out4 = tmp1 ^ tmp2;
- out7 = out2 ^ in2;
- out1 = out2 ^ in3 ^ in5;
- out6 = out4 ^ in0 ^ in2;
- out5 = tmp2 ^ out7;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_39(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out3 = in0;
- tmp0 = in1 ^ in5;
- tmp1 = tmp0 ^ in4;
- out1 = tmp1 ^ in6;
- out5 = out1 ^ in0 ^ in2;
- tmp2 = tmp0 ^ out5;
- out2 = tmp2 ^ in0 ^ in3;
- out7 = out2 ^ in7;
- out6 = tmp1 ^ out7;
- out4 = tmp2 ^ out6;
- out0 = out4 ^ in1;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_3A(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2, tmp3, tmp4, tmp5;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- tmp0 = in0 ^ in1;
- tmp1 = in0 ^ in2;
- tmp2 = in3 ^ in4;
- tmp3 = in1 ^ in6;
- tmp4 = in3 ^ in7;
- out4 = tmp0 ^ in5;
- out5 = tmp1 ^ tmp3;
- out3 = tmp1 ^ tmp4;
- out0 = tmp2 ^ in5;
- out7 = tmp2 ^ in2;
- tmp5 = tmp3 ^ in4;
- out2 = tmp4 ^ tmp5;
- out1 = tmp5 ^ out4;
- out6 = tmp0 ^ out3;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_3B(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- tmp0 = in1 ^ in6;
- tmp1 = in2 ^ in7;
- tmp2 = tmp0 ^ in3;
- out3 = tmp1 ^ in0;
- out6 = tmp1 ^ tmp2;
- out2 = out6 ^ in4;
- out7 = tmp0 ^ out2;
- out0 = out3 ^ out7 ^ in5;
- out5 = out0 ^ out2 ^ in7;
- out1 = tmp2 ^ out0;
- out4 = out1 ^ in6;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_3C(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- tmp0 = in0 ^ in3;
- tmp1 = in2 ^ in7;
- tmp2 = in1 ^ in6 ^ in7;
- out2 = tmp0 ^ in4;
- out3 = tmp0 ^ tmp2;
- out4 = tmp1 ^ out3 ^ in5;
- out5 = tmp2 ^ out2 ^ in2;
- out1 = out4 ^ out5 ^ in6;
- out0 = out1 ^ in3;
- out7 = tmp1 ^ out0;
- out6 = tmp2 ^ out7;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_3D(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- tmp0 = in0 ^ in2;
- tmp1 = tmp0 ^ in3;
- out2 = tmp1 ^ in4;
- tmp2 = out2 ^ in5;
- out4 = tmp2 ^ in1 ^ in6;
- out5 = out4 ^ in7;
- out6 = out5 ^ in0;
- out7 = out6 ^ in1;
- out0 = tmp0 ^ out7;
- out1 = tmp1 ^ out5;
- out3 = tmp2 ^ out6;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_3E(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- tmp0 = in3 ^ in5;
- tmp1 = tmp0 ^ in4;
- out0 = tmp1 ^ in6;
- out7 = tmp1 ^ in2;
- out6 = out7 ^ in1 ^ in5 ^ in7;
- out2 = out6 ^ in0 ^ in2;
- out4 = out0 ^ out6 ^ in0;
- out5 = tmp0 ^ out4;
- out3 = out5 ^ in7;
- out1 = out3 ^ out6 ^ in5;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_3F(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- tmp0 = in0 ^ in1;
- out3 = tmp0 ^ in2 ^ in6;
- tmp1 = out3 ^ in5 ^ in7;
- out4 = tmp1 ^ in4;
- out5 = tmp1 ^ in3;
- out1 = out4 ^ in2;
- out7 = out1 ^ out3 ^ in3;
- out2 = tmp0 ^ out7 ^ in5;
- tmp2 = out2 ^ in0;
- out6 = tmp2 ^ in6;
- out0 = tmp1 ^ tmp2;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_40(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out1 = in3 ^ in7;
- tmp0 = in3 ^ in4;
- tmp1 = in6 ^ in7;
- out4 = tmp0 ^ in2;
- out5 = tmp0 ^ in5;
- out0 = tmp1 ^ in2;
- out7 = tmp1 ^ in1 ^ in5;
- out2 = out0 ^ in4;
- out3 = out2 ^ out5 ^ in7;
- out6 = out3 ^ out4 ^ in0;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_41(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out4 = in2 ^ in3;
- tmp0 = in5 ^ in6;
- tmp1 = in6 ^ in7;
- out5 = in3 ^ in4;
- out1 = in1 ^ in3 ^ in7;
- out6 = in0 ^ in4 ^ in5;
- out3 = tmp0 ^ in2;
- out7 = tmp0 ^ in1;
- out2 = tmp1 ^ in4;
- out0 = tmp1 ^ in0 ^ in2;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_42(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out0 = in2 ^ in6;
- out5 = in3 ^ in5;
- out1 = in0 ^ in3 ^ in7;
- out7 = in1 ^ in5 ^ in7;
- out4 = in2 ^ in4 ^ in7;
- out6 = in0 ^ in4 ^ in6;
- out2 = out0 ^ in1 ^ in4;
- out3 = out5 ^ in6 ^ in7;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_43(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out5 = in3;
- out7 = in1 ^ in5;
- out4 = in2 ^ in7;
- out6 = in0 ^ in4;
- out0 = in0 ^ in2 ^ in6;
- out3 = in5 ^ in6 ^ in7;
- out2 = in1 ^ in4 ^ in6;
- out1 = in0 ^ in1 ^ in3 ^ in7;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_44(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out1 = in3;
- out0 = in2 ^ in7;
- tmp0 = in4 ^ in7;
- out7 = in1 ^ in6 ^ in7;
- out6 = in0 ^ in5 ^ in6;
- out4 = tmp0 ^ in3 ^ in6;
- out3 = out0 ^ in1 ^ in3 ^ in5;
- out2 = out0 ^ in0 ^ in4;
- out5 = tmp0 ^ in5;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_45(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out1 = in1 ^ in3;
- out7 = in1 ^ in6;
- out5 = in4 ^ in7;
- out6 = in0 ^ in5;
- out0 = in0 ^ in2 ^ in7;
- out4 = in3 ^ in6 ^ in7;
- out2 = out5 ^ in0;
- out3 = out0 ^ out6 ^ in1;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_46(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out0 = in2;
- out1 = in0 ^ in3;
- out7 = in1 ^ in7;
- out4 = in4 ^ in6;
- out5 = in5 ^ in7;
- out6 = in0 ^ in6;
- out3 = in1 ^ in3 ^ in5;
- out2 = out4 ^ out6 ^ in1 ^ in2;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_47(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out4 = in6;
- out7 = in1;
- out5 = in7;
- out6 = in0;
- tmp0 = in0 ^ in1;
- out3 = in1 ^ in5;
- out0 = in0 ^ in2;
- out1 = tmp0 ^ in3;
- out2 = tmp0 ^ in4;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_48(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- tmp0 = in2 ^ in3;
- out1 = in3 ^ in6 ^ in7;
- out3 = tmp0 ^ in0;
- out0 = tmp0 ^ out1 ^ in5;
- tmp1 = out0 ^ in4;
- out2 = tmp1 ^ in7;
- out5 = tmp1 ^ in3;
- out4 = out5 ^ in1;
- out7 = tmp0 ^ out4;
- out6 = tmp1 ^ out3;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_49(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out3 = in0 ^ in2;
- tmp0 = in2 ^ in5;
- out2 = in4 ^ in5 ^ in6;
- tmp1 = tmp0 ^ out2 ^ in3;
- out7 = out2 ^ in1;
- out5 = tmp1 ^ in7;
- out4 = out5 ^ out7 ^ in6;
- out1 = tmp0 ^ out4;
- out6 = out1 ^ out7 ^ in0;
- out0 = tmp1 ^ out6;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_4A(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- tmp0 = in2 ^ in6;
- tmp1 = in3 ^ in7;
- out0 = tmp0 ^ in5;
- out3 = tmp1 ^ in0;
- out5 = tmp1 ^ out0;
- out4 = out0 ^ in1 ^ in4;
- out1 = out3 ^ in6;
- out2 = out4 ^ in7;
- out6 = out1 ^ in4;
- out7 = tmp0 ^ out2;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_4B(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2, tmp3;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out3 = in0 ^ in7;
- tmp0 = in1 ^ in5;
- tmp1 = in2 ^ in6;
- tmp2 = out3 ^ in3;
- out7 = tmp0 ^ in4;
- out4 = tmp0 ^ tmp1;
- tmp3 = tmp1 ^ in0;
- out6 = tmp2 ^ in4;
- out5 = tmp2 ^ tmp3;
- out1 = tmp2 ^ in1 ^ in6;
- out2 = out7 ^ in6 ^ in7;
- out0 = tmp3 ^ in5;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_4C(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out1 = in3 ^ in6;
- tmp0 = in2 ^ in5;
- tmp1 = out1 ^ in5 ^ in7;
- out0 = tmp0 ^ in7;
- tmp2 = tmp0 ^ in4;
- out6 = tmp1 ^ in0;
- out2 = tmp2 ^ in0;
- out5 = tmp2 ^ in6;
- out3 = tmp0 ^ out6 ^ in1;
- out7 = out0 ^ out5 ^ in1;
- out4 = tmp1 ^ out7;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_4D(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- tmp0 = in0 ^ in5;
- tmp1 = in1 ^ in6;
- out4 = in1 ^ in3 ^ in5;
- tmp2 = tmp0 ^ in7;
- out2 = tmp0 ^ in4;
- out1 = tmp1 ^ in3;
- out7 = tmp1 ^ in4;
- out0 = tmp2 ^ in2;
- out6 = tmp2 ^ in3;
- out5 = out7 ^ in1 ^ in2;
- out3 = tmp1 ^ out0 ^ in5;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_4E(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out0 = in2 ^ in5;
- out7 = in1 ^ in4 ^ in7;
- out1 = in0 ^ in3 ^ in6;
- out5 = out0 ^ in6;
- out4 = out7 ^ in5;
- out3 = out1 ^ in1;
- out6 = out1 ^ in7;
- out2 = out4 ^ in0 ^ in2;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_4F(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out5 = in2 ^ in6;
- out7 = in1 ^ in4;
- out3 = in0 ^ in1 ^ in6;
- out4 = in1 ^ in5 ^ in7;
- out0 = in0 ^ in2 ^ in5;
- out6 = in0 ^ in3 ^ in7;
- out1 = out3 ^ in3;
- out2 = out4 ^ in0 ^ in4;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_50(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out2 = in2 ^ in7;
- tmp0 = in3 ^ in5;
- out0 = out2 ^ in4 ^ in6;
- out1 = tmp0 ^ in7;
- tmp1 = tmp0 ^ in6;
- out3 = out0 ^ in3;
- out7 = tmp1 ^ in1;
- tmp2 = tmp1 ^ in0;
- out5 = out3 ^ in1 ^ in2;
- out4 = tmp2 ^ in2;
- out6 = tmp2 ^ out3;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_51(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out2 = in7;
- out3 = in2 ^ in4 ^ in6 ^ in7;
- out0 = out3 ^ in0;
- out6 = out0 ^ in5;
- out4 = out6 ^ in3 ^ in7;
- out1 = out0 ^ out4 ^ in1;
- out7 = out1 ^ in6;
- out5 = out7 ^ in4;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_52(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2, tmp3;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out2 = in1 ^ in2;
- tmp0 = in2 ^ in4;
- tmp1 = in3 ^ in5;
- tmp2 = in3 ^ in6;
- tmp3 = in0 ^ in7;
- out0 = tmp0 ^ in6;
- out6 = tmp0 ^ tmp3;
- out7 = tmp1 ^ in1;
- out1 = tmp1 ^ tmp3;
- out3 = tmp2 ^ in4;
- out5 = tmp2 ^ in1 ^ in7;
- out4 = tmp2 ^ out1 ^ in2;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_53(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out2 = in1;
- out3 = in4 ^ in6;
- out0 = out3 ^ in0 ^ in2;
- out6 = out0 ^ in7;
- out4 = out6 ^ in5;
- out7 = out0 ^ out4 ^ in1 ^ in3;
- out1 = out7 ^ in0;
- out5 = out7 ^ in6;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_54(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2, tmp3;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out1 = in3 ^ in5;
- tmp0 = in1 ^ in3;
- tmp1 = in2 ^ in4;
- tmp2 = in0 ^ in7;
- out5 = in1 ^ in4 ^ in6;
- out4 = tmp2 ^ out1;
- out7 = tmp0 ^ in6;
- out3 = tmp0 ^ tmp1;
- out0 = tmp1 ^ in7;
- tmp3 = tmp2 ^ in2;
- out2 = tmp3 ^ in6;
- out6 = tmp3 ^ in5;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_55(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- tmp0 = in1 ^ in3;
- tmp1 = in1 ^ in4;
- tmp2 = in6 ^ in7;
- out7 = tmp0 ^ tmp2;
- out1 = tmp0 ^ in5;
- out3 = tmp1 ^ in2;
- out5 = tmp1 ^ in5 ^ in6;
- out2 = tmp2 ^ in0;
- out4 = out5 ^ out7 ^ in0;
- out6 = out2 ^ in2 ^ in5;
- out0 = out5 ^ out6 ^ in1;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_56(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out0 = in2 ^ in4;
- tmp0 = in0 ^ in2;
- out4 = in0 ^ in5;
- out7 = in1 ^ in3;
- out5 = in1 ^ in6;
- out6 = tmp0 ^ in7;
- out2 = tmp0 ^ out5;
- out1 = out4 ^ in3;
- out3 = out7 ^ in4 ^ in7;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_57(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- tmp0 = in0 ^ in5;
- tmp1 = in1 ^ in7;
- out0 = in0 ^ in2 ^ in4;
- out5 = in1 ^ in5 ^ in6;
- out4 = tmp0 ^ in4;
- out1 = tmp0 ^ in1 ^ in3;
- out2 = tmp0 ^ out5;
- out3 = tmp1 ^ in4;
- out7 = tmp1 ^ in3;
- out6 = tmp1 ^ out2 ^ in2;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_58(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out2 = in2 ^ in5;
- tmp0 = in2 ^ in3 ^ in4;
- out5 = tmp0 ^ in1;
- out6 = tmp0 ^ in0 ^ in5;
- out3 = out6 ^ in7;
- tmp1 = out2 ^ out5;
- out7 = tmp1 ^ in6;
- out4 = tmp1 ^ out3 ^ in3;
- out0 = out4 ^ out7 ^ in0;
- out1 = tmp0 ^ out0;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_59(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out2 = in5;
- tmp0 = in0 ^ in5 ^ in7;
- out3 = tmp0 ^ in2 ^ in4;
- out0 = out3 ^ in6;
- tmp1 = out0 ^ in7;
- out6 = tmp1 ^ in3;
- out5 = out6 ^ in0 ^ in1 ^ in6;
- out4 = tmp0 ^ out5;
- out1 = tmp1 ^ out4;
- out7 = out1 ^ in4;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_5A(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- tmp0 = in1 ^ in2;
- tmp1 = in2 ^ in5;
- out5 = tmp0 ^ in3;
- out4 = tmp0 ^ in0;
- tmp2 = tmp1 ^ in4;
- out2 = tmp1 ^ in1 ^ in7;
- out7 = tmp2 ^ out5;
- out6 = out4 ^ out7 ^ in5;
- out0 = tmp2 ^ in6;
- out1 = out0 ^ out6 ^ in7;
- out3 = tmp1 ^ out6;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_5B(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2, tmp3, tmp4;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- tmp0 = in2 ^ in3;
- tmp1 = in0 ^ in4;
- tmp2 = in1 ^ in5;
- out5 = tmp0 ^ tmp2;
- tmp3 = tmp1 ^ in6;
- out3 = tmp1 ^ in5;
- out2 = tmp2 ^ in7;
- tmp4 = out3 ^ in2;
- out7 = out2 ^ in3 ^ in4;
- out0 = tmp4 ^ in6;
- out6 = tmp0 ^ tmp3;
- out4 = tmp2 ^ tmp4;
- out1 = tmp3 ^ out7;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_5C(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- tmp0 = in3 ^ in6;
- tmp1 = in0 ^ in2 ^ in5;
- out1 = tmp0 ^ in5;
- tmp2 = tmp0 ^ in1;
- out2 = tmp1 ^ in6;
- out6 = tmp1 ^ in3;
- out4 = tmp2 ^ in0;
- out7 = tmp2 ^ in4;
- out3 = tmp1 ^ out7;
- out0 = out3 ^ out4 ^ in7;
- out5 = out0 ^ in1 ^ in5;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_5D(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2, tmp3, tmp4;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- tmp0 = in0 ^ in1;
- tmp1 = in0 ^ in6;
- out2 = tmp1 ^ in5;
- tmp2 = out2 ^ in3;
- out6 = tmp2 ^ in2;
- out1 = tmp0 ^ tmp2;
- tmp3 = out1 ^ in4 ^ in5;
- out4 = tmp3 ^ in0;
- out7 = tmp3 ^ in7;
- tmp4 = out4 ^ out6;
- out5 = tmp4 ^ in7;
- out0 = tmp0 ^ out5;
- out3 = tmp1 ^ tmp4;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_5E(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2, tmp3, tmp4;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- tmp0 = in2 ^ in5;
- tmp1 = in3 ^ in5;
- tmp2 = in1 ^ in7;
- out7 = in1 ^ in3 ^ in4;
- out0 = tmp0 ^ in4;
- tmp3 = tmp1 ^ in0;
- out5 = tmp2 ^ in2;
- out1 = tmp3 ^ in6;
- out6 = tmp0 ^ tmp3;
- tmp4 = tmp2 ^ out1;
- out3 = tmp4 ^ in4;
- out4 = tmp1 ^ tmp4;
- out2 = tmp0 ^ out4;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_5F(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2, tmp3;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- tmp0 = in1 ^ in5;
- tmp1 = in0 ^ in6;
- tmp2 = tmp0 ^ in7;
- tmp3 = tmp1 ^ in3;
- out2 = tmp1 ^ tmp2;
- out5 = tmp2 ^ in2;
- out6 = tmp3 ^ in2;
- out3 = out2 ^ in4;
- out4 = out3 ^ in5;
- out1 = tmp0 ^ tmp3;
- out7 = tmp3 ^ out4;
- out0 = out4 ^ out5 ^ in6;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_60(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out4 = in2 ^ in5;
- tmp0 = in3 ^ in6;
- out1 = in3 ^ in4 ^ in7;
- out7 = out4 ^ in1;
- tmp1 = out4 ^ in4;
- out0 = tmp0 ^ in2;
- out5 = tmp0 ^ in0;
- out2 = tmp0 ^ tmp1;
- out3 = tmp1 ^ in7;
- out6 = out3 ^ out7 ^ in0;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_61(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- tmp0 = in2 ^ in5;
- out4 = tmp0 ^ in4;
- tmp1 = out4 ^ in3;
- out3 = tmp1 ^ in7;
- out2 = tmp1 ^ in2 ^ in6;
- out1 = tmp0 ^ out3 ^ in1;
- out0 = out2 ^ out4 ^ in0;
- out7 = tmp1 ^ out1;
- out6 = out0 ^ out1 ^ in2;
- out5 = tmp0 ^ out0;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_62(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2, tmp3;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out3 = in4 ^ in5;
- tmp0 = in0 ^ in3 ^ in4;
- out1 = tmp0 ^ in7;
- out5 = tmp0 ^ in6;
- tmp1 = out1 ^ in0;
- tmp2 = tmp1 ^ out3;
- out4 = tmp2 ^ in2;
- tmp3 = tmp2 ^ in1;
- out0 = out4 ^ in5 ^ in6;
- out7 = tmp3 ^ out0;
- out6 = tmp0 ^ tmp3;
- out2 = tmp1 ^ out7;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_63(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2, tmp3, tmp4;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- tmp0 = in3 ^ in4;
- tmp1 = in1 ^ in7;
- out3 = tmp0 ^ in5;
- tmp2 = out3 ^ in6;
- out4 = out3 ^ in2 ^ in7;
- out5 = tmp2 ^ in0;
- tmp3 = out5 ^ in3;
- out0 = tmp3 ^ out4;
- out2 = tmp1 ^ tmp2;
- out6 = tmp1 ^ tmp3;
- tmp4 = tmp0 ^ out2;
- out1 = tmp4 ^ out5;
- out7 = tmp4 ^ in2;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_64(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out0 = in2 ^ in3;
- out1 = in3 ^ in4;
- out7 = in1 ^ in2;
- tmp0 = in4 ^ in5;
- tmp1 = in0 ^ in7;
- out4 = in5 ^ in6 ^ in7;
- out2 = tmp0 ^ out0 ^ in0;
- out3 = tmp0 ^ out7 ^ in6;
- out5 = tmp1 ^ in6;
- out6 = tmp1 ^ in1;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_65(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2, tmp3;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- tmp0 = in0 ^ in3;
- tmp1 = in4 ^ in5;
- tmp2 = in6 ^ in7;
- out7 = in1 ^ in2 ^ in7;
- out1 = in1 ^ in3 ^ in4;
- out0 = tmp0 ^ in2;
- out2 = tmp0 ^ tmp1;
- out4 = tmp1 ^ tmp2;
- tmp3 = tmp2 ^ in0;
- out3 = out4 ^ out7 ^ in3;
- out5 = tmp3 ^ in5;
- out6 = tmp3 ^ in1;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_66(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2, tmp3, tmp4;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- tmp0 = in1 ^ in2;
- tmp1 = in2 ^ in3;
- tmp2 = in0 ^ in4;
- out7 = tmp0 ^ in6;
- out0 = tmp1 ^ in7;
- out1 = tmp2 ^ in3;
- tmp3 = tmp2 ^ in6;
- tmp4 = out1 ^ in5;
- out5 = tmp3 ^ in7;
- out4 = tmp3 ^ tmp4;
- out2 = tmp0 ^ tmp4 ^ in7;
- out6 = tmp1 ^ out2 ^ in4;
- out3 = tmp3 ^ out6;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_67(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2, tmp3;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- tmp0 = in0 ^ in3;
- tmp1 = tmp0 ^ in1;
- tmp2 = tmp0 ^ in7;
- out1 = tmp1 ^ in4;
- out0 = tmp2 ^ in2;
- tmp3 = out1 ^ in7;
- out2 = tmp3 ^ in5;
- out3 = out2 ^ in0 ^ in6;
- out7 = tmp1 ^ out0 ^ in6;
- out5 = tmp1 ^ out3;
- out4 = tmp2 ^ out5;
- out6 = tmp3 ^ out4;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_68(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2, tmp3;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- tmp0 = in3 ^ in4;
- tmp1 = in2 ^ in3 ^ in5;
- tmp2 = tmp0 ^ in1;
- tmp3 = tmp0 ^ in6;
- out0 = tmp1 ^ in6;
- out6 = tmp2 ^ in0;
- out7 = tmp1 ^ tmp2;
- out1 = tmp3 ^ in7;
- out2 = out1 ^ in2;
- out4 = tmp2 ^ out2;
- out3 = out4 ^ out6 ^ in3;
- out5 = tmp3 ^ out3;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_69(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- tmp0 = in6 ^ in7;
- out2 = tmp0 ^ in3 ^ in4;
- out1 = out2 ^ in1;
- out3 = out2 ^ in0 ^ in2;
- out4 = out1 ^ in2 ^ in3;
- out6 = out1 ^ in0 ^ in7;
- out7 = out4 ^ in5 ^ in6;
- out5 = out4 ^ out6 ^ in5;
- out0 = tmp0 ^ out5;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_6A(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- tmp0 = in2 ^ in6;
- out3 = in0 ^ in4 ^ in6;
- tmp1 = tmp0 ^ in3;
- out4 = tmp1 ^ in1;
- tmp2 = tmp1 ^ in7;
- out2 = out4 ^ in4;
- out0 = tmp2 ^ in5;
- out5 = tmp2 ^ out3;
- out7 = out2 ^ in3 ^ in5;
- out1 = tmp0 ^ out5;
- out6 = tmp1 ^ out7 ^ in0;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_6B(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- tmp0 = in4 ^ in6;
- out2 = tmp0 ^ in1 ^ in3;
- out4 = out2 ^ in2;
- tmp1 = out2 ^ in0;
- out7 = out4 ^ in3 ^ in5 ^ in7;
- out1 = tmp1 ^ in7;
- out3 = tmp1 ^ in1;
- out6 = tmp1 ^ in5;
- out0 = tmp1 ^ out7 ^ in6;
- out5 = tmp0 ^ out0;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_6C(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out4 = in1;
- tmp0 = in2 ^ in3;
- out5 = in0 ^ in2;
- out1 = in3 ^ in4 ^ in6;
- tmp1 = out5 ^ in1;
- out0 = tmp0 ^ in5;
- out6 = tmp0 ^ tmp1;
- out3 = tmp1 ^ in4;
- out7 = out3 ^ in0;
- out2 = out6 ^ out7 ^ in7;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_6D(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out4 = in1 ^ in4;
- tmp0 = in0 ^ in2;
- tmp1 = out4 ^ in3;
- out7 = out4 ^ in2 ^ in7;
- out5 = tmp0 ^ in5;
- out3 = tmp0 ^ tmp1;
- out1 = tmp1 ^ in6;
- out0 = out5 ^ in3;
- out2 = out3 ^ out7 ^ in4;
- out6 = out1 ^ in0 ^ in4;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_6E(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- tmp0 = in1 ^ in3;
- tmp1 = in0 ^ in4;
- out4 = tmp0 ^ in7;
- out6 = tmp0 ^ in0 ^ in5;
- out5 = tmp1 ^ in2;
- tmp2 = tmp1 ^ in3;
- out3 = tmp2 ^ out4;
- out1 = tmp2 ^ in6;
- out2 = tmp0 ^ out5;
- out0 = out2 ^ out3 ^ in5;
- out7 = out1 ^ out2 ^ in4;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_6F(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- tmp0 = in3 ^ in7;
- tmp1 = tmp0 ^ in4;
- tmp2 = tmp0 ^ in0 ^ in2;
- out4 = tmp1 ^ in1;
- out0 = tmp2 ^ in5;
- out3 = out4 ^ in0;
- out2 = out3 ^ in7;
- out1 = out2 ^ in6;
- out6 = out1 ^ in4 ^ in5;
- out7 = tmp2 ^ out1;
- out5 = tmp1 ^ out0;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_70(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out3 = in2;
- tmp0 = in2 ^ in4;
- out2 = in2 ^ in3 ^ in5;
- tmp1 = tmp0 ^ in6;
- tmp2 = out2 ^ in7;
- out0 = tmp1 ^ in3;
- out4 = tmp1 ^ in0;
- out7 = tmp2 ^ in1;
- out6 = out4 ^ in1;
- out5 = out7 ^ in0 ^ in2;
- out1 = tmp0 ^ tmp2;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_71(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out2 = in3 ^ in5;
- out3 = in2 ^ in3;
- tmp0 = in0 ^ in2;
- tmp1 = out2 ^ in1;
- out4 = tmp0 ^ in6;
- tmp2 = tmp0 ^ in1;
- out7 = tmp1 ^ in2;
- out1 = tmp1 ^ in4 ^ in7;
- out0 = out4 ^ in3 ^ in4;
- out6 = tmp2 ^ in4;
- out5 = tmp2 ^ out3 ^ in7;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_72(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out3 = in7;
- tmp0 = in0 ^ in4;
- tmp1 = tmp0 ^ in3 ^ in7;
- out1 = tmp1 ^ in5;
- out5 = out1 ^ in1;
- tmp2 = tmp0 ^ out5;
- out2 = tmp2 ^ in2;
- out7 = out2 ^ in6;
- out6 = tmp1 ^ out7;
- out4 = tmp2 ^ out6;
- out0 = out4 ^ in0;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_73(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out3 = in3 ^ in7;
- out2 = out3 ^ in1 ^ in5;
- out1 = out2 ^ in0 ^ in4;
- out5 = out1 ^ in5;
- out6 = out1 ^ out3 ^ in2;
- out0 = out2 ^ out6 ^ in6;
- out7 = out0 ^ out1 ^ in3;
- out4 = out0 ^ in4;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_74(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- tmp0 = in3 ^ in4;
- tmp1 = in1 ^ in2 ^ in6;
- out4 = in0 ^ in4 ^ in7;
- out5 = in0 ^ in1 ^ in5;
- out0 = tmp0 ^ in2;
- out1 = tmp0 ^ in5;
- out3 = tmp1 ^ in7;
- out6 = tmp1 ^ in0;
- out2 = tmp1 ^ out5 ^ in3;
- out7 = out3 ^ in3 ^ in6;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_75(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out4 = in0 ^ in7;
- tmp0 = in1 ^ in3;
- out5 = in0 ^ in1;
- out7 = tmp0 ^ in2;
- tmp1 = tmp0 ^ in4;
- out6 = out5 ^ in2;
- tmp2 = out7 ^ in6;
- out1 = tmp1 ^ in5;
- out0 = tmp1 ^ out6;
- out3 = tmp2 ^ in7;
- out2 = tmp2 ^ out6 ^ in5;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_76(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2, tmp3;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out3 = in1 ^ in6;
- tmp0 = in0 ^ in5;
- tmp1 = in3 ^ in7;
- tmp2 = tmp0 ^ in4;
- tmp3 = tmp1 ^ in2;
- out5 = tmp2 ^ in1;
- out1 = tmp2 ^ in3;
- out0 = tmp3 ^ in4;
- out4 = out1 ^ in5;
- out7 = tmp3 ^ out3;
- out2 = tmp0 ^ out7;
- out6 = tmp1 ^ out2;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_77(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2, tmp3;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out4 = in0 ^ in3;
- tmp0 = in1 ^ in4;
- tmp1 = in1 ^ in6;
- tmp2 = out4 ^ in5;
- out5 = tmp0 ^ in0;
- out1 = tmp0 ^ tmp2;
- out3 = tmp1 ^ in3;
- out2 = tmp1 ^ tmp2 ^ in7;
- out7 = out3 ^ in2;
- tmp3 = out7 ^ in6;
- out6 = tmp2 ^ tmp3;
- out0 = tmp3 ^ out5 ^ in7;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_78(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- tmp0 = in0 ^ in3;
- tmp1 = in2 ^ in7;
- tmp2 = in0 ^ in5 ^ in6;
- out2 = tmp1 ^ in3;
- out3 = tmp2 ^ in2;
- out5 = out3 ^ in1 ^ in3;
- out0 = tmp0 ^ out3 ^ in4;
- out1 = tmp1 ^ out0;
- out4 = out1 ^ out5 ^ in5;
- out7 = tmp0 ^ out4;
- out6 = tmp2 ^ out7;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_79(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2, tmp3;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out2 = in3 ^ in7;
- tmp0 = in3 ^ in4;
- tmp1 = in1 ^ in5;
- tmp2 = tmp1 ^ in2;
- out4 = tmp2 ^ in0 ^ in7;
- tmp3 = out4 ^ in5;
- out5 = tmp3 ^ out2 ^ in6;
- out7 = tmp0 ^ tmp2;
- out6 = tmp0 ^ tmp3;
- out3 = tmp1 ^ out5;
- out0 = out3 ^ in4;
- out1 = tmp3 ^ out0;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_7A(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- tmp0 = in1 ^ in2;
- out2 = tmp0 ^ in3;
- tmp1 = out2 ^ in4;
- out4 = tmp1 ^ in0 ^ in5;
- out5 = out4 ^ in6;
- out6 = out5 ^ in7;
- out7 = out6 ^ in0;
- out0 = out7 ^ in1;
- out1 = tmp0 ^ out6;
- out3 = tmp1 ^ out6;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_7B(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out2 = in1 ^ in3;
- tmp0 = in0 ^ in5;
- out4 = tmp0 ^ out2 ^ in2;
- tmp1 = out4 ^ in4;
- out6 = tmp1 ^ in7;
- out5 = tmp1 ^ in5 ^ in6;
- out0 = out6 ^ in1 ^ in6;
- tmp2 = out0 ^ in2;
- out1 = tmp2 ^ in1;
- out3 = tmp2 ^ in4;
- out7 = tmp0 ^ out5;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_7C(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- tmp0 = in3 ^ in5;
- tmp1 = tmp0 ^ in4;
- out0 = tmp1 ^ in2;
- out1 = tmp1 ^ in6;
- out7 = out0 ^ in1 ^ in5 ^ in7;
- out5 = out1 ^ out7 ^ in0;
- out3 = out5 ^ in6;
- out6 = tmp0 ^ out5;
- out2 = out6 ^ in1;
- out4 = out2 ^ out7 ^ in5;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_7D(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2, tmp3;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- tmp0 = in1 ^ in2;
- tmp1 = tmp0 ^ in3;
- tmp2 = tmp0 ^ in6;
- out7 = tmp1 ^ in4;
- tmp3 = tmp2 ^ in0;
- out5 = tmp3 ^ in7;
- out4 = tmp3 ^ in2 ^ in5;
- out2 = tmp1 ^ out5;
- out6 = tmp2 ^ out2;
- out0 = out4 ^ out7 ^ in6;
- out1 = tmp3 ^ out0;
- out3 = out6 ^ in5;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_7E(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- tmp0 = in3 ^ in4;
- tmp1 = in0 ^ in5;
- out1 = tmp0 ^ tmp1 ^ in6;
- out3 = tmp1 ^ in1;
- out4 = out1 ^ in1 ^ in7;
- tmp2 = out4 ^ in3;
- out5 = tmp2 ^ in2;
- out6 = tmp0 ^ out5;
- out7 = tmp1 ^ out4 ^ in2;
- out2 = out6 ^ in5 ^ in7;
- out0 = tmp2 ^ out2;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_7F(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2, tmp3;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- tmp0 = in2 ^ in7;
- tmp1 = tmp0 ^ in3 ^ in5;
- tmp2 = tmp1 ^ in0;
- out0 = tmp2 ^ in4;
- out6 = tmp2 ^ in1;
- out3 = tmp0 ^ out6;
- tmp3 = out3 ^ in6;
- out1 = tmp3 ^ in4;
- out2 = tmp3 ^ in5;
- out4 = tmp3 ^ in7;
- out5 = tmp1 ^ out1;
- out7 = out0 ^ out4 ^ in3;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_80(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- tmp0 = in2 ^ in3;
- tmp1 = in4 ^ in5;
- out1 = in2 ^ in6 ^ in7;
- out5 = tmp0 ^ in4;
- tmp2 = tmp0 ^ in1;
- out6 = tmp1 ^ in3;
- out7 = tmp1 ^ in0 ^ in6;
- out4 = tmp2 ^ in7;
- out3 = tmp2 ^ out6;
- out2 = out3 ^ out5 ^ in6;
- out0 = out2 ^ in3 ^ in7;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_81(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- tmp0 = in4 ^ in6;
- tmp1 = tmp0 ^ in3;
- out6 = tmp1 ^ in5;
- out5 = out6 ^ in2 ^ in6;
- out3 = out5 ^ in1;
- out2 = tmp0 ^ out3;
- out1 = out3 ^ out6 ^ in7;
- out4 = tmp1 ^ out1;
- out7 = out2 ^ out4 ^ in0;
- out0 = out7 ^ in1 ^ in4;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_82(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out4 = in1 ^ in2;
- tmp0 = in6 ^ in7;
- out5 = in2 ^ in3;
- out6 = in3 ^ in4;
- out7 = in0 ^ in4 ^ in5;
- out0 = in1 ^ in5 ^ in6;
- out1 = tmp0 ^ in0 ^ in2;
- out2 = tmp0 ^ in3 ^ in5;
- out3 = tmp0 ^ out0 ^ in4;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_83(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2, tmp3, tmp4;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- tmp0 = in0 ^ in1;
- tmp1 = in2 ^ in5;
- tmp2 = in3 ^ in6;
- out4 = in1 ^ in2 ^ in4;
- out0 = tmp0 ^ in5 ^ in6;
- out5 = tmp1 ^ in3;
- tmp3 = tmp1 ^ in7;
- out6 = tmp2 ^ in4;
- out2 = tmp2 ^ tmp3;
- tmp4 = tmp3 ^ out4;
- out1 = tmp3 ^ out0;
- out3 = tmp4 ^ in3;
- out7 = tmp0 ^ tmp4;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_84(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out1 = in2 ^ in6;
- out6 = in3 ^ in5;
- out0 = in1 ^ in5 ^ in7;
- out7 = in0 ^ in4 ^ in6;
- out4 = in1 ^ in3 ^ in6;
- out5 = in2 ^ in4 ^ in7;
- out2 = out6 ^ in0 ^ in1;
- out3 = out5 ^ in5 ^ in6;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_85(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2, tmp3;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- tmp0 = in1 ^ in6;
- tmp1 = in3 ^ in6;
- tmp2 = tmp0 ^ in4;
- out1 = tmp0 ^ in2;
- out6 = tmp1 ^ in5;
- out4 = tmp2 ^ in3;
- tmp3 = out1 ^ out6;
- out2 = tmp3 ^ in0;
- out3 = tmp2 ^ tmp3 ^ in7;
- out7 = out2 ^ out3 ^ in1;
- out5 = tmp1 ^ out3;
- out0 = tmp2 ^ out7 ^ in5;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_86(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out6 = in3;
- out7 = in0 ^ in4;
- out0 = in1 ^ in5;
- out5 = in2 ^ in7;
- out3 = in4 ^ in5 ^ in6;
- out1 = in0 ^ in2 ^ in6;
- out4 = in1 ^ in6 ^ in7;
- out2 = in0 ^ in3 ^ in5 ^ in7;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_87(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out6 = in3 ^ in6;
- tmp0 = in0 ^ in1;
- out7 = in0 ^ in4 ^ in7;
- out5 = in2 ^ in5 ^ in7;
- out3 = out6 ^ in4 ^ in5;
- out0 = tmp0 ^ in5;
- tmp1 = tmp0 ^ in6;
- out2 = out5 ^ in0 ^ in3;
- out1 = tmp1 ^ in2;
- out4 = tmp1 ^ out7;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_88(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out1 = in2 ^ in7;
- tmp0 = in5 ^ in6;
- out0 = in1 ^ in6 ^ in7;
- out6 = in4 ^ in5 ^ in7;
- out3 = out0 ^ out1 ^ in0 ^ in4;
- out7 = tmp0 ^ in0;
- tmp1 = tmp0 ^ in3;
- out2 = out0 ^ in3;
- out4 = tmp1 ^ in2;
- out5 = tmp1 ^ out6;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_89(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- tmp0 = in0 ^ in7;
- tmp1 = in2 ^ in7;
- tmp2 = tmp0 ^ in6;
- out1 = tmp1 ^ in1;
- out7 = tmp2 ^ in5;
- out0 = tmp2 ^ in1;
- out2 = out1 ^ in3 ^ in6;
- out6 = out7 ^ in0 ^ in4;
- out5 = out6 ^ in3;
- out3 = tmp0 ^ out2 ^ in4;
- out4 = tmp1 ^ out5;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_8A(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out0 = in1 ^ in6;
- out7 = in0 ^ in5;
- out2 = in3 ^ in6;
- out6 = in4 ^ in7;
- out1 = in0 ^ in2 ^ in7;
- out3 = out0 ^ out6 ^ in0;
- out4 = out1 ^ out7 ^ in6;
- out5 = out2 ^ in7;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_8B(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2, tmp3, tmp4;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- tmp0 = in0 ^ in1;
- tmp1 = in3 ^ in6;
- tmp2 = in5 ^ in7;
- tmp3 = tmp0 ^ in7;
- out0 = tmp0 ^ in6;
- out2 = tmp1 ^ in2;
- out5 = tmp1 ^ tmp2;
- out7 = tmp2 ^ in0;
- tmp4 = tmp3 ^ in4;
- out1 = tmp3 ^ in2;
- out6 = tmp4 ^ out0;
- out4 = out6 ^ in2 ^ in5;
- out3 = tmp1 ^ tmp4;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_8C(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out1 = in2;
- out0 = in1 ^ in7;
- out7 = in0 ^ in6;
- out5 = in4 ^ in6;
- out6 = in5 ^ in7;
- out2 = out0 ^ in0 ^ in3;
- out3 = out5 ^ out7 ^ in2 ^ in7;
- out4 = out6 ^ in3;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_8D(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out1 = in1 ^ in2;
- tmp0 = in6 ^ in7;
- out0 = in0 ^ in1 ^ in7;
- out5 = in4 ^ in5 ^ in6;
- out6 = tmp0 ^ in5;
- out7 = tmp0 ^ in0;
- out4 = tmp0 ^ out5 ^ in3;
- out2 = out0 ^ in2 ^ in3;
- out3 = out2 ^ in1 ^ in4;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_8E(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out0 = in1;
- out4 = in5;
- out7 = in0;
- out5 = in6;
- out6 = in7;
- out3 = in0 ^ in4;
- out1 = in0 ^ in2;
- out2 = in0 ^ in3;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_8F(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out0 = in0 ^ in1;
- tmp0 = in0 ^ in3;
- out4 = in4 ^ in5;
- out7 = in0 ^ in7;
- out5 = in5 ^ in6;
- out6 = in6 ^ in7;
- out1 = out0 ^ in2;
- out2 = tmp0 ^ in2;
- out3 = tmp0 ^ in4;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_90(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- tmp0 = in1 ^ in2;
- tmp1 = in2 ^ in6 ^ in7;
- out3 = tmp0 ^ in7;
- out1 = tmp1 ^ in5;
- tmp2 = out1 ^ in4;
- out6 = tmp2 ^ in3;
- out5 = out6 ^ in1;
- out4 = out5 ^ in0;
- out0 = tmp0 ^ tmp2;
- out7 = tmp0 ^ out4;
- out2 = tmp1 ^ out5;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_91(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2, tmp3;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- tmp0 = in2 ^ in4;
- tmp1 = tmp0 ^ in3 ^ in5;
- out2 = tmp1 ^ in1;
- out6 = tmp1 ^ in7;
- tmp2 = out2 ^ in5 ^ in7;
- out3 = tmp2 ^ in4;
- out5 = tmp2 ^ in6;
- out1 = tmp1 ^ out5 ^ in2;
- tmp3 = out1 ^ in0;
- out4 = tmp3 ^ in3;
- out0 = tmp0 ^ tmp3;
- out7 = tmp2 ^ tmp3;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_92(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out3 = in1;
- tmp0 = in4 ^ in5;
- tmp1 = tmp0 ^ in1;
- out2 = tmp0 ^ in3 ^ in7;
- out0 = tmp1 ^ in6;
- out7 = out2 ^ in0;
- out4 = out0 ^ in0 ^ in2;
- out5 = out4 ^ out7 ^ in5;
- out6 = tmp1 ^ out5;
- out1 = out6 ^ out7 ^ in7;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_93(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out3 = in1 ^ in3;
- tmp0 = in2 ^ in7;
- tmp1 = out3 ^ in6;
- tmp2 = tmp0 ^ in4;
- out5 = tmp0 ^ tmp1;
- out6 = tmp2 ^ in3;
- out2 = out6 ^ in5;
- out0 = out2 ^ out5 ^ in0;
- out7 = tmp1 ^ out0;
- out1 = tmp2 ^ out0;
- out4 = out1 ^ in7;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_94(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out3 = in2 ^ in6;
- tmp0 = in1 ^ in4 ^ in5;
- out1 = out3 ^ in5;
- out5 = tmp0 ^ out3;
- out0 = tmp0 ^ in7;
- out4 = tmp0 ^ in0 ^ in3;
- out6 = out1 ^ in3 ^ in7;
- out2 = out4 ^ in6;
- out7 = out0 ^ out2 ^ in4;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_95(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2, tmp3, tmp4, tmp5;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- tmp0 = in2 ^ in3;
- out3 = tmp0 ^ in6;
- tmp1 = tmp0 ^ in7;
- tmp2 = out3 ^ in0;
- out6 = tmp1 ^ in5;
- tmp3 = tmp2 ^ in4;
- out7 = tmp3 ^ in2;
- tmp4 = tmp3 ^ in5;
- out2 = tmp4 ^ in1;
- tmp5 = out2 ^ in6;
- out0 = tmp1 ^ tmp5;
- out1 = tmp5 ^ out7;
- out4 = tmp2 ^ out1;
- out5 = tmp4 ^ out4;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_96(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out3 = in6 ^ in7;
- tmp0 = in1 ^ in5;
- tmp1 = in5 ^ in6;
- out6 = out3 ^ in2 ^ in3;
- out0 = tmp0 ^ in4;
- tmp2 = tmp1 ^ in2;
- out4 = out0 ^ in0 ^ in7;
- out1 = tmp2 ^ in0;
- out5 = tmp2 ^ in1;
- out7 = tmp0 ^ out4 ^ in3;
- out2 = tmp1 ^ out7;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_97(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2, tmp3;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- tmp0 = in0 ^ in4;
- tmp1 = in2 ^ in6;
- out3 = in3 ^ in6 ^ in7;
- out7 = tmp0 ^ in3;
- tmp2 = tmp0 ^ in5;
- out5 = tmp1 ^ in1;
- out6 = tmp1 ^ out3;
- out0 = tmp2 ^ in1;
- out2 = tmp2 ^ out3 ^ in2;
- tmp3 = out0 ^ in4;
- out4 = tmp3 ^ in7;
- out1 = tmp1 ^ tmp3;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_98(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- tmp0 = in5 ^ in7;
- tmp1 = in1 ^ in4 ^ in7;
- out1 = tmp0 ^ in2;
- out0 = tmp1 ^ in6;
- out2 = tmp1 ^ in3;
- out6 = out0 ^ out1 ^ in1;
- out5 = tmp0 ^ out2;
- out3 = tmp1 ^ out6 ^ in0;
- out7 = out0 ^ out5 ^ in0;
- out4 = out6 ^ out7 ^ in7;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_99(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- tmp0 = in0 ^ in3;
- out5 = in1 ^ in3 ^ in4;
- out6 = in2 ^ in4 ^ in5;
- out4 = tmp0 ^ in2;
- tmp1 = tmp0 ^ in6;
- tmp2 = out5 ^ in7;
- out7 = tmp1 ^ in5;
- out0 = tmp1 ^ tmp2;
- out2 = tmp2 ^ in2;
- out3 = out0 ^ out6 ^ in3;
- out1 = tmp1 ^ out3;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_9A(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out2 = in3 ^ in4;
- tmp0 = in0 ^ in5;
- tmp1 = in1 ^ in6;
- out5 = in1 ^ in3 ^ in5;
- tmp2 = tmp0 ^ in7;
- out3 = tmp0 ^ tmp1;
- out0 = tmp1 ^ in4;
- out7 = tmp2 ^ in3;
- out1 = tmp2 ^ in2;
- out6 = out0 ^ in1 ^ in2;
- out4 = out1 ^ in4 ^ in5;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_9B(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out5 = in1 ^ in3;
- tmp0 = in3 ^ in5;
- out6 = in2 ^ in4;
- out4 = in0 ^ in2 ^ in7;
- out7 = tmp0 ^ in0;
- out2 = out6 ^ in3;
- out1 = out4 ^ in1 ^ in5;
- out3 = out7 ^ in1 ^ in6;
- out0 = tmp0 ^ out3 ^ in4;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_9C(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out1 = in2 ^ in5;
- tmp0 = in0 ^ in3 ^ in6;
- out3 = out1 ^ in0;
- out6 = out1 ^ in6;
- out7 = tmp0 ^ in7;
- out4 = out7 ^ in4;
- out2 = out4 ^ in1;
- out0 = tmp0 ^ out2;
- out5 = out0 ^ in5;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_9D(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out6 = in2 ^ in5;
- tmp0 = in0 ^ in3;
- out5 = in1 ^ in4 ^ in7;
- out1 = out6 ^ in1;
- out3 = tmp0 ^ out6;
- out7 = tmp0 ^ in6;
- out0 = out5 ^ in0;
- out4 = out7 ^ in7;
- out2 = out5 ^ out7 ^ in2;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_9E(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out0 = in1 ^ in4;
- tmp0 = in0 ^ in5;
- out6 = in2 ^ in6;
- out7 = in0 ^ in3 ^ in7;
- out4 = in0 ^ in4 ^ in6;
- out5 = in1 ^ in5 ^ in7;
- out1 = tmp0 ^ in2;
- out3 = tmp0 ^ in7;
- out2 = out4 ^ in3;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_9F(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out6 = in2;
- out7 = in0 ^ in3;
- tmp0 = in0 ^ in1;
- out4 = in0 ^ in6;
- out5 = in1 ^ in7;
- out1 = tmp0 ^ in2 ^ in5;
- out2 = out7 ^ in2 ^ in4 ^ in6;
- out3 = out7 ^ in5 ^ in7;
- out0 = tmp0 ^ in4;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_A0(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2, tmp3;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- tmp0 = in1 ^ in6;
- out2 = tmp0 ^ in7;
- tmp1 = tmp0 ^ in5;
- out6 = out2 ^ in3 ^ in4;
- out0 = tmp1 ^ in3;
- tmp2 = out0 ^ in2;
- out3 = tmp2 ^ in7;
- tmp3 = tmp2 ^ in1;
- out5 = tmp3 ^ in0;
- out4 = tmp3 ^ out6;
- out7 = out5 ^ out6 ^ in1;
- out1 = tmp1 ^ out4;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_A1(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- tmp0 = in2 ^ in5;
- tmp1 = tmp0 ^ in1;
- tmp2 = tmp0 ^ in4;
- out4 = tmp1 ^ in7;
- out7 = tmp2 ^ in0;
- out6 = tmp2 ^ out4 ^ in3;
- out3 = out4 ^ in6;
- out2 = out3 ^ in5;
- out1 = out2 ^ in4;
- out5 = out1 ^ out6 ^ in0;
- out0 = tmp1 ^ out5;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_A2(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out2 = in6;
- tmp0 = in1 ^ in3 ^ in5;
- out3 = tmp0 ^ in6;
- out4 = tmp0 ^ in2 ^ in4;
- out0 = out3 ^ in7;
- out6 = out0 ^ in4;
- out1 = out0 ^ out4 ^ in0;
- out7 = out1 ^ in5;
- out5 = out7 ^ in3 ^ in7;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_A3(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out2 = in2 ^ in6;
- out3 = in1 ^ in5 ^ in6;
- tmp0 = out2 ^ in0;
- out4 = out2 ^ out3 ^ in3;
- tmp1 = tmp0 ^ in4;
- out0 = tmp0 ^ out4 ^ in7;
- out5 = tmp1 ^ in3;
- out7 = tmp1 ^ in5;
- out1 = tmp1 ^ in1 ^ in7;
- out6 = tmp1 ^ out0 ^ in2;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_A4(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2, tmp3, tmp4;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- tmp0 = in1 ^ in3;
- tmp1 = in2 ^ in4;
- tmp2 = in2 ^ in5;
- tmp3 = in0 ^ in7;
- out0 = tmp0 ^ in5;
- out6 = tmp0 ^ in6 ^ in7;
- out1 = tmp1 ^ in6;
- out7 = tmp1 ^ tmp3;
- out3 = tmp2 ^ in3;
- tmp4 = tmp2 ^ out1;
- out2 = tmp3 ^ in1;
- out5 = tmp4 ^ out7;
- out4 = tmp4 ^ in1;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_A5(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out3 = in2 ^ in5;
- tmp0 = in1 ^ in6;
- tmp1 = in0 ^ in1;
- tmp2 = in2 ^ in4;
- out6 = in1 ^ in3 ^ in7;
- out4 = tmp0 ^ in5;
- out1 = tmp0 ^ tmp2;
- out0 = tmp1 ^ in3 ^ in5;
- out2 = tmp1 ^ in2 ^ in7;
- out7 = tmp2 ^ in0;
- out5 = tmp0 ^ out2;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_A6(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out2 = in0;
- out3 = in3 ^ in5 ^ in7;
- out1 = in0 ^ in2 ^ in4 ^ in6;
- out0 = out3 ^ in1;
- out7 = out1 ^ in7;
- out6 = out0 ^ in6;
- out5 = out7 ^ in5;
- out4 = out6 ^ in4;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_A7(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out2 = in0 ^ in2;
- out3 = in5 ^ in7;
- out7 = out2 ^ in4 ^ in6;
- out6 = out3 ^ in1 ^ in3;
- out1 = out7 ^ in1;
- out5 = out7 ^ in7;
- out0 = out6 ^ in0;
- out4 = out6 ^ in6;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_A8(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- tmp0 = in2 ^ in4;
- tmp1 = in1 ^ in6;
- tmp2 = in0 ^ in2 ^ in7;
- out1 = tmp0 ^ in7;
- out4 = tmp0 ^ in6;
- out0 = tmp1 ^ in3;
- out2 = tmp1 ^ in5;
- out6 = tmp1 ^ in4;
- out7 = tmp2 ^ in5;
- out3 = tmp2 ^ out0 ^ in6;
- out5 = out7 ^ in2 ^ in3;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_A9(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out4 = in2 ^ in6;
- out6 = in1 ^ in4;
- out7 = in0 ^ in2 ^ in5;
- out5 = in0 ^ in3 ^ in7;
- out2 = out4 ^ in1 ^ in5;
- out1 = out6 ^ in2 ^ in7;
- out0 = out2 ^ out7 ^ in3;
- out3 = out1 ^ in0 ^ in4;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_AA(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- tmp0 = in0 ^ in2;
- tmp1 = in1 ^ in3;
- tmp2 = in6 ^ in7;
- out1 = tmp0 ^ in4 ^ in7;
- out3 = tmp1 ^ in0;
- out0 = tmp1 ^ tmp2;
- out2 = tmp2 ^ in5;
- out7 = tmp0 ^ out2;
- out6 = out1 ^ out7 ^ in1;
- out5 = out0 ^ out6 ^ in0;
- out4 = out5 ^ out7 ^ in7;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_AB(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out3 = in0 ^ in1;
- tmp0 = in1 ^ in4;
- tmp1 = in0 ^ in7;
- out6 = tmp0 ^ in5;
- out1 = tmp0 ^ tmp1 ^ in2;
- out5 = tmp1 ^ in3 ^ in4;
- out0 = tmp0 ^ out5 ^ in6;
- out4 = out0 ^ out3 ^ in2;
- out2 = out4 ^ in3 ^ in5;
- out7 = tmp1 ^ out2;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_AC(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out0 = in1 ^ in3;
- out1 = in2 ^ in4;
- tmp0 = in0 ^ in2;
- out4 = in4 ^ in7;
- out5 = in0 ^ in5;
- out6 = in1 ^ in6;
- out7 = tmp0 ^ in7;
- out3 = tmp0 ^ in3 ^ in6;
- out2 = out5 ^ in1;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_AD(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out4 = in7;
- out5 = in0;
- out6 = in1;
- out7 = in0 ^ in2;
- out0 = in0 ^ in1 ^ in3;
- out2 = out7 ^ in1 ^ in5;
- out1 = in1 ^ in2 ^ in4;
- out3 = out7 ^ in6;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_AE(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out4 = in3 ^ in4;
- tmp0 = in0 ^ in4;
- tmp1 = in0 ^ in7;
- out0 = in1 ^ in3 ^ in7;
- out1 = tmp0 ^ in2;
- out5 = tmp0 ^ in5;
- tmp2 = tmp1 ^ in6;
- out2 = tmp1 ^ in5;
- out3 = tmp2 ^ in3;
- out7 = tmp2 ^ in2;
- out6 = tmp2 ^ out2 ^ in1;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_AF(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out4 = in3;
- tmp0 = in0 ^ in7;
- out5 = in0 ^ in4;
- out6 = in1 ^ in5;
- out7 = in0 ^ in2 ^ in6;
- out0 = tmp0 ^ in1 ^ in3;
- out3 = tmp0 ^ in6;
- out2 = tmp0 ^ in2 ^ in5;
- out1 = out5 ^ in1 ^ in2;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_B0(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2, tmp3;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- tmp0 = in1 ^ in4;
- tmp1 = in3 ^ in6;
- out2 = tmp0 ^ in7;
- tmp2 = tmp0 ^ tmp1;
- out0 = tmp2 ^ in5;
- out3 = tmp2 ^ in2;
- out6 = out3 ^ in6;
- tmp3 = out6 ^ in0 ^ in1;
- out7 = tmp3 ^ in5;
- out5 = tmp3 ^ out2;
- out1 = out0 ^ out5 ^ in0;
- out4 = tmp1 ^ out5;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_B1(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- tmp0 = in1 ^ in4;
- out2 = tmp0 ^ in2 ^ in7;
- tmp1 = out2 ^ in6;
- out1 = tmp1 ^ in5;
- out3 = tmp1 ^ in7;
- out4 = tmp1 ^ in0;
- out6 = out3 ^ in3;
- out0 = out6 ^ in0 ^ in2 ^ in5;
- out5 = tmp1 ^ out0 ^ in1;
- out7 = tmp0 ^ out5;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_B2(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2, tmp3, tmp4;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out2 = in4;
- tmp0 = in4 ^ in7;
- tmp1 = in1 ^ in3 ^ in6;
- out3 = tmp0 ^ tmp1;
- tmp2 = tmp1 ^ in0;
- out0 = out3 ^ in5;
- out4 = tmp2 ^ in2;
- tmp3 = out4 ^ in6;
- out5 = tmp0 ^ tmp3;
- out1 = tmp3 ^ out0;
- tmp4 = out1 ^ in7;
- out7 = tmp4 ^ in3;
- out6 = tmp2 ^ tmp4;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_B3(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out2 = in2 ^ in4;
- tmp0 = in0 ^ in5;
- tmp1 = in1 ^ in6;
- out3 = tmp1 ^ in4 ^ in7;
- tmp2 = tmp0 ^ out3;
- out0 = tmp2 ^ in3;
- out1 = tmp2 ^ in2;
- out5 = out0 ^ in2 ^ in6;
- out7 = tmp1 ^ out5;
- out4 = out7 ^ in1 ^ in5 ^ in7;
- out6 = tmp0 ^ out4;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_B4(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out4 = in0 ^ in1;
- out5 = out4 ^ in2;
- tmp0 = out4 ^ in4;
- out6 = out5 ^ in0 ^ in3;
- out7 = tmp0 ^ out6;
- out2 = tmp0 ^ in6 ^ in7;
- out3 = out7 ^ in0 ^ in7;
- out0 = out5 ^ out7 ^ in5;
- out1 = out0 ^ out6 ^ in6;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_B5(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- tmp0 = in0 ^ in1;
- tmp1 = in2 ^ in4;
- out4 = tmp0 ^ in4;
- out3 = tmp1 ^ in7;
- tmp2 = out4 ^ in5;
- out7 = out3 ^ in0 ^ in3;
- out0 = tmp2 ^ in3;
- out2 = tmp0 ^ out3 ^ in6;
- out5 = tmp1 ^ tmp2;
- out6 = out2 ^ out7 ^ in2;
- out1 = tmp0 ^ out0 ^ out6;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_B6(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2, tmp3;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out3 = in3 ^ in4;
- tmp0 = in1 ^ in2;
- tmp1 = in0 ^ in4;
- tmp2 = in3 ^ in5;
- tmp3 = out3 ^ in1 ^ in7;
- out5 = tmp0 ^ tmp1;
- out6 = tmp0 ^ tmp2;
- out2 = tmp1 ^ in6;
- out4 = tmp1 ^ tmp3;
- out0 = tmp3 ^ in5;
- out1 = out2 ^ in2 ^ in5;
- out7 = tmp2 ^ out1;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_B7(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out3 = in4;
- tmp0 = in0 ^ in4;
- out2 = tmp0 ^ in2 ^ in6;
- tmp1 = out2 ^ in7;
- out1 = out2 ^ in1 ^ in5;
- out7 = tmp1 ^ in3;
- out5 = out1 ^ in6;
- out6 = tmp0 ^ out1 ^ in3;
- out0 = tmp1 ^ out6;
- out4 = out0 ^ in5;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_B8(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- tmp0 = in1 ^ in4;
- tmp1 = in2 ^ in5;
- out2 = tmp0 ^ in5;
- out4 = tmp1 ^ in0;
- tmp2 = tmp1 ^ in7;
- out6 = tmp2 ^ out2;
- out7 = out4 ^ in3;
- out1 = tmp2 ^ in4;
- out3 = tmp0 ^ out7;
- out0 = out3 ^ out4 ^ in6;
- out5 = out0 ^ in0 ^ in4;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_B9(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- tmp0 = in0 ^ in2;
- tmp1 = in4 ^ in5;
- out4 = tmp0 ^ tmp1;
- tmp2 = tmp0 ^ in3 ^ in7;
- out3 = out4 ^ in1;
- out7 = tmp2 ^ in5;
- out2 = out3 ^ in0;
- out1 = out2 ^ in7;
- out6 = out1 ^ in5 ^ in6;
- out0 = tmp2 ^ out6;
- out5 = tmp1 ^ out0;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_BA(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- tmp0 = in5 ^ in7;
- out2 = tmp0 ^ in4;
- tmp1 = out2 ^ in2;
- out1 = tmp1 ^ in0;
- out6 = tmp1 ^ in1;
- out4 = out1 ^ in3 ^ in4;
- tmp2 = out4 ^ out6;
- out7 = out4 ^ in6 ^ in7;
- out5 = tmp2 ^ in6;
- out3 = tmp0 ^ tmp2;
- out0 = out6 ^ out7 ^ in0;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_BB(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out2 = in2 ^ in4 ^ in5 ^ in7;
- tmp0 = out2 ^ in1;
- out4 = out2 ^ in0 ^ in3;
- out1 = tmp0 ^ in0;
- out6 = tmp0 ^ in6;
- out3 = out1 ^ in2;
- tmp1 = out4 ^ out6 ^ in4;
- out0 = tmp1 ^ in7;
- out5 = tmp1 ^ in5;
- out7 = tmp0 ^ tmp1;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_BC(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- tmp0 = in0 ^ in2;
- tmp1 = in2 ^ in4;
- out0 = in1 ^ in3 ^ in4;
- out6 = in1 ^ in2 ^ in7;
- out7 = tmp0 ^ in3;
- out5 = tmp0 ^ out6 ^ in6;
- out1 = tmp1 ^ in5;
- tmp2 = out1 ^ out5 ^ in1;
- out3 = tmp2 ^ in3;
- out4 = tmp1 ^ tmp2;
- out2 = tmp2 ^ out6;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_BD(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- tmp0 = in0 ^ in3;
- tmp1 = in1 ^ in4;
- out0 = tmp0 ^ tmp1;
- out7 = tmp0 ^ in2 ^ in7;
- out1 = tmp1 ^ in2 ^ in5;
- tmp2 = out1 ^ in0;
- out2 = tmp2 ^ in6;
- out3 = out2 ^ in1 ^ in7;
- out4 = out3 ^ in2;
- out5 = tmp1 ^ out4;
- out6 = tmp2 ^ out4;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_BE(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- tmp0 = in0 ^ in3 ^ in6;
- out4 = tmp0 ^ in5;
- out7 = tmp0 ^ in2;
- out3 = out4 ^ in4;
- out1 = out3 ^ out7 ^ in0;
- out2 = out3 ^ in3 ^ in7;
- out0 = out2 ^ out4 ^ in1;
- out5 = tmp0 ^ out0;
- out6 = out1 ^ out5 ^ in6;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_BF(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2, tmp3;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- tmp0 = in0 ^ in4;
- out3 = tmp0 ^ in5 ^ in6;
- out4 = out3 ^ in3;
- tmp1 = out3 ^ in7;
- out2 = tmp1 ^ in2;
- out5 = tmp1 ^ in1;
- tmp2 = out2 ^ in5;
- out7 = tmp2 ^ in3 ^ in4;
- tmp3 = tmp0 ^ out5;
- out0 = tmp3 ^ out4;
- out1 = tmp2 ^ tmp3;
- out6 = tmp3 ^ in2;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_C0(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out5 = in2 ^ in5;
- tmp0 = in1 ^ in4;
- tmp1 = in3 ^ in6;
- out0 = out5 ^ in1;
- out4 = tmp0 ^ in7;
- out3 = tmp0 ^ tmp1;
- out1 = tmp1 ^ in2;
- out6 = tmp1 ^ in0;
- out7 = out4 ^ in0;
- out2 = out4 ^ out5 ^ in3;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_C1(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out5 = in2;
- tmp0 = in0 ^ in1;
- out4 = in1 ^ in7;
- out6 = in0 ^ in3;
- out3 = in1 ^ in4 ^ in6;
- tmp1 = tmp0 ^ in2;
- out7 = tmp0 ^ in4;
- out0 = tmp1 ^ in5;
- out1 = tmp1 ^ out6 ^ in6;
- out2 = out6 ^ out7 ^ in5 ^ in7;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_C2(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out4 = in1 ^ in3 ^ in4;
- tmp0 = in0 ^ in3 ^ in6;
- out5 = in2 ^ in4 ^ in5;
- tmp1 = out4 ^ in7;
- out1 = tmp0 ^ in2;
- out6 = tmp0 ^ in5;
- out2 = out5 ^ in3;
- out7 = tmp0 ^ tmp1;
- out3 = tmp1 ^ in2 ^ in6;
- out0 = tmp1 ^ out2;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_C3(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out4 = in1 ^ in3;
- tmp0 = in0 ^ in2;
- tmp1 = in3 ^ in5;
- out5 = in2 ^ in4;
- tmp2 = tmp0 ^ out4;
- out2 = tmp1 ^ in4;
- out6 = tmp1 ^ in0;
- out0 = tmp1 ^ tmp2 ^ in7;
- out1 = tmp2 ^ in6;
- out7 = out1 ^ out5 ^ in3;
- out3 = tmp0 ^ out7 ^ in7;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_C4(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- tmp0 = in3 ^ in7;
- out3 = tmp0 ^ in4;
- tmp1 = tmp0 ^ in2;
- out1 = tmp1 ^ in6;
- out5 = tmp1 ^ in5;
- out4 = out1 ^ out3 ^ in1;
- out0 = out4 ^ in4 ^ in5;
- out2 = out0 ^ out3 ^ in0;
- out7 = out1 ^ out2 ^ in7;
- out6 = tmp1 ^ out0 ^ out7;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_C5(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out3 = in4 ^ in7;
- tmp0 = in3 ^ in7;
- out4 = in1 ^ in2 ^ in6;
- out6 = in0 ^ in3 ^ in4;
- out5 = tmp0 ^ in2;
- out1 = tmp0 ^ out4;
- out0 = out4 ^ in0 ^ in5;
- out2 = out0 ^ out5 ^ in4;
- out7 = tmp0 ^ out2 ^ in6;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_C6(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2, tmp3, tmp4, tmp5;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- tmp0 = in5 ^ in6;
- tmp1 = in1 ^ in7;
- tmp2 = tmp0 ^ in0;
- tmp3 = tmp0 ^ tmp1;
- tmp4 = tmp2 ^ in4;
- out0 = tmp3 ^ in2;
- out6 = tmp4 ^ in3;
- out2 = out6 ^ in2;
- out7 = tmp1 ^ tmp4;
- out3 = tmp2 ^ out2;
- tmp5 = out3 ^ in5;
- out5 = tmp5 ^ in7;
- out4 = tmp3 ^ tmp5;
- out1 = tmp4 ^ out5;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_C7(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out3 = in2 ^ in4;
- tmp0 = in3 ^ in5;
- tmp1 = out3 ^ in7;
- out6 = tmp0 ^ in0 ^ in4;
- out5 = tmp1 ^ in3;
- out2 = out6 ^ in6;
- out7 = out2 ^ in1 ^ in3;
- out0 = tmp1 ^ out7;
- out1 = tmp0 ^ out0;
- out4 = out1 ^ in0;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_C8(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out0 = in1 ^ in2;
- out1 = in2 ^ in3;
- tmp0 = in5 ^ in6;
- tmp1 = in0 ^ in7;
- out2 = out1 ^ in1 ^ in4;
- out4 = tmp0 ^ in4;
- out5 = tmp0 ^ in7;
- out6 = tmp1 ^ in6;
- out7 = tmp1 ^ in1;
- out3 = out2 ^ in0 ^ in2 ^ in5;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_C9(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out4 = in5 ^ in6;
- out7 = in0 ^ in1;
- tmp0 = in1 ^ in3;
- out5 = in6 ^ in7;
- out6 = in0 ^ in7;
- out0 = out7 ^ in2;
- out3 = out7 ^ in4 ^ in5;
- out1 = tmp0 ^ in2;
- out2 = tmp0 ^ in4;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_CA(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2, tmp3;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- tmp0 = in0 ^ in7;
- tmp1 = in2 ^ in7;
- tmp2 = tmp0 ^ in6;
- out0 = tmp1 ^ in1;
- tmp3 = tmp1 ^ in3;
- out6 = tmp2 ^ in5;
- out7 = tmp2 ^ in1;
- out2 = tmp3 ^ in4;
- out5 = out6 ^ in0 ^ in4;
- out4 = out5 ^ in3;
- out1 = tmp0 ^ tmp3;
- out3 = tmp3 ^ out5 ^ out7;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_CB(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- tmp0 = in4 ^ in7;
- tmp1 = in5 ^ in7;
- out7 = in0 ^ in1 ^ in6;
- out5 = tmp0 ^ in6;
- out2 = tmp0 ^ in3;
- out6 = tmp1 ^ in0;
- out4 = tmp1 ^ in3 ^ in6;
- tmp2 = out5 ^ out7 ^ in2;
- out1 = tmp2 ^ out2;
- out0 = tmp2 ^ in4;
- out3 = tmp2 ^ in5;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_CC(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2, tmp3;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- tmp0 = in3 ^ in5;
- tmp1 = in1 ^ in6;
- out1 = in2 ^ in3 ^ in7;
- out5 = tmp0 ^ in6;
- out0 = tmp1 ^ in2;
- tmp2 = out5 ^ in0 ^ in7;
- out3 = tmp2 ^ in4;
- out6 = tmp0 ^ out3;
- out7 = tmp1 ^ tmp2 ^ in3;
- tmp3 = out1 ^ out6;
- out4 = tmp2 ^ tmp3;
- out2 = tmp3 ^ in1;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_CD(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out5 = in3 ^ in6;
- tmp0 = in0 ^ in1;
- tmp1 = in2 ^ in7;
- out6 = in0 ^ in4 ^ in7;
- out2 = tmp0 ^ out5 ^ in4;
- out7 = tmp0 ^ in5;
- out0 = tmp0 ^ in2 ^ in6;
- out4 = tmp1 ^ in5;
- out1 = tmp1 ^ in1 ^ in3;
- out3 = out6 ^ in5 ^ in6;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_CE(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- tmp0 = in2 ^ in5;
- tmp1 = tmp0 ^ in3;
- out4 = tmp1 ^ in4;
- tmp2 = out4 ^ in6;
- out3 = tmp2 ^ in0;
- out5 = tmp2 ^ in2;
- out2 = out3 ^ in5 ^ in7;
- out6 = tmp1 ^ out2;
- out7 = out2 ^ out4 ^ in1;
- out1 = tmp2 ^ out6;
- out0 = tmp0 ^ out7 ^ in0;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_CF(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- tmp0 = in3 ^ in6;
- tmp1 = in0 ^ in1 ^ in5;
- out4 = in2 ^ in3 ^ in5;
- out5 = tmp0 ^ in4;
- out7 = tmp1 ^ in6;
- out1 = tmp1 ^ out4 ^ in7;
- tmp2 = out5 ^ in0;
- out2 = tmp2 ^ in7;
- out3 = tmp2 ^ out4;
- out6 = tmp0 ^ out2 ^ in5;
- out0 = tmp0 ^ out1;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_D0(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2, tmp3, tmp4;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- tmp0 = in0 ^ in3;
- tmp1 = in1 ^ in4;
- tmp2 = in2 ^ in5;
- out7 = tmp0 ^ tmp1;
- out0 = tmp1 ^ tmp2;
- tmp3 = tmp2 ^ in3;
- out1 = tmp3 ^ in6;
- tmp4 = out1 ^ in1;
- out2 = tmp4 ^ in7;
- out3 = out2 ^ in2;
- out4 = tmp0 ^ out3;
- out5 = tmp3 ^ out3;
- out6 = tmp4 ^ out4;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_D1(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- tmp0 = in3 ^ in5 ^ in6;
- tmp1 = tmp0 ^ in1;
- out1 = tmp1 ^ in2;
- out2 = tmp1 ^ in7;
- out3 = out2 ^ in3;
- out5 = out3 ^ in2;
- tmp2 = out3 ^ in0;
- out4 = tmp2 ^ in4;
- out7 = tmp0 ^ out4;
- out6 = tmp2 ^ out1 ^ in6;
- out0 = out2 ^ out6 ^ in4;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_D2(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- tmp0 = in5 ^ in6;
- out2 = tmp0 ^ in2 ^ in3;
- out1 = out2 ^ in0;
- out3 = out2 ^ in1;
- out4 = out1 ^ in1 ^ in2;
- out6 = out1 ^ in6 ^ in7;
- out7 = out4 ^ in4 ^ in5;
- out5 = out4 ^ out6 ^ in4;
- out0 = tmp0 ^ out5;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_D3(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2, tmp3;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out2 = in3 ^ in5 ^ in6;
- tmp0 = out2 ^ in2;
- tmp1 = tmp0 ^ in1;
- out1 = tmp1 ^ in0;
- out3 = tmp1 ^ in3;
- out4 = out1 ^ in2 ^ in4;
- tmp2 = out4 ^ in5;
- out7 = tmp2 ^ in7;
- out0 = tmp0 ^ out7;
- tmp3 = out0 ^ in0;
- out5 = tmp3 ^ in6;
- out6 = tmp2 ^ tmp3;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_D4(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out3 = in3 ^ in5;
- tmp0 = in1 ^ in5;
- tmp1 = tmp0 ^ in2;
- out4 = tmp1 ^ in0;
- tmp2 = tmp1 ^ in6;
- out2 = out4 ^ in3 ^ in7;
- out0 = tmp2 ^ in4;
- out5 = tmp2 ^ out3;
- out1 = tmp0 ^ out5 ^ in7;
- out6 = tmp0 ^ out2 ^ in4;
- out7 = tmp1 ^ out6 ^ in7;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_D5(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out3 = in5;
- tmp0 = in0 ^ in4;
- tmp1 = tmp0 ^ in1 ^ in5;
- out4 = tmp1 ^ in2;
- out0 = out4 ^ in6;
- tmp2 = tmp0 ^ out0;
- out5 = tmp2 ^ in3;
- out1 = out5 ^ in7;
- out6 = tmp1 ^ out1;
- out7 = tmp2 ^ out6;
- out2 = out7 ^ in4;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_D6(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- tmp0 = in1 ^ in2 ^ in4 ^ in6;
- out5 = tmp0 ^ in3;
- out0 = tmp0 ^ in5 ^ in7;
- out3 = out0 ^ out5 ^ in2;
- tmp1 = out3 ^ in0;
- out1 = tmp1 ^ in6;
- out2 = tmp1 ^ in7;
- out4 = tmp1 ^ in1;
- out6 = tmp1 ^ in4;
- out7 = tmp0 ^ out2;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_D7(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- tmp0 = in0 ^ in3;
- out3 = in2 ^ in5 ^ in7;
- out2 = tmp0 ^ in5;
- tmp1 = tmp0 ^ out3 ^ in1;
- out1 = tmp1 ^ in6;
- out4 = tmp1 ^ in4;
- tmp2 = out1 ^ in4;
- out6 = tmp2 ^ in1;
- out7 = tmp2 ^ in2;
- out0 = tmp2 ^ in3;
- out5 = tmp2 ^ in0 ^ in7;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_D8(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out4 = in0;
- out5 = in1;
- tmp0 = in1 ^ in2;
- out6 = in0 ^ in2;
- out0 = tmp0 ^ in4;
- tmp1 = tmp0 ^ in3;
- out7 = tmp1 ^ out6;
- out2 = tmp1 ^ in6;
- out3 = out7 ^ in7;
- out1 = tmp1 ^ in1 ^ in5;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_D9(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out4 = in0 ^ in4;
- out5 = in1 ^ in5;
- out2 = in1 ^ in3 ^ in6;
- out3 = in0 ^ in1 ^ in7;
- out6 = in0 ^ in2 ^ in6;
- out0 = out4 ^ in1 ^ in2;
- out1 = out5 ^ in2 ^ in3;
- out7 = out3 ^ in3;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_DA(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out5 = in1 ^ in4;
- tmp0 = in2 ^ in7;
- tmp1 = in0 ^ in2 ^ in3;
- out0 = tmp0 ^ out5;
- out4 = tmp0 ^ tmp1;
- out2 = tmp0 ^ in3 ^ in6;
- out1 = tmp1 ^ in5;
- out3 = tmp1 ^ in1;
- out6 = out1 ^ in3;
- out7 = out3 ^ in2 ^ in6;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_DB(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2, tmp3, tmp4;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- tmp0 = in0 ^ in1;
- tmp1 = in1 ^ in5;
- tmp2 = in3 ^ in7;
- out3 = tmp0 ^ in2;
- out5 = tmp1 ^ in4;
- out6 = tmp1 ^ out3 ^ in6;
- out2 = tmp2 ^ in6;
- tmp3 = tmp2 ^ in4;
- tmp4 = out3 ^ in3;
- out4 = tmp3 ^ in0;
- out1 = tmp4 ^ in5;
- out0 = tmp3 ^ tmp4;
- out7 = tmp0 ^ out2;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_DC(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2, tmp3;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- tmp0 = in0 ^ in2;
- tmp1 = in0 ^ in3;
- out6 = tmp0 ^ in4;
- tmp2 = tmp0 ^ in7;
- out3 = tmp1 ^ in6;
- tmp3 = tmp1 ^ in1;
- out1 = tmp1 ^ tmp2 ^ in5;
- out4 = tmp2 ^ in6;
- out2 = tmp3 ^ in2;
- out7 = tmp3 ^ in5;
- out5 = tmp2 ^ out2;
- out0 = out2 ^ out3 ^ in4;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_DD(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out3 = in0 ^ in6;
- out2 = in0 ^ in1 ^ in3;
- out6 = out3 ^ in2 ^ in4;
- out7 = out2 ^ in5 ^ in7;
- out0 = out6 ^ in1;
- out4 = out6 ^ in7;
- out5 = out7 ^ in0;
- out1 = out5 ^ in2;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_DE(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- tmp0 = in2 ^ in3 ^ in6;
- tmp1 = in3 ^ in4 ^ in7;
- out4 = tmp0 ^ in0;
- out5 = tmp1 ^ in1;
- out3 = out4 ^ in7;
- out2 = out3 ^ in6;
- out1 = out2 ^ in5;
- out6 = tmp1 ^ out1;
- out0 = tmp0 ^ out5;
- out7 = out0 ^ out1 ^ in4;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_DF(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out2 = in0 ^ in3 ^ in7;
- tmp0 = out2 ^ in1 ^ in5;
- out1 = tmp0 ^ in2;
- out7 = tmp0 ^ in6;
- out5 = tmp0 ^ in0 ^ in4;
- tmp1 = out1 ^ out5 ^ in6;
- out4 = tmp1 ^ in3;
- out6 = tmp1 ^ in5;
- tmp2 = tmp1 ^ in7;
- out0 = tmp2 ^ in1;
- out3 = tmp2 ^ in4;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_E0(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out3 = in1 ^ in7;
- tmp0 = in2 ^ in4;
- out4 = out3 ^ in3 ^ in5;
- out2 = tmp0 ^ in1;
- tmp1 = tmp0 ^ in6;
- out0 = out4 ^ in2;
- out6 = out4 ^ in0;
- out1 = tmp1 ^ in3;
- out5 = tmp1 ^ in0;
- out7 = out5 ^ in1;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_E1(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2, tmp3;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out2 = in1 ^ in4;
- tmp0 = in1 ^ in7;
- out3 = tmp0 ^ in3;
- tmp1 = out3 ^ in5;
- out4 = tmp1 ^ in4;
- tmp2 = tmp1 ^ in0;
- out0 = tmp2 ^ in2;
- out6 = tmp2 ^ in6;
- tmp3 = out0 ^ out4 ^ in6;
- out5 = tmp3 ^ in5;
- out7 = tmp0 ^ tmp3;
- out1 = tmp2 ^ out5 ^ in7;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_E2(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out3 = in1 ^ in2;
- out4 = in1 ^ in5;
- out2 = in2 ^ in4 ^ in7;
- out5 = in0 ^ in2 ^ in6;
- out0 = out3 ^ in3 ^ in5;
- out7 = out3 ^ in0 ^ in4;
- out6 = out2 ^ out7 ^ in3;
- out1 = out5 ^ in3 ^ in4;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_E3(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2, tmp3, tmp4;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out2 = in4 ^ in7;
- tmp0 = in1 ^ in3;
- out3 = tmp0 ^ in2;
- tmp1 = out3 ^ in0;
- out0 = tmp1 ^ in5;
- tmp2 = tmp1 ^ in4;
- out1 = tmp2 ^ in6;
- tmp3 = tmp2 ^ in3;
- out7 = tmp3 ^ in7;
- out6 = out1 ^ out2 ^ in2;
- tmp4 = tmp0 ^ out0;
- out5 = tmp4 ^ in6;
- out4 = tmp3 ^ tmp4;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_E4(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out3 = in6;
- tmp0 = in0 ^ in4;
- tmp1 = tmp0 ^ in2 ^ in6;
- out2 = tmp1 ^ in1;
- out7 = out2 ^ in5;
- tmp2 = tmp0 ^ out7;
- out4 = tmp2 ^ in3;
- out0 = out4 ^ in7;
- out6 = tmp1 ^ out0;
- out5 = tmp2 ^ out6;
- out1 = out5 ^ in0;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_E5(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out3 = in3 ^ in6;
- tmp0 = in0 ^ in1;
- tmp1 = in5 ^ in7;
- out2 = tmp0 ^ in4 ^ in6;
- tmp2 = tmp1 ^ out2;
- out6 = tmp2 ^ in3;
- out7 = tmp2 ^ in2;
- out0 = out6 ^ in2 ^ in4;
- out5 = out6 ^ in1 ^ in2;
- out1 = tmp0 ^ out5 ^ in5;
- out4 = tmp1 ^ out1;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_E6(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out3 = in2 ^ in6 ^ in7;
- out2 = out3 ^ in0 ^ in4;
- out4 = out3 ^ in1 ^ in5;
- out1 = out2 ^ in3;
- out7 = out2 ^ out4 ^ in2;
- out0 = out4 ^ in3 ^ in7;
- out5 = out1 ^ in4;
- out6 = out0 ^ out2 ^ in5;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_E7(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2, tmp3, tmp4;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- tmp0 = in2 ^ in3;
- out3 = tmp0 ^ in6 ^ in7;
- tmp1 = out3 ^ in0;
- out5 = tmp1 ^ in5;
- tmp2 = tmp1 ^ in4;
- tmp3 = out5 ^ in7;
- out1 = tmp2 ^ in1;
- out0 = tmp3 ^ in1;
- out6 = out1 ^ in2;
- out2 = tmp0 ^ tmp2;
- tmp4 = tmp3 ^ out6;
- out4 = tmp4 ^ in6;
- out7 = tmp4 ^ in0;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_E8(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2, tmp3;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out4 = in3 ^ in6;
- tmp0 = in4 ^ in7;
- out1 = in2 ^ in3 ^ in4;
- out5 = tmp0 ^ in0;
- tmp1 = tmp0 ^ in1;
- tmp2 = tmp1 ^ in5;
- out0 = tmp1 ^ out1;
- out2 = tmp2 ^ in2;
- out6 = tmp2 ^ out5;
- tmp3 = out6 ^ in6;
- out3 = tmp3 ^ in7;
- out7 = tmp3 ^ in2 ^ in5;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_E9(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- tmp0 = in0 ^ in1;
- tmp1 = in3 ^ in6;
- tmp2 = tmp0 ^ in6;
- out4 = tmp1 ^ in4;
- out6 = tmp2 ^ in5;
- out7 = tmp2 ^ in2 ^ in7;
- out3 = out6 ^ in3 ^ in7;
- out0 = tmp1 ^ out7;
- out2 = out3 ^ out4 ^ in0;
- out5 = tmp0 ^ out2;
- out1 = out0 ^ out5 ^ in5;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_EA(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out4 = in6 ^ in7;
- out5 = in0 ^ in7;
- out6 = in0 ^ in1;
- out0 = in1 ^ in2 ^ in3;
- out2 = in2 ^ in4 ^ in5;
- out7 = out6 ^ in2;
- out1 = out0 ^ out6 ^ in4;
- out3 = out7 ^ in5 ^ in6;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_EB(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out2 = in4 ^ in5;
- tmp0 = in0 ^ in1;
- out4 = in4 ^ in6 ^ in7;
- out5 = in0 ^ in5 ^ in7;
- out6 = tmp0 ^ in6;
- tmp1 = tmp0 ^ in2;
- out0 = tmp1 ^ in3;
- out7 = tmp1 ^ in7;
- out1 = out0 ^ in4;
- out3 = out0 ^ in5 ^ in6;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_EC(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out3 = in0 ^ in5;
- out4 = in2 ^ in3 ^ in7;
- out5 = in0 ^ in3 ^ in4;
- out6 = out3 ^ in1 ^ in4;
- out1 = out4 ^ in4;
- out0 = out4 ^ in1 ^ in6;
- out2 = out0 ^ out5 ^ in5;
- out7 = out2 ^ in4 ^ in7;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_ED(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- tmp0 = in2 ^ in4;
- tmp1 = in3 ^ in5;
- out4 = tmp0 ^ in3 ^ in7;
- out3 = tmp1 ^ in0;
- out1 = out4 ^ in1;
- out5 = out3 ^ in4;
- out7 = out1 ^ out5 ^ in6;
- out2 = tmp0 ^ out7;
- out0 = tmp1 ^ out7;
- out6 = out2 ^ in7;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_EE(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2, tmp3;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out4 = in2;
- tmp0 = in0 ^ in1;
- out5 = in0 ^ in3;
- tmp1 = tmp0 ^ in2;
- out6 = tmp0 ^ in4;
- tmp2 = tmp1 ^ out5;
- out7 = tmp1 ^ in5;
- out1 = tmp2 ^ out6 ^ in7;
- out0 = tmp2 ^ in6;
- tmp3 = out7 ^ in1;
- out3 = tmp3 ^ in7;
- out2 = tmp3 ^ in4 ^ in6;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_EF(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out4 = in2 ^ in4;
- tmp0 = in0 ^ in5;
- tmp1 = in4 ^ in6;
- out5 = tmp0 ^ in3;
- out2 = tmp0 ^ tmp1;
- out6 = tmp1 ^ in0 ^ in1;
- out3 = out5 ^ in2 ^ in7;
- out7 = out3 ^ in1 ^ in3;
- out0 = out4 ^ out6 ^ in3;
- out1 = tmp1 ^ out0 ^ in7;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_F0(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2, tmp3;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- tmp0 = in1 ^ in2;
- tmp1 = in4 ^ in5;
- out2 = tmp0 ^ in6;
- out3 = tmp1 ^ in1;
- tmp2 = tmp1 ^ in7;
- out1 = out2 ^ out3 ^ in3;
- tmp3 = tmp0 ^ tmp2;
- out0 = tmp3 ^ in3;
- out5 = tmp3 ^ in0;
- out4 = out1 ^ out5 ^ in4;
- out7 = out4 ^ in2;
- out6 = tmp2 ^ out7;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_F1(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2, tmp3;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out2 = in1 ^ in6;
- tmp0 = in3 ^ in5;
- out3 = tmp0 ^ in1 ^ in4;
- tmp1 = out3 ^ in2;
- out1 = tmp1 ^ in6;
- tmp2 = tmp1 ^ in0;
- tmp3 = out1 ^ in5;
- out0 = tmp2 ^ in7;
- out6 = tmp2 ^ in4;
- out7 = tmp3 ^ in0;
- out5 = tmp0 ^ out0;
- out4 = tmp3 ^ out5 ^ in1;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_F2(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2, tmp3;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- tmp0 = in4 ^ in5;
- out2 = in2 ^ in6 ^ in7;
- tmp1 = tmp0 ^ in1;
- tmp2 = tmp1 ^ in2;
- out0 = tmp2 ^ in3;
- out3 = tmp2 ^ in7;
- out5 = out3 ^ in0 ^ in4;
- tmp3 = tmp0 ^ out5;
- out7 = tmp3 ^ in3;
- out4 = tmp3 ^ out2;
- out1 = out0 ^ out4 ^ in4;
- out6 = tmp1 ^ out1;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_F3(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out2 = in6 ^ in7;
- tmp0 = in0 ^ in1;
- out4 = tmp0 ^ in6;
- tmp1 = tmp0 ^ in2;
- out5 = tmp1 ^ in7;
- out6 = tmp1 ^ in3;
- out7 = out6 ^ in4;
- out0 = out7 ^ in5;
- out1 = out0 ^ in6;
- out3 = out0 ^ in0 ^ in7;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_F4(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out2 = in0 ^ in1 ^ in2;
- tmp0 = out2 ^ in3;
- out4 = tmp0 ^ in4;
- out5 = out4 ^ in5;
- out6 = out5 ^ in6;
- out7 = out6 ^ in7;
- out0 = out7 ^ in0;
- out1 = out0 ^ in1;
- out3 = tmp0 ^ out7;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_F5(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out2 = in0 ^ in1;
- tmp0 = out2 ^ in2;
- out4 = tmp0 ^ in3;
- out5 = out4 ^ in4;
- out6 = out5 ^ in5;
- out7 = out6 ^ in6;
- out0 = out7 ^ in7;
- out1 = out0 ^ in0;
- out3 = tmp0 ^ out0;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_F6(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- tmp0 = in0 ^ in7;
- out2 = tmp0 ^ in2;
- out4 = out2 ^ in1 ^ in4;
- out7 = out4 ^ in3 ^ in5;
- out5 = out7 ^ in4 ^ in7;
- out0 = tmp0 ^ out7 ^ in6;
- tmp1 = out0 ^ in1;
- out6 = out0 ^ in0 ^ in5;
- out3 = tmp1 ^ in3;
- out1 = tmp0 ^ tmp1;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_F7(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out2 = in0 ^ in7;
- tmp0 = out2 ^ in1;
- out4 = tmp0 ^ in2;
- out5 = out4 ^ in3 ^ in7;
- out6 = out5 ^ in4;
- out7 = out6 ^ in5;
- out0 = out7 ^ in6;
- out1 = out0 ^ in7;
- out3 = tmp0 ^ out1;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_F8(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- tmp0 = in0 ^ in4;
- tmp1 = in3 ^ in5;
- tmp2 = tmp0 ^ in6;
- out4 = tmp0 ^ tmp1;
- out1 = tmp1 ^ in2 ^ in4;
- out3 = tmp2 ^ in1;
- out5 = out3 ^ in5;
- out7 = out1 ^ out5 ^ in7;
- out6 = tmp1 ^ out7;
- out0 = tmp2 ^ out7;
- out2 = out6 ^ in0;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_F9(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2, tmp3, tmp4;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- tmp0 = in3 ^ in5;
- tmp1 = in0 ^ in6;
- out4 = tmp0 ^ in0;
- tmp2 = tmp1 ^ in4;
- tmp3 = tmp1 ^ in2;
- out5 = tmp2 ^ in1;
- out3 = out5 ^ in3;
- tmp4 = tmp3 ^ out3;
- out1 = tmp4 ^ in5;
- out0 = tmp4 ^ in0 ^ in7;
- out6 = tmp0 ^ out0 ^ in4;
- out7 = tmp2 ^ tmp4;
- out2 = tmp3 ^ out6;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_FA(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2, tmp3;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- tmp0 = in0 ^ in1;
- tmp1 = tmp0 ^ in2;
- tmp2 = tmp0 ^ in5;
- tmp3 = tmp1 ^ in7;
- out5 = tmp2 ^ in6;
- out6 = tmp3 ^ in6;
- out7 = tmp3 ^ in3;
- out3 = out6 ^ in4;
- out2 = tmp1 ^ out5;
- out4 = out2 ^ out3 ^ in1;
- out0 = out4 ^ out7 ^ in5;
- out1 = tmp2 ^ out0;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_FB(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out2 = in5 ^ in6;
- tmp0 = in0 ^ in1;
- out4 = in0 ^ in5 ^ in7;
- out5 = tmp0 ^ in6;
- tmp1 = tmp0 ^ in2;
- out6 = tmp1 ^ in7;
- out7 = tmp1 ^ in3;
- out0 = out7 ^ in4;
- out1 = out0 ^ in5;
- out3 = out0 ^ in6 ^ in7;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_FC(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2, tmp3;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- tmp0 = in1 ^ in2;
- tmp1 = in0 ^ in7;
- out2 = tmp0 ^ tmp1 ^ in5;
- out3 = tmp1 ^ in4;
- tmp2 = out2 ^ in6;
- out6 = tmp2 ^ in4;
- out7 = tmp2 ^ in3;
- out4 = out6 ^ in1 ^ in3;
- tmp3 = out4 ^ in0;
- out1 = tmp3 ^ in6;
- out0 = tmp3 ^ in1 ^ in5;
- out5 = tmp0 ^ out4;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_FD(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2, tmp3;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- tmp0 = in0 ^ in5;
- tmp1 = in1 ^ in7;
- out2 = tmp0 ^ tmp1;
- out6 = out2 ^ in2 ^ in4;
- tmp2 = out6 ^ in0;
- out1 = tmp2 ^ in3;
- out0 = tmp0 ^ out1 ^ in6;
- out5 = out0 ^ in2;
- tmp3 = out5 ^ in1;
- out3 = tmp3 ^ in6;
- out7 = tmp2 ^ tmp3;
- out4 = tmp1 ^ out7;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_FE(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2, tmp3, tmp4;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- tmp0 = in0 ^ in2;
- out2 = tmp0 ^ in5;
- out3 = tmp0 ^ in4;
- tmp1 = out3 ^ in6;
- out4 = tmp1 ^ in5;
- tmp2 = tmp1 ^ in1;
- out6 = tmp2 ^ in7;
- tmp3 = tmp2 ^ in0;
- out0 = tmp3 ^ in3;
- tmp4 = out0 ^ out4 ^ in7;
- out5 = tmp4 ^ in6;
- out7 = tmp4 ^ in2;
- out1 = tmp3 ^ out5;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-static void gf8_muladd_FF(uint8_t * out, uint8_t * in, unsigned int width)
-{
- unsigned int i;
- uint64_t * in_ptr = (uint64_t *)in;
- uint64_t * out_ptr = (uint64_t *)out;
-
- for (i = 0; i < width; i++)
- {
- uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
- uint64_t tmp0, tmp1, tmp2, tmp3;
-
- uint64_t in0 = out_ptr[0];
- uint64_t in1 = out_ptr[width];
- uint64_t in2 = out_ptr[width * 2];
- uint64_t in3 = out_ptr[width * 3];
- uint64_t in4 = out_ptr[width * 4];
- uint64_t in5 = out_ptr[width * 5];
- uint64_t in6 = out_ptr[width * 6];
- uint64_t in7 = out_ptr[width * 7];
-
- out2 = in0 ^ in5;
- tmp0 = in4 ^ in7;
- tmp1 = out2 ^ in2;
- out4 = tmp1 ^ in6;
- out7 = tmp1 ^ in1 ^ in3;
- out1 = tmp0 ^ out7;
- tmp2 = out1 ^ in5;
- out6 = tmp2 ^ in3;
- tmp3 = tmp2 ^ in7;
- out0 = tmp3 ^ in6;
- out3 = tmp3 ^ in1;
- out5 = tmp0 ^ out0 ^ in2;
-
- out_ptr[0] = out0 ^ in_ptr[0];
- out_ptr[width] = out1 ^ in_ptr[width];
- out_ptr[width * 2] = out2 ^ in_ptr[width * 2];
- out_ptr[width * 3] = out3 ^ in_ptr[width * 3];
- out_ptr[width * 4] = out4 ^ in_ptr[width * 4];
- out_ptr[width * 5] = out5 ^ in_ptr[width * 5];
- out_ptr[width * 6] = out6 ^ in_ptr[width * 6];
- out_ptr[width * 7] = out7 ^ in_ptr[width * 7];
-
- in_ptr++;
- out_ptr++;
- }
-}
-
-void (* ec_gf_muladd[])(uint8_t * out, uint8_t * in, unsigned int width) =
-{
- gf8_muladd_00, gf8_muladd_01, gf8_muladd_02, gf8_muladd_03,
- gf8_muladd_04, gf8_muladd_05, gf8_muladd_06, gf8_muladd_07,
- gf8_muladd_08, gf8_muladd_09, gf8_muladd_0A, gf8_muladd_0B,
- gf8_muladd_0C, gf8_muladd_0D, gf8_muladd_0E, gf8_muladd_0F,
- gf8_muladd_10, gf8_muladd_11, gf8_muladd_12, gf8_muladd_13,
- gf8_muladd_14, gf8_muladd_15, gf8_muladd_16, gf8_muladd_17,
- gf8_muladd_18, gf8_muladd_19, gf8_muladd_1A, gf8_muladd_1B,
- gf8_muladd_1C, gf8_muladd_1D, gf8_muladd_1E, gf8_muladd_1F,
- gf8_muladd_20, gf8_muladd_21, gf8_muladd_22, gf8_muladd_23,
- gf8_muladd_24, gf8_muladd_25, gf8_muladd_26, gf8_muladd_27,
- gf8_muladd_28, gf8_muladd_29, gf8_muladd_2A, gf8_muladd_2B,
- gf8_muladd_2C, gf8_muladd_2D, gf8_muladd_2E, gf8_muladd_2F,
- gf8_muladd_30, gf8_muladd_31, gf8_muladd_32, gf8_muladd_33,
- gf8_muladd_34, gf8_muladd_35, gf8_muladd_36, gf8_muladd_37,
- gf8_muladd_38, gf8_muladd_39, gf8_muladd_3A, gf8_muladd_3B,
- gf8_muladd_3C, gf8_muladd_3D, gf8_muladd_3E, gf8_muladd_3F,
- gf8_muladd_40, gf8_muladd_41, gf8_muladd_42, gf8_muladd_43,
- gf8_muladd_44, gf8_muladd_45, gf8_muladd_46, gf8_muladd_47,
- gf8_muladd_48, gf8_muladd_49, gf8_muladd_4A, gf8_muladd_4B,
- gf8_muladd_4C, gf8_muladd_4D, gf8_muladd_4E, gf8_muladd_4F,
- gf8_muladd_50, gf8_muladd_51, gf8_muladd_52, gf8_muladd_53,
- gf8_muladd_54, gf8_muladd_55, gf8_muladd_56, gf8_muladd_57,
- gf8_muladd_58, gf8_muladd_59, gf8_muladd_5A, gf8_muladd_5B,
- gf8_muladd_5C, gf8_muladd_5D, gf8_muladd_5E, gf8_muladd_5F,
- gf8_muladd_60, gf8_muladd_61, gf8_muladd_62, gf8_muladd_63,
- gf8_muladd_64, gf8_muladd_65, gf8_muladd_66, gf8_muladd_67,
- gf8_muladd_68, gf8_muladd_69, gf8_muladd_6A, gf8_muladd_6B,
- gf8_muladd_6C, gf8_muladd_6D, gf8_muladd_6E, gf8_muladd_6F,
- gf8_muladd_70, gf8_muladd_71, gf8_muladd_72, gf8_muladd_73,
- gf8_muladd_74, gf8_muladd_75, gf8_muladd_76, gf8_muladd_77,
- gf8_muladd_78, gf8_muladd_79, gf8_muladd_7A, gf8_muladd_7B,
- gf8_muladd_7C, gf8_muladd_7D, gf8_muladd_7E, gf8_muladd_7F,
- gf8_muladd_80, gf8_muladd_81, gf8_muladd_82, gf8_muladd_83,
- gf8_muladd_84, gf8_muladd_85, gf8_muladd_86, gf8_muladd_87,
- gf8_muladd_88, gf8_muladd_89, gf8_muladd_8A, gf8_muladd_8B,
- gf8_muladd_8C, gf8_muladd_8D, gf8_muladd_8E, gf8_muladd_8F,
- gf8_muladd_90, gf8_muladd_91, gf8_muladd_92, gf8_muladd_93,
- gf8_muladd_94, gf8_muladd_95, gf8_muladd_96, gf8_muladd_97,
- gf8_muladd_98, gf8_muladd_99, gf8_muladd_9A, gf8_muladd_9B,
- gf8_muladd_9C, gf8_muladd_9D, gf8_muladd_9E, gf8_muladd_9F,
- gf8_muladd_A0, gf8_muladd_A1, gf8_muladd_A2, gf8_muladd_A3,
- gf8_muladd_A4, gf8_muladd_A5, gf8_muladd_A6, gf8_muladd_A7,
- gf8_muladd_A8, gf8_muladd_A9, gf8_muladd_AA, gf8_muladd_AB,
- gf8_muladd_AC, gf8_muladd_AD, gf8_muladd_AE, gf8_muladd_AF,
- gf8_muladd_B0, gf8_muladd_B1, gf8_muladd_B2, gf8_muladd_B3,
- gf8_muladd_B4, gf8_muladd_B5, gf8_muladd_B6, gf8_muladd_B7,
- gf8_muladd_B8, gf8_muladd_B9, gf8_muladd_BA, gf8_muladd_BB,
- gf8_muladd_BC, gf8_muladd_BD, gf8_muladd_BE, gf8_muladd_BF,
- gf8_muladd_C0, gf8_muladd_C1, gf8_muladd_C2, gf8_muladd_C3,
- gf8_muladd_C4, gf8_muladd_C5, gf8_muladd_C6, gf8_muladd_C7,
- gf8_muladd_C8, gf8_muladd_C9, gf8_muladd_CA, gf8_muladd_CB,
- gf8_muladd_CC, gf8_muladd_CD, gf8_muladd_CE, gf8_muladd_CF,
- gf8_muladd_D0, gf8_muladd_D1, gf8_muladd_D2, gf8_muladd_D3,
- gf8_muladd_D4, gf8_muladd_D5, gf8_muladd_D6, gf8_muladd_D7,
- gf8_muladd_D8, gf8_muladd_D9, gf8_muladd_DA, gf8_muladd_DB,
- gf8_muladd_DC, gf8_muladd_DD, gf8_muladd_DE, gf8_muladd_DF,
- gf8_muladd_E0, gf8_muladd_E1, gf8_muladd_E2, gf8_muladd_E3,
- gf8_muladd_E4, gf8_muladd_E5, gf8_muladd_E6, gf8_muladd_E7,
- gf8_muladd_E8, gf8_muladd_E9, gf8_muladd_EA, gf8_muladd_EB,
- gf8_muladd_EC, gf8_muladd_ED, gf8_muladd_EE, gf8_muladd_EF,
- gf8_muladd_F0, gf8_muladd_F1, gf8_muladd_F2, gf8_muladd_F3,
- gf8_muladd_F4, gf8_muladd_F5, gf8_muladd_F6, gf8_muladd_F7,
- gf8_muladd_F8, gf8_muladd_F9, gf8_muladd_FA, gf8_muladd_FB,
- gf8_muladd_FC, gf8_muladd_FD, gf8_muladd_FE, gf8_muladd_FF
-};
diff --git a/xlators/cluster/ec/src/ec-gf.h b/xlators/cluster/ec/src/ec-gf.h
deleted file mode 100644
index 23bca91e3b5..00000000000
--- a/xlators/cluster/ec/src/ec-gf.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- Copyright (c) 2012-2014 DataLab, s.l. <http://www.datalab.es>
- 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 __EC_GF8_H__
-#define __EC_GF8_H__
-
-#define EC_GF_BITS 8
-#define EC_GF_MOD 0x11D
-
-#define EC_GF_SIZE (1 << EC_GF_BITS)
-#define EC_GF_WORD_SIZE sizeof(uint64_t)
-
-extern void (* ec_gf_muladd[])(uint8_t * out, uint8_t * in,
- unsigned int width);
-
-#endif /* __EC_GF8_H__ */
diff --git a/xlators/cluster/ec/src/ec-heal.c b/xlators/cluster/ec/src/ec-heal.c
deleted file mode 100644
index 862d45d0cf3..00000000000
--- a/xlators/cluster/ec/src/ec-heal.c
+++ /dev/null
@@ -1,1597 +0,0 @@
-/*
- Copyright (c) 2012-2014 DataLab, s.l. <http://www.datalab.es>
- 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 "xlator.h"
-#include "defaults.h"
-#include "compat-errno.h"
-
-#include "ec-helpers.h"
-#include "ec-common.h"
-#include "ec-combine.h"
-#include "ec-method.h"
-#include "ec-fops.h"
-
-#include "ec-mem-types.h"
-#include "ec-data.h"
-
-static char *ec_ignore_xattrs[] = {
- GF_SELINUX_XATTR_KEY,
- QUOTA_SIZE_KEY,
- NULL
-};
-
-static gf_boolean_t
-ec_ignorable_key_match (dict_t *dict, char *key, data_t *val, void *mdata)
-{
- int i = 0;
-
- if (!key)
- goto out;
-
- for (i = 0; ec_ignore_xattrs[i]; i++) {
- if (!strcmp (key, ec_ignore_xattrs[i]))
- return _gf_true;
- }
-
-out:
- return _gf_false;
-}
-
-/* FOP: heal */
-
-void ec_heal_exclude(ec_heal_t * heal, uintptr_t mask)
-{
- LOCK(&heal->lock);
-
- heal->bad &= ~mask;
-
- UNLOCK(&heal->lock);
-}
-
-void ec_heal_lookup_resume(ec_fop_data_t * fop)
-{
- ec_heal_t * heal = fop->data;
- ec_cbk_data_t * cbk;
- uintptr_t good = 0, bad = 0;
-
- if (heal->lookup != NULL)
- {
- ec_fop_data_release(heal->lookup);
- }
- ec_fop_data_acquire(fop);
-
- list_for_each_entry(cbk, &fop->cbk_list, list)
- {
- if ((cbk->op_ret < 0) && (cbk->op_errno == ENOTCONN))
- {
- continue;
- }
-
- if (cbk == fop->answer)
- {
- if (cbk->op_ret >= 0)
- {
- heal->iatt = cbk->iatt[0];
- heal->version = cbk->version;
- heal->raw_size = cbk->size;
- heal->fop->pre_size = cbk->iatt[0].ia_size;
- heal->fop->post_size = cbk->iatt[0].ia_size;
- heal->fop->have_size = 1;
-
- if (ec_loc_update(heal->xl, &heal->loc, cbk->inode,
- &cbk->iatt[0]) != 0)
- {
- fop->answer = NULL;
- fop->error = EIO;
-
- bad |= cbk->mask;
-
- continue;
- }
- }
-
- good |= cbk->mask;
- }
- else
- {
- bad |= cbk->mask;
- }
- }
-
- /* Heal lookups are not executed concurrently with anything else. So, when
- * a lookup finishes, it's safe to access heal->good and heal->bad without
- * acquiring any lock.
- */
- heal->good = good;
- heal->bad = bad;
-
- heal->lookup = fop;
-
- ec_resume_parent(fop, fop->answer != NULL ? 0 : fop->error);
-}
-
-int32_t ec_heal_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 * xdata,
- struct iatt * postparent)
-{
- ec_heal_lookup_resume(cookie);
-
- return 0;
-}
-
-int32_t ec_heal_inode_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)
-{
- ec_heal_lookup_resume(cookie);
-
- return 0;
-}
-
-uintptr_t ec_heal_check(ec_fop_data_t * fop, uintptr_t * pgood)
-{
- ec_cbk_data_t * cbk;
- uintptr_t mask[2] = { 0, 0 };
-
- list_for_each_entry(cbk, &fop->cbk_list, list)
- {
- mask[cbk->op_ret >= 0] |= cbk->mask;
- }
-
- if (pgood != NULL)
- {
- *pgood = mask[1];
- }
-
- return mask[0];
-}
-
-void ec_heal_update(ec_fop_data_t * fop, int32_t is_open)
-{
- ec_heal_t * heal = fop->data;
- uintptr_t good, bad;
-
- bad = ec_heal_check(fop, &good);
-
- LOCK(&heal->lock);
-
- heal->bad &= ~bad;
- if (is_open)
- {
- heal->open |= good;
- }
-
- UNLOCK(&heal->lock);
-
- fop->error = 0;
-}
-
-void ec_heal_avoid(ec_fop_data_t * fop)
-{
- ec_heal_t * heal = fop->data;
- uintptr_t bad;
-
- bad = ec_heal_check(fop, NULL);
-
- LOCK(&heal->lock);
-
- heal->good &= ~bad;
-
- UNLOCK(&heal->lock);
-}
-
-int32_t ec_heal_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)
-{
- ec_heal_update(cookie, 0);
-
- return 0;
-}
-
-int32_t ec_heal_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)
-{
- ec_heal_update(cookie, 0);
-
- return 0;
-}
-
-int32_t ec_heal_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)
-{
- ec_heal_update(cookie, 0);
-
- return 0;
-}
-
-int32_t ec_heal_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)
-{
- ec_heal_update(cookie, 1);
-
- return 0;
-}
-
-int32_t ec_heal_setattr_cbk(call_frame_t * frame, void * cookie,
- xlator_t * this, int32_t op_ret, int32_t op_errno,
- struct iatt * preop_stbuf,
- struct iatt * postop_stbuf,
- dict_t * xdata)
-{
- ec_heal_update(cookie, 0);
-
- return 0;
-}
-
-int32_t ec_heal_setxattr_cbk(call_frame_t * frame, void * cookie,
- xlator_t * this, int32_t op_ret, int32_t op_errno,
- dict_t * xdata)
-{
- ec_heal_update(cookie, 0);
-
- return 0;
-}
-
-int32_t ec_heal_removexattr_cbk(call_frame_t * frame, void * cookie,
- xlator_t * this, int32_t op_ret,
- int32_t op_errno, dict_t * xdata)
-{
- ec_heal_update(cookie, 0);
-
- return 0;
-}
-
-int32_t ec_heal_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)
-{
- ec_fop_data_t * fop = cookie;
- ec_heal_t * heal = fop->data;
- uintptr_t good, bad;
-
- bad = ec_heal_check(fop, &good);
- ec_heal_exclude(heal, good);
-
- if (bad != 0)
- {
- fop->error = 0;
-
- xdata = fop->xdata;
- fop = fop->parent;
-
- ec_create(fop->frame, fop->xl, bad, EC_MINIMUM_ONE,
- ec_heal_create_cbk, heal, &heal->loc, 0,
- st_mode_from_ia(heal->iatt.ia_prot, IA_INVAL),
- 0, heal->fd, xdata);
- }
-
- return 0;
-}
-
-int32_t ec_heal_target_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)
-{
- ec_heal_update(cookie, 1);
-
- return 0;
-}
-
-int32_t ec_heal_source_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)
-{
- ec_heal_avoid(cookie);
-
- return 0;
-}
-
-int32_t ec_heal_reopen_cbk(call_frame_t * frame, void * cookie,
- xlator_t * this, int32_t op_ret, int32_t op_errno,
- fd_t * fd, dict_t * xdata)
-{
- ec_fop_data_t * fop = cookie;
- ec_fd_t * ctx;
- uintptr_t good;
-
- ec_heal_check(fop, &good);
-
- if (good != 0)
- {
- LOCK(&fd->lock);
-
- ctx = __ec_fd_get(fd, fop->xl);
- if (ctx != NULL) {
- ctx->bad &= ~good;
- ctx->open |= good;
- }
-
- UNLOCK(&fd->lock);
- }
-
- return 0;
-}
-
-int32_t ec_heal_create(ec_heal_t * heal, uintptr_t mask, int32_t try_link)
-{
- loc_t loc;
- dict_t * xdata;
-
- xdata = dict_new();
- if (xdata == NULL)
- {
- return ENOMEM;
- }
-
- if (dict_set_static_bin(xdata, "gfid-req", heal->iatt.ia_gfid,
- sizeof(uuid_t)) != 0)
- {
- dict_unref(xdata);
-
- return ENOMEM;
- }
-
- if ((heal->iatt.ia_type == IA_IFREG) && try_link)
- {
- memset(&loc, 0, sizeof(loc));
- loc.inode = heal->loc.inode;
- uuid_copy(loc.gfid, heal->iatt.ia_gfid);
-
- ec_link(heal->fop->frame, heal->xl, mask, EC_MINIMUM_ONE,
- ec_heal_link_cbk, heal, &loc, &heal->loc, xdata);
-
- dict_unref(xdata);
-
- return 0;
- }
-
- switch (heal->iatt.ia_type)
- {
- case IA_IFDIR:
- ec_mkdir(heal->fop->frame, heal->xl, mask, EC_MINIMUM_ONE,
- ec_heal_mkdir_cbk, heal, &heal->loc,
- st_mode_from_ia(heal->iatt.ia_prot, IA_INVAL),
- 0, xdata);
-
- break;
-
- case IA_IFLNK:
- ec_symlink(heal->fop->frame, heal->xl, mask, EC_MINIMUM_ONE,
- ec_heal_symlink_cbk, heal, heal->symlink, &heal->loc,
- 0, xdata);
-
- break;
-
- case IA_IFREG:
- ec_create(heal->fop->frame, heal->xl, mask, EC_MINIMUM_ONE,
- ec_heal_create_cbk, heal, &heal->loc, 0,
- st_mode_from_ia(heal->iatt.ia_prot, IA_INVAL),
- 0, heal->fd, xdata);
-
- break;
-
- default:
- ec_mknod(heal->fop->frame, heal->xl, mask, EC_MINIMUM_ONE,
- ec_heal_mknod_cbk, heal, &heal->loc,
- st_mode_from_ia(heal->iatt.ia_prot, IA_INVAL),
- heal->iatt.ia_rdev, 0, xdata);
-
- break;
- }
-
- dict_unref(xdata);
-
- return 0;
-}
-
-int32_t ec_heal_parent_cbk(call_frame_t *frame, void *cookie, xlator_t *xl,
- int32_t op_ret, int32_t op_errno, uintptr_t mask,
- uintptr_t good, uintptr_t bad, dict_t *xdata)
-{
- ec_fop_data_t *fop = cookie;
- ec_heal_t *heal = fop->data;
-
- /* Even if parent self-heal has failed, we try to heal the current entry */
- ec_heal_create(heal, fop->mask, 0);
-
- return 0;
-}
-
-void ec_heal_parent(ec_heal_t *heal, uintptr_t mask)
-{
- loc_t parent;
- int32_t healing = 0;
-
- /* First we try to do a partial heal of the parent directory to avoid
- * ENOENT/ENOTDIR errors caused by missing parents */
- if (ec_loc_parent(heal->xl, &heal->loc, &parent) == 0) {
- if (!__is_root_gfid(parent.gfid)) {
- ec_heal(heal->fop->frame, heal->xl, mask, EC_MINIMUM_ONE,
- ec_heal_parent_cbk, heal, &parent, 1, NULL);
-
- healing = 1;
- }
- loc_wipe(&parent);
- }
-
- if (!healing) {
- ec_heal_create(heal, mask, 0);
- }
-}
-
-void ec_heal_recreate(ec_fop_data_t * fop)
-{
- ec_cbk_data_t * cbk;
- ec_heal_t * heal = fop->data;
- uintptr_t mask = 0;
-
- if (heal->iatt.ia_type == IA_INVAL)
- {
- return;
- }
-
- list_for_each_entry(cbk, &fop->cbk_list, list)
- {
- if ((cbk->op_ret >= 0) || (cbk->op_errno == ENOENT) ||
- (cbk->op_errno == ENOTDIR))
- {
- mask |= cbk->mask;
- }
- }
-
- if (mask != 0)
- {
- ec_heal_parent(heal, mask);
- }
-}
-
-int32_t ec_heal_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)
-{
- ec_heal_update(cookie, 0);
- ec_heal_recreate(cookie);
-
- return 0;
-}
-
-int32_t ec_heal_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)
-{
- ec_heal_update(cookie, 0);
- ec_heal_recreate(cookie);
-
- return 0;
-}
-
-int32_t ec_heal_init(ec_fop_data_t * fop)
-{
- ec_t * ec = fop->xl->private;
- struct iobuf_pool * pool;
- inode_t * inode;
- ec_inode_t * ctx;
- ec_heal_t * heal = NULL;
- int32_t error = 0;
-
- inode = fop->loc[0].inode;
- if (inode == NULL)
- {
- gf_log(fop->xl->name, GF_LOG_WARNING, "Unable to start inode healing "
- "because there is not enough "
- "information");
-
- return ENODATA;
- }
-
- heal = GF_MALLOC(sizeof(ec_heal_t), ec_mt_ec_heal_t);
- if (heal == NULL)
- {
- return ENOMEM;
- }
-
- memset(heal, 0, sizeof(ec_heal_t));
-
- if (ec_loc_from_loc(fop->xl, &heal->loc, &fop->loc[0]) != 0) {
- error = ENOMEM;
-
- goto out;
- }
-
- LOCK_INIT(&heal->lock);
-
- heal->xl = fop->xl;
- heal->fop = fop;
- pool = fop->xl->ctx->iobuf_pool;
- heal->size = iobpool_default_pagesize(pool) * ec->fragments;
- heal->partial = fop->int32;
- fop->heal = heal;
-
- LOCK(&inode->lock);
-
- ctx = __ec_inode_get(inode, fop->xl);
- if (ctx == NULL)
- {
- error = EIO;
-
- goto unlock;
- }
-
- if (list_empty(&ctx->heal)) {
- gf_log("ec", GF_LOG_INFO, "Healing '%s', gfid %s", heal->loc.path,
- uuid_utoa(heal->loc.gfid));
- } else {
- error = EEXIST;
- }
-
- list_add_tail(&heal->list, &ctx->heal);
- heal = NULL;
-
-unlock:
- UNLOCK(&inode->lock);
-
- if (error == EEXIST) {
- LOCK(&fop->lock);
-
- fop->jobs++;
- fop->refs++;
-
- UNLOCK(&fop->lock);
-
- error = 0;
- }
-
-out:
- GF_FREE(heal);
-
- return error;
-}
-
-void ec_heal_entrylk(ec_heal_t * heal, entrylk_cmd cmd)
-{
- loc_t loc;
-
- if (ec_loc_parent(heal->xl, &heal->loc, &loc) != 0) {
- ec_fop_set_error(heal->fop, EIO);
-
- return;
- }
-
- ec_entrylk(heal->fop->frame, heal->xl, -1, EC_MINIMUM_ALL, NULL, NULL,
- heal->xl->name, &loc, NULL, cmd, ENTRYLK_WRLCK, NULL);
-
- loc_wipe(&loc);
-}
-
-void ec_heal_inodelk(ec_heal_t * heal, int32_t type, int32_t use_fd,
- off_t offset, size_t size)
-{
- struct gf_flock flock;
-
- flock.l_type = type;
- flock.l_whence = SEEK_SET;
- flock.l_start = offset;
- flock.l_len = size;
- flock.l_pid = 0;
- flock.l_owner.len = 0;
-
- if (use_fd)
- {
- ec_finodelk(heal->fop->frame, heal->xl, heal->fop->mask,
- EC_MINIMUM_ALL, NULL, NULL, heal->xl->name, heal->fd,
- F_SETLKW, &flock, NULL);
- }
- else
- {
- ec_inodelk(heal->fop->frame, heal->xl, heal->fop->mask, EC_MINIMUM_ALL,
- NULL, NULL, heal->xl->name, &heal->loc, F_SETLKW, &flock,
- NULL);
- }
-}
-
-void ec_heal_lookup(ec_heal_t *heal, uintptr_t mask)
-{
- dict_t * xdata;
- int32_t error = ENOMEM;
-
- xdata = dict_new();
- if (xdata == NULL)
- {
- goto out;
- }
- if (dict_set_uint64(xdata, "list-xattr", 0) != 0)
- {
- goto out;
- }
-
- ec_lookup(heal->fop->frame, heal->xl, mask, EC_MINIMUM_MIN,
- ec_heal_inode_lookup_cbk, heal, &heal->loc, xdata);
-
- error = 0;
-
-out:
- if (xdata != NULL)
- {
- dict_unref(xdata);
- }
-
- ec_fop_set_error(heal->fop, error);
-}
-
-void ec_heal_remove(ec_heal_t * heal, ec_cbk_data_t * cbk)
-{
- if (cbk->iatt[0].ia_type == IA_IFDIR)
- {
- // TODO: Remove directory recursively ?
- ec_rmdir(heal->fop->frame, heal->xl, cbk->mask, EC_MINIMUM_ONE,
- ec_heal_rmdir_cbk, heal, &heal->loc, 0, NULL);
- }
- else
- {
- ec_unlink(heal->fop->frame, heal->xl, cbk->mask, EC_MINIMUM_ONE,
- ec_heal_unlink_cbk, heal, &heal->loc, 0, NULL);
- }
-}
-
-void ec_heal_remove_others(ec_heal_t * heal)
-{
- struct list_head * item;
- ec_cbk_data_t * cbk;
-
- item = heal->lookup->cbk_list.next;
- do
- {
- item = item->next;
- cbk = list_entry(item, ec_cbk_data_t, list);
-
- if (cbk->op_ret < 0)
- {
- if ((cbk->op_errno != ENOENT) && (cbk->op_errno != ENOTDIR) &&
- (cbk->op_errno != ESTALE))
- {
- gf_log(heal->xl->name, GF_LOG_WARNING, "Don't know how to "
- "remove inode with "
- "error %d",
- cbk->op_errno);
- }
-
- ec_heal_exclude(heal, cbk->mask);
-
- continue;
- }
-
- ec_heal_remove(heal, cbk);
- } while (item->next != &heal->lookup->cbk_list);
-}
-
-void ec_heal_prepare_others(ec_heal_t * heal)
-{
- struct list_head * item;
- ec_cbk_data_t * cbk;
-
- item = heal->lookup->cbk_list.next;
- while (item->next != &heal->lookup->cbk_list)
- {
- item = item->next;
- cbk = list_entry(item, ec_cbk_data_t, list);
-
- if (cbk->op_ret < 0)
- {
- if ((cbk->op_errno == ENOENT) || (cbk->op_errno == ESTALE))
- {
- ec_heal_create(heal, cbk->mask, 1);
- }
- else
- {
- gf_log(heal->xl->name, GF_LOG_ERROR, "Don't know how to "
- "heal error %d",
- cbk->op_errno);
-
- ec_heal_exclude(heal, cbk->mask);
- }
- }
- else
- {
- if ((heal->iatt.ia_type != cbk->iatt[0].ia_type) ||
- (uuid_compare(heal->iatt.ia_gfid, cbk->iatt[0].ia_gfid) != 0))
- {
- ec_heal_remove(heal, cbk);
- }
- }
- }
-}
-
-int32_t ec_heal_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)
-{
- ec_fop_data_t * fop = cookie;
- ec_heal_t * heal = fop->data;
-
- if (op_ret >= 0)
- {
- heal->symlink = gf_strdup(path);
- if (heal->symlink != NULL)
- {
- ec_heal_prepare_others(heal);
- }
- else
- {
- ec_fop_set_error(fop, EIO);
- }
- }
-
- return 0;
-}
-
-ec_cbk_data_t * ec_heal_lookup_check(ec_heal_t * heal, uintptr_t * pgood,
- uintptr_t * pbad)
-{
- ec_fop_data_t * fop = heal->lookup;
- ec_cbk_data_t * cbk = NULL, * ans = NULL;
- uintptr_t good = 0, bad = 0;
-
- list_for_each_entry(ans, &fop->cbk_list, list)
- {
- if ((ans->op_ret < 0) && (ans->op_errno == ENOTCONN))
- {
- continue;
- }
-
- if (ans == fop->answer)
- {
- good |= ans->mask;
- cbk = ans;
- }
- else
- {
- bad |= ans->mask;
- }
- }
-
- *pgood = good;
- *pbad = bad;
-
- return cbk;
-}
-
-void ec_heal_prepare(ec_heal_t * heal)
-{
- ec_cbk_data_t * cbk;
- int32_t error = ENOMEM;
-
- heal->available = heal->good;
-
- cbk = heal->lookup->answer;
- if (cbk->op_ret < 0)
- {
- if ((cbk->op_errno == ENOENT) || (cbk->op_errno == ENOTDIR))
- {
- ec_heal_remove_others(heal);
- }
- else
- {
- gf_log(heal->xl->name, GF_LOG_ERROR, "Don't know how to heal "
- "error %d",
- cbk->op_errno);
- }
- }
- else
- {
- if (heal->iatt.ia_type == IA_IFREG)
- {
- heal->fd = fd_create(heal->loc.inode, heal->fop->frame->root->pid);
- if (heal->fd == NULL)
- {
- gf_log(heal->xl->name, GF_LOG_ERROR, "Unable to create a new "
- "file descriptor");
-
- goto out;
- }
- }
-
- if (heal->iatt.ia_type == IA_IFLNK)
- {
- ec_readlink(heal->fop->frame, heal->xl, cbk->mask, EC_MINIMUM_ONE,
- ec_heal_readlink_cbk, heal, &heal->loc,
- heal->iatt.ia_size, NULL);
- }
- else
- {
- ec_heal_prepare_others(heal);
- }
- }
-
- error = 0;
-
-out:
- ec_fop_set_error(heal->fop, error);
-}
-
-int32_t ec_heal_open_others(ec_heal_t * heal)
-{
- struct list_head * item;
- ec_cbk_data_t * cbk;
- uintptr_t mask = 0, open = heal->open;
-
- item = heal->lookup->cbk_list.next;
- while (item->next != &heal->lookup->cbk_list)
- {
- item = item->next;
- cbk = list_entry(item, ec_cbk_data_t, list);
-
- if ((cbk->op_ret < 0) || (cbk->iatt[0].ia_type != IA_IFREG) ||
- (uuid_compare(heal->iatt.ia_gfid, cbk->iatt[0].ia_gfid) != 0))
- {
- ec_heal_exclude(heal, cbk->mask);
- }
- else
- {
- mask |= cbk->mask & ~heal->open;
- }
- }
-
- if (mask != 0)
- {
- ec_open(heal->fop->frame, heal->xl, mask, EC_MINIMUM_ONE,
- ec_heal_target_open_cbk, heal, &heal->loc, O_RDWR | O_TRUNC,
- heal->fd, NULL);
-
- open |= mask;
- }
-
- return (open != 0);
-}
-
-void ec_heal_setxattr_others(ec_heal_t * heal)
-{
- ec_cbk_data_t * cbk;
- dict_t * xdata;
- int32_t error = ENOMEM;
-
- if ((heal->good != 0) && (heal->bad != 0))
- {
- cbk = heal->lookup->answer;
- xdata = cbk->xdata;
-
- if (dict_foreach_match (xdata, ec_ignorable_key_match, NULL,
- dict_remove_foreach_fn, NULL) == -1)
- goto out;
-
- if ((cbk->iatt[0].ia_type == IA_IFREG) ||
- (cbk->iatt[0].ia_type == IA_IFDIR))
- {
- if (ec_dict_set_number(xdata, EC_XATTR_VERSION, cbk->version) != 0)
- {
- goto out;
- }
- if (cbk->iatt[0].ia_type == IA_IFREG)
- {
- if (ec_dict_set_number(xdata, EC_XATTR_SIZE,
- cbk->iatt[0].ia_size) != 0)
- {
- goto out;
- }
- }
- }
-
- ec_setxattr(heal->fop->frame, heal->xl, heal->bad, EC_MINIMUM_ONE,
- ec_heal_setxattr_cbk, heal, &heal->loc, xdata, 0, NULL);
- }
-
- error = 0;
-
-out:
- ec_fop_set_error(heal->fop, error);
-}
-
-int32_t
-ec_heal_xattr_clean (dict_t *dict, char *key, data_t *data,
- void *arg)
-{
- dict_t *base = arg;
-
- if (ec_ignorable_key_match (NULL, key, NULL, NULL)) {
- dict_del (dict, key);
- return 0;
- }
-
- if (dict_get (base, key) != NULL)
- dict_del (dict, key);
-
- return 0;
-}
-
-void ec_heal_removexattr_others(ec_heal_t * heal)
-{
- struct list_head * item;
- ec_cbk_data_t * cbk;
- dict_t * xdata;
-
- if ((heal->good == 0) || (heal->bad == 0))
- {
- return;
- }
-
- xdata = heal->lookup->answer->xdata;
- item = heal->lookup->cbk_list.next;
- while (item->next != &heal->lookup->cbk_list)
- {
- item = item->next;
- cbk = list_entry(item, ec_cbk_data_t, list);
-
- if (cbk->op_ret >= 0)
- {
- if (dict_foreach(cbk->xdata, ec_heal_xattr_clean, xdata) == 0)
- {
- ec_removexattr(heal->fop->frame, heal->xl, cbk->mask,
- EC_MINIMUM_ONE, ec_heal_removexattr_cbk, heal,
- &heal->loc, "", cbk->xdata);
- }
- }
- }
-}
-
-void ec_heal_attr(ec_heal_t * heal)
-{
- if ((heal->good != 0) && (heal->bad != 0))
- {
- ec_setattr(heal->fop->frame, heal->xl, heal->bad, EC_MINIMUM_ONE,
- ec_heal_setattr_cbk, heal, &heal->loc, &heal->iatt,
- GF_SET_ATTR_MODE | GF_SET_ATTR_UID | GF_SET_ATTR_GID |
- GF_SET_ATTR_ATIME | GF_SET_ATTR_MTIME, NULL);
- }
-}
-
-int32_t ec_heal_needs_data_rebuild(ec_heal_t * heal)
-{
- ec_fop_data_t * fop = heal->lookup;
- ec_cbk_data_t * cbk = NULL;
- uintptr_t bad = 0;
-
- if ((heal->fop->error != 0) || (heal->good == 0) ||
- (heal->iatt.ia_type != IA_IFREG))
- {
- return 0;
- }
-
- list_for_each_entry(cbk, &fop->cbk_list, list)
- {
- if ((cbk->op_ret >= 0) &&
- ((cbk->size != heal->raw_size) || (cbk->version != heal->version)))
- {
- bad |= cbk->mask;
- }
- }
-
- /* This function can only be called concurrently with entrylk, which do
- * not modify heal structure, so it's safe to access heal->bad without
- * acquiring any lock.
- */
- heal->bad = bad;
-
- return (bad != 0);
-}
-
-void ec_heal_open(ec_heal_t * heal)
-{
- if (!ec_heal_needs_data_rebuild(heal))
- {
- return;
- }
-
- if (ec_heal_open_others(heal))
- {
- ec_open(heal->fop->frame, heal->xl, heal->good, EC_MINIMUM_MIN,
- ec_heal_source_open_cbk, heal, &heal->loc, O_RDONLY, heal->fd,
- NULL);
- }
-}
-
-void ec_heal_reopen_fd(ec_heal_t * heal)
-{
- inode_t * inode;
- fd_t * fd;
- ec_fd_t *ctx_fd;
- ec_inode_t *ctx_inode;
- uintptr_t mask;
- int32_t flags;
-
- inode = heal->loc.inode;
-
- LOCK(&inode->lock);
-
- ctx_inode = __ec_inode_get(inode, heal->xl);
- if (ctx_inode != NULL) {
- ctx_inode->bad &= ~(heal->good | heal->bad);
- }
-
- list_for_each_entry(fd, &inode->fd_list, inode_list)
- {
- ctx_fd = ec_fd_get(fd, heal->xl);
- if (ctx_fd != NULL) {
- mask = heal->bad & ~ctx_fd->open;
- if (mask != 0)
- {
- UNLOCK(&inode->lock);
-
- if (heal->iatt.ia_type == IA_IFDIR)
- {
- ec_opendir(heal->fop->frame, heal->xl, mask,
- EC_MINIMUM_ONE, ec_heal_reopen_cbk, NULL,
- &heal->loc, fd, NULL);
- }
- else
- {
- flags = ctx_fd->flags & ~(O_TRUNC | O_APPEND);
-
- ec_open(heal->fop->frame, heal->xl, mask, EC_MINIMUM_ONE,
- ec_heal_reopen_cbk, NULL, &heal->loc, flags, fd,
- NULL);
- }
-
- LOCK(&inode->lock);
- }
- }
- }
-
- UNLOCK(&inode->lock);
-}
-
-int32_t ec_heal_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)
-{
- ec_trace("WRITE_CBK", cookie, "ret=%d, errno=%d", op_ret, op_errno);
-
- ec_heal_update(cookie, 0);
-
- return 0;
-}
-
-int32_t ec_heal_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)
-{
- ec_fop_data_t * fop = cookie;
- ec_heal_t * heal = fop->data;
-
- ec_trace("READ_CBK", fop, "ret=%d, errno=%d", op_ret, op_errno);
-
- ec_heal_avoid(fop);
-
- if (op_ret > 0)
- {
- ec_writev(heal->fop->frame, heal->xl, heal->bad, EC_MINIMUM_ONE,
- ec_heal_writev_cbk, heal, heal->fd, vector, count,
- heal->offset, 0, iobref, NULL);
- }
- else
- {
- heal->done = 1;
- }
-
- return 0;
-}
-
-void ec_heal_data(ec_heal_t * heal)
-{
- ec_trace("DATA", heal->fop, "good=%lX, bad=%lX", heal->good, heal->bad);
-
- if ((heal->good != 0) && (heal->bad != 0) &&
- (heal->iatt.ia_type == IA_IFREG))
- {
- ec_readv(heal->fop->frame, heal->xl, heal->good, EC_MINIMUM_MIN,
- ec_heal_readv_cbk, heal, heal->fd, heal->size, heal->offset,
- 0, NULL);
- }
-}
-
-void ec_heal_dispatch(ec_heal_t *heal)
-{
- ec_fop_data_t *fop;
- ec_cbk_data_t *cbk;
- inode_t *inode;
- ec_inode_t *ctx;
- ec_heal_t *next = NULL;
- struct list_head list;
- int32_t error;
-
- inode = heal->loc.inode;
-
- INIT_LIST_HEAD(&list);
-
- LOCK(&inode->lock);
-
- /* A heal object not belonging to any list means that it has not been fully
- * executed. It got its information from a previous heal that was executing
- * when this heal started. */
- if (!list_empty(&heal->list)) {
-
- list_del_init(&heal->list);
-
- ctx = __ec_inode_get(inode, heal->xl);
- if (ctx != NULL) {
- ctx->bad &= ~heal->good;
-
- if (heal->partial) {
- /* Collect all partial heal requests. All of them will receive
- * the same answer. 'next' will contain a pointer to the first
- * full request (if any) after this partial heal request.*/
- while (!list_empty(&ctx->heal)) {
- next = list_entry(ctx->heal.next, ec_heal_t, list);
- if (!next->partial) {
- break;
- }
- list_move_tail(&next->list, &list);
- }
- if (list_empty(&ctx->heal)) {
- next = NULL;
- }
- } else {
- /* This is a full heal request, so take all received heal
- * requests to answer them now. */
- list_splice_init(&ctx->heal, &list);
- }
- }
- }
-
- UNLOCK(&inode->lock);
-
- fop = heal->fop;
- error = fop->error;
-
- cbk = ec_cbk_data_allocate(fop->frame, heal->xl, fop, fop->id, 0,
- error == 0 ? 0 : -1, error);
- if (cbk != NULL) {
- cbk->uintptr[0] = heal->available;
- cbk->uintptr[1] = heal->good;
- cbk->uintptr[2] = heal->fixed;
-
- ec_combine(cbk, NULL);
-
- fop->answer = cbk;
- } else if (error == 0) {
- error = ENOMEM;
- }
-
- if (heal->lookup != NULL)
- {
- ec_fop_data_release(heal->lookup);
- }
- if (heal->fd != NULL)
- {
- fd_unref(heal->fd);
- }
- GF_FREE(heal->symlink);
- loc_wipe(&heal->loc);
-
- LOCK_DESTROY(&heal->lock);
-
- GF_FREE(heal);
-
- ec_fop_set_error(fop, error);
-
- /* Resume all pending heal requests, setting the same data obtained by
- * this heal execution. */
- while (!list_empty(&list)) {
- heal = list_entry(list.next, ec_heal_t, list);
- list_del_init(&heal->list);
-
- heal->available = cbk->uintptr[0];
- heal->good = cbk->uintptr[1];
- heal->fixed = cbk->uintptr[2];
-
- /* Setting 'done' to 1 avoids executing all heal logic and directly
- * reports the result to the caller. */
- heal->done = 1;
-
- ec_resume(heal->fop, error);
- }
-
- /* If there is a pending full request, resume it. */
- if (next != NULL) {
- ec_resume(next->fop, 0);
- }
-}
-
-void ec_wind_heal(ec_t * ec, ec_fop_data_t * fop, int32_t idx)
-{
- ec_cbk_data_t * cbk;
- ec_heal_t * heal = fop->heal;
-
- ec_trace("WIND", fop, "idx=%d", idx);
-
- cbk = ec_cbk_data_allocate(fop->frame, fop->xl, fop, EC_FOP_HEAL, idx,
- fop->error == 0 ? 0 : -1, fop->error);
- if (cbk != NULL)
- {
- cbk->uintptr[0] = heal->available;
- cbk->uintptr[1] = heal->good;
- cbk->uintptr[2] = heal->bad;
-
- ec_combine(cbk, NULL);
- }
-
- ec_complete(fop);
-}
-
-int32_t ec_manager_heal(ec_fop_data_t * fop, int32_t state)
-{
- ec_cbk_data_t * cbk;
- ec_heal_t * heal = fop->heal;
-
- switch (state)
- {
- case EC_STATE_INIT:
- ec_owner_set(fop->frame, fop->frame->root);
-
- fop->error = ec_heal_init(fop);
- if (fop->error != 0)
- {
- return EC_STATE_REPORT;
- }
-
- return EC_STATE_DISPATCH;
-
- case EC_STATE_DISPATCH:
- if (heal->done) {
- return EC_STATE_HEAL_DISPATCH;
- }
-
- ec_heal_entrylk(heal, ENTRYLK_LOCK);
-
- return EC_STATE_HEAL_ENTRY_LOOKUP;
-
- case EC_STATE_HEAL_ENTRY_LOOKUP:
- ec_lookup(fop->frame, heal->xl, fop->mask, EC_MINIMUM_MIN,
- ec_heal_entry_lookup_cbk, heal, &heal->loc, NULL);
-
- return EC_STATE_HEAL_ENTRY_PREPARE;
-
- case EC_STATE_HEAL_ENTRY_PREPARE:
- if (!heal->partial || (heal->iatt.ia_type == IA_IFDIR)) {
- ec_heal_prepare(heal);
- }
-
- if (heal->partial) {
- return EC_STATE_HEAL_UNLOCK_ENTRY;
- }
-
- return EC_STATE_HEAL_PRE_INODELK_LOCK;
-
- case EC_STATE_HEAL_PRE_INODELK_LOCK:
- // Only heal data/metadata if enough information is supplied.
- if (uuid_is_null(heal->loc.gfid))
- {
- ec_heal_entrylk(heal, ENTRYLK_UNLOCK);
-
- return EC_STATE_HEAL_DISPATCH;
- }
-
- ec_heal_inodelk(heal, F_WRLCK, 0, 0, 0);
-
- return EC_STATE_HEAL_PRE_INODE_LOOKUP;
-
- case EC_STATE_HEAL_PRE_INODE_LOOKUP:
- ec_heal_lookup(heal, heal->fop->mask);
-
- return EC_STATE_HEAL_XATTRIBUTES_REMOVE;
-
- case EC_STATE_HEAL_XATTRIBUTES_REMOVE:
- ec_heal_removexattr_others(heal);
-
- return EC_STATE_HEAL_XATTRIBUTES_SET;
-
- case EC_STATE_HEAL_XATTRIBUTES_SET:
- ec_heal_setxattr_others(heal);
-
- return EC_STATE_HEAL_ATTRIBUTES;
-
- case EC_STATE_HEAL_ATTRIBUTES:
- ec_heal_attr(heal);
-
- return EC_STATE_HEAL_OPEN;
-
- case EC_STATE_HEAL_OPEN:
- ec_heal_open(heal);
-
- return EC_STATE_HEAL_REOPEN_FD;
-
- case EC_STATE_HEAL_REOPEN_FD:
- ec_heal_reopen_fd(heal);
-
- return EC_STATE_HEAL_UNLOCK;
-
- case -EC_STATE_HEAL_XATTRIBUTES_REMOVE:
- case -EC_STATE_HEAL_XATTRIBUTES_SET:
- case -EC_STATE_HEAL_ATTRIBUTES:
- case -EC_STATE_HEAL_OPEN:
- case -EC_STATE_HEAL_REOPEN_FD:
- case -EC_STATE_HEAL_UNLOCK:
- case EC_STATE_HEAL_UNLOCK:
- ec_heal_inodelk(heal, F_UNLCK, 0, 0, 0);
-
- /* Fall through */
-
- case -EC_STATE_HEAL_ENTRY_PREPARE:
- case -EC_STATE_HEAL_PRE_INODELK_LOCK:
- case -EC_STATE_HEAL_PRE_INODE_LOOKUP:
- case -EC_STATE_HEAL_UNLOCK_ENTRY:
- case EC_STATE_HEAL_UNLOCK_ENTRY:
- ec_heal_entrylk(heal, ENTRYLK_UNLOCK);
-
- if (ec_heal_needs_data_rebuild(heal))
- {
- return EC_STATE_HEAL_DATA_LOCK;
- }
-
- return EC_STATE_HEAL_DISPATCH;
-
- case EC_STATE_HEAL_DATA_LOCK:
- if (heal->done)
- {
- return EC_STATE_HEAL_POST_INODELK_LOCK;
- }
-
- ec_heal_inodelk(heal, F_WRLCK, 1, heal->offset, heal->size);
-
- return EC_STATE_HEAL_DATA_COPY;
-
- case EC_STATE_HEAL_DATA_COPY:
- ec_heal_data(heal);
-
- return EC_STATE_HEAL_DATA_UNLOCK;
-
- case -EC_STATE_HEAL_DATA_COPY:
- case -EC_STATE_HEAL_DATA_UNLOCK:
- case EC_STATE_HEAL_DATA_UNLOCK:
- ec_heal_inodelk(heal, F_UNLCK, 1, heal->offset, heal->size);
-
- heal->offset += heal->size;
-
- return EC_STATE_HEAL_DATA_LOCK;
-
- case EC_STATE_HEAL_POST_INODELK_LOCK:
- ec_heal_inodelk(heal, F_WRLCK, 1, 0, 0);
-
- return EC_STATE_HEAL_POST_INODE_LOOKUP;
-
- case EC_STATE_HEAL_POST_INODE_LOOKUP:
- heal->fixed = heal->bad;
- ec_heal_lookup(heal, heal->good);
-
- return EC_STATE_HEAL_SETATTR;
-
- case EC_STATE_HEAL_SETATTR:
- ec_setattr(heal->fop->frame, heal->xl, heal->fixed, EC_MINIMUM_ONE,
- ec_heal_setattr_cbk, heal, &heal->loc, &heal->iatt,
- GF_SET_ATTR_MODE | GF_SET_ATTR_UID | GF_SET_ATTR_GID |
- GF_SET_ATTR_ATIME | GF_SET_ATTR_MTIME, NULL);
-
- return EC_STATE_HEAL_POST_INODELK_UNLOCK;
-
- case -EC_STATE_HEAL_SETATTR:
- case -EC_STATE_HEAL_POST_INODELK_UNLOCK:
- case EC_STATE_HEAL_POST_INODELK_UNLOCK:
- ec_heal_inodelk(heal, F_UNLCK, 1, 0, 0);
-
- return EC_STATE_HEAL_DISPATCH;
-
- case -EC_STATE_HEAL_POST_INODELK_LOCK:
- case -EC_STATE_HEAL_POST_INODE_LOOKUP:
- case -EC_STATE_HEAL_ENTRY_LOOKUP:
- case -EC_STATE_HEAL_DATA_LOCK:
- case -EC_STATE_HEAL_DISPATCH:
- case EC_STATE_HEAL_DISPATCH:
- ec_heal_dispatch(heal);
-
- return EC_STATE_PREPARE_ANSWER;
-
- case EC_STATE_PREPARE_ANSWER:
- cbk = fop->answer;
- if (cbk != NULL)
- {
- if (!ec_dict_combine(cbk, EC_COMBINE_XDATA))
- {
- if (cbk->op_ret >= 0)
- {
- cbk->op_ret = -1;
- cbk->op_errno = EIO;
- }
- }
- if (cbk->op_ret < 0)
- {
- ec_fop_set_error(fop, cbk->op_errno);
- }
- }
- else
- {
- ec_fop_set_error(fop, EIO);
- }
-
- return EC_STATE_REPORT;
-
- case EC_STATE_REPORT:
- cbk = fop->answer;
-
- GF_ASSERT(cbk != NULL);
-
- if (fop->id == EC_FOP_HEAL)
- {
- if (fop->cbks.heal != NULL)
- {
- fop->cbks.heal(fop->req_frame, fop, fop->xl, cbk->op_ret,
- cbk->op_errno, cbk->uintptr[0],
- cbk->uintptr[1], cbk->uintptr[2],
- cbk->xdata);
- }
- }
- else
- {
- if (fop->cbks.fheal != NULL)
- {
- fop->cbks.fheal(fop->req_frame, fop, fop->xl, cbk->op_ret,
- cbk->op_errno, cbk->uintptr[0],
- cbk->uintptr[1], cbk->uintptr[2],
- cbk->xdata);
- }
- }
-
- return EC_STATE_END;
-
- case -EC_STATE_INIT:
- case -EC_STATE_DISPATCH:
- case -EC_STATE_PREPARE_ANSWER:
- case -EC_STATE_REPORT:
- GF_ASSERT(fop->error != 0);
-
- if (fop->id == EC_FOP_HEAL)
- {
- if (fop->cbks.heal != NULL)
- {
- fop->cbks.heal(fop->req_frame, fop, fop->xl, -1,
- fop->error, 0, 0, 0, NULL);
- }
- }
- else
- {
- if (fop->cbks.fheal != NULL)
- {
- fop->cbks.fheal(fop->req_frame, fop, fop->xl, -1,
- fop->error, 0, 0, 0, NULL);
- }
- }
-
- return EC_STATE_END;
-
- default:
- gf_log(fop->xl->name, GF_LOG_ERROR, "Unhandled state %d for %s",
- state, ec_fop_name(fop->id));
-
- return EC_STATE_END;
- }
-}
-
-void ec_heal(call_frame_t * frame, xlator_t * this, uintptr_t target,
- int32_t minimum, fop_heal_cbk_t func, void * data, loc_t * loc,
- int32_t partial, dict_t *xdata)
-{
- ec_cbk_t callback = { .heal = func };
- ec_fop_data_t * fop = NULL;
- int32_t error = EIO;
-
- gf_log("ec", GF_LOG_TRACE, "EC(HEAL) %p", frame);
-
- VALIDATE_OR_GOTO(this, out);
- GF_VALIDATE_OR_GOTO(this->name, this->private, out);
-
- fop = ec_fop_data_allocate(frame, this, EC_FOP_HEAL,
- EC_FLAG_UPDATE_LOC_INODE, target, minimum,
- ec_wind_heal, ec_manager_heal, callback, data);
- if (fop == NULL)
- {
- goto out;
- }
-
- fop->int32 = partial;
-
- if (loc != NULL)
- {
- if (loc_copy(&fop->loc[0], loc) != 0)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to copy a location.");
-
- goto out;
- }
- }
- if (xdata != NULL)
- {
- fop->xdata = dict_ref(xdata);
- if (fop->xdata == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
- "dictionary.");
-
- goto out;
- }
- }
-
- error = 0;
-
-out:
- if (fop != NULL)
- {
- ec_manager(fop, error);
- }
- else
- {
- func(frame, NULL, this, -1, EIO, 0, 0, 0, NULL);
- }
-}
-
-/* FOP: fheal */
-
-void ec_wind_fheal(ec_t * ec, ec_fop_data_t * fop, int32_t idx)
-{
- ec_cbk_data_t * cbk;
- ec_heal_t * heal = fop->heal;
-
- ec_trace("WIND", fop, "idx=%d", idx);
-
- cbk = ec_cbk_data_allocate(fop->frame, fop->xl, fop, EC_FOP_FHEAL, idx,
- fop->error == 0 ? 0 : -1, fop->error);
- if (cbk != NULL)
- {
- cbk->uintptr[0] = heal->available;
- cbk->uintptr[1] = heal->good;
- cbk->uintptr[2] = heal->bad;
-
- ec_combine(cbk, NULL);
- }
-
- ec_complete(fop);
-}
-
-void ec_fheal(call_frame_t * frame, xlator_t * this, uintptr_t target,
- int32_t minimum, fop_fheal_cbk_t func, void * data, fd_t * fd,
- int32_t partial, dict_t *xdata)
-{
- ec_fd_t * ctx = ec_fd_get(fd, this);
-
- if (ctx != NULL)
- {
- gf_log("ec", GF_LOG_DEBUG, "FHEAL ctx: flags=%X, open=%lX, bad=%lX",
- ctx->flags, ctx->open, ctx->bad);
- ec_heal(frame, this, target, minimum, func, data, &ctx->loc, partial,
- xdata);
- }
-}
diff --git a/xlators/cluster/ec/src/ec-helpers.c b/xlators/cluster/ec/src/ec-helpers.c
deleted file mode 100644
index 11e0b00f2eb..00000000000
--- a/xlators/cluster/ec/src/ec-helpers.c
+++ /dev/null
@@ -1,722 +0,0 @@
-/*
- Copyright (c) 2012-2014 DataLab, s.l. <http://www.datalab.es>
- 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 <libgen.h>
-
-#include "byte-order.h"
-
-#include "ec-mem-types.h"
-#include "ec-fops.h"
-#include "ec-helpers.h"
-
-#define BACKEND_D_OFF_BITS 63
-#define PRESENT_D_OFF_BITS 63
-
-#define ONE 1ULL
-#define MASK (~0ULL)
-#define PRESENT_MASK (MASK >> (64 - PRESENT_D_OFF_BITS))
-#define BACKEND_MASK (MASK >> (64 - BACKEND_D_OFF_BITS))
-
-#define TOP_BIT (ONE << (PRESENT_D_OFF_BITS - 1))
-#define SHIFT_BITS (max(0, (BACKEND_D_OFF_BITS - PRESENT_D_OFF_BITS + 1)))
-
-#ifndef ffsll
-#define ffsll(x) __builtin_ffsll(x)
-#endif
-
-static const char * ec_fop_list[] =
-{
- [-EC_FOP_HEAL] = "HEAL"
-};
-
-const char * ec_bin(char * str, size_t size, uint64_t value, int32_t digits)
-{
- str += size;
-
- if (size-- < 1)
- {
- goto failed;
- }
- *--str = 0;
-
- while ((value != 0) || (digits > 0))
- {
- if (size-- < 1)
- {
- goto failed;
- }
- *--str = '0' + (value & 1);
- digits--;
- value >>= 1;
- }
-
- return str;
-
-failed:
- return "<buffer too small>";
-}
-
-const char * ec_fop_name(int32_t id)
-{
- if (id >= 0)
- {
- return gf_fop_list[id];
- }
-
- return ec_fop_list[-id];
-}
-
-void ec_trace(const char * event, ec_fop_data_t * fop, const char * fmt, ...)
-{
- char str1[32], str2[32], str3[32];
- char * msg;
- ec_t * ec = fop->xl->private;
- va_list args;
- int32_t ret;
-
- va_start(args, fmt);
- ret = vasprintf(&msg, fmt, args);
- va_end(args);
-
- if (ret < 0)
- {
- msg = "<memory allocation error>";
- }
-
- gf_log("ec", GF_LOG_TRACE, "%s(%s) %p(%p) [refs=%d, winds=%d, jobs=%d] "
- "frame=%p/%p, min/exp=%d/%d, err=%d state=%d "
- "{%s:%s:%s} %s",
- event, ec_fop_name(fop->id), fop, fop->parent, fop->refs,
- fop->winds, fop->jobs, fop->req_frame, fop->frame, fop->minimum,
- fop->expected, fop->error, fop->state,
- ec_bin(str1, sizeof(str1), fop->mask, ec->nodes),
- ec_bin(str2, sizeof(str2), fop->remaining, ec->nodes),
- ec_bin(str3, sizeof(str3), fop->bad, ec->nodes), msg);
-
- if (ret >= 0)
- {
- free(msg);
- }
-}
-
-uint64_t ec_itransform(ec_t * ec, int32_t idx, uint64_t offset)
-{
- int32_t bits;
-
- if (offset == -1ULL)
- {
- return -1ULL;
- }
-
- bits = ec->bits_for_nodes;
- if ((offset & ~(PRESENT_MASK >> (bits + 1))) != 0)
- {
- return TOP_BIT | ((offset >> SHIFT_BITS) & (MASK << bits)) | idx;
- }
-
- return (offset * ec->nodes) + idx;
-}
-
-uint64_t ec_deitransform(ec_t * ec, int32_t * idx, uint64_t offset)
-{
- uint64_t mask = 0;
-
- if ((offset & TOP_BIT) != 0)
- {
- mask = MASK << ec->bits_for_nodes;
-
- *idx = offset & ~mask;
- return ((offset & ~TOP_BIT) & mask) << SHIFT_BITS;
- }
-
- *idx = offset % ec->nodes;
-
- return offset / ec->nodes;
-}
-
-int32_t ec_bits_count(uint64_t n)
-{
- n -= (n >> 1) & 0x5555555555555555ULL;
- n = ((n >> 2) & 0x3333333333333333ULL) + (n & 0x3333333333333333ULL);
- n = (n + (n >> 4)) & 0x0F0F0F0F0F0F0F0FULL;
- n += n >> 8;
- n += n >> 16;
- n += n >> 32;
-
- return n & 0xFF;
-}
-
-int32_t ec_bits_index(uint64_t n)
-{
- return ffsll(n) - 1;
-}
-
-int32_t ec_bits_consume(uint64_t * n)
-{
- uint64_t tmp;
-
- tmp = *n;
- tmp &= -tmp;
- *n ^= tmp;
-
- return ffsll(tmp) - 1;
-}
-
-size_t ec_iov_copy_to(void * dst, struct iovec * vector, int32_t count,
- off_t offset, size_t size)
-{
- int32_t i = 0;
- size_t total = 0, len = 0;
-
- while (i < count)
- {
- if (offset < vector[i].iov_len)
- {
- while ((i < count) && (size > 0))
- {
- len = size;
- if (len > vector[i].iov_len - offset)
- {
- len = vector[i].iov_len - offset;
- }
- memcpy(dst, vector[i++].iov_base + offset, len);
- offset = 0;
- dst += len;
- total += len;
- size -= len;
- }
-
- break;
- }
-
- offset -= vector[i].iov_len;
- i++;
- }
-
- return total;
-}
-
-int32_t ec_dict_set_number(dict_t * dict, char * key, uint64_t value)
-{
- uint64_t * ptr;
-
- ptr = GF_MALLOC(sizeof(value), gf_common_mt_char);
- if (ptr == NULL)
- {
- return -1;
- }
-
- *ptr = hton64(value);
-
- return dict_set_bin(dict, key, ptr, sizeof(value));
-}
-
-int32_t ec_dict_del_number(dict_t * dict, char * key, uint64_t * value)
-{
- void * ptr;
- int32_t len;
-
- if ((dict == NULL) || (dict_get_ptr_and_len(dict, key, &ptr, &len) != 0) ||
- (len != sizeof(uint64_t)))
- {
- return -1;
- }
-
- *value = ntoh64(*(uint64_t *)ptr);
-
- dict_del(dict, key);
-
- return 0;
-}
-
-int32_t ec_dict_set_config(dict_t * dict, char * key, ec_config_t * config)
-{
- uint64_t * ptr, data;
-
- if (config->version > EC_CONFIG_VERSION)
- {
- gf_log("ec", GF_LOG_ERROR, "Trying to store an unsupported config "
- "version (%u)", config->version);
-
- return -1;
- }
-
- ptr = GF_MALLOC(sizeof(uint64_t), gf_common_mt_char);
- if (ptr == NULL)
- {
- return -1;
- }
-
- data = ((uint64_t)config->version) << 56;
- data |= ((uint64_t)config->algorithm) << 48;
- data |= ((uint64_t)config->gf_word_size) << 40;
- data |= ((uint64_t)config->bricks) << 32;
- data |= ((uint64_t)config->redundancy) << 24;
- data |= config->chunk_size;
-
- *ptr = hton64(data);
-
- return dict_set_bin(dict, key, ptr, sizeof(uint64_t));
-}
-
-int32_t ec_dict_del_config(dict_t * dict, char * key, ec_config_t * config)
-{
- void * ptr;
- uint64_t data;
- int32_t len;
-
- if ((dict == NULL) || (dict_get_ptr_and_len(dict, key, &ptr, &len) != 0) ||
- (len != sizeof(uint64_t)))
- {
- return -1;
- }
-
- data = ntoh64(*(uint64_t *)ptr);
-
- config->version = (data >> 56) & 0xff;
- if (config->version > EC_CONFIG_VERSION)
- {
- gf_log("ec", GF_LOG_ERROR, "Found an unsupported config version (%u)",
- config->version);
-
- return -1;
- }
-
- config->algorithm = (data >> 48) & 0xff;
- config->gf_word_size = (data >> 40) & 0xff;
- config->bricks = (data >> 32) & 0xff;
- config->redundancy = (data >> 24) & 0xff;
- config->chunk_size = data & 0xffffff;
-
- dict_del(dict, key);
-
- return 0;
-}
-
-int32_t ec_loc_gfid_check(xlator_t * xl, uuid_t dst, uuid_t src)
-{
- if (uuid_is_null(src))
- {
- return 1;
- }
-
- if (uuid_is_null(dst))
- {
- uuid_copy(dst, src);
-
- return 1;
- }
-
- if (uuid_compare(dst, src) != 0)
- {
- gf_log(xl->name, GF_LOG_WARNING, "Mismatching GFID's in loc");
-
- return 0;
- }
-
- return 1;
-}
-
-int32_t ec_loc_setup_inode(xlator_t *xl, loc_t *loc)
-{
- int32_t ret = -1;
-
- if (loc->inode != NULL) {
- if (!ec_loc_gfid_check(xl, loc->gfid, loc->inode->gfid)) {
- goto out;
- }
- } else if (loc->parent != NULL) {
- if (!uuid_is_null(loc->gfid)) {
- loc->inode = inode_find(loc->parent->table, loc->gfid);
- } else if (loc->path != NULL) {
- loc->inode = inode_resolve(loc->parent->table, (char *)loc->path);
- }
- }
-
- ret = 0;
-
-out:
- return ret;
-}
-
-int32_t ec_loc_setup_parent(xlator_t *xl, loc_t *loc)
-{
- char *path, *parent;
- int32_t ret = -1;
-
- if (loc->parent != NULL) {
- if (!ec_loc_gfid_check(xl, loc->pargfid, loc->parent->gfid)) {
- goto out;
- }
- } else if (loc->inode != NULL) {
- if (!uuid_is_null(loc->pargfid)) {
- loc->parent = inode_find(loc->inode->table, loc->pargfid);
- } else if (loc->path != NULL) {
- path = gf_strdup(loc->path);
- if (path == NULL) {
- gf_log(xl->name, GF_LOG_ERROR, "Unable to duplicate path '%s'",
- loc->path);
-
- goto out;
- }
- parent = dirname(path);
- loc->parent = inode_resolve(loc->inode->table, parent);
- if (loc->parent != NULL) {
- uuid_copy(loc->pargfid, loc->parent->gfid);
- }
- GF_FREE(path);
- }
- }
-
- /* If 'pargfid' has not been determined, clear 'name' to avoid resolutions
- based on <gfid:pargfid>/name. */
- if (uuid_is_null(loc->pargfid)) {
- loc->name = NULL;
- }
-
- ret = 0;
-
-out:
- return ret;
-}
-
-int32_t ec_loc_setup_path(xlator_t *xl, loc_t *loc)
-{
- uuid_t root = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1};
- char *name;
- int32_t ret = -1;
-
- if (loc->path != NULL) {
- name = strrchr(loc->path, '/');
- if (name == NULL) {
- gf_log(xl->name, GF_LOG_ERROR, "Invalid path '%s' in loc",
- loc->path);
-
- goto out;
- }
- if (name == loc->path) {
- if (name[1] == 0) {
- if (!ec_loc_gfid_check(xl, loc->gfid, root)) {
- goto out;
- }
- } else {
- if (!ec_loc_gfid_check(xl, loc->pargfid, root)) {
- goto out;
- }
- }
- }
- name++;
-
- if (loc->name != NULL) {
- if (strcmp(loc->name, name) != 0) {
- gf_log(xl->name, GF_LOG_ERROR, "Invalid name '%s' in loc",
- loc->name);
-
- goto out;
- }
- } else {
- loc->name = name;
- }
- }
-
- ret = 0;
-
-out:
- return ret;
-}
-
-int32_t ec_loc_parent(xlator_t *xl, loc_t *loc, loc_t *parent)
-{
- char *str = NULL;
- int32_t ret = -1;
-
- memset(parent, 0, sizeof(loc_t));
-
- if (loc->parent != NULL) {
- parent->inode = inode_ref(loc->parent);
- }
- if (!uuid_is_null(loc->pargfid)) {
- uuid_copy(parent->gfid, loc->pargfid);
- }
- if (loc->path != NULL) {
- str = gf_strdup(loc->path);
- if (str == NULL) {
- gf_log(xl->name, GF_LOG_ERROR, "Unable to duplicate path '%s'",
- loc->path);
-
- goto out;
- }
- parent->path = gf_strdup(dirname(str));
- if (parent->path == NULL) {
- gf_log(xl->name, GF_LOG_ERROR, "Unable to duplicate path '%s'",
- dirname(str));
-
- goto out;
- }
- }
-
- if ((ec_loc_setup_path(xl, parent) != 0) ||
- (ec_loc_setup_inode(xl, parent) != 0) ||
- (ec_loc_setup_parent(xl, parent) != 0)) {
- goto out;
- }
-
- if ((parent->inode == NULL) && (parent->path == NULL) &&
- uuid_is_null(parent->gfid)) {
- gf_log(xl->name, GF_LOG_ERROR, "Parent inode missing for loc_t");
-
- goto out;
- }
-
- ret = 0;
-
-out:
- GF_FREE(str);
-
- if (ret != 0)
- {
- loc_wipe(parent);
- }
-
- return ret;
-}
-
-int32_t ec_loc_update(xlator_t *xl, loc_t *loc, inode_t *inode,
- struct iatt *iatt)
-{
- int32_t ret = -1;
-
- if ((inode != NULL) && (loc->inode != inode)) {
- if (loc->inode != NULL) {
- inode_unref(loc->inode);
- }
- loc->inode = inode_ref(inode);
- uuid_copy(loc->gfid, inode->gfid);
- }
-
- if (iatt != NULL) {
- if (!ec_loc_gfid_check(xl, loc->gfid, iatt->ia_gfid)) {
- goto out;
- }
- }
-
- if ((ec_loc_setup_path(xl, loc) != 0) ||
- (ec_loc_setup_inode(xl, loc) != 0) ||
- (ec_loc_setup_parent(xl, loc) != 0)) {
- goto out;
- }
-
- ret = 0;
-
-out:
- return ret;
-}
-
-int32_t ec_loc_from_fd(xlator_t * xl, loc_t * loc, fd_t * fd)
-{
- ec_fd_t * ctx;
- int32_t ret = -1;
-
- memset(loc, 0, sizeof(*loc));
-
- ctx = ec_fd_get(fd, xl);
- if (ctx != NULL) {
- if (loc_copy(loc, &ctx->loc) != 0) {
- goto out;
- }
- }
-
- if (ec_loc_update(xl, loc, fd->inode, NULL) != 0) {
- goto out;
- }
-
- ret = 0;
-
-out:
- if (ret != 0) {
- loc_wipe(loc);
- }
-
- return ret;
-}
-
-int32_t ec_loc_from_loc(xlator_t * xl, loc_t * dst, loc_t * src)
-{
- int32_t ret = -1;
-
- memset(dst, 0, sizeof(*dst));
-
- if (loc_copy(dst, src) != 0) {
- goto out;
- }
-
- if (ec_loc_update(xl, dst, NULL, NULL) != 0) {
- goto out;
- }
-
- ret = 0;
-
-out:
- if (ret != 0) {
- loc_wipe(dst);
- }
-
- return ret;
-}
-
-void ec_owner_set(call_frame_t * frame, void * owner)
-{
- set_lk_owner_from_ptr(&frame->root->lk_owner, owner);
-}
-
-void ec_owner_copy(call_frame_t * frame, gf_lkowner_t * owner)
-{
- frame->root->lk_owner.len = owner->len;
- memcpy(frame->root->lk_owner.data, owner->data, owner->len);
-}
-
-ec_inode_t * __ec_inode_get(inode_t * inode, xlator_t * xl)
-{
- ec_inode_t * ctx = NULL;
- uint64_t value = 0;
-
- if ((__inode_ctx_get(inode, xl, &value) != 0) || (value == 0))
- {
- ctx = GF_MALLOC(sizeof(*ctx), ec_mt_ec_inode_t);
- if (ctx != NULL)
- {
- memset(ctx, 0, sizeof(*ctx));
- INIT_LIST_HEAD(&ctx->heal);
-
- value = (uint64_t)(uintptr_t)ctx;
- if (__inode_ctx_set(inode, xl, &value) != 0)
- {
- GF_FREE(ctx);
-
- return NULL;
- }
- }
- }
- else
- {
- ctx = (ec_inode_t *)(uintptr_t)value;
- }
-
- return ctx;
-}
-
-ec_inode_t * ec_inode_get(inode_t * inode, xlator_t * xl)
-{
- ec_inode_t * ctx = NULL;
-
- LOCK(&inode->lock);
-
- ctx = __ec_inode_get(inode, xl);
-
- UNLOCK(&inode->lock);
-
- return ctx;
-}
-
-ec_fd_t * __ec_fd_get(fd_t * fd, xlator_t * xl)
-{
- ec_fd_t * ctx = NULL;
- uint64_t value = 0;
-
- if ((__fd_ctx_get(fd, xl, &value) != 0) || (value == 0))
- {
- ctx = GF_MALLOC(sizeof(*ctx), ec_mt_ec_fd_t);
- if (ctx != NULL)
- {
- memset(ctx, 0, sizeof(*ctx));
-
- value = (uint64_t)(uintptr_t)ctx;
- if (__fd_ctx_set(fd, xl, value) != 0)
- {
- GF_FREE(ctx);
-
- return NULL;
- }
- }
- }
- else
- {
- ctx = (ec_fd_t *)(uintptr_t)value;
- }
-
- /* Treat anonymous fd specially */
- if (fd->anonymous) {
- /* Mark the fd open for all subvolumes. */
- ctx->open = -1;
- /* Try to populate ctx->loc with fd->inode information. */
- ec_loc_update(xl, &ctx->loc, fd->inode, NULL);
- }
-
- return ctx;
-}
-
-ec_fd_t * ec_fd_get(fd_t * fd, xlator_t * xl)
-{
- ec_fd_t * ctx = NULL;
-
- LOCK(&fd->lock);
-
- ctx = __ec_fd_get(fd, xl);
-
- UNLOCK(&fd->lock);
-
- return ctx;
-}
-
-uint32_t ec_adjust_offset(ec_t * ec, off_t * offset, int32_t scale)
-{
- off_t head, tmp;
-
- tmp = *offset;
- head = tmp % ec->stripe_size;
- tmp -= head;
- if (scale)
- {
- tmp /= ec->fragments;
- }
-
- *offset = tmp;
-
- return head;
-}
-
-uint64_t ec_adjust_size(ec_t * ec, uint64_t size, int32_t scale)
-{
- size += ec->stripe_size - 1;
- size -= size % ec->stripe_size;
- if (scale)
- {
- size /= ec->fragments;
- }
-
- return size;
-}
-
-gf_boolean_t
-ec_is_internal_xattr (dict_t *dict, char *key, data_t *value, void *data)
-{
- if (key &&
- (strncmp (key, EC_XATTR_PREFIX, strlen (EC_XATTR_PREFIX)) == 0))
- return _gf_true;
-
- return _gf_false;
-}
-
-void
-ec_filter_internal_xattrs (dict_t *xattr)
-{
- dict_foreach_match (xattr, ec_is_internal_xattr, NULL,
- dict_remove_foreach_fn, NULL);
-}
diff --git a/xlators/cluster/ec/src/ec-helpers.h b/xlators/cluster/ec/src/ec-helpers.h
deleted file mode 100644
index 5f5d9382532..00000000000
--- a/xlators/cluster/ec/src/ec-helpers.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- Copyright (c) 2012-2014 DataLab, s.l. <http://www.datalab.es>
- 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 __EC_HELPERS_H__
-#define __EC_HELPERS_H__
-
-#include "ec-data.h"
-
-const char * ec_bin(char * str, size_t size, uint64_t value, int32_t digits);
-const char * ec_fop_name(int32_t id);
-void ec_trace(const char * event, ec_fop_data_t * fop, const char * fmt, ...);
-uint64_t ec_itransform(ec_t * ec, int32_t idx, uint64_t offset);
-uint64_t ec_deitransform(ec_t * ec, int32_t * idx, uint64_t offset);
-int32_t ec_bits_count(uint64_t n);
-int32_t ec_bits_index(uint64_t n);
-int32_t ec_bits_consume(uint64_t * n);
-size_t ec_iov_copy_to(void * dst, struct iovec * vector, int32_t count,
- off_t offset, size_t size);
-
-int32_t ec_dict_set_number(dict_t * dict, char * key, uint64_t value);
-int32_t ec_dict_del_number(dict_t * dict, char * key, uint64_t * value);
-int32_t ec_dict_set_config(dict_t * dict, char * key, ec_config_t * config);
-int32_t ec_dict_del_config(dict_t * dict, char * key, ec_config_t * config);
-
-int32_t ec_loc_parent(xlator_t *xl, loc_t *loc, loc_t *parent);
-int32_t ec_loc_update(xlator_t *xl, loc_t *loc, inode_t *inode,
- struct iatt *iatt);
-
-int32_t ec_loc_from_fd(xlator_t * xl, loc_t * loc, fd_t * fd);
-int32_t ec_loc_from_loc(xlator_t * xl, loc_t * dst, loc_t * src);
-
-void ec_owner_set(call_frame_t * frame, void * owner);
-void ec_owner_copy(call_frame_t * frame, gf_lkowner_t * owner);
-
-ec_inode_t * __ec_inode_get(inode_t * inode, xlator_t * xl);
-ec_inode_t * ec_inode_get(inode_t * inode, xlator_t * xl);
-ec_fd_t * __ec_fd_get(fd_t * fd, xlator_t * xl);
-ec_fd_t * ec_fd_get(fd_t * fd, xlator_t * xl);
-
-uint32_t ec_adjust_offset(ec_t * ec, off_t * offset, int32_t scale);
-uint64_t ec_adjust_size(ec_t * ec, uint64_t size, int32_t scale);
-
-static inline int32_t ec_is_power_of_2(uint32_t value)
-{
- return (value != 0) && ((value & (value - 1)) == 0);
-}
-
-gf_boolean_t
-ec_is_internal_xattr (dict_t *dict, char *key, data_t *value, void *data);
-
-void
-ec_filter_internal_xattrs (dict_t *xattr);
-#endif /* __EC_HELPERS_H__ */
diff --git a/xlators/cluster/ec/src/ec-inode-read.c b/xlators/cluster/ec/src/ec-inode-read.c
deleted file mode 100644
index 3483dfb3354..00000000000
--- a/xlators/cluster/ec/src/ec-inode-read.c
+++ /dev/null
@@ -1,1865 +0,0 @@
-/*
- Copyright (c) 2012-2014 DataLab, s.l. <http://www.datalab.es>
- 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 "xlator.h"
-#include "defaults.h"
-
-#include "ec-helpers.h"
-#include "ec-common.h"
-#include "ec-combine.h"
-#include "ec-method.h"
-#include "ec-fops.h"
-
-/* FOP: access */
-
-int32_t ec_access_cbk(call_frame_t * frame, void * cookie, xlator_t * this,
- int32_t op_ret, int32_t op_errno, dict_t * xdata)
-{
- ec_fop_data_t * fop = NULL;
- int32_t idx = (int32_t)(uintptr_t)cookie;
-
- VALIDATE_OR_GOTO(this, out);
- GF_VALIDATE_OR_GOTO(this->name, frame, out);
- GF_VALIDATE_OR_GOTO(this->name, frame->local, out);
- GF_VALIDATE_OR_GOTO(this->name, this->private, out);
-
- fop = frame->local;
-
- ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx,
- frame, op_ret, op_errno);
-
- if (!ec_dispatch_one_retry(fop, idx, op_ret, op_errno))
- {
- if (fop->cbks.access != NULL)
- {
- fop->cbks.access(fop->req_frame, fop, this, op_ret, op_errno,
- xdata);
- }
- }
-
-out:
- if (fop != NULL)
- {
- ec_complete(fop);
- }
-
- return 0;
-}
-
-void ec_wind_access(ec_t * ec, ec_fop_data_t * fop, int32_t idx)
-{
- ec_trace("WIND", fop, "idx=%d", idx);
-
- STACK_WIND_COOKIE(fop->frame, ec_access_cbk, (void *)(uintptr_t)idx,
- ec->xl_list[idx], ec->xl_list[idx]->fops->access,
- &fop->loc[0], fop->int32, fop->xdata);
-}
-
-int32_t ec_manager_access(ec_fop_data_t * fop, int32_t state)
-{
- switch (state)
- {
- case EC_STATE_INIT:
- case EC_STATE_DISPATCH:
- ec_dispatch_one(fop);
-
- return EC_STATE_REPORT;
-
- case -EC_STATE_INIT:
- case -EC_STATE_REPORT:
- if (fop->cbks.access != NULL)
- {
- fop->cbks.access(fop->req_frame, fop, fop->xl, -1, fop->error,
- NULL);
- }
-
- case EC_STATE_REPORT:
- return EC_STATE_END;
-
- default:
- gf_log(fop->xl->name, GF_LOG_ERROR, "Unhandled state %d for %s",
- state, ec_fop_name(fop->id));
-
- return EC_STATE_END;
- }
-}
-
-void ec_access(call_frame_t * frame, xlator_t * this, uintptr_t target,
- int32_t minimum, fop_access_cbk_t func, void * data,
- loc_t * loc, int32_t mask, dict_t * xdata)
-{
- ec_cbk_t callback = { .access = func };
- ec_fop_data_t * fop = NULL;
- int32_t error = EIO;
-
- gf_log("ec", GF_LOG_TRACE, "EC(ACCESS) %p", frame);
-
- VALIDATE_OR_GOTO(this, out);
- GF_VALIDATE_OR_GOTO(this->name, frame, out);
- GF_VALIDATE_OR_GOTO(this->name, this->private, out);
-
- fop = ec_fop_data_allocate(frame, this, GF_FOP_ACCESS, 0, target, minimum,
- ec_wind_access, ec_manager_access, callback,
- data);
- if (fop == NULL)
- {
- goto out;
- }
-
- fop->int32 = mask;
-
- if (loc != NULL)
- {
- if (loc_copy(&fop->loc[0], loc) != 0)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to copy a location.");
-
- goto out;
- }
- }
- if (xdata != NULL)
- {
- fop->xdata = dict_ref(xdata);
- if (fop->xdata == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
- "dictionary.");
-
- goto out;
- }
- }
-
- error = 0;
-
-out:
- if (fop != NULL)
- {
- ec_manager(fop, error);
- }
- else
- {
- func(frame, NULL, this, -1, EIO, NULL);
- }
-}
-
-/* FOP: getxattr */
-
-int32_t ec_combine_getxattr(ec_fop_data_t * fop, ec_cbk_data_t * dst,
- ec_cbk_data_t * src)
-{
- if (!ec_dict_compare(dst->dict, src->dict))
- {
- gf_log(fop->xl->name, GF_LOG_NOTICE, "Mismatching dictionary in "
- "answers of 'GF_FOP_GETXATTR'");
-
- return 0;
- }
-
- return 1;
-}
-
-int32_t ec_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)
-{
- ec_fop_data_t * fop = NULL;
- ec_cbk_data_t * cbk = NULL;
- int32_t idx = (int32_t)(uintptr_t)cookie;
-
- VALIDATE_OR_GOTO(this, out);
- GF_VALIDATE_OR_GOTO(this->name, frame, out);
- GF_VALIDATE_OR_GOTO(this->name, frame->local, out);
- GF_VALIDATE_OR_GOTO(this->name, this->private, out);
-
- fop = frame->local;
-
- ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx,
- frame, op_ret, op_errno);
-
- cbk = ec_cbk_data_allocate(frame, this, fop, GF_FOP_GETXATTR, idx, op_ret,
- op_errno);
- if (cbk != NULL)
- {
- if (op_ret >= 0)
- {
- if (dict != NULL)
- {
- cbk->dict = dict_ref(dict);
- if (cbk->dict == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
- "dictionary.");
-
- goto out;
- }
- }
- }
- if (xdata != NULL)
- {
- cbk->xdata = dict_ref(xdata);
- if (cbk->xdata == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
- "dictionary.");
-
- goto out;
- }
- }
-
- ec_combine(cbk, ec_combine_getxattr);
- }
-
-out:
- if (fop != NULL)
- {
- ec_complete(fop);
- }
-
- return 0;
-}
-
-void ec_wind_getxattr(ec_t * ec, ec_fop_data_t * fop, int32_t idx)
-{
- ec_trace("WIND", fop, "idx=%d", idx);
-
- STACK_WIND_COOKIE(fop->frame, ec_getxattr_cbk, (void *)(uintptr_t)idx,
- ec->xl_list[idx], ec->xl_list[idx]->fops->getxattr,
- &fop->loc[0], fop->str[0], fop->xdata);
-}
-
-int32_t ec_manager_getxattr(ec_fop_data_t * fop, int32_t state)
-{
- ec_cbk_data_t * cbk;
-
- switch (state)
- {
- case EC_STATE_INIT:
- case EC_STATE_LOCK:
- /* clear-locks commands must be done without any locks acquired
- to avoid interferences. */
- if ((fop->str[0] == NULL) ||
- (strncmp(fop->str[0], GF_XATTR_CLRLK_CMD,
- strlen(GF_XATTR_CLRLK_CMD)) != 0)) {
- if (fop->fd == NULL) {
- ec_lock_prepare_inode(fop, &fop->loc[0], 0);
- } else {
- ec_lock_prepare_fd(fop, fop->fd, 0);
- }
- ec_lock(fop);
- }
-
- return EC_STATE_DISPATCH;
-
- case EC_STATE_DISPATCH:
- ec_dispatch_all(fop);
-
- return EC_STATE_PREPARE_ANSWER;
-
- case EC_STATE_PREPARE_ANSWER:
- cbk = fop->answer;
- if (cbk != NULL)
- {
- if (!ec_dict_combine(cbk, EC_COMBINE_XDATA) ||
- ((cbk->op_ret >= 0) && !ec_dict_combine(cbk,
- EC_COMBINE_DICT)))
- {
- if (cbk->op_ret >= 0)
- {
- cbk->op_ret = -1;
- cbk->op_errno = EIO;
- }
- }
- if (cbk->op_ret < 0)
- {
- ec_fop_set_error(fop, cbk->op_errno);
- }
- else
- {
- if (cbk->xdata != NULL)
- ec_filter_internal_xattrs (cbk->xdata);
-
- if (cbk->dict != NULL)
- ec_filter_internal_xattrs (cbk->dict);
- }
- }
- else
- {
- ec_fop_set_error(fop, EIO);
- }
-
- return EC_STATE_REPORT;
-
- case EC_STATE_REPORT:
- cbk = fop->answer;
-
- GF_ASSERT(cbk != NULL);
-
- if (fop->cbks.getxattr != NULL)
- {
- fop->cbks.getxattr(fop->req_frame, fop, fop->xl, cbk->op_ret,
- cbk->op_errno, cbk->dict, cbk->xdata);
- }
-
- return EC_STATE_LOCK_REUSE;
-
- case -EC_STATE_INIT:
- case -EC_STATE_LOCK:
- case -EC_STATE_DISPATCH:
- case -EC_STATE_PREPARE_ANSWER:
- case -EC_STATE_REPORT:
- GF_ASSERT(fop->error != 0);
-
- if (fop->cbks.getxattr != NULL)
- {
- fop->cbks.getxattr(fop->req_frame, fop, fop->xl, -1,
- fop->error, NULL, NULL);
- }
-
- return EC_STATE_LOCK_REUSE;
-
- case -EC_STATE_LOCK_REUSE:
- case EC_STATE_LOCK_REUSE:
- ec_lock_reuse(fop);
-
- return EC_STATE_UNLOCK;
-
- case -EC_STATE_UNLOCK:
- case EC_STATE_UNLOCK:
- ec_unlock(fop);
-
- return EC_STATE_END;
-
- default:
- gf_log(fop->xl->name, GF_LOG_ERROR, "Unhandled state %d for %s",
- state, ec_fop_name(fop->id));
-
- return EC_STATE_END;
- }
-}
-
-int32_t ec_getxattr_heal_cbk(call_frame_t *frame, void *cookie, xlator_t *xl,
- int32_t op_ret, int32_t op_errno, uintptr_t mask,
- uintptr_t good, uintptr_t bad, dict_t *xdata)
-{
- ec_fop_data_t *fop = cookie;
- fop_getxattr_cbk_t func = fop->data;
- ec_t *ec = xl->private;
- dict_t *dict = NULL;
- char *str;
- char bin1[65], bin2[65];
-
- if (op_ret >= 0) {
- dict = dict_new();
- if (dict == NULL) {
- op_ret = -1;
- op_errno = ENOMEM;
- } else {
- if (gf_asprintf(&str, "Good: %s, Bad: %s",
- ec_bin(bin1, sizeof(bin1), good, ec->nodes),
- ec_bin(bin2, sizeof(bin2), mask & ~(good | bad),
- ec->nodes)) < 0) {
- dict_unref(dict);
- dict = NULL;
-
- op_ret = -1;
- op_errno = ENOMEM;
-
- goto out;
- }
-
- if (dict_set_str(dict, EC_XATTR_HEAL, str) != 0) {
- GF_FREE(str);
- dict_unref(dict);
- dict = NULL;
-
- op_ret = -1;
- op_errno = ENOMEM;
-
- goto out;
- }
- }
- }
-
-out:
- func(frame, NULL, xl, op_ret, op_errno, dict, NULL);
-
- if (dict != NULL) {
- dict_unref(dict);
- }
-
- return 0;
-}
-
-void
-ec_getxattr (call_frame_t *frame, xlator_t *this, uintptr_t target,
- int32_t minimum, fop_getxattr_cbk_t func, void *data,
- loc_t *loc, const char *name, dict_t *xdata)
-{
- ec_cbk_t callback = { .getxattr = func };
- ec_fop_data_t * fop = NULL;
- int32_t error = EIO;
-
- gf_log("ec", GF_LOG_TRACE, "EC(GETXATTR) %p", frame);
-
- VALIDATE_OR_GOTO(this, out);
- GF_VALIDATE_OR_GOTO(this->name, frame, out);
- GF_VALIDATE_OR_GOTO(this->name, this->private, out);
-
- /* Special handling of an explicit self-heal request */
- if ((name != NULL) && (strcmp(name, EC_XATTR_HEAL) == 0)) {
- ec_heal(frame, this, target, EC_MINIMUM_ONE, ec_getxattr_heal_cbk,
- func, loc, 0, NULL);
-
- return;
- }
-
- fop = ec_fop_data_allocate(frame, this, GF_FOP_GETXATTR,
- EC_FLAG_UPDATE_LOC_INODE, target, minimum,
- ec_wind_getxattr, ec_manager_getxattr, callback,
- data);
- if (fop == NULL)
- {
- goto out;
- }
-
- if (loc != NULL)
- {
- if (loc_copy(&fop->loc[0], loc) != 0)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to copy a location.");
-
- goto out;
- }
- }
- if (name != NULL)
- {
- fop->str[0] = gf_strdup(name);
- if (fop->str[0] == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to duplicate a string.");
-
- goto out;
- }
- }
- if (xdata != NULL)
- {
- fop->xdata = dict_ref(xdata);
- if (fop->xdata == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
- "dictionary.");
-
- goto out;
- }
- }
-
- error = 0;
-
-out:
- if (fop != NULL) {
- ec_manager (fop, error);
- } else {
- func (frame, NULL, this, -1, error, NULL, NULL);
- }
-}
-
-/* FOP: fgetxattr */
-
-int32_t ec_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)
-{
- ec_fop_data_t * fop = NULL;
- ec_cbk_data_t * cbk = NULL;
- int32_t idx = (int32_t)(uintptr_t)cookie;
-
- VALIDATE_OR_GOTO(this, out);
- GF_VALIDATE_OR_GOTO(this->name, frame, out);
- GF_VALIDATE_OR_GOTO(this->name, frame->local, out);
- GF_VALIDATE_OR_GOTO(this->name, this->private, out);
-
- fop = frame->local;
-
- ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx,
- frame, op_ret, op_errno);
-
- cbk = ec_cbk_data_allocate(frame, this, fop, GF_FOP_FGETXATTR, idx, op_ret,
- op_errno);
- if (cbk != NULL)
- {
- if (op_ret >= 0)
- {
- if (dict != NULL)
- {
- cbk->dict = dict_ref(dict);
- if (cbk->dict == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
- "dictionary.");
-
- goto out;
- }
- }
- }
- if (xdata != NULL)
- {
- cbk->xdata = dict_ref(xdata);
- if (cbk->xdata == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
- "dictionary.");
-
- goto out;
- }
- }
-
- ec_combine(cbk, ec_combine_getxattr);
- }
-
-out:
- if (fop != NULL)
- {
- ec_complete(fop);
- }
-
- return 0;
-}
-
-void
-ec_wind_fgetxattr (ec_t *ec, ec_fop_data_t *fop, int32_t idx)
-{
- ec_trace("WIND", fop, "idx=%d", idx);
-
- STACK_WIND_COOKIE(fop->frame, ec_fgetxattr_cbk, (void *)(uintptr_t)idx,
- ec->xl_list[idx], ec->xl_list[idx]->fops->fgetxattr,
- fop->fd, fop->str[0], fop->xdata);
-}
-
-void
-ec_fgetxattr (call_frame_t *frame, xlator_t *this, uintptr_t target,
- int32_t minimum, fop_fgetxattr_cbk_t func, void *data,
- fd_t *fd, const char *name, dict_t *xdata)
-{
- ec_cbk_t callback = { .fgetxattr = func };
- ec_fop_data_t * fop = NULL;
- int32_t error = EIO;
-
- gf_log("ec", GF_LOG_TRACE, "EC(FGETXATTR) %p", frame);
-
- VALIDATE_OR_GOTO(this, out);
- GF_VALIDATE_OR_GOTO(this->name, frame, out);
- GF_VALIDATE_OR_GOTO(this->name, this->private, out);
-
- fop = ec_fop_data_allocate(frame, this, GF_FOP_FGETXATTR,
- EC_FLAG_UPDATE_FD_INODE, target, minimum,
- ec_wind_fgetxattr, ec_manager_getxattr,
- callback, data);
- if (fop == NULL)
- {
- goto out;
- }
-
- fop->use_fd = 1;
-
- if (fd != NULL)
- {
- fop->fd = fd_ref(fd);
- if (fop->fd == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
- "file descriptor.");
-
- goto out;
- }
- }
- if (name != NULL)
- {
- fop->str[0] = gf_strdup(name);
- if (fop->str[0] == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to duplicate a string.");
-
- goto out;
- }
- }
- if (xdata != NULL)
- {
- fop->xdata = dict_ref(xdata);
- if (fop->xdata == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
- "dictionary.");
-
- goto out;
- }
- }
-
- error = 0;
-
-out:
- if (fop != NULL) {
- ec_manager (fop, error);
- } else {
- func (frame, NULL, this, -1, error, NULL, NULL);
- }
-}
-
-/* FOP: open */
-
-int32_t ec_combine_open(ec_fop_data_t * fop, ec_cbk_data_t * dst,
- ec_cbk_data_t * src)
-{
- if (dst->fd != src->fd)
- {
- gf_log(fop->xl->name, GF_LOG_NOTICE, "Mismatching fd in answers "
- "of 'GF_FOP_OPEN': %p <-> %p",
- dst->fd, src->fd);
-
- return 0;
- }
-
- return 1;
-}
-
-int32_t ec_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)
-{
- ec_fop_data_t * fop = NULL;
- ec_cbk_data_t * cbk = NULL;
- int32_t idx = (int32_t)(uintptr_t)cookie;
-
- VALIDATE_OR_GOTO(this, out);
- GF_VALIDATE_OR_GOTO(this->name, frame, out);
- GF_VALIDATE_OR_GOTO(this->name, frame->local, out);
- GF_VALIDATE_OR_GOTO(this->name, this->private, out);
-
- fop = frame->local;
-
- ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx,
- frame, op_ret, op_errno);
-
- cbk = ec_cbk_data_allocate(frame, this, fop, GF_FOP_OPEN, idx, op_ret,
- op_errno);
- if (cbk != NULL)
- {
- if (op_ret >= 0)
- {
- if (fd != NULL)
- {
- cbk->fd = fd_ref(fd);
- if (cbk->fd == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
- "file descriptor.");
-
- goto out;
- }
- }
- }
- if (xdata != NULL)
- {
- cbk->xdata = dict_ref(xdata);
- if (cbk->xdata == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
- "dictionary.");
-
- goto out;
- }
- }
-
- ec_combine(cbk, ec_combine_open);
- }
-
-out:
- if (fop != NULL)
- {
- ec_complete(fop);
- }
-
- return 0;
-}
-
-void ec_wind_open(ec_t * ec, ec_fop_data_t * fop, int32_t idx)
-{
- ec_trace("WIND", fop, "idx=%d", idx);
-
- STACK_WIND_COOKIE(fop->frame, ec_open_cbk, (void *)(uintptr_t)idx,
- ec->xl_list[idx], ec->xl_list[idx]->fops->open,
- &fop->loc[0], fop->int32, fop->fd, fop->xdata);
-}
-
-int32_t ec_open_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)
-{
- ec_fop_data_t *fop = cookie;
- int32_t error = 0;
-
- fop = fop->data;
- if (op_ret >= 0) {
- fop->answer->iatt[0] = *postbuf;
- } else {
- error = op_errno;
- }
-
- ec_resume(fop, error);
-
- return 0;
-}
-
-int32_t ec_manager_open(ec_fop_data_t * fop, int32_t state)
-{
- ec_cbk_data_t * cbk;
- ec_fd_t * ctx;
-
- switch (state)
- {
- case EC_STATE_INIT:
- LOCK(&fop->fd->lock);
-
- ctx = __ec_fd_get(fop->fd, fop->xl);
- if ((ctx == NULL) ||
- (ec_loc_from_loc(fop->xl, &ctx->loc, &fop->loc[0])) != 0) {
- UNLOCK(&fop->fd->lock);
-
- fop->error = EIO;
-
- return EC_STATE_REPORT;
- }
-
- ctx->flags = fop->int32;
-
- UNLOCK(&fop->fd->lock);
-
- /* We need to write to specific offsets on the bricks, so we
- need to remove O_APPEND from flags (if present).
- If O_TRUNC is specified, we remove it from open and an
- ftruncate will be executed later, which will correctly update
- the file size taking appropriate locks. O_TRUNC flag is saved
- into fop->uint32 to use it later.*/
- fop->uint32 = fop->int32 & O_TRUNC;
- fop->int32 &= ~(O_APPEND | O_TRUNC);
-
- /* Fall through */
-
- case EC_STATE_DISPATCH:
- ec_dispatch_all(fop);
-
- return EC_STATE_PREPARE_ANSWER;
-
- case EC_STATE_PREPARE_ANSWER:
- cbk = fop->answer;
- if (cbk != NULL)
- {
- if (!ec_dict_combine(cbk, EC_COMBINE_XDATA))
- {
- if (cbk->op_ret >= 0)
- {
- cbk->op_ret = -1;
- cbk->op_errno = EIO;
- }
- }
- if (cbk->op_ret >= 0) {
- if (ec_loc_update(fop->xl, &fop->loc[0], cbk->fd->inode,
- NULL) != 0) {
- cbk->op_ret = -1;
- cbk->op_errno = EIO;
- } else {
- LOCK(&fop->fd->lock);
-
- ctx = __ec_fd_get(fop->fd, fop->xl);
- if (ctx != NULL) {
- ctx->open |= cbk->mask;
- }
-
- UNLOCK(&fop->fd->lock);
-
- /* If O_TRUNC was specified, call ftruncate to
- effectively trunc the file with appropriate locks
- acquired. We don't use ctx->flags because self-heal
- can use the same fd with different flags. */
- if (fop->uint32 != 0) {
- ec_sleep(fop);
- ec_ftruncate(fop->req_frame, fop->xl, cbk->mask,
- fop->minimum, ec_open_truncate_cbk,
- fop, cbk->fd, 0, NULL);
- }
- }
- }
- if (cbk->op_ret < 0) {
- ec_fop_set_error(fop, cbk->op_errno);
- }
- }
- else
- {
- ec_fop_set_error(fop, EIO);
- }
-
- return EC_STATE_REPORT;
-
- case EC_STATE_REPORT:
- cbk = fop->answer;
-
- GF_ASSERT(cbk != NULL);
-
- if (fop->cbks.open != NULL)
- {
- fop->cbks.open(fop->req_frame, fop, fop->xl, cbk->op_ret,
- cbk->op_errno, cbk->fd, cbk->xdata);
- }
-
- return EC_STATE_END;
-
- case -EC_STATE_INIT:
- case -EC_STATE_DISPATCH:
- case -EC_STATE_PREPARE_ANSWER:
- case -EC_STATE_REPORT:
- GF_ASSERT(fop->error != 0);
-
- if (fop->cbks.open != NULL)
- {
- fop->cbks.open(fop->req_frame, fop, fop->xl, -1, fop->error,
- NULL, NULL);
- }
-
- return EC_STATE_END;
-
- default:
- gf_log(fop->xl->name, GF_LOG_ERROR, "Unhandled state %d for %s",
- state, ec_fop_name(fop->id));
-
- return EC_STATE_END;
- }
-}
-
-void ec_open(call_frame_t * frame, xlator_t * this, uintptr_t target,
- int32_t minimum, fop_open_cbk_t func, void * data, loc_t * loc,
- int32_t flags, fd_t * fd, dict_t * xdata)
-{
- ec_cbk_t callback = { .open = func };
- ec_fop_data_t * fop = NULL;
- int32_t error = EIO;
-
- gf_log("ec", GF_LOG_TRACE, "EC(OPEN) %p", frame);
-
- VALIDATE_OR_GOTO(this, out);
- GF_VALIDATE_OR_GOTO(this->name, frame, out);
- GF_VALIDATE_OR_GOTO(this->name, this->private, out);
-
- fop = ec_fop_data_allocate(frame, this, GF_FOP_OPEN, EC_FLAG_UPDATE_FD,
- target, minimum, ec_wind_open, ec_manager_open,
- callback, data);
- if (fop == NULL)
- {
- goto out;
- }
-
- fop->int32 = flags;
-
- if (loc != NULL)
- {
- if (loc_copy(&fop->loc[0], loc) != 0)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to copy a location.");
-
- goto out;
- }
- }
- if (fd != NULL)
- {
- fop->fd = fd_ref(fd);
- if (fop->fd == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
- "file descriptor.");
-
- goto out;
- }
- }
- if (xdata != NULL)
- {
- fop->xdata = dict_ref(xdata);
- if (fop->xdata == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
- "dictionary.");
-
- goto out;
- }
- }
-
- error = 0;
-
-out:
- if (fop != NULL)
- {
- ec_manager(fop, error);
- }
- else
- {
- func(frame, NULL, this, -1, EIO, NULL, NULL);
- }
-}
-
-/* FOP: readlink */
-
-int32_t ec_combine_readlink(ec_fop_data_t * fop, ec_cbk_data_t * dst,
- ec_cbk_data_t * src)
-{
- if (!ec_iatt_combine(dst->iatt, src->iatt, 1))
- {
- gf_log(fop->xl->name, GF_LOG_NOTICE, "Mismatching iatt in "
- "answers of 'GF_FOP_READLINK'");
-
- return 0;
- }
-
- return 1;
-}
-
-int32_t ec_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)
-{
- ec_fop_data_t * fop = NULL;
- int32_t idx = (int32_t)(uintptr_t)cookie;
-
- VALIDATE_OR_GOTO(this, out);
- GF_VALIDATE_OR_GOTO(this->name, frame, out);
- GF_VALIDATE_OR_GOTO(this->name, frame->local, out);
- GF_VALIDATE_OR_GOTO(this->name, this->private, out);
-
- fop = frame->local;
-
- ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx,
- frame, op_ret, op_errno);
-
- if (op_ret > 0)
- {
- ec_iatt_rebuild(fop->xl->private, buf, 1, 1);
- }
-
- if (!ec_dispatch_one_retry(fop, idx, op_ret, op_errno))
- {
- if (fop->cbks.readlink != NULL)
- {
- fop->cbks.readlink(fop->req_frame, fop, this, op_ret, op_errno,
- path, buf, xdata);
- }
- }
-
-out:
- if (fop != NULL)
- {
- ec_complete(fop);
- }
-
- return 0;
-}
-
-void ec_wind_readlink(ec_t * ec, ec_fop_data_t * fop, int32_t idx)
-{
- ec_trace("WIND", fop, "idx=%d", idx);
-
- STACK_WIND_COOKIE(fop->frame, ec_readlink_cbk, (void *)(uintptr_t)idx,
- ec->xl_list[idx], ec->xl_list[idx]->fops->readlink,
- &fop->loc[0], fop->size, fop->xdata);
-}
-
-int32_t ec_manager_readlink(ec_fop_data_t * fop, int32_t state)
-{
- switch (state)
- {
- case EC_STATE_INIT:
- case EC_STATE_DISPATCH:
- ec_dispatch_one(fop);
-
- return EC_STATE_REPORT;
-
- case -EC_STATE_INIT:
- case -EC_STATE_REPORT:
- if (fop->cbks.readlink != NULL)
- {
- fop->cbks.readlink(fop->req_frame, fop, fop->xl, -1,
- fop->error, NULL, NULL, NULL);
- }
-
- case EC_STATE_REPORT:
- return EC_STATE_END;
-
- default:
- gf_log(fop->xl->name, GF_LOG_ERROR, "Unhandled state %d for %s",
- state, ec_fop_name(fop->id));
-
- return EC_STATE_END;
- }
-}
-
-void ec_readlink(call_frame_t * frame, xlator_t * this, uintptr_t target,
- int32_t minimum, fop_readlink_cbk_t func, void * data,
- loc_t * loc, size_t size, dict_t * xdata)
-{
- ec_cbk_t callback = { .readlink = func };
- ec_fop_data_t * fop = NULL;
- int32_t error = EIO;
-
- gf_log("ec", GF_LOG_TRACE, "EC(READLINK) %p", frame);
-
- VALIDATE_OR_GOTO(this, out);
- GF_VALIDATE_OR_GOTO(this->name, frame, out);
- GF_VALIDATE_OR_GOTO(this->name, this->private, out);
-
- fop = ec_fop_data_allocate(frame, this, GF_FOP_READLINK, 0, target,
- minimum, ec_wind_readlink, ec_manager_readlink,
- callback, data);
- if (fop == NULL)
- {
- goto out;
- }
-
- fop->size = size;
-
- if (loc != NULL)
- {
- if (loc_copy(&fop->loc[0], loc) != 0)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to copy a location.");
-
- goto out;
- }
- }
- if (xdata != NULL)
- {
- fop->xdata = dict_ref(xdata);
- if (fop->xdata == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
- "dictionary.");
-
- goto out;
- }
- }
-
- error = 0;
-
-out:
- if (fop != NULL)
- {
- ec_manager(fop, error);
- }
- else
- {
- func(frame, NULL, this, -1, EIO, NULL, NULL, NULL);
- }
-}
-
-/* FOP: readv */
-
-int32_t ec_readv_rebuild(ec_t * ec, ec_fop_data_t * fop, ec_cbk_data_t * cbk)
-{
- ec_cbk_data_t * ans = NULL;
- struct iobref * iobref = NULL;
- struct iobuf * iobuf = NULL;
- uint8_t * buff = NULL, * ptr;
- size_t fsize = 0, size = 0, max = 0;
- int32_t i = 0;
-
- if (cbk->op_ret < 0)
- {
- goto out;
- }
-
- cbk->iatt[0].ia_size = fop->pre_size;
-
- if (cbk->op_ret > 0)
- {
- struct iovec vector[1];
- uint8_t * blocks[cbk->count];
- uint32_t values[cbk->count];
-
- fsize = cbk->op_ret;
- size = fsize * ec->fragments;
- buff = GF_MALLOC(size, gf_common_mt_char);
- if (buff == NULL)
- {
- goto out;
- }
- ptr = buff;
- for (i = 0, ans = cbk; ans != NULL; i++, ans = ans->next)
- {
- values[i] = ans->idx;
- blocks[i] = ptr;
- ptr += ec_iov_copy_to(ptr, ans->vector, ans->int32, 0, fsize);
- }
-
- iobref = iobref_new();
- if (iobref == NULL)
- {
- goto out;
- }
- iobuf = iobuf_get2(fop->xl->ctx->iobuf_pool, size);
- if (iobuf == NULL)
- {
- goto out;
- }
- if (iobref_add(iobref, iobuf) != 0)
- {
- goto out;
- }
-
- vector[0].iov_base = iobuf->ptr;
- vector[0].iov_len = ec_method_decode(fsize, ec->fragments, values,
- blocks, iobuf->ptr);
-
- iobuf_unref(iobuf);
-
- GF_FREE(buff);
- buff = NULL;
-
- vector[0].iov_base += fop->head;
- vector[0].iov_len -= fop->head;
-
- max = fop->offset * ec->fragments + size;
- if (max > cbk->iatt[0].ia_size)
- {
- max = cbk->iatt[0].ia_size;
- }
- max -= fop->offset * ec->fragments + fop->head;
- if (max > fop->user_size)
- {
- max = fop->user_size;
- }
- size -= fop->head;
- if (size > max)
- {
- vector[0].iov_len -= size - max;
- size = max;
- }
-
- cbk->op_ret = size;
- cbk->int32 = 1;
-
- iobref_unref(cbk->buffers);
- cbk->buffers = iobref;
-
- GF_FREE(cbk->vector);
- cbk->vector = iov_dup(vector, 1);
- if (cbk->vector == NULL)
- {
- cbk->op_ret = -1;
- cbk->op_errno = EIO;
-
- return 0;
- }
- }
-
- return 1;
-
-out:
- if (iobuf != NULL)
- {
- iobuf_unref(iobuf);
- }
- if (iobref != NULL)
- {
- iobref_unref(iobref);
- }
- GF_FREE(buff);
-
- return 0;
-}
-
-int32_t ec_combine_readv(ec_fop_data_t * fop, ec_cbk_data_t * dst,
- ec_cbk_data_t * src)
-{
- if (!ec_vector_compare(dst->vector, dst->int32, src->vector, src->int32))
- {
- gf_log(fop->xl->name, GF_LOG_NOTICE, "Mismatching vector in "
- "answers of 'GF_FOP_READ'");
-
- return 0;
- }
-
- if (!ec_iatt_combine(dst->iatt, src->iatt, 1))
- {
- gf_log(fop->xl->name, GF_LOG_NOTICE, "Mismatching iatt in "
- "answers of 'GF_FOP_READ'");
-
- return 0;
- }
-
- return 1;
-}
-
-int32_t ec_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)
-{
- ec_fop_data_t * fop = NULL;
- ec_cbk_data_t * cbk = NULL;
- ec_t * ec = this->private;
- int32_t idx = (int32_t)(uintptr_t)cookie;
-
- VALIDATE_OR_GOTO(this, out);
- GF_VALIDATE_OR_GOTO(this->name, frame, out);
- GF_VALIDATE_OR_GOTO(this->name, frame->local, out);
- GF_VALIDATE_OR_GOTO(this->name, this->private, out);
-
- fop = frame->local;
-
- ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx,
- frame, op_ret, op_errno);
-
- cbk = ec_cbk_data_allocate(frame, this, fop, GF_FOP_READ, idx, op_ret,
- op_errno);
- if (cbk != NULL)
- {
- if (op_ret >= 0)
- {
- cbk->int32 = count;
-
- if (count > 0)
- {
- cbk->vector = iov_dup(vector, count);
- if (cbk->vector == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to duplicate a "
- "vector list.");
-
- goto out;
- }
- cbk->int32 = count;
- }
- if (stbuf != NULL)
- {
- cbk->iatt[0] = *stbuf;
- }
- if (iobref != NULL)
- {
- cbk->buffers = iobref_ref(iobref);
- if (cbk->buffers == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
- "buffer.");
-
- goto out;
- }
- }
- }
- if (xdata != NULL)
- {
- cbk->xdata = dict_ref(xdata);
- if (cbk->xdata == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
- "dictionary.");
-
- goto out;
- }
- }
-
- if ((op_ret > 0) && ((op_ret % ec->fragment_size) != 0))
- {
- cbk->op_ret = -1;
- cbk->op_errno = EIO;
- }
-
- ec_combine(cbk, ec_combine_readv);
- }
-
-out:
- if (fop != NULL)
- {
- ec_complete(fop);
- }
-
- return 0;
-}
-
-void ec_wind_readv(ec_t * ec, ec_fop_data_t * fop, int32_t idx)
-{
- ec_trace("WIND", fop, "idx=%d", idx);
-
- STACK_WIND_COOKIE(fop->frame, ec_readv_cbk, (void *)(uintptr_t)idx,
- ec->xl_list[idx], ec->xl_list[idx]->fops->readv, fop->fd,
- fop->size, fop->offset, fop->uint32, fop->xdata);
-}
-
-int32_t ec_manager_readv(ec_fop_data_t * fop, int32_t state)
-{
- ec_cbk_data_t * cbk;
-
- switch (state)
- {
- case EC_STATE_INIT:
- fop->user_size = fop->size;
- fop->head = ec_adjust_offset(fop->xl->private, &fop->offset, 1);
- fop->size = ec_adjust_size(fop->xl->private, fop->size + fop->head,
- 1);
-
- /* Fall through */
-
- case EC_STATE_LOCK:
- ec_lock_prepare_fd(fop, fop->fd, 0);
- ec_lock(fop);
-
- return EC_STATE_GET_SIZE_AND_VERSION;
-
- case EC_STATE_GET_SIZE_AND_VERSION:
- ec_get_size_version(fop);
-
- return EC_STATE_DISPATCH;
-
- case EC_STATE_DISPATCH:
- ec_dispatch_min(fop);
-
- return EC_STATE_PREPARE_ANSWER;
-
- case EC_STATE_PREPARE_ANSWER:
- cbk = fop->answer;
- if (cbk != NULL)
- {
- if (!ec_dict_combine(cbk, EC_COMBINE_XDATA))
- {
- if (cbk->op_ret >= 0)
- {
- cbk->op_ret = -1;
- cbk->op_errno = EIO;
- }
- }
- if (cbk->op_ret < 0)
- {
- ec_fop_set_error(fop, cbk->op_errno);
- }
- else
- {
- ec_iatt_rebuild(fop->xl->private, cbk->iatt, 1,
- cbk->count);
-
- if (!ec_readv_rebuild(fop->xl->private, fop, cbk))
- {
- ec_fop_set_error(fop, EIO);
- }
- }
- }
- else
- {
- ec_fop_set_error(fop, EIO);
- }
-
- return EC_STATE_REPORT;
-
- case EC_STATE_REPORT:
- cbk = fop->answer;
-
- GF_ASSERT(cbk != NULL);
-
- if (fop->cbks.readv != NULL)
- {
- fop->cbks.readv(fop->req_frame, fop, fop->xl, cbk->op_ret,
- cbk->op_errno, cbk->vector, cbk->int32,
- &cbk->iatt[0], cbk->buffers, cbk->xdata);
- }
-
- return EC_STATE_LOCK_REUSE;
-
- case -EC_STATE_INIT:
- case -EC_STATE_LOCK:
- case -EC_STATE_GET_SIZE_AND_VERSION:
- case -EC_STATE_DISPATCH:
- case -EC_STATE_PREPARE_ANSWER:
- case -EC_STATE_REPORT:
- GF_ASSERT(fop->error != 0);
-
- if (fop->cbks.readv != NULL)
- {
- fop->cbks.readv(fop->req_frame, fop, fop->xl, -1, fop->error,
- NULL, 0, NULL, NULL, NULL);
- }
-
- return EC_STATE_LOCK_REUSE;
-
- case -EC_STATE_LOCK_REUSE:
- case EC_STATE_LOCK_REUSE:
- ec_lock_reuse(fop);
-
- return EC_STATE_UNLOCK;
-
- case -EC_STATE_UNLOCK:
- case EC_STATE_UNLOCK:
- ec_unlock(fop);
-
- return EC_STATE_END;
-
- default:
- gf_log(fop->xl->name, GF_LOG_ERROR, "Unhandled state %d for %s",
- state, ec_fop_name(fop->id));
-
- return EC_STATE_END;
- }
-}
-
-void ec_readv(call_frame_t * frame, xlator_t * this, uintptr_t target,
- int32_t minimum, fop_readv_cbk_t func, void * data, fd_t * fd,
- size_t size, off_t offset, uint32_t flags, dict_t * xdata)
-{
- ec_cbk_t callback = { .readv = func };
- ec_fop_data_t * fop = NULL;
- int32_t error = EIO;
-
- gf_log("ec", GF_LOG_TRACE, "EC(READ) %p", frame);
-
- VALIDATE_OR_GOTO(this, out);
- GF_VALIDATE_OR_GOTO(this->name, frame, out);
- GF_VALIDATE_OR_GOTO(this->name, this->private, out);
-
- fop = ec_fop_data_allocate(frame, this, GF_FOP_READ, EC_FLAG_UPDATE_FD,
- target, minimum, ec_wind_readv,
- ec_manager_readv, callback, data);
- if (fop == NULL)
- {
- goto out;
- }
-
- fop->use_fd = 1;
-
- fop->size = size;
- fop->offset = offset;
- fop->uint32 = flags;
-
- if (fd != NULL)
- {
- fop->fd = fd_ref(fd);
- if (fop->fd == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
- "file descriptor.");
-
- goto out;
- }
- }
- if (xdata != NULL)
- {
- fop->xdata = dict_ref(xdata);
- if (fop->xdata == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
- "dictionary.");
-
- goto out;
- }
- }
-
- error = 0;
-
-out:
- if (fop != NULL)
- {
- ec_manager(fop, error);
- }
- else
- {
- func(frame, NULL, this, -1, EIO, NULL, 0, NULL, NULL, NULL);
- }
-}
-
-/* FOP: stat */
-
-int32_t ec_combine_stat(ec_fop_data_t * fop, ec_cbk_data_t * dst,
- ec_cbk_data_t * src)
-{
- if (!ec_iatt_combine(dst->iatt, src->iatt, 1))
- {
- gf_log(fop->xl->name, GF_LOG_NOTICE, "Mismatching iatt in "
- "answers of 'GF_FOP_STAT'");
-
- return 0;
- }
-
- return 1;
-}
-
-int32_t ec_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)
-{
- ec_fop_data_t * fop = NULL;
- ec_cbk_data_t * cbk = NULL;
- int32_t idx = (int32_t)(uintptr_t)cookie;
-
- VALIDATE_OR_GOTO(this, out);
- GF_VALIDATE_OR_GOTO(this->name, frame, out);
- GF_VALIDATE_OR_GOTO(this->name, frame->local, out);
- GF_VALIDATE_OR_GOTO(this->name, this->private, out);
-
- fop = frame->local;
-
- ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx,
- frame, op_ret, op_errno);
-
- cbk = ec_cbk_data_allocate(frame, this, fop, GF_FOP_STAT, idx, op_ret,
- op_errno);
- if (cbk != NULL)
- {
- if (op_ret >= 0)
- {
- if (buf != NULL)
- {
- cbk->iatt[0] = *buf;
- }
- }
- if (xdata != NULL)
- {
- cbk->xdata = dict_ref(xdata);
- if (cbk->xdata == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
- "dictionary.");
-
- goto out;
- }
- }
-
- ec_combine(cbk, ec_combine_stat);
- }
-
-out:
- if (fop != NULL)
- {
- ec_complete(fop);
- }
-
- return 0;
-}
-
-void ec_wind_stat(ec_t * ec, ec_fop_data_t * fop, int32_t idx)
-{
- ec_trace("WIND", fop, "idx=%d", idx);
-
- STACK_WIND_COOKIE(fop->frame, ec_stat_cbk, (void *)(uintptr_t)idx,
- ec->xl_list[idx], ec->xl_list[idx]->fops->stat,
- &fop->loc[0], fop->xdata);
-}
-
-int32_t ec_manager_stat(ec_fop_data_t * fop, int32_t state)
-{
- ec_cbk_data_t * cbk;
-
- switch (state)
- {
- case EC_STATE_INIT:
- case EC_STATE_LOCK:
- if (fop->fd == NULL)
- {
- ec_lock_prepare_inode(fop, &fop->loc[0], 0);
- }
- else
- {
- ec_lock_prepare_fd(fop, fop->fd, 0);
- }
- ec_lock(fop);
-
- return EC_STATE_GET_SIZE_AND_VERSION;
-
- case EC_STATE_GET_SIZE_AND_VERSION:
- ec_get_size_version(fop);
-
- return EC_STATE_DISPATCH;
-
- case EC_STATE_DISPATCH:
- ec_dispatch_all(fop);
-
- return EC_STATE_PREPARE_ANSWER;
-
- case EC_STATE_PREPARE_ANSWER:
- cbk = fop->answer;
- if (cbk != NULL)
- {
- if (!ec_dict_combine(cbk, EC_COMBINE_XDATA))
- {
- if (cbk->op_ret >= 0)
- {
- cbk->op_ret = -1;
- cbk->op_errno = EIO;
- }
- }
- if (cbk->op_ret < 0)
- {
- ec_fop_set_error(fop, cbk->op_errno);
- }
- else
- {
- ec_iatt_rebuild(fop->xl->private, cbk->iatt, 1,
- cbk->count);
-
- cbk->iatt[0].ia_size = fop->pre_size;
- }
- }
- else
- {
- ec_fop_set_error(fop, EIO);
- }
-
- return EC_STATE_REPORT;
-
- case EC_STATE_REPORT:
- cbk = fop->answer;
-
- GF_ASSERT(cbk != NULL);
-
- if (fop->id == GF_FOP_STAT)
- {
- if (fop->cbks.stat != NULL)
- {
- fop->cbks.stat(fop->req_frame, fop, fop->xl, cbk->op_ret,
- cbk->op_errno, &cbk->iatt[0], cbk->xdata);
- }
- }
- else
- {
- if (fop->cbks.fstat != NULL)
- {
- fop->cbks.fstat(fop->req_frame, fop, fop->xl, cbk->op_ret,
- cbk->op_errno, &cbk->iatt[0], cbk->xdata);
- }
- }
-
- return EC_STATE_LOCK_REUSE;
-
- case -EC_STATE_INIT:
- case -EC_STATE_LOCK:
- case -EC_STATE_GET_SIZE_AND_VERSION:
- case -EC_STATE_DISPATCH:
- case -EC_STATE_PREPARE_ANSWER:
- case -EC_STATE_REPORT:
- GF_ASSERT(fop->error != 0);
-
- if (fop->id == GF_FOP_STAT)
- {
- if (fop->cbks.stat != NULL)
- {
- fop->cbks.stat(fop->req_frame, fop, fop->xl, -1,
- fop->error, NULL, NULL);
- }
- }
- else
- {
- if (fop->cbks.fstat != NULL)
- {
- fop->cbks.fstat(fop->req_frame, fop, fop->xl, -1,
- fop->error, NULL, NULL);
- }
- }
-
- return EC_STATE_LOCK_REUSE;
-
- case -EC_STATE_LOCK_REUSE:
- case EC_STATE_LOCK_REUSE:
- ec_lock_reuse(fop);
-
- return EC_STATE_UNLOCK;
-
- case -EC_STATE_UNLOCK:
- case EC_STATE_UNLOCK:
- ec_unlock(fop);
-
- return EC_STATE_END;
-
- default:
- gf_log(fop->xl->name, GF_LOG_ERROR, "Unhandled state %d for %s",
- state, ec_fop_name(fop->id));
-
- return EC_STATE_END;
- }
-}
-
-void ec_stat(call_frame_t * frame, xlator_t * this, uintptr_t target,
- int32_t minimum, fop_stat_cbk_t func, void * data, loc_t * loc,
- dict_t * xdata)
-{
- ec_cbk_t callback = { .stat = func };
- ec_fop_data_t * fop = NULL;
- int32_t error = EIO;
-
- gf_log("ec", GF_LOG_TRACE, "EC(STAT) %p", frame);
-
- VALIDATE_OR_GOTO(this, out);
- GF_VALIDATE_OR_GOTO(this->name, frame, out);
- GF_VALIDATE_OR_GOTO(this->name, this->private, out);
-
- fop = ec_fop_data_allocate(frame, this, GF_FOP_STAT,
- EC_FLAG_UPDATE_LOC_INODE, target, minimum,
- ec_wind_stat, ec_manager_stat, callback, data);
- if (fop == NULL)
- {
- goto out;
- }
-
- if (loc != NULL)
- {
- if (loc_copy(&fop->loc[0], loc) != 0)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to copy a location.");
-
- goto out;
- }
- }
- if (xdata != NULL)
- {
- fop->xdata = dict_ref(xdata);
- if (fop->xdata == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
- "dictionary.");
-
- goto out;
- }
- }
-
- error = 0;
-
-out:
- if (fop != NULL)
- {
- ec_manager(fop, error);
- }
- else
- {
- func(frame, NULL, this, -1, EIO, NULL, NULL);
- }
-}
-
-/* FOP: fstat */
-
-int32_t ec_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)
-{
- ec_fop_data_t * fop = NULL;
- ec_cbk_data_t * cbk = NULL;
- int32_t idx = (int32_t)(uintptr_t)cookie;
-
- VALIDATE_OR_GOTO(this, out);
- GF_VALIDATE_OR_GOTO(this->name, frame, out);
- GF_VALIDATE_OR_GOTO(this->name, frame->local, out);
- GF_VALIDATE_OR_GOTO(this->name, this->private, out);
-
- fop = frame->local;
-
- ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx,
- frame, op_ret, op_errno);
-
- cbk = ec_cbk_data_allocate(frame, this, fop, GF_FOP_FSTAT, idx, op_ret,
- op_errno);
- if (cbk != NULL)
- {
- if (op_ret >= 0)
- {
- if (buf != NULL)
- {
- cbk->iatt[0] = *buf;
- }
- }
- if (xdata != NULL)
- {
- cbk->xdata = dict_ref(xdata);
- if (cbk->xdata == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
- "dictionary.");
-
- goto out;
- }
- }
-
- ec_combine(cbk, ec_combine_stat);
- }
-
-out:
- if (fop != NULL)
- {
- ec_complete(fop);
- }
-
- return 0;
-}
-
-void ec_wind_fstat(ec_t * ec, ec_fop_data_t * fop, int32_t idx)
-{
- ec_trace("WIND", fop, "idx=%d", idx);
-
- STACK_WIND_COOKIE(fop->frame, ec_fstat_cbk, (void *)(uintptr_t)idx,
- ec->xl_list[idx], ec->xl_list[idx]->fops->fstat, fop->fd,
- fop->xdata);
-}
-
-void ec_fstat(call_frame_t * frame, xlator_t * this, uintptr_t target,
- int32_t minimum, fop_fstat_cbk_t func, void * data, fd_t * fd,
- dict_t * xdata)
-{
- ec_cbk_t callback = { .fstat = func };
- ec_fop_data_t * fop = NULL;
- int32_t error = EIO;
-
- gf_log("ec", GF_LOG_TRACE, "EC(FSTAT) %p", frame);
-
- VALIDATE_OR_GOTO(this, out);
- GF_VALIDATE_OR_GOTO(this->name, frame, out);
- GF_VALIDATE_OR_GOTO(this->name, this->private, out);
-
- fop = ec_fop_data_allocate(frame, this, GF_FOP_FSTAT,
- EC_FLAG_UPDATE_FD_INODE, target, minimum,
- ec_wind_fstat, ec_manager_stat, callback, data);
- if (fop == NULL)
- {
- goto out;
- }
-
- fop->use_fd = 1;
-
- if (fd != NULL)
- {
- fop->fd = fd_ref(fd);
- if (fop->fd == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
- "file descriptor.");
-
- goto out;
- }
- }
- if (xdata != NULL)
- {
- fop->xdata = dict_ref(xdata);
- if (fop->xdata == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
- "dictionary.");
-
- goto out;
- }
- }
-
- error = 0;
-
-out:
- if (fop != NULL)
- {
- ec_manager(fop, error);
- }
- else
- {
- func(frame, NULL, this, -1, EIO, NULL, NULL);
- }
-}
diff --git a/xlators/cluster/ec/src/ec-inode-write.c b/xlators/cluster/ec/src/ec-inode-write.c
deleted file mode 100644
index 140d59f5f20..00000000000
--- a/xlators/cluster/ec/src/ec-inode-write.c
+++ /dev/null
@@ -1,2225 +0,0 @@
-/*
- Copyright (c) 2012-2014 DataLab, s.l. <http://www.datalab.es>
- 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 "xlator.h"
-#include "defaults.h"
-
-#include "ec-helpers.h"
-#include "ec-common.h"
-#include "ec-combine.h"
-#include "ec-method.h"
-#include "ec-fops.h"
-
-/* FOP: removexattr */
-
-int32_t ec_removexattr_cbk(call_frame_t * frame, void * cookie,
- xlator_t * this, int32_t op_ret, int32_t op_errno,
- dict_t * xdata)
-{
- ec_fop_data_t * fop = NULL;
- ec_cbk_data_t * cbk = NULL;
- int32_t idx = (int32_t)(uintptr_t)cookie;
-
- VALIDATE_OR_GOTO(this, out);
- GF_VALIDATE_OR_GOTO(this->name, frame, out);
- GF_VALIDATE_OR_GOTO(this->name, frame->local, out);
- GF_VALIDATE_OR_GOTO(this->name, this->private, out);
-
- fop = frame->local;
-
- ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx,
- frame, op_ret, op_errno);
-
- cbk = ec_cbk_data_allocate(frame, this, fop, GF_FOP_REMOVEXATTR, idx,
- op_ret, op_errno);
- if (cbk != NULL)
- {
- if (xdata != NULL)
- {
- cbk->xdata = dict_ref(xdata);
- if (cbk->xdata == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
- "dictionary.");
-
- goto out;
- }
- }
-
- ec_combine(cbk, NULL);
- }
-
-out:
- if (fop != NULL)
- {
- ec_complete(fop);
- }
-
- return 0;
-}
-
-void ec_wind_removexattr(ec_t * ec, ec_fop_data_t * fop, int32_t idx)
-{
- ec_trace("WIND", fop, "idx=%d", idx);
-
- STACK_WIND_COOKIE(fop->frame, ec_removexattr_cbk, (void *)(uintptr_t)idx,
- ec->xl_list[idx], ec->xl_list[idx]->fops->removexattr,
- &fop->loc[0], fop->str[0], fop->xdata);
-}
-
-int32_t ec_manager_removexattr(ec_fop_data_t * fop, int32_t state)
-{
- ec_cbk_data_t * cbk;
-
- switch (state)
- {
- case EC_STATE_INIT:
- case EC_STATE_LOCK:
- if (fop->fd == NULL)
- {
- ec_lock_prepare_inode(fop, &fop->loc[0], 1);
- }
- else
- {
- ec_lock_prepare_fd(fop, fop->fd, 1);
- }
- ec_lock(fop);
-
- return EC_STATE_DISPATCH;
-
- case EC_STATE_DISPATCH:
- ec_dispatch_all(fop);
-
- return EC_STATE_PREPARE_ANSWER;
-
- case EC_STATE_PREPARE_ANSWER:
- cbk = fop->answer;
- if (cbk != NULL)
- {
- if (!ec_dict_combine(cbk, EC_COMBINE_XDATA))
- {
- if (cbk->op_ret >= 0)
- {
- cbk->op_ret = -1;
- cbk->op_errno = EIO;
- }
- }
- if (cbk->op_ret < 0)
- {
- ec_fop_set_error(fop, cbk->op_errno);
- }
- }
- else
- {
- ec_fop_set_error(fop, EIO);
- }
-
- return EC_STATE_REPORT;
-
- case EC_STATE_REPORT:
- cbk = fop->answer;
-
- GF_ASSERT(cbk != NULL);
-
- if (fop->id == GF_FOP_REMOVEXATTR)
- {
- if (fop->cbks.removexattr != NULL)
- {
- fop->cbks.removexattr(fop->req_frame, fop, fop->xl,
- cbk->op_ret, cbk->op_errno,
- cbk->xdata);
- }
- }
- else
- {
- if (fop->cbks.fremovexattr != NULL)
- {
- fop->cbks.fremovexattr(fop->req_frame, fop, fop->xl,
- cbk->op_ret, cbk->op_errno,
- cbk->xdata);
- }
- }
-
- return EC_STATE_LOCK_REUSE;
-
- case -EC_STATE_INIT:
- case -EC_STATE_LOCK:
- case -EC_STATE_DISPATCH:
- case -EC_STATE_PREPARE_ANSWER:
- case -EC_STATE_REPORT:
- GF_ASSERT(fop->error != 0);
-
- if (fop->id == GF_FOP_REMOVEXATTR)
- {
- if (fop->cbks.removexattr != NULL)
- {
- fop->cbks.removexattr(fop->req_frame, fop, fop->xl, -1,
- fop->error, NULL);
- }
- }
- else
- {
- if (fop->cbks.fremovexattr != NULL)
- {
- fop->cbks.fremovexattr(fop->req_frame, fop, fop->xl, -1,
- fop->error, NULL);
- }
- }
-
- return EC_STATE_LOCK_REUSE;
-
- case -EC_STATE_LOCK_REUSE:
- case EC_STATE_LOCK_REUSE:
- ec_lock_reuse(fop);
-
- return EC_STATE_UNLOCK;
-
- case -EC_STATE_UNLOCK:
- case EC_STATE_UNLOCK:
- ec_unlock(fop);
-
- return EC_STATE_END;
-
- default:
- gf_log(fop->xl->name, GF_LOG_ERROR, "Unhandled state %d for %s",
- state, ec_fop_name(fop->id));
-
- return EC_STATE_END;
- }
-}
-
-void
-ec_removexattr (call_frame_t *frame, xlator_t *this, uintptr_t target,
- int32_t minimum, fop_removexattr_cbk_t func, void *data,
- loc_t *loc, const char *name, dict_t *xdata)
-{
- ec_cbk_t callback = { .removexattr = func };
- ec_fop_data_t * fop = NULL;
- int32_t error = EIO;
-
- gf_log("ec", GF_LOG_TRACE, "EC(REMOVEXATTR) %p", frame);
-
- VALIDATE_OR_GOTO (this, out);
- GF_VALIDATE_OR_GOTO (this->name, frame, out);
- GF_VALIDATE_OR_GOTO (this->name, this->private, out);
-
- fop = ec_fop_data_allocate(frame, this, GF_FOP_REMOVEXATTR,
- EC_FLAG_UPDATE_LOC_INODE, target, minimum,
- ec_wind_removexattr, ec_manager_removexattr,
- callback, data);
- if (fop == NULL)
- {
- goto out;
- }
-
- if (loc != NULL)
- {
- if (loc_copy(&fop->loc[0], loc) != 0)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to copy a location.");
-
- goto out;
- }
- }
- if (name != NULL)
- {
- fop->str[0] = gf_strdup(name);
- if (fop->str[0] == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to duplicate a string.");
-
- goto out;
- }
- }
- if (xdata != NULL)
- {
- fop->xdata = dict_ref(xdata);
- if (fop->xdata == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
- "dictionary.");
-
- goto out;
- }
- }
-
- error = 0;
-
-out:
- if (fop != NULL) {
- ec_manager (fop, error);
- } else {
- func (frame, NULL, this, -1, error, NULL);
- }
-}
-
-/* FOP: fremovexattr */
-
-int32_t ec_fremovexattr_cbk(call_frame_t * frame, void * cookie,
- xlator_t * this, int32_t op_ret, int32_t op_errno,
- dict_t * xdata)
-{
- ec_fop_data_t * fop = NULL;
- ec_cbk_data_t * cbk = NULL;
- int32_t idx = (int32_t)(uintptr_t)cookie;
-
- VALIDATE_OR_GOTO(this, out);
- GF_VALIDATE_OR_GOTO(this->name, frame, out);
- GF_VALIDATE_OR_GOTO(this->name, frame->local, out);
- GF_VALIDATE_OR_GOTO(this->name, this->private, out);
-
- fop = frame->local;
-
- ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx,
- frame, op_ret, op_errno);
-
- cbk = ec_cbk_data_allocate(frame, this, fop, GF_FOP_FREMOVEXATTR, idx,
- op_ret, op_errno);
- if (cbk != NULL)
- {
- if (xdata != NULL)
- {
- cbk->xdata = dict_ref(xdata);
- if (cbk->xdata == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
- "dictionary.");
-
- goto out;
- }
- }
-
- ec_combine(cbk, NULL);
- }
-
-out:
- if (fop != NULL)
- {
- ec_complete(fop);
- }
-
- return 0;
-}
-
-void ec_wind_fremovexattr(ec_t * ec, ec_fop_data_t * fop, int32_t idx)
-{
- ec_trace("WIND", fop, "idx=%d", idx);
-
- STACK_WIND_COOKIE(fop->frame, ec_fremovexattr_cbk, (void *)(uintptr_t)idx,
- ec->xl_list[idx], ec->xl_list[idx]->fops->fremovexattr,
- fop->fd, fop->str[0], fop->xdata);
-}
-
-void
-ec_fremovexattr (call_frame_t *frame, xlator_t *this, uintptr_t target,
- int32_t minimum, fop_fremovexattr_cbk_t func, void *data,
- fd_t *fd, const char *name, dict_t *xdata)
-{
- ec_cbk_t callback = { .fremovexattr = func };
- ec_fop_data_t * fop = NULL;
- int32_t error = EIO;
-
- gf_log("ec", GF_LOG_TRACE, "EC(FREMOVEXATTR) %p", frame);
-
- VALIDATE_OR_GOTO (this, out);
- GF_VALIDATE_OR_GOTO (this->name, frame, out);
- GF_VALIDATE_OR_GOTO (this->name, this->private, out);
-
- fop = ec_fop_data_allocate(frame, this, GF_FOP_FREMOVEXATTR,
- EC_FLAG_UPDATE_FD_INODE, target, minimum,
- ec_wind_fremovexattr, ec_manager_removexattr,
- callback, data);
- if (fop == NULL)
- {
- goto out;
- }
-
- fop->use_fd = 1;
-
- if (fd != NULL)
- {
- fop->fd = fd_ref(fd);
- if (fop->fd == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
- "file descriptor.");
-
- goto out;
- }
- }
- if (name != NULL)
- {
- fop->str[0] = gf_strdup(name);
- if (fop->str[0] == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to duplicate a string.");
-
- goto out;
- }
- }
- if (xdata != NULL)
- {
- fop->xdata = dict_ref(xdata);
- if (fop->xdata == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
- "dictionary.");
-
- goto out;
- }
- }
-
- error = 0;
-
-out:
- if (fop != NULL) {
- ec_manager (fop, error);
- } else {
- func (frame, NULL, this, -1, error, NULL);
- }
-}
-
-/* FOP: setattr */
-
-int32_t ec_combine_setattr(ec_fop_data_t * fop, ec_cbk_data_t * dst,
- ec_cbk_data_t * src)
-{
- if (!ec_iatt_combine(dst->iatt, src->iatt, 2))
- {
- gf_log(fop->xl->name, GF_LOG_NOTICE, "Mismatching iatt in "
- "answers of 'GF_FOP_SETATTR'");
-
- return 0;
- }
-
- return 1;
-}
-
-int32_t ec_setattr_cbk(call_frame_t * frame, void * cookie, xlator_t * this,
- int32_t op_ret, int32_t op_errno,
- struct iatt * preop_stbuf, struct iatt * postop_stbuf,
- dict_t * xdata)
-{
- ec_fop_data_t * fop = NULL;
- ec_cbk_data_t * cbk = NULL;
- int32_t idx = (int32_t)(uintptr_t)cookie;
-
- VALIDATE_OR_GOTO(this, out);
- GF_VALIDATE_OR_GOTO(this->name, frame, out);
- GF_VALIDATE_OR_GOTO(this->name, frame->local, out);
- GF_VALIDATE_OR_GOTO(this->name, this->private, out);
-
- fop = frame->local;
-
- ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx,
- frame, op_ret, op_errno);
-
- cbk = ec_cbk_data_allocate(frame, this, fop, GF_FOP_SETATTR, idx, op_ret,
- op_errno);
- if (cbk != NULL)
- {
- if (op_ret >= 0)
- {
- if (preop_stbuf != NULL)
- {
- cbk->iatt[0] = *preop_stbuf;
- }
- if (postop_stbuf != NULL)
- {
- cbk->iatt[1] = *postop_stbuf;
- }
- }
- if (xdata != NULL)
- {
- cbk->xdata = dict_ref(xdata);
- if (cbk->xdata == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
- "dictionary.");
-
- goto out;
- }
- }
-
- ec_combine(cbk, ec_combine_setattr);
- }
-
-out:
- if (fop != NULL)
- {
- ec_complete(fop);
- }
-
- return 0;
-}
-
-void ec_wind_setattr(ec_t * ec, ec_fop_data_t * fop, int32_t idx)
-{
- ec_trace("WIND", fop, "idx=%d", idx);
-
- STACK_WIND_COOKIE(fop->frame, ec_setattr_cbk, (void *)(uintptr_t)idx,
- ec->xl_list[idx], ec->xl_list[idx]->fops->setattr,
- &fop->loc[0], &fop->iatt, fop->int32, fop->xdata);
-}
-
-int32_t ec_manager_setattr(ec_fop_data_t * fop, int32_t state)
-{
- ec_cbk_data_t * cbk;
-
- switch (state)
- {
- case EC_STATE_INIT:
- case EC_STATE_LOCK:
- if (fop->fd == NULL)
- {
- ec_lock_prepare_inode(fop, &fop->loc[0], 1);
- }
- else
- {
- ec_lock_prepare_fd(fop, fop->fd, 1);
- }
- ec_lock(fop);
-
- return EC_STATE_GET_SIZE_AND_VERSION;
-
- case EC_STATE_GET_SIZE_AND_VERSION:
- ec_get_size_version(fop);
-
- return EC_STATE_DISPATCH;
-
- case EC_STATE_DISPATCH:
- ec_dispatch_all(fop);
-
- return EC_STATE_PREPARE_ANSWER;
-
- case EC_STATE_PREPARE_ANSWER:
- cbk = fop->answer;
- if (cbk != NULL)
- {
- if (!ec_dict_combine(cbk, EC_COMBINE_XDATA))
- {
- if (cbk->op_ret >= 0)
- {
- cbk->op_ret = -1;
- cbk->op_errno = EIO;
- }
- }
- if (cbk->op_ret < 0)
- {
- ec_fop_set_error(fop, cbk->op_errno);
- }
- else
- {
- ec_iatt_rebuild(fop->xl->private, cbk->iatt, 2,
- cbk->count);
-
- cbk->iatt[0].ia_size = fop->pre_size;
- cbk->iatt[1].ia_size = fop->pre_size;
- }
- }
- else
- {
- ec_fop_set_error(fop, EIO);
- }
-
- return EC_STATE_REPORT;
-
- case EC_STATE_REPORT:
- cbk = fop->answer;
-
- GF_ASSERT(cbk != NULL);
-
- if (fop->id == GF_FOP_SETATTR)
- {
- if (fop->cbks.setattr != NULL)
- {
- fop->cbks.setattr(fop->req_frame, fop, fop->xl,
- cbk->op_ret, cbk->op_errno,
- &cbk->iatt[0], &cbk->iatt[1],
- cbk->xdata);
- }
- }
- else
- {
- if (fop->cbks.fsetattr != NULL)
- {
- fop->cbks.fsetattr(fop->req_frame, fop, fop->xl,
- cbk->op_ret, cbk->op_errno,
- &cbk->iatt[0], &cbk->iatt[1],
- cbk->xdata);
- }
- }
-
- return EC_STATE_LOCK_REUSE;
-
- case -EC_STATE_INIT:
- case -EC_STATE_LOCK:
- case -EC_STATE_GET_SIZE_AND_VERSION:
- case -EC_STATE_DISPATCH:
- case -EC_STATE_PREPARE_ANSWER:
- case -EC_STATE_REPORT:
- GF_ASSERT(fop->error != 0);
-
- if (fop->id == GF_FOP_SETATTR)
- {
- if (fop->cbks.setattr != NULL)
- {
- fop->cbks.setattr(fop->req_frame, fop, fop->xl, -1,
- fop->error, NULL, NULL, NULL);
- }
- }
- else
- {
- if (fop->cbks.fsetattr != NULL)
- {
- fop->cbks.fsetattr(fop->req_frame, fop, fop->xl, -1,
- fop->error, NULL, NULL, NULL);
- }
- }
-
- return EC_STATE_LOCK_REUSE;
-
- case -EC_STATE_LOCK_REUSE:
- case EC_STATE_LOCK_REUSE:
- ec_lock_reuse(fop);
-
- return EC_STATE_UNLOCK;
-
- case -EC_STATE_UNLOCK:
- case EC_STATE_UNLOCK:
- ec_unlock(fop);
-
- return EC_STATE_END;
-
- default:
- gf_log(fop->xl->name, GF_LOG_ERROR, "Unhandled state %d for %s",
- state, ec_fop_name(fop->id));
-
- return EC_STATE_END;
- }
-}
-
-void ec_setattr(call_frame_t * frame, xlator_t * this, uintptr_t target,
- int32_t minimum, fop_setattr_cbk_t func, void * data,
- loc_t * loc, struct iatt * stbuf, int32_t valid,
- dict_t * xdata)
-{
- ec_cbk_t callback = { .setattr = func };
- ec_fop_data_t * fop = NULL;
- int32_t error = EIO;
-
- gf_log("ec", GF_LOG_TRACE, "EC(SETATTR) %p", frame);
-
- VALIDATE_OR_GOTO(this, out);
- GF_VALIDATE_OR_GOTO(this->name, frame, out);
- GF_VALIDATE_OR_GOTO(this->name, this->private, out);
-
- fop = ec_fop_data_allocate(frame, this, GF_FOP_SETATTR,
- EC_FLAG_UPDATE_LOC_INODE, target, minimum,
- ec_wind_setattr, ec_manager_setattr, callback,
- data);
- if (fop == NULL)
- {
- goto out;
- }
-
- fop->int32 = valid;
-
- if (loc != NULL)
- {
- if (loc_copy(&fop->loc[0], loc) != 0)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to copy a location.");
-
- goto out;
- }
- }
- if (stbuf != NULL)
- {
- fop->iatt = *stbuf;
- }
- if (xdata != NULL)
- {
- fop->xdata = dict_ref(xdata);
- if (fop->xdata == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
- "dictionary.");
-
- goto out;
- }
- }
-
- error = 0;
-
-out:
- if (fop != NULL)
- {
- ec_manager(fop, error);
- }
- else
- {
- func(frame, NULL, this, -1, EIO, NULL, NULL, NULL);
- }
-}
-
-/* FOP: fsetattr */
-
-int32_t ec_fsetattr_cbk(call_frame_t * frame, void * cookie, xlator_t * this,
- int32_t op_ret, int32_t op_errno,
- struct iatt * preop_stbuf, struct iatt * postop_stbuf,
- dict_t * xdata)
-{
- ec_fop_data_t * fop = NULL;
- ec_cbk_data_t * cbk = NULL;
- int32_t idx = (int32_t)(uintptr_t)cookie;
-
- VALIDATE_OR_GOTO(this, out);
- GF_VALIDATE_OR_GOTO(this->name, frame, out);
- GF_VALIDATE_OR_GOTO(this->name, frame->local, out);
- GF_VALIDATE_OR_GOTO(this->name, this->private, out);
-
- fop = frame->local;
-
- ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx,
- frame, op_ret, op_errno);
-
- cbk = ec_cbk_data_allocate(frame, this, fop, GF_FOP_FSETATTR, idx, op_ret,
- op_errno);
- if (cbk != NULL)
- {
- if (op_ret >= 0)
- {
- if (preop_stbuf != NULL)
- {
- cbk->iatt[0] = *preop_stbuf;
- }
- if (postop_stbuf != NULL)
- {
- cbk->iatt[1] = *postop_stbuf;
- }
- }
- if (xdata != NULL)
- {
- cbk->xdata = dict_ref(xdata);
- if (cbk->xdata == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
- "dictionary.");
-
- goto out;
- }
- }
-
- ec_combine(cbk, ec_combine_setattr);
- }
-
-out:
- if (fop != NULL)
- {
- ec_complete(fop);
- }
-
- return 0;
-}
-
-void ec_wind_fsetattr(ec_t * ec, ec_fop_data_t * fop, int32_t idx)
-{
- ec_trace("WIND", fop, "idx=%d", idx);
-
- STACK_WIND_COOKIE(fop->frame, ec_fsetattr_cbk, (void *)(uintptr_t)idx,
- ec->xl_list[idx], ec->xl_list[idx]->fops->fsetattr,
- fop->fd, &fop->iatt, fop->int32, fop->xdata);
-}
-
-void ec_fsetattr(call_frame_t * frame, xlator_t * this, uintptr_t target,
- int32_t minimum, fop_fsetattr_cbk_t func, void * data,
- fd_t * fd, struct iatt * stbuf, int32_t valid, dict_t * xdata)
-{
- ec_cbk_t callback = { .fsetattr = func };
- ec_fop_data_t * fop = NULL;
- int32_t error = EIO;
-
- gf_log("ec", GF_LOG_TRACE, "EC(FSETATTR) %p", frame);
-
- VALIDATE_OR_GOTO(this, out);
- GF_VALIDATE_OR_GOTO(this->name, frame, out);
- GF_VALIDATE_OR_GOTO(this->name, this->private, out);
-
- fop = ec_fop_data_allocate(frame, this, GF_FOP_FSETATTR,
- EC_FLAG_UPDATE_FD_INODE, target, minimum,
- ec_wind_fsetattr, ec_manager_setattr, callback,
- data);
- if (fop == NULL)
- {
- goto out;
- }
-
- fop->use_fd = 1;
-
- fop->int32 = valid;
-
- if (fd != NULL)
- {
- fop->fd = fd_ref(fd);
- if (fop->fd == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
- "file descriptor.");
-
- goto out;
- }
- }
- if (stbuf != NULL)
- {
- fop->iatt = *stbuf;
- }
- if (xdata != NULL)
- {
- fop->xdata = dict_ref(xdata);
- if (fop->xdata == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
- "dictionary.");
-
- goto out;
- }
- }
-
- error = 0;
-
-out:
- if (fop != NULL)
- {
- ec_manager(fop, error);
- }
- else
- {
- func(frame, NULL, this, -1, EIO, NULL, NULL, NULL);
- }
-}
-
-/* FOP: setxattr */
-
-int32_t ec_setxattr_cbk(call_frame_t * frame, void * cookie, xlator_t * this,
- int32_t op_ret, int32_t op_errno, dict_t * xdata)
-{
- ec_fop_data_t * fop = NULL;
- ec_cbk_data_t * cbk = NULL;
- int32_t idx = (int32_t)(uintptr_t)cookie;
-
- VALIDATE_OR_GOTO(this, out);
- GF_VALIDATE_OR_GOTO(this->name, frame, out);
- GF_VALIDATE_OR_GOTO(this->name, frame->local, out);
- GF_VALIDATE_OR_GOTO(this->name, this->private, out);
-
- fop = frame->local;
-
- ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx,
- frame, op_ret, op_errno);
-
- cbk = ec_cbk_data_allocate(frame, this, fop, GF_FOP_SETXATTR, idx, op_ret,
- op_errno);
- if (cbk != NULL)
- {
- if (xdata != NULL)
- {
- cbk->xdata = dict_ref(xdata);
- if (cbk->xdata == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
- "dictionary.");
-
- goto out;
- }
- }
-
- ec_combine(cbk, NULL);
- }
-
-out:
- if (fop != NULL)
- {
- ec_complete(fop);
- }
-
- return 0;
-}
-
-void ec_wind_setxattr(ec_t * ec, ec_fop_data_t * fop, int32_t idx)
-{
- ec_trace("WIND", fop, "idx=%d", idx);
-
- STACK_WIND_COOKIE(fop->frame, ec_setxattr_cbk, (void *)(uintptr_t)idx,
- ec->xl_list[idx], ec->xl_list[idx]->fops->setxattr,
- &fop->loc[0], fop->dict, fop->int32, fop->xdata);
-}
-
-int32_t ec_manager_setxattr(ec_fop_data_t * fop, int32_t state)
-{
- ec_cbk_data_t * cbk;
-
- switch (state)
- {
- case EC_STATE_INIT:
- case EC_STATE_LOCK:
- if (fop->fd == NULL)
- {
- ec_lock_prepare_inode(fop, &fop->loc[0], 1);
- }
- else
- {
- ec_lock_prepare_fd(fop, fop->fd, 1);
- }
- ec_lock(fop);
-
- return EC_STATE_DISPATCH;
-
- case EC_STATE_DISPATCH:
- ec_dispatch_all(fop);
-
- return EC_STATE_PREPARE_ANSWER;
-
- case EC_STATE_PREPARE_ANSWER:
- cbk = fop->answer;
- if (cbk != NULL)
- {
- if (!ec_dict_combine(cbk, EC_COMBINE_XDATA))
- {
- if (cbk->op_ret >= 0)
- {
- cbk->op_ret = -1;
- cbk->op_errno = EIO;
- }
- }
- if (cbk->op_ret < 0)
- {
- ec_fop_set_error(fop, cbk->op_errno);
- }
- }
- else
- {
- ec_fop_set_error(fop, EIO);
- }
-
- return EC_STATE_REPORT;
-
- case EC_STATE_REPORT:
- cbk = fop->answer;
-
- GF_ASSERT(cbk != NULL);
-
- if (fop->id == GF_FOP_SETXATTR)
- {
- if (fop->cbks.setxattr != NULL)
- {
- fop->cbks.setxattr(fop->req_frame, fop, fop->xl,
- cbk->op_ret, cbk->op_errno, cbk->xdata);
- }
- }
- else
- {
- if (fop->cbks.fsetxattr != NULL)
- {
- fop->cbks.fsetxattr(fop->req_frame, fop, fop->xl,
- cbk->op_ret, cbk->op_errno,
- cbk->xdata);
- }
- }
-
- return EC_STATE_LOCK_REUSE;
-
- case -EC_STATE_INIT:
- case -EC_STATE_LOCK:
- case -EC_STATE_DISPATCH:
- case -EC_STATE_PREPARE_ANSWER:
- case -EC_STATE_REPORT:
- GF_ASSERT(fop->error != 0);
-
- if (fop->id == GF_FOP_SETXATTR)
- {
- if (fop->cbks.setxattr != NULL)
- {
- fop->cbks.setxattr(fop->req_frame, fop, fop->xl, -1,
- fop->error, NULL);
- }
- }
- else
- {
- if (fop->cbks.fsetxattr != NULL)
- {
- fop->cbks.fsetxattr(fop->req_frame, fop, fop->xl, -1,
- fop->error, NULL);
- }
- }
-
- return EC_STATE_LOCK_REUSE;
-
- case -EC_STATE_LOCK_REUSE:
- case EC_STATE_LOCK_REUSE:
- ec_lock_reuse(fop);
-
- return EC_STATE_UNLOCK;
-
- case -EC_STATE_UNLOCK:
- case EC_STATE_UNLOCK:
- ec_unlock(fop);
-
- return EC_STATE_END;
-
- default:
- gf_log(fop->xl->name, GF_LOG_ERROR, "Unhandled state %d for %s",
- state, ec_fop_name(fop->id));
-
- return EC_STATE_END;
- }
-}
-
-void
-ec_setxattr (call_frame_t *frame, xlator_t *this, uintptr_t target,
- int32_t minimum, fop_setxattr_cbk_t func, void *data,
- loc_t *loc, dict_t *dict, int32_t flags, dict_t *xdata)
-{
- ec_cbk_t callback = { .setxattr = func };
- ec_fop_data_t * fop = NULL;
- int32_t error = EIO;
-
- gf_log("ec", GF_LOG_TRACE, "EC(SETXATTR) %p", frame);
-
- VALIDATE_OR_GOTO(this, out);
- GF_VALIDATE_OR_GOTO(this->name, frame, out);
- GF_VALIDATE_OR_GOTO(this->name, this->private, out);
-
- fop = ec_fop_data_allocate(frame, this, GF_FOP_SETXATTR,
- EC_FLAG_UPDATE_LOC_INODE, target, minimum,
- ec_wind_setxattr, ec_manager_setxattr, callback,
- data);
- if (fop == NULL)
- {
- goto out;
- }
-
- fop->int32 = flags;
-
- if (loc != NULL)
- {
- if (loc_copy(&fop->loc[0], loc) != 0)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to copy a location.");
-
- goto out;
- }
- }
- if (dict != NULL)
- {
- fop->dict = dict_ref(dict);
- if (fop->dict == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
- "dictionary.");
-
- goto out;
- }
- }
- if (xdata != NULL)
- {
- fop->xdata = dict_ref(xdata);
- if (fop->xdata == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
- "dictionary.");
-
- goto out;
- }
- }
-
- error = 0;
-
-out:
- if (fop != NULL) {
- ec_manager (fop, error);
- } else {
- func (frame, NULL, this, -1, error, NULL);
- }
-}
-
-/* FOP: fsetxattr */
-
-int32_t
-ec_fsetxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
-{
- ec_fop_data_t * fop = NULL;
- ec_cbk_data_t * cbk = NULL;
- int32_t idx = (int32_t)(uintptr_t)cookie;
-
- VALIDATE_OR_GOTO (this, out);
- GF_VALIDATE_OR_GOTO (this->name, frame, out);
- GF_VALIDATE_OR_GOTO (this->name, frame->local, out);
- GF_VALIDATE_OR_GOTO (this->name, this->private, out);
-
- fop = frame->local;
-
- ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx,
- frame, op_ret, op_errno);
-
- cbk = ec_cbk_data_allocate(frame, this, fop, GF_FOP_FSETXATTR, idx, op_ret,
- op_errno);
- if (cbk != NULL)
- {
- if (xdata != NULL)
- {
- cbk->xdata = dict_ref(xdata);
- if (cbk->xdata == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
- "dictionary.");
-
- goto out;
- }
- }
-
- ec_combine(cbk, NULL);
- }
-
-out:
- if (fop != NULL)
- {
- ec_complete(fop);
- }
-
- return 0;
-}
-
-void ec_wind_fsetxattr(ec_t * ec, ec_fop_data_t * fop, int32_t idx)
-{
- ec_trace("WIND", fop, "idx=%d", idx);
-
- STACK_WIND_COOKIE(fop->frame, ec_fsetxattr_cbk, (void *)(uintptr_t)idx,
- ec->xl_list[idx], ec->xl_list[idx]->fops->fsetxattr,
- fop->fd, fop->dict, fop->int32, fop->xdata);
-}
-
-void
-ec_fsetxattr (call_frame_t *frame, xlator_t *this, uintptr_t target,
- int32_t minimum, fop_fsetxattr_cbk_t func, void *data,
- fd_t *fd, dict_t *dict, int32_t flags, dict_t *xdata)
-{
- ec_cbk_t callback = { .fsetxattr = func };
- ec_fop_data_t * fop = NULL;
- int32_t error = EIO;
-
- gf_log("ec", GF_LOG_TRACE, "EC(FSETXATTR) %p", frame);
-
- VALIDATE_OR_GOTO(this, out);
- GF_VALIDATE_OR_GOTO(this->name, frame, out);
- GF_VALIDATE_OR_GOTO(this->name, this->private, out);
-
- fop = ec_fop_data_allocate(frame, this, GF_FOP_FSETXATTR,
- EC_FLAG_UPDATE_FD_INODE, target, minimum,
- ec_wind_fsetxattr, ec_manager_setxattr,
- callback, data);
- if (fop == NULL)
- {
- goto out;
- }
-
- fop->use_fd = 1;
-
- fop->int32 = flags;
-
- if (fd != NULL)
- {
- fop->fd = fd_ref(fd);
- if (fop->fd == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
- "file descriptor.");
-
- goto out;
- }
- }
- if (dict != NULL)
- {
- fop->dict = dict_ref(dict);
- if (fop->dict == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
- "dictionary.");
-
- goto out;
- }
- }
- if (xdata != NULL)
- {
- fop->xdata = dict_ref(xdata);
- if (fop->xdata == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
- "dictionary.");
-
- goto out;
- }
- }
-
- error = 0;
-
-out:
- if (fop != NULL) {
- ec_manager (fop, error);
- } else {
- func (frame, NULL, this, -1, error, NULL);
- }
-}
-
-/* FOP: truncate */
-
-int32_t ec_truncate_write(ec_fop_data_t * fop, uintptr_t mask)
-{
- ec_t * ec = fop->xl->private;
- struct iobref * iobref = NULL;
- struct iobuf * iobuf = NULL;
- struct iovec vector;
- int32_t ret = 0;
-
- iobref = iobref_new();
- if (iobref == NULL)
- {
- goto out;
- }
- iobuf = iobuf_get(fop->xl->ctx->iobuf_pool);
- if (iobuf == NULL)
- {
- goto out;
- }
- if (iobref_add(iobref, iobuf) != 0)
- {
- goto out;
- }
-
- vector.iov_base = iobuf->ptr;
- vector.iov_len = fop->offset * ec->fragments - fop->user_size;
-
- memset(iobuf->ptr, 0, vector.iov_len);
-
- iobuf = NULL;
-
- ec_writev(fop->frame, fop->xl, mask, fop->minimum, NULL, NULL, fop->fd,
- &vector, 1, fop->user_size, 0, iobref, NULL);
-
- ret = 1;
-
-out:
- if (iobuf != NULL)
- {
- iobuf_unref(iobuf);
- }
- if (iobref != NULL)
- {
- iobref_unref(iobref);
- }
-
- return ret;
-}
-
-int32_t ec_truncate_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)
-{
- ec_fop_data_t * fop = cookie;
-
- if (op_ret >= 0)
- {
- if (!ec_truncate_write(fop->parent, fop->answer->mask))
- {
- fop->error = EIO;
- }
- }
-
- return 0;
-}
-
-int32_t ec_truncate_clean(ec_fop_data_t * fop)
-{
- if (fop->fd == NULL)
- {
- fop->fd = fd_create(fop->loc[0].inode, fop->frame->root->pid);
- if (fop->fd == NULL)
- {
- return 0;
- }
-
- ec_open(fop->frame, fop->xl, fop->answer->mask, fop->minimum,
- ec_truncate_open_cbk, fop, &fop->loc[0], O_RDWR, fop->fd,
- NULL);
-
- return 1;
- }
- else
- {
- return ec_truncate_write(fop, fop->answer->mask);
- }
-}
-
-int32_t ec_combine_truncate(ec_fop_data_t * fop, ec_cbk_data_t * dst,
- ec_cbk_data_t * src)
-{
- if (!ec_iatt_combine(dst->iatt, src->iatt, 2))
- {
- gf_log(fop->xl->name, GF_LOG_NOTICE, "Mismatching iatt in "
- "answers of 'GF_FOP_TRUNCATE'");
-
- return 0;
- }
-
- return 1;
-}
-
-int32_t ec_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)
-{
- ec_fop_data_t * fop = NULL;
- ec_cbk_data_t * cbk = NULL;
- int32_t idx = (int32_t)(uintptr_t)cookie;
-
- VALIDATE_OR_GOTO(this, out);
- GF_VALIDATE_OR_GOTO(this->name, frame, out);
- GF_VALIDATE_OR_GOTO(this->name, frame->local, out);
- GF_VALIDATE_OR_GOTO(this->name, this->private, out);
-
- fop = frame->local;
-
- ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx,
- frame, op_ret, op_errno);
-
- cbk = ec_cbk_data_allocate(frame, this, fop, GF_FOP_TRUNCATE, idx, op_ret,
- op_errno);
- if (cbk != NULL)
- {
- if (op_ret >= 0)
- {
- if (prebuf != NULL)
- {
- cbk->iatt[0] = *prebuf;
- }
- if (postbuf != NULL)
- {
- cbk->iatt[1] = *postbuf;
- }
- }
- if (xdata != NULL)
- {
- cbk->xdata = dict_ref(xdata);
- if (cbk->xdata == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
- "dictionary.");
-
- goto out;
- }
- }
-
- ec_combine(cbk, ec_combine_truncate);
- }
-
-out:
- if (fop != NULL)
- {
- ec_complete(fop);
- }
-
- return 0;
-}
-
-void ec_wind_truncate(ec_t * ec, ec_fop_data_t * fop, int32_t idx)
-{
- ec_trace("WIND", fop, "idx=%d", idx);
-
- STACK_WIND_COOKIE(fop->frame, ec_truncate_cbk, (void *)(uintptr_t)idx,
- ec->xl_list[idx], ec->xl_list[idx]->fops->truncate,
- &fop->loc[0], fop->offset, fop->xdata);
-}
-
-int32_t ec_manager_truncate(ec_fop_data_t * fop, int32_t state)
-{
- ec_cbk_data_t * cbk;
-
- switch (state)
- {
- case EC_STATE_INIT:
- fop->user_size = fop->offset;
- fop->offset = ec_adjust_size(fop->xl->private, fop->offset, 1);
-
- /* Fall through */
-
- case EC_STATE_LOCK:
- if (fop->id == GF_FOP_TRUNCATE)
- {
- ec_lock_prepare_inode(fop, &fop->loc[0], 1);
- }
- else
- {
- ec_lock_prepare_fd(fop, fop->fd, 1);
- }
- ec_lock(fop);
-
- return EC_STATE_GET_SIZE_AND_VERSION;
-
- case EC_STATE_GET_SIZE_AND_VERSION:
- ec_get_size_version(fop);
-
- return EC_STATE_DISPATCH;
-
- case EC_STATE_DISPATCH:
- ec_dispatch_all(fop);
-
- return EC_STATE_PREPARE_ANSWER;
-
- case EC_STATE_PREPARE_ANSWER:
- cbk = fop->answer;
- if (cbk != NULL)
- {
- if (!ec_dict_combine(cbk, EC_COMBINE_XDATA))
- {
- if (cbk->op_ret >= 0)
- {
- cbk->op_ret = -1;
- cbk->op_errno = EIO;
- }
- }
- if (cbk->op_ret < 0)
- {
- ec_fop_set_error(fop, cbk->op_errno);
- }
- else
- {
- ec_iatt_rebuild(fop->xl->private, cbk->iatt, 2,
- cbk->count);
-
- cbk->iatt[0].ia_size = fop->pre_size;
- cbk->iatt[1].ia_size = fop->user_size;
- fop->post_size = fop->user_size;
- if ((fop->pre_size > fop->post_size) &&
- (fop->user_size != fop->offset))
- {
- if (!ec_truncate_clean(fop))
- {
- ec_fop_set_error(fop, EIO);
- }
- }
- }
- }
- else
- {
- ec_fop_set_error(fop, EIO);
- }
-
- return EC_STATE_REPORT;
-
- case EC_STATE_REPORT:
- cbk = fop->answer;
-
- GF_ASSERT(cbk != NULL);
-
- if (fop->id == GF_FOP_TRUNCATE)
- {
- if (fop->cbks.truncate != NULL)
- {
- fop->cbks.truncate(fop->req_frame, fop, fop->xl,
- cbk->op_ret, cbk->op_errno,
- &cbk->iatt[0], &cbk->iatt[1],
- cbk->xdata);
- }
- }
- else
- {
- if (fop->cbks.ftruncate != NULL)
- {
- fop->cbks.ftruncate(fop->req_frame, fop, fop->xl,
- cbk->op_ret, cbk->op_errno,
- &cbk->iatt[0], &cbk->iatt[1],
- cbk->xdata);
- }
- }
-
- return EC_STATE_LOCK_REUSE;
-
- case -EC_STATE_INIT:
- case -EC_STATE_LOCK:
- case -EC_STATE_GET_SIZE_AND_VERSION:
- case -EC_STATE_DISPATCH:
- case -EC_STATE_PREPARE_ANSWER:
- case -EC_STATE_REPORT:
- GF_ASSERT(fop->error != 0);
-
- if (fop->id == GF_FOP_TRUNCATE)
- {
- if (fop->cbks.truncate != NULL)
- {
- fop->cbks.truncate(fop->req_frame, fop, fop->xl, -1,
- fop->error, NULL, NULL, NULL);
- }
- }
- else
- {
- if (fop->cbks.ftruncate != NULL)
- {
- fop->cbks.ftruncate(fop->req_frame, fop, fop->xl, -1,
- fop->error, NULL, NULL, NULL);
- }
- }
-
- return EC_STATE_LOCK_REUSE;
-
- case -EC_STATE_LOCK_REUSE:
- case EC_STATE_LOCK_REUSE:
- ec_lock_reuse(fop);
-
- return EC_STATE_UNLOCK;
-
- case -EC_STATE_UNLOCK:
- case EC_STATE_UNLOCK:
- ec_unlock(fop);
-
- return EC_STATE_END;
-
- default:
- gf_log(fop->xl->name, GF_LOG_ERROR, "Unhandled state %d for %s",
- state, ec_fop_name(fop->id));
-
- return EC_STATE_END;
- }
-}
-
-void ec_truncate(call_frame_t * frame, xlator_t * this, uintptr_t target,
- int32_t minimum, fop_truncate_cbk_t func, void * data,
- loc_t * loc, off_t offset, dict_t * xdata)
-{
- ec_cbk_t callback = { .truncate = func };
- ec_fop_data_t * fop = NULL;
- int32_t error = EIO;
-
- gf_log("ec", GF_LOG_TRACE, "EC(TRUNCATE) %p", frame);
-
- VALIDATE_OR_GOTO(this, out);
- GF_VALIDATE_OR_GOTO(this->name, frame, out);
- GF_VALIDATE_OR_GOTO(this->name, this->private, out);
-
- fop = ec_fop_data_allocate(frame, this, GF_FOP_TRUNCATE,
- EC_FLAG_UPDATE_LOC_INODE, target, minimum,
- ec_wind_truncate, ec_manager_truncate, callback,
- data);
- if (fop == NULL)
- {
- goto out;
- }
-
- fop->offset = offset;
-
- if (loc != NULL)
- {
- if (loc_copy(&fop->loc[0], loc) != 0)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to copy a location.");
-
- goto out;
- }
- }
- if (xdata != NULL)
- {
- fop->xdata = dict_ref(xdata);
- if (fop->xdata == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
- "dictionary.");
-
- goto out;
- }
- }
-
- error = 0;
-
-out:
- if (fop != NULL)
- {
- ec_manager(fop, error);
- }
- else
- {
- func(frame, NULL, this, -1, EIO, NULL, NULL, NULL);
- }
-}
-
-/* FOP: ftruncate */
-
-int32_t ec_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)
-{
- ec_fop_data_t * fop = NULL;
- ec_cbk_data_t * cbk = NULL;
- int32_t idx = (int32_t)(uintptr_t)cookie;
-
- VALIDATE_OR_GOTO(this, out);
- GF_VALIDATE_OR_GOTO(this->name, frame, out);
- GF_VALIDATE_OR_GOTO(this->name, frame->local, out);
- GF_VALIDATE_OR_GOTO(this->name, this->private, out);
-
- fop = frame->local;
-
- ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx,
- frame, op_ret, op_errno);
-
- cbk = ec_cbk_data_allocate(frame, this, fop, GF_FOP_FTRUNCATE, idx, op_ret,
- op_errno);
- if (cbk != NULL)
- {
- if (op_ret >= 0)
- {
- if (prebuf != NULL)
- {
- cbk->iatt[0] = *prebuf;
- }
- if (postbuf != NULL)
- {
- cbk->iatt[1] = *postbuf;
- }
- }
- if (xdata != NULL)
- {
- cbk->xdata = dict_ref(xdata);
- if (cbk->xdata == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
- "dictionary.");
-
- goto out;
- }
- }
-
- ec_combine(cbk, ec_combine_truncate);
- }
-
-out:
- if (fop != NULL)
- {
- ec_complete(fop);
- }
-
- return 0;
-}
-
-void ec_wind_ftruncate(ec_t * ec, ec_fop_data_t * fop, int32_t idx)
-{
- ec_trace("WIND", fop, "idx=%d", idx);
-
- STACK_WIND_COOKIE(fop->frame, ec_ftruncate_cbk, (void *)(uintptr_t)idx,
- ec->xl_list[idx], ec->xl_list[idx]->fops->ftruncate,
- fop->fd, fop->offset, fop->xdata);
-}
-
-void ec_ftruncate(call_frame_t * frame, xlator_t * this, uintptr_t target,
- int32_t minimum, fop_ftruncate_cbk_t func, void * data,
- fd_t * fd, off_t offset, dict_t * xdata)
-{
- ec_cbk_t callback = { .ftruncate = func };
- ec_fop_data_t * fop = NULL;
- int32_t error = EIO;
-
- gf_log("ec", GF_LOG_TRACE, "EC(FTRUNCATE) %p", frame);
-
- VALIDATE_OR_GOTO(this, out);
- GF_VALIDATE_OR_GOTO(this->name, frame, out);
- GF_VALIDATE_OR_GOTO(this->name, this->private, out);
-
- fop = ec_fop_data_allocate(frame, this, GF_FOP_FTRUNCATE,
- EC_FLAG_UPDATE_FD_INODE, target, minimum,
- ec_wind_ftruncate, ec_manager_truncate,
- callback, data);
- if (fop == NULL)
- {
- goto out;
- }
-
- fop->use_fd = 1;
-
- fop->offset = offset;
-
- if (fd != NULL)
- {
- fop->fd = fd_ref(fd);
- if (fop->fd == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
- "file descriptor.");
-
- goto out;
- }
- }
- if (xdata != NULL)
- {
- fop->xdata = dict_ref(xdata);
- if (fop->xdata == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
- "dictionary.");
-
- goto out;
- }
- }
-
- error = 0;
-
-out:
- if (fop != NULL)
- {
- ec_manager(fop, error);
- }
- else
- {
- func(frame, NULL, this, -1, EIO, NULL, NULL, NULL);
- }
-}
-
-/* FOP: writev */
-
-int32_t ec_writev_merge_tail(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)
-{
- ec_t * ec = this->private;
- ec_fop_data_t * fop = frame->local;
- size_t size, base, tmp;
-
- if (op_ret >= 0)
- {
- tmp = 0;
- size = fop->size - fop->user_size - fop->head;
- base = ec->stripe_size - size;
- if (op_ret > base)
- {
- tmp = min(op_ret - base, size);
- ec_iov_copy_to(fop->vector[0].iov_base + fop->size - size, vector,
- count, base, tmp);
-
- size -= tmp;
- }
-
- if (size > 0)
- {
- memset(fop->vector[0].iov_base + fop->size - size, 0, size);
- }
- }
-
- return 0;
-}
-
-int32_t ec_writev_merge_head(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)
-{
- ec_t * ec = this->private;
- ec_fop_data_t * fop = frame->local;
- size_t size, base;
-
- if (op_ret >= 0)
- {
- size = fop->head;
- base = 0;
-
- if (op_ret > 0)
- {
- base = min(op_ret, size);
- ec_iov_copy_to(fop->vector[0].iov_base, vector, count, 0, base);
-
- size -= base;
- }
-
- if (size > 0)
- {
- memset(fop->vector[0].iov_base + base, 0, size);
- }
-
- size = fop->size - fop->user_size - fop->head;
- if ((size > 0) && (fop->size == ec->stripe_size))
- {
- ec_writev_merge_tail(frame, cookie, this, op_ret, op_errno, vector,
- count, stbuf, iobref, xdata);
- }
- }
-
- return 0;
-}
-
-void ec_writev_start(ec_fop_data_t *fop)
-{
- ec_t *ec = fop->xl->private;
- struct iobref *iobref = NULL;
- struct iobuf *iobuf = NULL;
- void *ptr = NULL;
- ec_fd_t *ctx;
- fd_t *fd;
- size_t tail;
- uid_t uid;
- gid_t gid;
-
- fd = fd_anonymous(fop->fd->inode);
- if (fd == NULL) {
- ec_fop_set_error(fop, EIO);
-
- return;
- }
-
- uid = fop->frame->root->uid;
- fop->frame->root->uid = 0;
- gid = fop->frame->root->gid;
- fop->frame->root->gid = 0;
-
- ctx = ec_fd_get(fop->fd, fop->xl);
- if (ctx != NULL) {
- if ((ctx->flags & O_APPEND) != 0) {
- fop->offset = fop->pre_size;
- }
- }
-
- fop->user_size = iov_length(fop->vector, fop->int32);
- fop->head = ec_adjust_offset(ec, &fop->offset, 0);
- fop->size = ec_adjust_size(ec, fop->user_size + fop->head, 0);
-
- iobref = iobref_new();
- if (iobref == NULL) {
- goto out;
- }
- iobuf = iobuf_get2(fop->xl->ctx->iobuf_pool, fop->size);
- if (iobuf == NULL) {
- goto out;
- }
- if (iobref_add(iobref, iobuf) != 0) {
- goto out;
- }
-
- ptr = iobuf->ptr + fop->head;
- ec_iov_copy_to(ptr, fop->vector, fop->int32, 0, fop->user_size);
-
- fop->vector[0].iov_base = iobuf->ptr;
- fop->vector[0].iov_len = fop->size;
-
- iobuf_unref(iobuf);
-
- iobref_unref(fop->buffers);
- fop->buffers = iobref;
-
- if (fop->head > 0)
- {
- ec_readv(fop->frame, fop->xl, -1, EC_MINIMUM_MIN, ec_writev_merge_head,
- NULL, fd, ec->stripe_size, fop->offset, 0, NULL);
- }
- tail = fop->size - fop->user_size - fop->head;
- if ((tail > 0) && ((fop->head == 0) || (fop->size > ec->stripe_size)))
- {
- if (fop->pre_size > fop->offset + fop->head + fop->user_size)
- {
- ec_readv(fop->frame, fop->xl, -1, EC_MINIMUM_MIN,
- ec_writev_merge_tail, NULL, fd, ec->stripe_size,
- fop->offset + fop->size - ec->stripe_size, 0, NULL);
- }
- else
- {
- memset(fop->vector[0].iov_base + fop->size - tail, 0, tail);
- }
- }
-
- fop->frame->root->uid = uid;
- fop->frame->root->gid = gid;
-
- fd_unref(fd);
-
- return;
-
-out:
- if (iobuf != NULL) {
- iobuf_unref(iobuf);
- }
- if (iobref != NULL) {
- iobref_unref(iobref);
- }
-
- fop->frame->root->uid = uid;
- fop->frame->root->gid = gid;
-
- fd_unref(fd);
-
- ec_fop_set_error(fop, EIO);
-}
-
-int32_t ec_combine_writev(ec_fop_data_t * fop, ec_cbk_data_t * dst,
- ec_cbk_data_t * src)
-{
- if (!ec_iatt_combine(dst->iatt, src->iatt, 2))
- {
- gf_log(fop->xl->name, GF_LOG_NOTICE, "Mismatching iatt in "
- "answers of 'GF_FOP_WRITE'");
-
- return 0;
- }
-
- return 1;
-}
-
-int32_t ec_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)
-{
- ec_fop_data_t * fop = NULL;
- ec_cbk_data_t * cbk = NULL;
- ec_t * ec = this->private;
- int32_t idx = (int32_t)(uintptr_t)cookie;
-
- VALIDATE_OR_GOTO(this, out);
- GF_VALIDATE_OR_GOTO(this->name, frame, out);
- GF_VALIDATE_OR_GOTO(this->name, frame->local, out);
- GF_VALIDATE_OR_GOTO(this->name, this->private, out);
-
- fop = frame->local;
-
- ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx,
- frame, op_ret, op_errno);
-
- cbk = ec_cbk_data_allocate(frame, this, fop, GF_FOP_WRITE, idx, op_ret,
- op_errno);
- if (cbk != NULL)
- {
- if (op_ret >= 0)
- {
- if (prebuf != NULL)
- {
- cbk->iatt[0] = *prebuf;
- }
- if (postbuf != NULL)
- {
- cbk->iatt[1] = *postbuf;
- }
- }
- if (xdata != NULL)
- {
- cbk->xdata = dict_ref(xdata);
- if (cbk->xdata == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
- "dictionary.");
-
- goto out;
- }
- }
-
- if ((op_ret > 0) && ((op_ret % ec->fragment_size) != 0))
- {
- cbk->op_ret = -1;
- cbk->op_errno = EIO;
- }
-
- ec_combine(cbk, ec_combine_writev);
- }
-
-out:
- if (fop != NULL)
- {
- ec_complete(fop);
- }
-
- return 0;
-}
-
-void ec_wind_writev(ec_t * ec, ec_fop_data_t * fop, int32_t idx)
-{
- ec_trace("WIND", fop, "idx=%d", idx);
-
- struct iovec vector[1];
- struct iobref * iobref = NULL;
- struct iobuf * iobuf = NULL;
- ssize_t size = 0, bufsize = 0;
-
- iobref = iobref_new();
- if (iobref == NULL)
- {
- goto out;
- }
-
- size = fop->vector[0].iov_len;
- bufsize = size / ec->fragments;
-
- iobuf = iobuf_get2(fop->xl->ctx->iobuf_pool, bufsize);
- if (iobuf == NULL)
- {
- goto out;
- }
- if (iobref_add(iobref, iobuf) != 0)
- {
- goto out;
- }
-
- ec_method_encode(size, ec->fragments, idx, fop->vector[0].iov_base,
- iobuf->ptr);
-
- vector[0].iov_base = iobuf->ptr;
- vector[0].iov_len = bufsize;
-
- iobuf_unref(iobuf);
-
- STACK_WIND_COOKIE(fop->frame, ec_writev_cbk, (void *)(uintptr_t)idx,
- ec->xl_list[idx], ec->xl_list[idx]->fops->writev,
- fop->fd, vector, 1, fop->offset / ec->fragments,
- fop->uint32, iobref, fop->xdata);
-
- iobref_unref(iobref);
-
- return;
-
-out:
- if (iobuf != NULL)
- {
- iobuf_unref(iobuf);
- }
- if (iobref != NULL)
- {
- iobref_unref(iobref);
- }
-
- ec_writev_cbk(fop->frame, (void *)(uintptr_t)idx, fop->xl, -1, EIO, NULL,
- NULL, NULL);
-}
-
-int32_t ec_manager_writev(ec_fop_data_t * fop, int32_t state)
-{
- ec_cbk_data_t * cbk;
-
- switch (state)
- {
- case EC_STATE_INIT:
- case EC_STATE_LOCK:
- ec_lock_prepare_fd(fop, fop->fd, 1);
- ec_lock(fop);
-
- return EC_STATE_GET_SIZE_AND_VERSION;
-
- case EC_STATE_GET_SIZE_AND_VERSION:
- ec_get_size_version(fop);
-
- return EC_STATE_DISPATCH;
-
- case EC_STATE_DISPATCH:
- ec_writev_start(fop);
-
- return EC_STATE_DELAYED_START;
-
- case EC_STATE_DELAYED_START:
- ec_dispatch_all(fop);
-
- return EC_STATE_PREPARE_ANSWER;
-
- case EC_STATE_PREPARE_ANSWER:
- cbk = fop->answer;
- if (cbk != NULL)
- {
- if (!ec_dict_combine(cbk, EC_COMBINE_XDATA))
- {
- if (cbk->op_ret >= 0)
- {
- cbk->op_ret = -1;
- cbk->op_errno = EIO;
- }
- }
- if (cbk->op_ret < 0)
- {
- ec_fop_set_error(fop, cbk->op_errno);
- }
- else
- {
- ec_t * ec = fop->xl->private;
- size_t size;
-
- ec_iatt_rebuild(fop->xl->private, cbk->iatt, 2,
- cbk->count);
-
- size = fop->offset + fop->head + fop->user_size;
- if (size > fop->pre_size)
- {
- fop->post_size = size;
- }
-
- cbk->iatt[0].ia_size = fop->pre_size;
- cbk->iatt[1].ia_size = fop->post_size;
-
- cbk->op_ret *= ec->fragments;
- if (cbk->op_ret < fop->head)
- {
- cbk->op_ret = 0;
- }
- else
- {
- cbk->op_ret -= fop->head;
- }
- if (cbk->op_ret > fop->user_size)
- {
- cbk->op_ret = fop->user_size;
- }
- }
- }
- else
- {
- ec_fop_set_error(fop, EIO);
- }
-
- return EC_STATE_REPORT;
-
- case EC_STATE_REPORT:
- cbk = fop->answer;
-
- GF_ASSERT(cbk != NULL);
-
- if (fop->cbks.writev != NULL)
- {
- fop->cbks.writev(fop->req_frame, fop, fop->xl, cbk->op_ret,
- cbk->op_errno, &cbk->iatt[0], &cbk->iatt[1],
- cbk->xdata);
- }
-
- return EC_STATE_LOCK_REUSE;
-
- case -EC_STATE_INIT:
- case -EC_STATE_LOCK:
- case -EC_STATE_GET_SIZE_AND_VERSION:
- case -EC_STATE_DISPATCH:
- case -EC_STATE_PREPARE_ANSWER:
- case -EC_STATE_REPORT:
- GF_ASSERT(fop->error != 0);
-
- if (fop->cbks.writev != NULL)
- {
- fop->cbks.writev(fop->req_frame, fop, fop->xl, -1, fop->error,
- NULL, NULL, NULL);
- }
-
- return EC_STATE_LOCK_REUSE;
-
- case -EC_STATE_LOCK_REUSE:
- case EC_STATE_LOCK_REUSE:
- ec_lock_reuse(fop);
-
- return EC_STATE_UNLOCK;
-
- case -EC_STATE_UNLOCK:
- case EC_STATE_UNLOCK:
- ec_unlock(fop);
-
- return EC_STATE_END;
-
- default:
- gf_log(fop->xl->name, GF_LOG_ERROR, "Unhandled state %d for %s",
- state, ec_fop_name(fop->id));
-
- return EC_STATE_END;
- }
-}
-
-void ec_writev(call_frame_t * frame, xlator_t * this, uintptr_t target,
- int32_t minimum, fop_writev_cbk_t func, void * data, fd_t * fd,
- struct iovec * vector, int32_t count, off_t offset,
- uint32_t flags, struct iobref * iobref, dict_t * xdata)
-{
- ec_cbk_t callback = { .writev = func };
- ec_fop_data_t * fop = NULL;
- int32_t error = EIO;
-
- gf_log("ec", GF_LOG_TRACE, "EC(WRITE) %p", frame);
-
- VALIDATE_OR_GOTO(this, out);
- GF_VALIDATE_OR_GOTO(this->name, frame, out);
- GF_VALIDATE_OR_GOTO(this->name, this->private, out);
-
- fop = ec_fop_data_allocate(frame, this, GF_FOP_WRITE,
- EC_FLAG_UPDATE_FD_INODE, target, minimum,
- ec_wind_writev, ec_manager_writev, callback,
- data);
- if (fop == NULL)
- {
- goto out;
- }
-
- fop->int32 = count;
- fop->offset = offset;
- fop->uint32 = flags;
-
- fop->use_fd = 1;
-
- if (fd != NULL)
- {
- fop->fd = fd_ref(fd);
- if (fop->fd == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
- "file descriptor.");
-
- goto out;
- }
- }
- if (count > 0)
- {
- fop->vector = iov_dup(vector, count);
- if (fop->vector == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to duplicate a "
- "vector list.");
-
- goto out;
- }
- fop->int32 = count;
- }
- if (iobref != NULL)
- {
- fop->buffers = iobref_ref(iobref);
- if (fop->buffers == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
- "buffer.");
-
- goto out;
- }
- }
- if (xdata != NULL)
- {
- fop->xdata = dict_ref(xdata);
- if (fop->xdata == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
- "dictionary.");
-
- goto out;
- }
- }
-
- error = 0;
-
-out:
- if (fop != NULL)
- {
- ec_manager(fop, error);
- }
- else
- {
- func(frame, NULL, this, -1, EIO, NULL, NULL, NULL);
- }
-}
diff --git a/xlators/cluster/ec/src/ec-locks.c b/xlators/cluster/ec/src/ec-locks.c
deleted file mode 100644
index 93933153b86..00000000000
--- a/xlators/cluster/ec/src/ec-locks.c
+++ /dev/null
@@ -1,1212 +0,0 @@
-/*
- Copyright (c) 2012-2014 DataLab, s.l. <http://www.datalab.es>
- 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 "xlator.h"
-#include "defaults.h"
-
-#include "ec-helpers.h"
-#include "ec-common.h"
-#include "ec-combine.h"
-#include "ec-method.h"
-#include "ec-fops.h"
-
-#define EC_LOCK_MODE_NONE 0
-#define EC_LOCK_MODE_INC 1
-#define EC_LOCK_MODE_ALL 2
-
-int32_t ec_lock_check(ec_fop_data_t * fop, ec_cbk_data_t ** cbk,
- uintptr_t * mask)
-{
- ec_t * ec = fop->xl->private;
- ec_cbk_data_t * ans = NULL;
- uintptr_t locked = 0, notlocked = 0;
- int32_t error = -1;
-
- list_for_each_entry(ans, &fop->cbk_list, list)
- {
- if (ans->op_ret >= 0)
- {
- if (locked != 0)
- {
- error = EIO;
- }
- locked |= ans->mask;
- *cbk = ans;
- }
- else if (ans->op_errno == EAGAIN)
- {
- notlocked |= ans->mask;
- }
- }
-
- if (error == -1)
- {
- if (ec_bits_count(locked | notlocked) >= ec->fragments)
- {
- if (notlocked == 0)
- {
- fop->answer = *cbk;
-
- ec_update_bad(fop, locked);
-
- error = 0;
- }
- else
- {
- switch (fop->uint32)
- {
- case EC_LOCK_MODE_NONE:
- error = EAGAIN;
- break;
-
- case EC_LOCK_MODE_ALL:
- fop->uint32 = EC_LOCK_MODE_INC;
- break;
-
- default:
- error = EIO;
- break;
- }
- }
- }
- else
- {
- error = EIO;
- }
- }
-
- *mask = locked;
-
- return error;
-}
-
-int32_t ec_lock_unlocked(call_frame_t * frame, void * cookie,
- xlator_t * this, int32_t op_ret, int32_t op_errno,
- dict_t * xdata)
-{
- if (op_ret < 0)
- {
- gf_log(this->name, GF_LOG_WARNING, "Failed to unlock an entry/inode");
- }
-
- return 0;
-}
-
-int32_t ec_lock_lk_unlocked(call_frame_t * frame, void * cookie,
- xlator_t * this, int32_t op_ret, int32_t op_errno,
- struct gf_flock * flock, dict_t * xdata)
-{
- if (op_ret < 0)
- {
- gf_log(this->name, GF_LOG_WARNING, "Failed to unlock an lk");
- }
-
- return 0;
-}
-
-/* FOP: entrylk */
-
-int32_t ec_entrylk_cbk(call_frame_t * frame, void * cookie, xlator_t * this,
- int32_t op_ret, int32_t op_errno, dict_t * xdata)
-{
- ec_fop_data_t * fop = NULL;
- ec_cbk_data_t * cbk = NULL;
- int32_t idx = (int32_t)(uintptr_t)cookie;
-
- VALIDATE_OR_GOTO(this, out);
- GF_VALIDATE_OR_GOTO(this->name, frame, out);
- GF_VALIDATE_OR_GOTO(this->name, frame->local, out);
- GF_VALIDATE_OR_GOTO(this->name, this->private, out);
-
- fop = frame->local;
-
- ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx,
- frame, op_ret, op_errno);
-
- cbk = ec_cbk_data_allocate(frame, this, fop, GF_FOP_ENTRYLK, idx, op_ret,
- op_errno);
- if (cbk != NULL)
- {
- if (xdata != NULL)
- {
- cbk->xdata = dict_ref(xdata);
- if (cbk->xdata == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
- "dictionary.");
-
- goto out;
- }
- }
-
- ec_combine(cbk, NULL);
- }
-
-out:
- if (fop != NULL)
- {
- ec_complete(fop);
- }
-
- return 0;
-}
-
-void ec_wind_entrylk(ec_t * ec, ec_fop_data_t * fop, int32_t idx)
-{
- ec_trace("WIND", fop, "idx=%d", idx);
-
- STACK_WIND_COOKIE(fop->frame, ec_entrylk_cbk, (void *)(uintptr_t)idx,
- ec->xl_list[idx], ec->xl_list[idx]->fops->entrylk,
- fop->str[0], &fop->loc[0], fop->str[1], fop->entrylk_cmd,
- fop->entrylk_type, fop->xdata);
-}
-
-int32_t ec_manager_entrylk(ec_fop_data_t * fop, int32_t state)
-{
- ec_cbk_data_t * cbk;
-
- switch (state)
- {
- case EC_STATE_INIT:
- if (fop->entrylk_cmd == ENTRYLK_LOCK)
- {
- fop->uint32 = EC_LOCK_MODE_ALL;
- fop->entrylk_cmd = ENTRYLK_LOCK_NB;
- }
-
- /* Fall through */
-
- case EC_STATE_DISPATCH:
- ec_dispatch_all(fop);
-
- return EC_STATE_PREPARE_ANSWER;
-
- case EC_STATE_PREPARE_ANSWER:
- cbk = fop->answer;
- if ((cbk == NULL) ||
- ((cbk->op_ret < 0) && (cbk->op_errno == EAGAIN)))
- {
- uintptr_t mask;
-
- fop->error = ec_lock_check(fop, &cbk, &mask);
- if (fop->error != 0)
- {
- if (mask != 0)
- {
- if (fop->id == GF_FOP_ENTRYLK)
- {
- ec_entrylk(fop->req_frame, fop->xl, mask, 1,
- ec_lock_unlocked, NULL, fop->str[0],
- &fop->loc[0], fop->str[1],
- ENTRYLK_UNLOCK, fop->entrylk_type,
- fop->xdata);
- }
- else
- {
- ec_fentrylk(fop->req_frame, fop->xl, mask, 1,
- ec_lock_unlocked, NULL, fop->str[0],
- fop->fd, fop->str[1], ENTRYLK_UNLOCK,
- fop->entrylk_type, fop->xdata);
- }
- }
- if (fop->error > 0)
- {
- return EC_STATE_REPORT;
- }
-
- fop->error = 0;
-
- fop->entrylk_cmd = ENTRYLK_LOCK;
-
- ec_dispatch_inc(fop);
-
- return EC_STATE_PREPARE_ANSWER;
- }
- }
-
- return EC_STATE_REPORT;
-
- case EC_STATE_REPORT:
- cbk = fop->answer;
-
- GF_ASSERT(cbk != NULL);
-
- if (fop->id == GF_FOP_ENTRYLK)
- {
- if (fop->cbks.entrylk != NULL)
- {
- fop->cbks.entrylk(fop->req_frame, fop, fop->xl,
- cbk->op_ret, cbk->op_errno, cbk->xdata);
- }
- }
- else
- {
- if (fop->cbks.fentrylk != NULL)
- {
- fop->cbks.fentrylk(fop->req_frame, fop, fop->xl,
- cbk->op_ret, cbk->op_errno, cbk->xdata);
- }
- }
-
- ec_wait_winds(fop);
-
- return EC_STATE_END;
-
- case -EC_STATE_INIT:
- case -EC_STATE_DISPATCH:
- case -EC_STATE_PREPARE_ANSWER:
- case -EC_STATE_REPORT:
- GF_ASSERT(fop->error != 0);
-
- if (fop->id == GF_FOP_ENTRYLK)
- {
- if (fop->cbks.entrylk != NULL)
- {
- fop->cbks.entrylk(fop->req_frame, fop, fop->xl, -1,
- fop->error, NULL);
- }
- }
- else
- {
- if (fop->cbks.fentrylk != NULL)
- {
- fop->cbks.fentrylk(fop->req_frame, fop, fop->xl, -1,
- fop->error, NULL);
- }
- }
-
- ec_wait_winds(fop);
-
- return EC_STATE_END;
-
- default:
- gf_log(fop->xl->name, GF_LOG_ERROR, "Unhandled state %d for %s",
- state, ec_fop_name(fop->id));
-
- return EC_STATE_END;
- }
-}
-
-void ec_entrylk(call_frame_t * frame, xlator_t * this, uintptr_t target,
- int32_t minimum, fop_entrylk_cbk_t func, void * data,
- const char * volume, loc_t * loc, const char * basename,
- entrylk_cmd cmd, entrylk_type type, dict_t * xdata)
-{
- ec_cbk_t callback = { .entrylk = func };
- ec_fop_data_t * fop = NULL;
- int32_t error = EIO;
-
- gf_log("ec", GF_LOG_TRACE, "EC(ENTRYLK) %p", frame);
-
- VALIDATE_OR_GOTO(this, out);
- GF_VALIDATE_OR_GOTO(this->name, frame, out);
- GF_VALIDATE_OR_GOTO(this->name, this->private, out);
-
- fop = ec_fop_data_allocate(frame, this, GF_FOP_ENTRYLK,
- EC_FLAG_UPDATE_LOC_INODE, target, minimum,
- ec_wind_entrylk, ec_manager_entrylk, callback,
- data);
- if (fop == NULL)
- {
- goto out;
- }
-
- fop->entrylk_cmd = cmd;
- fop->entrylk_type = type;
-
- if (volume != NULL)
- {
- fop->str[0] = gf_strdup(volume);
- if (fop->str[0] == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to duplicate a string.");
-
- goto out;
- }
- }
- if (loc != NULL)
- {
- if (loc_copy(&fop->loc[0], loc) != 0)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to copy a location.");
-
- goto out;
- }
- }
- if (basename != NULL)
- {
- fop->str[1] = gf_strdup(basename);
- if (fop->str[1] == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to duplicate a string.");
-
- goto out;
- }
- }
- if (xdata != NULL)
- {
- fop->xdata = dict_ref(xdata);
- if (fop->xdata == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
- "dictionary.");
-
- goto out;
- }
- }
-
- error = 0;
-
-out:
- if (fop != NULL)
- {
- ec_manager(fop, error);
- }
- else
- {
- func(frame, NULL, this, -1, EIO, NULL);
- }
-}
-
-/* FOP: fentrylk */
-
-int32_t ec_fentrylk_cbk(call_frame_t * frame, void * cookie, xlator_t * this,
- int32_t op_ret, int32_t op_errno, dict_t * xdata)
-{
- ec_fop_data_t * fop = NULL;
- ec_cbk_data_t * cbk = NULL;
- int32_t idx = (int32_t)(uintptr_t)cookie;
-
- VALIDATE_OR_GOTO(this, out);
- GF_VALIDATE_OR_GOTO(this->name, frame, out);
- GF_VALIDATE_OR_GOTO(this->name, frame->local, out);
- GF_VALIDATE_OR_GOTO(this->name, this->private, out);
-
- fop = frame->local;
-
- ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx,
- frame, op_ret, op_errno);
-
- cbk = ec_cbk_data_allocate(frame, this, fop, GF_FOP_FENTRYLK, idx, op_ret,
- op_errno);
- if (cbk != NULL)
- {
- if (xdata != NULL)
- {
- cbk->xdata = dict_ref(xdata);
- if (cbk->xdata == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
- "dictionary.");
-
- goto out;
- }
- }
-
- ec_combine(cbk, NULL);
- }
-
-out:
- if (fop != NULL)
- {
- ec_complete(fop);
- }
-
- return 0;
-}
-
-void ec_wind_fentrylk(ec_t * ec, ec_fop_data_t * fop, int32_t idx)
-{
- ec_trace("WIND", fop, "idx=%d", idx);
-
- STACK_WIND_COOKIE(fop->frame, ec_fentrylk_cbk, (void *)(uintptr_t)idx,
- ec->xl_list[idx], ec->xl_list[idx]->fops->fentrylk,
- fop->str[0], fop->fd, fop->str[1], fop->entrylk_cmd,
- fop->entrylk_type, fop->xdata);
-}
-
-void ec_fentrylk(call_frame_t * frame, xlator_t * this, uintptr_t target,
- int32_t minimum, fop_fentrylk_cbk_t func, void * data,
- const char * volume, fd_t * fd, const char * basename,
- entrylk_cmd cmd, entrylk_type type, dict_t * xdata)
-{
- ec_cbk_t callback = { .fentrylk = func };
- ec_fop_data_t * fop = NULL;
- int32_t error = EIO;
-
- gf_log("ec", GF_LOG_TRACE, "EC(FENTRYLK) %p", frame);
-
- VALIDATE_OR_GOTO(this, out);
- GF_VALIDATE_OR_GOTO(this->name, frame, out);
- GF_VALIDATE_OR_GOTO(this->name, this->private, out);
-
- fop = ec_fop_data_allocate(frame, this, GF_FOP_FENTRYLK,
- EC_FLAG_UPDATE_FD_INODE, target, minimum,
- ec_wind_fentrylk, ec_manager_entrylk, callback,
- data);
- if (fop == NULL)
- {
- goto out;
- }
-
- fop->use_fd = 1;
-
- fop->entrylk_cmd = cmd;
- fop->entrylk_type = type;
-
- if (volume != NULL)
- {
- fop->str[0] = gf_strdup(volume);
- if (fop->str[0] == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to duplicate a string.");
-
- goto out;
- }
- }
- if (fd != NULL)
- {
- fop->fd = fd_ref(fd);
- if (fop->fd == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
- "file descriptor.");
-
- goto out;
- }
- }
- if (basename != NULL)
- {
- fop->str[1] = gf_strdup(basename);
- if (fop->str[1] == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to duplicate a string.");
-
- goto out;
- }
- }
- if (xdata != NULL)
- {
- fop->xdata = dict_ref(xdata);
- if (fop->xdata == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
- "dictionary.");
-
- goto out;
- }
- }
-
- error = 0;
-
-out:
- if (fop != NULL)
- {
- ec_manager(fop, error);
- }
- else
- {
- func(frame, NULL, this, -1, EIO, NULL);
- }
-}
-
-/* FOP: inodelk */
-
-int32_t ec_inodelk_cbk(call_frame_t * frame, void * cookie, xlator_t * this,
- int32_t op_ret, int32_t op_errno, dict_t * xdata)
-{
- ec_fop_data_t * fop = NULL;
- ec_cbk_data_t * cbk = NULL;
- int32_t idx = (int32_t)(uintptr_t)cookie;
-
- VALIDATE_OR_GOTO(this, out);
- GF_VALIDATE_OR_GOTO(this->name, frame, out);
- GF_VALIDATE_OR_GOTO(this->name, frame->local, out);
- GF_VALIDATE_OR_GOTO(this->name, this->private, out);
-
- fop = frame->local;
-
- ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx,
- frame, op_ret, op_errno);
-
- cbk = ec_cbk_data_allocate(frame, this, fop, GF_FOP_INODELK, idx, op_ret,
- op_errno);
- if (cbk != NULL)
- {
- if (xdata != NULL)
- {
- cbk->xdata = dict_ref(xdata);
- if (cbk->xdata == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
- "dictionary.");
-
- goto out;
- }
- }
-
- ec_combine(cbk, NULL);
- }
-
-out:
- if (fop != NULL)
- {
- ec_complete(fop);
- }
-
- return 0;
-}
-
-void ec_wind_inodelk(ec_t * ec, ec_fop_data_t * fop, int32_t idx)
-{
- ec_trace("WIND", fop, "idx=%d", idx);
-
- STACK_WIND_COOKIE(fop->frame, ec_inodelk_cbk, (void *)(uintptr_t)idx,
- ec->xl_list[idx], ec->xl_list[idx]->fops->inodelk,
- fop->str[0], &fop->loc[0], fop->int32, &fop->flock,
- fop->xdata);
-}
-
-int32_t ec_manager_inodelk(ec_fop_data_t * fop, int32_t state)
-{
- ec_cbk_data_t * cbk;
-
- switch (state)
- {
- case EC_STATE_INIT:
- fop->flock.l_len += ec_adjust_offset(fop->xl->private,
- &fop->flock.l_start, 1);
- fop->flock.l_len = ec_adjust_size(fop->xl->private,
- fop->flock.l_len, 1);
- if ((fop->int32 == F_SETLKW) && (fop->flock.l_type != F_UNLCK))
- {
- fop->uint32 = EC_LOCK_MODE_ALL;
- fop->int32 = F_SETLK;
- }
-
- /* Fall through */
-
- case EC_STATE_DISPATCH:
- ec_dispatch_all(fop);
-
- return EC_STATE_PREPARE_ANSWER;
-
- case EC_STATE_PREPARE_ANSWER:
- cbk = fop->answer;
- if ((cbk == NULL) ||
- ((cbk->op_ret < 0) && (cbk->op_errno == EAGAIN)))
- {
- uintptr_t mask;
-
- fop->error = ec_lock_check(fop, &cbk, &mask);
- if (fop->error != 0)
- {
- if (mask != 0)
- {
- ec_t * ec = fop->xl->private;
- struct gf_flock flock;
-
- flock.l_type = F_UNLCK;
- flock.l_whence = fop->flock.l_whence;
- flock.l_start = fop->flock.l_start * ec->fragments;
- flock.l_len = fop->flock.l_len * ec->fragments;
- flock.l_pid = 0;
- flock.l_owner.len = 0;
-
- if (fop->id == GF_FOP_INODELK)
- {
- ec_inodelk(fop->req_frame, fop->xl, mask, 1,
- ec_lock_unlocked, NULL, fop->str[0],
- &fop->loc[0], F_SETLK, &flock,
- fop->xdata);
- }
- else
- {
- ec_finodelk(fop->req_frame, fop->xl, mask, 1,
- ec_lock_unlocked, NULL, fop->str[0],
- fop->fd, F_SETLK, &flock, fop->xdata);
- }
- }
- if (fop->error > 0)
- {
- return EC_STATE_REPORT;
- }
-
- fop->error = 0;
-
- fop->int32 = F_SETLKW;
-
- ec_dispatch_inc(fop);
-
- return EC_STATE_PREPARE_ANSWER;
- }
- }
-
- return EC_STATE_REPORT;
-
- case EC_STATE_REPORT:
- cbk = fop->answer;
-
- GF_ASSERT(cbk != NULL);
-
- if (fop->id == GF_FOP_INODELK)
- {
- if (fop->cbks.inodelk != NULL)
- {
- fop->cbks.inodelk(fop->req_frame, fop, fop->xl,
- cbk->op_ret, cbk->op_errno, cbk->xdata);
- }
- }
- else
- {
- if (fop->cbks.finodelk != NULL)
- {
- fop->cbks.finodelk(fop->req_frame, fop, fop->xl,
- cbk->op_ret, cbk->op_errno, cbk->xdata);
- }
- }
-
- ec_wait_winds(fop);
-
- return EC_STATE_END;
-
- case -EC_STATE_INIT:
- case -EC_STATE_DISPATCH:
- case -EC_STATE_PREPARE_ANSWER:
- case -EC_STATE_REPORT:
- GF_ASSERT(fop->error != 0);
-
- if (fop->id == GF_FOP_INODELK)
- {
- if (fop->cbks.inodelk != NULL)
- {
- fop->cbks.inodelk(fop->req_frame, fop, fop->xl, -1,
- fop->error, NULL);
- }
- }
- else
- {
- if (fop->cbks.finodelk != NULL)
- {
- fop->cbks.finodelk(fop->req_frame, fop, fop->xl, -1,
- fop->error, NULL);
- }
- }
-
- ec_wait_winds(fop);
-
- return EC_STATE_END;
-
- default:
- gf_log(fop->xl->name, GF_LOG_ERROR, "Unhandled state %d for %s",
- state, ec_fop_name(fop->id));
-
- return EC_STATE_END;
- }
-}
-
-void ec_inodelk(call_frame_t * frame, xlator_t * this, uintptr_t target,
- int32_t minimum, fop_inodelk_cbk_t func, void * data,
- const char * volume, loc_t * loc, int32_t cmd,
- struct gf_flock * flock, dict_t * xdata)
-{
- ec_cbk_t callback = { .inodelk = func };
- ec_fop_data_t * fop = NULL;
- int32_t error = EIO;
-
- gf_log("ec", GF_LOG_TRACE, "EC(INODELK) %p", frame);
-
- VALIDATE_OR_GOTO(this, out);
- GF_VALIDATE_OR_GOTO(this->name, frame, out);
- GF_VALIDATE_OR_GOTO(this->name, this->private, out);
-
- fop = ec_fop_data_allocate(frame, this, GF_FOP_INODELK,
- EC_FLAG_UPDATE_LOC_INODE, target, minimum,
- ec_wind_inodelk, ec_manager_inodelk, callback,
- data);
- if (fop == NULL)
- {
- goto out;
- }
-
- fop->int32 = cmd;
-
- if (volume != NULL)
- {
- fop->str[0] = gf_strdup(volume);
- if (fop->str[0] == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to duplicate a string.");
-
- goto out;
- }
- }
- if (loc != NULL)
- {
- if (loc_copy(&fop->loc[0], loc) != 0)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to copy a location.");
-
- goto out;
- }
- }
- if (flock != NULL)
- {
- fop->flock.l_type = flock->l_type;
- fop->flock.l_whence = flock->l_whence;
- fop->flock.l_start = flock->l_start;
- fop->flock.l_len = flock->l_len;
- fop->flock.l_pid = flock->l_pid;
- fop->flock.l_owner.len = flock->l_owner.len;
- if (flock->l_owner.len > 0)
- {
- memcpy(fop->flock.l_owner.data, flock->l_owner.data,
- flock->l_owner.len);
- }
- }
- if (xdata != NULL)
- {
- fop->xdata = dict_ref(xdata);
- if (fop->xdata == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
- "dictionary.");
-
- goto out;
- }
- }
-
- error = 0;
-
-out:
- if (fop != NULL)
- {
- ec_manager(fop, error);
- }
- else
- {
- func(frame, NULL, this, -1, EIO, NULL);
- }
-}
-
-/* FOP: finodelk */
-
-int32_t ec_finodelk_cbk(call_frame_t * frame, void * cookie, xlator_t * this,
- int32_t op_ret, int32_t op_errno, dict_t * xdata)
-{
- ec_fop_data_t * fop = NULL;
- ec_cbk_data_t * cbk = NULL;
- int32_t idx = (int32_t)(uintptr_t)cookie;
-
- VALIDATE_OR_GOTO(this, out);
- GF_VALIDATE_OR_GOTO(this->name, frame, out);
- GF_VALIDATE_OR_GOTO(this->name, frame->local, out);
- GF_VALIDATE_OR_GOTO(this->name, this->private, out);
-
- fop = frame->local;
-
- ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx,
- frame, op_ret, op_errno);
-
- cbk = ec_cbk_data_allocate(frame, this, fop, GF_FOP_FINODELK, idx, op_ret,
- op_errno);
- if (cbk != NULL)
- {
- if (xdata != NULL)
- {
- cbk->xdata = dict_ref(xdata);
- if (cbk->xdata == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
- "dictionary.");
-
- goto out;
- }
- }
-
- ec_combine(cbk, NULL);
- }
-
-out:
- if (fop != NULL)
- {
- ec_complete(fop);
- }
-
- return 0;
-}
-
-void ec_wind_finodelk(ec_t * ec, ec_fop_data_t * fop, int32_t idx)
-{
- ec_trace("WIND", fop, "idx=%d", idx);
-
- STACK_WIND_COOKIE(fop->frame, ec_finodelk_cbk, (void *)(uintptr_t)idx,
- ec->xl_list[idx], ec->xl_list[idx]->fops->finodelk,
- fop->str[0], fop->fd, fop->int32, &fop->flock,
- fop->xdata);
-}
-
-void ec_finodelk(call_frame_t * frame, xlator_t * this, uintptr_t target,
- int32_t minimum, fop_finodelk_cbk_t func, void * data,
- const char * volume, fd_t * fd, int32_t cmd,
- struct gf_flock * flock, dict_t * xdata)
-{
- ec_cbk_t callback = { .finodelk = func };
- ec_fop_data_t * fop = NULL;
- int32_t error = EIO;
-
- gf_log("ec", GF_LOG_TRACE, "EC(FINODELK) %p", frame);
-
- VALIDATE_OR_GOTO(this, out);
- GF_VALIDATE_OR_GOTO(this->name, frame, out);
- GF_VALIDATE_OR_GOTO(this->name, this->private, out);
-
- fop = ec_fop_data_allocate(frame, this, GF_FOP_FINODELK,
- EC_FLAG_UPDATE_FD_INODE, target, minimum,
- ec_wind_finodelk, ec_manager_inodelk, callback,
- data);
- if (fop == NULL)
- {
- goto out;
- }
-
- fop->use_fd = 1;
-
- fop->int32 = cmd;
-
- if (volume != NULL)
- {
- fop->str[0] = gf_strdup(volume);
- if (fop->str[0] == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to duplicate a string.");
-
- goto out;
- }
- }
- if (fd != NULL)
- {
- fop->fd = fd_ref(fd);
- if (fop->fd == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
- "file descriptor.");
-
- goto out;
- }
- }
- if (flock != NULL)
- {
- fop->flock.l_type = flock->l_type;
- fop->flock.l_whence = flock->l_whence;
- fop->flock.l_start = flock->l_start;
- fop->flock.l_len = flock->l_len;
- fop->flock.l_pid = flock->l_pid;
- fop->flock.l_owner.len = flock->l_owner.len;
- if (flock->l_owner.len > 0)
- {
- memcpy(fop->flock.l_owner.data, flock->l_owner.data,
- flock->l_owner.len);
- }
- }
- if (xdata != NULL)
- {
- fop->xdata = dict_ref(xdata);
- if (fop->xdata == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
- "dictionary.");
-
- goto out;
- }
- }
-
- error = 0;
-
-out:
- if (fop != NULL)
- {
- ec_manager(fop, error);
- }
- else
- {
- func(frame, NULL, this, -1, EIO, NULL);
- }
-}
-
-/* FOP: lk */
-
-int32_t ec_combine_lk(ec_fop_data_t * fop, ec_cbk_data_t * dst,
- ec_cbk_data_t * src)
-{
- if (!ec_flock_compare(&dst->flock, &src->flock))
- {
- gf_log(fop->xl->name, GF_LOG_NOTICE, "Mismatching lock in "
- "answers of 'GF_FOP_LK'");
-
- return 0;
- }
-
- return 1;
-}
-
-int32_t ec_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)
-{
- ec_fop_data_t * fop = NULL;
- ec_cbk_data_t * cbk = NULL;
- int32_t idx = (int32_t)(uintptr_t)cookie;
-
- VALIDATE_OR_GOTO(this, out);
- GF_VALIDATE_OR_GOTO(this->name, frame, out);
- GF_VALIDATE_OR_GOTO(this->name, frame->local, out);
- GF_VALIDATE_OR_GOTO(this->name, this->private, out);
-
- fop = frame->local;
-
- ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx,
- frame, op_ret, op_errno);
-
- cbk = ec_cbk_data_allocate(frame, this, fop, GF_FOP_LK, idx, op_ret,
- op_errno);
- if (cbk != NULL)
- {
- if (op_ret >= 0)
- {
- if (flock != NULL)
- {
- cbk->flock.l_type = flock->l_type;
- cbk->flock.l_whence = flock->l_whence;
- cbk->flock.l_start = flock->l_start;
- cbk->flock.l_len = flock->l_len;
- cbk->flock.l_pid = flock->l_pid;
- cbk->flock.l_owner.len = flock->l_owner.len;
- if (flock->l_owner.len > 0)
- {
- memcpy(cbk->flock.l_owner.data, flock->l_owner.data,
- flock->l_owner.len);
- }
- }
- }
- if (xdata != NULL)
- {
- cbk->xdata = dict_ref(xdata);
- if (cbk->xdata == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
- "dictionary.");
-
- goto out;
- }
- }
-
- ec_combine(cbk, ec_combine_lk);
- }
-
-out:
- if (fop != NULL)
- {
- ec_complete(fop);
- }
-
- return 0;
-}
-
-void ec_wind_lk(ec_t * ec, ec_fop_data_t * fop, int32_t idx)
-{
- ec_trace("WIND", fop, "idx=%d", idx);
-
- STACK_WIND_COOKIE(fop->frame, ec_lk_cbk, (void *)(uintptr_t)idx,
- ec->xl_list[idx], ec->xl_list[idx]->fops->lk, fop->fd,
- fop->int32, &fop->flock, fop->xdata);
-}
-
-int32_t ec_manager_lk(ec_fop_data_t * fop, int32_t state)
-{
- ec_cbk_data_t * cbk;
-
- switch (state)
- {
- case EC_STATE_INIT:
- fop->flock.l_len += ec_adjust_offset(fop->xl->private,
- &fop->flock.l_start, 1);
- fop->flock.l_len = ec_adjust_size(fop->xl->private,
- fop->flock.l_len, 1);
- if ((fop->int32 == F_SETLKW) && (fop->flock.l_type != F_UNLCK))
- {
- fop->uint32 = EC_LOCK_MODE_ALL;
- fop->int32 = F_SETLK;
- }
-
- /* Fall through */
-
- case EC_STATE_DISPATCH:
- ec_dispatch_all(fop);
-
- return EC_STATE_PREPARE_ANSWER;
-
- case EC_STATE_PREPARE_ANSWER:
- cbk = fop->answer;
- if ((cbk == NULL) ||
- ((cbk->op_ret < 0) && (cbk->op_errno == EAGAIN)))
- {
- uintptr_t mask;
-
- fop->error = ec_lock_check(fop, &cbk, &mask);
- if (fop->error != 0)
- {
- if (mask != 0)
- {
- ec_t * ec = fop->xl->private;
- struct gf_flock flock;
-
- flock.l_type = F_UNLCK;
- flock.l_whence = fop->flock.l_whence;
- flock.l_start = fop->flock.l_start * ec->fragments;
- flock.l_len = fop->flock.l_len * ec->fragments;
- flock.l_pid = 0;
- flock.l_owner.len = 0;
-
- ec_lk(fop->req_frame, fop->xl, mask, 1,
- ec_lock_lk_unlocked, NULL, fop->fd, F_SETLK,
- &flock, fop->xdata);
- }
- if (fop->error > 0)
- {
- return EC_STATE_REPORT;
- }
-
- fop->error = 0;
-
- fop->int32 = F_SETLKW;
-
- ec_dispatch_inc(fop);
-
- return EC_STATE_PREPARE_ANSWER;
- }
- }
-
- return EC_STATE_REPORT;
-
- case EC_STATE_REPORT:
- cbk = fop->answer;
-
- GF_ASSERT(cbk != NULL);
-
- if (fop->cbks.lk != NULL)
- {
- fop->cbks.lk(fop->req_frame, fop, fop->xl, cbk->op_ret,
- cbk->op_errno, &cbk->flock, cbk->xdata);
- }
-
- ec_wait_winds(fop);
-
- return EC_STATE_END;
-
- case -EC_STATE_INIT:
- case -EC_STATE_DISPATCH:
- case -EC_STATE_PREPARE_ANSWER:
- case -EC_STATE_REPORT:
- GF_ASSERT(fop->error != 0);
-
- if (fop->cbks.lk != NULL)
- {
- fop->cbks.lk(fop->req_frame, fop, fop->xl, -1, fop->error,
- NULL, NULL);
- }
-
- ec_wait_winds(fop);
-
- return EC_STATE_END;
-
- default:
- gf_log(fop->xl->name, GF_LOG_ERROR, "Unhandled state %d for %s",
- state, ec_fop_name(fop->id));
-
- return EC_STATE_END;
- }
-}
-
-void ec_lk(call_frame_t * frame, xlator_t * this, uintptr_t target,
- int32_t minimum, fop_lk_cbk_t func, void * data, fd_t * fd,
- int32_t cmd, struct gf_flock * flock, dict_t * xdata)
-{
- ec_cbk_t callback = { .lk = func };
- ec_fop_data_t * fop = NULL;
- int32_t error = EIO;
-
- gf_log("ec", GF_LOG_TRACE, "EC(LK) %p", frame);
-
- VALIDATE_OR_GOTO(this, out);
- GF_VALIDATE_OR_GOTO(this->name, frame, out);
- GF_VALIDATE_OR_GOTO(this->name, this->private, out);
-
- fop = ec_fop_data_allocate(frame, this, GF_FOP_LK, EC_FLAG_UPDATE_FD_INODE,
- target, minimum, ec_wind_lk, ec_manager_lk,
- callback, data);
- if (fop == NULL)
- {
- goto out;
- }
-
- fop->use_fd = 1;
-
- fop->int32 = cmd;
-
- if (fd != NULL)
- {
- fop->fd = fd_ref(fd);
- if (fop->fd == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
- "file descriptor.");
-
- goto out;
- }
- }
- if (flock != NULL)
- {
- fop->flock.l_type = flock->l_type;
- fop->flock.l_whence = flock->l_whence;
- fop->flock.l_start = flock->l_start;
- fop->flock.l_len = flock->l_len;
- fop->flock.l_pid = flock->l_pid;
- fop->flock.l_owner.len = flock->l_owner.len;
- if (flock->l_owner.len > 0)
- {
- memcpy(fop->flock.l_owner.data, flock->l_owner.data,
- flock->l_owner.len);
- }
- }
- if (xdata != NULL)
- {
- fop->xdata = dict_ref(xdata);
- if (fop->xdata == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
- "dictionary.");
-
- goto out;
- }
- }
-
- error = 0;
-
-out:
- if (fop != NULL)
- {
- ec_manager(fop, error);
- }
- else
- {
- func(frame, NULL, this, -1, EIO, NULL, NULL);
- }
-}
diff --git a/xlators/cluster/ec/src/ec-mem-types.h b/xlators/cluster/ec/src/ec-mem-types.h
deleted file mode 100644
index 8a66fb912a5..00000000000
--- a/xlators/cluster/ec/src/ec-mem-types.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- Copyright (c) 2012-2014 DataLab, s.l. <http://www.datalab.es>
- 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 __EC_MEM_TYPES_H__
-#define __EC_MEM_TYPES_H__
-
-#include "mem-types.h"
-
-enum gf_ec_mem_types_
-{
- ec_mt_ec_t = gf_common_mt_end + 1,
- ec_mt_xlator_t,
- ec_mt_ec_inode_t,
- ec_mt_ec_fd_t,
- ec_mt_ec_heal_t,
- ec_mt_end
-};
-
-#endif /* __EC_MEM_TYPES_H__ */
diff --git a/xlators/cluster/ec/src/ec-method.c b/xlators/cluster/ec/src/ec-method.c
deleted file mode 100644
index faab0115cdd..00000000000
--- a/xlators/cluster/ec/src/ec-method.c
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- Copyright (c) 2012-2014 DataLab, s.l. <http://www.datalab.es>
- 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 <string.h>
-#include <inttypes.h>
-
-#include "ec-gf.h"
-#include "ec-method.h"
-
-static uint32_t GfPow[EC_GF_SIZE << 1];
-static uint32_t GfLog[EC_GF_SIZE << 1];
-
-void ec_method_initialize(void)
-{
- uint32_t i;
-
- GfPow[0] = 1;
- GfLog[0] = EC_GF_SIZE;
- for (i = 1; i < EC_GF_SIZE; i++)
- {
- GfPow[i] = GfPow[i - 1] << 1;
- if (GfPow[i] >= EC_GF_SIZE)
- {
- GfPow[i] ^= EC_GF_MOD;
- }
- GfPow[i + EC_GF_SIZE - 1] = GfPow[i];
- GfLog[GfPow[i] + EC_GF_SIZE - 1] = GfLog[GfPow[i]] = i;
- }
-}
-
-static uint32_t ec_method_mul(uint32_t a, uint32_t b)
-{
- if (a && b)
- {
- return GfPow[GfLog[a] + GfLog[b]];
- }
- return 0;
-}
-
-static uint32_t ec_method_div(uint32_t a, uint32_t b)
-{
- if (b)
- {
- if (a)
- {
- return GfPow[EC_GF_SIZE - 1 + GfLog[a] - GfLog[b]];
- }
- return 0;
- }
- return EC_GF_SIZE;
-}
-
-size_t ec_method_encode(size_t size, uint32_t columns, uint32_t row,
- uint8_t * in, uint8_t * out)
-{
- uint32_t i, j;
-
- size /= EC_METHOD_CHUNK_SIZE * columns;
- row++;
- for (j = 0; j < size; j++)
- {
- ec_gf_muladd[0](out, in, EC_METHOD_WIDTH);
- in += EC_METHOD_CHUNK_SIZE;
- for (i = 1; i < columns; i++)
- {
- ec_gf_muladd[row](out, in, EC_METHOD_WIDTH);
- in += EC_METHOD_CHUNK_SIZE;
- }
- out += EC_METHOD_CHUNK_SIZE;
- }
-
- return size * EC_METHOD_CHUNK_SIZE;
-}
-
-size_t ec_method_decode(size_t size, uint32_t columns, uint32_t * rows,
- uint8_t ** in, uint8_t * out)
-{
- uint32_t i, j, k, off, last, value;
- uint32_t f;
- uint8_t inv[EC_METHOD_MAX_FRAGMENTS][EC_METHOD_MAX_FRAGMENTS + 1];
- uint8_t mtx[EC_METHOD_MAX_FRAGMENTS][EC_METHOD_MAX_FRAGMENTS];
- uint8_t dummy[EC_METHOD_CHUNK_SIZE];
-
- size /= EC_METHOD_CHUNK_SIZE;
-
- memset(inv, 0, sizeof(inv));
- memset(mtx, 0, sizeof(mtx));
- memset(dummy, 0, sizeof(dummy));
- for (i = 0; i < columns; i++)
- {
- inv[i][i] = 1;
- inv[i][columns] = 1;
- }
- for (i = 0; i < columns; i++)
- {
- mtx[i][columns - 1] = 1;
- for (j = columns - 1; j > 0; j--)
- {
- mtx[i][j - 1] = ec_method_mul(mtx[i][j], rows[i] + 1);
- }
- }
-
- for (i = 0; i < columns; i++)
- {
- f = mtx[i][i];
- for (j = 0; j < columns; j++)
- {
- mtx[i][j] = ec_method_div(mtx[i][j], f);
- inv[i][j] = ec_method_div(inv[i][j], f);
- }
- for (j = 0; j < columns; j++)
- {
- if (i != j)
- {
- f = mtx[j][i];
- for (k = 0; k < columns; k++)
- {
- mtx[j][k] ^= ec_method_mul(mtx[i][k], f);
- inv[j][k] ^= ec_method_mul(inv[i][k], f);
- }
- }
- }
- }
- off = 0;
- for (f = 0; f < size; f++)
- {
- for (i = 0; i < columns; i++)
- {
- last = 0;
- j = 0;
- do
- {
- while (inv[i][j] == 0)
- {
- j++;
- }
- if (j < columns)
- {
- value = ec_method_div(last, inv[i][j]);
- last = inv[i][j];
- ec_gf_muladd[value](out, in[j] + off, EC_METHOD_WIDTH);
- j++;
- }
- } while (j < columns);
- ec_gf_muladd[last](out, dummy, EC_METHOD_WIDTH);
- out += EC_METHOD_CHUNK_SIZE;
- }
- off += EC_METHOD_CHUNK_SIZE;
- }
-
- return size * EC_METHOD_CHUNK_SIZE * columns;
-}
diff --git a/xlators/cluster/ec/src/ec-method.h b/xlators/cluster/ec/src/ec-method.h
deleted file mode 100644
index 29b46e10443..00000000000
--- a/xlators/cluster/ec/src/ec-method.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- Copyright (c) 2012-2014 DataLab, s.l. <http://www.datalab.es>
- 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 __EC_METHOD_H__
-#define __EC_METHOD_H__
-
-#include "ec-gf.h"
-
-/* Determines the maximum size of the matrix used to encode/decode data */
-#define EC_METHOD_MAX_FRAGMENTS 16
-/* Determines the maximum number of usable elements in the Galois Field */
-#define EC_METHOD_MAX_NODES (EC_GF_SIZE - 1)
-
-#define EC_METHOD_WORD_SIZE 64
-
-#define EC_METHOD_CHUNK_SIZE (EC_METHOD_WORD_SIZE * EC_GF_BITS)
-#define EC_METHOD_WIDTH (EC_METHOD_WORD_SIZE / EC_GF_WORD_SIZE)
-
-void ec_method_initialize(void);
-size_t ec_method_encode(size_t size, uint32_t columns, uint32_t row,
- uint8_t * in, uint8_t * out);
-size_t ec_method_decode(size_t size, uint32_t columns, uint32_t * rows,
- uint8_t ** in, uint8_t * out);
-
-#endif /* __EC_METHOD_H__ */
diff --git a/xlators/cluster/ec/src/ec.c b/xlators/cluster/ec/src/ec.c
deleted file mode 100644
index 1d681d14c84..00000000000
--- a/xlators/cluster/ec/src/ec.c
+++ /dev/null
@@ -1,1029 +0,0 @@
-/*
- Copyright (c) 2012-2014 DataLab, s.l. <http://www.datalab.es>
- 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 "defaults.h"
-#include "statedump.h"
-#include "compat-errno.h"
-
-#include "ec-mem-types.h"
-#include "ec-helpers.h"
-#include "ec-common.h"
-#include "ec-fops.h"
-#include "ec-method.h"
-#include "ec.h"
-
-#define EC_MAX_FRAGMENTS EC_METHOD_MAX_FRAGMENTS
-/* The maximum number of nodes is derived from the maximum allowed fragments
- * using the rule that redundancy cannot be equal or greater than the number
- * of fragments.
- */
-#define EC_MAX_NODES min(EC_MAX_FRAGMENTS * 2 - 1, EC_METHOD_MAX_NODES)
-
-#define EC_INTERNAL_XATTR_OR_GOTO(name, xattr, op_errno, label) \
- do { \
- if (ec_is_internal_xattr (NULL, (char *)name, NULL, NULL)) { \
- op_errno = EPERM; \
- goto label; \
- } \
- if (name && (strlen (name) == 0) && xattr) { \
- /* Bulk [f]removexattr/[f]setxattr */ \
- GF_IF_INTERNAL_XATTR_GOTO (EC_XATTR_PREFIX"*", xattr, \
- op_errno, label); \
- } \
- } while (0)
-
-int32_t ec_parse_options(xlator_t * this)
-{
- ec_t * ec = this->private;
- int32_t error = EINVAL;
- uintptr_t mask;
-
- GF_OPTION_INIT("redundancy", ec->redundancy, int32, out);
- ec->fragments = ec->nodes - ec->redundancy;
- if ((ec->redundancy < 1) || (ec->redundancy >= ec->fragments) ||
- (ec->fragments > EC_MAX_FRAGMENTS))
- {
- gf_log(this->name, GF_LOG_ERROR, "Invalid redundancy (must be between "
- "1 and %d)", (ec->nodes - 1) / 2);
-
- goto out;
- }
-
- ec->bits_for_nodes = 1;
- mask = 2;
- while (ec->nodes > mask)
- {
- ec->bits_for_nodes++;
- mask <<= 1;
- }
- ec->node_mask = (1ULL << ec->nodes) - 1ULL;
- ec->fragment_size = EC_METHOD_CHUNK_SIZE;
- ec->stripe_size = ec->fragment_size * ec->fragments;
-
- gf_log("ec", GF_LOG_DEBUG, "Initialized with: nodes=%u, fragments=%u, "
- "stripe_size=%u, node_mask=%lX",
- ec->nodes, ec->fragments, ec->stripe_size, ec->node_mask);
-
- error = 0;
-
-out:
- return error;
-}
-
-int32_t ec_prepare_childs(xlator_t * this)
-{
- ec_t * ec = this->private;
- xlator_list_t * child = NULL;
- int32_t count = 0;
-
- for (child = this->children; child != NULL; child = child->next)
- {
- count++;
- }
- if (count > EC_MAX_NODES)
- {
- gf_log(this->name, GF_LOG_ERROR, "Too many subvolumes");
-
- return EINVAL;
- }
- ec->nodes = count;
-
- ec->xl_list = GF_CALLOC(count, sizeof(ec->xl_list[0]), ec_mt_xlator_t);
- if (ec->xl_list == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Allocation of xlator list failed");
-
- return ENOMEM;
- }
- ec->xl_up = 0;
- ec->xl_up_count = 0;
-
- count = 0;
- for (child = this->children; child != NULL; child = child->next)
- {
- ec->xl_list[count++] = child->xlator;
- }
-
- return 0;
-}
-
-void __ec_destroy_private(xlator_t * this)
-{
- ec_t * ec = this->private;
-
- if (ec != NULL)
- {
- LOCK(&ec->lock);
-
- if (ec->timer != NULL)
- {
- gf_timer_call_cancel(this->ctx, ec->timer);
- ec->timer = NULL;
- }
-
- UNLOCK(&ec->lock);
-
- /* There is a race with timer because there is no way to know if
- * timer callback has really been cancelled or it has been scheduled
- * for execution. If it has been scheduled, it will crash if we
- * destroy ec too fast.
- *
- * Not sure how this can be solved without using global variables or
- * having support from gf_timer_call_cancel()
- */
- sleep(2);
-
- this->private = NULL;
- if (ec->xl_list != NULL)
- {
- GF_FREE(ec->xl_list);
- ec->xl_list = NULL;
- }
-
- if (ec->fop_pool != NULL)
- {
- mem_pool_destroy(ec->fop_pool);
- }
-
- if (ec->cbk_pool != NULL)
- {
- mem_pool_destroy(ec->cbk_pool);
- }
-
- if (ec->lock_pool != NULL)
- {
- mem_pool_destroy(ec->lock_pool);
- }
-
- LOCK_DESTROY(&ec->lock);
-
- GF_FREE(ec);
- }
-}
-
-int32_t mem_acct_init(xlator_t * this)
-{
- if (xlator_mem_acct_init(this, ec_mt_end + 1) != 0)
- {
- gf_log(this->name, GF_LOG_ERROR, "Memory accounting initialization "
- "failed.");
-
- return -1;
- }
-
- return 0;
-}
-
-int32_t reconfigure(xlator_t * this, dict_t * options)
-{
- gf_log(this->name, GF_LOG_ERROR, "Online volume reconfiguration is not "
- "supported.");
-
- return -1;
-}
-
-glusterfs_event_t
-ec_get_event_from_state (ec_t *ec)
-{
- int down_count = 0;
-
- if (ec->xl_up_count >= ec->fragments) {
- /* If ec is up but some subvolumes are yet to notify, give
- * grace time for other subvols to notify to prevent start of
- * I/O which may result in self-heals */
- if (ec->timer && ec->xl_notify_count < ec->nodes)
- return GF_EVENT_MAXVAL;
-
- return GF_EVENT_CHILD_UP;
- } else {
- down_count = ec->xl_notify_count - ec->xl_up_count;
- if (down_count > ec->redundancy)
- return GF_EVENT_CHILD_DOWN;
- }
-
- return GF_EVENT_MAXVAL;
-}
-
-void
-ec_up (xlator_t *this, ec_t *ec)
-{
- if (ec->timer != NULL) {
- gf_timer_call_cancel (this->ctx, ec->timer);
- ec->timer = NULL;
- }
-
- ec->up = 1;
- gf_log(this->name, GF_LOG_INFO, "Going UP");
-}
-
-void
-ec_down (xlator_t *this, ec_t *ec)
-{
- if (ec->timer != NULL) {
- gf_timer_call_cancel(this->ctx, ec->timer);
- ec->timer = NULL;
- }
-
- ec->up = 0;
- gf_log(this->name, GF_LOG_INFO, "Going DOWN");
-}
-
-void
-ec_notify_cbk (void *data)
-{
- ec_t *ec = data;
- glusterfs_event_t event = GF_EVENT_MAXVAL;
-
- LOCK(&ec->lock);
- {
- if (!ec->timer) {
- /*
- * Either child_up/child_down is already sent to parent
- * This is a spurious wake up.
- */
- goto unlock;
- }
-
- gf_timer_call_cancel (ec->xl->ctx, ec->timer);
- ec->timer = NULL;
-
- event = ec_get_event_from_state (ec);
- /* If event is still MAXVAL then enough subvolumes didn't
- * notify, treat it as CHILD_DOWN. */
- if (event == GF_EVENT_MAXVAL) {
- event = GF_EVENT_CHILD_DOWN;
- ec->xl_notify = (1ULL << ec->nodes) - 1ULL;
- ec->xl_notify_count = ec->nodes;
- } else if (event == GF_EVENT_CHILD_UP) {
- /* Rest of the bricks are still not coming up,
- * notify that ec is up. Files/directories will be
- * healed as in when they come up. */
- ec_up (ec->xl, ec);
- }
-
- /* CHILD_DOWN should not come here as no grace period is given
- * for notifying CHILD_DOWN. */
-
- default_notify (ec->xl, event, NULL);
- }
-unlock:
- UNLOCK(&ec->lock);
-}
-
-void
-ec_launch_notify_timer (xlator_t *this, ec_t *ec)
-{
- struct timespec delay = {0, };
-
- gf_log (this->name, GF_LOG_DEBUG, "Initiating child-down timer");
- delay.tv_sec = 10;
- delay.tv_nsec = 0;
- ec->timer = gf_timer_call_after (this->ctx, delay, ec_notify_cbk, ec);
- if (ec->timer == NULL) {
- gf_log(this->name, GF_LOG_ERROR, "Cannot create timer "
- "for delayed initialization");
- }
-}
-
-void
-ec_handle_up (xlator_t *this, ec_t *ec, int32_t idx)
-{
- if (((ec->xl_notify >> idx) & 1) == 0) {
- ec->xl_notify |= 1ULL << idx;
- ec->xl_notify_count++;
- }
-
- if (((ec->xl_up >> idx) & 1) == 0) { /* Duplicate event */
- ec->xl_up |= 1ULL << idx;
- ec->xl_up_count++;
- }
-}
-
-void
-ec_handle_down (xlator_t *this, ec_t *ec, int32_t idx)
-{
- if (((ec->xl_notify >> idx) & 1) == 0) {
- ec->xl_notify |= 1ULL << idx;
- ec->xl_notify_count++;
- }
-
- if (((ec->xl_up >> idx) & 1) != 0) { /* Duplicate event */
- gf_log(this->name, GF_LOG_DEBUG, "Child %d is DOWN", idx);
-
- ec->xl_up ^= 1ULL << idx;
- ec->xl_up_count--;
- }
-}
-
-int32_t
-notify (xlator_t *this, int32_t event, void *data, ...)
-{
- ec_t * ec = this->private;
- int32_t idx = 0;
- int32_t error = 0;
- glusterfs_event_t old_event = GF_EVENT_MAXVAL;
- glusterfs_event_t new_event = GF_EVENT_MAXVAL;
-
- LOCK (&ec->lock);
-
- if (event == GF_EVENT_PARENT_UP) {
- /*
- * Start a timer which sends appropriate event to parent
- * xlator to prevent the 'mount' syscall from hanging.
- */
- ec_launch_notify_timer (this, ec);
- goto unlock;
- }
-
- for (idx = 0; idx < ec->nodes; idx++) {
- if (ec->xl_list[idx] == data)
- break;
- }
-
- gf_log (this->name, GF_LOG_TRACE, "NOTIFY(%d): %p, %d",
- event, data, idx);
-
- if (idx < ec->nodes) { /* CHILD_* events */
-
- old_event = ec_get_event_from_state (ec);
-
- if (event == GF_EVENT_CHILD_UP) {
- ec_handle_up (this, ec, idx);
- } else if (event == GF_EVENT_CHILD_DOWN) {
- ec_handle_down (this, ec, idx);
- }
-
- new_event = ec_get_event_from_state (ec);
-
- if (new_event == GF_EVENT_CHILD_UP && !ec->up) {
- ec_up (this, ec);
- } else if (new_event == GF_EVENT_CHILD_DOWN && ec->up) {
- ec_down (this, ec);
- }
-
- if ((new_event == old_event) && (new_event != GF_EVENT_MAXVAL))
- new_event = GF_EVENT_CHILD_MODIFIED;
-
- event = GF_EVENT_MAXVAL;/* Take care of notifying inside lock */
- if (new_event != GF_EVENT_MAXVAL)
- error = default_notify (this, new_event, data);
- }
-unlock:
- UNLOCK (&ec->lock);
-
- if (event != GF_EVENT_MAXVAL)
- return default_notify (this, event, data);
-
- return error;
-}
-
-int32_t init(xlator_t * this)
-{
- ec_t * ec;
-
- if (this->parents == NULL)
- {
- gf_log(this->name, GF_LOG_WARNING, "Volume does not have parents.");
- }
-
- ec = GF_MALLOC(sizeof(*ec), ec_mt_ec_t);
- if (ec == NULL)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to allocate private memory.");
-
- return -1;
- }
- memset(ec, 0, sizeof(*ec));
-
- this->private = ec;
-
- ec->xl = this;
- LOCK_INIT(&ec->lock);
-
- ec->fop_pool = mem_pool_new(ec_fop_data_t, 1024);
- ec->cbk_pool = mem_pool_new(ec_cbk_data_t, 4096);
- ec->lock_pool = mem_pool_new(ec_lock_t, 1024);
- if ((ec->fop_pool == NULL) || (ec->cbk_pool == NULL) ||
- (ec->lock_pool == NULL))
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to create memory pools.");
-
- goto failed;
- }
-
- if (ec_prepare_childs(this) != 0)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to initialize xlator");
-
- goto failed;
- }
-
- if (ec_parse_options(this) != 0)
- {
- gf_log(this->name, GF_LOG_ERROR, "Failed to parse xlator options");
-
- goto failed;
- }
-
- ec_method_initialize();
-
- gf_log(this->name, GF_LOG_DEBUG, "Disperse translator initialized.");
-
- return 0;
-
-failed:
- __ec_destroy_private(this);
-
- return -1;
-}
-
-void fini(xlator_t * this)
-{
- __ec_destroy_private(this);
-}
-
-int32_t ec_gf_access(call_frame_t * frame, xlator_t * this, loc_t * loc,
- int32_t mask, dict_t * xdata)
-{
- ec_access(frame, this, -1, EC_MINIMUM_ONE, default_access_cbk, NULL, loc,
- mask, xdata);
-
- return 0;
-}
-
-int32_t ec_gf_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)
-{
- ec_create(frame, this, -1, EC_MINIMUM_MIN, default_create_cbk, NULL, loc,
- flags, mode, umask, fd, xdata);
-
- return 0;
-}
-
-int32_t ec_gf_discard(call_frame_t * frame, xlator_t * this, fd_t * fd,
- off_t offset, size_t len, dict_t * xdata)
-{
- default_discard_failure_cbk(frame, ENOTSUP);
-
- return 0;
-}
-
-int32_t ec_gf_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)
-{
- ec_entrylk(frame, this, -1, EC_MINIMUM_ALL, default_entrylk_cbk, NULL,
- volume, loc, basename, cmd, type, xdata);
-
- return 0;
-}
-
-int32_t ec_gf_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)
-{
- ec_fentrylk(frame, this, -1, EC_MINIMUM_ALL, default_fentrylk_cbk, NULL,
- volume, fd, basename, cmd, type, xdata);
-
- return 0;
-}
-
-int32_t ec_gf_fallocate(call_frame_t * frame, xlator_t * this, fd_t * fd,
- int32_t keep_size, off_t offset, size_t len,
- dict_t * xdata)
-{
- default_fallocate_failure_cbk(frame, ENOTSUP);
-
- return 0;
-}
-
-int32_t ec_gf_flush(call_frame_t * frame, xlator_t * this, fd_t * fd,
- dict_t * xdata)
-{
- ec_flush(frame, this, -1, EC_MINIMUM_MIN, default_flush_cbk, NULL, fd,
- xdata);
-
- return 0;
-}
-
-int32_t ec_gf_fsync(call_frame_t * frame, xlator_t * this, fd_t * fd,
- int32_t datasync, dict_t * xdata)
-{
- ec_fsync(frame, this, -1, EC_MINIMUM_MIN, default_fsync_cbk, NULL, fd,
- datasync, xdata);
-
- return 0;
-}
-
-int32_t ec_gf_fsyncdir(call_frame_t * frame, xlator_t * this, fd_t * fd,
- int32_t datasync, dict_t * xdata)
-{
- ec_fsyncdir(frame, this, -1, EC_MINIMUM_MIN, default_fsyncdir_cbk, NULL,
- fd, datasync, xdata);
-
- return 0;
-}
-
-int32_t
-ec_gf_getxattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
- const char *name, dict_t *xdata)
-{
- int error = 0;
-
- if (name && strcmp (name, EC_XATTR_HEAL) != 0) {
- EC_INTERNAL_XATTR_OR_GOTO(name, NULL, error, out);
- }
-
- ec_getxattr (frame, this, -1, EC_MINIMUM_MIN, default_getxattr_cbk,
- NULL, loc, name, xdata);
-
- return 0;
-out:
- error = ENODATA;
- STACK_UNWIND_STRICT (getxattr, frame, -1, error, NULL, NULL);
- return 0;
-}
-
-int32_t
-ec_gf_fgetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
- const char *name, dict_t *xdata)
-{
- int error = 0;
-
- EC_INTERNAL_XATTR_OR_GOTO(name, NULL, error, out);
-
- ec_fgetxattr (frame, this, -1, EC_MINIMUM_MIN, default_fgetxattr_cbk,
- NULL, fd, name, xdata);
- return 0;
-out:
- error = ENODATA;
- STACK_UNWIND_STRICT (fgetxattr, frame, -1, error, NULL, NULL);
- return 0;
-}
-
-int32_t ec_gf_inodelk(call_frame_t * frame, xlator_t * this,
- const char * volume, loc_t * loc, int32_t cmd,
- struct gf_flock * flock, dict_t * xdata)
-{
- ec_inodelk(frame, this, -1, EC_MINIMUM_ALL, default_inodelk_cbk, NULL,
- volume, loc, cmd, flock, xdata);
-
- return 0;
-}
-
-int32_t ec_gf_finodelk(call_frame_t * frame, xlator_t * this,
- const char * volume, fd_t * fd, int32_t cmd,
- struct gf_flock * flock, dict_t * xdata)
-{
- ec_finodelk(frame, this, -1, EC_MINIMUM_ALL, default_finodelk_cbk, NULL,
- volume, fd, cmd, flock, xdata);
-
- return 0;
-}
-
-int32_t ec_gf_link(call_frame_t * frame, xlator_t * this, loc_t * oldloc,
- loc_t * newloc, dict_t * xdata)
-{
- ec_link(frame, this, -1, EC_MINIMUM_MIN, default_link_cbk, NULL, oldloc,
- newloc, xdata);
-
- return 0;
-}
-
-int32_t ec_gf_lk(call_frame_t * frame, xlator_t * this, fd_t * fd,
- int32_t cmd, struct gf_flock * flock, dict_t * xdata)
-{
- ec_lk(frame, this, -1, EC_MINIMUM_ALL, default_lk_cbk, NULL, fd, cmd,
- flock, xdata);
-
- return 0;
-}
-
-int32_t ec_gf_lookup(call_frame_t * frame, xlator_t * this, loc_t * loc,
- dict_t * xdata)
-{
- ec_lookup(frame, this, -1, EC_MINIMUM_MIN, default_lookup_cbk, NULL, loc,
- xdata);
-
- return 0;
-}
-
-int32_t ec_gf_mkdir(call_frame_t * frame, xlator_t * this, loc_t * loc,
- mode_t mode, mode_t umask, dict_t * xdata)
-{
- ec_mkdir(frame, this, -1, EC_MINIMUM_MIN, default_mkdir_cbk, NULL, loc,
- mode, umask, xdata);
-
- return 0;
-}
-
-int32_t ec_gf_mknod(call_frame_t * frame, xlator_t * this, loc_t * loc,
- mode_t mode, dev_t rdev, mode_t umask, dict_t * xdata)
-{
- ec_mknod(frame, this, -1, EC_MINIMUM_MIN, default_mknod_cbk, NULL, loc,
- mode, rdev, umask, xdata);
-
- return 0;
-}
-
-int32_t ec_gf_open(call_frame_t * frame, xlator_t * this, loc_t * loc,
- int32_t flags, fd_t * fd, dict_t * xdata)
-{
- ec_open(frame, this, -1, EC_MINIMUM_MIN, default_open_cbk, NULL, loc,
- flags, fd, xdata);
-
- return 0;
-}
-
-int32_t ec_gf_opendir(call_frame_t * frame, xlator_t * this, loc_t * loc,
- fd_t * fd, dict_t * xdata)
-{
- ec_opendir(frame, this, -1, EC_MINIMUM_MIN, default_opendir_cbk, NULL, loc,
- fd, xdata);
-
- return 0;
-}
-
-int32_t ec_gf_readdir(call_frame_t * frame, xlator_t * this, fd_t * fd,
- size_t size, off_t offset, dict_t * xdata)
-{
- ec_readdir(frame, this, -1, EC_MINIMUM_ONE, default_readdir_cbk, NULL, fd,
- size, offset, xdata);
-
- return 0;
-}
-
-int32_t ec_gf_readdirp(call_frame_t * frame, xlator_t * this, fd_t * fd,
- size_t size, off_t offset, dict_t * xdata)
-{
- ec_readdirp(frame, this, -1, EC_MINIMUM_ONE, default_readdirp_cbk, NULL,
- fd, size, offset, xdata);
-
- return 0;
-}
-
-int32_t ec_gf_readlink(call_frame_t * frame, xlator_t * this, loc_t * loc,
- size_t size, dict_t * xdata)
-{
- ec_readlink(frame, this, -1, EC_MINIMUM_ONE, default_readlink_cbk, NULL,
- loc, size, xdata);
-
- return 0;
-}
-
-int32_t ec_gf_readv(call_frame_t * frame, xlator_t * this, fd_t * fd,
- size_t size, off_t offset, uint32_t flags, dict_t * xdata)
-{
- ec_readv(frame, this, -1, EC_MINIMUM_MIN, default_readv_cbk, NULL, fd,
- size, offset, flags, xdata);
-
- return 0;
-}
-
-int32_t
-ec_gf_removexattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
- const char *name, dict_t *xdata)
-{
- int error = 0;
-
- EC_INTERNAL_XATTR_OR_GOTO (name, xdata, error, out);
-
- ec_removexattr (frame, this, -1, EC_MINIMUM_MIN,
- default_removexattr_cbk, NULL, loc, name, xdata);
-
- return 0;
-out:
- STACK_UNWIND_STRICT (removexattr, frame, -1, error, NULL);
- return 0;
-}
-
-int32_t
-ec_gf_fremovexattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
- const char *name, dict_t *xdata)
-{
- int error = 0;
-
- EC_INTERNAL_XATTR_OR_GOTO (name, xdata, error, out);
-
- ec_fremovexattr (frame, this, -1, EC_MINIMUM_MIN,
- default_fremovexattr_cbk, NULL, fd, name, xdata);
-
- return 0;
-out:
- STACK_UNWIND_STRICT (fremovexattr, frame, -1, error, NULL);
- return 0;
-}
-
-int32_t ec_gf_rename(call_frame_t * frame, xlator_t * this, loc_t * oldloc,
- loc_t * newloc, dict_t * xdata)
-{
- ec_rename(frame, this, -1, EC_MINIMUM_MIN, default_rename_cbk, NULL,
- oldloc, newloc, xdata);
-
- return 0;
-}
-
-int32_t ec_gf_rmdir(call_frame_t * frame, xlator_t * this, loc_t * loc,
- int xflags, dict_t * xdata)
-{
- ec_rmdir(frame, this, -1, EC_MINIMUM_MIN, default_rmdir_cbk, NULL, loc,
- xflags, xdata);
-
- return 0;
-}
-
-int32_t ec_gf_setattr(call_frame_t * frame, xlator_t * this, loc_t * loc,
- struct iatt * stbuf, int32_t valid, dict_t * xdata)
-{
- ec_setattr(frame, this, -1, EC_MINIMUM_MIN, default_setattr_cbk, NULL, loc,
- stbuf, valid, xdata);
-
- return 0;
-}
-
-int32_t ec_gf_fsetattr(call_frame_t * frame, xlator_t * this, fd_t * fd,
- struct iatt * stbuf, int32_t valid, dict_t * xdata)
-{
- ec_fsetattr(frame, this, -1, EC_MINIMUM_MIN, default_fsetattr_cbk, NULL,
- fd, stbuf, valid, xdata);
-
- return 0;
-}
-
-int32_t
-ec_gf_setxattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
- dict_t *dict, int32_t flags, dict_t *xdata)
-{
- int error = 0;
-
- EC_INTERNAL_XATTR_OR_GOTO ("", dict, error, out);
-
- ec_setxattr (frame, this, -1, EC_MINIMUM_MIN, default_setxattr_cbk,
- NULL, loc, dict, flags, xdata);
-
- return 0;
-out:
- STACK_UNWIND_STRICT (setxattr, frame, -1, error, NULL);
- return 0;
-}
-
-int32_t
-ec_gf_fsetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
- dict_t *dict, int32_t flags, dict_t *xdata)
-{
- int error = 0;
-
- EC_INTERNAL_XATTR_OR_GOTO ("", dict, error, out);
-
- ec_fsetxattr (frame, this, -1, EC_MINIMUM_MIN, default_fsetxattr_cbk,
- NULL, fd, dict, flags, xdata);
-
- return 0;
-out:
- STACK_UNWIND_STRICT (fsetxattr, frame, -1, error, NULL);
- return 0;
-}
-
-int32_t ec_gf_stat(call_frame_t * frame, xlator_t * this, loc_t * loc,
- dict_t * xdata)
-{
- ec_stat(frame, this, -1, EC_MINIMUM_MIN, default_stat_cbk, NULL, loc,
- xdata);
-
- return 0;
-}
-
-int32_t ec_gf_fstat(call_frame_t * frame, xlator_t * this, fd_t * fd,
- dict_t * xdata)
-{
- ec_fstat(frame, this, -1, EC_MINIMUM_MIN, default_fstat_cbk, NULL, fd,
- xdata);
-
- return 0;
-}
-
-int32_t ec_gf_statfs(call_frame_t * frame, xlator_t * this, loc_t * loc,
- dict_t * xdata)
-{
- ec_statfs(frame, this, -1, EC_MINIMUM_MIN, default_statfs_cbk, NULL, loc,
- xdata);
-
- return 0;
-}
-
-int32_t ec_gf_symlink(call_frame_t * frame, xlator_t * this,
- const char * linkname, loc_t * loc, mode_t umask,
- dict_t * xdata)
-{
- ec_symlink(frame, this, -1, EC_MINIMUM_MIN, default_symlink_cbk, NULL,
- linkname, loc, umask, xdata);
-
- return 0;
-}
-
-int32_t ec_gf_truncate(call_frame_t * frame, xlator_t * this, loc_t * loc,
- off_t offset, dict_t * xdata)
-{
- ec_truncate(frame, this, -1, EC_MINIMUM_MIN, default_truncate_cbk, NULL,
- loc, offset, xdata);
-
- return 0;
-}
-
-int32_t ec_gf_ftruncate(call_frame_t * frame, xlator_t * this, fd_t * fd,
- off_t offset, dict_t * xdata)
-{
- ec_ftruncate(frame, this, -1, EC_MINIMUM_MIN, default_ftruncate_cbk, NULL,
- fd, offset, xdata);
-
- return 0;
-}
-
-int32_t ec_gf_unlink(call_frame_t * frame, xlator_t * this, loc_t * loc,
- int xflags, dict_t * xdata)
-{
- ec_unlink(frame, this, -1, EC_MINIMUM_MIN, default_unlink_cbk, NULL, loc,
- xflags, xdata);
-
- return 0;
-}
-
-int32_t ec_gf_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)
-{
- ec_writev(frame, this, -1, EC_MINIMUM_MIN, default_writev_cbk, NULL, fd,
- vector, count, offset, flags, iobref, xdata);
-
- return 0;
-}
-
-int32_t ec_gf_xattrop(call_frame_t * frame, xlator_t * this, loc_t * loc,
- gf_xattrop_flags_t optype, dict_t * xattr,
- dict_t * xdata)
-{
- ec_xattrop(frame, this, -1, EC_MINIMUM_MIN, default_xattrop_cbk, NULL, loc,
- optype, xattr, xdata);
-
- return 0;
-}
-
-int32_t ec_gf_fxattrop(call_frame_t * frame, xlator_t * this, fd_t * fd,
- gf_xattrop_flags_t optype, dict_t * xattr,
- dict_t * xdata)
-{
- ec_fxattrop(frame, this, -1, EC_MINIMUM_MIN, default_fxattrop_cbk, NULL,
- fd, optype, xattr, xdata);
-
- return 0;
-}
-
-int32_t ec_gf_zerofill(call_frame_t * frame, xlator_t * this, fd_t * fd,
- off_t offset, off_t len, dict_t * xdata)
-{
- default_zerofill_failure_cbk(frame, ENOTSUP);
-
- return 0;
-}
-
-int32_t ec_gf_forget(xlator_t * this, inode_t * inode)
-{
- uint64_t value = 0;
- ec_inode_t * ctx = NULL;
-
- if ((inode_ctx_del(inode, this, &value) == 0) && (value != 0))
- {
- ctx = (ec_inode_t *)(uintptr_t)value;
- GF_FREE(ctx);
- }
-
- return 0;
-}
-
-void ec_gf_release_fd(xlator_t * this, fd_t * fd)
-{
- uint64_t value = 0;
- ec_fd_t * ctx = NULL;
-
- if ((fd_ctx_del(fd, this, &value) == 0) && (value != 0))
- {
- ctx = (ec_fd_t *)(uintptr_t)value;
- loc_wipe(&ctx->loc);
- GF_FREE(ctx);
- }
-}
-
-int32_t ec_gf_release(xlator_t * this, fd_t * fd)
-{
- ec_gf_release_fd(this, fd);
-
- return 0;
-}
-
-int32_t ec_gf_releasedir(xlator_t * this, fd_t * fd)
-{
- ec_gf_release_fd(this, fd);
-
- return 0;
-}
-
-int32_t ec_dump_private(xlator_t *this)
-{
- ec_t *ec = NULL;
- char key_prefix[GF_DUMP_MAX_BUF_LEN];
- char tmp[65];
-
- GF_ASSERT(this);
-
- ec = this->private;
- GF_ASSERT(ec);
-
- 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("nodes", "%u", ec->nodes);
- gf_proc_dump_write("redundancy", "%u", ec->redundancy);
- gf_proc_dump_write("fragment_size", "%u", ec->fragment_size);
- gf_proc_dump_write("stripe_size", "%u", ec->stripe_size);
- gf_proc_dump_write("childs_up", "%u", ec->xl_up_count);
- gf_proc_dump_write("childs_up_mask", "%s",
- ec_bin(tmp, sizeof(tmp), ec->xl_up, ec->nodes));
-
- return 0;
-}
-
-struct xlator_fops fops =
-{
- .lookup = ec_gf_lookup,
- .stat = ec_gf_stat,
- .fstat = ec_gf_fstat,
- .truncate = ec_gf_truncate,
- .ftruncate = ec_gf_ftruncate,
- .access = ec_gf_access,
- .readlink = ec_gf_readlink,
- .mknod = ec_gf_mknod,
- .mkdir = ec_gf_mkdir,
- .unlink = ec_gf_unlink,
- .rmdir = ec_gf_rmdir,
- .symlink = ec_gf_symlink,
- .rename = ec_gf_rename,
- .link = ec_gf_link,
- .create = ec_gf_create,
- .open = ec_gf_open,
- .readv = ec_gf_readv,
- .writev = ec_gf_writev,
- .flush = ec_gf_flush,
- .fsync = ec_gf_fsync,
- .opendir = ec_gf_opendir,
- .readdir = ec_gf_readdir,
- .readdirp = ec_gf_readdirp,
- .fsyncdir = ec_gf_fsyncdir,
- .statfs = ec_gf_statfs,
- .setxattr = ec_gf_setxattr,
- .getxattr = ec_gf_getxattr,
- .fsetxattr = ec_gf_fsetxattr,
- .fgetxattr = ec_gf_fgetxattr,
- .removexattr = ec_gf_removexattr,
- .fremovexattr = ec_gf_fremovexattr,
- .lk = ec_gf_lk,
- .inodelk = ec_gf_inodelk,
- .finodelk = ec_gf_finodelk,
- .entrylk = ec_gf_entrylk,
- .fentrylk = ec_gf_fentrylk,
- .xattrop = ec_gf_xattrop,
- .fxattrop = ec_gf_fxattrop,
- .setattr = ec_gf_setattr,
- .fsetattr = ec_gf_fsetattr,
- .fallocate = ec_gf_fallocate,
- .discard = ec_gf_discard,
- .zerofill = ec_gf_zerofill
-};
-
-struct xlator_cbks cbks =
-{
- .forget = ec_gf_forget,
- .release = ec_gf_release,
- .releasedir = ec_gf_releasedir
-};
-
-struct xlator_dumpops dumpops = {
- .priv = ec_dump_private
-};
-
-struct volume_options options[] =
-{
- {
- .key = { "redundancy" },
- .type = GF_OPTION_TYPE_INT,
- .description = "Maximum number of bricks that can fail "
- "simultaneously without losing data."
- },
- { }
-};
diff --git a/xlators/cluster/ec/src/ec.h b/xlators/cluster/ec/src/ec.h
deleted file mode 100644
index 6a976980074..00000000000
--- a/xlators/cluster/ec/src/ec.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- Copyright (c) 2012-2014 DataLab, s.l. <http://www.datalab.es>
- 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 __EC_H__
-#define __EC_H__
-
-#include "xlator.h"
-#include "timer.h"
-
-#define EC_XATTR_PREFIX "trusted.ec."
-#define EC_XATTR_CONFIG EC_XATTR_PREFIX"config"
-#define EC_XATTR_SIZE EC_XATTR_PREFIX"size"
-#define EC_XATTR_VERSION EC_XATTR_PREFIX"version"
-#define EC_XATTR_HEAL EC_XATTR_PREFIX"heal"
-
-struct _ec;
-typedef struct _ec ec_t;
-
-struct _ec
-{
- xlator_t * xl;
- int32_t nodes;
- int32_t bits_for_nodes;
- int32_t fragments;
- int32_t redundancy;
- uint32_t fragment_size;
- uint32_t stripe_size;
- int32_t up;
- uint32_t idx;
- uint32_t xl_up_count;
- uintptr_t xl_up;
- uint32_t xl_notify_count;
- uintptr_t xl_notify;
- uintptr_t node_mask;
- xlator_t ** xl_list;
- gf_lock_t lock;
- gf_timer_t * timer;
- struct mem_pool * fop_pool;
- struct mem_pool * cbk_pool;
- struct mem_pool * lock_pool;
-};
-
-#endif /* __EC_H__ */
diff --git a/xlators/cluster/ha/src/Makefile.am b/xlators/cluster/ha/src/Makefile.am
index 5c1364b7f9d..5f78a296533 100644
--- a/xlators/cluster/ha/src/Makefile.am
+++ b/xlators/cluster/ha/src/Makefile.am
@@ -1,16 +1,15 @@
xlator_LTLIBRARIES = ha.la
xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/testing/cluster
-ha_la_LDFLAGS = -module -avoid-version
+ha_la_LDFLAGS = -module -avoidversion
ha_la_SOURCES = ha-helpers.c ha.c
ha_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la
noinst_HEADERS = ha.h
-AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src
-
-AM_CFLAGS = -Wall $(GF_CFLAGS)
+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/ha/src/ha-helpers.c b/xlators/cluster/ha/src/ha-helpers.c
index 19be1ed2773..c23c5676ce0 100644
--- a/xlators/cluster/ha/src/ha-helpers.c
+++ b/xlators/cluster/ha/src/ha-helpers.c
@@ -1,12 +1,22 @@
/*
- 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-2009 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 "xlator.h"
#include "call-stub.h"
#include "defaults.h"
@@ -39,14 +49,12 @@ int ha_alloc_init_fd (call_frame_t *frame, fd_t *fd)
goto out;
}
hafdp = (hafd_t *)(long)tmp_hafdp;
- local = frame->local = GF_CALLOC (1, sizeof (*local),
- gf_ha_mt_ha_local_t);
+ local = frame->local = CALLOC (1, sizeof (*local));
if (local == NULL) {
ret = -ENOMEM;
goto out;
}
- local->state = GF_CALLOC (1, child_count,
- gf_ha_mt_child_count);
+ local->state = CALLOC (1, child_count);
if (local->state == NULL) {
ret = -ENOMEM;
goto out;
@@ -139,7 +147,7 @@ int ha_handle_cbk (call_frame_t *frame, void *cookie, int op_ret, int op_errno)
}
if (local->fd) {
- GF_FREE (local->state);
+ FREE (local->state);
local->state = NULL;
fd_unref (local->fd);
@@ -162,8 +170,7 @@ int ha_alloc_init_inode (call_frame_t *frame, inode_t *inode)
local = frame->local;
if (local == NULL) {
- local = frame->local = GF_CALLOC (1, sizeof (*local),
- gf_ha_mt_ha_local_t);
+ local = frame->local = CALLOC (1, sizeof (*local));
if (local == NULL) {
ret = -ENOMEM;
goto out;
diff --git a/xlators/cluster/ha/src/ha-mem-types.h b/xlators/cluster/ha/src/ha-mem-types.h
deleted file mode 100644
index e5e97d237dc..00000000000
--- a/xlators/cluster/ha/src/ha-mem-types.h
+++ /dev/null
@@ -1,26 +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 __HA_MEM_TYPES_H__
-#define __HA_MEM_TYPES_H__
-
-#include "mem-types.h"
-
-enum gf_ha_mem_types_ {
- gf_ha_mt_ha_local_t = gf_common_mt_end + 1,
- gf_ha_mt_hafd_t,
- gf_ha_mt_char,
- gf_ha_mt_child_count,
- gf_ha_mt_xlator_t,
- gf_ha_mt_ha_private_t,
- gf_ha_mt_end
-};
-#endif
-
diff --git a/xlators/cluster/ha/src/ha.c b/xlators/cluster/ha/src/ha.c
index 742ec46f107..442de21df5d 100644
--- a/xlators/cluster/ha/src/ha.c
+++ b/xlators/cluster/ha/src/ha.c
@@ -1,12 +1,22 @@
/*
- 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-2009 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/>.
*/
+
/* generate errors randomly, code is simple now, better alogorithm
* can be written to decide what error to be returned and when
*/
@@ -40,7 +50,7 @@ ha_local_wipe (ha_local_t *local)
}
if (local->state) {
- GF_FREE (local->state);
+ FREE (local->state);
local->state = NULL;
}
@@ -61,7 +71,7 @@ ha_local_wipe (ha_local_t *local)
local->inode = NULL;
}
- GF_FREE (local);
+ FREE (local);
return;
}
@@ -74,7 +84,7 @@ ha_forget (xlator_t *this,
char *state = NULL;
if (!inode_ctx_del (inode, this, &stateino)) {
state = ((char *)(long)stateino);
- GF_FREE (state);
+ FREE (state);
}
return 0;
@@ -88,9 +98,9 @@ ha_lookup_cbk (call_frame_t *frame,
int32_t op_ret,
int32_t op_errno,
inode_t *inode,
- struct iatt *buf,
+ struct stat *buf,
dict_t *dict,
- struct iatt *postparent)
+ struct stat *postparent)
{
ha_local_t *local = NULL;
ha_private_t *pvt = NULL;
@@ -183,8 +193,7 @@ ha_lookup (call_frame_t *frame,
child_count = pvt->child_count;
children = pvt->children;
- frame->local = local = GF_CALLOC (1, sizeof (*local),
- gf_ha_mt_ha_local_t);
+ frame->local = local = CALLOC (1, sizeof (*local));
if (!local) {
gf_log (this->name, GF_LOG_ERROR, "out of memory");
op_errno = ENOMEM;
@@ -196,7 +205,7 @@ ha_lookup (call_frame_t *frame,
ret = inode_ctx_get (loc->inode, this, NULL);
if (ret) {
- state = GF_CALLOC (1, child_count, gf_ha_mt_child_count);
+ state = CALLOC (1, child_count);
if (state == NULL) {
gf_log (this->name, GF_LOG_ERROR, "out of memory");
op_errno = ENOMEM;
@@ -236,7 +245,7 @@ ha_stat_cbk (call_frame_t *frame,
xlator_t *this,
int32_t op_ret,
int32_t op_errno,
- struct iatt *buf)
+ struct stat *buf)
{
int ret = -1;
@@ -281,8 +290,8 @@ err:
int32_t
ha_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 op_ret, int32_t op_errno, struct stat *statpre,
+ struct stat *statpost)
{
int ret = -1;
@@ -296,7 +305,7 @@ ha_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t
-ha_setattr (call_frame_t *frame, xlator_t *this, loc_t *loc, struct iatt *stbuf,
+ha_setattr (call_frame_t *frame, xlator_t *this, loc_t *loc, struct stat *stbuf,
int32_t valid)
{
ha_local_t *local = NULL;
@@ -324,7 +333,7 @@ err:
int32_t
-ha_fsetattr (call_frame_t *frame, xlator_t *this, fd_t *fd, struct iatt *stbuf,
+ha_fsetattr (call_frame_t *frame, xlator_t *this, fd_t *fd, struct stat *stbuf,
int32_t valid)
{
ha_local_t *local = NULL;
@@ -357,8 +366,8 @@ ha_truncate_cbk (call_frame_t *frame,
xlator_t *this,
int32_t op_ret,
int32_t op_errno,
- struct iatt *prebuf,
- struct iatt *postbuf)
+ struct stat *prebuf,
+ struct stat *postbuf)
{
int ret = -1;
@@ -414,8 +423,8 @@ ha_ftruncate_cbk (call_frame_t *frame,
xlator_t *this,
int32_t op_ret,
int32_t op_errno,
- struct iatt *prebuf,
- struct iatt *postbuf)
+ struct stat *prebuf,
+ struct stat *postbuf)
{
int ret = -1;
@@ -537,7 +546,7 @@ ha_readlink_cbk (call_frame_t *frame,
int32_t op_ret,
int32_t op_errno,
const char *path,
- struct iatt *sbuf)
+ struct stat *sbuf)
{
int ret = -1;
@@ -590,9 +599,9 @@ ha_mknod_lookup_cbk (call_frame_t *frame,
int32_t op_ret,
int32_t op_errno,
inode_t *inode,
- struct iatt *buf,
+ struct stat *buf,
dict_t *dict,
- struct iatt *postparent)
+ struct stat *postparent)
{
ha_local_t *local = NULL;
ha_private_t *pvt = NULL;
@@ -636,7 +645,7 @@ ha_mknod_lookup_cbk (call_frame_t *frame,
if (cnt == 0) {
call_stub_t *stub = local->stub;
- GF_FREE (local->state);
+ FREE (local->state);
STACK_UNWIND (frame,
local->op_ret,
local->op_errno,
@@ -655,9 +664,9 @@ ha_mknod_cbk (call_frame_t *frame,
int32_t op_ret,
int32_t op_errno,
inode_t *inode,
- struct iatt *buf,
- struct iatt *preparent,
- struct iatt *postparent)
+ struct stat *buf,
+ struct stat *preparent,
+ struct stat *postparent)
{
ha_local_t *local = NULL;
ha_private_t *pvt = NULL;
@@ -706,7 +715,7 @@ ha_mknod_cbk (call_frame_t *frame,
if (cnt == 0 || i == child_count) {
call_stub_t *stub = local->stub;
- GF_FREE (local->state);
+ FREE (local->state);
stub = local->stub;
STACK_UNWIND (frame, local->op_ret, local->op_errno,
local->stub->args.mknod.loc.inode, &local->buf,
@@ -761,8 +770,7 @@ ha_mknod (call_frame_t *frame,
pvt = this->private;
child_count = pvt->child_count;
- frame->local = local = GF_CALLOC (1, sizeof (*local),
- gf_ha_mt_ha_local_t);
+ frame->local = local = CALLOC (1, sizeof (*local));
if (!local) {
gf_log (this->name, GF_LOG_ERROR, "out of memory");
op_errno = ENOMEM;
@@ -778,7 +786,7 @@ ha_mknod (call_frame_t *frame,
local->op_ret = -1;
local->op_errno = ENOTCONN;
- local->state = GF_CALLOC (1, child_count, gf_ha_mt_char);
+ local->state = CALLOC (1, child_count);
if (!local->state) {
gf_log (this->name, GF_LOG_ERROR, "out of memory");
op_errno = ENOMEM;
@@ -788,7 +796,7 @@ ha_mknod (call_frame_t *frame,
memcpy (local->state, pvt->state, child_count);
local->active = -1;
- stateino = GF_CALLOC (1, child_count, gf_ha_mt_char);
+ stateino = CALLOC (1, child_count);
if (!stateino) {
gf_log (this->name, GF_LOG_ERROR, "out of memory");
op_errno = ENOMEM;
@@ -829,9 +837,9 @@ ha_mkdir_lookup_cbk (call_frame_t *frame,
int32_t op_ret,
int32_t op_errno,
inode_t *inode,
- struct iatt *buf,
+ struct stat *buf,
dict_t *dict,
- struct iatt *postparent)
+ struct stat *postparent)
{
ha_local_t *local = NULL;
ha_private_t *pvt = NULL;
@@ -867,7 +875,7 @@ ha_mkdir_lookup_cbk (call_frame_t *frame,
if (cnt == 0) {
call_stub_t *stub = local->stub;
- GF_FREE (local->state);
+ FREE (local->state);
STACK_UNWIND (frame,
local->op_ret,
local->op_errno,
@@ -885,9 +893,9 @@ ha_mkdir_cbk (call_frame_t *frame,
int32_t op_ret,
int32_t op_errno,
inode_t *inode,
- struct iatt *buf,
- struct iatt *preparent,
- struct iatt *postparent)
+ struct stat *buf,
+ struct stat *preparent,
+ struct stat *postparent)
{
ha_local_t *local = NULL;
ha_private_t *pvt = NULL;
@@ -932,7 +940,7 @@ ha_mkdir_cbk (call_frame_t *frame,
if (cnt == 0 || i == child_count) {
call_stub_t *stub = local->stub;
- GF_FREE (local->state);
+ FREE (local->state);
stub = local->stub;
STACK_UNWIND (frame, local->op_ret, local->op_errno,
local->stub->args.mkdir.loc.inode, &local->buf,
@@ -985,8 +993,7 @@ ha_mkdir (call_frame_t *frame,
pvt = this->private;
child_count = pvt->child_count;
- frame->local = local = GF_CALLOC (1, sizeof (*local),
- gf_ha_mt_ha_local_t);
+ frame->local = local = CALLOC (1, sizeof (*local));
if (!frame->local) {
gf_log (this->name, GF_LOG_ERROR, "out of memory");
op_errno = ENOMEM;
@@ -1002,7 +1009,7 @@ ha_mkdir (call_frame_t *frame,
local->op_ret = -1;
local->op_errno = ENOTCONN;
- local->state = GF_CALLOC (1, child_count, gf_ha_mt_char);
+ local->state = CALLOC (1, child_count);
if (!local->state) {
gf_log (this->name, GF_LOG_ERROR, "out of memory");
op_errno = ENOMEM;
@@ -1012,7 +1019,7 @@ ha_mkdir (call_frame_t *frame,
memcpy (local->state, pvt->state, child_count);
local->active = -1;
- stateino = GF_CALLOC (1, child_count, gf_ha_mt_char);
+ stateino = CALLOC (1, child_count);
if (!stateino) {
gf_log (this->name, GF_LOG_ERROR, "out of memory");
op_errno = ENOMEM;
@@ -1049,8 +1056,8 @@ ha_unlink_cbk (call_frame_t *frame,
xlator_t *this,
int32_t op_ret,
int32_t op_errno,
- struct iatt *preparent,
- struct iatt *postparent)
+ struct stat *preparent,
+ struct stat *postparent)
{
int ret = -1;
@@ -1101,8 +1108,8 @@ ha_rmdir_cbk (call_frame_t *frame,
xlator_t *this,
int32_t op_ret,
int32_t op_errno,
- struct iatt *preparent,
- struct iatt *postparent)
+ struct stat *preparent,
+ struct stat *postparent)
{
int ret = -1;
@@ -1159,9 +1166,9 @@ ha_symlink_lookup_cbk (call_frame_t *frame,
int32_t op_ret,
int32_t op_errno,
inode_t *inode,
- struct iatt *buf,
+ struct stat *buf,
dict_t *dict,
- struct iatt *postparent)
+ struct stat *postparent)
{
ha_local_t *local = NULL;
ha_private_t *pvt = NULL;
@@ -1197,7 +1204,7 @@ ha_symlink_lookup_cbk (call_frame_t *frame,
if (cnt == 0) {
call_stub_t *stub = local->stub;
- GF_FREE (local->state);
+ FREE (local->state);
STACK_UNWIND (frame,
local->op_ret,
local->op_errno,
@@ -1215,9 +1222,9 @@ ha_symlink_cbk (call_frame_t *frame,
int32_t op_ret,
int32_t op_errno,
inode_t *inode,
- struct iatt *buf,
- struct iatt *preparent,
- struct iatt *postparent)
+ struct stat *buf,
+ struct stat *preparent,
+ struct stat *postparent)
{
ha_local_t *local = NULL;
ha_private_t *pvt = NULL;
@@ -1261,7 +1268,7 @@ ha_symlink_cbk (call_frame_t *frame,
if (cnt == 0 || i == child_count) {
call_stub_t *stub = local->stub;
- GF_FREE (local->state);
+ FREE (local->state);
stub = local->stub;
STACK_UNWIND (frame, local->op_ret, local->op_errno,
local->stub->args.symlink.loc.inode, &local->buf,
@@ -1314,8 +1321,7 @@ ha_symlink (call_frame_t *frame,
pvt = this->private;
child_count = pvt->child_count;
- frame->local = local = GF_CALLOC (1, sizeof (*local),
- gf_ha_mt_ha_local_t);
+ frame->local = local = CALLOC (1, sizeof (*local));
if (!local) {
op_errno = ENOMEM;
gf_log (this->name, GF_LOG_ERROR, "out of memory");
@@ -1331,7 +1337,7 @@ ha_symlink (call_frame_t *frame,
local->op_ret = -1;
local->op_errno = ENOTCONN;
- local->state = GF_CALLOC (1, child_count, gf_ha_mt_char);
+ local->state = CALLOC (1, child_count);
if (!local->state) {
op_errno = ENOMEM;
gf_log (this->name, GF_LOG_ERROR, "out of memory");
@@ -1341,7 +1347,7 @@ ha_symlink (call_frame_t *frame,
memcpy (local->state, pvt->state, child_count);
local->active = -1;
- stateino = GF_CALLOC (1, child_count, gf_ha_mt_char);
+ stateino = CALLOC (1, child_count);
if (!stateino) {
op_errno = ENOMEM;
gf_log (this->name, GF_LOG_ERROR, "out of memory");
@@ -1379,11 +1385,11 @@ ha_rename_cbk (call_frame_t *frame,
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)
+ struct stat *buf,
+ struct stat *preoldparent,
+ struct stat *postoldparent,
+ struct stat *prenewparent,
+ struct stat *postnewparent)
{
int ret = -1;
@@ -1437,9 +1443,9 @@ ha_link_lookup_cbk (call_frame_t *frame,
int32_t op_ret,
int32_t op_errno,
inode_t *inode,
- struct iatt *buf,
+ struct stat *buf,
dict_t *dict,
- struct iatt *postparent)
+ struct stat *postparent)
{
ha_local_t *local = NULL;
ha_private_t *pvt = NULL;
@@ -1475,7 +1481,7 @@ ha_link_lookup_cbk (call_frame_t *frame,
if (cnt == 0) {
call_stub_t *stub = local->stub;
- GF_FREE (local->state);
+ FREE (local->state);
STACK_UNWIND (frame,
local->op_ret,
local->op_errno,
@@ -1493,9 +1499,9 @@ ha_link_cbk (call_frame_t *frame,
int32_t op_ret,
int32_t op_errno,
inode_t *inode,
- struct iatt *buf,
- struct iatt *preparent,
- struct iatt *postparent)
+ struct stat *buf,
+ struct stat *preparent,
+ struct stat *postparent)
{
ha_local_t *local = NULL;
ha_private_t *pvt = NULL;
@@ -1539,7 +1545,7 @@ ha_link_cbk (call_frame_t *frame,
if (cnt == 0 || i == child_count) {
call_stub_t *stub = local->stub;
- GF_FREE (local->state);
+ FREE (local->state);
stub = local->stub;
STACK_UNWIND (frame, local->op_ret, local->op_errno,
local->stub->args.link.oldloc.inode, &local->buf,
@@ -1607,8 +1613,7 @@ ha_link (call_frame_t *frame,
pvt = this->private;
child_count = pvt->child_count;
- frame->local = local = GF_CALLOC (1, sizeof (*local),
- gf_ha_mt_ha_local_t);
+ frame->local = local = CALLOC (1, sizeof (*local));
if (!frame->local) {
gf_log (this->name, GF_LOG_ERROR, "out of memory");
op_errno = ENOMEM;
@@ -1624,7 +1629,7 @@ ha_link (call_frame_t *frame,
local->op_ret = -1;
local->op_errno = ENOTCONN;
- local->state = GF_CALLOC (1, child_count, gf_ha_mt_char);
+ local->state = CALLOC (1, child_count);
if (!local->state) {
gf_log (this->name, GF_LOG_ERROR, "out of memory");
op_errno = ENOMEM;
@@ -1664,9 +1669,9 @@ ha_create_cbk (call_frame_t *frame,
int32_t op_errno,
fd_t *fd,
inode_t *inode,
- struct iatt *buf,
- struct iatt *preparent,
- struct iatt *postparent)
+ struct stat *buf,
+ struct stat *preparent,
+ struct stat *postparent)
{
ha_local_t *local = NULL;
ha_private_t *pvt = NULL;
@@ -1736,7 +1741,7 @@ ha_create_cbk (call_frame_t *frame,
stub->args.create.fd,
stub->args.create.loc.inode, &local->buf,
&local->preparent, &local->postparent);
- GF_FREE (state);
+ FREE (state);
call_stub_destroy (stub);
return 0;
}
@@ -1780,8 +1785,7 @@ ha_create (call_frame_t *frame,
children = pvt->children;
if (local == NULL) {
- frame->local = local = GF_CALLOC (1, sizeof (*local),
- gf_ha_mt_ha_local_t);
+ local = frame->local = CALLOC (1, sizeof (*local));
if (!local) {
op_errno = ENOMEM;
gf_log (this->name, GF_LOG_ERROR, "out of memory");
@@ -1795,7 +1799,7 @@ ha_create (call_frame_t *frame,
goto err;
}
- local->state = GF_CALLOC (1, child_count, gf_ha_mt_char);
+ local->state = CALLOC (1, child_count);
if (!local->state) {
op_errno = ENOMEM;
gf_log (this->name, GF_LOG_ERROR, "out of memory");
@@ -1815,28 +1819,28 @@ ha_create (call_frame_t *frame,
}
}
/* FIXME handle active -1 */
- stateino = GF_CALLOC (1, child_count, gf_ha_mt_char);
+ stateino = CALLOC (1, child_count);
if (!stateino) {
op_errno = ENOMEM;
gf_log (this->name, GF_LOG_ERROR, "out of memory");
goto err;
}
- hafdp = GF_CALLOC (1, sizeof (*hafdp), gf_ha_mt_hafd_t);
+ hafdp = CALLOC (1, sizeof (*hafdp));
if (!hafdp) {
op_errno = ENOMEM;
gf_log (this->name, GF_LOG_ERROR, "out of memory");
goto err;
}
- hafdp->fdstate = GF_CALLOC (1, child_count, gf_ha_mt_char);
+ hafdp->fdstate = CALLOC (1, child_count);
if (!hafdp->fdstate) {
op_errno = ENOMEM;
gf_log (this->name, GF_LOG_ERROR, "out of memory");
goto err;
}
- hafdp->path = gf_strdup(loc->path);
+ hafdp->path = strdup(loc->path);
if (!hafdp->path) {
op_errno = ENOMEM;
gf_log (this->name, GF_LOG_ERROR, "out of memory");
@@ -1861,16 +1865,20 @@ err:
ha_local_wipe (local);
if (stateino) {
- GF_FREE (stateino);
+ FREE (stateino);
stateino = NULL;
}
if (hafdp) {
- GF_FREE (hafdp->fdstate);
+ if (hafdp->fdstate) {
+ FREE (hafdp->fdstate);
+ }
- GF_FREE (hafdp->path);
+ if (hafdp->path) {
+ FREE (hafdp->path);
+ }
- GF_FREE (hafdp);
+ FREE (hafdp);
}
return 0;
@@ -1947,8 +1955,7 @@ ha_open (call_frame_t *frame,
child_count = pvt->child_count;
- frame->local = local = GF_CALLOC (1, sizeof (*local),
- gf_ha_mt_ha_local_t);
+ local = frame->local = CALLOC (1, sizeof (*local));
if (!local) {
op_errno = ENOMEM;
gf_log (this->name, GF_LOG_ERROR, "out of memory");
@@ -1959,21 +1966,21 @@ ha_open (call_frame_t *frame,
local->op_errno = ENOTCONN;
local->fd = fd;
- hafdp = GF_CALLOC (1, sizeof (*hafdp), gf_ha_mt_hafd_t);
+ hafdp = CALLOC (1, sizeof (*hafdp));
if (!hafdp) {
op_errno = ENOMEM;
gf_log (this->name, GF_LOG_ERROR, "out of memory");
goto err;
}
- hafdp->fdstate = GF_CALLOC (1, child_count, gf_ha_mt_char);
+ hafdp->fdstate = CALLOC (1, child_count);
if (!hafdp->fdstate) {
op_errno = ENOMEM;
gf_log (this->name, GF_LOG_ERROR, "out of memory");
goto err;
}
- hafdp->path = gf_strdup (loc->path);
+ hafdp->path = strdup (loc->path);
if (!hafdp->path) {
op_errno = ENOMEM;
gf_log (this->name, GF_LOG_ERROR, "out of memory");
@@ -2013,16 +2020,16 @@ err:
STACK_UNWIND (frame, -1, op_errno, fd);
if (hafdp) {
if (hafdp->fdstate) {
- GF_FREE (hafdp->fdstate);
+ FREE (hafdp->fdstate);
hafdp->fdstate = NULL;
}
if (hafdp->path) {
- GF_FREE (hafdp->path);
+ FREE (hafdp->path);
hafdp->path = NULL;
}
- GF_FREE (hafdp);
+ FREE (hafdp);
}
ha_local_wipe (local);
@@ -2037,7 +2044,7 @@ ha_readv_cbk (call_frame_t *frame,
int32_t op_errno,
struct iovec *vector,
int32_t count,
- struct iatt *stbuf,
+ struct stat *stbuf,
struct iobref *iobref)
{
int ret = 0;
@@ -2104,8 +2111,8 @@ ha_writev_cbk (call_frame_t *frame,
xlator_t *this,
int32_t op_ret,
int32_t op_errno,
- struct iatt *prebuf,
- struct iatt *postbuf)
+ struct stat *prebuf,
+ struct stat *postbuf)
{
int ret = 0;
ret = ha_handle_cbk (frame, cookie, op_ret, op_errno);
@@ -2230,8 +2237,8 @@ ha_fsync_cbk (call_frame_t *frame,
xlator_t *this,
int32_t op_ret,
int32_t op_errno,
- struct iatt *prebuf,
- struct iatt *postbuf)
+ struct stat *prebuf,
+ struct stat *postbuf)
{
int ret = 0;
ret = ha_handle_cbk (frame, cookie, op_ret, op_errno);
@@ -2290,7 +2297,7 @@ ha_fstat_cbk (call_frame_t *frame,
xlator_t *this,
int32_t op_ret,
int32_t op_errno,
- struct iatt *buf)
+ struct stat *buf)
{
int ret = 0;
@@ -2413,8 +2420,7 @@ ha_opendir (call_frame_t *frame,
children = pvt->children;
child_count = pvt->child_count;
- frame->local = local = GF_CALLOC (1, sizeof (*local),
- gf_ha_mt_ha_local_t);
+ local = frame->local = CALLOC (1, sizeof (*local));
if (!local) {
op_errno = ENOMEM;
gf_log (this->name, GF_LOG_ERROR, "out of memory");
@@ -2425,21 +2431,21 @@ ha_opendir (call_frame_t *frame,
local->op_errno = ENOTCONN;
local->fd = fd;
- hafdp = GF_CALLOC (1, sizeof (*hafdp), gf_ha_mt_hafd_t);
+ hafdp = CALLOC (1, sizeof (*hafdp));
if (!hafdp) {
op_errno = ENOMEM;
gf_log (this->name, GF_LOG_ERROR, "out of memory");
goto err;
}
- hafdp->fdstate = GF_CALLOC (1, child_count, gf_ha_mt_char);
+ hafdp->fdstate = CALLOC (1, child_count);
if (!hafdp->fdstate) {
op_errno = ENOMEM;
gf_log (this->name, GF_LOG_ERROR, "out of memory");
goto err;
}
- hafdp->path = gf_strdup (loc->path);
+ hafdp->path = strdup (loc->path);
if (!hafdp->path) {
op_errno = ENOMEM;
gf_log (this->name, GF_LOG_ERROR, "out of memory");
@@ -2478,16 +2484,16 @@ err:
ha_local_wipe (local);
if (hafdp) {
if (hafdp->fdstate) {
- GF_FREE (hafdp->fdstate);
+ FREE (hafdp->fdstate);
hafdp->fdstate = NULL;
}
if (hafdp->path) {
- GF_FREE (hafdp->path);
+ FREE (hafdp->path);
hafdp->path = NULL;
}
- GF_FREE (hafdp);
+ FREE (hafdp);
}
return 0;
}
@@ -2694,12 +2700,7 @@ ha_statfs_cbk (call_frame_t *frame,
ha_local_t *local = NULL;
ha_private_t *priv = NULL;
- GF_ASSERT (this);
-
local = frame->local;
- priv = this->private;
- GF_ASSERT (priv);
-
if (-1 == op_ret) {
local->active = (local->active + 1) % priv->child_count;
local->tries--;
@@ -2716,6 +2717,7 @@ ha_statfs_cbk (call_frame_t *frame,
out:
loc_wipe (&local->loc);
STACK_UNWIND (frame, op_ret, op_errno, buf);
+
return 0;
}
@@ -2731,8 +2733,7 @@ ha_statfs (call_frame_t *frame,
/* The normal way of handling failover doesn't work here
* as loc->inode may be null in this case.
*/
- local = GF_CALLOC (1, sizeof (*local),
- gf_ha_mt_ha_local_t);
+ local = CALLOC (1, sizeof (*local));
if (!local) {
op_errno = ENOMEM;
goto err;
@@ -3056,7 +3057,7 @@ ha_lk_setlk_unlck_cbk (call_frame_t *frame,
xlator_t *this,
int32_t op_ret,
int32_t op_errno,
- struct gf_flock *lock)
+ struct flock *lock)
{
ha_local_t *local = NULL;
int cnt = 0;
@@ -3072,7 +3073,7 @@ ha_lk_setlk_unlck_cbk (call_frame_t *frame,
if (cnt == 0) {
stub = local->stub;
- GF_FREE (local->state);
+ FREE (local->state);
if (stub->args.lk.lock.l_type == F_UNLCK) {
STACK_UNWIND (frame, local->op_ret, local->op_errno, &stub->args.lk.lock);
} else {
@@ -3089,7 +3090,7 @@ ha_lk_setlk_cbk (call_frame_t *frame,
xlator_t *this,
int32_t op_ret,
int32_t op_errno,
- struct gf_flock *lock)
+ struct flock *lock)
{
ha_local_t *local = NULL;
ha_private_t *pvt = NULL;
@@ -3121,7 +3122,7 @@ ha_lk_setlk_cbk (call_frame_t *frame,
}
if (i == child_count) {
call_stub_t *stub = local->stub;
- GF_FREE (local->state);
+ FREE (local->state);
STACK_UNWIND (frame, 0, op_errno, &stub->args.lk.lock);
call_stub_destroy (stub);
return 0;
@@ -3145,7 +3146,7 @@ ha_lk_setlk_cbk (call_frame_t *frame,
cnt++;
}
if (cnt) {
- struct gf_flock lock;
+ struct flock lock;
lock = local->stub->args.lk.lock;
for (i = 0; i < child_count; i++) {
if (state[i]) {
@@ -3162,7 +3163,7 @@ ha_lk_setlk_cbk (call_frame_t *frame,
}
return 0;
} else {
- GF_FREE (local->state);
+ FREE (local->state);
call_stub_destroy (local->stub);
STACK_UNWIND (frame,
op_ret,
@@ -3179,7 +3180,7 @@ ha_lk_getlk_cbk (call_frame_t *frame,
xlator_t *this,
int32_t op_ret,
int32_t op_errno,
- struct gf_flock *lock)
+ struct flock *lock)
{
ha_local_t *local = NULL;
ha_private_t *pvt = NULL;
@@ -3196,7 +3197,7 @@ ha_lk_getlk_cbk (call_frame_t *frame,
prev_frame = cookie;
if (op_ret == 0) {
- GF_FREE (local->state);
+ FREE (local->state);
call_stub_destroy (local->stub);
STACK_UNWIND (frame, 0, 0, lock);
return 0;
@@ -3213,7 +3214,7 @@ ha_lk_getlk_cbk (call_frame_t *frame,
}
if (i == child_count) {
- GF_FREE (local->state);
+ FREE (local->state);
call_stub_destroy (local->stub);
STACK_UNWIND (frame, op_ret, op_errno, lock);
return 0;
@@ -3234,7 +3235,7 @@ ha_lk (call_frame_t *frame,
xlator_t *this,
fd_t *fd,
int32_t cmd,
- struct gf_flock *lock)
+ struct flock *lock)
{
ha_local_t *local = NULL;
ha_private_t *pvt = NULL;
@@ -3254,8 +3255,7 @@ ha_lk (call_frame_t *frame,
gf_log (this->name, GF_LOG_ERROR, "fd_ctx_get failed");
if (local == NULL) {
- local = frame->local = GF_CALLOC (1, sizeof (*local),
- gf_ha_mt_ha_local_t);
+ local = frame->local = CALLOC (1, sizeof (*local));
if (!local) {
op_errno = ENOMEM;
gf_log (this->name, GF_LOG_ERROR, "out of memory");
@@ -3280,7 +3280,7 @@ ha_lk (call_frame_t *frame,
goto err;
}
- local->state = GF_CALLOC (1, child_count, gf_ha_mt_char);
+ local->state = CALLOC (1, child_count);
if (!local->state) {
op_errno = ENOMEM;
gf_log (this->name, GF_LOG_ERROR, "out of memory");
@@ -3368,7 +3368,7 @@ ha_inodelk (call_frame_t *frame,
const char *volume,
loc_t *loc,
int32_t cmd,
- struct gf_flock *lock)
+ struct flock *lock)
{
ha_local_t *local = NULL;
int op_errno = 0;
@@ -3636,8 +3636,7 @@ ha_stats (call_frame_t *frame,
int i = 0;
int32_t op_errno = EINVAL;
- local = frame->local = GF_CALLOC (1, sizeof (*local),
- gf_ha_mt_ha_local_t);
+ local = frame->local = CALLOC (1, sizeof (*local));
if (!local) {
op_errno = ENOMEM;
gf_log (this->name, GF_LOG_ERROR, "out of memory");
@@ -3738,8 +3737,7 @@ ha_getspec (call_frame_t *frame,
int i = 0;
int32_t op_errno = EINVAL;
- local = frame->local = GF_CALLOC (1, sizeof (*local),
- gf_ha_mt_ha_local_t);
+ local = frame->local = CALLOC (1, sizeof (*local));
if (!local) {
op_errno = ENOMEM;
gf_log (this->name, GF_LOG_ERROR, "out of memory");
@@ -3793,8 +3791,8 @@ ha_closedir (xlator_t *this,
}
hafdp = (hafd_t *)(long)tmp_hafdp;
- GF_FREE (hafdp->fdstate);
- GF_FREE (hafdp->path);
+ FREE (hafdp->fdstate);
+ FREE (hafdp->path);
LOCK_DESTROY (&hafdp->lock);
return 0;
}
@@ -3814,8 +3812,8 @@ ha_close (xlator_t *this,
}
hafdp = (hafd_t *)(long)tmp_hafdp;
- GF_FREE (hafdp->fdstate);
- GF_FREE (hafdp->path);
+ FREE (hafdp->fdstate);
+ FREE (hafdp->path);
LOCK_DESTROY (&hafdp->lock);
return 0;
}
@@ -3886,25 +3884,6 @@ notify (xlator_t *this,
return 0;
}
-int32_t
-mem_acct_init (xlator_t *this)
-{
- int ret = -1;
-
- if (!this)
- return ret;
-
- ret = xlator_mem_acct_init (this, gf_ha_mt_end + 1);
-
- if (ret != 0) {
- gf_log (this->name, GF_LOG_ERROR, "Memory accounting init"
- "failed");
- return ret;
- }
-
- return ret;
-}
-
int
init (xlator_t *this)
{
@@ -3912,7 +3891,6 @@ init (xlator_t *this)
xlator_list_t *trav = NULL;
int count = 0, ret = 0;
-
if (!this->children) {
gf_log (this->name,GF_LOG_ERROR,
"FATAL: ha should have one or more child defined");
@@ -3925,7 +3903,7 @@ init (xlator_t *this)
}
trav = this->children;
- pvt = GF_CALLOC (1, sizeof (ha_private_t), gf_ha_mt_ha_private_t);
+ pvt = CALLOC (1, sizeof (ha_private_t));
ret = dict_get_int32 (this->options, "preferred-subvolume",
&pvt->pref_subvol);
@@ -3940,8 +3918,7 @@ init (xlator_t *this)
}
pvt->child_count = count;
- pvt->children = GF_CALLOC (count, sizeof (xlator_t*),
- gf_ha_mt_xlator_t);
+ pvt->children = CALLOC (count, sizeof (xlator_t*));
trav = this->children;
count = 0;
@@ -3951,7 +3928,7 @@ init (xlator_t *this)
trav = trav->next;
}
- pvt->state = GF_CALLOC (1, count, gf_ha_mt_char);
+ pvt->state = CALLOC (1, count);
this->private = pvt;
return 0;
}
@@ -3961,7 +3938,7 @@ fini (xlator_t *this)
{
ha_private_t *priv = NULL;
priv = this->private;
- GF_FREE (priv);
+ FREE (priv);
return;
}
@@ -4006,6 +3983,11 @@ struct xlator_fops fops = {
.fsetattr = ha_fsetattr,
};
+struct xlator_mops mops = {
+ .stats = ha_stats,
+ .getspec = ha_getspec,
+};
+
struct xlator_cbks cbks = {
.release = ha_close,
.releasedir = ha_closedir,
diff --git a/xlators/cluster/ha/src/ha.h b/xlators/cluster/ha/src/ha.h
index e2ed7eaa68a..0da31850c51 100644
--- a/xlators/cluster/ha/src/ha.h
+++ b/xlators/cluster/ha/src/ha.h
@@ -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) 2008-2009 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 __HA_H_
#define __HA_H_
-#include "ha-mem-types.h"
-
typedef struct {
call_stub_t *stub;
int32_t op_ret, op_errno;
@@ -20,9 +28,9 @@ typedef struct {
char *state, *pattern;
dict_t *dict;
loc_t loc;
- struct iatt buf;
- struct iatt postparent;
- struct iatt preparent;
+ struct stat buf;
+ struct stat postparent;
+ struct stat preparent;
fd_t *fd;
inode_t *inode;
int32_t flags;
diff --git a/xlators/cluster/map/src/Makefile.am b/xlators/cluster/map/src/Makefile.am
index a278b05e2d1..26e19137a8b 100644
--- a/xlators/cluster/map/src/Makefile.am
+++ b/xlators/cluster/map/src/Makefile.am
@@ -1,16 +1,15 @@
xlator_LTLIBRARIES = map.la
xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/testing/cluster
-map_la_LDFLAGS = -module -avoid-version
+map_la_LDFLAGS = -module -avoidversion
map_la_SOURCES = map.c map-helper.c
map_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la
noinst_HEADERS = map.h
-AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src
-
-AM_CFLAGS = -Wall $(GF_CFLAGS)
+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/map/src/map-helper.c b/xlators/cluster/map/src/map-helper.c
index 851397b68d3..b4c8ad52590 100644
--- a/xlators/cluster/map/src/map-helper.c
+++ b/xlators/cluster/map/src/map-helper.c
@@ -1,12 +1,22 @@
/*
- Copyright (c) 2009-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) 2009-2009 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"
@@ -246,15 +256,14 @@ verify_dir_and_assign_subvol (xlator_t *this,
goto out;
}
- tmp_map = GF_CALLOC (1, sizeof (struct map_pattern),
- gf_map_mt_map_pattern);
+ tmp_map = CALLOC (1, sizeof (struct map_pattern));
tmp_map->xl = trav->xlator;
tmp_map->dir_len = strlen (directory);
/* make sure that the top level directory starts
* with '/' and ends without '/'
*/
- tmp_map->directory = gf_strdup (directory);
+ tmp_map->directory = strdup (directory);
if (directory[tmp_map->dir_len - 1] == '/') {
tmp_map->dir_len--;
}
diff --git a/xlators/cluster/map/src/map-mem-types.h b/xlators/cluster/map/src/map-mem-types.h
deleted file mode 100644
index 3e89f4736e4..00000000000
--- a/xlators/cluster/map/src/map-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 __MAP_MEM_TYPES_H__
-#define __MAP_MEM_TYPES_H__
-
-#include "mem-types.h"
-
-enum gf_map_mem_types_ {
- gf_map_mt_map_private_t = gf_common_mt_end + 1,
- gf_map_mt_map_local_t,
- gf_map_mt_map_xlator_array,
- gf_map_mt_map_pattern,
- gf_map_mt_end
-};
-#endif
-
diff --git a/xlators/cluster/map/src/map.c b/xlators/cluster/map/src/map.c
index 6150a33cec8..72464fc82c9 100644
--- a/xlators/cluster/map/src/map.c
+++ b/xlators/cluster/map/src/map.c
@@ -1,12 +1,22 @@
/*
- Copyright (c) 2010-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) 2009 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"
@@ -26,13 +36,13 @@ map_stat_cbk (call_frame_t *frame,
xlator_t *this,
int32_t op_ret,
int32_t op_errno,
- struct iatt *buf)
+ struct stat *buf)
{
call_frame_t *prev = NULL;
prev = cookie;
- map_itransform (this, prev->this, buf->ia_ino, &buf->ia_ino);
+ map_itransform (this, prev->this, buf->st_ino, &buf->st_ino);
STACK_UNWIND (frame, op_ret, op_errno, buf);
return 0;
@@ -44,14 +54,14 @@ map_setattr_cbk (call_frame_t *frame,
xlator_t *this,
int32_t op_ret,
int32_t op_errno,
- struct iatt *statpre,
- struct iatt *statpost)
+ struct stat *statpre,
+ struct stat *statpost)
{
call_frame_t *prev = NULL;
prev = cookie;
- map_itransform (this, prev->this, statpre->ia_ino, &statpre->ia_ino);
- map_itransform (this, prev->this, statpost->ia_ino, &statpost->ia_ino);
+ map_itransform (this, prev->this, statpre->st_ino, &statpre->st_ino);
+ map_itransform (this, prev->this, statpost->st_ino, &statpost->st_ino);
STACK_UNWIND (frame, op_ret, op_errno, statpre, statpost);
return 0;
@@ -63,14 +73,14 @@ map_fsetattr_cbk (call_frame_t *frame,
xlator_t *this,
int32_t op_ret,
int32_t op_errno,
- struct iatt *statpre,
- struct iatt *statpost)
+ struct stat *statpre,
+ struct stat *statpost)
{
call_frame_t *prev = NULL;
prev = cookie;
- map_itransform (this, prev->this, statpre->ia_ino, &statpre->ia_ino);
- map_itransform (this, prev->this, statpost->ia_ino, &statpost->ia_ino);
+ map_itransform (this, prev->this, statpre->st_ino, &statpre->st_ino);
+ map_itransform (this, prev->this, statpost->st_ino, &statpost->st_ino);
STACK_UNWIND (frame, op_ret, op_errno, statpre, statpost);
return 0;
@@ -82,13 +92,13 @@ map_truncate_cbk (call_frame_t *frame,
xlator_t *this,
int32_t op_ret,
int32_t op_errno,
- struct iatt *prebuf,
- struct iatt *postbuf)
+ struct stat *prebuf,
+ struct stat *postbuf)
{
call_frame_t *prev = NULL;
prev = cookie;
- map_itransform (this, prev->this, postbuf->ia_ino, &postbuf->ia_ino);
+ map_itransform (this, prev->this, postbuf->st_ino, &postbuf->st_ino);
STACK_UNWIND (frame, op_ret, op_errno, prebuf, postbuf);
return 0;
@@ -100,13 +110,13 @@ map_ftruncate_cbk (call_frame_t *frame,
xlator_t *this,
int32_t op_ret,
int32_t op_errno,
- struct iatt *prebuf,
- struct iatt *postbuf)
+ struct stat *prebuf,
+ struct stat *postbuf)
{
call_frame_t *prev = NULL;
prev = cookie;
- map_itransform (this, prev->this, postbuf->ia_ino, &postbuf->ia_ino);
+ map_itransform (this, prev->this, postbuf->st_ino, &postbuf->st_ino);
STACK_UNWIND (frame, op_ret, op_errno, prebuf, postbuf);
return 0;
@@ -131,7 +141,7 @@ map_readlink_cbk (call_frame_t *frame,
int32_t op_ret,
int32_t op_errno,
const char *path,
- struct iatt *sbuf)
+ struct stat *sbuf)
{
STACK_UNWIND (frame, op_ret, op_errno, path, sbuf);
return 0;
@@ -143,8 +153,8 @@ map_unlink_cbk (call_frame_t *frame,
xlator_t *this,
int32_t op_ret,
int32_t op_errno,
- struct iatt *preparent,
- struct iatt *postparent)
+ struct stat *preparent,
+ struct stat *postparent)
{
STACK_UNWIND (frame, op_ret, op_errno, preparent, postparent);
return 0;
@@ -156,8 +166,8 @@ map_rmdir_cbk (call_frame_t *frame,
xlator_t *this,
int32_t op_ret,
int32_t op_errno,
- struct iatt *preparent,
- struct iatt *postparent)
+ struct stat *preparent,
+ struct stat *postparent)
{
STACK_UNWIND (frame, op_ret, op_errno, preparent, postparent);
return 0;
@@ -170,16 +180,16 @@ map_rename_cbk (call_frame_t *frame,
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)
+ struct stat *buf,
+ struct stat *preoldparent,
+ struct stat *postoldparent,
+ struct stat *prenewparent,
+ struct stat *postnewparent)
{
call_frame_t *prev = NULL;
prev = cookie;
- map_itransform (this, prev->this, buf->ia_ino, &buf->ia_ino);
+ map_itransform (this, prev->this, buf->st_ino, &buf->st_ino);
STACK_UNWIND (frame, op_ret, op_errno, buf);
return 0;
@@ -192,14 +202,14 @@ map_link_cbk (call_frame_t *frame,
int32_t op_ret,
int32_t op_errno,
inode_t *inode,
- struct iatt *buf,
- struct iatt *preparent,
- struct iatt *postparent)
+ struct stat *buf,
+ struct stat *preparent,
+ struct stat *postparent)
{
call_frame_t *prev = NULL;
prev = cookie;
- map_itransform (this, prev->this, buf->ia_ino, &buf->ia_ino);
+ map_itransform (this, prev->this, buf->st_ino, &buf->st_ino);
STACK_UNWIND (frame, op_ret, op_errno, inode, buf);
return 0;
@@ -225,13 +235,13 @@ map_readv_cbk (call_frame_t *frame,
int32_t op_errno,
struct iovec *vector,
int32_t count,
- struct iatt *stbuf,
+ struct stat *stbuf,
struct iobref *iobref)
{
call_frame_t *prev = NULL;
prev = cookie;
- map_itransform (this, prev->this, stbuf->ia_ino, &stbuf->ia_ino);
+ map_itransform (this, prev->this, stbuf->st_ino, &stbuf->st_ino);
STACK_UNWIND (frame, op_ret, op_errno, vector, count, stbuf, iobref);
return 0;
@@ -243,13 +253,13 @@ map_writev_cbk (call_frame_t *frame,
xlator_t *this,
int32_t op_ret,
int32_t op_errno,
- struct iatt *prebuf,
- struct iatt *postbuf)
+ struct stat *prebuf,
+ struct stat *postbuf)
{
call_frame_t *prev = NULL;
prev = cookie;
- map_itransform (this, prev->this, postbuf->ia_ino, &postbuf->ia_ino);
+ map_itransform (this, prev->this, postbuf->st_ino, &postbuf->st_ino);
STACK_UNWIND (frame, op_ret, op_errno, prebuf, postbuf);
return 0;
@@ -273,8 +283,8 @@ map_fsync_cbk (call_frame_t *frame,
xlator_t *this,
int32_t op_ret,
int32_t op_errno,
- struct iatt *prebuf,
- struct iatt *postbuf)
+ struct stat *prebuf,
+ struct stat *postbuf)
{
STACK_UNWIND (frame, op_ret, op_errno, prebuf, postbuf);
return 0;
@@ -287,12 +297,12 @@ map_fstat_cbk (call_frame_t *frame,
xlator_t *this,
int32_t op_ret,
int32_t op_errno,
- struct iatt *buf)
+ struct stat *buf)
{
call_frame_t *prev = NULL;
prev = cookie;
- map_itransform (this, prev->this, buf->ia_ino, &buf->ia_ino);
+ map_itransform (this, prev->this, buf->st_ino, &buf->st_ino);
STACK_UNWIND (frame, op_ret, op_errno, buf);
return 0;
@@ -428,7 +438,7 @@ map_lk_cbk (call_frame_t *frame,
xlator_t *this,
int32_t op_ret,
int32_t op_errno,
- struct gf_flock *lock)
+ struct flock *lock)
{
STACK_UNWIND (frame, op_ret, op_errno, lock);
return 0;
@@ -482,14 +492,14 @@ map_newentry_cbk (call_frame_t *frame,
int32_t op_ret,
int32_t op_errno,
inode_t *inode,
- struct iatt *buf,
- struct iatt *preparent,
- struct iatt *postparent)
+ struct stat *buf,
+ struct stat *preparent,
+ struct stat *postparent)
{
call_frame_t *prev = NULL;
prev = cookie;
- map_itransform (this, prev->this, buf->ia_ino, &buf->ia_ino);
+ map_itransform (this, prev->this, buf->st_ino, &buf->st_ino);
STACK_UNWIND (frame, op_ret, op_errno, inode, buf);
return 0;
@@ -505,14 +515,14 @@ map_create_cbk (call_frame_t *frame,
int32_t op_errno,
fd_t *fd,
inode_t *inode,
- struct iatt *buf,
- struct iatt *preparent,
- struct iatt *postparent)
+ struct stat *buf,
+ struct stat *preparent,
+ struct stat *postparent)
{
call_frame_t *prev = NULL;
prev = cookie;
- map_itransform (this, prev->this, buf->ia_ino, &buf->ia_ino);
+ map_itransform (this, prev->this, buf->st_ino, &buf->st_ino);
STACK_UNWIND (frame, op_ret, op_errno, fd, inode, buf);
return 0;
@@ -614,14 +624,14 @@ map_single_lookup_cbk (call_frame_t *frame,
int32_t op_ret,
int32_t op_errno,
inode_t *inode,
- struct iatt *buf,
+ struct stat *buf,
dict_t *dict,
- struct iatt *postparent)
+ struct stat *postparent)
{
call_frame_t *prev = NULL;
prev = cookie;
- map_itransform (this, prev->this, buf->ia_ino, &buf->ia_ino);
+ map_itransform (this, prev->this, buf->st_ino, &buf->st_ino);
STACK_UNWIND (frame, op_ret, op_errno, inode, buf, dict);
@@ -635,9 +645,9 @@ map_root_lookup_cbk (call_frame_t *frame,
int32_t op_ret,
int32_t op_errno,
inode_t *inode,
- struct iatt *buf,
+ struct stat *buf,
dict_t *dict,
- struct iatt *postparent)
+ struct stat *postparent)
{
int callcnt = 0;
map_local_t *local = NULL;
@@ -752,7 +762,7 @@ map_single_readdirp_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
list_for_each_entry (orig_entry, &entries->list, list) {
map_itransform (this, prev->this, orig_entry->d_ino,
&orig_entry->d_ino);
- orig_entry->d_stat.ia_ino = orig_entry->d_ino;
+ orig_entry->d_stat.st_ino = orig_entry->d_ino;
}
STACK_UNWIND (frame, op_ret, op_errno, entries);
return 0;
@@ -805,7 +815,7 @@ map_generic_readdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
&entry->d_off);
if (whichop == GF_FOP_READDIRP)
- entry->d_stat.ia_ino = entry->d_ino;
+ entry->d_stat.st_ino = entry->d_ino;
entry->d_type = orig_entry->d_type;
entry->d_len = orig_entry->d_len;
@@ -895,6 +905,23 @@ map_checksum_cbk (call_frame_t *frame,
}
+int32_t
+map_lock_notify_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;
+}
+
+
+int32_t
+map_lock_fnotify_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;
+}
+
/* Fops starts here */
int32_t
@@ -930,7 +957,7 @@ int32_t
map_setattr (call_frame_t *frame,
xlator_t *this,
loc_t *loc,
- struct iatt *stbuf,
+ struct stat *stbuf,
int32_t valid)
{
int32_t op_errno = 1;
@@ -962,7 +989,7 @@ int32_t
map_fsetattr (call_frame_t *frame,
xlator_t *this,
fd_t *fd,
- struct iatt *stbuf,
+ struct stat *stbuf,
int32_t valid)
{
int32_t op_errno = 1;
@@ -1760,7 +1787,7 @@ map_lk (call_frame_t *frame,
xlator_t *this,
fd_t *fd,
int32_t cmd,
- struct gf_flock *lock)
+ struct flock *lock)
{
int32_t op_errno = 1;
xlator_t *subvol = NULL;
@@ -1789,7 +1816,7 @@ map_lk (call_frame_t *frame,
int32_t
map_inodelk (call_frame_t *frame, xlator_t *this,
- const char *volume, loc_t *loc, int32_t cmd, struct gf_flock *lock)
+ const char *volume, loc_t *loc, int32_t cmd, struct flock *lock)
{
int32_t op_errno = 1;
xlator_t *subvol = NULL;
@@ -1819,7 +1846,7 @@ map_inodelk (call_frame_t *frame, xlator_t *this,
int32_t
map_finodelk (call_frame_t *frame, xlator_t *this,
- const char *volume, fd_t *fd, int32_t cmd, struct gf_flock *lock)
+ const char *volume, fd_t *fd, int32_t cmd, struct flock *lock)
{
int32_t op_errno = 1;
xlator_t *subvol = NULL;
@@ -2137,8 +2164,7 @@ map_lookup (call_frame_t *frame,
return 0;
root_inode:
- local = GF_CALLOC (1, sizeof (map_local_t),
- gf_map_mt_map_local_t);
+ local = CALLOC (1, sizeof (map_local_t));
frame->local = local;
local->call_count = priv->child_count;
@@ -2190,8 +2216,7 @@ map_statfs (call_frame_t *frame,
return 0;
root_inode:
- local = GF_CALLOC (1, sizeof (map_local_t),
- gf_map_mt_map_local_t);
+ local = CALLOC (1, sizeof (map_local_t));
priv = this->private;
frame->local = local;
@@ -2243,8 +2268,7 @@ map_opendir (call_frame_t *frame,
return 0;
root_inode:
- local = GF_CALLOC (1, sizeof (map_local_t),
- gf_map_mt_map_local_t);
+ local = CALLOC (1, sizeof (map_local_t));
priv = this->private;
frame->local = local;
@@ -2303,8 +2327,7 @@ map_do_readdir (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
root_inode:
/* readdir on '/' */
- local = GF_CALLOC (1, sizeof (map_local_t),
- gf_map_mt_map_local_t);
+ local = CALLOC (1, sizeof (map_local_t));
if (!local) {
gf_log (this->name, GF_LOG_ERROR,
"memory allocation failed :(");
@@ -2365,40 +2388,22 @@ fini (xlator_t *this)
priv = this->private;
if (priv) {
- GF_FREE (priv->xlarray);
+ if (priv->xlarray)
+ FREE (priv->xlarray);
trav_map = priv->map;
while (trav_map) {
tmp_map = trav_map;
trav_map = trav_map->next;
- GF_FREE (tmp_map);
+ FREE (tmp_map);
}
- GF_FREE(priv);
+ 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_map_mt_end + 1);
-
- if (ret != 0) {
- gf_log (this->name, GF_LOG_ERROR, "Memory accounting init"
- "failed");
- return ret;
- }
-
- return ret;
-}
-
int
init (xlator_t *this)
{
@@ -2415,7 +2420,6 @@ init (xlator_t *this)
char *subvol_str = NULL;
char *map_xl = NULL;
-
if (!this->children) {
gf_log (this->name,GF_LOG_ERROR,
"FATAL: map should have one or more child defined");
@@ -2427,8 +2431,7 @@ init (xlator_t *this)
"dangling volume. check volfile ");
}
- priv = GF_CALLOC (1, sizeof (map_private_t),
- gf_map_mt_map_private_t);
+ priv = CALLOC (1, sizeof (map_private_t));
this->private = priv;
/* allocate xlator array */
@@ -2437,8 +2440,7 @@ init (xlator_t *this)
count++;
trav = trav->next;
}
- priv->xlarray = GF_CALLOC (1, sizeof (struct map_xlator_array) * count,
- gf_map_mt_map_xlator_array);
+ priv->xlarray = CALLOC (1, sizeof (struct map_xlator_array) * count);
priv->child_count = count;
/* build xlator array */
@@ -2458,7 +2460,7 @@ init (xlator_t *this)
}
map_pair_str = strtok_r (pattern_string, ";", &tmp_str);
while (map_pair_str) {
- dup_map_pair = gf_strdup (map_pair_str);
+ dup_map_pair = strdup (map_pair_str);
dir_str = strtok_r (dup_map_pair, ":", &tmp_str1);
if (!dir_str) {
gf_log (this->name, GF_LOG_ERROR,
@@ -2480,7 +2482,7 @@ init (xlator_t *this)
goto err;
}
- GF_FREE (dup_map_pair);
+ FREE (dup_map_pair);
map_pair_str = strtok_r (NULL, ";", &tmp_str);
}
@@ -2551,6 +2553,9 @@ struct xlator_fops fops = {
.fsetattr = map_fsetattr,
};
+struct xlator_mops mops = {
+};
+
struct xlator_cbks cbks = {
};
diff --git a/xlators/cluster/map/src/map.h b/xlators/cluster/map/src/map.h
index 7703a543e28..b5f57518bfd 100644
--- a/xlators/cluster/map/src/map.h
+++ b/xlators/cluster/map/src/map.h
@@ -1,17 +1,26 @@
/*
- Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
- This file is part of GlusterFS.
+ Copyright (c) 2008-2009 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 General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that 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 __MAP_H__
#define __MAP_H__
#include "xlator.h"
-#include "map-mem-types.h"
struct map_pattern {
struct map_pattern *next;
@@ -37,7 +46,7 @@ typedef struct {
int32_t op_errno;
int call_count;
struct statvfs statvfs;
- struct iatt stbuf;
+ struct stat stbuf;
inode_t *inode;
dict_t *dict;
fd_t *fd;
diff --git a/xlators/cluster/stripe/src/Makefile.am b/xlators/cluster/stripe/src/Makefile.am
index 4268d6f0382..180d0da1f3c 100644
--- a/xlators/cluster/stripe/src/Makefile.am
+++ b/xlators/cluster/stripe/src/Makefile.am
@@ -1,19 +1,16 @@
+
xlator_LTLIBRARIES = stripe.la
xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/cluster
-stripe_la_LDFLAGS = -module -avoid-version
-
-stripe_la_SOURCES = stripe.c stripe-helpers.c \
- $(top_builddir)/xlators/lib/src/libxlator.c
+stripe_la_LDFLAGS = -module -avoidversion
+stripe_la_SOURCES = stripe.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
-
-AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \
- -I$(top_srcdir)/xlators/lib/src
+noinst_HEADERS = stripe.h
-AM_CFLAGS = -Wall $(GF_CFLAGS)
+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/stripe/src/stripe-helpers.c b/xlators/cluster/stripe/src/stripe-helpers.c
deleted file mode 100644
index 3c12809d625..00000000000
--- a/xlators/cluster/stripe/src/stripe-helpers.c
+++ /dev/null
@@ -1,677 +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"
-#include "mem-types.h"
-#include "logging.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;
-}
-
-
-
-int
-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 0;
-}
-
-
-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_lockinfo_xattr (xlator_t *this, stripe_local_t *local,
- void **xattr_serz)
-{
- int32_t ret = -1, i = 0, len = 0;
- dict_t *tmp1 = NULL, *tmp2 = NULL;
- char *buf = NULL;
- stripe_xattr_sort_t *xattr = NULL;
-
- if (xattr_serz == NULL) {
- goto out;
- }
-
- tmp2 = dict_new ();
-
- if (tmp2 == NULL) {
- goto out;
- }
-
- for (i = 0; i < local->nallocs; i++) {
- xattr = local->xattr_list + i;
- len = xattr->xattr_len;
-
- if (len && xattr && xattr->xattr_value) {
- ret = dict_reset (tmp2);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_DEBUG,
- "dict_reset failed (%s)",
- strerror (-ret));
- }
-
- ret = dict_unserialize (xattr->xattr_value,
- xattr->xattr_len,
- &tmp2);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_WARNING,
- "dict_unserialize failed (%s)",
- strerror (-ret));
- ret = -1;
- goto out;
- }
-
- tmp1 = dict_copy (tmp2, tmp1);
- if (tmp1 == NULL) {
- gf_log (this->name, GF_LOG_WARNING,
- "dict_copy failed (%s)",
- strerror (-ret));
- ret = -1;
- goto out;
- }
- }
- }
-
- len = dict_serialized_length (tmp1);
- if (len > 0) {
- buf = GF_CALLOC (1, len, gf_common_mt_dict_t);
- if (buf == NULL) {
- ret = -1;
- goto out;
- }
-
- ret = dict_serialize (tmp1, buf);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_WARNING,
- "dict_serialize failed (%s)", strerror (-ret));
- GF_FREE(buf);
- ret = -1;
- goto out;
- }
-
- *xattr_serz = buf;
- }
-
- ret = 0;
-out:
- if (tmp1 != NULL) {
- dict_unref (tmp1);
- }
-
- if (tmp2 != NULL) {
- dict_unref (tmp2);
- }
-
- 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, "%"PRId64,
- (long long) (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");
- GF_FREE(pathinfo_serz);
- 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_uint64 (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_uint64 (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
deleted file mode 100644
index e9ac9cf4648..00000000000
--- a/xlators/cluster/stripe/src/stripe-mem-types.h
+++ /dev/null
@@ -1,31 +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 __STRIPE_MEM_TYPES_H__
-#define __STRIPE_MEM_TYPES_H__
-
-#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_fd_ctx_t,
- gf_stripe_mt_char,
- gf_stripe_mt_int8_t,
- gf_stripe_mt_int32_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 7783603c0a5..cbfbf288466 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-2009 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 General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that 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/>.
*/
/**
* 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,28 +32,472 @@
* very much necessary, or else, use it in combination with AFR, to have a
* backup copy.
*/
-#include <fnmatch.h>
+
+/* TODO:
+ * 1. Implement basic self-heal ability to manage the basic backend
+ * layout missmatch.
+ *
+ */
#include "stripe.h"
-#include "libxlator.h"
-#include "byte-order.h"
-#include "statedump.h"
-struct volume_options options[];
+/**
+ * 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;
+ pathname = strdup (path);
+ trav = opts;
+
+ while (trav) {
+ if (!fnmatch (trav->path_pattern, pathname, FNM_NOESCAPE)) {
+ block_size = trav->block_size;
+ break;
+ }
+ trav = trav->next;
+ }
+ free (pathname);
+
+ return block_size;
+}
+
+/**
+ * stripe_common_cbk - This function is used for all the _cbk without
+ * any extra arguments (other than the minimum given)
+ * This is called from functions like fsync,unlink,rmdir etc.
+ *
+ */
+int32_t
+stripe_common_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno)
+{
+ int32_t callcnt = 0;
+ stripe_local_t *local = NULL;
+ call_frame_t *prev = NULL;
+
+ 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));
+ local->op_errno = op_errno;
+ if ((op_errno != ENOENT) ||
+ (prev->this == FIRST_CHILD (this)))
+ local->failed = 1;
+ }
+ if (op_ret >= 0)
+ local->op_ret = op_ret;
+ }
+ UNLOCK (&frame->lock);
+
+ if (!callcnt) {
+ if (local->failed)
+ local->op_ret = -1;
+
+ if (local->loc.path)
+ loc_wipe (&local->loc);
+ if (local->loc2.path)
+ loc_wipe (&local->loc2);
+
+ STACK_UNWIND (frame, local->op_ret, local->op_errno);
+ }
+ return 0;
+}
+
+
+
+int32_t
+stripe_fsync_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct stat *prebuf,
+ struct stat *postbuf)
+{
+ int32_t callcnt = 0;
+ stripe_local_t *local = NULL;
+ call_frame_t *prev = NULL;
+
+ 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));
+ local->op_errno = op_errno;
+ if ((op_errno != ENOENT) ||
+ (prev->this == FIRST_CHILD (this)))
+ local->failed = 1;
+ }
+ if (op_ret >= 0) {
+ local->op_ret = op_ret;
+ if (FIRST_CHILD(this) == prev->this) {
+ local->pre_buf = *prebuf;
+ local->post_buf = *postbuf;
+ }
+ local->prebuf_blocks += prebuf->st_blocks;
+ local->postbuf_blocks += postbuf->st_blocks;
+
+ if (local->prebuf_size < prebuf->st_size)
+ local->prebuf_size = prebuf->st_size;
+
+ if (local->postbuf_size < postbuf->st_size)
+ local->postbuf_size = postbuf->st_size;
+ }
+ }
+ UNLOCK (&frame->lock);
+
+ if (!callcnt) {
+ if (local->failed)
+ local->op_ret = -1;
+
+ if (local->loc.path)
+ loc_wipe (&local->loc);
+ if (local->loc2.path)
+ loc_wipe (&local->loc2);
+
+ if (local->op_ret != -1) {
+ local->pre_buf.st_blocks = local->prebuf_blocks;
+ local->pre_buf.st_size = local->prebuf_size;
+ local->post_buf.st_blocks = local->postbuf_blocks;
+ local->post_buf.st_size = local->postbuf_size;
+ }
+ STACK_UNWIND_STRICT (fsync, frame, local->op_ret,
+ local->op_errno, &local->pre_buf,
+ &local->post_buf);
+ }
+ return 0;
+}
+
+
+/**
+ * stripe_unlink_cbk -
+ * This is called from functions like unlink,rmdir.
+ *
+ */
+int32_t
+stripe_unlink_cbk (call_frame_t *frame, void *cookie,
+ xlator_t *this, int32_t op_ret,
+ int32_t op_errno, struct stat *preparent,
+ struct stat *postparent)
+{
+ int32_t callcnt = 0;
+ stripe_local_t *local = NULL;
+ call_frame_t *prev = NULL;
+
+ 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));
+ local->op_errno = op_errno;
+ if ((op_errno != ENOENT) ||
+ (prev->this == FIRST_CHILD (this)))
+ local->failed = 1;
+ }
+ 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->st_blocks;
+ local->postparent_blocks += postparent->st_blocks;
+
+ if (local->preparent_size < preparent->st_size)
+ local->preparent_size = preparent->st_size;
+
+ if (local->postparent_size < postparent->st_size)
+ local->postparent_size = postparent->st_size;
+ }
+ }
+ UNLOCK (&frame->lock);
+
+ if (!callcnt) {
+ if (local->failed)
+ local->op_ret = -1;
+
+ if (local->loc.path)
+ loc_wipe (&local->loc);
+ if (local->loc2.path)
+ loc_wipe (&local->loc2);
+
+ if (local->op_ret != -1) {
+ local->preparent.st_blocks = local->preparent_blocks;
+ local->preparent.st_size = local->preparent_size;
+ local->postparent.st_blocks = local->postparent_blocks;
+ local->postparent.st_size = local->postparent_size;
+ }
+ STACK_UNWIND (frame, local->op_ret, local->op_errno,
+ &local->preparent, &local->postparent);
+ }
+ return 0;
+}
+
+int32_t
+stripe_truncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct stat *prebuf,
+ struct stat *postbuf)
+{
+ int32_t callcnt = 0;
+ stripe_local_t *local = NULL;
+ call_frame_t *prev = NULL;
+
+ 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 error %s",
+ prev->this->name, strerror (op_errno));
+ local->op_errno = op_errno;
+ if ((op_errno != ENOENT) ||
+ (prev->this == FIRST_CHILD (this)))
+ local->failed = 1;
+ }
+
+ if (op_ret == 0) {
+ local->op_ret = 0;
+ if (FIRST_CHILD(this) == prev->this) {
+ local->pre_buf = *prebuf;
+ local->post_buf = *postbuf;
+ }
+
+ local->prebuf_blocks += prebuf->st_blocks;
+ local->postbuf_blocks += postbuf->st_blocks;
+
+ if (local->prebuf_size < prebuf->st_size)
+ local->prebuf_size = prebuf->st_size;
+
+ if (local->postbuf_size < postbuf->st_size)
+ local->postbuf_size = postbuf->st_size;
+ }
+ }
+ UNLOCK (&frame->lock);
+
+ if (!callcnt) {
+ if (local->failed)
+ local->op_ret = -1;
+
+ if (local->loc.path)
+ loc_wipe (&local->loc);
+ if (local->loc2.path)
+ loc_wipe (&local->loc2);
+
+ if (local->op_ret != -1) {
+ local->pre_buf.st_blocks = local->prebuf_blocks;
+ local->pre_buf.st_size = local->prebuf_size;
+ local->post_buf.st_blocks = local->postbuf_blocks;
+ local->post_buf.st_size = local->postbuf_size;
+ }
+
+ STACK_UNWIND_STRICT (truncate, frame, local->op_ret,
+ local->op_errno, &local->pre_buf,
+ &local->post_buf);
+ }
+
+ return 0;
+}
+
+
+/**
+ * stripe_common_buf_cbk - This function is used for all the _cbk with
+ * 'struct stat *buf' as extra argument (other than minimum)
+ * This is called from functions like, chmod, fchmod, chown, fchown,
+ * truncate, ftruncate, utimens etc.
+ *
+ * @cookie - this argument should be always 'xlator_t *' of child node
+ */
+int32_t
+stripe_common_buf_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct stat *buf)
+{
+ int32_t callcnt = 0;
+ stripe_local_t *local = NULL;
+ call_frame_t *prev = NULL;
+
+ 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 error %s",
+ prev->this->name, strerror (op_errno));
+ local->op_errno = op_errno;
+ if ((op_errno != ENOENT) ||
+ (prev->this == FIRST_CHILD (this)))
+ local->failed = 1;
+ }
+
+ if (op_ret == 0) {
+ local->op_ret = 0;
+
+ if (FIRST_CHILD(this) == prev->this) {
+ local->stbuf = *buf;
+ }
+
+ local->stbuf_blocks += buf->st_blocks;
+ if (local->stbuf_size < buf->st_size)
+ local->stbuf_size = buf->st_size;
+ }
+ }
+ UNLOCK (&frame->lock);
+
+ if (!callcnt) {
+ if (local->failed)
+ local->op_ret = -1;
+
+ if (local->loc.path)
+ loc_wipe (&local->loc);
+ if (local->loc2.path)
+ loc_wipe (&local->loc2);
+
+ if (local->op_ret != -1) {
+ local->stbuf.st_size = local->stbuf_size;
+ local->stbuf.st_blocks = local->stbuf_blocks;
+ }
+
+ STACK_UNWIND (frame, local->op_ret, local->op_errno,
+ &local->stbuf);
+ }
+
+ return 0;
+}
+
+/* In case of symlink, mknod, the file is created on just first node */
+int32_t
+stripe_mknod_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, inode_t *inode,
+ struct stat *buf, struct stat *preparent,
+ struct stat *postparent)
+{
+ STACK_UNWIND_STRICT (mknod, frame, op_ret, op_errno, inode, buf,
+ preparent, postparent);
+ return 0;
+}
+
+/**
+ * stripe_common_inode_cbk - This is called by the function like,
+ * link (), symlink (), mkdir (), mknod ()
+ * This creates a inode for new inode. It keeps a list of all
+ * the inodes received from the child nodes. It is used while
+ * forwarding any fops to child nodes.
+ *
+ */
+int32_t
+stripe_common_inode_cbk (call_frame_t *frame, void *cookie,
+ xlator_t *this, int32_t op_ret,
+ int32_t op_errno, inode_t *inode,
+ struct stat *buf, struct stat *preparent,
+ struct stat *postparent)
+{
+ int32_t callcnt = 0;
+ stripe_local_t *local = NULL;
+ inode_t *local_inode = NULL;
+ call_frame_t *prev = NULL;
+
+ 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 error %s",
+ prev->this->name, strerror (op_errno));
+ local->op_errno = op_errno;
+ if ((op_errno != ENOENT) ||
+ (prev->this == FIRST_CHILD (this)))
+ local->failed = 1;
+ }
+
+ 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->st_blocks;
+ local->preparent_blocks += preparent->st_blocks;
+ local->postparent_blocks += postparent->st_blocks;
+
+ if (local->stbuf_size < buf->st_size)
+ local->stbuf_size = buf->st_size;
+ if (local->preparent_size < preparent->st_size)
+ local->preparent_size = preparent->st_size;
+ if (local->postparent_size < postparent->st_size)
+ local->postparent_size = postparent->st_size;
+ }
+ }
+ UNLOCK (&frame->lock);
+
+ if (!callcnt) {
+ if (local->failed)
+ local->op_ret = -1;
+
+ local_inode = local->inode;
+
+ if (local->op_ret != -1) {
+ local->preparent.st_blocks = local->preparent_blocks;
+ local->preparent.st_size = local->preparent_size;
+ local->postparent.st_blocks = local->postparent_blocks;
+ local->postparent.st_size = local->postparent_size;
+ local->stbuf.st_size = local->stbuf_size;
+ local->stbuf.st_blocks = local->stbuf_blocks;
+ }
+ STACK_UNWIND (frame, local->op_ret, local->op_errno,
+ local->inode, &local->stbuf,
+ &local->preparent, &local->postparent);
+
+ if (local_inode)
+ inode_unref (local_inode);
+ }
+
+ return 0;
+}
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 stat *preop, struct stat *postop)
{
int callcnt = -1;
stripe_local_t *local = NULL;
- if (!this || !frame || !frame->local) {
- gf_log ("stripe", GF_LOG_DEBUG, "possible NULL deref");
- goto out;
- }
-
local = frame->local;
LOCK (&frame->lock);
@@ -54,34 +507,28 @@ stripe_sh_chown_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
UNLOCK (&frame->lock);
if (!callcnt) {
- STRIPE_STACK_DESTROY (frame);
+ loc_wipe (&local->loc);
+ STACK_DESTROY (frame->root);
}
-out:
return 0;
}
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 stat *buf, struct stat *preparent,
+ struct stat *postparent)
{
stripe_local_t *local = NULL;
- call_frame_t *prev = NULL;
-
- if (!frame || !frame->local || !cookie || !this) {
- gf_log ("stripe", GF_LOG_DEBUG, "possible NULL deref");
- goto out;
- }
+ call_frame_t *prev = NULL;
- prev = cookie;
+ prev = cookie;
local = frame->local;
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,16 +540,9 @@ 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;
- int ret = 0;
-
- if (!local || !this || !frame) {
- gf_log ("stripe", GF_LOG_DEBUG, "possible NULL deref");
- goto out;
- }
- if (!(IA_ISREG (local->stbuf.ia_type) ||
- IA_ISDIR (local->stbuf.ia_type)))
+ if (!(S_ISREG (local->stbuf.st_mode) ||
+ S_ISDIR (local->stbuf.st_mode)))
return 0;
priv = this->private;
@@ -111,72 +551,43 @@ stripe_entry_self_heal (call_frame_t *frame, xlator_t *this,
if (!rframe) {
goto out;
}
- rlocal = mem_get0 (this->local_pool);
+ rlocal = CALLOC (1, sizeof (stripe_local_t));
if (!rlocal) {
goto out;
}
rframe->local = rlocal;
rlocal->call_count = priv->child_count;
loc_copy (&rlocal->loc, &local->loc);
- memcpy (&rlocal->stbuf, &local->stbuf, sizeof (struct iatt));
-
- xdata = dict_new ();
- if (!xdata)
- goto out;
-
- ret = dict_set_static_bin (xdata, "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);
+ memcpy (&rlocal->stbuf, &local->stbuf, sizeof (struct stat));
while (trav) {
- if (IA_ISREG (local->stbuf.ia_type)) {
+ if (S_ISREG (local->stbuf.st_mode)) {
STACK_WIND (rframe, stripe_sh_make_entry_cbk,
trav->xlator, trav->xlator->fops->mknod,
- &local->loc,
- st_mode_from_ia (local->stbuf.ia_prot,
- local->stbuf.ia_type),
- 0, 0, xdata);
+ &local->loc, local->stbuf.st_mode, 0);
}
- if (IA_ISDIR (local->stbuf.ia_type)) {
+ if (S_ISDIR (local->stbuf.st_mode)) {
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, local->stbuf.st_mode);
}
trav = trav->next;
}
- if (xdata)
- dict_unref (xdata);
- return 0;
-
out:
- if (rframe)
- STRIPE_STACK_DESTROY (rframe);
- if (xdata)
- dict_unref (xdata);
-
return 0;
}
-
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 stat *buf, dict_t *dict, struct stat *postparent)
{
- int32_t callcnt = 0;
- stripe_local_t *local = NULL;
- call_frame_t *prev = NULL;
- int ret = 0;
-
- if (!this || !frame || !frame->local || !cookie) {
- gf_log ("stripe", GF_LOG_DEBUG, "possible NULL deref");
- goto out;
- }
+ int32_t callcnt = 0;
+ dict_t *tmp_dict = NULL;
+ inode_t *tmp_inode = NULL;
+ stripe_local_t *local = NULL;
+ call_frame_t *prev = NULL;
prev = cookie;
local = frame->local;
@@ -186,15 +597,14 @@ stripe_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
callcnt = --local->call_count;
if (op_ret == -1) {
- if ((op_errno != ENOENT) || (op_errno != ESTALE))
+ if (op_errno != ENOENT)
gf_log (this->name, GF_LOG_DEBUG,
"%s returned error %s",
prev->this->name,
strerror (op_errno));
if (local->op_errno != ESTALE)
local->op_errno = op_errno;
- if (((op_errno != ENOENT) && (op_errno != ENOTCONN)
- && (op_errno != ESTALE)) ||
+ if ((op_errno != ENOENT) ||
(prev->this == FIRST_CHILD (this)))
local->failed = 1;
if (op_errno == ENOENT)
@@ -203,108 +613,80 @@ 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);
+ local->dict = dict_ref (dict);
}
+ local->stbuf_blocks += buf->st_blocks;
+ local->postparent_blocks += postparent->st_blocks;
- 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)) {
- gf_log (this->name, GF_LOG_WARNING,
- "%s: gfid different on subvolume %s",
- local->loc.path, prev->this->name);
- }
+ if (local->stbuf_size < buf->st_size)
+ local->stbuf_size = buf->st_size;
+ if (local->postparent_size < postparent->st_size)
+ local->postparent_size = postparent->st_size;
}
}
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);
+ local->stbuf.st_blocks = local->stbuf_blocks;
+ local->stbuf.st_size = local->stbuf_size;
+ local->postparent.st_blocks = local->postparent_blocks;
+ local->postparent.st_size = local->postparent_size;
}
- STRIPE_STACK_UNWIND (lookup, frame, local->op_ret,
+ loc_wipe (&local->loc);
+
+ STACK_UNWIND_STRICT (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;
}
+/**
+ * stripe_lookup -
+ */
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;
- int32_t op_errno = EINVAL;
- int64_t filesize = 0;
- int ret = 0;
- uint64_t tmpctx = 0;
+ stripe_local_t *local = NULL;
+ xlator_list_t *trav = NULL;
+ stripe_private_t *priv = NULL;
+ int32_t op_errno = 1;
VALIDATE_OR_GOTO (frame, err);
VALIDATE_OR_GOTO (this, err);
VALIDATE_OR_GOTO (loc, err);
+ VALIDATE_OR_GOTO (loc->path, err);
VALIDATE_OR_GOTO (loc->inode, err);
priv = this->private;
trav = this->children;
/* Initialization */
- local = mem_get0 (this->local_pool);
+ local = CALLOC (1, sizeof (stripe_local_t));
if (!local) {
op_errno = ENOMEM;
goto err;
@@ -313,127 +695,32 @@ 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);
- return 0;
-}
-
-
-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 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 error %s",
- prev->this->name, strerror (op_errno));
- local->op_errno = op_errno;
- if ((op_errno != ENOENT) ||
- (prev->this == FIRST_CHILD (this)))
- local->failed = 1;
- }
-
- if (op_ret == 0) {
- local->op_ret = 0;
-
- if (FIRST_CHILD(this) == prev->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;
- }
- }
- UNLOCK (&frame->lock);
-
- if (!callcnt) {
- if (local->failed)
- local->op_ret = -1;
-
- if (local->op_ret != -1) {
- local->stbuf.ia_size = local->stbuf_size;
- local->stbuf.ia_blocks = local->stbuf_blocks;
- }
-
- STRIPE_STACK_UNWIND (stat, frame, local->op_ret,
- local->op_errno, &local->stbuf, NULL);
- }
-out:
+ err:
+ STACK_UNWIND_STRICT (lookup, frame, -1, op_errno, NULL,NULL,NULL,NULL);
return 0;
}
+/**
+ * stripe_stat -
+ */
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;
+ int32_t op_errno = 1;
VALIDATE_OR_GOTO (frame, err);
VALIDATE_OR_GOTO (this, err);
@@ -450,7 +737,7 @@ stripe_stat (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
}
/* Initialization */
- local = mem_get0 (this->local_pool);
+ local = CALLOC (1, sizeof (stripe_local_t));
if (!local) {
op_errno = ENOMEM;
goto err;
@@ -459,38 +746,30 @@ 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);
+ STACK_WIND (frame, stripe_common_buf_cbk, trav->xlator,
+ trav->xlator->fops->stat, loc);
trav = trav->next;
}
return 0;
err:
- STRIPE_STACK_UNWIND (stat, frame, -1, op_errno, NULL, NULL);
+ STACK_UNWIND_STRICT (stat, frame, -1, op_errno, NULL);
return 0;
}
+/**
+ * stripe_statfs_cbk -
+ */
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;
- if (!this || !frame || !frame->local) {
- gf_log ("stripe", GF_LOG_DEBUG, "possible NULL deref");
- goto out;
- }
local = frame->local;
LOCK(&frame->lock);
@@ -519,30 +798,30 @@ stripe_statfs_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
UNLOCK (&frame->lock);
if (!callcnt) {
- STRIPE_STACK_UNWIND (statfs, frame, local->op_ret,
- local->op_errno, &local->statvfs_buf, NULL);
+ STACK_UNWIND_STRICT (statfs, frame, local->op_ret,
+ local->op_errno, &local->statvfs_buf);
}
-out:
+
return 0;
}
+
+/**
+ * stripe_statfs -
+ */
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;
stripe_private_t *priv = NULL;
- int32_t op_errno = EINVAL;
-
- VALIDATE_OR_GOTO (frame, err);
- VALIDATE_OR_GOTO (this, err);
- VALIDATE_OR_GOTO (loc, err);
+ int32_t op_errno = 1;
trav = this->children;
priv = this->private;
/* Initialization */
- local = mem_get0 (this->local_pool);
+ local = CALLOC (1, sizeof (stripe_local_t));
if (!local) {
op_errno = ENOMEM;
goto err;
@@ -554,99 +833,27 @@ 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);
+ err:
+ STACK_UNWIND_STRICT (statfs, frame, -1, op_errno, NULL);
return 0;
}
-
-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)
-{
- 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 error %s",
- prev->this->name, strerror (op_errno));
- local->op_errno = op_errno;
- if ((op_errno != ENOENT) ||
- (prev->this == FIRST_CHILD (this)))
- local->failed = 1;
- }
-
- if (op_ret == 0) {
- local->op_ret = 0;
- if (FIRST_CHILD(this) == prev->this) {
- local->pre_buf = *prebuf;
- local->post_buf = *postbuf;
- }
-
- 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;
-
- if (local->postbuf_size < postbuf->ia_size)
- local->postbuf_size = postbuf->ia_size;
- }
- }
- UNLOCK (&frame->lock);
-
- if (!callcnt) {
- if (local->failed)
- local->op_ret = -1;
-
- if (local->op_ret != -1) {
- local->pre_buf.ia_blocks = local->prebuf_blocks;
- local->pre_buf.ia_size = local->prebuf_size;
- local->post_buf.ia_blocks = local->postbuf_blocks;
- local->post_buf.ia_size = local->postbuf_size;
- }
-
- STRIPE_STACK_UNWIND (truncate, frame, local->op_ret,
- local->op_errno, &local->pre_buf,
- &local->post_buf, NULL);
- }
-out:
- return 0;
-}
-
+/**
+ * stripe_truncate -
+ */
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;
+ int32_t op_errno = 1;
VALIDATE_OR_GOTO (frame, err);
VALIDATE_OR_GOTO (this, err);
@@ -655,6 +862,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 +870,7 @@ stripe_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset,
}
/* Initialization */
- local = mem_get0 (this->local_pool);
+ local = CALLOC (1, sizeof (stripe_local_t));
if (!local) {
op_errno = ENOMEM;
goto err;
@@ -671,55 +879,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);
+ err:
+ STACK_UNWIND_STRICT (truncate, frame, -1, op_errno, NULL, NULL);
return 0;
}
@@ -727,18 +895,13 @@ 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 stat *preop, struct stat *postop)
{
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;
+ prev = cookie;
local = frame->local;
LOCK (&frame->lock);
@@ -763,16 +926,13 @@ stripe_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
local->post_buf = *postop;
}
- 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);
+ local->prebuf_blocks += preop->st_blocks;
+ local->postbuf_blocks += postop->st_blocks;
- if (local->prebuf_size < preop->ia_size)
- local->prebuf_size = preop->ia_size;
- if (local->postbuf_size < postop->ia_size)
- local->postbuf_size = postop->ia_size;
+ if (local->prebuf_size < preop->st_size)
+ local->prebuf_size = preop->st_size;
+ if (local->postbuf_size < postop->st_size)
+ local->postbuf_size = postop->st_size;
}
}
UNLOCK (&frame->lock);
@@ -781,31 +941,35 @@ stripe_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
if (local->failed)
local->op_ret = -1;
+ if (local->loc.path)
+ loc_wipe (&local->loc);
+ if (local->loc2.path)
+ loc_wipe (&local->loc2);
+
if (local->op_ret != -1) {
- local->pre_buf.ia_blocks = local->prebuf_blocks;
- local->pre_buf.ia_size = local->prebuf_size;
- local->post_buf.ia_blocks = local->postbuf_blocks;
- local->post_buf.ia_size = local->postbuf_size;
+ local->pre_buf.st_blocks = local->prebuf_blocks;
+ local->pre_buf.st_size = local->prebuf_size;
+ local->post_buf.st_blocks = local->postbuf_blocks;
+ local->post_buf.st_size = local->postbuf_size;
}
- STRIPE_STACK_UNWIND (setattr, frame, local->op_ret,
+ STACK_UNWIND_STRICT (setattr, frame, local->op_ret,
local->op_errno, &local->pre_buf,
- &local->post_buf, NULL);
+ &local->post_buf);
}
-out:
+
return 0;
}
int32_t
stripe_setattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
- struct iatt *stbuf, int32_t valid, dict_t *xdata)
+ struct stat *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;
+ int32_t op_errno = 1;
VALIDATE_OR_GOTO (frame, err);
VALIDATE_OR_GOTO (this, err);
@@ -822,52 +986,37 @@ stripe_setattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
}
/* Initialization */
- local = mem_get0 (this->local_pool);
+ local = CALLOC (1, sizeof (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);
+ err:
+ STACK_UNWIND_STRICT (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 stat *stbuf, int32_t valid)
{
stripe_local_t *local = NULL;
stripe_private_t *priv = NULL;
xlator_list_t *trav = NULL;
- int32_t op_errno = EINVAL;
+ int32_t op_errno = 1;
VALIDATE_OR_GOTO (frame, err);
VALIDATE_OR_GOTO (this, err);
@@ -878,7 +1027,7 @@ stripe_fsetattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
trav = this->children;
/* Initialization */
- local = mem_get0 (this->local_pool);
+ local = CALLOC (1, sizeof (stripe_local_t));
if (!local) {
op_errno = ENOMEM;
goto err;
@@ -889,33 +1038,27 @@ 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);
+ err:
+ STACK_UNWIND_STRICT (fsetattr, frame, -1, op_errno, NULL, NULL);
return 0;
}
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)
+stripe_rename_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct stat *buf,
+ struct stat *preoldparent, struct stat *postoldparent,
+ struct stat *prenewparent, struct stat *postnewparent)
{
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;
+ prev = cookie;
local = frame->local;
LOCK (&frame->lock);
@@ -935,28 +1078,26 @@ stripe_stack_rename_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
if (op_ret == 0) {
local->op_ret = 0;
- local->stbuf.ia_blocks += buf->ia_blocks;
- local->preparent.ia_blocks += preoldparent->ia_blocks;
- local->postparent.ia_blocks += postoldparent->ia_blocks;
- local->pre_buf.ia_blocks += prenewparent->ia_blocks;
- local->post_buf.ia_blocks += postnewparent->ia_blocks;
-
- correct_file_size(buf, local->fctx, prev);
+ local->stbuf.st_blocks += buf->st_blocks;
+ local->preparent.st_blocks += preoldparent->st_blocks;
+ local->postparent.st_blocks += postoldparent->st_blocks;
+ local->pre_buf.st_blocks += prenewparent->st_blocks;
+ local->post_buf.st_blocks += postnewparent->st_blocks;
- if (local->stbuf.ia_size < buf->ia_size)
- local->stbuf.ia_size = buf->ia_size;
+ if (local->stbuf.st_size < buf->st_size)
+ local->stbuf.st_size = buf->st_size;
- if (local->preparent.ia_size < preoldparent->ia_size)
- local->preparent.ia_size = preoldparent->ia_size;
+ if (local->preparent.st_size < preoldparent->st_size)
+ local->preparent.st_size = preoldparent->st_size;
- if (local->postparent.ia_size < postoldparent->ia_size)
- local->postparent.ia_size = postoldparent->ia_size;
+ if (local->postparent.st_size < postoldparent->st_size)
+ local->postparent.st_size = postoldparent->st_size;
- if (local->pre_buf.ia_size < prenewparent->ia_size)
- local->pre_buf.ia_size = prenewparent->ia_size;
+ if (local->pre_buf.st_size < prenewparent->st_size)
+ local->pre_buf.st_size = prenewparent->st_size;
- if (local->post_buf.ia_size < postnewparent->ia_size)
- local->post_buf.ia_size = postnewparent->ia_size;
+ if (local->post_buf.st_size < postnewparent->st_size)
+ local->post_buf.st_size = postnewparent->st_size;
}
}
UNLOCK (&frame->lock);
@@ -965,38 +1106,36 @@ stripe_stack_rename_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
if (local->failed)
local->op_ret = -1;
- STRIPE_STACK_UNWIND (rename, frame, local->op_ret, local->op_errno,
- &local->stbuf, &local->preparent,
- &local->postparent, &local->pre_buf,
- &local->post_buf, NULL);
+ if (local->loc.path)
+ loc_wipe (&local->loc);
+ if (local->loc2.path)
+ loc_wipe (&local->loc2);
+
+ STACK_UNWIND_STRICT (rename, frame, local->op_ret,
+ local->op_errno, &local->stbuf,
+ &local->preparent, &local->postparent,
+ &local->pre_buf, &local->post_buf);
}
-out:
+
return 0;
}
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)
+ int32_t op_ret, int32_t op_errno, struct stat *buf,
+ struct stat *preoldparent, struct stat *postoldparent,
+ struct stat *prenewparent, struct stat *postnewparent)
{
stripe_local_t *local = NULL;
xlator_list_t *trav = NULL;
- if (!this || !frame || !frame->local) {
- gf_log ("stripe", GF_LOG_DEBUG, "possible NULL deref");
- op_errno = EINVAL;
- goto unwind;
- }
+ local = frame->local;
+ trav = this->children;
if (op_ret == -1) {
goto unwind;
}
- local = frame->local;
- trav = this->children;
-
local->stbuf = *buf;
local->preparent = *preoldparent;
local->postparent = *postoldparent;
@@ -1008,28 +1147,34 @@ stripe_first_rename_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
trav = trav->next; /* Skip first child */
while (trav) {
- STACK_WIND (frame, stripe_stack_rename_cbk,
+ STACK_WIND (frame, stripe_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);
+ unwind:
+ if (local->loc.path)
+ loc_wipe (&local->loc);
+ if (local->loc2.path)
+ loc_wipe (&local->loc2);
+
+ STACK_UNWIND_STRICT (rename, frame, op_ret, op_errno, buf, preoldparent,
+ postoldparent, prenewparent, postnewparent);
return 0;
}
-
+/**
+ * stripe_rename -
+ */
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;
+ int32_t op_errno = 1;
VALIDATE_OR_GOTO (frame, err);
VALIDATE_OR_GOTO (this, err);
@@ -1048,132 +1193,40 @@ stripe_rename (call_frame_t *frame, xlator_t *this, loc_t *oldloc,
}
/* Initialization */
- local = mem_get0 (this->local_pool);
+ local = CALLOC (1, sizeof (stripe_local_t));
if (!local) {
op_errno = ENOMEM;
goto err;
}
-
- frame->local = local;
-
local->op_ret = -1;
loc_copy (&local->loc, oldloc);
loc_copy (&local->loc2, newloc);
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);
-
+ err:
+ STACK_UNWIND_STRICT (rename, 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)
-{
- 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));
- local->op_errno = op_errno;
- if (op_errno != ENOENT) {
- local->failed = 1;
- local->op_ret = op_ret;
- }
- }
- }
- UNLOCK (&frame->lock);
-
- if (callcnt == 1) {
- if (local->failed) {
- op_errno = local->op_errno;
- goto out;
- }
- STACK_WIND(frame, stripe_first_unlink_cbk, FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->unlink, &local->loc,
- local->xflag, local->xdata);
- }
- return 0;
-out:
- STRIPE_STACK_UNWIND (unlink, frame, -1, op_errno, NULL, NULL, NULL);
-
- return 0;
-}
-
+/**
+ * stripe_unlink -
+ */
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;
stripe_private_t *priv = NULL;
- int32_t op_errno = EINVAL;
+ int32_t op_errno = 1;
VALIDATE_OR_GOTO (frame, err);
VALIDATE_OR_GOTO (this, err);
@@ -1196,124 +1249,75 @@ stripe_unlink (call_frame_t *frame, xlator_t *this, loc_t *loc,
}
/* Initialization */
- local = mem_get0 (this->local_pool);
+ local = CALLOC (1, sizeof (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);
+ err:
+ STACK_UNWIND_STRICT (unlink, frame, -1, op_errno, NULL, NULL);
return 0;
}
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)
+ int32_t op_ret, int32_t op_errno,struct stat *preparent,
+ struct stat *postparent)
+
{
+ xlator_list_t *trav = NULL;
stripe_local_t *local = NULL;
- if (!this || !frame || !frame->local) {
- gf_log ("stripe", GF_LOG_DEBUG, "possible NULL deref");
- op_errno = EINVAL;
- goto err;
- }
-
if (op_ret == -1) {
- goto err;
+ STACK_UNWIND_STRICT (rmdir, frame, op_ret, op_errno, NULL,NULL);
+ return 0;
}
+ 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;
- local->preparent_size = preparent->ia_size;
- local->postparent_size = postparent->ia_size;
- 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;
+ local->preparent_blocks += preparent->st_blocks;
+ local->postparent_blocks += postparent->st_blocks;
+ local->preparent_size = preparent->st_size;
+ local->postparent_size = postparent->st_size;
- 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);
+ 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);
return 0;
}
+/**
+ * stripe_rmdir -
+ */
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)
{
xlator_list_t *trav = NULL;
stripe_local_t *local = NULL;
stripe_private_t *priv = NULL;
- int32_t op_errno = EINVAL;
+ int32_t op_errno = 1;
VALIDATE_OR_GOTO (frame, err);
VALIDATE_OR_GOTO (this, err);
@@ -1331,7 +1335,7 @@ stripe_rmdir (call_frame_t *frame, xlator_t *this, loc_t *loc, int flags, dict_t
}
/* Initialization */
- local = mem_get0 (this->local_pool);
+ local = CALLOC (1, sizeof (stripe_local_t));
if (!local) {
op_errno = ENOMEM;
goto err;
@@ -1339,19 +1343,14 @@ stripe_rmdir (call_frame_t *frame, xlator_t *this, loc_t *loc, int flags, dict_t
local->op_ret = -1;
frame->local = local;
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);
return 0;
-err:
- STRIPE_STACK_UNWIND (rmdir, frame, -1, op_errno, NULL, NULL, NULL);
+ err:
+ STACK_UNWIND_STRICT (rmdir, frame, -1, op_errno, NULL, NULL);
return 0;
}
@@ -1359,17 +1358,12 @@ err:
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)
+ int32_t op_errno, struct stat *preparent,
+ struct stat *postparent)
{
int32_t callcnt = 0;
stripe_local_t *local = NULL;
- if (!this || !frame || !frame->local) {
- gf_log ("stripe", GF_LOG_DEBUG, "possible NULL deref");
- goto out;
- }
-
local = frame->local;
LOCK (&frame->lock);
@@ -1379,11 +1373,12 @@ stripe_mknod_ifreg_fail_unlink_cbk (call_frame_t *frame, void *cookie,
UNLOCK (&frame->lock);
if (!callcnt) {
- STRIPE_STACK_UNWIND (mknod, frame, local->op_ret, local->op_errno,
- local->inode, &local->stbuf,
- &local->preparent, &local->postparent, NULL);
+ loc_wipe (&local->loc);
+ STACK_UNWIND_STRICT (mknod, frame, local->op_ret,
+ local->op_errno, local->inode, &local->stbuf,
+ &local->preparent, &local->postparent);
}
-out:
+
return 0;
}
@@ -1393,21 +1388,16 @@ 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;
stripe_private_t *priv = NULL;
xlator_list_t *trav = NULL;
- call_frame_t *prev = NULL;
-
- if (!this || !frame || !frame->local || !cookie) {
- gf_log ("stripe", GF_LOG_DEBUG, "possible NULL deref");
- goto out;
- }
+ call_frame_t *prev = NULL;
- prev = cookie;
- priv = this->private;
+ prev = cookie;
+ priv = this->private;
local = frame->local;
LOCK (&frame->lock);
@@ -1432,39 +1422,37 @@ 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;
}
- STRIPE_STACK_UNWIND (mknod, frame, local->op_ret, local->op_errno,
+ loc_wipe (&local->loc);
+ STACK_UNWIND_STRICT (mknod, frame, local->op_ret, local->op_errno,
local->inode, &local->stbuf,
- &local->preparent, &local->postparent, NULL);
+ &local->preparent, &local->postparent);
}
-out:
return 0;
}
+/**
+ */
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 stat *buf, struct stat *preparent,
+ struct stat *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;
+ stripe_private_t *priv = 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;
- priv = this->private;
+ prev = cookie;
+ priv = this->private;
local = frame->local;
LOCK (&frame->lock);
@@ -1480,30 +1468,26 @@ 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");
-
- local->stbuf_blocks += buf->ia_blocks;
- local->preparent_blocks += preparent->ia_blocks;
- local->postparent_blocks += postparent->ia_blocks;
+ if (FIRST_CHILD(this) == prev->this) {
+ local->stbuf = *buf;
+ local->preparent = *preparent;
+ local->postparent = *postparent;
+ }
- correct_file_size(buf, local->fctx, prev);
+ local->stbuf_blocks += buf->st_blocks;
+ local->preparent_blocks += preparent->st_blocks;
+ local->postparent_blocks += postparent->st_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->stbuf_size < buf->st_size)
+ local->stbuf_size = buf->st_size;
+ if (local->preparent_size < preparent->st_size)
+ local->preparent_size = preparent->st_size;
+ if (local->postparent_size < postparent->st_size)
+ local->postparent_size = postparent->st_size;
}
}
UNLOCK (&frame->lock);
@@ -1512,159 +1496,80 @@ 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;
- 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;
- 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;
-}
-
-
-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--;
+ local->preparent.st_blocks = local->preparent_blocks;
+ local->preparent.st_size = local->preparent_size;
+ local->postparent.st_blocks = local->postparent_blocks;
+ local->postparent.st_size = local->postparent_size;
+ local->stbuf.st_size = local->stbuf_size;
+ local->stbuf.st_blocks = local->stbuf_blocks;
+ }
+
+ if ((local->op_ret != -1) && priv->xattr_supported) {
+ /* Send a setxattr request to nodes where the
+ files are created */
+ int32_t index = 0;
+ char size_key[256] = {0,};
+ char index_key[256] = {0,};
+ char count_key[256] = {0,};
+ dict_t *dict = NULL;
- 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;
- }
+ trav = this->children;
+ 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);
- local->op_ret = op_ret;
+ local->call_count = priv->child_count;
- local->stbuf = *buf;
- local->preparent = *preparent;
- local->postparent = *postparent;
+ while (trav) {
+ dict = get_new_dict ();
+ dict_ref (dict);
+ /* TODO: check return value */
+ ret = dict_set_int64 (dict, size_key,
+ local->stripe_size);
+ ret = dict_set_int32 (dict, count_key,
+ priv->child_count);
+ ret = dict_set_int32 (dict, index_key, index);
- 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,
+ trav->xlator,
+ trav->xlator->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);
+ index++;
+ trav = trav->next;
}
- 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;
+ /* Create itself has failed.. so return
+ without setxattring */
+ loc_wipe (&local->loc);
+ STACK_UNWIND_STRICT (mknod, frame, local->op_ret,
+ local->op_errno, local->inode,
+ &local->stbuf, &local->preparent,
+ &local->postparent);
}
-
- 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);
}
return 0;
-
-out:
-
- STRIPE_STACK_UNWIND (mknod, frame, op_ret, op_errno, NULL, NULL, NULL, NULL, NULL);
- return 0;
}
+/**
+ * stripe_mknod -
+ */
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)
-{
- STRIPE_STACK_UNWIND (mknod, frame, op_ret, op_errno, inode, buf,
- preparent, postparent, xdata);
- 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)
{
- 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 = 1;
VALIDATE_OR_GOTO (frame, err);
VALIDATE_OR_GOTO (this, err);
@@ -1673,6 +1578,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;
@@ -1691,198 +1597,51 @@ stripe_mknod (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
}
/* Initialization */
- local = mem_get0 (this->local_pool);
+ local = CALLOC (1, sizeof (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);
+ 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);
-
- return 0;
-err:
- STRIPE_STACK_UNWIND (mknod, frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL);
- return 0;
-}
-
-
-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)
-{
- 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 error %s",
- prev->this->name, strerror (op_errno));
- local->op_errno = op_errno;
- if ((op_errno != ENOENT) ||
- (prev->this == FIRST_CHILD (this)))
- local->failed = 1;
- }
-
- if (op_ret >= 0) {
- local->op_ret = 0;
-
- 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);
-
- if (!callcnt) {
- if (local->failed != -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;
- }
- 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;
+ STACK_WIND (frame, stripe_mknod_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->mknod, loc, mode, rdev);
- local->stbuf_size = buf->ia_size;
- local->preparent_size = preparent->ia_size;
- local->postparent_size = postparent->ia_size;
-
- 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;
- }
return 0;
-out:
- STRIPE_STACK_UNWIND (mkdir, frame, -1, op_errno, NULL, NULL, NULL,
- NULL, NULL);
-
+ err:
+ STACK_UNWIND_STRICT (mknod, frame, -1, op_errno, 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)
+/**
+ * stripe_mkdir -
+ */
+int32_t
+stripe_mkdir (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode)
{
stripe_private_t *priv = NULL;
stripe_local_t *local = NULL;
@@ -1904,122 +1663,35 @@ stripe_mkdir (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
}
/* Initialization */
- local = mem_get0 (this->local_pool);
+ local = CALLOC (1, sizeof (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_common_inode_cbk,
+ trav->xlator, trav->xlator->fops->mkdir,
+ loc, mode);
+ trav = trav->next;
+ }
return 0;
-err:
- STRIPE_STACK_UNWIND (mkdir, frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL);
+ err:
+ STACK_UNWIND_STRICT (mkdir, frame, -1, op_errno, NULL,NULL,NULL,NULL);
return 0;
}
+/**
+ * stripe_link -
+ */
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)
-{
- int32_t callcnt = 0;
- stripe_local_t *local = 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");
- 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 error %s",
- prev->this->name, strerror (op_errno));
- local->op_errno = op_errno;
- if ((op_errno != ENOENT) ||
- (prev->this == FIRST_CHILD (this)))
- local->failed = 1;
- }
-
- 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;
- local->postparent = *postparent;
- local->preparent = *preparent;
- }
- local->stbuf_blocks += buf->ia_blocks;
- 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)
- 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->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;
- }
- STRIPE_STACK_UNWIND (link, frame, local->op_ret,
- local->op_errno, local->inode,
- &local->stbuf, &local->preparent,
- &local->postparent, NULL);
- }
-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;
@@ -2042,7 +1714,7 @@ stripe_link (call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc,
}
/* Initialization */
- local = mem_get0 (this->local_pool);
+ local = CALLOC (1, sizeof (stripe_local_t));
if (!local) {
op_errno = ENOMEM;
goto err;
@@ -2054,31 +1726,28 @@ stripe_link (call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc,
/* Everytime in stripe lookup, all child
nodes should be looked up */
while (trav) {
- STACK_WIND (frame, stripe_link_cbk,
+ STACK_WIND (frame, stripe_common_inode_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);
+ err:
+ STACK_UNWIND_STRICT (link, frame, -1, op_errno, NULL, NULL, NULL, NULL);
return 0;
}
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)
+ int32_t op_errno, struct stat *preparent,
+ struct stat *postparent)
{
int32_t callcnt = 0;
+ fd_t *lfd = NULL;
stripe_local_t *local = NULL;
-
- if (!this || !frame || !frame->local) {
- gf_log ("stripe", GF_LOG_DEBUG, "possible NULL deref");
- goto out;
- }
+ inode_t *local_inode = NULL;
local = frame->local;
@@ -2089,34 +1758,41 @@ stripe_create_fail_unlink_cbk (call_frame_t *frame, void *cookie,
UNLOCK (&frame->lock);
if (!callcnt) {
- STRIPE_STACK_UNWIND (create, frame, local->op_ret, local->op_errno,
- local->fd, local->inode, &local->stbuf,
- &local->preparent, &local->postparent, NULL);
+ local_inode = local->inode;
+ lfd = local->fd;
+ loc_wipe (&local->loc);
+
+ STACK_UNWIND_STRICT (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:
return 0;
}
+/**
+ * stripe_create_setxattr_cbk -
+ */
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");
- goto out;
- }
-
- prev = cookie;
- priv = this->private;
+ prev = cookie;
+ priv = this->private;
local = frame->local;
LOCK (&frame->lock);
@@ -2127,40 +1803,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;
@@ -2169,157 +1818,178 @@ 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;
-
- 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);
- }
+ lfd = local->fd;
+ local_inode = local->inode;
+ loc_wipe (&local->loc);
- /* 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);
+ STACK_UNWIND_STRICT (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:
return 0;
}
-
-
+/**
+ * stripe_create_cbk -
+ */
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)
+ inode_t *inode, struct stat *buf, struct stat *preparent,
+ struct stat *postparent)
{
+ int32_t callcnt = 0;
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;
- loc_t *loc = NULL;
- int32_t need_unref = 0;
- int32_t ret = -1;
-
- if (!this || !frame || !frame->local || !cookie) {
- gf_log ("stripe", GF_LOG_DEBUG, "possible NULL deref");
- goto out;
- }
+ fd_t *lfd = NULL;
+ stripe_fd_ctx_t *fctx = NULL;
+ inode_t *local_inode = NULL;
+ call_frame_t *prev = NULL;
- prev = cookie;
+ 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->st_blocks;
+ local->preparent_blocks += preparent->st_blocks;
+ local->postparent_blocks += postparent->st_blocks;
+
+ if (local->stbuf_size < buf->st_size)
+ local->stbuf_size = buf->st_size;
+ if (local->preparent_size < preparent->st_size)
+ local->preparent_size = preparent->st_size;
+ if (local->postparent_size < postparent->st_size)
+ local->postparent_size = postparent->st_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.st_blocks = local->preparent_blocks;
+ local->preparent.st_size = local->preparent_size;
+ local->postparent.st_blocks = local->postparent_blocks;
+ local->postparent.st_size = local->postparent_size;
+ local->stbuf.st_size = local->stbuf_size;
+ local->stbuf.st_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 = CALLOC (1, sizeof (stripe_fd_ctx_t));
+ if (fctx) {
+ 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->failed)
- local->op_ret = -1;
+ if ((local->op_ret != -1) &&
+ local->stripe_size && priv->xattr_supported) {
+ /* Send a setxattr request to nodes where
+ the files are created */
+ int ret = 0;
+ 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 == -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;
- }
+ local->call_count = priv->child_count;
- 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;
- }
+ for (i = 0; i < priv->child_count; i++) {
+ dict = get_new_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);
+ ret = dict_set_int32 (dict, count_key,
+ priv->child_count);
+ ret = dict_set_int32 (dict, index_key, i);
- dict_copy (local->xattr, dict);
+ STACK_WIND (frame, stripe_create_setxattr_cbk,
+ priv->xl_array[i],
+ priv->xl_array[i]->fops->setxattr,
+ &local->loc, dict, 0);
- 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");
+ dict_unref (dict);
+ }
} else {
- dict = local->xattr;
- }
+ /* Create itself has failed.. so return
+ without setxattring */
+ lfd = local->fd;
+ local_inode = local->inode;
+ loc_wipe (&local->loc);
- 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++;
+ STACK_UNWIND_STRICT (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:
return 0;
}
-
/**
* 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.
@@ -2328,21 +1998,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)
{
stripe_private_t *priv = NULL;
stripe_local_t *local = 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);
- VALIDATE_OR_GOTO (loc, err);
- VALIDATE_OR_GOTO (loc->path, err);
- VALIDATE_OR_GOTO (loc->inode, err);
+ xlator_list_t *trav = NULL;
+ int32_t op_errno = 1;
priv = this->private;
@@ -2357,79 +2018,118 @@ stripe_create (call_frame_t *frame, xlator_t *this, loc_t *loc,
}
/* Initialization */
- local = mem_get0 (this->local_pool);
+ local = CALLOC (1, sizeof (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);
+ 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);
+ err:
+ STACK_UNWIND_STRICT (create, frame, -1, op_errno,
+ NULL,NULL,NULL,NULL,NULL);
return 0;
}
+/**
+ * stripe_open_cbk -
+ */
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) {
- 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) {
+ if ((op_errno != ENOENT) ||
+ (prev->this == FIRST_CHILD (this)))
+ local->failed = 1;
+ gf_log (this->name, GF_LOG_DEBUG,
+ "%s returned error %s",
+ prev->this->name, strerror (op_errno));
+ local->op_errno = op_errno;
+ }
+
+ if (op_ret >= 0)
+ local->op_ret = op_ret;
}
+ UNLOCK (&frame->lock);
+
+ if (!callcnt) {
+ if (local->failed)
+ local->op_ret = -1;
+
+ if (local->op_ret == -1) {
+ if (local->fctx) {
+ if (!local->fctx->static_array)
+ FREE (local->fctx->xl_array);
+ FREE (local->fctx);
+ }
+ } else {
+ fd_ctx_set (local->fd, this,
+ (uint64_t)(long)local->fctx);
+ }
+
+ lfd = local->fd;
+ loc_wipe (&local->loc);
+ STACK_UNWIND_STRICT (open, frame, local->op_ret,
+ local->op_errno, local->fd);
+ if (lfd)
+ fd_unref (lfd);
+
+ }
+
+ return 0;
+}
+
+
+/**
+ * stripe_getxattr_cbk -
+ */
+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;
prev = cookie;
+ priv = this->private;
local = frame->local;
LOCK (&frame->lock);
@@ -2437,39 +2137,158 @@ stripe_open_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
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;
- local->op_errno = op_errno;
+ goto unlock;
}
- if (op_ret >= 0)
- local->op_ret = op_ret;
+ if (!local->fctx) {
+ local->fctx = CALLOC (1, sizeof (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_DEBUG,
+ "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 =
+ CALLOC (local->fctx->stripe_count,
+ sizeof (xlator_t *));
+ }
+ if (local->fctx->stripe_count != data_to_int32 (data)) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "error with stripe-count xattr");
+ 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");
+ 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;
- STRIPE_STACK_UNWIND (open, frame, local->op_ret,
- local->op_errno, local->fd, xdata);
+ if (local->op_ret)
+ goto err;
+
+ if (local->entry_count != local->fctx->stripe_count) {
+ local->op_ret = -1;
+ local->op_errno = EIO;
+ goto err;
+ }
+ if (!local->fctx->stripe_size) {
+ 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;
+ }
}
-out:
+
return 0;
-}
+ err:
+ lfd = local->fd;
+ loc_wipe (&local->loc);
+ STACK_UNWIND_STRICT (open, frame, local->op_ret, local->op_errno,
+ local->fd);
+ if (lfd)
+ fd_unref (lfd);
+ 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;
@@ -2491,7 +2310,7 @@ stripe_open (call_frame_t *frame, xlator_t *this, loc_t *loc,
}
/* Initialization */
- local = mem_get0 (this->local_pool);
+ local = CALLOC (1, sizeof (stripe_local_t));
if (!local) {
op_errno = ENOMEM;
goto err;
@@ -2507,38 +2326,57 @@ 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);
- while (trav) {
- STACK_WIND (frame, stripe_open_cbk, trav->xlator,
- trav->xlator->fops->open,
- &local->loc, local->flags, local->fd,
- xdata);
- trav = trav->next;
+ if (priv->xattr_supported) {
+ while (trav) {
+ STACK_WIND (frame, stripe_open_getxattr_cbk,
+ trav->xlator, trav->xlator->fops->getxattr,
+ loc, NULL);
+ trav = trav->next;
+ }
+ } else {
+ local->fctx = CALLOC (1, sizeof (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,
+ wbflags);
+ trav = trav->next;
+ }
}
+
return 0;
-err:
- STRIPE_STACK_UNWIND (open, frame, -1, op_errno, NULL, NULL);
+ err:
+ STACK_UNWIND_STRICT (open, frame, -1, op_errno, NULL);
return 0;
}
-
+/**
+ * stripe_opendir_cbk -
+ */
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;
+ stripe_local_t *local = frame->local;
+ fd_t *local_fd = 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;
-
+ prev = cookie;
LOCK (&frame->lock);
{
callcnt = --local->call_count;
@@ -2557,21 +2395,27 @@ stripe_opendir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
UNLOCK (&frame->lock);
if (!callcnt) {
- STRIPE_STACK_UNWIND (opendir, frame, local->op_ret,
- local->op_errno, local->fd, NULL);
+ local_fd = local->fd;
+ STACK_UNWIND_STRICT (opendir, frame, local->op_ret,
+ local->op_errno, local->fd);
+ if (local_fd)
+ fd_unref (local_fd);
}
-out:
+
return 0;
}
+/**
+ * stripe_opendir -
+ */
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;
stripe_private_t *priv = NULL;
- int32_t op_errno = EINVAL;
+ int32_t op_errno = 1;
VALIDATE_OR_GOTO (frame, err);
VALIDATE_OR_GOTO (this, err);
@@ -2588,7 +2432,7 @@ stripe_opendir (call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd, dict_
}
/* Initialization */
- local = mem_get0 (this->local_pool);
+ local = CALLOC (1, sizeof (stripe_local_t));
if (!local) {
op_errno = ENOMEM;
goto err;
@@ -2599,30 +2443,29 @@ 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);
+ err:
+ STACK_UNWIND_STRICT (opendir, frame, -1, op_errno, NULL);
return 0;
}
+
+/**
+ * stripe_lk_cbk -
+ */
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 flock *lock)
{
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;
+ prev = cookie;
local = frame->local;
LOCK (&frame->lock);
@@ -2650,21 +2493,24 @@ stripe_lk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
if (!callcnt) {
if (local->failed)
local->op_ret = -1;
- STRIPE_STACK_UNWIND (lk, frame, local->op_ret,
- local->op_errno, &local->lock, NULL);
+ STACK_UNWIND_STRICT (lk, frame, local->op_ret,
+ local->op_errno, &local->lock);
}
-out:
return 0;
}
+
+/**
+ * stripe_lk -
+ */
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 flock *lock)
{
stripe_local_t *local = NULL;
xlator_list_t *trav = NULL;
stripe_private_t *priv = NULL;
- int32_t op_errno = EINVAL;
+ int32_t op_errno = 1;
VALIDATE_OR_GOTO (frame, err);
VALIDATE_OR_GOTO (this, err);
@@ -2675,7 +2521,7 @@ 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 = CALLOC (1, sizeof (stripe_local_t));
if (!local) {
op_errno = ENOMEM;
goto err;
@@ -2686,64 +2532,21 @@ 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);
- 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 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));
- local->op_errno = op_errno;
- if ((op_errno != ENOENT) ||
- (prev->this == FIRST_CHILD (this)))
- local->failed = 1;
- }
- if (op_ret >= 0)
- local->op_ret = op_ret;
- }
- UNLOCK (&frame->lock);
-
- if (!callcnt) {
- if (local->failed)
- local->op_ret = -1;
-
- STRIPE_STACK_UNWIND (flush, frame, local->op_ret,
- local->op_errno, NULL);
- }
-out:
+ err:
+ STACK_UNWIND_STRICT (lk, frame, -1, op_errno, NULL);
return 0;
}
+/**
+ * stripe_flush -
+ */
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;
@@ -2763,7 +2566,7 @@ 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 = CALLOC (1, sizeof (stripe_local_t));
if (!local) {
op_errno = ENOMEM;
goto err;
@@ -2773,96 +2576,27 @@ stripe_flush (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
local->call_count = priv->child_count;
while (trav) {
- STACK_WIND (frame, stripe_flush_cbk, trav->xlator,
- trav->xlator->fops->flush, fd, NULL);
+ STACK_WIND (frame, stripe_common_cbk, trav->xlator,
+ trav->xlator->fops->flush, fd);
trav = trav->next;
}
return 0;
-err:
- STRIPE_STACK_UNWIND (flush, frame, -1, op_errno, NULL);
+ err:
+ STACK_UNWIND_STRICT (flush, frame, -1, op_errno);
return 0;
}
-
-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)
-{
- 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));
- local->op_errno = op_errno;
- if ((op_errno != ENOENT) ||
- (prev->this == FIRST_CHILD (this)))
- local->failed = 1;
- }
- if (op_ret >= 0) {
- local->op_ret = op_ret;
- if (FIRST_CHILD(this) == prev->this) {
- local->pre_buf = *prebuf;
- local->post_buf = *postbuf;
- }
- 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;
-
- if (local->postbuf_size < postbuf->ia_size)
- local->postbuf_size = postbuf->ia_size;
- }
- }
- UNLOCK (&frame->lock);
-
- if (!callcnt) {
- if (local->failed)
- local->op_ret = -1;
-
- if (local->op_ret != -1) {
- local->pre_buf.ia_blocks = local->prebuf_blocks;
- local->pre_buf.ia_size = local->prebuf_size;
- local->post_buf.ia_blocks = local->postbuf_blocks;
- local->post_buf.ia_size = local->postbuf_size;
- }
-
- STRIPE_STACK_UNWIND (fsync, frame, local->op_ret,
- local->op_errno, &local->pre_buf,
- &local->post_buf, NULL);
- }
-out:
- return 0;
-}
-
+/**
+ * stripe_fsync -
+ */
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);
@@ -2874,107 +2608,39 @@ 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 = CALLOC (1, sizeof (stripe_local_t));
if (!local) {
op_errno = ENOMEM;
goto err;
}
-
- frame->local = local;
-
- 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);
+ err:
+ STACK_UNWIND_STRICT (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 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 error %s",
- prev->this->name, strerror (op_errno));
- local->op_errno = op_errno;
- if ((op_errno != ENOENT) ||
- (prev->this == FIRST_CHILD (this)))
- local->failed = 1;
- }
-
- if (op_ret == 0) {
- local->op_ret = 0;
-
- if (FIRST_CHILD(this) == prev->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;
- }
- }
- UNLOCK (&frame->lock);
-
- if (!callcnt) {
- if (local->failed)
- local->op_ret = -1;
-
- if (local->op_ret != -1) {
- local->stbuf.ia_size = local->stbuf_size;
- local->stbuf.ia_blocks = local->stbuf_blocks;
- }
-
- STRIPE_STACK_UNWIND (fstat, frame, local->op_ret,
- local->op_errno, &local->stbuf, NULL);
- }
-
-out:
- return 0;
-}
+/**
+ * stripe_fstat -
+ */
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);
@@ -2986,7 +2652,7 @@ stripe_fstat (call_frame_t *frame,
trav = this->children;
/* Initialization */
- local = mem_get0 (this->local_pool);
+ local = CALLOC (1, sizeof (stripe_local_t));
if (!local) {
op_errno = ENOMEM;
goto err;
@@ -2995,35 +2661,29 @@ 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);
+ STACK_WIND (frame, stripe_common_buf_cbk, trav->xlator,
+ trav->xlator->fops->fstat, fd);
trav = trav->next;
}
return 0;
-err:
- STRIPE_STACK_UNWIND (fstat, frame, -1, op_errno, NULL, NULL);
+ err:
+ STACK_UNWIND_STRICT (fstat, frame, -1, op_errno, NULL);
return 0;
}
+/**
+ * stripe_ftruncate -
+ */
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);
@@ -3031,9 +2691,10 @@ 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 = CALLOC (1, sizeof (stripe_local_t));
if (!local) {
op_errno = ENOMEM;
goto err;
@@ -3042,104 +2703,24 @@ 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);
+ err:
+ STACK_UNWIND_STRICT (ftruncate, frame, -1, op_errno, NULL, NULL);
return 0;
}
+/**
+ * stripe_fsyncdir -
+ */
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 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));
- local->op_errno = op_errno;
- if ((op_errno != ENOENT) ||
- (prev->this == FIRST_CHILD (this)))
- local->failed = 1;
- }
- if (op_ret >= 0)
- local->op_ret = op_ret;
- }
- UNLOCK (&frame->lock);
-
- if (!callcnt) {
- if (local->failed)
- local->op_ret = -1;
-
- STRIPE_STACK_UNWIND (fsyncdir, frame, local->op_ret,
- local->op_errno, NULL);
- }
-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;
@@ -3155,7 +2736,7 @@ 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 = CALLOC (1, sizeof (stripe_local_t));
if (!local) {
op_errno = ENOMEM;
goto err;
@@ -3165,48 +2746,39 @@ stripe_fsyncdir (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags, d
local->call_count = priv->child_count;
while (trav) {
- STACK_WIND (frame, stripe_fsyncdir_cbk, trav->xlator,
- trav->xlator->fops->fsyncdir, fd, flags, NULL);
+ STACK_WIND (frame, stripe_common_cbk, trav->xlator,
+ trav->xlator->fops->fsyncdir, fd, flags);
trav = trav->next;
}
return 0;
-err:
- STRIPE_STACK_UNWIND (fsyncdir, frame, -1, op_errno, NULL);
+ err:
+ STACK_UNWIND_STRICT (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 stat *buf)
{
int32_t i = 0;
int32_t callcnt = 0;
int32_t count = 0;
stripe_local_t *local = NULL;
struct iovec *vec = NULL;
- struct iatt tmp_stbuf = {0,};
+ struct stat 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");
- goto out;
- }
+ struct iobuf *iobuf = NULL;
local = frame->local;
- prev = cookie;
LOCK (&frame->lock);
{
callcnt = --local->call_count;
- if (op_ret != -1) {
- correct_file_size(buf, local->fctx, prev);
- if (local->stbuf_size < buf->ia_size)
- local->stbuf_size = buf->ia_size;
- }
+ if (op_ret != -1)
+ if (local->stbuf_size < buf->st_size)
+ local->stbuf_size = buf->st_size;
}
UNLOCK (&frame->lock);
@@ -3214,8 +2786,7 @@ stripe_readv_fstat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
op_ret = 0;
/* Keep extra space for filling in '\0's */
- vec = GF_CALLOC ((local->count * 2), sizeof (struct iovec),
- gf_stripe_mt_iovec);
+ vec = CALLOC ((local->count * 2), sizeof (struct iovec));
if (!vec) {
op_ret = -1;
goto done;
@@ -3235,8 +2806,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.");
@@ -3245,37 +2815,37 @@ 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++;
}
- GF_FREE (local->replies[i].vector);
+ FREE (local->replies[i].vector);
}
/* FIXME: notice that st_ino, and st_dev (gen) will be
* different than what inode will have. Make sure this doesn't
* cause any bugs at higher levels */
memcpy (&tmp_stbuf, &local->replies[0].stbuf,
- sizeof (struct iatt));
- tmp_stbuf.ia_size = local->stbuf_size;
-
+ sizeof (struct stat));
+ tmp_stbuf.st_size = local->stbuf_size;
done:
- GF_FREE (local->replies);
+ /* */
+ FREE (local->replies);
tmp_iobref = local->iobref;
- STRIPE_STACK_UNWIND (readv, frame, op_ret, op_errno, vec,
- count, &tmp_stbuf, tmp_iobref, NULL);
+ fd_unref (local->fd);
+ STACK_UNWIND_STRICT (readv, frame, op_ret, op_errno, vec,
+ count, &tmp_stbuf, tmp_iobref);
iobref_unref (tmp_iobref);
- GF_FREE (vec);
+ if (vec)
+ FREE (vec);
}
-out:
+
return 0;
}
-
/**
* stripe_readv_cbk - get all the striped reads, and order it properly, send it
* to above layer after putting it in a single vector.
@@ -3283,7 +2853,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 stat *stbuf, struct iobref *iobref)
{
int32_t index = 0;
int32_t callcnt = 0;
@@ -3293,29 +2863,15 @@ stripe_readv_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
stripe_local_t *mlocal = NULL;
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 stat tmp_stbuf = {0,};
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");
- goto end;
- }
local = frame->local;
index = local->node_index;
- prev = cookie;
mframe = local->orig_frame;
- if (!mframe)
- goto out;
-
mlocal = mframe->local;
- if (!mlocal)
- goto out;
-
- fctx = mlocal->fctx;
+ fctx = mlocal->fctx;
LOCK (&mframe->lock);
{
@@ -3327,12 +2883,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);
@@ -3367,8 +2917,7 @@ stripe_readv_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
if (need_to_check_proper_size)
goto check_size;
- final_vec = GF_CALLOC (mlocal->count, sizeof (struct iovec),
- gf_stripe_mt_iovec);
+ final_vec = CALLOC (mlocal->count, sizeof (struct iovec));
if (!final_vec) {
op_ret = -1;
@@ -3381,55 +2930,52 @@ stripe_readv_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
(mlocal->replies[index].count *
sizeof (struct iovec)));
final_count += mlocal->replies[index].count;
- GF_FREE (mlocal->replies[index].vector);
+ FREE (mlocal->replies[index].vector);
}
/* FIXME: notice that st_ino, and st_dev (gen) will be
* different than what inode will have. Make sure this doesn't
* 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;
+ sizeof (struct stat));
done:
/* */
- GF_FREE (mlocal->replies);
+ FREE (mlocal->replies);
tmp_iobref = mlocal->iobref;
- /* work around for nfs truncated read. Bug 3774 */
- tmp_stbuf_p = &tmp_stbuf;
- WIPE (tmp_stbuf_p);
- STRIPE_STACK_UNWIND (readv, mframe, op_ret, op_errno, final_vec,
- final_count, &tmp_stbuf, tmp_iobref, NULL);
+ fd_unref (mlocal->fd);
+ STACK_UNWIND_STRICT (readv, mframe, op_ret, op_errno, final_vec,
+ final_count, &tmp_stbuf, tmp_iobref);
iobref_unref (tmp_iobref);
- GF_FREE (final_vec);
- }
+ if (final_vec)
+ FREE (final_vec);
- goto out;
+ goto out;
-check_size:
- mlocal->call_count = fctx->stripe_count;
+ check_size:
+ mlocal->call_count = fctx->stripe_count;
- for (index = 0; index < fctx->stripe_count; index++) {
- STACK_WIND (mframe, stripe_readv_fstat_cbk,
- (fctx->xl_array[index]),
- (fctx->xl_array[index])->fops->fstat,
- mlocal->fd, NULL);
+ for (index = 0; index < fctx->stripe_count; index++) {
+ STACK_WIND (mframe, stripe_readv_fstat_cbk,
+ (fctx->xl_array[index]),
+ (fctx->xl_array[index])->fops->fstat,
+ mlocal->fd);
+ }
}
-
out:
- STRIPE_STACK_DESTROY (frame);
-end:
+ STACK_DESTROY (frame->root);
return 0;
}
-
+/**
+ * stripe_readv -
+ */
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 op_errno = 1;
int32_t idx = 0;
int32_t index = 0;
int32_t num_stripe = 0;
@@ -3440,18 +2986,17 @@ 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;
+ xlator_list_t *trav = NULL;
+ stripe_private_t *priv = NULL;
stripe_fd_ctx_t *fctx = NULL;
- VALIDATE_OR_GOTO (frame, err);
- VALIDATE_OR_GOTO (this, err);
- VALIDATE_OR_GOTO (fd, err);
- VALIDATE_OR_GOTO (fd->inode, err);
+ trav = this->children;
+ priv = this->private;
- inode_ctx_get (fd->inode, this, &tmp_fctx);
+ fd_ctx_get (fd, this, &tmp_fctx);
if (!tmp_fctx) {
op_errno = EBADFD;
goto err;
@@ -3459,13 +3004,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");
- goto err;
- }
/* The file is stripe across the child nodes. Send the read request
* to the child nodes appropriately after checking which region of
* the file is in which child node. Always '0-<stripe_size>' part of
@@ -3473,9 +3011,9 @@ stripe_readv (call_frame_t *frame, xlator_t *this, fd_t *fd,
*/
rounded_start = floor (offset, stripe_size);
rounded_end = roof (offset+size, stripe_size);
- num_stripe = (rounded_end- rounded_start)/stripe_size;
+ num_stripe = rounded_end/stripe_size - rounded_start/stripe_size;
- local = mem_get0 (this->local_pool);
+ local = CALLOC (1, sizeof (stripe_local_t));
if (!local) {
op_errno = ENOMEM;
goto err;
@@ -3483,8 +3021,7 @@ 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 = CALLOC (num_stripe, sizeof (struct readv_replies));
if (!local->replies) {
op_errno = ENOMEM;
goto err;
@@ -3496,10 +3033,11 @@ stripe_readv (call_frame_t *frame, xlator_t *this, fd_t *fd,
local->offset = offset;
local->fd = fd_ref (fd);
local->fctx = fctx;
+ local->entry_count = off_index % fctx->stripe_count;
for (index = off_index; index < (num_stripe + off_index); index++) {
rframe = copy_frame (frame);
- rlocal = mem_get0 (this->local_pool);
+ rlocal = CALLOC (1, sizeof (stripe_local_t));
if (!rlocal) {
op_errno = ENOMEM;
goto err;
@@ -3513,129 +3051,77 @@ 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 (rframe)
- STRIPE_STACK_DESTROY (rframe);
+ err:
+ if (local->fd)
+ fd_unref (local->fd);
- STRIPE_STACK_UNWIND (readv, frame, -1, op_errno, NULL, 0, NULL, NULL, NULL);
+ STACK_UNWIND_STRICT (readv, frame, -1, op_errno, NULL, 0, NULL, NULL);
return 0;
}
+/**
+ * stripe_writev_cbk -
+ */
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)
+ int32_t op_ret, int32_t op_errno, struct stat *prebuf,
+ struct stat *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");
- goto out;
- }
- prev = cookie;
+ 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) {
+ STACK_UNWIND_STRICT (writev, frame, local->op_ret,
+ local->op_errno, &local->pre_buf,
+ &local->post_buf);
}
-out:
- STRIPE_STACK_DESTROY(frame);
return 0;
}
+/**
+ * stripe_writev -
+ */
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;
+ struct iovec *tmp_vec = vector;
+ 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 = 1;
int32_t idx = 0;
@@ -3646,19 +3132,10 @@ 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);
+ priv = this->private;
- inode_ctx_get (fd->inode, this, &tmp_fctx);
+ fd_ctx_get (fd, this, &tmp_fctx);
if (!tmp_fctx) {
op_errno = EINVAL;
goto err;
@@ -3666,53 +3143,25 @@ 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;
+ total_size += tmp_vec[idx].iov_len;
}
remaining_size = total_size;
- local = mem_get0 (this->local_pool);
+ local = CALLOC (1, sizeof (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. */
+ trav = this->children;
+
idx = (((offset + offset_offset) /
local->stripe_size) % fctx->stripe_count);
@@ -3725,8 +3174,7 @@ stripe_writev (call_frame_t *frame, xlator_t *this, fd_t *fd,
tmp_count = iov_subset (vector, count, offset_offset,
offset_offset + fill_size, NULL);
- tmp_vec = GF_CALLOC (tmp_count, sizeof (struct iovec),
- gf_stripe_mt_iovec);
+ tmp_vec = CALLOC (tmp_count, sizeof (struct iovec));
if (!tmp_vec) {
op_errno = ENOMEM;
goto err;
@@ -3738,578 +3186,55 @@ 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],
- fctx->xl_array[idx]->fops->writev, fd, tmp_vec,
- tmp_count, dest_offset, flags, iobref,
- xdata);
-
- GF_FREE (tmp_vec);
+ STACK_WIND(frame, stripe_writev_cbk, fctx->xl_array[idx],
+ fctx->xl_array[idx]->fops->writev, fd, tmp_vec,
+ tmp_count, offset + offset_offset, iobref);
+ 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);
+ err:
+ STACK_UNWIND_STRICT (writev, frame, -1, op_errno, NULL, NULL);
return 0;
}
-int32_t
-stripe_fallocate_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 callcnt = 0;
- stripe_local_t *local = NULL;
- stripe_local_t *mlocal = NULL;
- call_frame_t *prev = NULL;
- call_frame_t *mframe = NULL;
-
- if (!this || !frame || !frame->local || !cookie) {
- gf_log ("stripe", GF_LOG_DEBUG, "possible NULL deref");
- goto out;
- }
-
- prev = cookie;
- local = frame->local;
- mframe = local->orig_frame;
- mlocal = mframe->local;
-
- LOCK(&frame->lock);
- {
- callcnt = ++mlocal->call_count;
-
- 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;
- }
-
- /* return the first failure */
- if (mlocal->op_ret == 0) {
- mlocal->op_ret = op_ret;
- mlocal->op_errno = op_errno;
- }
- }
- 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;
- STRIPE_STACK_UNWIND (fallocate, mframe, mlocal->op_ret,
- mlocal->op_errno, &mlocal->pre_buf,
- &mlocal->post_buf, NULL);
- }
-out:
- STRIPE_STACK_DESTROY(frame);
- return 0;
-}
int32_t
-stripe_fallocate(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t mode,
- off_t offset, size_t len, dict_t *xdata)
+stripe_release (xlator_t *this, fd_t *fd)
{
- stripe_local_t *local = NULL;
- stripe_fd_ctx_t *fctx = NULL;
- int32_t op_errno = 1;
- int32_t idx = 0;
- int32_t offset_offset = 0;
- int32_t remaining_size = 0;
- off_t fill_size = 0;
- uint64_t stripe_size = 0;
uint64_t tmp_fctx = 0;
- off_t dest_offset = 0;
- call_frame_t *fframe = NULL;
- stripe_local_t *flocal = 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);
- if (!tmp_fctx) {
- op_errno = EINVAL;
- goto err;
- }
- fctx = (stripe_fd_ctx_t *)(long)tmp_fctx;
- stripe_size = fctx->stripe_size;
-
- STRIPE_VALIDATE_FCTX (fctx, err);
-
- remaining_size = len;
-
- local = mem_get0 (this->local_pool);
- 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;
- }
-
- while (1) {
- fframe = copy_frame(frame);
- flocal = mem_get0(this->local_pool);
- if (!flocal) {
- op_errno = ENOMEM;
- goto err;
- }
- flocal->orig_frame = frame;
- fframe->local = flocal;
-
- /* send fallocate request to the associated child node */
- idx = (((offset + offset_offset) /
- local->stripe_size) % fctx->stripe_count);
-
- fill_size = (local->stripe_size -
- ((offset + offset_offset) % local->stripe_size));
- if (fill_size > remaining_size)
- fill_size = remaining_size;
-
- remaining_size -= fill_size;
-
- local->wind_count++;
- if (remaining_size == 0)
- local->unwind = 1;
-
- dest_offset = offset + offset_offset;
- if (fctx->stripe_coalesce)
- dest_offset = coalesced_offset(dest_offset,
- local->stripe_size, fctx->stripe_count);
-
- /*
- * TODO: Create a separate handler for coalesce mode that sends a
- * single fallocate per-child (since the ranges are linear).
- */
- STACK_WIND(fframe, stripe_fallocate_cbk, fctx->xl_array[idx],
- fctx->xl_array[idx]->fops->fallocate, fd, mode,
- dest_offset, fill_size, xdata);
-
- offset_offset += fill_size;
- if (remaining_size == 0)
- break;
- }
-
- return 0;
-err:
- if (fframe)
- STRIPE_STACK_DESTROY(fframe);
-
- STRIPE_STACK_UNWIND (fallocate, frame, -1, op_errno, NULL, NULL, NULL);
- return 0;
-}
-
-
-int32_t
-stripe_discard_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 callcnt = 0;
- stripe_local_t *local = NULL;
- stripe_local_t *mlocal = NULL;
- call_frame_t *prev = NULL;
- call_frame_t *mframe = NULL;
-
- if (!this || !frame || !frame->local || !cookie) {
- gf_log ("stripe", GF_LOG_DEBUG, "possible NULL deref");
- goto out;
- }
-
- prev = cookie;
- local = frame->local;
- mframe = local->orig_frame;
- mlocal = mframe->local;
-
- LOCK(&frame->lock);
- {
- callcnt = ++mlocal->call_count;
-
- 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;
- }
-
- /* return the first failure */
- if (mlocal->op_ret == 0) {
- mlocal->op_ret = op_ret;
- mlocal->op_errno = op_errno;
- }
- }
- 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;
-
- STRIPE_STACK_UNWIND (discard, mframe, mlocal->op_ret,
- mlocal->op_errno, &mlocal->pre_buf,
- &mlocal->post_buf, NULL);
- }
-out:
- STRIPE_STACK_DESTROY(frame);
- return 0;
-}
-
-int32_t
-stripe_discard(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
- size_t len, dict_t *xdata)
-{
- stripe_local_t *local = NULL;
stripe_fd_ctx_t *fctx = NULL;
- int32_t op_errno = 1;
- int32_t idx = 0;
- int32_t offset_offset = 0;
- int32_t remaining_size = 0;
- off_t fill_size = 0;
- uint64_t stripe_size = 0;
- uint64_t tmp_fctx = 0;
- off_t dest_offset = 0;
- call_frame_t *fframe = NULL;
- stripe_local_t *flocal = 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_del (fd, this, &tmp_fctx);
if (!tmp_fctx) {
- op_errno = EINVAL;
- goto err;
- }
- fctx = (stripe_fd_ctx_t *)(long)tmp_fctx;
- stripe_size = fctx->stripe_size;
-
- STRIPE_VALIDATE_FCTX (fctx, err);
-
- remaining_size = len;
-
- local = mem_get0 (this->local_pool);
- 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;
- }
-
- while (1) {
- fframe = copy_frame(frame);
- flocal = mem_get0(this->local_pool);
- if (!flocal) {
- op_errno = ENOMEM;
- goto err;
- }
- flocal->orig_frame = frame;
- fframe->local = flocal;
-
- /* send discard request to the associated child node */
- idx = (((offset + offset_offset) /
- local->stripe_size) % fctx->stripe_count);
-
- fill_size = (local->stripe_size -
- ((offset + offset_offset) % local->stripe_size));
- if (fill_size > remaining_size)
- fill_size = remaining_size;
-
- remaining_size -= fill_size;
-
- local->wind_count++;
- if (remaining_size == 0)
- local->unwind = 1;
-
- dest_offset = offset + offset_offset;
- if (fctx->stripe_coalesce)
- dest_offset = coalesced_offset(dest_offset,
- local->stripe_size, fctx->stripe_count);
-
- /*
- * TODO: Create a separate handler for coalesce mode that sends a
- * single discard per-child (since the ranges are linear).
- */
- STACK_WIND(fframe, stripe_discard_cbk, fctx->xl_array[idx],
- fctx->xl_array[idx]->fops->discard, fd, dest_offset,
- fill_size, xdata);
-
- offset_offset += fill_size;
- if (remaining_size == 0)
- break;
- }
-
- return 0;
-err:
- if (fframe)
- STRIPE_STACK_DESTROY(fframe);
-
- STRIPE_STACK_UNWIND (discard, frame, -1, op_errno, NULL, NULL, NULL);
- return 0;
-}
-
-int32_t
-stripe_zerofill_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 callcnt = 0;
- stripe_local_t *local = NULL;
- stripe_local_t *mlocal = NULL;
- call_frame_t *prev = NULL;
- call_frame_t *mframe = NULL;
-
- GF_ASSERT (frame);
-
- if (!this || !frame->local || !cookie) {
- gf_log ("stripe", GF_LOG_DEBUG, "possible NULL deref");
goto out;
}
- prev = cookie;
- local = frame->local;
- mframe = local->orig_frame;
- mlocal = mframe->local;
-
- LOCK(&frame->lock);
- {
- callcnt = ++mlocal->call_count;
-
- 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;
- }
-
- /* return the first failure */
- if (mlocal->op_ret == 0) {
- mlocal->op_ret = op_ret;
- mlocal->op_errno = op_errno;
- }
- }
- 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;
-
- STRIPE_STACK_UNWIND (zerofill, mframe, mlocal->op_ret,
- mlocal->op_errno, &mlocal->pre_buf,
- &mlocal->post_buf, NULL);
- }
-out:
- STRIPE_STACK_DESTROY(frame);
- return 0;
-}
-
-int32_t
-stripe_zerofill(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
- off_t len, dict_t *xdata)
-{
- stripe_local_t *local = NULL;
- stripe_fd_ctx_t *fctx = NULL;
- int32_t op_errno = 1;
- int32_t idx = 0;
- int32_t offset_offset = 0;
- int32_t remaining_size = 0;
- off_t fill_size = 0;
- uint64_t stripe_size = 0;
- uint64_t tmp_fctx = 0;
- off_t dest_offset = 0;
- call_frame_t *fframe = NULL;
- stripe_local_t *flocal = 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);
- if (!tmp_fctx) {
- op_errno = EINVAL;
- goto err;
- }
fctx = (stripe_fd_ctx_t *)(long)tmp_fctx;
- stripe_size = fctx->stripe_size;
-
- STRIPE_VALIDATE_FCTX (fctx, err);
-
- remaining_size = len;
-
- local = mem_get0 (this->local_pool);
- 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;
- }
-
- while (1) {
- fframe = copy_frame(frame);
- flocal = mem_get0(this->local_pool);
- if (!flocal) {
- op_errno = ENOMEM;
- goto err;
- }
- flocal->orig_frame = frame;
- fframe->local = flocal;
-
- idx = (((offset + offset_offset) /
- local->stripe_size) % fctx->stripe_count);
-
- fill_size = (local->stripe_size -
- ((offset + offset_offset) % local->stripe_size));
- if (fill_size > remaining_size)
- fill_size = remaining_size;
-
- remaining_size -= fill_size;
-
- local->wind_count++;
- if (remaining_size == 0)
- local->unwind = 1;
- dest_offset = offset + offset_offset;
- if (fctx->stripe_coalesce)
- dest_offset = coalesced_offset(dest_offset,
- local->stripe_size,
- fctx->stripe_count);
-
- STACK_WIND(fframe, stripe_zerofill_cbk, fctx->xl_array[idx],
- fctx->xl_array[idx]->fops->zerofill, fd,
- dest_offset, fill_size, xdata);
- offset_offset += fill_size;
- if (remaining_size == 0)
- break;
- }
-
- return 0;
-err:
- if (fframe)
- STRIPE_STACK_DESTROY(fframe);
+ if (!fctx->static_array)
+ FREE (fctx->xl_array);
- STRIPE_STACK_UNWIND (zerofill, frame, -1, op_errno, NULL, NULL, NULL);
- return 0;
-}
+ FREE (fctx);
-int32_t
-stripe_release (xlator_t *this, fd_t *fd)
-{
+ out:
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);
-
- (void) inode_ctx_del (inode, this, &tmp_fctx);
- if (!tmp_fctx) {
- goto err;
- }
-
- fctx = (stripe_fd_ctx_t *)(long)tmp_fctx;
-
- if (!fctx->static_array)
- GF_FREE (fctx->xl_array);
-
- GF_FREE (fctx);
-err:
- return 0;
-}
-
+/**
+ * notify
+ */
int32_t
notify (xlator_t *this, int32_t event, void *data, ...)
{
stripe_private_t *priv = NULL;
int down_client = 0;
int i = 0;
- gf_boolean_t heard_from_all_children = _gf_false;
-
- if (!this)
- return 0;
priv = this->private;
if (!priv)
@@ -4324,28 +3249,24 @@ notify (xlator_t *this, int32_t event, void *data, ...)
if (data == priv->xl_array[i])
break;
}
-
- if (priv->child_count == i) {
- gf_log (this->name, GF_LOG_ERROR,
- "got GF_EVENT_CHILD_UP bad subvolume %s",
- data? ((xlator_t *)data)->name: NULL);
- break;
+ priv->state[i] = 1;
+ for (i = 0; i < priv->child_count; i++) {
+ if (!priv->state[i])
+ down_client++;
}
LOCK (&priv->lock);
{
+ priv->nodes_down = down_client;
+
if (data == FIRST_CHILD (this))
priv->first_child_down = 0;
- priv->last_event[i] = event;
+ if (!priv->nodes_down)
+ default_notify (this, event, data);
}
UNLOCK (&priv->lock);
}
break;
- case GF_EVENT_CHILD_CONNECTING:
- {
- // 'CONNECTING' doesn't ensure its CHILD_UP, so do nothing
- goto out;
- }
case GF_EVENT_CHILD_DOWN:
{
/* get an index number to set */
@@ -4353,19 +3274,20 @@ notify (xlator_t *this, int32_t event, void *data, ...)
if (data == priv->xl_array[i])
break;
}
-
- if (priv->child_count == i) {
- gf_log (this->name, GF_LOG_ERROR,
- "got GF_EVENT_CHILD_DOWN bad subvolume %s",
- data? ((xlator_t *)data)->name: NULL);
- break;
+ priv->state[i] = 0;
+ for (i = 0; i < priv->child_count; i++) {
+ if (!priv->state[i])
+ down_client++;
}
LOCK (&priv->lock);
{
+ priv->nodes_down = down_client;
+
if (data == FIRST_CHILD (this))
priv->first_child_down = 1;
- priv->last_event[i] = event;
+ if (priv->nodes_down)
+ default_notify (this, event, data);
}
UNLOCK (&priv->lock);
}
@@ -4375,731 +3297,68 @@ notify (xlator_t *this, int32_t event, void *data, ...)
{
/* */
default_notify (this, event, data);
- goto out;
}
break;
}
- // Consider child as down if it's last_event is not CHILD_UP
- for (i = 0, down_client = 0; i < priv->child_count; i++)
- if (priv->last_event[i] != GF_EVENT_CHILD_UP)
- down_client++;
-
- LOCK (&priv->lock);
- {
- priv->nodes_down = down_client;
- }
- UNLOCK (&priv->lock);
-
- heard_from_all_children = _gf_true;
- for (i = 0; i < priv->child_count; i++)
- if (!priv->last_event[i])
- heard_from_all_children = _gf_false;
-
- if (heard_from_all_children)
- default_notify (this, event, data);
-out:
- return 0;
-}
-
-int
-stripe_setxattr_cbk (call_frame_t *frame, void *cookie,
- xlator_t *this, int op_ret, int op_errno, dict_t *xdata)
-{
- 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;
-
- /**
- * 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;
- }
- }
-
- unlock:
- UNLOCK (&frame->lock);
-
- if (!call_cnt) {
- STRIPE_STACK_UNWIND (setxattr, frame, local->op_ret,
- local->op_errno, xdata);
- }
-
- return 0;
-}
-
-#ifdef HAVE_BD_XLATOR
-int
-stripe_is_bd (dict_t *this, char *key, data_t *value, void *data)
-{
- gf_boolean_t *is_bd = data;
-
- if (data == NULL)
- return 0;
-
- if (XATTR_IS_BD (key))
- *is_bd = _gf_true;
-
return 0;
}
-static inline gf_boolean_t
-stripe_setxattr_is_bd (dict_t *dict)
-{
- gf_boolean_t is_bd = _gf_false;
-
- if (dict == NULL)
- goto out;
-
- dict_foreach (dict, stripe_is_bd, &is_bd);
-out:
- return is_bd;
-}
-#else
-#define stripe_setxattr_is_bd(dict) _gf_false
-#endif
-
int
-stripe_setxattr (call_frame_t *frame, xlator_t *this,
- loc_t *loc, dict_t *dict, int flags, dict_t *xdata)
+set_stripe_block_size (xlator_t *this, stripe_private_t *priv, char *data)
{
- int32_t op_errno = EINVAL;
- xlator_list_t *trav = NULL;
- stripe_private_t *priv = NULL;
- stripe_local_t *local = NULL;
- int i = 0;
- gf_boolean_t is_bd = _gf_false;
-
- 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,
- op_errno, err);
-
- priv = this->private;
- trav = this->children;
-
- local = mem_get0 (this->local_pool);
- if (!local) {
- op_errno = ENOMEM;
- goto err;
- }
-
- frame->local = local;
- local->wind_count = priv->child_count;
- local->op_ret = local->op_errno = 0;
-
- is_bd = stripe_setxattr_is_bd (dict);
-
- /**
- * Set xattrs for directories on all subvolumes. Additionally
- * this power is only given to a special client. Bd xlator
- * also needs xattrs for regular files (ie LVs)
- */
- if (((frame->root->pid == GF_CLIENT_PID_GSYNCD) &&
- IA_ISDIR (loc->inode->ia_type)) || is_bd) {
- 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);
- }
- } else {
- local->wind_count = 1;
- STACK_WIND (frame, stripe_setxattr_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->setxattr,
- loc, dict, flags, xdata);
- }
-
- 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_is_special_key (dict_t *this,
- char *key,
- data_t *value,
- void *data)
-{
- gf_boolean_t *is_special = NULL;
-
- if (data == NULL) {
- goto out;
- }
-
- is_special = data;
-
- if (XATTR_IS_LOCKINFO (key) || XATTR_IS_BD (key))
- *is_special = _gf_true;
-
-out:
- return 0;
-}
-
-int32_t
-stripe_fsetxattr_everyone_cbk (call_frame_t *frame, void *cookie,
- xlator_t *this, int32_t op_ret, int32_t op_errno,
- dict_t *xdata)
-{
- int call_count = 0;
- stripe_local_t *local = NULL;
-
- local = frame->local;
-
- LOCK (&frame->lock);
- {
- call_count = --local->wind_count;
-
- if (op_ret < 0) {
- local->op_ret = op_ret;
- local->op_errno = op_errno;
- }
- }
- UNLOCK (&frame->lock);
-
- if (call_count == 0) {
- STRIPE_STACK_UNWIND (fsetxattr, frame, local->op_ret,
- local->op_errno, NULL);
- }
- return 0;
-}
-
-int
-stripe_fsetxattr_to_everyone (call_frame_t *frame, xlator_t *this, fd_t *fd,
- dict_t *dict, int flags, dict_t *xdata)
-{
- xlator_list_t *trav = NULL;
- stripe_private_t *priv = NULL;
- int ret = -1;
- stripe_local_t *local = NULL;
-
- priv = this->private;
-
- local = mem_get0 (this->local_pool);
- if (local == NULL) {
- goto out;
- }
-
- frame->local = local;
-
- local->wind_count = priv->child_count;
-
- trav = this->children;
-
- while (trav) {
- STACK_WIND (frame, stripe_fsetxattr_everyone_cbk,
- trav->xlator, trav->xlator->fops->fsetxattr,
- fd, dict, flags, xdata);
- trav = trav->next;
- }
-
- ret = 0;
-out:
- return ret;
-}
-
-static inline gf_boolean_t
-stripe_fsetxattr_is_special (dict_t *dict)
-{
- gf_boolean_t is_spl = _gf_false;
-
- if (dict == NULL) {
- goto out;
- }
-
- dict_foreach (dict, stripe_is_special_key, &is_spl);
-
-out:
- return is_spl;
-}
-
-int
-stripe_fsetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
- dict_t *dict, int flags, dict_t *xdata)
-{
- int32_t op_ret = -1, ret = -1, op_errno = EINVAL;
- gf_boolean_t is_spl = _gf_false;
-
- VALIDATE_OR_GOTO (frame, err);
- VALIDATE_OR_GOTO (this, err);
- VALIDATE_OR_GOTO (fd, err);
-
- GF_IF_INTERNAL_XATTR_GOTO ("trusted.*stripe*", dict,
- op_errno, err);
-
- is_spl = stripe_fsetxattr_is_special (dict);
- if (is_spl) {
- ret = stripe_fsetxattr_to_everyone (frame, this, fd, dict,
- flags, xdata);
- if (ret < 0) {
- op_errno = ENOMEM;
- goto err;
- }
-
- goto out;
- }
-
- STACK_WIND (frame, stripe_fsetxattr_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fsetxattr,
- fd, dict, flags, xdata);
-out:
- 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;
-}
-
-int
-stripe_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.*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);
- 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_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;
-
- 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)
- 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;
- }
-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);
- }
- frame->local = NULL;
- stripe_local_wipe (local);
- mem_put (local);
- STRIPE_STACK_DESTROY (frame);
- }
-
- 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)
-{
- stripe_local_t *local = NULL;
- call_frame_t *prev = NULL;
- gf_dirent_t *local_entry = NULL;
- gf_dirent_t *tmp_entry = NULL;
- xlator_list_t *trav = NULL;
- loc_t loc = {0, };
- 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");
- goto out;
- }
- prev = cookie;
- local = frame->local;
- trav = this->children;
- priv = this->private;
-
- subvols = priv->child_count;
-
- LOCK (&frame->lock);
- {
- local->op_errno = op_errno;
- local->op_ret = op_ret;
-
- if (op_ret != -1) {
- list_splice_init (&orig_entries->list,
- &local->entries.list);
- local->wind_count = op_ret;
- }
-
- }
- UNLOCK (&frame->lock);
-
- if (op_ret == -1) {
- gf_log (this->name, GF_LOG_WARNING, "%s returned error %s",
- prev->this->name, strerror (op_errno));
- 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) {
-
- if (!local_entry)
- break;
- if (!IA_ISREG (local_entry->d_stat.ia_type) || !local_entry->inode) {
- LOCK (&frame->lock);
- {
- local->wind_count--;
- count = local->wind_count;
- }
- UNLOCK (&frame->lock);
- continue;
- }
-
- local_frame = copy_frame (frame);
-
- if (!local_frame) {
- op_errno = ENOMEM;
- op_ret = -1;
+ 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;
+
+ /* Get the pattern for striping.
+ "option block-size *avi:10MB" etc */
+ stripe_str = strtok_r (data, ",", &tmp_str);
+ while (stripe_str) {
+ dup_str = strdup (stripe_str);
+ stripe_opt = CALLOC (1, sizeof (struct stripe_options));
+ if (!stripe_opt) {
+ FREE (dup_str);
goto out;
}
- local_ent = mem_get0 (this->local_pool);
- if (!local_ent) {
- op_errno = ENOMEM;
- op_ret = -1;
- goto out;
+ pattern = strtok_r (dup_str, ":", &tmp_str1);
+ num = strtok_r (NULL, ":", &tmp_str1);
+ if (!num) {
+ num = pattern;
+ pattern = "*";
}
-
- 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;
-
- trav = this->children;
- while (trav) {
- STACK_WIND (local_frame, stripe_readdirp_lookup_cbk,
- trav->xlator, trav->xlator->fops->lookup,
- &loc, xattrs);
- trav = trav->next;
+ if (gf_string2bytesize (num, &stripe_opt->block_size) != 0) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "invalid number format \"%s\"", num);
+ goto out;
}
- loc_wipe (&loc);
- }
-out:
- if (!count) {
- /* all entries are directories */
- frame->local = NULL;
- STRIPE_STACK_UNWIND (readdir, frame,
- local ? local->op_ret : -1,
- local ? local->op_errno : EINVAL,
- local ? &local->entries : NULL,
- NULL);
- 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)
-{
- 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);
-
- priv = this->private;
- trav = this->children;
-
- if (priv->first_child_down) {
- op_errno = ENOTCONN;
- goto err;
- }
-
- /* Initialization */
- local = mem_get0 (this->local_pool);
- if (!local) {
- op_errno = ENOMEM;
- goto err;
- }
-
- frame->local = local;
-
- 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;
+ memcpy (stripe_opt->path_pattern, pattern, strlen (pattern));
- STACK_WIND (frame, stripe_readdirp_cbk, trav->xlator,
- trav->xlator->fops->readdirp, fd, size, off, xdata);
- return 0;
-err:
- op_errno = (op_errno == -1) ? errno : op_errno;
- STRIPE_STACK_UNWIND (readdir, frame, -1, op_errno, NULL, NULL);
-
- return 0;
-
-}
-
-int32_t
-mem_acct_init (xlator_t *this)
-{
- int ret = -1;
-
- if (!this)
- goto out;
-
- ret = xlator_mem_acct_init (this, gf_stripe_mt_end + 1);
-
- if (ret != 0) {
- gf_log (this->name, GF_LOG_ERROR, "Memory accounting init"
- "failed");
- goto out;
- }
-
-out:
- return ret;
-}
-
-static int
-clear_pattern_list (stripe_private_t *priv)
-{
- struct stripe_options *prev = NULL;
- struct stripe_options *trav = NULL;
- int ret = -1;
-
- GF_VALIDATE_OR_GOTO ("stripe", priv, out);
-
- trav = priv->pattern;
- priv->pattern = NULL;
- while (trav) {
- prev = trav;
- trav = trav->next;
- GF_FREE (prev);
- }
-
- ret = 0;
- 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;
-
-
- ret = 0;
- LOCK (&priv->lock);
- {
- ret = clear_pattern_list (priv);
- if (ret)
- goto unlock;
+ gf_log (this->name, GF_LOG_DEBUG,
+ "block-size : pattern %s : size %"PRId64,
+ stripe_opt->path_pattern, stripe_opt->block_size);
- data = dict_get (options, "block-size");
- if (data) {
- ret = set_stripe_block_size (this, priv, data->data);
- if (ret)
- goto unlock;
+ if (!priv->pattern) {
+ priv->pattern = stripe_opt;
} 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;
- }
-
- if (gf_string2bytesize_uint64 (opt->default_value, &priv->block_size)){
- gf_log (this->name, GF_LOG_ERROR,
- "Unable to set default block-size ");
- ret = -1;
- goto unlock;
- }
+ temp_stripeopt = priv->pattern;
+ while (temp_stripeopt->next)
+ temp_stripeopt = temp_stripeopt->next;
+ temp_stripeopt->next = stripe_opt;
}
-
- GF_OPTION_RECONF("coalesce", priv->coalesce, options, bool,
- unlock);
+ stripe_str = strtok_r (NULL, ",", &tmp_str);
}
- unlock:
- UNLOCK (&priv->lock);
- if (ret)
- goto out;
ret = 0;
out:
return ret;
-
}
/**
@@ -5111,15 +3370,11 @@ 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;
int ret = -1;
- if (!this)
- goto out;
-
trav = this->children;
while (trav) {
count++;
@@ -5144,20 +3399,15 @@ init (xlator_t *this)
" please check the volume. exiting");
goto out;
}
-
- priv = GF_CALLOC (1, sizeof (stripe_private_t),
- gf_stripe_mt_stripe_private_t);
-
+ priv = CALLOC (1, sizeof (stripe_private_t));
if (!priv)
goto out;
- priv->xl_array = GF_CALLOC (count, sizeof (xlator_t *),
- gf_stripe_mt_xlator_t);
+ priv->xl_array = CALLOC (count, sizeof (xlator_t *));
if (!priv->xl_array)
goto out;
- priv->last_event = GF_CALLOC (count, sizeof (int),
- gf_stripe_mt_int32_t);
- if (!priv->last_event)
+ priv->state = CALLOC (count, sizeof (int8_t));
+ if (!priv->state)
goto out;
priv->child_count = count;
@@ -5177,57 +3427,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_uint64 (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:
+ out:
if (ret) {
if (priv) {
- GF_FREE (priv->xl_array);
- GF_FREE (priv);
+ if (priv->xl_array)
+ FREE (priv->xl_array);
+ FREE (priv);
}
}
return ret;
@@ -5244,547 +3479,65 @@ fini (xlator_t *this)
struct stripe_options *prev = NULL;
struct stripe_options *trav = NULL;
- if (!this)
- goto out;
-
priv = this->private;
if (priv) {
- this->private = NULL;
- GF_FREE (priv->xl_array);
+ if (priv->xl_array)
+ FREE (priv->xl_array);
trav = priv->pattern;
while (trav) {
prev = trav;
trav = trav->next;
- GF_FREE (prev);
+ FREE (prev);
}
- GF_FREE (priv->last_event);
LOCK_DESTROY (&priv->lock);
- GF_FREE (priv);
+ FREE (priv);
}
-out:
return;
}
-int32_t
-stripe_getxattr_unwind (call_frame_t *frame,
- int op_ret, int op_errno, dict_t *dict, dict_t *xdata)
-
-{
- STRIPE_STACK_UNWIND (getxattr, frame, op_ret, op_errno, dict, xdata);
- 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 call_cnt = 0;
- stripe_local_t *local = NULL;
-
- VALIDATE_OR_GOTO (frame, out);
- VALIDATE_OR_GOTO (frame->local, out);
-
- local = frame->local;
-
- LOCK (&frame->lock);
- {
- call_cnt = --local->wind_count;
- }
- UNLOCK (&frame->lock);
-
- if (!xattr || (op_ret < 0))
- goto out;
-
- local->op_ret = 0;
-
- if (!local->xattr) {
- local->xattr = dict_ref (xattr);
- } else {
- stripe_aggregate_xattr (local->xattr, xattr);
- }
-
-out:
- if (!call_cnt) {
- STRIPE_STACK_UNWIND (getxattr, frame, local->op_ret, op_errno,
- local->xattr, xdata);
- }
-
- 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;
- void *xattr_val = NULL;
- void *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) {
- xattr = local->xattr_list + (int32_t) cky;
-
- ret = dict_get_ptr_and_len (dict, local->xsel,
- &xattr_val,
- &xattr->xattr_len);
- if (xattr->xattr_len == 0)
- goto out;
-
- xattr->pos = cky;
- xattr->xattr_value = gf_memdup (xattr_val,
- xattr->xattr_len);
-
- if (xattr->xattr_value != NULL)
- 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,
- (char **)&xattr_serz);
- else if (XATTR_IS_LOCKINFO (local->xsel)) {
- ret = stripe_fill_lockinfo_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_dynptr (stripe_xattr, local->xsel,
- xattr_serz,
- local->xattr_total_len);
- 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)
-{
- 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;
-
- VALIDATE_OR_GOTO (frame, err);
- VALIDATE_OR_GOTO (this, err);
- VALIDATE_OR_GOTO (loc, err);
- VALIDATE_OR_GOTO (loc->path, err);
- VALIDATE_OR_GOTO (loc->inode, err);
-
- priv = this->private;
- trav = this->children;
-
- /* Initialization */
- local = mem_get0 (this->local_pool);
- if (!local) {
- op_errno = ENOMEM;
- goto err;
- }
- local->op_ret = -1;
- frame->local = local;
- loc_copy (&local->loc, loc);
-
-
- if (name && (strcmp (GF_XATTR_MARKER_KEY, name) == 0)
- && (GF_CLIENT_PID_GSYNCD == 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 (cluster_getmarkerattr (frame, this, loc, name,
- local, stripe_getxattr_unwind,
- sub_volumes, priv->child_count,
- MARKER_UUID_TYPE, marker_uuid_default_gauge,
- priv->vol_uuid)) {
- op_errno = EINVAL;
- goto err;
- }
-
- return 0;
- }
-
- if (name && strncmp (name, GF_XATTR_QUOTA_SIZE_KEY,
- 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);
- }
-
- return 0;
- }
-
- if (name && (XATTR_IS_PATHINFO (name))) {
- 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 ((match_uuid_local (name, priv->vol_uuid) == 0)
- && (GF_CLIENT_PID_GSYNCD == frame->root->pid)) {
-
- 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 *));
-
- 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,
- sub_volumes,
- local->marker.call_count,
- MARKER_XTIME_TYPE,
- marker_xtime_default_gauge,
- 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);
-
- return 0;
-
-err:
- STRIPE_STACK_UNWIND (getxattr, frame, -1, op_errno, NULL, NULL);
- return 0;
-}
-
-static inline gf_boolean_t
-stripe_is_special_xattr (const char *name)
-{
- gf_boolean_t is_spl = _gf_false;
-
- if (!name) {
- goto out;
- }
-
- if (!strncmp (name, GF_XATTR_LOCKINFO_KEY,
- strlen (GF_XATTR_LOCKINFO_KEY))
- || XATTR_IS_PATHINFO (name))
- is_spl = _gf_true;
-out:
- return is_spl;
-}
-
-int32_t
-stripe_fgetxattr_from_everyone (call_frame_t *frame, xlator_t *this, fd_t *fd,
- const char *name, dict_t *xdata)
-{
- stripe_local_t *local = NULL;
- stripe_private_t *priv = NULL;
- int32_t ret = -1, op_errno = 0;
- int i = 0;
- xlator_list_t *trav = NULL;
-
- priv = this->private;
-
- local = mem_get0 (this->local_pool);
- if (!local) {
- op_errno = ENOMEM;
- goto err;
- }
-
- local->op_ret = -1;
- frame->local = local;
-
- strncpy (local->xsel, name, strlen (name));
- local->nallocs = local->wind_count = priv->child_count;
-
- 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->fgetxattr,
- fd, name, xdata);
- }
-
- return 0;
-
-err:
- STACK_UNWIND_STRICT (fgetxattr, frame, -1, op_errno, NULL, NULL);
- return ret;
-}
-
-int32_t
-stripe_fgetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
- const char *name, dict_t *xdata)
-{
- if (stripe_is_special_xattr (name)) {
- stripe_fgetxattr_from_everyone (frame, this, fd, name, xdata);
- goto out;
- }
-
- STACK_WIND (frame, stripe_internal_getxattr_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fgetxattr, fd, name, xdata);
-
-out:
- 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,
- .fgetxattr = stripe_fgetxattr,
- .removexattr = stripe_removexattr,
- .fremovexattr = stripe_fremovexattr,
- .readdirp = stripe_readdirp,
- .fallocate = stripe_fallocate,
- .discard = stripe_discard,
- .zerofill = stripe_zerofill,
+ .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,
+};
+
+struct xlator_mops mops = {
};
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 = "true",
- .description = "Enable/Disable 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 5673d18f390..8a92e43da9f 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) 2009 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 General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that 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/>.
*/
@@ -23,60 +32,9 @@
#include "common-utils.h"
#include "compat.h"
#include "compat-errno.h"
-#include "stripe-mem-types.h"
-#include "libxlator.h"
#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 (__local) { \
- stripe_local_wipe (__local); \
- mem_put (__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 {
- int pos;
- int xattr_len;
- char *xattr_value;
-} stripe_xattr_sort_t;
/**
* struct stripe_options : This keeps the pattern and the block-size
@@ -98,29 +56,26 @@ struct stripe_private {
gf_lock_t lock;
uint8_t nodes_down;
int8_t first_child_down;
- int *last_event;
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
int32_t op_errno;
int32_t requested_size;
- struct iatt stbuf; /* 'stbuf' is also a part of reply */
+ struct stat stbuf; /* 'stbuf' is also a part of reply */
};
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;
@@ -138,11 +93,11 @@ struct stripe_local {
stripe_fd_ctx_t *fctx;
/* Used by _cbk functions */
- struct iatt stbuf;
- struct iatt pre_buf;
- struct iatt post_buf;
- struct iatt preparent;
- struct iatt postparent;
+ struct stat stbuf;
+ struct stat pre_buf;
+ struct stat post_buf;
+ struct stat preparent;
+ struct stat postparent;
off_t stbuf_size;
off_t prebuf_size;
@@ -156,9 +111,10 @@ struct stripe_local {
blkcnt_t preparent_blocks;
blkcnt_t postparent_blocks;
- struct stripe_replies *replies;
- struct statvfs statvfs_buf;
- dir_entry_t *entry;
+ struct readv_replies *replies;
+ struct statvfs statvfs_buf;
+ dir_entry_t *entry;
+ struct xlator_stats stats;
int8_t revalidate;
int8_t failed;
@@ -180,17 +136,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];
-
- struct marker_str marker;
+ dict_t *dict;
/* General usage */
off_t offset;
@@ -200,89 +147,13 @@ struct stripe_local {
int entry_self_heal_needed;
int8_t *list;
- struct gf_flock lock;
+ struct flock lock;
fd_t *fd;
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);
-int32_t
-stripe_fill_lockinfo_xattr (xlator_t *this, stripe_local_t *local,
- void **xattr_serz);
-
-/*
- * 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/ec/Makefile.am b/xlators/cluster/unify/Makefile.am
index d471a3f9243..d471a3f9243 100644
--- a/xlators/cluster/ec/Makefile.am
+++ b/xlators/cluster/unify/Makefile.am
diff --git a/xlators/cluster/unify/src/Makefile.am b/xlators/cluster/unify/src/Makefile.am
new file mode 100644
index 00000000000..2a1fe837263
--- /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-self-heal.c b/xlators/cluster/unify/src/unify-self-heal.c
new file mode 100644
index 00000000000..3e4affe8c23
--- /dev/null
+++ b/xlators/cluster/unify/src/unify-self-heal.c
@@ -0,0 +1,1227 @@
+/*
+ Copyright (c) 2007-2009 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/>.
+*/
+
+/**
+ * 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) {
+ FREE (local->name);
+ }
+
+ if (local->sh_struct) {
+ if (local->sh_struct->offset_list)
+ FREE (local->sh_struct->offset_list);
+
+ if (local->sh_struct->entry_list)
+ FREE (local->sh_struct->entry_list);
+
+ if (local->sh_struct->count_list)
+ FREE (local->sh_struct->count_list);
+
+ 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;
+ FREE (trav->name);
+ if (S_ISLNK (trav->buf.st_mode))
+ FREE (trav->link);
+ FREE (trav);
+ trav = prev->next;
+ }
+ 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 = CALLOC (1, sizeof (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;
+ FREE (trav->name);
+ if (S_ISLNK (trav->buf.st_mode))
+ FREE (trav->link);
+ FREE (trav);
+ trav = prev->next;
+ }
+ 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 = CALLOC (1, sizeof (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 =
+ calloc (priv->child_count,
+ sizeof (off_t));
+ ERR_ABORT (local->sh_struct->offset_list);
+
+ local->sh_struct->entry_list =
+ calloc (priv->child_count,
+ sizeof (dir_entry_t *));
+ ERR_ABORT (local->sh_struct->entry_list);
+
+ local->sh_struct->count_list =
+ calloc (priv->child_count,
+ sizeof (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;
+ FREE (trav->name);
+ if (S_ISLNK (trav->buf.st_mode))
+ FREE (trav->link);
+ FREE (trav);
+ trav = prev->next;
+ }
+ 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 = CALLOC (1, sizeof (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;
+ FREE (trav->name);
+ if (S_ISLNK (trav->buf.st_mode))
+ FREE (trav->link);
+ FREE (trav);
+ trav = prev->next;
+ }
+ 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 = CALLOC (1, sizeof (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 =
+ calloc (priv->child_count,
+ sizeof (off_t));
+ ERR_ABORT (local->sh_struct->offset_list);
+
+ local->sh_struct->entry_list =
+ calloc (priv->child_count,
+ sizeof (dir_entry_t *));
+ ERR_ABORT (local->sh_struct->entry_list);
+
+ local->sh_struct->count_list =
+ calloc (priv->child_count,
+ sizeof (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 =
+ calloc (1, sizeof (struct 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 =
+ calloc (1, sizeof (struct 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 00000000000..6ce31da9dc6
--- /dev/null
+++ b/xlators/cluster/unify/src/unify.c
@@ -0,0 +1,4552 @@
+/*
+ Copyright (c) 2006-2009 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/>.
+*/
+
+/**
+ * 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 'st_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) {
+ 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 (!S_ISDIR (loc->inode->st_mode)) {
+ 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 stat *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->st_ino = buf->st_ino;
+ /* If the entry is directory, get the stat
+ from NS node */
+ if (S_ISDIR (buf->st_mode) ||
+ !local->stbuf.st_blksize) {
+ local->stbuf = *buf;
+ }
+ }
+
+ if ((!S_ISDIR (buf->st_mode)) &&
+ (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->st_ino)
+ local->op_ret = -1;
+
+ local->stbuf.st_ino = local->st_ino;
+ unify_local_wipe (local);
+ STACK_UNWIND (frame, local->op_ret, local->op_errno,
+ &local->stbuf);
+ }
+
+ return 0;
+}
+
+#define check_if_dht_linkfile(s) ((s->st_mode & ~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 stat *buf,
+ dict_t *dict,
+ struct stat *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.st_mode && local->stbuf.st_blksize) {
+ /* make sure we already have a stbuf
+ stored in local->stbuf */
+ if (S_ISDIR (local->stbuf.st_mode) &&
+ !S_ISDIR (buf->st_mode)) {
+ 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 (!S_ISDIR (local->stbuf.st_mode) &&
+ S_ISDIR (buf->st_mode)) {
+ 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 && !S_ISDIR (buf->st_mode)) {
+ /* This is the first time lookup on file*/
+ if (!local->list) {
+ /* list is not allocated, allocate
+ the max possible range */
+ local->list = CALLOC (1, 2 * (priv->child_count + 2));
+ 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 && S_ISDIR (buf->st_mode)) {
+ /* 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->st_ino = buf->st_ino;
+ if (S_ISDIR (buf->st_mode) ||
+ !(local->stbuf.st_blksize)) {
+ local->stbuf = *buf;
+ local->oldpostparent = *postparent;
+ }
+ } else if (!S_ISDIR (buf->st_mode)) {
+ /* If file, then get the stat from
+ storage node */
+ local->stbuf = *buf;
+ }
+
+ if (local->st_nlink < buf->st_nlink) {
+ local->st_nlink = buf->st_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.st_blksize) {
+ /* Inode not present */
+ local->op_ret = -1;
+ } else {
+ if (!local->revalidate &&
+ !S_ISDIR (local->stbuf.st_mode)) {
+ /* If its a file, big array is useless,
+ allocate the smaller one */
+ int16_t *list = NULL;
+ list = CALLOC (1, 2 * (local->index + 1));
+ ERR_ABORT (list);
+ memcpy (list, local->list, 2 * local->index);
+ /* Make the end of the list as -1 */
+ 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 (S_ISDIR(local->loc1.inode->st_mode)) {
+ /* 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.st_ino = local->st_ino;
+ }
+
+ local->stbuf.st_nlink = local->st_nlink;
+ }
+ if (local->op_ret == -1) {
+ if (!local->revalidate && local->list)
+ 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) &&
+ S_ISDIR(local->stbuf.st_mode))) {
+ /* 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)
+ && S_ISDIR (loc->inode->st_mode)) {
+ local->revalidate = 1;
+ }
+
+ if (!inode_ctx_get (loc->inode, this, NULL) &&
+ loc->inode->st_mode &&
+ !S_ISDIR (loc->inode->st_mode)) {
+ 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->st_mode) {
+ 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->st_ino = loc->inode->ino;
+ if (S_ISDIR (loc->inode->st_mode)) {
+ /* 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 stat *buf,
+ struct stat *preparent,
+ struct stat *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 stat *buf,
+ struct stat *preparent,
+ struct stat *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 stat *preparent,
+ struct stat *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 stat *preparent,
+ struct stat *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 stat *buf,
+ dict_t *dict)
+{
+ 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 (S_ISDIR (buf->st_mode))
+ 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)
+{
+ 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 = strdup (path);
+ ERR_ABORT (local->name);
+ } else {
+ char *tmp_str = strdup (local->loc1.path);
+ char *tmp_base = dirname (tmp_str);
+ local->name = CALLOC (1, ZR_PATH_MAX);
+ strcpy (local->name, tmp_base);
+ strncat (local->name, "/", 1);
+ strcat (local->name, path);
+ FREE (tmp_str);
+ }
+
+ local->list = CALLOC (1, sizeof (int16_t) * 3);
+ 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 (S_ISLNK (loc->inode->st_mode)) {
+ /* 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 stat *preparent,
+ struct stat *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 stat *buf,
+ dict_t *dict,
+ struct stat *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->st_ino = buf->st_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.st_ino = local->st_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 stat *buf,
+ struct stat *preparent,
+ struct stat *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.st_ino = local->st_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 stat *buf,
+ struct stat *preparent,
+ struct stat *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->st_ino = buf->st_ino;
+
+ local->oldpreparent = *preparent;
+ local->oldpostparent = *postparent;
+
+ local->op_ret = -1;
+
+ /* Start the mapping list */
+ list = CALLOC (1, sizeof (int16_t) * 3);
+ 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 = CALLOC (1, sizeof (int16_t) * 3);
+ 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 stat *statpre,
+ struct stat *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->st_ino = statpost->st_ino;
+ /* If the entry is directory, get the stat
+ from NS node */
+ if (S_ISDIR (statpost->st_mode) ||
+ !local->stpost.st_blksize) {
+ local->stpre = *statpre;
+ local->stpost = *statpost;
+ }
+ }
+
+ if ((!S_ISDIR (statpost->st_mode)) &&
+ (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->st_ino)
+ local->op_ret = -1;
+
+ local->stpre.st_ino = local->st_ino;
+ local->stpost.st_ino = local->st_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 stat *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 (S_ISDIR (loc->inode->st_mode)) {
+ 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 stat *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 stat *prebuf,
+ struct stat *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->st_ino = postbuf->st_ino;
+ /* If the entry is directory, get the
+ stat from NS node */
+ if (S_ISDIR (postbuf->st_mode) ||
+ !local->stbuf.st_blksize) {
+ local->stbuf = *prebuf;
+ local->poststbuf = *postbuf;
+ }
+ }
+
+ if ((!S_ISDIR (postbuf->st_mode)) &&
+ (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->st_ino) {
+ local->stbuf.st_ino = local->st_ino;
+ local->poststbuf.st_ino = local->st_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->st_ino = loc->inode->ino;
+
+ if (S_ISDIR (loc->inode->st_mode)) {
+ 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 stat *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 stat *preparent,
+ struct stat *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 stat *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 stat *prebuf,
+ struct stat *postbuf)
+{
+ unify_local_t *local = NULL;
+
+ local = frame->local;
+
+ local->stbuf = *prebuf;
+ local->stbuf.st_ino = local->st_ino;
+
+ local->poststbuf = *postbuf;
+ local->poststbuf.st_ino = local->st_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->st_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 stat *prebuf,
+ struct stat *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->st_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 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 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 (S_ISDIR (loc->inode->st_mode)) {
+
+ 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 = 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 (S_ISDIR (loc->inode->st_mode)) {
+ 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 (S_ISDIR (loc->inode->st_mode)) {
+ 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 stat *preparent,
+ struct stat *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 stat *buf,
+ struct stat *preparent,
+ struct stat *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.st_ino = local->st_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 stat *buf,
+ struct stat *preparent,
+ struct stat *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->st_ino = buf->st_ino;
+
+ local->oldpreparent = *preparent;
+ local->oldpostparent = *postparent;
+
+ list = CALLOC (1, sizeof (int16_t) * 3);
+ 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 stat *preparent,
+ struct stat *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 stat *buf,
+ struct stat *preparent,
+ struct stat *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.st_ino = local->st_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 stat *buf,
+ struct stat *preparent,
+ struct stat *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->st_ino = buf->st_ino;
+
+ local->oldpreparent = *preparent;
+ local->oldpostparent = *postparent;
+
+ /* Start the mapping list */
+
+ list = CALLOC (1, sizeof (int16_t) * 3);
+ 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 = 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 stat *preparent,
+ struct stat *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.st_ino = local->st_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 stat *buf,
+ struct stat *preoldparent,
+ struct stat *postoldparent,
+ struct stat *prenewparent,
+ struct stat *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.st_ino = local->st_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 stat *buf,
+ struct stat *preoldparent,
+ struct stat *postoldparent,
+ struct stat *prenewparent,
+ struct stat *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 (!S_ISDIR (buf->st_mode))
+ 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.st_ino = local->st_ino;
+ if (S_ISDIR (local->loc1.inode->st_mode)) {
+ 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 = CALLOC (1, index * 2);
+ 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;
+ }
+ }
+
+ FREE (tmp_list);
+ return 0;
+ }
+ if (tmp_list)
+ 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 stat *buf,
+ struct stat *preoldparent,
+ struct stat *postoldparent,
+ struct stat *prenewparent,
+ struct stat *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->st_ino = buf->st_ino;
+
+ local->oldpreparent = *preoldparent;
+ local->oldpostparent = *postoldparent;
+ local->newpreparent = *prenewparent;
+ local->newpostparent = *postnewparent;
+
+ /* Everything is fine. */
+ if (S_ISDIR (buf->st_mode)) {
+ 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 stat *buf,
+ struct stat *preparent,
+ struct stat *postparent)
+{
+ unify_local_t *local = frame->local;
+
+ if (op_ret >= 0)
+ local->stbuf = *buf;
+ local->stbuf.st_ino = local->st_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 stat *buf,
+ struct stat *preparent,
+ struct stat *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->st_ino = buf->st_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 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 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->st_mode && (!S_ISDIR(inode->st_mode))) {
+ inode_ctx_get (inode, this, &tmp_list);
+ if (tmp_list) {
+ list = (int16_t *)(long)tmp_list;
+ 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;
+}
+
+/**
+ * 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 = CALLOC (1, sizeof (*_private));
+ 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");
+ 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");
+ 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 = CALLOC (1,
+ sizeof (xlator_t) * (count + 1));
+ 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;
+ {
+ /* 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");
+ FREE (_private);
+ return -1;
+ }
+
+ ret = 0;
+
+ /* This section is required because some fops may look
+ * for 'xl->parent' variable
+ */
+ xlparent = CALLOC (1, sizeof (*xlparent));
+ 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);
+ FREE (priv->xl_array);
+ 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_mops mops = {
+};
+
+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 00000000000..b81946697f8
--- /dev/null
+++ b/xlators/cluster/unify/src/unify.h
@@ -0,0 +1,145 @@
+/*
+ Copyright (c) 2006-2009 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
+
+#ifndef _UNIFY_H
+#define _UNIFY_H
+
+#include "scheduler.h"
+#include "list.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 = CALLOC (1, sizeof (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 stat stbuf;
+ struct stat stpre;
+ struct stat stpost;
+ struct statvfs statvfs_buf;
+ struct timespec tv[2];
+ char *name;
+ int32_t revalidate;
+
+ ino_t st_ino;
+ nlink_t st_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 stat poststbuf;
+ /* When not used for rename, old*
+ * are used as the attrs for the current
+ * parent directory.
+ */
+ struct stat oldpreparent;
+ struct stat oldpostparent;
+ struct stat newpreparent;
+ struct stat 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 5075c59a861..f353b61e69c 100644
--- a/xlators/debug/error-gen/src/Makefile.am
+++ b/xlators/debug/error-gen/src/Makefile.am
@@ -2,16 +2,15 @@
xlator_LTLIBRARIES = error-gen.la
xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/debug
-error_gen_la_LDFLAGS = -module -avoid-version
+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_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src
-
-AM_CFLAGS = -Wall $(GF_CFLAGS)
+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/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 f02280535df..00000000000
--- a/xlators/debug/error-gen/src/error-gen-mem-types.h
+++ /dev/null
@@ -1,20 +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 __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 ec0874b354a..e6a5967cceb 100644
--- a/xlators/debug/error-gen/src/error-gen.c
+++ b/xlators/debug/error-gen/src/error-gen.c
@@ -1,12 +1,22 @@
/*
- 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-2009 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"
@@ -14,165 +24,166 @@
#include "xlator.h"
#include "error-gen.h"
-#include "statedump.h"
sys_error_t error_no_list[] = {
- [GF_FOP_LOOKUP] = { .error_no_count = 4,
+ [ERR_LOOKUP] = { .error_no_count = 4,
.error_no = {ENOENT,ENOTDIR,
ENAMETOOLONG,EAGAIN}},
- [GF_FOP_STAT] = { .error_no_count = 7,
+ [ERR_STAT] = { .error_no_count = 7,
.error_no = {EACCES,EBADF,EFAULT,
ENAMETOOLONG,ENOENT,
ENOMEM,ENOTDIR}},
- [GF_FOP_READLINK] = { .error_no_count = 8,
+ [ERR_READLINK] = { .error_no_count = 8,
.error_no = {EACCES,EFAULT,EINVAL,EIO,
ENAMETOOLONG,ENOENT,ENOMEM,
ENOTDIR}},
- [GF_FOP_MKNOD] = { .error_no_count = 11,
+ [ERR_MKNOD] = { .error_no_count = 11,
.error_no = {EACCES,EEXIST,EFAULT,
EINVAL,ENAMETOOLONG,
ENOENT,ENOMEM,ENOSPC,
ENOTDIR,EPERM,EROFS}},
- [GF_FOP_MKDIR] = { .error_no_count = 10,
+ [ERR_MKDIR] = { .error_no_count = 10,
.error_no = {EACCES,EEXIST,EFAULT,
ENAMETOOLONG,ENOENT,
ENOMEM,ENOSPC,ENOTDIR,
EPERM,EROFS}},
- [GF_FOP_UNLINK] = { .error_no_count = 10,
+ [ERR_UNLINK] = { .error_no_count = 10,
.error_no = {EACCES,EBUSY,EFAULT,EIO,
EISDIR,ENAMETOOLONG,
ENOENT,ENOMEM,ENOTDIR,
EPERM,EROFS}},
- [GF_FOP_RMDIR] = { .error_no_count = 8,
+ [ERR_RMDIR] = { .error_no_count = 8,
.error_no = {EACCES,EBUSY,EFAULT,
ENOMEM,ENOTDIR,ENOTEMPTY,
EPERM,EROFS}},
- [GF_FOP_SYMLINK] = { .error_no_count = 11,
+ [ERR_SYMLINK] = { .error_no_count = 11,
.error_no = {EACCES,EEXIST,EFAULT,EIO,
ENAMETOOLONG,ENOENT,ENOMEM,
ENOSPC,ENOTDIR,EPERM,
EROFS}},
- [GF_FOP_RENAME] = { .error_no_count = 13,
+ [ERR_RENAME] = { .error_no_count = 13,
.error_no = {EACCES,EBUSY,EFAULT,
EINVAL,EISDIR,EMLINK,
ENAMETOOLONG,ENOENT,ENOMEM,
ENOSPC,ENOTDIR,EEXIST,
EXDEV}},
- [GF_FOP_LINK] = { .error_no_count = 13,
+ [ERR_LINK] = { .error_no_count = 13,
.error_no = {EACCES,EFAULT,EEXIST,EIO,
EMLINK,ENAMETOOLONG,
ENOENT,ENOMEM,ENOSPC,
ENOTDIR,EPERM,EROFS,
EXDEV}},
- [GF_FOP_TRUNCATE] = { .error_no_count = 10,
+ [ERR_TRUNCATE] = { .error_no_count = 10,
.error_no = {EACCES,EFAULT,EFBIG,
EINTR,EINVAL,EIO,EISDIR,
ENAMETOOLONG,ENOENT,
EISDIR}},
- [GF_FOP_CREATE] = {.error_no_count = 10,
+ [ERR_CREATE] = {.error_no_count = 10,
.error_no = {EACCES,EEXIST,EFAULT,
EISDIR,EMFILE,ENAMETOOLONG,
ENFILE,ENODEV,ENOENT,
ENODEV}},
- [GF_FOP_OPEN] = { .error_no_count = 10,
+ [ERR_OPEN] = { .error_no_count = 10,
.error_no = {EACCES,EEXIST,EFAULT,
EISDIR,EMFILE,
ENAMETOOLONG,ENFILE,
ENODEV,ENOENT,ENOMEM}},
- [GF_FOP_READ] = { .error_no_count = 5,
+ [ERR_READV] = { .error_no_count = 5,
.error_no = {EINVAL,EBADF,EFAULT,EISDIR,
ENAMETOOLONG}},
- [GF_FOP_WRITE] = { .error_no_count = 7,
+ [ERR_WRITEV] = { .error_no_count = 5,
.error_no = {EINVAL,EBADF,EFAULT,EISDIR,
- ENAMETOOLONG,ENOSPC,
- GF_ERROR_SHORT_WRITE}},
- [GF_FOP_STATFS] = {.error_no_count = 10,
+ ENAMETOOLONG}},
+ [ERR_STATFS] = {.error_no_count = 10,
.error_no = {EACCES,EBADF,EFAULT,EINTR,
EIO,ENAMETOOLONG,ENOENT,
ENOMEM,ENOSYS,ENOTDIR}},
- [GF_FOP_FLUSH] = { .error_no_count = 5,
+ [ERR_FLUSH] = { .error_no_count = 5,
.error_no = {EACCES,EFAULT,
ENAMETOOLONG,ENOSYS,
ENOENT}},
- [GF_FOP_FSYNC] = { .error_no_count = 4,
+ [ERR_FSYNC] = { .error_no_count = 4,
.error_no = {EBADF,EIO,EROFS,EINVAL}},
- [GF_FOP_SETXATTR] = { .error_no_count = 4,
+ [ERR_SETXATTR] = { .error_no_count = 4,
.error_no = {EACCES,EBADF,EINTR,
ENAMETOOLONG}},
- [GF_FOP_GETXATTR] = { .error_no_count = 4,
+ [ERR_GETXATTR] = { .error_no_count = 4,
.error_no = {EACCES,EBADF,ENAMETOOLONG,
EINTR}},
- [GF_FOP_REMOVEXATTR] = { .error_no_count = 4,
+ [ERR_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,
+ [ERR_OPENDIR] = { .error_no_count = 8,
.error_no = {EACCES,EEXIST,EFAULT,
EISDIR,EMFILE,
ENAMETOOLONG,ENFILE,
ENODEV}},
- [GF_FOP_READDIR] = { .error_no_count = 5,
+ [ERR_READDIR] = { .error_no_count = 5,
.error_no = {EINVAL,EACCES,EBADF,
EMFILE,ENOENT}},
- [GF_FOP_READDIRP] = { .error_no_count = 5,
+ [ERR_READDIRP] = { .error_no_count = 5,
.error_no = {EINVAL,EACCES,EBADF,
EMFILE,ENOENT}},
- [GF_FOP_FSYNCDIR] = { .error_no_count = 4,
+ [ERR_GETDENTS] = { .error_no_count = 5,
+ .error_no = {EBADF,EFAULT,EINVAL,
+ ENOENT,ENOTDIR}},
+ [ERR_FSYNCDIR] = { .error_no_count = 4,
.error_no = {EBADF,EIO,EROFS,EINVAL}},
- [GF_FOP_ACCESS] = { .error_no_count = 8,
+ [ERR_ACCESS] = { .error_no_count = 8,
.error_no = {EACCES,ENAMETOOLONG,
ENOENT,ENOTDIR,EROFS,
EFAULT,EINVAL,EIO}},
- [GF_FOP_FTRUNCATE] = { .error_no_count = 9,
+ [ERR_FTRUNCATE] = { .error_no_count = 9,
.error_no = {EACCES,EFAULT,EFBIG,
EINTR,EINVAL,EIO,EISDIR,
ENAMETOOLONG,ENOENT}},
- [GF_FOP_FSTAT] = { .error_no_count = 7,
+ [ERR_FSTAT] = { .error_no_count = 7,
.error_no = {EACCES,EBADF,EFAULT,
ENAMETOOLONG,ENOENT,
ENOMEM,ENOTDIR}},
- [GF_FOP_LK] = { .error_no_count = 4,
+ [ERR_LK] = { .error_no_count = 4,
.error_no = {EACCES,EFAULT,ENOENT,
EINTR}},
- [GF_FOP_XATTROP] = { .error_no_count = 5,
+ [ERR_SETDENTS] = { .error_no_count = 4,
+ .error_no = {EACCES,EBADF,EINTR,
+ ENAMETOOLONG}},
+ [ERR_CHECKSUM] = { .error_no_count = 4,
+ .error_no = {EACCES,EBADF,
+ ENAMETOOLONG,EINTR}},
+ [ERR_XATTROP] = { .error_no_count = 5,
.error_no = {EACCES,EFAULT,
ENAMETOOLONG,ENOSYS,
ENOENT}},
- [GF_FOP_FXATTROP] = { .error_no_count = 4,
+ [ERR_FXATTROP] = { .error_no_count = 4,
.error_no = {EBADF,EIO,EROFS,EINVAL}},
- [GF_FOP_INODELK] = { .error_no_count = 4,
+ [ERR_INODELK] = { .error_no_count = 4,
.error_no = {EACCES,EBADF,EINTR,
ENAMETOOLONG}},
- [GF_FOP_FINODELK] = { .error_no_count = 4,
+ [ERR_FINODELK] = { .error_no_count = 4,
.error_no = {EACCES,EBADF,EINTR,
ENAMETOOLONG}},
- [GF_FOP_ENTRYLK] = { .error_no_count = 4,
+ [ERR_ENTRYLK] = { .error_no_count = 4,
.error_no = {EACCES,EBADF,
ENAMETOOLONG,EINTR}},
- [GF_FOP_FENTRYLK] = { .error_no_count = 10,
+ [ERR_FENTRYLK] = { .error_no_count = 10,
.error_no = {EACCES,EEXIST,EFAULT,
EISDIR,EMFILE,
ENAMETOOLONG,ENFILE,
ENODEV,ENOENT,ENOMEM}},
- [GF_FOP_SETATTR] = {.error_no_count = 11,
+ [ERR_SETATTR] = {.error_no_count = 11,
.error_no = {EACCES,EFAULT,EIO,
ENAMETOOLONG,ENOENT,
ENOMEM,ENOTDIR,EPERM,
EROFS,EBADF,EIO}},
- [GF_FOP_FSETATTR] = { .error_no_count = 11,
+ [ERR_FSETATTR] = { .error_no_count = 11,
.error_no = {EACCES,EFAULT,EIO,
ENAMETOOLONG,ENOENT,
ENOMEM,ENOTDIR,EPERM,
EROFS,EBADF,EIO}},
- [GF_FOP_GETSPEC] = { .error_no_count = 4,
+ [ERR_STATS] = { .error_no_count = 4,
+ .error_no = {EACCES,EBADF,ENAMETOOLONG,
+ EINTR}},
+ [ERR_GETSPEC] = { .error_no_count = 4,
.error_no = {EACCES,EBADF,ENAMETOOLONG,
EINTR}}
};
@@ -182,7 +193,7 @@ generate_rand_no (int op_no)
{
int rand_no = 0;
- if (op_no < GF_FOP_MAXVALUE)
+ if (op_no < NO_OF_FOPS)
rand_no = rand () % error_no_list[op_no].error_no_count;
return rand_no;
}
@@ -238,8 +249,6 @@ conv_errno_to_int (char **error_no)
return EINTR;
else if (!strcmp ((*error_no), "EFBIG"))
return EFBIG;
- else if (!strcmp((*error_no), "GF_ERROR_SHORT_WRITE"))
- return GF_ERROR_SHORT_WRITE;
else
return EAGAIN;
}
@@ -248,87 +257,89 @@ int
get_fop_int (char **op_no_str)
{
if (!strcmp ((*op_no_str), "lookup"))
- return GF_FOP_LOOKUP;
+ return ERR_LOOKUP;
else if (!strcmp ((*op_no_str), "stat"))
- return GF_FOP_STAT;
+ return ERR_STAT;
else if (!strcmp ((*op_no_str), "readlink"))
- return GF_FOP_READLINK;
+ return ERR_READLINK;
else if (!strcmp ((*op_no_str), "mknod"))
- return GF_FOP_MKNOD;
+ return ERR_MKNOD;
else if (!strcmp ((*op_no_str), "mkdir"))
- return GF_FOP_MKDIR;
+ return ERR_MKDIR;
else if (!strcmp ((*op_no_str), "unlink"))
- return GF_FOP_UNLINK;
+ return ERR_UNLINK;
else if (!strcmp ((*op_no_str), "rmdir"))
- return GF_FOP_RMDIR;
+ return ERR_RMDIR;
else if (!strcmp ((*op_no_str), "symlink"))
- return GF_FOP_SYMLINK;
+ return ERR_SYMLINK;
else if (!strcmp ((*op_no_str), "rename"))
- return GF_FOP_RENAME;
+ return ERR_RENAME;
else if (!strcmp ((*op_no_str), "link"))
- return GF_FOP_LINK;
+ return ERR_LINK;
else if (!strcmp ((*op_no_str), "truncate"))
- return GF_FOP_TRUNCATE;
+ return ERR_TRUNCATE;
else if (!strcmp ((*op_no_str), "create"))
- return GF_FOP_CREATE;
+ return ERR_CREATE;
else if (!strcmp ((*op_no_str), "open"))
- return GF_FOP_OPEN;
+ return ERR_OPEN;
else if (!strcmp ((*op_no_str), "readv"))
- return GF_FOP_READ;
+ return ERR_READV;
else if (!strcmp ((*op_no_str), "writev"))
- return GF_FOP_WRITE;
+ return ERR_WRITEV;
else if (!strcmp ((*op_no_str), "statfs"))
- return GF_FOP_STATFS;
+ return ERR_STATFS;
else if (!strcmp ((*op_no_str), "flush"))
- return GF_FOP_FLUSH;
+ return ERR_FLUSH;
else if (!strcmp ((*op_no_str), "fsync"))
- return GF_FOP_FSYNC;
+ return ERR_FSYNC;
else if (!strcmp ((*op_no_str), "setxattr"))
- return GF_FOP_SETXATTR;
+ return ERR_SETXATTR;
else if (!strcmp ((*op_no_str), "getxattr"))
- return GF_FOP_GETXATTR;
+ return ERR_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;
+ return ERR_REMOVEXATTR;
else if (!strcmp ((*op_no_str), "opendir"))
- return GF_FOP_OPENDIR;
+ return ERR_OPENDIR;
else if (!strcmp ((*op_no_str), "readdir"))
- return GF_FOP_READDIR;
+ return ERR_READDIR;
else if (!strcmp ((*op_no_str), "readdirp"))
- return GF_FOP_READDIRP;
+ return ERR_READDIRP;
+ else if (!strcmp ((*op_no_str), "getdents"))
+ return ERR_GETDENTS;
else if (!strcmp ((*op_no_str), "fsyncdir"))
- return GF_FOP_FSYNCDIR;
+ return ERR_FSYNCDIR;
else if (!strcmp ((*op_no_str), "access"))
- return GF_FOP_ACCESS;
+ return ERR_ACCESS;
else if (!strcmp ((*op_no_str), "ftruncate"))
- return GF_FOP_FTRUNCATE;
+ return ERR_FTRUNCATE;
else if (!strcmp ((*op_no_str), "fstat"))
- return GF_FOP_FSTAT;
+ return ERR_FSTAT;
else if (!strcmp ((*op_no_str), "lk"))
- return GF_FOP_LK;
+ return ERR_LK;
+ else if (!strcmp ((*op_no_str), "setdents"))
+ return ERR_SETDENTS;
+ else if (!strcmp ((*op_no_str), "checksum"))
+ return ERR_CHECKSUM;
else if (!strcmp ((*op_no_str), "xattrop"))
- return GF_FOP_XATTROP;
+ return ERR_XATTROP;
else if (!strcmp ((*op_no_str), "fxattrop"))
- return GF_FOP_FXATTROP;
+ return ERR_FXATTROP;
else if (!strcmp ((*op_no_str), "inodelk"))
- return GF_FOP_INODELK;
+ return ERR_INODELK;
else if (!strcmp ((*op_no_str), "finodelk"))
- return GF_FOP_FINODELK;
+ return ERR_FINODELK;
else if (!strcmp ((*op_no_str), "etrylk"))
- return GF_FOP_ENTRYLK;
+ return ERR_ENTRYLK;
else if (!strcmp ((*op_no_str), "fentrylk"))
- return GF_FOP_FENTRYLK;
+ return ERR_FENTRYLK;
else if (!strcmp ((*op_no_str), "setattr"))
- return GF_FOP_SETATTR;
+ return ERR_SETATTR;
else if (!strcmp ((*op_no_str), "fsetattr"))
- return GF_FOP_FSETATTR;
+ return ERR_FSETATTR;
+ else if (!strcmp ((*op_no_str), "stats"))
+ return ERR_STATS;
else if (!strcmp ((*op_no_str), "getspec"))
- return GF_FOP_GETSPEC;
+ return ERR_GETSPEC;
else
return -1;
}
@@ -365,14 +376,12 @@ error_gen (xlator_t *this, int op_no)
else {
rand_no = generate_rand_no (op_no);
- if (op_no >= GF_FOP_MAXVALUE)
+ if (op_no >= NO_OF_FOPS)
op_no = 0;
if (rand_no >= error_no_list[op_no].error_no_count)
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);
}
return ret;
}
@@ -381,663 +390,667 @@ 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 stat *buf, dict_t *dict, struct stat *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;
int enable = 1;
egp = this->private;
- enable = egp->enable[GF_FOP_LOOKUP];
+ enable = egp->enable[ERR_LOOKUP];
if (enable)
- op_errno = error_gen (this, GF_FOP_LOOKUP);
+ op_errno = error_gen (this, ERR_LOOKUP);
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;
+ STACK_UNWIND (frame, -1, op_errno, NULL, NULL, NULL,
+ 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 stat *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;
int enable = 1;
egp = this->private;
- enable = egp->enable[GF_FOP_STAT];
+ enable = egp->enable[ERR_STAT];
if (enable)
- op_errno = error_gen (this, GF_FOP_STAT);
+ op_errno = error_gen (this, ERR_STAT);
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 (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 stat *preop, struct stat *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 stat *stbuf, int32_t valid)
{
int op_errno = 0;
eg_t *egp = NULL;
int enable = 1;
egp = this->private;
- enable = egp->enable[GF_FOP_SETATTR];
+ enable = egp->enable[ERR_SETATTR];
if (enable)
- op_errno = error_gen (this, GF_FOP_SETATTR);
+ op_errno = error_gen (this, ERR_SETATTR);
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 stat *stbuf, int32_t valid)
{
int op_errno = 0;
eg_t *egp = NULL;
int enable = 1;
egp = this->private;
- enable = egp->enable[GF_FOP_FSETATTR];
+ enable = egp->enable[ERR_FSETATTR];
if (enable)
- op_errno = error_gen (this, GF_FOP_FSETATTR);
+ op_errno = error_gen (this, ERR_FSETATTR);
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 stat *prebuf, struct stat *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;
int enable = 1;
egp = this->private;
- enable = egp->enable[GF_FOP_TRUNCATE];
+ enable = egp->enable[ERR_TRUNCATE];
if (enable)
- op_errno = error_gen (this, GF_FOP_TRUNCATE);
+ op_errno = error_gen (this, ERR_TRUNCATE);
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)
+ int32_t op_ret, int32_t op_errno, struct stat *prebuf,
+ struct stat *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;
int enable = 1;
egp = this->private;
- enable = egp->enable[GF_FOP_FTRUNCATE];
+ enable = egp->enable[ERR_FTRUNCATE];
if (enable)
- op_errno = error_gen (this, GF_FOP_FTRUNCATE);
+ op_errno = error_gen (this, ERR_FTRUNCATE);
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;
int enable = 1;
egp = this->private;
- enable = egp->enable[GF_FOP_ACCESS];
+ enable = egp->enable[ERR_ACCESS];
if (enable)
- op_errno = error_gen (this, GF_FOP_ACCESS);
+ op_errno = error_gen (this, ERR_ACCESS);
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 stat *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;
int enable = 1;
egp = this->private;
- enable = egp->enable[GF_FOP_READLINK];
+ enable = egp->enable[ERR_READLINK];
if (enable)
- op_errno = error_gen (this, GF_FOP_READLINK);
+ op_errno = error_gen (this, ERR_READLINK);
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;
}
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 stat *buf, struct stat *preparent,
+ struct stat *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)
{
int op_errno = 0;
eg_t *egp = NULL;
int enable = 1;
egp = this->private;
- enable = egp->enable[GF_FOP_MKNOD];
+ enable = egp->enable[ERR_MKNOD];
if (enable)
- op_errno = error_gen (this, GF_FOP_MKNOD);
+ op_errno = error_gen (this, ERR_MKNOD);
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);
+ return 0;
}
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 stat *buf, struct stat *preparent,
+ struct stat *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)
{
int op_errno = 0;
eg_t *egp = NULL;
int enable = 1;
egp = this->private;
- enable = egp->enable[GF_FOP_MKDIR];
+ enable = egp->enable[ERR_MKDIR];
if (enable)
- op_errno = error_gen (this, GF_FOP_MKDIR);
+ op_errno = error_gen (this, ERR_MKDIR);
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);
+ 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 stat *preparent, struct stat *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;
int enable = 1;
egp = this->private;
- enable = egp->enable[GF_FOP_UNLINK];
+ enable = egp->enable[ERR_UNLINK];
if (enable)
- op_errno = error_gen (this, GF_FOP_UNLINK);
+ op_errno = error_gen (this, ERR_UNLINK);
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 stat *preparent, struct stat *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 op_errno = 0;
eg_t *egp = NULL;
int enable = 1;
egp = this->private;
- enable = egp->enable[GF_FOP_RMDIR];
+ enable = egp->enable[ERR_RMDIR];
if (enable)
- op_errno = error_gen (this, GF_FOP_RMDIR);
+ op_errno = error_gen (this, ERR_RMDIR);
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);
+ return 0;
}
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 stat *buf, struct stat *preparent,
+ struct stat *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)
{
int op_errno = 0;
eg_t *egp = NULL;
int enable = 1;
egp = this->private;
- enable = egp->enable[GF_FOP_SYMLINK];
+ enable = egp->enable[ERR_SYMLINK];
if (enable)
- op_errno = error_gen (this, GF_FOP_SYMLINK);
+ op_errno = error_gen (this, ERR_SYMLINK);
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);
+ return 0;
}
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)
+ int32_t op_ret, int32_t op_errno, struct stat *buf,
+ struct stat *preoldparent, struct stat *postoldparent,
+ struct stat *prenewparent, struct stat *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;
int enable = 1;
egp = this->private;
- enable = egp->enable[GF_FOP_RENAME];
+ enable = egp->enable[ERR_RENAME];
if (enable)
- op_errno = error_gen (this, GF_FOP_RENAME);
+ op_errno = error_gen (this, ERR_RENAME);
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;
}
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 stat *buf, struct stat *preparent,
+ struct stat *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;
int enable = 1;
egp = this->private;
- enable = egp->enable[GF_FOP_LINK];
+ enable = egp->enable[ERR_LINK];
if (enable)
- op_errno = error_gen (this, GF_FOP_LINK);
+ op_errno = error_gen (this, ERR_LINK);
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;
}
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)
+ fd_t *fd, inode_t *inode, struct stat *buf,
+ struct stat *preparent, struct stat *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)
{
int op_errno = 0;
eg_t *egp = NULL;
int enable = 1;
egp = this->private;
- enable = egp->enable[GF_FOP_CREATE];
+ enable = egp->enable[ERR_CREATE];
if (enable)
- op_errno = error_gen (this, GF_FOP_CREATE);
+ op_errno = error_gen (this, ERR_CREATE);
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);
+ 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;
int enable = 1;
egp = this->private;
- enable = egp->enable[GF_FOP_OPEN];
+ enable = egp->enable[ERR_OPEN];
if (enable)
- op_errno = error_gen (this, GF_FOP_OPEN);
+ op_errno = error_gen (this, ERR_OPEN);
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;
}
@@ -1045,1051 +1058,977 @@ 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 stat *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;
int enable = 1;
egp = this->private;
- enable = egp->enable[GF_FOP_READ];
+ enable = egp->enable[ERR_READV];
if (enable)
- op_errno = error_gen (this, GF_FOP_READ);
+ op_errno = error_gen (this, ERR_READV);
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 stat *prebuf, struct stat *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;
int enable = 1;
egp = this->private;
- enable = egp->enable[GF_FOP_WRITE];
+ enable = egp->enable[ERR_WRITEV];
if (enable)
- op_errno = error_gen (this, GF_FOP_WRITE);
-
- if (op_errno == GF_ERROR_SHORT_WRITE) {
- struct iovec *shortvec;
-
- /*
- * A short write error returns some value less than what was
- * requested from a write. To simulate this, replace the vector
- * with one half the size;
- */
- shortvec = iov_dup(vector, 1);
- shortvec->iov_len /= 2;
-
- STACK_WIND(frame, error_gen_writev_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->writev, fd, shortvec, count,
- off, flags, iobref, xdata);
- GF_FREE(shortvec);
- return 0;
- } else if (op_errno) {
+ op_errno = error_gen (this, ERR_WRITEV);
+
+ 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;
int enable = 1;
egp = this->private;
- enable = egp->enable[GF_FOP_FLUSH];
+ enable = egp->enable[ERR_FLUSH];
if (enable)
- op_errno = error_gen (this, GF_FOP_FLUSH);
+ op_errno = error_gen (this, ERR_FLUSH);
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;
}
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)
+ int32_t op_errno, struct stat *prebuf,
+ struct stat *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;
int enable = 1;
egp = this->private;
- enable = egp->enable[GF_FOP_FSYNC];
+ enable = egp->enable[ERR_FSYNC];
if (enable)
- op_errno = error_gen (this, GF_FOP_FSYNC);
+ op_errno = error_gen (this, ERR_FSYNC);
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 stat *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;
int enable = 1;
egp = this->private;
- enable = egp->enable[GF_FOP_FSTAT];
+ enable = egp->enable[ERR_FSTAT];
if (enable)
- op_errno = error_gen (this, GF_FOP_FSTAT);
+ op_errno = error_gen (this, ERR_FSTAT);
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;
int enable = 1;
egp = this->private;
- enable = egp->enable[GF_FOP_OPENDIR];
+ enable = egp->enable[ERR_OPENDIR];
if (enable)
- op_errno = error_gen (this, GF_FOP_OPENDIR);
+ op_errno = error_gen (this, ERR_OPENDIR);
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)
+error_gen_getdents_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dir_entry_t *entries,
+ int32_t count)
{
- STACK_UNWIND_STRICT (fsyncdir, frame, op_ret, op_errno, xdata);
- return 0;
+ STACK_UNWIND_STRICT (getdents, frame, op_ret, op_errno, entries,
+ count);
+ return 0;
}
int
-error_gen_fsyncdir (call_frame_t *frame, xlator_t *this, fd_t *fd,
- int32_t flags, dict_t *xdata)
+error_gen_getdents (call_frame_t *frame, xlator_t *this, fd_t *fd,
+ size_t size, off_t offset, int32_t flag)
{
int op_errno = 0;
eg_t *egp = NULL;
int enable = 1;
egp = this->private;
- enable = egp->enable[GF_FOP_FSYNCDIR];
+ enable = egp->enable[ERR_GETDENTS];
if (enable)
- op_errno = error_gen (this, GF_FOP_FSYNCDIR);
+ op_errno = error_gen (this, ERR_GETDENTS);
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 (getdents, frame, -1, op_errno, NULL, 0);
+ return 0;
}
- STACK_WIND (frame, error_gen_fsyncdir_cbk,
+ STACK_WIND (frame, error_gen_getdents_cbk,
FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fsyncdir,
- fd, flags, xdata);
- return 0;
+ FIRST_CHILD(this)->fops->getdents,
+ fd, size, offset, flag);
+ 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)
+error_gen_setdents_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno)
{
- STACK_UNWIND_STRICT (statfs, frame, op_ret, op_errno, buf, xdata);
- return 0;
+ STACK_UNWIND_STRICT (setdents, frame, op_ret, op_errno);
+ return 0;
}
int
-error_gen_statfs (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
+error_gen_setdents (call_frame_t *frame, xlator_t *this, fd_t *fd,
+ int32_t flags, dir_entry_t *entries, int32_t count)
{
int op_errno = 0;
eg_t *egp = NULL;
int enable = 1;
egp = this->private;
- enable = egp->enable[GF_FOP_STATFS];
+ enable = egp->enable[ERR_SETDENTS];
if (enable)
- op_errno = error_gen (this, GF_FOP_STATFS);
+ op_errno = error_gen (this, ERR_SETDENTS);
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 (setdents, frame, -1, op_errno);
+ return 0;
}
- STACK_WIND (frame, error_gen_statfs_cbk,
+ STACK_WIND (frame, error_gen_setdents_cbk,
FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->statfs,
- loc, xdata);
- return 0;
+ FIRST_CHILD(this)->fops->setdents,
+ fd, flags, entries, count);
+ 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)
+error_gen_fsyncdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno)
{
- STACK_UNWIND_STRICT (setxattr, frame, op_ret, op_errno, xdata);
- return 0;
+ STACK_UNWIND_STRICT (fsyncdir, 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)
+error_gen_fsyncdir (call_frame_t *frame, xlator_t *this, fd_t *fd,
+ int32_t flags)
{
int op_errno = 0;
eg_t *egp = NULL;
int enable = 1;
egp = this->private;
- enable = egp->enable[GF_FOP_SETXATTR];
+ enable = egp->enable[ERR_FSYNCDIR];
if (enable)
- op_errno = error_gen (this, GF_FOP_SETXATTR);
+ op_errno = error_gen (this, ERR_FSYNCDIR);
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 (fsyncdir, frame, -1, op_errno);
+ return 0;
}
- STACK_WIND (frame, error_gen_setxattr_cbk,
+ STACK_WIND (frame, error_gen_fsyncdir_cbk,
FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->setxattr,
- loc, dict, flags, xdata);
- return 0;
+ FIRST_CHILD(this)->fops->fsyncdir,
+ fd, 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)
+error_gen_statfs_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct statvfs *buf)
{
- STACK_UNWIND_STRICT (getxattr, frame, op_ret, op_errno, dict, xdata);
- return 0;
+ STACK_UNWIND_STRICT (statfs, frame, op_ret, op_errno, buf);
+
+ return 0;
}
int
-error_gen_getxattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
- const char *name, dict_t *xdata)
+error_gen_statfs (call_frame_t *frame, xlator_t *this, loc_t *loc)
{
int op_errno = 0;
eg_t *egp = NULL;
int enable = 1;
egp = this->private;
- enable = egp->enable[GF_FOP_GETXATTR];
+ enable = egp->enable[ERR_STATFS];
if (enable)
- op_errno = error_gen (this, GF_FOP_GETXATTR);
+ op_errno = error_gen (this, ERR_STATFS);
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 (statfs, frame, -1, op_errno, NULL);
+ return 0;
}
- STACK_WIND (frame, error_gen_getxattr_cbk,
+ STACK_WIND (frame, error_gen_statfs_cbk,
FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->getxattr,
- loc, name, xdata);
- return 0;
+ FIRST_CHILD(this)->fops->statfs,
+ loc);
+ 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)
+error_gen_setxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno)
{
- STACK_UNWIND_STRICT (fsetxattr, frame, op_ret, op_errno, xdata);
- return 0;
+ STACK_UNWIND_STRICT (setxattr, frame, op_ret, op_errno);
+
+ 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)
+error_gen_setxattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
+ dict_t *dict, int32_t flags)
{
int op_errno = 0;
eg_t *egp = NULL;
int enable = 1;
egp = this->private;
- enable = egp->enable[GF_FOP_FSETXATTR];
+ enable = egp->enable[ERR_SETXATTR];
if (enable)
- op_errno = error_gen (this, GF_FOP_FSETXATTR);
+ op_errno = error_gen (this, ERR_SETXATTR);
if (op_errno) {
GF_ERROR(this, "unwind(-1, %s)", strerror (op_errno));
- STACK_UNWIND_STRICT (fsetxattr, frame, -1, op_errno, xdata);
- return 0;
+ STACK_UNWIND_STRICT (setxattr, frame, -1, op_errno);
+ return 0;
}
- STACK_WIND (frame, error_gen_fsetxattr_cbk,
+ STACK_WIND (frame, error_gen_setxattr_cbk,
FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fsetxattr,
- fd, dict, flags, xdata);
- return 0;
+ FIRST_CHILD(this)->fops->setxattr,
+ loc, dict, flags);
+ 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)
+error_gen_getxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *dict)
{
- STACK_UNWIND_STRICT (fgetxattr, frame, op_ret, op_errno, dict, xdata);
- return 0;
+ STACK_UNWIND_STRICT (getxattr, frame, op_ret, op_errno, dict);
+ return 0;
}
int
-error_gen_fgetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
- const char *name, dict_t *xdata)
+error_gen_getxattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
+ const char *name)
{
int op_errno = 0;
eg_t *egp = NULL;
int enable = 1;
egp = this->private;
- enable = egp->enable[GF_FOP_FGETXATTR];
+ enable = egp->enable[ERR_GETXATTR];
if (enable)
- op_errno = error_gen (this, GF_FOP_FGETXATTR);
+ op_errno = error_gen (this, ERR_GETXATTR);
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_UNWIND_STRICT (getxattr, frame, -1, op_errno, NULL);
+ return 0;
}
- STACK_WIND (frame, error_gen_fgetxattr_cbk,
+ STACK_WIND (frame, error_gen_getxattr_cbk,
FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fgetxattr,
- fd, name, xdata);
- return 0;
+ FIRST_CHILD(this)->fops->getxattr,
+ 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;
int enable = 1;
egp = this->private;
- enable = egp->enable[GF_FOP_XATTROP];
+ enable = egp->enable[ERR_XATTROP];
if (enable)
- op_errno = error_gen (this, GF_FOP_XATTROP);
+ op_errno = error_gen (this, ERR_XATTROP);
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;
int enable = 1;
egp = this->private;
- enable = egp->enable[GF_FOP_FXATTROP];
+ enable = egp->enable[ERR_FXATTROP];
if (enable)
- op_errno = error_gen (this, GF_FOP_FXATTROP);
+ op_errno = error_gen (this, ERR_FXATTROP);
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;
int enable = 1;
egp = this->private;
- enable = egp->enable[GF_FOP_REMOVEXATTR];
+ enable = egp->enable[ERR_REMOVEXATTR];
if (enable)
- op_errno = error_gen (this, GF_FOP_REMOVEXATTR);
+ op_errno = error_gen (this, ERR_REMOVEXATTR);
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 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 flock *lock)
{
int op_errno = 0;
eg_t *egp = NULL;
int enable = 1;
egp = this->private;
- enable = egp->enable[GF_FOP_LK];
+ enable = egp->enable[ERR_LK];
if (enable)
- op_errno = error_gen (this, GF_FOP_LK);
+ op_errno = error_gen (this, ERR_LK);
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 flock *lock)
{
int op_errno = 0;
eg_t *egp = NULL;
int enable = 1;
egp = this->private;
- enable = egp->enable[GF_FOP_INODELK];
+ enable = egp->enable[ERR_INODELK];
if (enable)
- op_errno = error_gen (this, GF_FOP_INODELK);
+ op_errno = error_gen (this, ERR_INODELK);
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 flock *lock)
{
int op_errno = 0;
eg_t *egp = NULL;
int enable = 1;
egp = this->private;
- enable = egp->enable[GF_FOP_FINODELK];
+ enable = egp->enable[ERR_FINODELK];
if (enable)
- op_errno = error_gen (this, GF_FOP_FINODELK);
+ op_errno = error_gen (this, ERR_FINODELK);
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;
int enable = 1;
egp = this->private;
- enable = egp->enable[GF_FOP_ENTRYLK];
+ enable = egp->enable[ERR_ENTRYLK];
if (enable)
- op_errno = error_gen (this, GF_FOP_ENTRYLK);
+ op_errno = error_gen (this, ERR_ENTRYLK);
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;
int enable = 1;
egp = this->private;
- enable = egp->enable[GF_FOP_FENTRYLK];
+ enable = egp->enable[ERR_FENTRYLK];
if (enable)
- op_errno = error_gen (this, GF_FOP_FENTRYLK);
+ op_errno = error_gen (this, ERR_FENTRYLK);
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;
}
/* Management operations */
-
int
-error_gen_getspec_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, char *spec_data)
+error_gen_stats_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno,
+ struct xlator_stats *stats)
{
- STACK_UNWIND_STRICT (getspec, frame, op_ret, op_errno, spec_data);
- return 0;
+ STACK_UNWIND (frame, op_ret, op_errno, stats);
+ return 0;
}
int
-error_gen_getspec (call_frame_t *frame, xlator_t *this, const char *key,
- int32_t flags)
+error_gen_stats (call_frame_t *frame, xlator_t *this, int32_t flags)
{
int op_errno = 0;
eg_t *egp = NULL;
int enable = 1;
egp = this->private;
- enable = egp->enable[GF_FOP_GETSPEC];
+ enable = egp->enable[ERR_STATS];
if (enable)
- op_errno = error_gen (this, GF_FOP_GETSPEC);
+ op_errno = error_gen (this, ERR_STATS);
if (op_errno) {
GF_ERROR(this, "unwind(-1, %s)", strerror (op_errno));
- STACK_UNWIND_STRICT (getspec, frame, -1, op_errno, NULL);
+ STACK_UNWIND (frame, -1, op_errno, NULL);
return 0;
}
- STACK_WIND (frame, error_gen_getspec_cbk,
+ STACK_WIND (frame, error_gen_stats_cbk,
FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->getspec,
- key, flags);
+ FIRST_CHILD(this)->mops->stats,
+ flags);
return 0;
}
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)
+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 (readdir, frame, op_ret, op_errno, entries, xdata);
+ STACK_UNWIND (frame, op_ret, op_errno, spec_data);
+
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)
+error_gen_getspec (call_frame_t *frame, xlator_t *this, const char *key,
+ int32_t flags)
{
int op_errno = 0;
eg_t *egp = NULL;
int enable = 1;
egp = this->private;
- enable = egp->enable[GF_FOP_READDIR];
+ enable = egp->enable[ERR_GETSPEC];
if (enable)
- op_errno = error_gen (this, GF_FOP_READDIR);
+ op_errno = error_gen (this, ERR_GETSPEC);
if (op_errno) {
GF_ERROR(this, "unwind(-1, %s)", strerror (op_errno));
- STACK_UNWIND_STRICT (readdir, frame, -1, op_errno, NULL, xdata);
+ STACK_UNWIND (frame, -1, op_errno, NULL);
return 0;
}
- STACK_WIND (frame, error_gen_readdir_cbk,
+ STACK_WIND (frame, error_gen_getspec_cbk,
FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->readdir,
- fd, size, off, xdata);
+ FIRST_CHILD(this)->mops->getspec,
+ key, flags);
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)
+error_gen_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)
{
- STACK_UNWIND_STRICT (readdirp, frame, op_ret, op_errno, entries, xdata);
+ STACK_UNWIND (frame, op_ret, op_errno,
+ file_checksum, dir_checksum);
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)
+error_gen_checksum (call_frame_t *frame, xlator_t *this, loc_t *loc,
+ int32_t flag)
{
int op_errno = 0;
eg_t *egp = NULL;
int enable = 1;
egp = this->private;
- enable = egp->enable[GF_FOP_READDIRP];
+ enable = egp->enable[ERR_CHECKSUM];
if (enable)
- op_errno = error_gen (this, GF_FOP_READDIRP);
+ op_errno = error_gen (this, ERR_CHECKSUM);
if (op_errno) {
GF_ERROR(this, "unwind(-1, %s)", strerror (op_errno));
- STACK_UNWIND_STRICT (readdirp, frame, -1, op_errno, NULL, NULL);
+ STACK_UNWIND (frame, -1, op_errno, NULL, NULL);
return 0;
}
- STACK_WIND (frame, error_gen_readdirp_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->readdirp,
- fd, size, off, dict);
+ STACK_WIND (frame, error_gen_checksum_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->checksum,
+ loc, flag);
return 0;
}
-static void
-error_gen_set_failure (eg_t *pvt, int percent)
-{
- GF_ASSERT (pvt);
- if (percent)
- pvt->failure_iter_no = 100/percent;
- else
- pvt->failure_iter_no = 100/GF_FAILURE_DEFAULT;
-}
-
-static void
-error_gen_parse_fill_fops (eg_t *pvt, char *enable_fops)
+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)
{
- char *op_no_str = NULL;
- int op_no = -1;
- int i = 0;
- xlator_t *this = THIS;
- char *saveptr = NULL;
-
- GF_ASSERT (pvt);
- GF_ASSERT (this);
-
- for (i = 0; i < GF_FOP_MAXVALUE; i++)
- pvt->enable[i] = 0;
-
- if (!enable_fops) {
- gf_log (this->name, GF_LOG_WARNING,
- "All fops are enabled.");
- for (i = 0; i < GF_FOP_MAXVALUE; i++)
- pvt->enable[i] = 1;
- } else {
- op_no_str = strtok_r (enable_fops, ",", &saveptr);
- while (op_no_str) {
- op_no = get_fop_int (&op_no_str);
- if (op_no == -1) {
- gf_log (this->name, GF_LOG_WARNING,
- "Wrong option value %s", op_no_str);
- } else
- pvt->enable[op_no] = 1;
-
- op_no_str = strtok_r (NULL, ",", &saveptr);
- }
- }
+ STACK_UNWIND_STRICT (readdir, frame, op_ret, op_errno, entries);
+ return 0;
}
-int32_t
-error_gen_priv_dump (xlator_t *this)
-{
- char key_prefix[GF_DUMP_MAX_BUF_LEN];
- int ret = -1;
- eg_t *conf = NULL;
- if (!this)
- goto out;
-
- conf = this->private;
- if (!conf)
- goto out;
+int
+error_gen_readdir (call_frame_t *frame, xlator_t *this, fd_t *fd,
+ size_t size, off_t off)
+{
+ int op_errno = 0;
+ eg_t *egp = NULL;
+ int enable = 1;
- ret = TRY_LOCK(&conf->lock);
- if (ret != 0) {
- return ret;
- }
+ egp = this->private;
+ enable = egp->enable[ERR_READDIR];
- gf_proc_dump_add_section("xlator.debug.error-gen.%s.priv", this->name);
- gf_proc_dump_build_key(key_prefix,"xlator.debug.error-gen","%s.priv",
- this->name);
+ if (enable)
+ op_errno = error_gen (this, ERR_READDIR);
- gf_proc_dump_write("op_count", "%d", conf->op_count);
- gf_proc_dump_write("failure_iter_no", "%d", conf->failure_iter_no);
- gf_proc_dump_write("error_no", "%s", conf->error_no);
- gf_proc_dump_write("random_failure", "%d", conf->random_failure);
+ if (op_errno) {
+ GF_ERROR(this, "unwind(-1, %s)", strerror (op_errno));
+ STACK_UNWIND_STRICT (readdir, frame, -1, op_errno, NULL);
+ return 0;
+ }
- UNLOCK(&conf->lock);
-out:
- return ret;
+ STACK_WIND (frame, error_gen_readdir_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->readdir,
+ fd, size, off);
+ return 0;
}
-int32_t
-mem_acct_init (xlator_t *this)
-{
- int ret = -1;
-
- if (!this)
- return ret;
- 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_readdirp_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, gf_dirent_t *entries)
+{
+ STACK_UNWIND_STRICT (readdirp, frame, op_ret, op_errno, entries);
+ return 0;
}
+
int
-reconfigure (xlator_t *this, dict_t *options)
+error_gen_readdirp (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
+ off_t off)
{
- eg_t *pvt = NULL;
- int32_t ret = 0;
- char *error_enable_fops = NULL;
- int32_t failure_percent_int = 0;
+ int op_errno = 0;
+ eg_t *egp = NULL;
+ int enable = 1;
- if (!this || !this->private)
- goto out;
+ egp = this->private;
+ enable = egp->enable[ERR_READDIRP];
- pvt = this->private;
+ if (enable)
+ op_errno = error_gen (this, ERR_READDIRP);
- GF_OPTION_RECONF ("error-no", pvt->error_no, options, str, out);
+ if (op_errno) {
+ GF_ERROR(this, "unwind(-1, %s)", strerror (op_errno));
+ STACK_UNWIND_STRICT (readdirp, frame, -1, op_errno, NULL);
+ return 0;
+ }
- GF_OPTION_RECONF ("failure", failure_percent_int, options, int32,
- out);
+ STACK_WIND (frame, error_gen_readdirp_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->readdirp,
+ fd, size, off);
+ return 0;
+}
- GF_OPTION_RECONF ("enable", error_enable_fops, options, str, out);
- GF_OPTION_RECONF ("random-failure", pvt->random_failure, options,
- bool, out);
+int
+error_gen_closedir (xlator_t *this, fd_t *fd)
+{
+ return 0;
+}
- error_gen_parse_fill_fops (pvt, error_enable_fops);
- error_gen_set_failure (pvt, failure_percent_int);
- ret = 0;
-out:
- gf_log (this->name, GF_LOG_DEBUG, "reconfigure returning %d", ret);
- return ret;
+int
+error_gen_close (xlator_t *this, fd_t *fd)
+{
+ return 0;
}
+
int
init (xlator_t *this)
{
eg_t *pvt = NULL;
+ data_t *error_no = NULL;
+ data_t *failure_percent = NULL;
+ data_t *enable = NULL;
int32_t ret = 0;
char *error_enable_fops = NULL;
+ char *op_no_str = NULL;
+ int op_no = -1;
+ int i = 0;
int32_t failure_percent_int = 0;
if (!this->children || this->children->next) {
@@ -2104,34 +2043,71 @@ init (xlator_t *this)
"dangling volume. check volfile ");
}
- pvt = GF_CALLOC (1, sizeof (eg_t), gf_error_gen_mt_eg_t);
+ error_no = dict_get (this->options, "error-no");
+ failure_percent = dict_get (this->options, "failure");
+ enable = dict_get (this->options, "enable");
+
+ pvt = CALLOC (1, sizeof (eg_t));
if (!pvt) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "out of memory.");
ret = -1;
goto out;
}
LOCK_INIT (&pvt->lock);
- GF_OPTION_INIT ("error-no", pvt->error_no, str, out);
-
- GF_OPTION_INIT ("failure", failure_percent_int, int32, out);
-
- GF_OPTION_INIT ("enable", error_enable_fops, str, out);
-
- GF_OPTION_INIT ("random-failure", pvt->random_failure, bool, out);
-
+ for (i = 0; i < NO_OF_FOPS; i++)
+ pvt->enable[i] = 0;
+ if (!error_no) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "error-no not specified.");
+ } else {
+ pvt->error_no = data_to_str (error_no);
+ }
- error_gen_parse_fill_fops (pvt, error_enable_fops);
- error_gen_set_failure (pvt, failure_percent_int);
+ if (!failure_percent) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "failure percent not specified.");
+ pvt->failure_iter_no = 100/GF_FAILURE_DEFAULT;
+ } else {
+ failure_percent_int = data_to_int32 (failure_percent);
+ if (failure_percent_int)
+ pvt->failure_iter_no = 100/failure_percent_int;
+ else
+ pvt->failure_iter_no = 100/GF_FAILURE_DEFAULT;
+ }
+ if (!enable) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "All fops are enabled.");
+ for (i = 0; i < NO_OF_FOPS; i++)
+ pvt->enable[i] = 1;
+ } else {
+ error_enable_fops = data_to_str (enable);
+ op_no_str = error_enable_fops;
+ while ((*error_enable_fops) != '\0') {
+ error_enable_fops++;
+ if (((*error_enable_fops) == ',') ||
+ ((*error_enable_fops) == '\0')) {
+ if ((*error_enable_fops) != '\0') {
+ (*error_enable_fops) = '\0';
+ error_enable_fops++;
+ }
+ op_no = get_fop_int (&op_no_str);
+ if (op_no == -1) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "Wrong option value %s",
+ op_no_str);
+ } else
+ pvt->enable[op_no] = 1;
+ op_no_str = error_enable_fops;
+ }
+ }
+ }
this->private = pvt;
-
- /* Give some seed value here */
- srand (time(NULL));
out:
- if (ret)
- GF_FREE (pvt);
return ret;
}
@@ -2147,18 +2123,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_dumpops dumpops = {
- .priv = error_gen_priv_dump,
-};
-
-struct xlator_fops cbks;
-
struct xlator_fops fops = {
.lookup = error_gen_lookup,
.stat = error_gen_stat,
@@ -2181,18 +2151,18 @@ 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,
+ .getdents = error_gen_getdents,
.fsyncdir = error_gen_fsyncdir,
.access = error_gen_access,
.ftruncate = error_gen_ftruncate,
.fstat = error_gen_fstat,
.lk = error_gen_lk,
+ .setdents = error_gen_setdents,
.lookup_cbk = error_gen_lookup_cbk,
+ .checksum = error_gen_checksum,
.xattrop = error_gen_xattrop,
.fxattrop = error_gen_fxattrop,
.inodelk = error_gen_inodelk,
@@ -2201,32 +2171,29 @@ struct xlator_fops fops = {
.fentrylk = error_gen_fentrylk,
.setattr = error_gen_setattr,
.fsetattr = error_gen_fsetattr,
- .getspec = error_gen_getspec,
+};
+
+struct xlator_mops mops = {
+ .stats = error_gen_stats,
+ .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,
- .description = "Percentage failure of operations when enabled.",
- },
-
+ .type = GF_OPTION_TYPE_INT },
{ .key = {"error-no"},
.value = {"ENOENT","ENOTDIR","ENAMETOOLONG","EACCES","EBADF",
"EFAULT","ENOMEM","EINVAL","EIO","EEXIST","ENOSPC",
"EPERM","EROFS","EBUSY","EISDIR","ENOTEMPTY","EMLINK"
"ENODEV","EXDEV","EMFILE","ENFILE","ENOSYS","EINTR",
- "EFBIG","EAGAIN","GF_ERROR_SHORT_WRITE"},
- .type = GF_OPTION_TYPE_STR,
- },
-
- { .key = {"random-failure"},
- .type = GF_OPTION_TYPE_BOOL,
- .default_value = "off",
- },
-
+ "EFBIG","EAGAIN"},
+ .type = GF_OPTION_TYPE_STR },
{ .key = {"enable"},
- .type = GF_OPTION_TYPE_STR,
- },
-
+ .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 d92c2306240..7fb5fdfb56c 100644
--- a/xlators/debug/error-gen/src/error-gen.h
+++ b/xlators/debug/error-gen/src/error-gen.h
@@ -1,12 +1,22 @@
/*
- Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
- This file is part of GlusterFS.
+ Copyright (c) 2008-2009 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 General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that 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_H
#define _ERROR_GEN_H
@@ -15,28 +25,59 @@
#include "config.h"
#endif
-#include "error-gen-mem-types.h"
-
#define GF_FAILURE_DEFAULT 10
+#define NO_OF_FOPS 42
-/*
- * Pseudo-errors refer to errors beyond the scope of traditional <-1, op_errno>
- * returns. This facilitates the ability to return unexpected, but not -1 values
- * and/or to inject operations that lead to implicit error conditions. The range
- * for pseudo errors resides at a high value to avoid conflicts with the errno
- * range.
- */
-enum GF_PSEUDO_ERRORS {
- GF_ERROR_SHORT_WRITE = 1000, /* short writev return value */
- GF_ERROR_MAX
+enum {
+ ERR_LOOKUP,
+ ERR_STAT,
+ ERR_READLINK,
+ ERR_MKNOD,
+ ERR_MKDIR,
+ ERR_UNLINK,
+ ERR_RMDIR,
+ ERR_SYMLINK,
+ ERR_RENAME,
+ ERR_LINK,
+ ERR_TRUNCATE,
+ ERR_CREATE,
+ ERR_OPEN,
+ ERR_READV,
+ ERR_WRITEV,
+ ERR_STATFS,
+ ERR_FLUSH,
+ ERR_FSYNC,
+ ERR_SETXATTR,
+ ERR_GETXATTR,
+ ERR_REMOVEXATTR,
+ ERR_OPENDIR,
+ ERR_READDIR,
+ ERR_READDIRP,
+ ERR_GETDENTS,
+ ERR_FSYNCDIR,
+ ERR_ACCESS,
+ ERR_FTRUNCATE,
+ ERR_FSTAT,
+ ERR_LK,
+ ERR_SETDENTS,
+ ERR_CHECKSUM,
+ ERR_XATTROP,
+ ERR_FXATTROP,
+ ERR_INODELK,
+ ERR_FINODELK,
+ ERR_ENTRYLK,
+ ERR_FENTRYLK,
+ ERR_SETATTR,
+ ERR_FSETATTR,
+ ERR_STATS,
+ ERR_GETSPEC
};
typedef struct {
- int enable[GF_FOP_MAXVALUE];
+ int enable[NO_OF_FOPS];
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/Makefile.am b/xlators/debug/io-stats/src/Makefile.am
index dff294cd84e..91aea6ebbc2 100644
--- a/xlators/debug/io-stats/src/Makefile.am
+++ b/xlators/debug/io-stats/src/Makefile.am
@@ -2,17 +2,12 @@
xlator_LTLIBRARIES = io-stats.la
xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/debug
-io_stats_la_LDFLAGS = -module -avoid-version
+io_stats_la_LDFLAGS = -module -avoidversion
io_stats_la_SOURCES = io-stats.c
io_stats_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la
-noinst_HEADERS = io-stats-mem-types.h
-
-AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \
- -I$(top_srcdir)/rpc/xdr/src \
- -I$(top_srcdir)/rpc/rpc-lib/src
-
-AM_CFLAGS = -Wall $(GF_CFLAGS)
+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/debug/io-stats/src/io-stats-mem-types.h b/xlators/debug/io-stats/src/io-stats-mem-types.h
deleted file mode 100644
index c30dfb17e7c..00000000000
--- a/xlators/debug/io-stats/src/io-stats-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 __IO_STATS_MEM_TYPES_H__
-#define __IO_STATS_MEM_TYPES_H__
-
-#include "mem-types.h"
-
-enum gf_io_stats_mem_types_ {
- gf_io_stats_mt_ios_conf = gf_common_mt_end + 1,
- gf_io_stats_mt_ios_fd,
- gf_io_stats_mt_ios_stat,
- gf_io_stats_mt_ios_stat_list,
- gf_io_stats_mt_end
-};
-#endif
-
diff --git a/xlators/debug/io-stats/src/io-stats.c b/xlators/debug/io-stats/src/io-stats.c
index 9033d724dc2..b3cfbeb4ffc 100644
--- a/xlators/debug/io-stats/src/io-stats.c
+++ b/xlators/debug/io-stats/src/io-stats.c
@@ -1,16 +1,25 @@
/*
- Copyright (c) 2006-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) 2006-2009 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"
-#include "xlator.h"
#endif
/**
@@ -32,66 +41,7 @@
#include <errno.h>
#include "glusterfs.h"
#include "xlator.h"
-#include "io-stats-mem-types.h"
-#include <stdarg.h>
-#include "defaults.h"
-#include "logging.h"
-#include "cli1-xdr.h"
-#include "statedump.h"
-
-#define MAX_LIST_MEMBERS 100
-
-typedef enum {
- IOS_STATS_TYPE_NONE,
- IOS_STATS_TYPE_OPEN,
- IOS_STATS_TYPE_READ,
- IOS_STATS_TYPE_WRITE,
- IOS_STATS_TYPE_OPENDIR,
- IOS_STATS_TYPE_READDIRP,
- IOS_STATS_TYPE_READ_THROUGHPUT,
- IOS_STATS_TYPE_WRITE_THROUGHPUT,
- IOS_STATS_TYPE_MAX
-}ios_stats_type_t;
-
-typedef enum {
- IOS_STATS_THRU_READ,
- IOS_STATS_THRU_WRITE,
- IOS_STATS_THRU_MAX,
-}ios_stats_thru_t;
-
-struct ios_stat_lat {
- struct timeval time;
- double throughput;
-};
-struct ios_stat {
- gf_lock_t lock;
- uuid_t gfid;
- char *filename;
- uint64_t counters [IOS_STATS_TYPE_MAX];
- struct ios_stat_lat thru_counters [IOS_STATS_THRU_MAX];
- int refcnt;
-};
-
-struct ios_stat_list {
- struct list_head list;
- struct ios_stat *iosstat;
- double value;
-};
-
-struct ios_stat_head {
- gf_lock_t lock;
- double min_cnt;
- uint64_t members;
- struct ios_stat_list *iosstats;
-};
-
-struct ios_lat {
- double min;
- double max;
- double avg;
- uint64_t total;
-};
struct ios_global_stats {
uint64_t data_written;
@@ -99,11 +49,8 @@ struct ios_global_stats {
uint64_t block_count_write[32];
uint64_t block_count_read[32];
uint64_t fop_hits[GF_FOP_MAXVALUE];
+ uint64_t cbk_hits[GF_CBK_MAXVALUE];
struct timeval started_at;
- struct ios_lat latency[GF_FOP_MAXVALUE];
- uint64_t nr_opens;
- uint64_t max_nr_opens;
- struct timeval max_openfd_time;
};
@@ -113,10 +60,6 @@ struct ios_conf {
uint64_t increment;
struct ios_global_stats incremental;
gf_boolean_t dump_fd_stats;
- gf_boolean_t count_fop_hits;
- gf_boolean_t measure_latency;
- struct ios_stat_head list[IOS_STATS_TYPE_MAX];
- struct ios_stat_head thru_list[IOS_STATS_THRU_MAX];
};
@@ -129,92 +72,40 @@ struct ios_fd {
struct timeval opened_at;
};
-typedef enum {
- IOS_DUMP_TYPE_NONE = 0,
- IOS_DUMP_TYPE_FILE = 1,
- IOS_DUMP_TYPE_DICT = 2,
- IOS_DUMP_TYPE_MAX = 3
-} ios_dump_type_t;
-
-struct ios_dump_args {
- ios_dump_type_t type;
- union {
- FILE *logfp;
- dict_t *dict;
- } u;
-};
-
-typedef int (*block_dump_func) (xlator_t *, struct ios_dump_args*,
- int , int , uint64_t ) ;
struct ios_local {
struct timeval wind_at;
struct timeval unwind_at;
};
-struct volume_options options[];
-
-inline static int
-is_fop_latency_started (call_frame_t *frame)
-{
- GF_ASSERT (frame);
- struct timeval epoch = {0,};
- return memcmp (&frame->begin, &epoch, sizeof (epoch));
-}
-#define END_FOP_LATENCY(frame, op) \
+#define BUMP_FOP(op) \
do { \
struct ios_conf *conf = NULL; \
\
conf = this->private; \
- if (conf && conf->measure_latency) { \
- gettimeofday (&frame->end, NULL); \
- update_ios_latency (conf, frame, GF_FOP_##op); \
+ LOCK (&conf->lock); \
+ { \
+ conf->cumulative.fop_hits[GF_FOP_##op]++; \
+ conf->incremental.fop_hits[GF_FOP_##op]++; \
} \
- } while (0)
-
-#define START_FOP_LATENCY(frame) \
- do { \
- struct ios_conf *conf = NULL; \
- \
- conf = this->private; \
- if (conf && conf->measure_latency) { \
- gettimeofday (&frame->begin, NULL); \
- } else { \
- memset (&frame->begin, 0, sizeof (frame->begin));\
- } \
+ UNLOCK (&conf->lock); \
} while (0)
-#define BUMP_FOP(op) \
+#define BUMP_CBK(op) \
do { \
struct ios_conf *conf = NULL; \
\
conf = this->private; \
- if (!conf) \
- break; \
- conf->cumulative.fop_hits[GF_FOP_##op]++; \
- conf->incremental.fop_hits[GF_FOP_##op]++; \
+ LOCK (&conf->lock); \
+ { \
+ conf->cumulative.cbk_hits[GF_CBK_##op]++; \
+ conf->incremental.cbk_hits[GF_CBK_##op]++; \
+ } \
+ UNLOCK (&conf->lock); \
} while (0)
-#define UPDATE_PROFILE_STATS(frame, op) \
- do { \
- struct ios_conf *conf = NULL; \
- \
- if (!is_fop_latency_started (frame)) \
- break; \
- conf = this->private; \
- LOCK (&conf->lock); \
- { \
- if (conf && conf->measure_latency && \
- conf->count_fop_hits) { \
- BUMP_FOP(op); \
- gettimeofday (&frame->end, NULL); \
- update_ios_latency (conf, frame, GF_FOP_##op);\
- } \
- } \
- UNLOCK (&conf->lock); \
- } while (0)
#define BUMP_READ(fd, len) \
do { \
@@ -225,8 +116,6 @@ is_fop_latency_started (call_frame_t *frame)
conf = this->private; \
lb2 = log_base2 (len); \
ios_fd_ctx_get (fd, this, &iosfd); \
- if (!conf) \
- break; \
\
LOCK (&conf->lock); \
{ \
@@ -253,8 +142,6 @@ is_fop_latency_started (call_frame_t *frame)
conf = this->private; \
lb2 = log_base2 (len); \
ios_fd_ctx_get (fd, this, &iosfd); \
- if (!conf) \
- break; \
\
LOCK (&conf->lock); \
{ \
@@ -272,58 +159,6 @@ is_fop_latency_started (call_frame_t *frame)
} while (0)
-#define BUMP_STATS(iosstat, type) \
- do { \
- struct ios_conf *conf = NULL; \
- uint64_t value = 0; \
- \
- conf = this->private; \
- \
- LOCK(&iosstat->lock); \
- { \
- iosstat->counters[type]++; \
- value = iosstat->counters[type]; \
- } \
- UNLOCK (&iosstat->lock); \
- ios_stat_add_to_list (&conf->list[type], \
- value, iosstat); \
- \
- } while (0)
-
-
-#define BUMP_THROUGHPUT(iosstat, type) \
- do { \
- 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 \
- <= throughput) { \
- iosstat->thru_counters[type].throughput = \
- throughput; \
- gettimeofday (&iosstat-> \
- thru_counters[type].time, NULL); \
- flag = 1; \
- } \
- } \
- UNLOCK (&iosstat->lock); \
- if (flag) \
- ios_stat_add_to_list (&conf->thru_list[type], \
- throughput, iosstat); \
- } while (0)
-
int
ios_fd_ctx_get (fd_t *fd, xlator_t *this, struct ios_fd **iosfd)
{
@@ -353,184 +188,6 @@ ios_fd_ctx_set (fd_t *fd, xlator_t *this, struct ios_fd *iosfd)
return ret;
}
-int
-ios_stat_ref (struct ios_stat *iosstat)
-{
- LOCK (&iosstat->lock);
- {
- iosstat->refcnt++;
- }
- UNLOCK (&iosstat->lock);
-
- return iosstat->refcnt;
-}
-
-int
-ios_stat_unref (struct ios_stat *iosstat)
-{
- int cleanup = 0;
- LOCK (&iosstat->lock);
- {
- iosstat->refcnt--;
- if (iosstat->refcnt == 0) {
- if (iosstat->filename) {
- GF_FREE (iosstat->filename);
- iosstat->filename = NULL;
- }
- cleanup = 1;
- }
- }
- UNLOCK (&iosstat->lock);
-
- if (cleanup) {
- LOCK_DESTROY (&iosstat->lock);
- GF_FREE (iosstat);
- iosstat = NULL;
- }
-
- return 0;
-}
-
-int
-ios_inode_ctx_set (inode_t *inode, xlator_t *this, struct ios_stat *iosstat)
-{
- uint64_t iosstat64 = 0;
- int ret = 0;
-
- ios_stat_ref (iosstat);
- iosstat64 = (unsigned long )iosstat;
- ret = inode_ctx_put (inode, this, iosstat64);
- return ret;
-}
-
-int
-ios_inode_ctx_get (inode_t *inode, xlator_t *this, struct ios_stat **iosstat)
-{
- uint64_t iosstat64 = 0;
- unsigned long iosstatlong = 0;
- int ret = 0;
-
- ret = inode_ctx_get (inode, this, &iosstat64);
- iosstatlong = iosstat64;
- if (ret != -1)
- *iosstat = (void *) iosstatlong;
-
- return ret;
-
-}
-
-int
-ios_stat_add_to_list (struct ios_stat_head *list_head, uint64_t value,
- struct ios_stat *iosstat)
-{
- struct ios_stat_list *new = NULL;
- struct ios_stat_list *entry = NULL;
- struct ios_stat_list *t = NULL;
- struct ios_stat_list *list_entry = NULL;
- struct ios_stat_list *tmp = NULL;
- struct ios_stat_list *last = NULL;
- struct ios_stat *stat = NULL;
- int cnt = 0;
- int found = 0;
- int reposition = 0;
- double min_count = 0;
-
- LOCK (&list_head->lock);
- {
-
- if (list_head->min_cnt == 0)
- list_head->min_cnt = value;
- if ((list_head->members == MAX_LIST_MEMBERS) &&
- (list_head->min_cnt > value))
- goto out;
-
- list_for_each_entry_safe (entry, t,
- &list_head->iosstats->list, list) {
- cnt++;
- if (cnt == list_head->members)
- last = entry;
-
- if (!uuid_compare (iosstat->gfid,
- entry->iosstat->gfid)) {
- list_entry = entry;
- found = cnt;
- entry->value = value;
- if (!reposition) {
- if (cnt == list_head->members)
- list_head->min_cnt = value;
- goto out;
- }
- break;
- } else if (entry->value <= value && !reposition) {
- reposition = cnt;
- tmp = entry;
- if (cnt == list_head->members - 1)
- min_count = entry->value;
- }
- }
- if (found) {
- list_del (&list_entry->list);
- list_add_tail (&list_entry->list, &tmp->list);
- if (min_count)
- list_head->min_cnt = min_count;
- goto out;
- } else if (list_head->members == MAX_LIST_MEMBERS && reposition) {
- new = GF_CALLOC (1, sizeof (*new),
- gf_io_stats_mt_ios_stat_list);
- new->iosstat = iosstat;
- new->value = value;
- ios_stat_ref (iosstat);
- list_add_tail (&new->list, &tmp->list);
- stat = last->iosstat;
- last->iosstat = NULL;
- ios_stat_unref (stat);
- list_del (&last->list);
- GF_FREE (last);
- if (reposition == MAX_LIST_MEMBERS)
- list_head->min_cnt = value;
- else if (min_count) {
- list_head->min_cnt = min_count;
- }
- } else if (list_head->members < MAX_LIST_MEMBERS) {
- new = GF_CALLOC (1, sizeof (*new),
- gf_io_stats_mt_ios_stat_list);
- new->iosstat = iosstat;
- new->value = value;
- ios_stat_ref (iosstat);
- if (reposition) {
- list_add_tail (&new->list, &tmp->list);
- } else {
- list_add_tail (&new->list, &entry->list);
- }
- list_head->members++;
- if (list_head->min_cnt > value)
- list_head->min_cnt = value;
- }
- }
-out:
- UNLOCK (&list_head->lock);
- return 0;
-}
-
-static inline int
-ios_stats_cleanup (xlator_t *this, inode_t *inode)
-{
-
- struct ios_stat *iosstat = NULL;
- uint64_t iosstat64 = 0;
-
- inode_ctx_del (inode, this, &iosstat64);
- if (!iosstat64) {
- gf_log (this->name, GF_LOG_WARNING,
- "could not get inode ctx");
- return 0;
- }
- iosstat = (void *) (long)iosstat64;
- if (iosstat) {
- ios_stat_unref (iosstat);
- }
- return 0;
-}
#define ios_log(this, logfp, fmt ...) \
do { \
@@ -538,445 +195,85 @@ ios_stats_cleanup (xlator_t *this, inode_t *inode)
fprintf (logfp, fmt); \
fprintf (logfp, "\n"); \
} \
- gf_log (this->name, GF_LOG_INFO, fmt); \
+ gf_log (this->name, GF_LOG_NORMAL, fmt); \
} while (0)
-int
-ios_dump_file_stats (struct ios_stat_head *list_head, xlator_t *this, FILE* logfp)
-{
- struct ios_stat_list *entry = NULL;
-
- LOCK (&list_head->lock);
- {
- list_for_each_entry (entry, &list_head->iosstats->list, list) {
- ios_log (this, logfp, "%-12.0f %s",
- entry->value, entry->iosstat->filename);
- }
- }
- UNLOCK (&list_head->lock);
- return 0;
-}
int
-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, };
- 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),
- ".%"GF_PRI_SUSECONDS, time.tv_usec);
-
- ios_log (this, logfp, "%s \t %-10.2f \t %s",
- timestr, entry->value, entry->iosstat->filename);
- }
- }
- UNLOCK (&list_head->lock);
- return 0;
-}
-
-int
-io_stats_dump_global_to_logfp (xlator_t *this, struct ios_global_stats *stats,
- struct timeval *now, int interval, FILE* logfp)
+io_stats_dump_global (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;
- 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;
+ int i = 0;
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;
- }
- }
-
- 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);
- }
-
- 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");
- 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, "------ ----- ----- ----- ----- ----- ----- ----- "
- " ----- ----- ----- -----\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);
- }
- UNLOCK (&conf->lock);
- ios_log (this, logfp, "\n==========Open File Stats========");
- ios_log (this, logfp, "\nCOUNT: \t FILE 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");
- 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");
- 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");
- 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");
- 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");
- list_head = &conf->thru_list[IOS_STATS_THRU_READ];
- ios_dump_throughput_stats(list_head, this, logfp, IOS_STATS_TYPE_READ);
-
- ios_log (this, logfp, "\n======Write Throughput File Stats======");
- ios_log (this, logfp, "\nTIMESTAMP \t\t\t THROUGHPUT(KBPS)"
- "\tFILE NAME");
- list_head = &conf->thru_list[IOS_STATS_THRU_WRITE];
- ios_dump_throughput_stats (list_head, this, logfp, IOS_STATS_TYPE_WRITE);
- }
- return 0;
-}
-
-int
-io_stats_dump_global_to_dict (xlator_t *this, struct ios_global_stats *stats,
- struct timeval *now, int interval, dict_t *dict)
-{
- int ret = 0;
- char key[256] = {0};
- uint64_t sec = 0;
- int i = 0;
- uint64_t count = 0;
-
- GF_ASSERT (stats);
- GF_ASSERT (now);
- GF_ASSERT (dict);
- GF_ASSERT (this);
-
- if (interval == -1)
- snprintf (key, sizeof (key), "cumulative");
- else
- snprintf (key, sizeof (key), "interval");
- ret = dict_set_int32 (dict, key, interval);
- if (ret)
- gf_log (this->name, GF_LOG_ERROR, "failed to set "
- "interval %d", interval);
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%d-duration", interval);
- sec = (uint64_t) (now->tv_sec - stats->started_at.tv_sec);
- ret = dict_set_uint64 (dict, key, sec);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "failed to set "
- "duration(%d) - %"PRId64, interval, sec);
- goto out;
- }
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%d-total-read", interval);
- ret = dict_set_uint64 (dict, key, stats->data_read);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "failed to set total "
- "read(%d) - %"PRId64, interval, stats->data_read);
- goto out;
- }
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%d-total-write", interval);
- ret = dict_set_uint64 (dict, key, stats->data_written);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "failed to set total "
- "write(%d) - %"PRId64, interval, stats->data_written);
- goto out;
- }
- for (i = 0; i < 32; i++) {
- if (stats->block_count_read[i]) {
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%d-read-%d", interval,
- (1 << i));
- count = stats->block_count_read[i];
- ret = dict_set_uint64 (dict, key, count);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "failed to "
- "set read-%db+, with: %"PRId64,
- (1<<i), count);
- goto out;
- }
- }
+ ios_log (this, logfp, " Read %06db+ : %"PRId64,
+ (1 << i), stats->block_count_read[i]);
}
for (i = 0; i < 32; i++) {
- if (stats->block_count_write[i]) {
- snprintf (key, sizeof (key), "%d-write-%d", interval,
- (1<<i));
- count = stats->block_count_write[i];
- ret = dict_set_uint64 (dict, key, count);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "failed to "
- "set write-%db+, with: %"PRId64,
- (1<<i), count);
- goto out;
- }
- }
- }
-
- for (i = 0; i < GF_FOP_MAXVALUE; i++) {
- if (stats->fop_hits[i] == 0)
- continue;
- snprintf (key, sizeof (key), "%d-%d-hits", interval, i);
- ret = dict_set_uint64 (dict, key, stats->fop_hits[i]);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "failed to "
- "set %s-fop-hits: %"PRIu64, gf_fop_list[i],
- stats->fop_hits[i]);
- goto out;
- }
-
- if (stats->latency[i].avg == 0)
- continue;
- snprintf (key, sizeof (key), "%d-%d-avglatency", interval, i);
- ret = dict_set_double (dict, key, stats->latency[i].avg);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "failed to set %s "
- "avglatency(%d) with %f", gf_fop_list[i],
- interval, stats->latency[i].avg);
- goto out;
- }
- snprintf (key, sizeof (key), "%d-%d-minlatency", interval, i);
- ret = dict_set_double (dict, key, stats->latency[i].min);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "failed to set %s "
- "minlatency(%d) with %f", gf_fop_list[i],
- interval, stats->latency[i].min);
- goto out;
- }
- snprintf (key, sizeof (key), "%d-%d-maxlatency", interval, i);
- ret = dict_set_double (dict, key, stats->latency[i].max);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "failed to set %s "
- "maxlatency(%d) with %f", gf_fop_list[i],
- interval, stats->latency[i].max);
- goto out;
- }
- }
-out:
- gf_log (this->name, GF_LOG_DEBUG, "returning %d", ret);
- return ret;
-}
-
-int
-io_stats_dump_global (xlator_t *this, struct ios_global_stats *stats,
- struct timeval *now, int interval,
- struct ios_dump_args *args)
-{
- int ret = -1;
-
- GF_ASSERT (args);
- GF_ASSERT (now);
- GF_ASSERT (stats);
- GF_ASSERT (this);
-
-
-
- switch (args->type) {
- case IOS_DUMP_TYPE_FILE:
- ret = io_stats_dump_global_to_logfp (this, stats, now,
- interval, args->u.logfp);
- break;
- case IOS_DUMP_TYPE_DICT:
- ret = io_stats_dump_global_to_dict (this, stats, now,
- interval, args->u.dict);
- break;
- default:
- GF_ASSERT (0);
- ret = -1;
- break;
+ if (stats->block_count_write[i])
+ ios_log (this, logfp, "Write %06db+ : %"PRId64,
+ (1 << i), stats->block_count_write[i]);
}
- return ret;
-}
-
-int
-ios_dump_args_init (struct ios_dump_args *args, ios_dump_type_t type,
- void *output)
-{
- int ret = 0;
- GF_ASSERT (args);
- GF_ASSERT (type > IOS_DUMP_TYPE_NONE && type < IOS_DUMP_TYPE_MAX);
- GF_ASSERT (output);
-
- args->type = type;
- switch (args->type) {
- case IOS_DUMP_TYPE_FILE:
- args->u.logfp = output;
- break;
- case IOS_DUMP_TYPE_DICT:
- args->u.dict = output;
- break;
- default:
- GF_ASSERT (0);
- ret = -1;
- }
+ for (i = 0; i < GF_FOP_MAXVALUE; i++)
+ if (stats->fop_hits[i])
+ ios_log (this, logfp, "%14s : %"PRId64,
+ gf_fop_list[i], stats->fop_hits[i]);
- return ret;
+ for (i = 0; i < GF_CBK_MAXVALUE; i++)
+ if (stats->cbk_hits[i])
+ ios_log (this, logfp, "%14s : %"PRId64,
+ gf_fop_list[i], stats->cbk_hits[i]);
+ return 0;
}
-static void
-ios_global_stats_clear (struct ios_global_stats *stats, struct timeval *now)
-{
- GF_ASSERT (stats);
- GF_ASSERT (now);
-
- memset (stats, 0, sizeof (*stats));
- stats->started_at = *now;
-}
int
-io_stats_dump (xlator_t *this, struct ios_dump_args *args,
- gf1_cli_info_op op, gf_boolean_t is_peek)
+io_stats_dump (xlator_t *this, char *filename, inode_t *inode,
+ const char *path)
{
struct ios_conf *conf = NULL;
struct ios_global_stats cumulative = {0, };
struct ios_global_stats incremental = {0, };
int increment = 0;
struct timeval now;
-
- GF_ASSERT (this);
- GF_ASSERT (args);
- GF_ASSERT (args->type > IOS_DUMP_TYPE_NONE);
- GF_ASSERT (args->type < IOS_DUMP_TYPE_MAX);
+ FILE *logfp = NULL;
conf = this->private;
gettimeofday (&now, NULL);
LOCK (&conf->lock);
{
- if (op == GF_CLI_INFO_ALL ||
- op == GF_CLI_INFO_CUMULATIVE)
- cumulative = conf->cumulative;
+ cumulative = conf->cumulative;
+ incremental = conf->incremental;
- if (op == GF_CLI_INFO_ALL ||
- op == GF_CLI_INFO_INCREMENTAL) {
- incremental = conf->incremental;
- increment = conf->increment;
+ increment = conf->increment++;
- if (!is_peek) {
- increment = conf->increment++;
-
- ios_global_stats_clear (&conf->incremental,
- &now);
- }
- }
+ memset (&conf->incremental, 0, sizeof (conf->incremental));
+ conf->incremental.started_at = now;
}
UNLOCK (&conf->lock);
- if (op == GF_CLI_INFO_ALL ||
- op == GF_CLI_INFO_CUMULATIVE)
- io_stats_dump_global (this, &cumulative, &now, -1, args);
-
- if (op == GF_CLI_INFO_ALL ||
- op == GF_CLI_INFO_INCREMENTAL)
- io_stats_dump_global (this, &incremental, &now, increment, args);
+ logfp = fopen (filename, "w+");
+ io_stats_dump_global (this, &cumulative, &now, -1, logfp);
+ io_stats_dump_global (this, &incremental, &now, increment, logfp);
+ if (logfp)
+ fclose (logfp);
return 0;
}
@@ -1008,216 +305,53 @@ io_stats_dump_fd (xlator_t *this, struct ios_fd *iosfd)
sec = now.tv_sec - iosfd->opened_at.tv_sec;
usec = now.tv_usec - iosfd->opened_at.tv_usec;
- gf_log (this->name, GF_LOG_INFO,
+ gf_log (this->name, GF_LOG_NORMAL,
"--- fd stats ---");
if (iosfd->filename)
- gf_log (this->name, GF_LOG_INFO,
+ gf_log (this->name, GF_LOG_NORMAL,
" Filename : %s",
iosfd->filename);
if (sec)
- gf_log (this->name, GF_LOG_INFO,
+ gf_log (this->name, GF_LOG_NORMAL,
" Lifetime : %"PRId64"secs, %"PRId64"usecs",
sec, usec);
if (iosfd->data_read)
- gf_log (this->name, GF_LOG_INFO,
+ gf_log (this->name, GF_LOG_NORMAL,
" BytesRead : %"PRId64" bytes",
iosfd->data_read);
if (iosfd->data_written)
- gf_log (this->name, GF_LOG_INFO,
+ gf_log (this->name, GF_LOG_NORMAL,
" BytesWritten : %"PRId64" bytes",
iosfd->data_written);
for (i = 0; i < 32; i++) {
if (iosfd->block_count_read[i])
- gf_log (this->name, GF_LOG_INFO,
+ gf_log (this->name, GF_LOG_NORMAL,
" Read %06db+ : %"PRId64,
(1 << i), iosfd->block_count_read[i]);
}
for (i = 0; i < 32; i++) {
if (iosfd->block_count_write[i])
- gf_log (this->name, GF_LOG_INFO,
+ gf_log (this->name, GF_LOG_NORMAL,
"Write %06db+ : %"PRId64,
(1 << i), iosfd->block_count_write[i]);
}
return 0;
}
-static void
-update_ios_latency_stats (struct ios_global_stats *stats, double elapsed,
- glusterfs_fop_t op)
-{
- double avg;
-
- GF_ASSERT (stats);
-
- stats->latency[op].total += elapsed;
-
- if (!stats->latency[op].min)
- stats->latency[op].min = elapsed;
- if (stats->latency[op].min > elapsed)
- stats->latency[op].min = elapsed;
- if (stats->latency[op].max < elapsed)
- stats->latency[op].max = elapsed;
-
- avg = stats->latency[op].avg;
-
- stats->latency[op].avg = avg + (elapsed - avg) / stats->fop_hits[op];
-}
-
-int
-update_ios_latency (struct ios_conf *conf, call_frame_t *frame,
- glusterfs_fop_t op)
-{
- double elapsed;
- struct timeval *begin, *end;
-
- begin = &frame->begin;
- end = &frame->end;
-
- elapsed = (end->tv_sec - begin->tv_sec) * 1e6
- + (end->tv_usec - begin->tv_usec);
-
- update_ios_latency_stats (&conf->cumulative, elapsed, op);
- update_ios_latency_stats (&conf->incremental, elapsed, op);
-
- return 0;
-}
-
-int32_t
-io_stats_dump_stats_to_dict (xlator_t *this, dict_t *resp,
- ios_stats_type_t flags, int32_t list_cnt)
-{
- struct ios_conf *conf = NULL;
- int cnt = 0;
- char key[256];
- struct ios_stat_head *list_head = NULL;
- 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:
- 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;
- 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);
- if (conf->cumulative.max_openfd_time.tv_sec)
- 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);
- if (ret)
- goto unlock;
- }
- 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];
- break;
- case IOS_STATS_TYPE_WRITE:
- list_head = &conf->list[IOS_STATS_TYPE_WRITE];
- break;
- case IOS_STATS_TYPE_OPENDIR:
- list_head = &conf->list[IOS_STATS_TYPE_OPENDIR];
- break;
- case IOS_STATS_TYPE_READDIRP:
- list_head = &conf->list[IOS_STATS_TYPE_READDIRP];
- break;
- case IOS_STATS_TYPE_READ_THROUGHPUT:
- list_head = &conf->thru_list[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];
- index = IOS_STATS_THRU_WRITE;
- break;
-
- default:
- goto out;
- }
- ret = dict_set_int32 (resp, "top-op", flags);
- if (!list_cnt)
- goto out;
- LOCK (&list_head->lock);
- {
- list_for_each_entry (entry, &list_head->iosstats->list, list) {
-
- cnt++;
- snprintf (key, 256, "%s-%d", "filename", cnt);
- ret = dict_set_str (resp, key, entry->iosstat->filename);
- if (ret)
- goto unlock_list_head;
- snprintf (key, 256, "%s-%d", "value",cnt);
- ret = dict_set_uint64 (resp, key, entry->value);
- if (ret)
- goto unlock_list_head;
- if (index != IOS_STATS_THRU_MAX) {
- snprintf (key, 256, "%s-%d", "time-sec", cnt);
- ret = dict_set_int32 (resp, key,
- entry->iosstat->thru_counters[index].time.tv_sec);
- if (ret)
- goto unlock_list_head;
- snprintf (key, 256, "%s-%d", "time-usec", cnt);
- ret = dict_set_int32 (resp, key,
- entry->iosstat->thru_counters[index].time.tv_usec);
- if (ret)
- goto unlock_list_head;
- }
- 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)
+ inode_t *inode, struct stat *buf,
+ struct stat *preparent, struct stat *postparent)
{
struct ios_fd *iosfd = NULL;
char *path = NULL;
- struct ios_stat *iosstat = NULL;
- struct ios_conf *conf = NULL;
-
- conf = this->private;
path = frame->local;
frame->local = NULL;
@@ -1226,13 +360,13 @@ io_stats_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
goto unwind;
if (op_ret < 0) {
- GF_FREE (path);
+ FREE (path);
goto unwind;
}
- iosfd = GF_CALLOC (1, sizeof (*iosfd), gf_io_stats_mt_ios_fd);
+ iosfd = CALLOC (1, sizeof (*iosfd));
if (!iosfd) {
- GF_FREE (path);
+ FREE (path);
goto unwind;
}
@@ -1240,44 +374,21 @@ io_stats_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
gettimeofday (&iosfd->opened_at, NULL);
ios_fd_ctx_set (fd, this, iosfd);
- LOCK (&conf->lock);
- {
- conf->cumulative.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);
-
- iosstat = GF_CALLOC (1, sizeof (*iosstat), gf_io_stats_mt_ios_stat);
- if (!iosstat) {
- GF_FREE (path);
- goto unwind;
- }
- iosstat->filename = gf_strdup (path);
- uuid_copy (iosstat->gfid, buf->ia_gfid);
- LOCK_INIT (&iosstat->lock);
- ios_inode_ctx_set (fd->inode, this, iosstat);
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;
path = frame->local;
frame->local = NULL;
@@ -1285,13 +396,13 @@ io_stats_open_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
goto unwind;
if (op_ret < 0) {
- GF_FREE (path);
+ FREE (path);
goto unwind;
}
- iosfd = GF_CALLOC (1, sizeof (*iosfd), gf_io_stats_mt_ios_fd);
+ iosfd = CALLOC (1, sizeof (*iosfd));
if (!iosfd) {
- GF_FREE (path);
+ FREE (path);
goto unwind;
}
@@ -1300,46 +411,17 @@ 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) {
- 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;
- }
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;
-
}
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 stat *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;
}
@@ -1348,11 +430,13 @@ 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 stat *buf, struct iobref *iobref)
{
+ struct ios_conf *conf = NULL;
int len = 0;
fd_t *fd = NULL;
- struct ios_stat *iosstat = NULL;
+
+ conf = this->private;
fd = frame->local;
frame->local = NULL;
@@ -1362,80 +446,46 @@ io_stats_readv_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
BUMP_READ (fd, len);
}
- UPDATE_PROFILE_STATS (frame, READ);
- ios_inode_ctx_get (fd->inode, this, &iosstat);
-
- if (iosstat) {
- BUMP_STATS (iosstat, IOS_STATS_TYPE_READ);
- BUMP_THROUGHPUT (iosstat, IOS_STATS_THRU_READ);
- iosstat = NULL;
- }
-
STACK_UNWIND_STRICT (readv, frame, op_ret, op_errno,
- vector, count, buf, iobref, xdata);
+ vector, count, buf, iobref);
return 0;
-
}
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 ios_stat *iosstat = NULL;
- inode_t *inode = NULL;
-
- UPDATE_PROFILE_STATS (frame, WRITE);
- if (frame->local){
- inode = frame->local;
- frame->local = NULL;
- ios_inode_ctx_get (inode, this, &iosstat);
- if (iosstat) {
- BUMP_STATS (iosstat, IOS_STATS_TYPE_WRITE);
- BUMP_THROUGHPUT (iosstat, IOS_STATS_THRU_WRITE);
- inode = NULL;
- iosstat = NULL;
- }
- }
-
- STACK_UNWIND_STRICT (writev, frame, op_ret, op_errno, prebuf, postbuf, xdata);
+ struct stat *prebuf, struct stat *postbuf)
+{
+ STACK_UNWIND_STRICT (writev, frame, op_ret, op_errno, prebuf, postbuf);
return 0;
-
}
+int
+io_stats_getdents_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno,
+ dir_entry_t *entries, int32_t count)
+{
+ STACK_UNWIND_STRICT (getdents, frame, op_ret, op_errno, entries, count);
+ return 0;
+}
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;
-
- frame->local = NULL;
-
- UPDATE_PROFILE_STATS (frame, READDIRP);
-
- ios_inode_ctx_get (inode, this, &iosstat);
-
- if (iosstat) {
- BUMP_STATS (iosstat, IOS_STATS_TYPE_READDIRP);
- 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;
}
@@ -1443,10 +493,9 @@ 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 stat *prebuf, struct stat *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;
}
@@ -1454,10 +503,9 @@ 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 stat *preop, struct stat *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;
}
@@ -1465,26 +513,23 @@ 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 stat *preparent, struct stat *postparent)
{
- UPDATE_PROFILE_STATS (frame, UNLINK);
STACK_UNWIND_STRICT (unlink, frame, op_ret, op_errno,
- preparent, postparent, xdata);
+ preparent, postparent);
return 0;
-
}
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)
+ int32_t op_ret, int32_t op_errno, struct stat *buf,
+ struct stat *preoldparent, struct stat *postoldparent,
+ struct stat *prenewparent, struct stat *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;
}
@@ -1492,10 +537,9 @@ 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 stat *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;
}
@@ -1503,11 +547,10 @@ io_stats_readlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
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)
+ inode_t *inode, struct stat *buf,
+ dict_t *xattr, struct stat *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;
}
@@ -1516,12 +559,11 @@ io_stats_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
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)
+ inode_t *inode, struct stat *buf,
+ struct stat *preparent, struct stat *postparent)
{
- UPDATE_PROFILE_STATS (frame, SYMLINK);
STACK_UNWIND_STRICT (symlink, frame, op_ret, op_errno, inode, buf,
- preparent, postparent, xdata);
+ preparent, postparent);
return 0;
}
@@ -1529,12 +571,11 @@ io_stats_symlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
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)
+ inode_t *inode, struct stat *buf,
+ struct stat *preparent, struct stat *postparent)
{
- UPDATE_PROFILE_STATS (frame, MKNOD);
STACK_UNWIND_STRICT (mknod, frame, op_ret, op_errno, inode, buf,
- preparent, postparent, xdata);
+ preparent, postparent);
return 0;
}
@@ -1542,31 +583,11 @@ io_stats_mknod_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
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)
+ inode_t *inode, struct stat *buf,
+ struct stat *preparent, struct stat *postparent)
{
- struct ios_stat *iosstat = NULL;
- char *path = frame->local;
-
- UPDATE_PROFILE_STATS (frame, MKDIR);
- if (op_ret < 0)
- goto unwind;
-
- iosstat = GF_CALLOC (1, sizeof (*iosstat), gf_io_stats_mt_ios_stat);
- if (iosstat) {
- LOCK_INIT (&iosstat->lock);
- iosstat->filename = gf_strdup(path);
- uuid_copy (iosstat->gfid, buf->ia_gfid);
- ios_inode_ctx_set (inode, this, iosstat);
- }
-
-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;
}
@@ -1574,45 +595,32 @@ unwind:
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)
+ inode_t *inode, struct stat *buf,
+ struct stat *preparent, struct stat *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;
-
- UPDATE_PROFILE_STATS (frame, OPENDIR);
- if (op_ret < 0)
- goto unwind;
-
- ios_fd_ctx_set (fd, this, 0);
+ if (op_ret >= 0)
+ ios_fd_ctx_set (fd, this, 0);
- ret = ios_inode_ctx_get (fd->inode, this, &iosstat);
- if (!ret)
- 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;
}
@@ -1620,13 +628,10 @@ 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 stat *preparent, struct stat *postparent)
{
-
- UPDATE_PROFILE_STATS (frame, RMDIR);
-
STACK_UNWIND_STRICT (rmdir, frame, op_ret, op_errno,
- preparent, postparent, xdata);
+ preparent, postparent);
return 0;
}
@@ -1634,100 +639,64 @@ 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 stat *prebuf, struct stat *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 (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)
-{
- 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)
+ int32_t op_ret, int32_t op_errno)
{
- 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;
}
@@ -1735,405 +704,381 @@ 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 stat *prebuf, struct stat *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 stat *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_fallocate_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)
-{
- UPDATE_PROFILE_STATS(frame, FALLOCATE);
- STACK_UNWIND_STRICT(fallocate, frame, op_ret, op_errno, prebuf, postbuf,
- xdata);
- return 0;
-}
-
-
-int
-io_stats_discard_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)
-{
- UPDATE_PROFILE_STATS(frame, DISCARD);
- STACK_UNWIND_STRICT(discard, frame, op_ret, op_errno, prebuf, postbuf,
- xdata);
- return 0;
-}
-
-int
-io_stats_zerofill_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)
+io_stats_lk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct flock *lock)
{
- UPDATE_PROFILE_STATS(frame, ZEROFILL);
- STACK_UNWIND_STRICT(zerofill, frame, op_ret, op_errno, prebuf, postbuf,
- xdata);
+ STACK_UNWIND_STRICT (lk, frame, op_ret, op_errno, lock);
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)
+io_stats_setdents_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno)
{
- UPDATE_PROFILE_STATS (frame, LK);
- STACK_UNWIND_STRICT (lk, frame, op_ret, op_errno, lock, xdata);
+ STACK_UNWIND_STRICT (setdents, frame, op_ret, op_errno);
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);
+ BUMP_FOP (ENTRYLK);
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 flock *flock)
{
- START_FOP_LATENCY (frame);
+ BUMP_FOP (INODELK);
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 flock *flock)
{
- START_FOP_LATENCY (frame);
+ BUMP_FOP (FINODELK);
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);
+ BUMP_FOP (XATTROP);
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);
+ BUMP_FOP (FXATTROP);
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);
+ BUMP_FOP (LOOKUP);
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);
+ BUMP_FOP (STAT);
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);
+ BUMP_FOP (READLINK);
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)
{
- START_FOP_LATENCY (frame);
+ BUMP_FOP (MKNOD);
STACK_WIND (frame, io_stats_mknod_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->mknod,
- loc, mode, dev, umask, xdata);
+ loc, mode, dev);
+
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)
{
- frame->local = gf_strdup (loc->path);
-
- START_FOP_LATENCY (frame);
+ BUMP_FOP (MKDIR);
STACK_WIND (frame, io_stats_mkdir_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->mkdir,
- loc, mode, umask, xdata);
+ loc, mode);
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);
+ BUMP_FOP (UNLINK);
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)
{
- START_FOP_LATENCY (frame);
+ BUMP_FOP (RMDIR);
STACK_WIND (frame, io_stats_rmdir_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->rmdir,
- loc, flags, xdata);
+ loc);
+
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)
{
- START_FOP_LATENCY (frame);
+ BUMP_FOP (SYMLINK);
STACK_WIND (frame, io_stats_symlink_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->symlink,
- linkpath, loc, umask, xdata);
+ linkpath, loc);
+
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);
+ BUMP_FOP (RENAME);
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);
+ BUMP_FOP (LINK);
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 stat *stbuf, int32_t valid)
{
- START_FOP_LATENCY (frame);
+ BUMP_FOP (SETATTR);
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);
+ BUMP_FOP (TRUNCATE);
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);
+ BUMP_FOP (OPEN);
- START_FOP_LATENCY (frame);
+ frame->local = strdup (loc->path);
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;
}
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)
+ loc_t *loc, int32_t flags, mode_t mode, fd_t *fd)
{
- frame->local = gf_strdup (loc->path);
+ BUMP_FOP (CREATE);
- START_FOP_LATENCY (frame);
+ frame->local = strdup (loc->path);
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);
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;
+ BUMP_FOP (READ);
- START_FOP_LATENCY (frame);
+ frame->local = fd;
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;
}
@@ -2142,69 +1087,69 @@ 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)
{
+ struct ios_conf *conf = NULL;
int len = 0;
- if (fd->inode)
- frame->local = fd->inode;
+ conf = this->private;
+
len = iov_length (vector, count);
+ BUMP_FOP (WRITE);
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;
-
}
int
io_stats_statfs (call_frame_t *frame, xlator_t *this,
- loc_t *loc, dict_t *xdata)
+ loc_t *loc)
{
- START_FOP_LATENCY (frame);
+ BUMP_FOP (STATFS);
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);
+ BUMP_FOP (FLUSH);
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);
+ BUMP_FOP (FSYNC);
STACK_WIND (frame, io_stats_fsync_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->fsync,
- fd, flags, xdata);
+ fd, flags);
return 0;
}
-int
+void
conditional_dump (dict_t *dict, char *key, data_t *value, void *data)
{
struct {
@@ -2212,43 +1157,30 @@ conditional_dump (dict_t *dict, char *key, data_t *value, void *data)
inode_t *inode;
const char *path;
} *stub;
- xlator_t *this = NULL;
- char *filename = NULL;
- FILE *logfp = NULL;
- struct ios_dump_args args = {0};
+ xlator_t *this = NULL;
+ inode_t *inode = NULL;
+ const char *path = NULL;
+ char *filename = NULL;
stub = data;
this = stub->this;
+ inode = stub->inode;
+ path = stub->path;
filename = alloca (value->len + 1);
memset (filename, 0, value->len + 1);
memcpy (filename, data_to_str (value), value->len);
if (fnmatch ("*io*stat*dump", key, 0) == 0) {
-
- if (!strncmp (filename, "", 1)) {
- gf_log (this->name, GF_LOG_ERROR, "No filename given");
- return -1;
- }
- logfp = fopen (filename, "w+");
- if (!logfp) {
- gf_log (this->name, GF_LOG_ERROR, "failed to open %s "
- "for writing", filename);
- return -1;
- }
- (void) ios_dump_args_init (&args, IOS_DUMP_TYPE_FILE,
- logfp);
- io_stats_dump (this, &args, GF_CLI_INFO_ALL, _gf_false);
- fclose (logfp);
+ io_stats_dump (this, filename, inode, path);
}
- return 0;
}
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;
@@ -2256,676 +1188,345 @@ io_stats_setxattr (call_frame_t *frame, xlator_t *this,
const char *path;
} stub;
+ BUMP_FOP (SETXATTR);
+
stub.this = this;
stub.inode = loc->inode;
stub.path = loc->path;
dict_foreach (dict, conditional_dump, &stub);
- START_FOP_LATENCY (frame);
-
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);
+ BUMP_FOP (GETXATTR);
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);
+ BUMP_FOP (REMOVEXATTR);
STACK_WIND (frame, io_stats_removexattr_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->removexattr,
- loc, name, xdata);
- return 0;
-}
-
-
-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);
+ loc, name);
- 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)
+io_stats_opendir (call_frame_t *frame, xlator_t *this,
+ loc_t *loc, fd_t *fd)
{
- START_FOP_LATENCY (frame);
+ BUMP_FOP (OPENDIR);
- STACK_WIND (frame, io_stats_fgetxattr_cbk,
+ STACK_WIND (frame, io_stats_opendir_cbk,
FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fgetxattr,
- fd, name, xdata);
+ FIRST_CHILD(this)->fops->opendir,
+ loc, fd);
return 0;
}
int
-io_stats_fremovexattr (call_frame_t *frame, xlator_t *this,
- fd_t *fd, const char *name, dict_t *xdata)
+io_stats_getdents (call_frame_t *frame, xlator_t *this,
+ fd_t *fd, size_t size, off_t offset, int32_t flag)
{
- START_FOP_LATENCY (frame);
+ BUMP_FOP (GETDENTS);
- STACK_WIND (frame, io_stats_fremovexattr_cbk,
+ STACK_WIND (frame, io_stats_getdents_cbk,
FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fremovexattr,
- fd, name, xdata);
+ FIRST_CHILD(this)->fops->getdents,
+ fd, size, offset, flag);
return 0;
}
int
-io_stats_opendir (call_frame_t *frame, xlator_t *this,
- loc_t *loc, fd_t *fd, dict_t *xdata)
-{
-
- START_FOP_LATENCY (frame);
-
- STACK_WIND (frame, io_stats_opendir_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->opendir,
- loc, fd, xdata);
- 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);
+ BUMP_FOP (READDIRP);
STACK_WIND (frame, io_stats_readdirp_cbk,
FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->readdirp,
- fd, size, offset, dict);
+ FIRST_CHILD(this)->fops->readdir,
+ 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);
+ BUMP_FOP (READDIR);
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);
+ BUMP_FOP (FSYNCDIR);
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);
+ BUMP_FOP (ACCESS);
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);
+ BUMP_FOP (FTRUNCATE);
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 stat *stbuf, int32_t valid)
{
- START_FOP_LATENCY (frame);
+ BUMP_FOP (FSETATTR);
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);
+ BUMP_FOP (FSTAT);
STACK_WIND (frame, io_stats_fstat_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->fstat,
- fd, xdata);
+ fd);
return 0;
}
int
-io_stats_fallocate(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t mode,
- off_t offset, size_t len, dict_t *xdata)
-{
- START_FOP_LATENCY(frame);
-
- STACK_WIND(frame, io_stats_fallocate_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fallocate, fd, mode, offset, len,
- xdata);
-
- return 0;
-}
-
-
-int
-io_stats_discard(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
- size_t len, dict_t *xdata)
-{
- START_FOP_LATENCY(frame);
-
- STACK_WIND(frame, io_stats_discard_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->discard, fd, offset, len, xdata);
-
- return 0;
-}
-
-int
-io_stats_zerofill(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
- off_t len, dict_t *xdata)
+io_stats_lk (call_frame_t *frame, xlator_t *this,
+ fd_t *fd, int32_t cmd, struct flock *lock)
{
- START_FOP_LATENCY(frame);
-
- STACK_WIND(frame, io_stats_zerofill_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->zerofill, fd, offset, len, xdata);
+ BUMP_FOP (LK);
+ STACK_WIND (frame, io_stats_lk_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->lk,
+ fd, cmd, lock);
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)
+io_stats_setdents (call_frame_t *frame, xlator_t *this,
+ fd_t *fd, int32_t flags,
+ dir_entry_t *entries, int32_t count)
{
- START_FOP_LATENCY (frame);
+ BUMP_FOP (SETDENTS);
- STACK_WIND (frame, io_stats_lk_cbk,
+ STACK_WIND (frame, io_stats_setdents_cbk,
FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->lk,
- fd, cmd, lock, xdata);
+ FIRST_CHILD(this)->fops->setdents,
+ fd, flags, entries, count);
return 0;
}
int
-io_stats_release (xlator_t *this, fd_t *fd)
+io_stats_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)
{
- struct ios_fd *iosfd = NULL;
- struct ios_conf *conf = NULL;
-
- BUMP_FOP (RELEASE);
-
- conf = this->private;
-
- LOCK (&conf->lock);
- {
- conf->cumulative.nr_opens--;
- }
- UNLOCK (&conf->lock);
-
- ios_fd_ctx_get (fd, this, &iosfd);
- if (iosfd) {
- io_stats_dump_fd (this, iosfd);
-
- GF_FREE (iosfd->filename);
- GF_FREE (iosfd);
- }
+ STACK_UNWIND_STRICT (checksum, frame, op_ret, op_errno,
+ fchecksum, dchecksum);
return 0;
}
int
-io_stats_releasedir (xlator_t *this, fd_t *fd)
+io_stats_checksum (call_frame_t *frame, xlator_t *this,
+ loc_t *loc, int32_t flag)
{
- BUMP_FOP (RELEASEDIR);
+ STACK_WIND (frame, io_stats_checksum_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->checksum,
+ loc, flag);
return 0;
}
int
-io_stats_forget (xlator_t *this, inode_t *inode)
+io_stats_stats_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct xlator_stats *stats)
{
- BUMP_FOP (FORGET);
- ios_stats_cleanup (this, inode);
+ STACK_UNWIND (frame, op_ret, op_errno, stats);
return 0;
}
-static int
-ios_init_top_stats (struct ios_conf *conf)
-{
- int i = 0;
-
- 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);
- }
-
- 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);
- }
-
- return 0;
-}
-static void
-ios_destroy_top_stats (struct ios_conf *conf)
+int
+io_stats_stats (call_frame_t *frame, xlator_t *this, int32_t flags)
{
- 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--;
- }
- }
-
- 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--;
- }
- }
-
- UNLOCK (&conf->lock);
+ STACK_WIND (frame, io_stats_stats_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->mops->stats,
+ flags);
- return;
+ return 0;
}
-static int
-io_stats_clear (struct ios_conf *conf)
-{
- struct timeval now;
- int ret = -1;
-
- GF_ASSERT (conf);
-
- if (!gettimeofday (&now, NULL))
- {
- LOCK (&conf->lock);
- {
- ios_global_stats_clear (&conf->cumulative, &now);
- ios_global_stats_clear (&conf->incremental, &now);
- conf->increment = 0;
- }
- UNLOCK (&conf->lock);
- ret = 0;
- }
-
- return ret;
-}
-int32_t
-io_priv (xlator_t *this)
+int
+io_stats_release (xlator_t *this, fd_t *fd)
{
- int i;
- char key[GF_DUMP_MAX_BUF_LEN];
- char key_prefix_cumulative[GF_DUMP_MAX_BUF_LEN];
- char key_prefix_incremental[GF_DUMP_MAX_BUF_LEN];
- double min, max, avg;
- uint64_t count, total;
- struct ios_conf *conf = NULL;
-
- conf = this->private;
- if (!conf)
- return -1;
-
- if(!conf->count_fop_hits || !conf->measure_latency)
- return -1;
-
- gf_proc_dump_write("cumulative.data_read", "%"PRIu64,
- conf->cumulative.data_read);
- gf_proc_dump_write("cumulative.data_written", "%"PRIu64,
- conf->cumulative.data_written);
-
- gf_proc_dump_write("incremental.data_read", "%"PRIu64,
- conf->incremental.data_read);
- gf_proc_dump_write("incremental.data_written", "%"PRIu64,
- conf->incremental.data_written);
-
- snprintf (key_prefix_cumulative, GF_DUMP_MAX_BUF_LEN, "%s.cumulative",
- this->name);
- snprintf (key_prefix_incremental, GF_DUMP_MAX_BUF_LEN, "%s.incremental",
- this->name);
-
- for (i = 0; i < GF_FOP_MAXVALUE; i++) {
- count = conf->cumulative.fop_hits[i];
- total = conf->cumulative.latency[i].total;
- min = conf->cumulative.latency[i].min;
- max = conf->cumulative.latency[i].max;
- avg = conf->cumulative.latency[i].avg;
-
- gf_proc_dump_build_key (key, key_prefix_cumulative,
- (char *)gf_fop_list[i]);
-
- gf_proc_dump_write (key,"%"PRId64",%"PRId64",%.03f,%.03f,%.03f",
- count, total, min, max, avg);
-
- count = conf->incremental.fop_hits[i];
- total = conf->incremental.latency[i].total;
- min = conf->incremental.latency[i].min;
- max = conf->incremental.latency[i].max;
- avg = conf->incremental.latency[i].avg;
+ struct ios_fd *iosfd = NULL;
- gf_proc_dump_build_key (key, key_prefix_incremental,
- (char *)gf_fop_list[i]);
+ BUMP_CBK (RELEASE);
- gf_proc_dump_write (key,"%"PRId64",%"PRId64",%.03f,%.03f,%.03f",
- count, total, min, max, avg);
+ ios_fd_ctx_get (fd, this, &iosfd);
+ if (iosfd) {
+ io_stats_dump_fd (this, iosfd);
+ if (iosfd->filename)
+ FREE (iosfd->filename);
+ FREE (iosfd);
}
return 0;
}
+
int
-reconfigure (xlator_t *this, dict_t *options)
+io_stats_releasedir (xlator_t *this, fd_t *fd)
{
- struct ios_conf *conf = NULL;
- int ret = -1;
- char *sys_log_str = NULL;
- char *log_format_str = NULL;
- char *logger_str = NULL;
- int sys_log_level = -1;
- char *log_str = NULL;
- int log_level = -1;
- int log_format = -1;
- int logger = -1;
- uint32_t log_buf_size = 0;
- uint32_t log_flush_timeout = 0;
-
- if (!this || !this->private)
- goto out;
-
- conf = this->private;
-
- GF_OPTION_RECONF ("dump-fd-stats", conf->dump_fd_stats, options, bool,
- out);
+ BUMP_CBK (RELEASEDIR);
- 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);
- }
-
- GF_OPTION_RECONF ("logger", logger_str, options, str, out);
- if (logger_str) {
- logger = gf_check_logger (logger_str);
- gf_log_set_logger (logger);
- }
-
- GF_OPTION_RECONF ("log-format", log_format_str, options, str, out);
- if (log_format_str) {
- log_format = gf_check_log_format (log_format_str);
- gf_log_set_logformat (log_format);
- }
-
- GF_OPTION_RECONF ("log-buf-size", log_buf_size, options, uint32, out);
- gf_log_set_log_buf_size (log_buf_size);
-
- GF_OPTION_RECONF ("log-flush-timeout", log_flush_timeout, options,
- time, out);
- gf_log_set_log_flush_timeout (log_flush_timeout);
-
- 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)
+int
+io_stats_forget (xlator_t *this, fd_t *fd)
{
- int ret = -1;
+ BUMP_CBK (FORGET);
- if (!this)
- return ret;
-
- ret = xlator_mem_acct_init (this, gf_io_stats_mt_end + 1);
-
- if (ret != 0) {
- gf_log (this->name, GF_LOG_ERROR, "Memory accounting init"
- " failed");
- return ret;
- }
-
- return ret;
+ return 0;
}
-void
-ios_conf_destroy (struct ios_conf *conf)
-{
- if (!conf)
- return;
-
- ios_destroy_top_stats (conf);
- LOCK_DESTROY (&conf->lock);
- GF_FREE(conf);
-}
int
init (xlator_t *this)
{
+ dict_t *options = NULL;
struct ios_conf *conf = NULL;
- char *sys_log_str = NULL;
- char *logger_str = NULL;
- char *log_format_str = NULL;
- int logger = -1;
- int log_format = -1;
- int sys_log_level = -1;
- char *log_str = NULL;
- int log_level = -1;
- int ret = -1;
- uint32_t log_buf_size = 0;
- uint32_t log_flush_timeout = 0;
+ char *str = NULL;
+ int ret = 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;
}
if (!this->parents) {
- /* This is very much valid as io-stats currently is loaded
- * on top of volumes on both client and server, hence this is
- * not an warning message */
- gf_log (this->name, GF_LOG_DEBUG,
+ gf_log (this->name, GF_LOG_WARNING,
"dangling volume. check volfile ");
}
- conf = GF_CALLOC (1, sizeof(*conf), gf_io_stats_mt_ios_conf);
+ options = this->options;
- if (!conf)
- goto out;
+ conf = CALLOC (1, sizeof(*conf));
- /*
- * Init it just after calloc, so that we are sure the lock is inited
- * in case of error paths.
- */
LOCK_INIT (&conf->lock);
gettimeofday (&conf->cumulative.started_at, NULL);
gettimeofday (&conf->incremental.started_at, NULL);
- ret = ios_init_top_stats (conf);
- if (ret)
- goto out;
-
- GF_OPTION_INIT ("dump-fd-stats", conf->dump_fd_stats, bool, out);
-
- GF_OPTION_INIT ("count-fop-hits", conf->count_fop_hits, bool, out);
-
- GF_OPTION_INIT ("latency-measurement", conf->measure_latency,
- bool, out);
-
- 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);
- }
-
- 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);
- }
-
- GF_OPTION_INIT ("logger", logger_str, str, out);
- if (logger_str) {
- logger = gf_check_logger (logger_str);
- gf_log_set_logger (logger);
- }
+ ret = dict_get_str (options, "dump-fd-stats", &str);
+ if (ret == 0) {
+ ret = gf_string2boolean (str, &conf->dump_fd_stats);
+ if (ret == -1) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "'dump-fd-stats' takes only boolean arguments");
+ return -1;
+ }
- GF_OPTION_INIT ("log-format", log_format_str, str, out);
- if (log_format_str) {
- log_format = gf_check_log_format (log_format_str);
- gf_log_set_logformat (log_format);
+ if (conf->dump_fd_stats) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "enabling dump-fd-stats");
+ }
}
- GF_OPTION_INIT ("log-buf-size", log_buf_size, uint32, out);
- gf_log_set_log_buf_size (log_buf_size);
-
- GF_OPTION_INIT ("log-flush-timeout", log_flush_timeout, time, out);
- gf_log_set_log_flush_timeout (log_flush_timeout);
-
-
this->private = conf;
- ret = 0;
-out:
- if (!this->private) {
- ios_conf_destroy (conf);
- ret = -1;
- }
- return ret;
+ return 0;
}
+
void
fini (xlator_t *this)
{
@@ -2935,134 +1536,12 @@ fini (xlator_t *this)
return;
conf = this->private;
- this->private = NULL;
- ios_conf_destroy (conf);
- gf_log (this->name, GF_LOG_INFO,
+ gf_log (this->name, GF_LOG_NORMAL,
"io-stats translator unloaded");
return;
}
-int
-notify (xlator_t *this, int32_t event, void *data, ...)
-{
- int ret = 0;
- struct ios_dump_args args = {0};
- dict_t *output = NULL;
- dict_t *dict = NULL;
- int32_t op = 0;
- int32_t list_cnt = 0;
- double throughput = 0;
- double time = 0;
- gf_boolean_t is_peek = _gf_false;
- va_list ap;
-
- dict = data;
- va_start (ap, data);
- output = va_arg (ap, dict_t*);
- 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", 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", &op);
- if (!ret) {
- ret = dict_get_int32 (dict, "list-cnt", &list_cnt);
- if (op > IOS_STATS_TYPE_NONE &&
- op < IOS_STATS_TYPE_MAX)
- ret = io_stats_dump_stats_to_dict (this, output,
- op, list_cnt);
- if (op == IOS_STATS_TYPE_READ_THROUGHPUT ||
- op == IOS_STATS_TYPE_WRITE_THROUGHPUT) {
- ret = dict_get_double (dict, "throughput",
- &throughput);
- if (!ret) {
- ret = dict_get_double (dict, "time",
- &time);
- if (ret)
- goto out;
- ret = dict_set_double (output,
- "throughput", throughput);
- if (ret)
- goto out;
- ret = dict_set_double (output, "time",
- time);
- if (ret)
- goto out;
- }
- ret = 0;
-
- }
- } else {
- ret = dict_get_int32 (dict, "info-op", &op);
- if (ret || op < GF_CLI_INFO_ALL ||
- GF_CLI_INFO_CLEAR < op)
- op = GF_CLI_INFO_ALL;
-
- ret = dict_set_int32 (output, "info-op", op);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to set info-op in dict");
- goto out;
- }
-
- if (GF_CLI_INFO_CLEAR == op) {
- ret = io_stats_clear (this->private);
- if (ret)
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to clear info 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");
- }
- else {
- ret = dict_get_str_boolean (dict, "peek",
- _gf_false);
- if (-1 != ret)
- is_peek = ret;
-
- (void) ios_dump_args_init (&args,
- IOS_DUMP_TYPE_DICT, output);
- ret = io_stats_dump (this, &args, op, is_peek);
- }
- }
- break;
- default:
- default_notify (this, event, data);
- break;
-
- }
-out:
- return ret;
-}
-
-struct xlator_dumpops dumpops = {
- .priv = io_priv
-};
struct xlator_fops fops = {
.stat = io_stats_stat,
@@ -3084,9 +1563,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,
@@ -3100,147 +1576,27 @@ struct xlator_fops fops = {
.finodelk = io_stats_finodelk,
.entrylk = io_stats_entrylk,
.lookup = io_stats_lookup,
+ .setdents = io_stats_setdents,
+ .getdents = io_stats_getdents,
+ .checksum = io_stats_checksum,
.xattrop = io_stats_xattrop,
.fxattrop = io_stats_fxattrop,
.setattr = io_stats_setattr,
.fsetattr = io_stats_fsetattr,
- .fallocate = io_stats_fallocate,
- .discard = io_stats_discard,
- .zerofill = io_stats_zerofill,
+};
+
+struct xlator_mops mops = {
+ .stats = io_stats_stats,
};
struct xlator_cbks cbks = {
.release = io_stats_release,
.releasedir = io_stats_releasedir,
- .forget = io_stats_forget,
};
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", "INFO", "CRITICAL"}
- },
- { .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 = {"logger"},
- .type = GF_OPTION_TYPE_STR,
- .value = { GF_LOGGER_GLUSTER_LOG, GF_LOGGER_SYSLOG}
- },
- { .key = {"client-logger"},
- .type = GF_OPTION_TYPE_STR,
- .default_value = GF_LOGGER_GLUSTER_LOG,
- .description = "Changes the logging sub-system to log to, for the "
- "clients",
- .value = { GF_LOGGER_GLUSTER_LOG, GF_LOGGER_SYSLOG}
- },
- { .key = {"brick-logger"},
- .type = GF_OPTION_TYPE_STR,
- .default_value = GF_LOGGER_GLUSTER_LOG,
- .description = "Changes the logging sub-system to log to, for the "
- "bricks",
- .value = { GF_LOGGER_GLUSTER_LOG, GF_LOGGER_SYSLOG}
- },
- { .key = {"log-format"},
- .type = GF_OPTION_TYPE_STR,
- .value = { GF_LOG_FORMAT_NO_MSG_ID, GF_LOG_FORMAT_WITH_MSG_ID}
- },
- { .key = {"client-log-format"},
- .type = GF_OPTION_TYPE_STR,
- .default_value = GF_LOG_FORMAT_WITH_MSG_ID,
- .description = "Changes log format for the clients",
- .value = { GF_LOG_FORMAT_NO_MSG_ID, GF_LOG_FORMAT_WITH_MSG_ID}
- },
- { .key = {"brick-log-format"},
- .type = GF_OPTION_TYPE_STR,
- .default_value = GF_LOG_FORMAT_WITH_MSG_ID,
- .description = "Changes the log format for the bricks",
- .value = { GF_LOG_FORMAT_NO_MSG_ID, GF_LOG_FORMAT_WITH_MSG_ID}
- },
- { .key = {"log-buf-size"},
- .type = GF_OPTION_TYPE_INT,
- .min = GF_LOG_LRU_BUFSIZE_MIN,
- .max = GF_LOG_LRU_BUFSIZE_MAX,
- .default_value = "5",
- },
- { .key = {"client-log-buf-size"},
- .type = GF_OPTION_TYPE_INT,
- .min = GF_LOG_LRU_BUFSIZE_MIN,
- .max = GF_LOG_LRU_BUFSIZE_MAX,
- .default_value = "5",
- .description = "This option determines the maximum number of unique "
- "log messages that can be buffered for a time equal to"
- " the value of the option client-log-flush-timeout."
- },
- { .key = {"brick-log-buf-size"},
- .type = GF_OPTION_TYPE_INT,
- .min = GF_LOG_LRU_BUFSIZE_MIN,
- .max = GF_LOG_LRU_BUFSIZE_MAX,
- .default_value = "5",
- .description = "This option determines the maximum number of unique "
- "log messages that can be buffered for a time equal to"
- " the value of the option brick-log-flush-timeout."
- },
- { .key = {"log-flush-timeout"},
- .type = GF_OPTION_TYPE_TIME,
- .min = GF_LOG_FLUSH_TIMEOUT_MIN,
- .max = GF_LOG_FLUSH_TIMEOUT_MAX,
- .default_value = "120",
- },
- { .key = {"client-log-flush-timeout"},
- .type = GF_OPTION_TYPE_TIME,
- .min = GF_LOG_FLUSH_TIMEOUT_MIN,
- .max = GF_LOG_FLUSH_TIMEOUT_MAX,
- .default_value = "120",
- .description = "This option determines the maximum number of unique "
- "log messages that can be buffered for a time equal to"
- " the value of the option client-log-flush-timeout."
- },
- { .key = {"brick-log-flush-timeout"},
- .type = GF_OPTION_TYPE_TIME,
- .min = GF_LOG_FLUSH_TIMEOUT_MIN,
- .max = GF_LOG_FLUSH_TIMEOUT_MAX,
- .default_value = "120",
- .description = "This option determines the maximum number of unique "
- "log messages that can be buffered for a time equal to"
- " the value of the option brick-log-flush-timeout."
},
{ .key = {NULL} },
-
};
diff --git a/xlators/debug/trace/src/Makefile.am b/xlators/debug/trace/src/Makefile.am
index 7b2597b4db6..0f1679a049d 100644
--- a/xlators/debug/trace/src/Makefile.am
+++ b/xlators/debug/trace/src/Makefile.am
@@ -2,15 +2,13 @@
xlator_LTLIBRARIES = trace.la
xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/debug
-trace_la_LDFLAGS = -module -avoid-version
+trace_la_LDFLAGS = -module -avoidversion
trace_la_SOURCES = trace.c
trace_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la
-noinst_HEADERS = trace.h trace-mem-types.h
-AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src
-
-AM_CFLAGS = -Wall $(GF_CFLAGS)
+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/debug/trace/src/trace-mem-types.h b/xlators/debug/trace/src/trace-mem-types.h
deleted file mode 100644
index 9fa7d97c2ca..00000000000
--- a/xlators/debug/trace/src/trace-mem-types.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- Copyright (c) 2006-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 __TRACE_MEM_TYPES_H__
-#define __TRACE_MEM_TYPES_H__
-
-#include "mem-types.h"
-
-enum gf_trace_mem_types_ {
- gf_trace_mt_trace_conf_t = gf_common_mt_end + 1,
- gf_trace_mt_end
-};
-#endif
diff --git a/xlators/debug/trace/src/trace.c b/xlators/debug/trace/src/trace.c
index c1293127495..67ebeb13407 100644
--- a/xlators/debug/trace/src/trace.c
+++ b/xlators/debug/trace/src/trace.c
@@ -1,15 +1,26 @@
/*
- Copyright (c) 2006-2012 Red Hat, Inc. <http://www.redhat.com>
+ Copyright (c) 2006-2009 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 General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that 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 "trace.h"
-#include "trace-mem-types.h"
+#ifndef _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
/**
* xlators/debug/trace :
@@ -17,2944 +28,1979 @@
* their _cbk functions, which later passes the call to next layer.
* Very helpful translator for debugging.
*/
-#define TRACE_STAT_TO_STR(buf, str) trace_stat_to_str (buf, str, sizeof (str))
-static inline void
-trace_stat_to_str(struct iatt *buf, char *str, size_t len)
-{
- char atime_buf[256] = {0,};
- char mtime_buf[256] = {0,};
- char ctime_buf[256] = {0,};
- uint64_t ia_time = 0;
+#include <time.h>
+#include <errno.h>
+#include "glusterfs.h"
+#include "xlator.h"
+#include "common-utils.h"
- if (!buf)
- return;
+#define ERR_EINVAL_NORETURN(cond) \
+ do \
+ { \
+ if ((cond)) \
+ { \
+ gf_log ("ERROR", GF_LOG_ERROR, \
+ "%s: %s: (%s) is true", \
+ __FILE__, __FUNCTION__, #cond); \
+ } \
+ } while (0)
- 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));
+typedef struct trace_private {
+ int32_t debug_flag;
+} trace_private_t;
- snprintf (str, len,
- "gfid=%s ino=%"PRIu64", mode=%o, "
- "nlink=%"GF_PRI_NLINK", uid=%u, "
- "gid=%u, size=%"PRIu64", "
- "blocks=%"PRIu64", atime=%s, "
- "mtime=%s, ctime=%s",
- uuid_utoa (buf->ia_gfid),
- buf->ia_ino,
- st_mode_from_ia (buf->ia_prot, buf->ia_type),
- buf->ia_nlink, buf->ia_uid,
- buf->ia_gid, buf->ia_size,
- buf->ia_blocks, atime_buf,
- mtime_buf, ctime_buf);
-}
+struct {
+ char *name;
+ int enabled;
+} trace_fop_names[GF_FOP_MAXVALUE];
-int
-dump_history_trace (circular_buffer_t *cb, void *data)
+
+static char *
+trace_stat_to_str (struct stat *stbuf)
{
- char *string = NULL;
- struct tm *tm = NULL;
- char timestr[256] = {0,};
+ char *statstr = NULL;
+ char atime_buf[256] = {0,};
+ char mtime_buf[256] = {0,};
+ char ctime_buf[256] = {0,};
+ int asprint_ret_value = 0;
- string = (char *)cb->data;
- tm = localtime (&cb->tv.tv_sec);
+ strftime (atime_buf, 256, "[%b %d %H:%M:%S]",
+ localtime (&stbuf->st_atime));
+ strftime (mtime_buf, 256, "[%b %d %H:%M:%S]",
+ localtime (&stbuf->st_mtime));
+ strftime (ctime_buf, 256, "[%b %d %H:%M:%S]",
+ localtime (&stbuf->st_ctime));
- /* Since we are continuing with adding entries to the buffer even when
- gettimeofday () fails, it's safe to check tm and then dump the time
- at which the entry was added to the buffer */
- if (tm) {
- strftime (timestr, 256, "%Y-%m-%d %H:%M:%S", tm);
- snprintf (timestr + strlen (timestr), 256 - strlen (timestr),
- ".%"GF_PRI_SUSECONDS, cb->tv.tv_usec);
- gf_proc_dump_write ("TIME", "%s", timestr);
- }
+ asprint_ret_value = asprintf (&statstr,
+ "st_ino=%"PRIu64", st_mode=%o, st_nlink=%"GF_PRI_NLINK", "
+ "st_uid=%d, st_gid=%d, st_size=%"PRId64", st_blocks=%"PRId64
+ ", st_atime=%s, st_mtime=%s, st_ctime=%s",
+ stbuf->st_ino, stbuf->st_mode, stbuf->st_nlink, stbuf->st_uid,
+ stbuf->st_gid, stbuf->st_size, stbuf->st_blocks, atime_buf,
+ mtime_buf, ctime_buf);
- gf_proc_dump_write ("FOP", "%s\n", string);
+ if (asprint_ret_value < 0)
+ statstr = NULL;
- return 0;
+ return statstr;
}
+
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)
+ inode_t *inode, struct stat *buf,
+ struct stat *preparent, struct stat *postparent)
{
- char statstr[4096] = {0, };
- char preparentstr[4096] = {0, };
- char postparentstr[4096] = {0, };
- trace_conf_t *conf = NULL;
-
- conf = this->private;
+ char *statstr = NULL;
+ char *preparentstr = NULL;
+ char *postparentstr = NULL;
- if (!conf->log_file && !conf->log_history)
- goto out;
if (trace_fop_names[GF_FOP_CREATE].enabled) {
- char string[4096] = {0,};
if (op_ret >= 0) {
- TRACE_STAT_TO_STR (buf, statstr);
- TRACE_STAT_TO_STR (preparent, preparentstr);
- TRACE_STAT_TO_STR (postparent, postparentstr);
-
- snprintf (string, sizeof (string),
- "%"PRId64": gfid=%s (op_ret=%d, fd=%p"
- "*stbuf {%s}, *preparent {%s}, "
- "*postparent = {%s})",
- frame->root->unique,
- uuid_utoa (inode->gfid), op_ret, fd,
- statstr, preparentstr, postparentstr);
-
- /* for 'release' log */
- fd_ctx_set (fd, this, 0);
+ statstr = trace_stat_to_str (buf);
+ preparentstr = trace_stat_to_str (preparent);
+ postparentstr = trace_stat_to_str (postparent);
+
+ gf_log (this->name, GF_LOG_NORMAL,
+ "%"PRId64": (op_ret=%d, fd=%p, ino=%"PRIu64" "
+ "*stbuf {%s}, *preparent {%s}, *postparent = "
+ "{%s})",
+ frame->root->unique, op_ret, fd, inode->ino,
+ statstr, preparentstr, postparentstr);
+
+ if (statstr)
+ FREE (statstr);
+ if (preparentstr)
+ FREE (preparentstr);
+ if (postparentstr)
+ FREE (postparentstr);
} else {
- snprintf (string, sizeof (string),
- "%"PRId64": (op_ret=%d, op_errno=%d)",
- frame->root->unique, op_ret,
- op_errno);
+ gf_log (this->name, GF_LOG_NORMAL,
+ "%"PRId64": (op_ret=%d, op_errno=%d)",
+ frame->root->unique, op_ret, op_errno);
}
- LOG_ELEMENT (conf, string);
}
-out:
- TRACE_STACK_UNWIND (create, frame, op_ret, op_errno, fd, inode, buf,
- preparent, postparent, xdata);
+
+ STACK_UNWIND_STRICT (create, frame, op_ret, op_errno, fd, inode, buf,
+ 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)
{
- trace_conf_t *conf = NULL;
- conf = this->private;
-
- if (!conf->log_file && !conf->log_history)
- goto out;
if (trace_fop_names[GF_FOP_OPEN].enabled) {
- char string[4096] = {0,};
- snprintf (string, sizeof (string),
- "%"PRId64": gfid=%s op_ret=%d, op_errno=%d, "
- "*fd=%p", frame->root->unique,
- uuid_utoa (frame->local), op_ret, op_errno,
- fd);
-
- LOG_ELEMENT (conf, string);
+ gf_log (this->name, GF_LOG_NORMAL,
+ "%"PRId64": (op_ret=%d, op_errno=%d, *fd=%p)",
+ frame->root->unique, op_ret, op_errno, fd);
}
-out:
- /* for 'release' log */
- if (op_ret >= 0)
- fd_ctx_set (fd, this, 0);
-
- TRACE_STACK_UNWIND (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 stat *buf)
{
- char statstr[4096] = {0, };
- trace_conf_t *conf = NULL;
+ char atime_buf[256];
+ char mtime_buf[256];
+ char ctime_buf[256];
- conf = this->private;
- if (!conf->log_file && !conf->log_history)
- goto out;
if (trace_fop_names[GF_FOP_STAT].enabled) {
- char string[4096] = {0,};
- if (op_ret == 0) {
- TRACE_STAT_TO_STR (buf, statstr);
- snprintf (string, sizeof (string),
- "%"PRId64": gfid=%s op_ret=%d buf=%s",
- frame->root->unique,
- uuid_utoa (frame->local), op_ret,
- statstr);
+ if (op_ret >= 0) {
+ strftime (atime_buf, 256, "[%b %d %H:%M:%S]", localtime (&buf->st_atime));
+ strftime (mtime_buf, 256, "[%b %d %H:%M:%S]", localtime (&buf->st_mtime));
+ strftime (ctime_buf, 256, "[%b %d %H:%M:%S]", localtime (&buf->st_ctime));
+
+ gf_log (this->name, GF_LOG_NORMAL,
+ "%"PRId64": (op_ret=%d, buf {st_dev=%"GF_PRI_DEV", "
+ "st_ino=%"PRIu64", st_mode=%o, st_nlink=%"GF_PRI_NLINK", "
+ "st_uid=%d, st_gid=%d, st_rdev=%"GF_PRI_DEV", st_size=%"PRId64
+ ", st_blksize=%"GF_PRI_BLKSIZE", st_blocks=%"PRId64", "
+ "st_atime=%s, st_mtime=%s, st_ctime=%s})",
+ frame->root->unique, op_ret, buf->st_dev, buf->st_ino,
+ buf->st_mode, buf->st_nlink, buf->st_uid, buf->st_gid,
+ buf->st_rdev, buf->st_size, buf->st_blksize,
+ buf->st_blocks, atime_buf, mtime_buf, ctime_buf);
} else {
- snprintf (string, sizeof (string),
- "%"PRId64": gfid=%s op_ret=%d, "
- "op_errno=%d)",
- frame->root->unique,
- uuid_utoa (frame->local), op_ret,
- op_errno);
+ gf_log (this->name, GF_LOG_NORMAL,
+ "%"PRId64": (op_ret=%d, op_errno=%d)",
+ frame->root->unique, op_ret, op_errno);
}
- LOG_ELEMENT (conf, string);
}
-out:
- TRACE_STACK_UNWIND (stat, frame, op_ret, op_errno, buf, xdata);
+
+ STACK_UNWIND_STRICT (stat, frame, op_ret, op_errno, buf);
return 0;
}
+
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 stat *buf, struct iobref *iobref)
{
- char statstr[4096] = {0, };
- trace_conf_t *conf = NULL;
-
- conf = this->private;
+ char atime_buf[256];
+ char mtime_buf[256];
+ char ctime_buf[256];
- if (!conf->log_file && !conf->log_history)
- goto out;
if (trace_fop_names[GF_FOP_READ].enabled) {
- char string[4096] = {0,};
if (op_ret >= 0) {
- TRACE_STAT_TO_STR (buf, statstr);
- snprintf (string, sizeof (string),
- "%"PRId64": gfid=%s op_ret=%d buf=%s",
- frame->root->unique,
- uuid_utoa (frame->local), op_ret,
- statstr);
+ strftime (atime_buf, 256, "[%b %d %H:%M:%S]", localtime (&buf->st_atime));
+ strftime (mtime_buf, 256, "[%b %d %H:%M:%S]", localtime (&buf->st_mtime));
+ strftime (ctime_buf, 256, "[%b %d %H:%M:%S]", localtime (&buf->st_ctime));
+
+ gf_log (this->name, GF_LOG_NORMAL,
+ "%"PRId64": (op_ret=%d, *buf {st_dev=%"GF_PRI_DEV", "
+ "st_ino=%"PRIu64", st_mode=%o, st_nlink=%"GF_PRI_NLINK", "
+ "st_uid=%d, st_gid=%d, st_rdev=%"GF_PRI_DEV", "
+ "st_size=%"PRId64", st_blksize=%"GF_PRI_BLKSIZE", "
+ "st_blocks=%"PRId64", st_atime=%s, st_mtime=%s, st_ctime=%s})",
+ frame->root->unique, op_ret, buf->st_dev, buf->st_ino,
+ buf->st_mode, buf->st_nlink, buf->st_uid, buf->st_gid,
+ buf->st_rdev, buf->st_size, buf->st_blksize, buf->st_blocks,
+ atime_buf, mtime_buf, ctime_buf);
} else {
- snprintf (string, sizeof (string),
- "%"PRId64": gfid=%s op_ret=%d, "
- "op_errno=%d)",
- frame->root->unique,
- uuid_utoa (frame->local), op_ret,
- op_errno);
+ gf_log (this->name, GF_LOG_NORMAL,
+ "%"PRId64": (op_ret=%d, op_errno=%d)",
+ frame->root->unique, op_ret, op_errno);
}
- LOG_ELEMENT (conf, string);
}
-out:
- TRACE_STACK_UNWIND (readv, frame, op_ret, op_errno, vector, count,
- buf, iobref, xdata);
+
+ STACK_UNWIND_STRICT (readv, frame, op_ret, op_errno, vector, count,
+ buf, iobref);
return 0;
}
+
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 stat *prebuf, struct stat *postbuf)
{
- char preopstr[4096] = {0, };
- char postopstr[4096] = {0, };
- trace_conf_t *conf = NULL;
+ char *preopstr = NULL;
+ char *postopstr = NULL;
- conf = this->private;
-
- if (!conf->log_file && !conf->log_history)
- goto out;
if (trace_fop_names[GF_FOP_WRITE].enabled) {
- char string[4096] = {0,};
if (op_ret >= 0) {
- TRACE_STAT_TO_STR (prebuf, preopstr);
- TRACE_STAT_TO_STR (postbuf, postopstr);
-
- snprintf (string, sizeof (string),
- "%"PRId64": (op_ret=%d, "
- "*prebuf = {%s}, *postbuf = {%s})",
- frame->root->unique, op_ret,
- preopstr, postopstr);
+ preopstr = trace_stat_to_str (prebuf);
+ preopstr = trace_stat_to_str (postbuf);
+
+ gf_log (this->name, GF_LOG_NORMAL,
+ "%"PRId64": (op_ret=%d, ino = %"PRIu64
+ ", *prebuf = {%s}, *postbuf = {%s})",
+ frame->root->unique, op_ret, postbuf->st_ino,
+ preopstr, postopstr);
+
+ if (preopstr)
+ FREE (preopstr);
+
+ if (postopstr)
+ FREE (postopstr);
} else {
- snprintf (string, sizeof (string),
- "%"PRId64": gfid=%s op_ret=%d, "
- "op_errno=%d", frame->root->unique,
- uuid_utoa (frame->local), op_ret,
- op_errno);
+ gf_log (this->name, GF_LOG_NORMAL,
+ "%"PRId64": (op_ret=%d, op_errno=%d)",
+ frame->root->unique, op_ret, op_errno);
}
- LOG_ELEMENT (conf, string);
}
-out:
- TRACE_STACK_UNWIND (writev, frame, op_ret, op_errno, prebuf, postbuf,
- xdata);
+
+ STACK_UNWIND_STRICT (writev, frame, op_ret, op_errno, prebuf, postbuf);
return 0;
}
+
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)
+trace_getdents_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dir_entry_t *entries,
+ int32_t count)
{
- trace_conf_t *conf = NULL;
+ if (trace_fop_names[GF_FOP_GETDENTS].enabled) {
+ gf_log (this->name, GF_LOG_NORMAL,
+ "%"PRId64": (op_ret=%d, op_errno=%d, count=%d)",
+ frame->root->unique, op_ret, op_errno, count);
+ }
- conf = this->private;
+ STACK_UNWIND_STRICT (getdents, frame, op_ret, op_errno, entries, count);
+ return 0;
+}
- if (!conf->log_file && !conf->log_history)
- goto out;
- if (trace_fop_names[GF_FOP_READDIR].enabled) {
- char string[4096] = {0,};
- snprintf (string, sizeof (string),
- "%"PRId64" : gfid=%s op_ret=%d, op_errno=%d",
- frame->root->unique, uuid_utoa (frame->local),
- op_ret, op_errno);
- LOG_ELEMENT (conf, string);
+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)
+{
+ if (trace_fop_names[GF_FOP_READDIR].enabled) {
+ gf_log (this->name, GF_LOG_NORMAL,
+ "%"PRId64" :(op_ret=%d, op_errno=%d)",
+ frame->root->unique, op_ret, op_errno);
}
-out:
- TRACE_STACK_UNWIND (readdir, frame, op_ret, op_errno, buf, xdata);
+
+ STACK_UNWIND_STRICT (readdir, frame, op_ret, op_errno, buf);
return 0;
}
+
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)
{
- trace_conf_t *conf = NULL;
-
- conf = this->private;
-
- if (!conf->log_file && !conf->log_history)
- goto out;
if (trace_fop_names[GF_FOP_READDIRP].enabled) {
- char string[4096] = {0,};
- snprintf (string, sizeof (string),
- "%"PRId64" : gfid=%s op_ret=%d, op_errno=%d",
- frame->root->unique, uuid_utoa (frame->local),
- op_ret, op_errno);
-
- LOG_ELEMENT (conf, string);
+ gf_log (this->name, GF_LOG_NORMAL,
+ "%"PRId64" :(op_ret=%d, op_errno=%d)",
+ frame->root->unique, op_ret, op_errno);
}
-out:
- TRACE_STACK_UNWIND (readdirp, frame, op_ret, op_errno, buf, xdata);
+ STACK_UNWIND_STRICT (readdirp, frame, op_ret, op_errno, buf);
+
return 0;
}
+
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 stat *prebuf, struct stat *postbuf)
{
- char preopstr[4096] = {0, };
- char postopstr[4096] = {0, };
- trace_conf_t *conf = NULL;
-
- conf = this->private;
+ char *preopstr = NULL;
+ char *postopstr = NULL;
- if (!conf->log_file && !conf->log_history)
- goto out;
if (trace_fop_names[GF_FOP_FSYNC].enabled) {
- char string[4096] = {0,};
- if (op_ret == 0) {
- TRACE_STAT_TO_STR (prebuf, preopstr);
- TRACE_STAT_TO_STR (postbuf, postopstr);
-
- snprintf (string, sizeof (string),
- "%"PRId64": (op_ret=%d, "
- "*prebuf = {%s}, *postbuf = {%s}",
- frame->root->unique, op_ret,
- preopstr, postopstr);
- } else {
- snprintf (string, sizeof (string),
- "%"PRId64": gfid=%s op_ret=%d, "
- "op_errno=%d", frame->root->unique,
- uuid_utoa (frame->local), op_ret,
- op_errno);
+ if (op_ret >= 0) {
+ preopstr = trace_stat_to_str (prebuf);
+ preopstr = trace_stat_to_str (postbuf);
+ gf_log (this->name, GF_LOG_NORMAL,
+ "%"PRId64": (op_ret=%d, ino = %"PRIu64
+ ", *prebuf = {%s}, *postbuf = {%s}",
+ frame->root->unique, op_ret, postbuf->st_ino,
+ preopstr, postopstr);
+
+ if (preopstr)
+ FREE (preopstr);
+
+ if (postopstr)
+ FREE (postopstr);
+ } else {
+ gf_log (this->name, GF_LOG_NORMAL,
+ "%"PRId64": (op_ret=%d, op_errno=%d)",
+ frame->root->unique, op_ret, op_errno);
}
- LOG_ELEMENT (conf, string);
}
-out:
- TRACE_STACK_UNWIND (fsync, frame, op_ret, op_errno, prebuf, postbuf,
- xdata);
+
+ STACK_UNWIND_STRICT (fsync, frame, op_ret, op_errno, prebuf, postbuf);
return 0;
}
+
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 stat *statpre, struct stat *statpost)
{
- char preopstr[4096] = {0, };
- char postopstr[4096] = {0, };
- trace_conf_t *conf = NULL;
+ char atime_pre[256] = {0,};
+ char mtime_pre[256] = {0,};
+ char ctime_pre[256] = {0,};
+ char atime_post[256] = {0,};
+ char mtime_post[256] = {0,};
+ char ctime_post[256] = {0,};
- conf = this->private;
-
- if (!conf->log_file && !conf->log_history)
- goto out;
if (trace_fop_names[GF_FOP_SETATTR].enabled) {
- char string[4096] = {0,};
- if (op_ret == 0) {
- TRACE_STAT_TO_STR (statpre, preopstr);
- TRACE_STAT_TO_STR (statpost, postopstr);
-
- snprintf (string, sizeof (string),
- "%"PRId64": (op_ret=%d, "
- "*prebuf = {%s}, *postbuf = {%s})",
- frame->root->unique, op_ret,
- preopstr, postopstr);
+ if (op_ret >= 0) {
+ strftime (atime_pre, 256, "[%b %d %H:%M:%S]",
+ localtime (&statpre->st_atime));
+ strftime (mtime_pre, 256, "[%b %d %H:%M:%S]",
+ localtime (&statpre->st_mtime));
+ strftime (ctime_pre, 256, "[%b %d %H:%M:%S]",
+ localtime (&statpre->st_ctime));
+
+ strftime (atime_post, 256, "[%b %d %H:%M:%S]",
+ localtime (&statpost->st_atime));
+ strftime (mtime_post, 256, "[%b %d %H:%M:%S]",
+ localtime (&statpost->st_mtime));
+ strftime (ctime_post, 256, "[%b %d %H:%M:%S]",
+ localtime (&statpost->st_ctime));
+
+ gf_log (this->name, GF_LOG_NORMAL,
+ "%"PRId64": (op_ret=%d, *statpre "
+ "{st_ino=%"PRIu64", st_mode=%o, st_uid=%d, "
+ "st_gid=%d, st_atime=%s, st_mtime=%s, "
+ "st_ctime=%s}, *statpost {st_ino=%"PRIu64", "
+ "st_mode=%o, st_uid=%d, st_gid=%d, st_atime=%s,"
+ " st_mtime=%s, st_ctime=%s})",
+ frame->root->unique, op_ret, statpre->st_ino,
+ statpre->st_mode, statpre->st_uid,
+ statpre->st_gid, atime_pre, mtime_pre,
+ ctime_pre, statpost->st_ino, statpost->st_mode,
+ statpost->st_uid, statpost->st_gid, atime_post,
+ mtime_post, ctime_post);
} else {
- snprintf (string, sizeof (string),
- "%"PRId64": gfid=%s op_ret=%d, "
- "op_errno=%d)", frame->root->unique,
- uuid_utoa (frame->local), op_ret,
- op_errno);
+ gf_log (this->name, GF_LOG_NORMAL,
+ "%"PRId64": (op_ret=%d, op_errno=%d)",
+ frame->root->unique, op_ret, op_errno);
}
- LOG_ELEMENT (conf, string);
}
-out:
- TRACE_STACK_UNWIND (setattr, frame, op_ret, op_errno, statpre,
- statpost, xdata);
+
+ STACK_UNWIND_STRICT (setattr, frame, op_ret, op_errno, statpre, statpost);
return 0;
}
+
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 stat *statpre, struct stat *statpost)
{
- char preopstr[4096] = {0, };
- char postopstr[4096] = {0, };
- trace_conf_t *conf = NULL;
-
- conf = this->private;
+ char atime_pre[256] = {0,};
+ char mtime_pre[256] = {0,};
+ char ctime_pre[256] = {0,};
+ char atime_post[256] = {0,};
+ char mtime_post[256] = {0,};
+ char ctime_post[256] = {0,};
- if (!conf->log_file && !conf->log_history)
- goto out;
if (trace_fop_names[GF_FOP_FSETATTR].enabled) {
- char string[4096] = {0,};
- if (op_ret == 0) {
- TRACE_STAT_TO_STR (statpre, preopstr);
- TRACE_STAT_TO_STR (statpost, postopstr);
-
- snprintf (string, sizeof (string),
- "%"PRId64": (op_ret=%d, "
- "*prebuf = {%s}, *postbuf = {%s})",
- frame->root->unique, op_ret,
- preopstr, postopstr);
+ if (op_ret >= 0) {
+ strftime (atime_pre, 256, "[%b %d %H:%M:%S]",
+ localtime (&statpre->st_atime));
+ strftime (mtime_pre, 256, "[%b %d %H:%M:%S]",
+ localtime (&statpre->st_mtime));
+ strftime (ctime_pre, 256, "[%b %d %H:%M:%S]",
+ localtime (&statpre->st_ctime));
+
+ strftime (atime_post, 256, "[%b %d %H:%M:%S]",
+ localtime (&statpost->st_atime));
+ strftime (mtime_post, 256, "[%b %d %H:%M:%S]",
+ localtime (&statpost->st_mtime));
+ strftime (ctime_post, 256, "[%b %d %H:%M:%S]",
+ localtime (&statpost->st_ctime));
+
+ gf_log (this->name, GF_LOG_NORMAL,
+ "%"PRId64": (op_ret=%d, *statpre "
+ "{st_ino=%"PRIu64", st_mode=%o, st_uid=%d, "
+ "st_gid=%d, st_atime=%s, st_mtime=%s, "
+ "st_ctime=%s}, *statpost {st_ino=%"PRIu64", "
+ "st_mode=%o, st_uid=%d, st_gid=%d, st_atime=%s,"
+ " st_mtime=%s, st_ctime=%s})",
+ frame->root->unique, op_ret, statpre->st_ino,
+ statpre->st_mode, statpre->st_uid,
+ statpre->st_gid, atime_pre, mtime_pre,
+ ctime_pre, statpost->st_ino, statpost->st_mode,
+ statpost->st_uid, statpost->st_gid, atime_post,
+ mtime_post, ctime_post);
} else {
- snprintf (string, sizeof (string),
- "%"PRId64": gfid=%s op_ret=%d, op_errno=%d)",
- frame->root->unique, uuid_utoa (frame->local),
- op_ret, op_errno);
+ gf_log (this->name, GF_LOG_NORMAL,
+ "%"PRId64": (op_ret=%d, op_errno=%d)",
+ frame->root->unique, op_ret, op_errno);
}
- LOG_ELEMENT (conf, string);
}
-out:
- TRACE_STACK_UNWIND (fsetattr, frame, op_ret, op_errno,
- statpre, statpost, xdata);
+
+ STACK_UNWIND_STRICT (fsetattr, frame, op_ret, op_errno,
+ statpre, statpost);
return 0;
}
+
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 stat *preparent, struct stat *postparent)
{
- char preparentstr[4096] = {0, };
- char postparentstr[4096] = {0, };
- trace_conf_t *conf = NULL;
+ char *preparentstr = NULL;
+ char *postparentstr = NULL;
- conf = this->private;
-
- if (!conf->log_file && !conf->log_history)
- goto out;
if (trace_fop_names[GF_FOP_UNLINK].enabled) {
- char string[4096] = {0,};
- if (op_ret == 0) {
- TRACE_STAT_TO_STR (preparent, preparentstr);
- TRACE_STAT_TO_STR (postparent, postparentstr);
-
- snprintf (string, sizeof (string),
- "%"PRId64": gfid=%s op_ret=%d, "
- " *preparent = {%s}, "
- "*postparent = {%s})",
- frame->root->unique,
- uuid_utoa (frame->local),
- op_ret, preparentstr,
- postparentstr);
+ if (op_ret >= 0) {
+ preparentstr = trace_stat_to_str (preparent);
+ postparentstr = trace_stat_to_str (postparent);
+
+ gf_log (this->name, GF_LOG_NORMAL,
+ "%"PRId64": (op_ret=%d, *preparent = {%s}, "
+ "*postparent = {%s})",
+ frame->root->unique, op_ret, preparentstr,
+ postparentstr);
+
+ if (preparentstr)
+ FREE (preparentstr);
+
+ if (postparentstr)
+ FREE (postparentstr);
} else {
- snprintf (string, sizeof (string),
- "%"PRId64": gfid=%s op_ret=%d, "
- "op_errno=%d)",
- frame->root->unique,
- uuid_utoa (frame->local), op_ret,
- op_errno);
+ gf_log (this->name, GF_LOG_NORMAL,
+ "%"PRId64": (op_ret=%d, op_errno=%d)",
+ frame->root->unique, op_ret, op_errno);
}
- LOG_ELEMENT (conf, string);
}
-out:
- TRACE_STACK_UNWIND (unlink, frame, op_ret, op_errno,
- preparent, postparent, xdata);
+
+ STACK_UNWIND_STRICT (unlink, frame, op_ret, op_errno,
+ preparent, postparent);
return 0;
}
+
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)
-{
- char statstr[4096] = {0, };
- char preoldparentstr[4096] = {0, };
- char postoldparentstr[4096] = {0, };
- char prenewparentstr[4096] = {0, };
- char postnewparentstr[4096] = {0, };
- trace_conf_t *conf = NULL;
-
- conf = this->private;
-
- if (!conf->log_file && !conf->log_history)
- goto out;
+ int32_t op_ret, int32_t op_errno, struct stat *buf,
+ struct stat *preoldparent, struct stat *postoldparent,
+ struct stat *prenewparent, struct stat *postnewparent)
+{
+ char *statstr = NULL;
+ char *preoldparentstr = NULL;
+ char *postoldparentstr = NULL;
+ char *prenewparentstr = NULL;
+ char *postnewparentstr = NULL;
+
if (trace_fop_names[GF_FOP_RENAME].enabled) {
- char string[4096] = {0,};
- if (op_ret == 0) {
- TRACE_STAT_TO_STR (buf, statstr);
- TRACE_STAT_TO_STR (preoldparent, preoldparentstr);
- TRACE_STAT_TO_STR (postoldparent, postoldparentstr);
- TRACE_STAT_TO_STR (prenewparent, prenewparentstr);
- TRACE_STAT_TO_STR (postnewparent, postnewparentstr);
-
- snprintf (string, sizeof (string),
- "%"PRId64": (op_ret=%d, "
- "*stbuf = {%s}, *preoldparent = {%s},"
- " *postoldparent = {%s}"
- " *prenewparent = {%s}, "
- "*postnewparent = {%s})",
- frame->root->unique, op_ret, statstr,
- preoldparentstr, postoldparentstr,
- prenewparentstr, postnewparentstr);
- } else {
- snprintf (string, sizeof (string),
- "%"PRId64": gfid=%s op_ret=%d, "
- "op_errno=%d", frame->root->unique,
- uuid_utoa (frame->local),
- op_ret, op_errno);
+ if (op_ret >= 0) {
+ statstr = trace_stat_to_str (buf);
+ preoldparentstr = trace_stat_to_str (preoldparent);
+ postoldparentstr = trace_stat_to_str (postoldparent);
+ prenewparentstr = trace_stat_to_str (prenewparent);
+ postnewparentstr = trace_stat_to_str (postnewparent);
+
+ gf_log (this->name, GF_LOG_NORMAL,
+ "%"PRId64": (op_ret=%d, *stbuf = {%s}, "
+ "*preoldparent = {%s}, *postoldparent = {%s}"
+ " *prenewparent = {%s}, *postnewparent = {%s})",
+ frame->root->unique, op_ret, statstr,
+ preoldparentstr, postoldparentstr,
+ prenewparentstr, postnewparentstr);
+
+ if (preoldparentstr)
+ FREE (preoldparentstr);
+
+ if (postoldparentstr)
+ FREE (postoldparentstr);
+
+ if (prenewparentstr)
+ FREE (prenewparentstr);
+
+ if (postnewparentstr)
+ FREE (postnewparentstr);
+ } else {
+ gf_log (this->name, GF_LOG_NORMAL,
+ "%"PRId64": (op_ret=%d, op_errno=%d)",
+ frame->root->unique, op_ret, op_errno);
}
- LOG_ELEMENT (conf, string);
+ gf_log (this->name, GF_LOG_NORMAL,
+ "%"PRId64": (op_ret=%d, op_errno=%d, buf {st_ino=%"PRIu64"})",
+ frame->root->unique, op_ret, op_errno,
+ (buf? buf->st_ino : 0));
}
-out:
- TRACE_STACK_UNWIND (rename, frame, op_ret, op_errno, buf,
- preoldparent, postoldparent,
- prenewparent, postnewparent, xdata);
+
+ STACK_UNWIND_STRICT (rename, frame, op_ret, op_errno, buf,
+ preoldparent, postoldparent,
+ prenewparent, postnewparent);
return 0;
}
+
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 stat *stbuf)
{
- char statstr[4096] = {0, };
- trace_conf_t *conf = NULL;
+ char *statstr = NULL;
- conf = this->private;
-
- if (!conf->log_file && !conf->log_history)
- goto out;
if (trace_fop_names[GF_FOP_READLINK].enabled) {
- char string[4096] = {0,};
- if (op_ret == 0) {
- TRACE_STAT_TO_STR (stbuf, statstr);
- snprintf (string, sizeof (string),
- "%"PRId64": (op_ret=%d, op_errno=%d,"
- "buf=%s, stbuf = { %s })",
- frame->root->unique, op_ret, op_errno,
- buf, statstr);
- } else {
- snprintf (string, sizeof (string),
- "%"PRId64": gfid=%s op_ret=%d, "
- "op_errno=%d",
- frame->root->unique,
- uuid_utoa (frame->local), op_ret,
- op_errno);
- }
+ statstr = trace_stat_to_str (stbuf);
+
+ gf_log (this->name, GF_LOG_NORMAL,
+ "%"PRId64": (op_ret=%d, op_errno=%d, buf=%s, "
+ "stbuf = { %s })",
+ frame->root->unique, op_ret, op_errno, buf, statstr);
- LOG_ELEMENT (conf, string);
+ if (statstr)
+ FREE (statstr);
}
-out:
- TRACE_STACK_UNWIND (readlink, frame, op_ret, op_errno, buf, stbuf,
- xdata);
+
+ STACK_UNWIND_STRICT (readlink, frame, op_ret, op_errno, buf, stbuf);
return 0;
}
+
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)
+ inode_t *inode, struct stat *buf,
+ dict_t *xattr, struct stat *postparent)
{
- char statstr[4096] = {0, };
- char postparentstr[4096] = {0, };
- trace_conf_t *conf = NULL;
-
- conf = this->private;
+ char *statstr = NULL;
+ char *postparentstr = NULL;
- if (!conf->log_file && !conf->log_history)
- goto out;
if (trace_fop_names[GF_FOP_LOOKUP].enabled) {
- char string[4096] = {0,};
- if (op_ret == 0) {
- TRACE_STAT_TO_STR (buf, statstr);
- TRACE_STAT_TO_STR (postparent, postparentstr);
- /* print buf->ia_gfid instead of inode->gfid,
- * since if the inode is not yet linked to the
- * inode table (fresh lookup) then null gfid
- * will be printed.
- */
- snprintf (string, sizeof (string),
- "%"PRId64": gfid=%s (op_ret=%d "
- "*buf {%s}, *postparent {%s}",
- frame->root->unique,
- uuid_utoa (buf->ia_gfid),
- op_ret, statstr, postparentstr);
-
- /* For 'forget' */
- inode_ctx_put (inode, this, 0);
+ if (op_ret >= 0) {
+ statstr = trace_stat_to_str (buf);
+ postparentstr = trace_stat_to_str (buf);
+
+ gf_log (this->name, GF_LOG_NORMAL,
+ "%"PRId64": (op_ret=%d, ino=%"PRIu64", "
+ "*buf {%s}, *postparent {%s}",
+ frame->root->unique, op_ret, inode->ino,
+ statstr, postparentstr);
+
+ if (statstr)
+ FREE (statstr);
+ if (postparentstr)
+ FREE (postparentstr);
} else {
- snprintf (string, sizeof (string),
- "%"PRId64": gfid=%s op_ret=%d, "
- "op_errno=%d)",
- frame->root->unique,
- uuid_utoa (frame->local), op_ret,
- op_errno);
+ gf_log (this->name, GF_LOG_NORMAL,
+ "%"PRId64": (op_ret=%d, op_errno=%d)",
+ frame->root->unique, op_ret, op_errno);
}
- LOG_ELEMENT (conf, string);
}
-out:
- TRACE_STACK_UNWIND (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
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)
+ inode_t *inode, struct stat *buf,
+ struct stat *preparent, struct stat *postparent)
{
- char statstr[4096] = {0, };
- char preparentstr[4096] = {0, };
- char postparentstr[4096] = {0, };
- trace_conf_t *conf = NULL;
+ char *statstr = NULL;
+ char *preparentstr = NULL;
+ char *postparentstr = NULL;
- conf = this->private;
-
- if (!conf->log_file && !conf->log_history)
- goto out;
if (trace_fop_names[GF_FOP_SYMLINK].enabled) {
- char string[4096] = {0,};
- if (op_ret == 0) {
- TRACE_STAT_TO_STR (buf, statstr);
- TRACE_STAT_TO_STR (preparent, preparentstr);
- TRACE_STAT_TO_STR (postparent, postparentstr);
-
- snprintf (string, sizeof (string),
- "%"PRId64": gfid=%s (op_ret=%d "
- "*stbuf = {%s}, *preparent = {%s}, "
- "*postparent = {%s})",
- frame->root->unique,
- uuid_utoa (inode->gfid),
- op_ret, statstr, preparentstr,
- postparentstr);
+ if (op_ret >= 0) {
+ statstr = trace_stat_to_str (buf);
+ preparentstr = trace_stat_to_str (preparent);
+ postparentstr = trace_stat_to_str (postparent);
+
+ gf_log (this->name, GF_LOG_NORMAL,
+ "%"PRId64": (op_ret=%d, ino=%"PRIu64", "
+ "*stbuf = {%s}, *preparent = {%s}, "
+ "*postparent = {%s})",
+ frame->root->unique, op_ret, inode->ino,
+ statstr, preparentstr, postparentstr);
+
+ if (statstr)
+ FREE (statstr);
+
+ if (preparentstr)
+ FREE (preparentstr);
+
+ if (postparentstr)
+ FREE (postparentstr);
+
} else {
- snprintf (string, sizeof (string),
- "%"PRId64": op_ret=%d, op_errno=%d",
- frame->root->unique, op_ret,
- op_errno);
+ gf_log (this->name, GF_LOG_NORMAL,
+ "%"PRId64": (op_ret=%d, op_errno=%d)",
+ frame->root->unique, op_ret, op_errno);
}
- LOG_ELEMENT (conf, string);
}
-out:
- TRACE_STACK_UNWIND (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
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)
+ inode_t *inode, struct stat *buf,
+ struct stat *preparent, struct stat *postparent)
{
- char statstr[4096] = {0, };
- char preparentstr[4096] = {0, };
- char postparentstr[4096] = {0, };
- trace_conf_t *conf = NULL;
-
- conf = this->private;
+ char *statstr = NULL;
+ char *preparentstr = NULL;
+ char *postparentstr = NULL;
- if (!conf->log_file && !conf->log_history)
- goto out;
- char string[4096] = {0,};
if (trace_fop_names[GF_FOP_MKNOD].enabled) {
- if (op_ret == 0) {
- TRACE_STAT_TO_STR (buf, statstr);
- TRACE_STAT_TO_STR (preparent, preparentstr);
- TRACE_STAT_TO_STR (postparent, postparentstr);
-
- snprintf (string, sizeof (string),
- "%"PRId64": gfid=%s (op_ret=%d "
- "*stbuf = {%s}, *preparent = {%s}, "
- "*postparent = {%s})",
- frame->root->unique,
- uuid_utoa (inode->gfid),
- op_ret, statstr, preparentstr,
- postparentstr);
+ if (op_ret >= 0) {
+ statstr = trace_stat_to_str (buf);
+ preparentstr = trace_stat_to_str (preparent);
+ postparentstr = trace_stat_to_str (postparent);
+
+ gf_log (this->name, GF_LOG_NORMAL,
+ "%"PRId64": (op_ret=%d, ino=%"PRIu64", "
+ "*stbuf = {%s}, *preparent = {%s}, "
+ "*postparent = {%s})",
+ frame->root->unique, op_ret, inode->ino,
+ statstr, preparentstr, postparentstr);
+
+ if (statstr)
+ FREE (statstr);
+
+ if (preparentstr)
+ FREE (preparentstr);
+
+ if (postparentstr)
+ FREE (postparentstr);
} else {
- snprintf (string, sizeof (string),
- "%"PRId64": (op_ret=%d, op_errno=%d)",
- frame->root->unique, op_ret,
- op_errno);
+ gf_log (this->name, GF_LOG_NORMAL,
+ "%"PRId64": (op_ret=%d, op_errno=%d)",
+ frame->root->unique, op_ret, op_errno);
}
- LOG_ELEMENT (conf, string);
}
-out:
- TRACE_STACK_UNWIND (mknod, frame, op_ret, op_errno, inode, buf,
- preparent, postparent, xdata);
+
+ STACK_UNWIND_STRICT (mknod, frame, op_ret, op_errno, inode, buf,
+ preparent, postparent);
return 0;
}
+
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)
+ inode_t *inode, struct stat *buf,
+ struct stat *preparent, struct stat *postparent)
{
- char statstr[4096] = {0, };
- char preparentstr[4096] = {0, };
- char postparentstr[4096] = {0, };
- trace_conf_t *conf = NULL;
+ char *statstr = NULL;
+ char *preparentstr = NULL;
+ char *postparentstr = NULL;
- conf = this->private;
-
- if (!conf->log_file && !conf->log_history)
- goto out;
if (trace_fop_names[GF_FOP_MKDIR].enabled) {
- char string[4096] = {0,};
- if (op_ret == 0) {
- TRACE_STAT_TO_STR (buf, statstr);
- TRACE_STAT_TO_STR (preparent, preparentstr);
- TRACE_STAT_TO_STR (postparent, postparentstr);
-
- snprintf (string, sizeof (string),
- "%"PRId64": gfid=%s (op_ret=%d "
- ", *stbuf = {%s}, *prebuf = {%s}, "
- "*postbuf = {%s} )",
- frame->root->unique,
- uuid_utoa (inode->gfid),
- op_ret, statstr, preparentstr,
- postparentstr);
+ if (op_ret >= 0) {
+ statstr = trace_stat_to_str (buf);
+ preparentstr = trace_stat_to_str (preparent);
+ preparentstr = trace_stat_to_str (postparent);
+
+ gf_log (this->name, GF_LOG_NORMAL,
+ "%"PRId64": (op_ret=%d, ino = %"PRIu64
+ ", *stbuf = {%s}, *prebuf = {%s}, "
+ "*postbuf = {%s} )",
+ frame->root->unique, op_ret, buf->st_ino,
+ statstr, preparentstr, postparentstr);
+
+ if (statstr)
+ FREE (statstr);
+
+ if (preparentstr)
+ FREE (preparentstr);
+
+ if (postparentstr)
+ FREE (postparentstr);
} else {
- snprintf (string, sizeof (string),
- "%"PRId64": (op_ret=%d, op_errno=%d)",
- frame->root->unique, op_ret,
- op_errno);
+ gf_log (this->name, GF_LOG_NORMAL,
+ "%"PRId64": (op_ret=%d, op_errno=%d)",
+ frame->root->unique, op_ret, op_errno);
}
- LOG_ELEMENT (conf, string);
}
-out:
- TRACE_STACK_UNWIND (mkdir, frame, op_ret, op_errno, inode, buf,
- preparent, postparent, xdata);
+
+ STACK_UNWIND_STRICT (mkdir, frame, op_ret, op_errno, inode, buf,
+ preparent, postparent);
return 0;
}
+
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)
+ inode_t *inode, struct stat *buf,
+ struct stat *preparent, struct stat *postparent)
{
- char statstr[4096] = {0, };
- char preparentstr[4096] = {0, };
- char postparentstr[4096] = {0, };
- trace_conf_t *conf = NULL;
+ char *statstr = NULL;
+ char *preparentstr = NULL;
+ char *postparentstr = NULL;
- conf = this->private;
-
- if (!conf->log_file && !conf->log_history)
- goto out;
- char string[4096] = {0,};
if (trace_fop_names[GF_FOP_LINK].enabled) {
- if (op_ret == 0) {
- TRACE_STAT_TO_STR (buf, statstr);
- TRACE_STAT_TO_STR (preparent, preparentstr);
- TRACE_STAT_TO_STR (postparent, postparentstr);
-
- snprintf (string, sizeof (string),
- "%"PRId64": (op_ret=%d, "
- "*stbuf = {%s}, *prebuf = {%s},"
- " *postbuf = {%s})",
- frame->root->unique, op_ret,
- statstr, preparentstr, postparentstr);
+ if (op_ret >= 0) {
+ statstr = trace_stat_to_str (buf);
+ preparentstr = trace_stat_to_str (preparent);
+ preparentstr = trace_stat_to_str (postparent);
+
+ gf_log (this->name, GF_LOG_NORMAL,
+ "%"PRId64": (op_ret=%d, ino = %"PRIu64
+ ", *stbuf = {%s}, *prebuf = {%s}, "
+ "*postbuf = {%s})",
+ frame->root->unique, op_ret, buf->st_ino,
+ statstr, preparentstr, postparentstr);
+
+ if (statstr)
+ FREE (statstr);
+
+ if (preparentstr)
+ FREE (preparentstr);
+
+ if (postparentstr)
+ FREE (postparentstr);
} else {
- snprintf (string, sizeof (string),
- "%"PRId64": gfid=%s op_ret=%d, "
- "op_errno=%d",
- frame->root->unique,
- uuid_utoa (frame->local),
- op_ret, op_errno);
+ gf_log (this->name, GF_LOG_NORMAL,
+ "%"PRId64": (op_ret=%d, op_errno=%d)",
+ frame->root->unique, op_ret, op_errno);
}
- LOG_ELEMENT (conf, string);
}
-out:
- TRACE_STACK_UNWIND (link, frame, op_ret, op_errno, inode, buf,
- preparent, postparent, xdata);
+
+ STACK_UNWIND_STRICT (link, frame, op_ret, op_errno, inode, buf,
+ 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)
{
- trace_conf_t *conf = NULL;
-
- conf = this->private;
-
- if (!conf->log_file && !conf->log_history)
- goto out;
- char string[4096] = {0,};
if (trace_fop_names[GF_FOP_FLUSH].enabled) {
- snprintf (string, sizeof (string),
- "%"PRId64": gfid=%s op_ret=%d, op_errno=%d",
- frame->root->unique, uuid_utoa (frame->local),
- op_ret, op_errno);
-
- LOG_ELEMENT (conf, string);
+ gf_log (this->name, GF_LOG_NORMAL,
+ "%"PRId64": (op_ret=%d, op_errno=%d)",
+ frame->root->unique, op_ret, op_errno);
}
-out:
- TRACE_STACK_UNWIND (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)
{
- trace_conf_t *conf = NULL;
-
- conf = this->private;
-
- if (!conf->log_file && !conf->log_history)
- goto out;
- char string[4096] = {0,};
if (trace_fop_names[GF_FOP_OPENDIR].enabled) {
- snprintf (string, sizeof (string),
- "%"PRId64": gfid=%s op_ret=%d, op_errno=%d,"
- " fd=%p",
- frame->root->unique, uuid_utoa (frame->local),
- op_ret, op_errno, fd);
-
- LOG_ELEMENT (conf, string);
+ gf_log (this->name, GF_LOG_NORMAL,
+ "%"PRId64": (op_ret=%d, op_errno=%d, fd=%p)",
+ frame->root->unique, op_ret, op_errno, fd);
}
-out:
- /* for 'releasedir' log */
- if (op_ret >= 0)
- fd_ctx_set (fd, this, 0);
- TRACE_STACK_UNWIND (opendir, frame, op_ret, op_errno, fd, xdata);
+ STACK_UNWIND_STRICT (opendir, frame, op_ret, op_errno, fd);
return 0;
}
+
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 stat *preparent, struct stat *postparent)
{
- char preparentstr[4096] = {0, };
- char postparentstr[4096] = {0, };
- trace_conf_t *conf = NULL;
+ char *preparentstr = NULL;
+ char *postparentstr = NULL;
- conf = this->private;
-
- if (!conf->log_file && !conf->log_history)
- goto out;
if (trace_fop_names[GF_FOP_RMDIR].enabled) {
- char string[4096] = {0,};
- if (op_ret == 0) {
- TRACE_STAT_TO_STR (preparent, preparentstr);
- TRACE_STAT_TO_STR (postparent, postparentstr);
-
- snprintf (string, sizeof (string),
- "%"PRId64": gfid=%s op_ret=%d, "
- "*prebuf={%s}, *postbuf={%s}",
- frame->root->unique,
- uuid_utoa (frame->local),
- op_ret, preparentstr, postparentstr);
+ if (op_ret >= 0) {
+ preparentstr = trace_stat_to_str (preparent);
+ preparentstr = trace_stat_to_str (postparent);
+
+ gf_log (this->name, GF_LOG_NORMAL,
+ "%"PRId64": (op_ret=%d, *prebuf = {%s}, "
+ "*postbuf = {%s}",
+ frame->root->unique, op_ret, preparentstr,
+ postparentstr);
+
+ if (preparentstr)
+ FREE (preparentstr);
+
+ if (postparentstr)
+ FREE (postparentstr);
} else {
- snprintf (string, sizeof (string),
- "%"PRId64": gfid=%s op_ret=%d, "
- "op_errno=%d", frame->root->unique,
- uuid_utoa (frame->local),
- op_ret, op_errno);
+ gf_log (this->name, GF_LOG_NORMAL,
+ "%"PRId64": (op_ret=%d, op_errno=%d)",
+ frame->root->unique, op_ret, op_errno);
}
- LOG_ELEMENT (conf, string);
}
-out:
- TRACE_STACK_UNWIND (rmdir, frame, op_ret, op_errno,
- preparent, postparent, xdata);
+
+ STACK_UNWIND_STRICT (rmdir, frame, op_ret, op_errno,
+ preparent, postparent);
return 0;
}
+
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 stat *prebuf, struct stat *postbuf)
{
- char preopstr[4096] = {0, };
- char postopstr[4096] = {0, };
- trace_conf_t *conf = NULL;
-
- conf = this->private;
+ char *preopstr = NULL;
+ char *postopstr = NULL;
- if (!conf->log_file && !conf->log_history)
- goto out;
if (trace_fop_names[GF_FOP_TRUNCATE].enabled) {
- char string[4096] = {0,};
- if (op_ret == 0) {
- TRACE_STAT_TO_STR (prebuf, preopstr);
- TRACE_STAT_TO_STR (postbuf, postopstr);
-
- snprintf (string, sizeof (string),
- "%"PRId64": (op_ret=%d, "
- "*prebuf = {%s}, *postbuf = {%s} )",
- frame->root->unique, op_ret,
- preopstr, postopstr);
+ if (op_ret >= 0) {
+ preopstr = trace_stat_to_str (prebuf);
+ postopstr = trace_stat_to_str (prebuf);
+
+ gf_log (this->name, GF_LOG_NORMAL,
+ "%"PRId64": (op_ret=%d, *prebuf = {%s}, "
+ "*postbuf = {%s} )",
+ frame->root->unique, op_ret, preopstr,
+ postopstr);
+
+ if (preopstr)
+ FREE (preopstr);
+
+ if (postopstr)
+ FREE (postopstr);
} else {
- snprintf (string, sizeof (string),
- "%"PRId64": gfid=%s op_ret=%d, "
- "op_errno=%d", frame->root->unique,
- uuid_utoa (frame->local), op_ret,
- op_errno);
+ gf_log (this->name, GF_LOG_NORMAL,
+ "%"PRId64": (op_ret=%d, op_errno=%d)",
+ frame->root->unique, op_ret, op_errno);
}
- LOG_ELEMENT (conf, string);
}
-out:
- TRACE_STACK_UNWIND (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)
{
- trace_conf_t *conf = NULL;
-
- conf = this->private;
-
- if (!conf->log_file && !conf->log_history)
- goto out;
if (trace_fop_names[GF_FOP_STATFS].enabled) {
- char string[4096] = {0,};
- if (op_ret == 0) {
- snprintf (string, sizeof (string),
- "%"PRId64": ({f_bsize=%lu, "
- "f_frsize=%lu, "
- "f_blocks=%"GF_PRI_FSBLK
- ", f_bfree=%"GF_PRI_FSBLK", "
- "f_bavail=%"GF_PRI_FSBLK", "
- "f_files=%"GF_PRI_FSBLK", "
- "f_ffree=%"GF_PRI_FSBLK", "
- "f_favail=%"GF_PRI_FSBLK", "
- "f_fsid=%lu, f_flag=%lu, "
- "f_namemax=%lu}) => ret=%d",
- frame->root->unique, buf->f_bsize,
- buf->f_frsize, buf->f_blocks,
- buf->f_bfree, buf->f_bavail,
- buf->f_files, buf->f_ffree,
- buf->f_favail, buf->f_fsid,
- buf->f_flag, buf->f_namemax, op_ret);
+ if (op_ret >= 0) {
+ gf_log (this->name, GF_LOG_NORMAL,
+ "%"PRId64": ({f_bsize=%lu, f_frsize=%lu, f_blocks=%"GF_PRI_FSBLK
+ ", f_bfree=%"GF_PRI_FSBLK", f_bavail=%"GF_PRI_FSBLK", "
+ "f_files=%"GF_PRI_FSBLK", f_ffree=%"GF_PRI_FSBLK", f_favail=%"
+ GF_PRI_FSBLK", f_fsid=%lu, f_flag=%lu, f_namemax=%lu}) => ret=%d",
+ frame->root->unique, buf->f_bsize, buf->f_frsize, buf->f_blocks,
+ buf->f_bfree, buf->f_bavail, buf->f_files, buf->f_ffree,
+ buf->f_favail, buf->f_fsid, buf->f_flag, buf->f_namemax, op_ret);
} else {
- snprintf (string, sizeof (string),
- "%"PRId64": (op_ret=%d, "
- "op_errno=%d)",
- frame->root->unique, op_ret,
- op_errno);
+ gf_log (this->name, GF_LOG_NORMAL,
+ "%"PRId64": (op_ret=%d, op_errno=%d)",
+ frame->root->unique, op_ret, op_errno);
}
- LOG_ELEMENT (conf, string);
}
-out:
- TRACE_STACK_UNWIND (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)
{
- trace_conf_t *conf = NULL;
-
- conf = this->private;
-
- if (!conf->log_file && !conf->log_history)
- goto out;
if (trace_fop_names[GF_FOP_SETXATTR].enabled) {
- char string[4096] = {0,};
- snprintf (string, sizeof (string),
- "%"PRId64": gfid=%s op_ret=%d, op_errno=%d",
- frame->root->unique,
- uuid_utoa (frame->local), op_ret,
- op_errno);
-
- LOG_ELEMENT (conf, string);
+ gf_log (this->name, GF_LOG_NORMAL,
+ "%"PRId64": (op_ret=%d, op_errno=%d)",
+ frame->root->unique, op_ret, op_errno);
}
-out:
- TRACE_STACK_UNWIND (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)
{
- trace_conf_t *conf = NULL;
-
- conf = this->private;
-
- if (!conf->log_file && !conf->log_history)
- goto out;
if (trace_fop_names[GF_FOP_GETXATTR].enabled) {
- char string[4096] = {0,};
- snprintf (string, sizeof (string),
- "%"PRId64": gfid=%s op_ret=%d, op_errno=%d,"
- " dict=%p", frame->root->unique,
- uuid_utoa (frame->local), op_ret, op_errno,
- dict);
-
- LOG_ELEMENT (conf, string);
+ gf_log (this->name, GF_LOG_NORMAL,
+ "%"PRId64": (op_ret=%d, op_errno=%d, dict=%p)",
+ frame->root->unique, op_ret, op_errno, dict);
}
-out:
- TRACE_STACK_UNWIND (getxattr, frame, op_ret, op_errno, dict, xdata);
-
- 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)
-{
- trace_conf_t *conf = NULL;
-
- conf = this->private;
- if (!conf->log_file && !conf->log_history)
- goto out;
- if (trace_fop_names[GF_FOP_FSETXATTR].enabled) {
- char string[4096] = {0,};
- snprintf (string, sizeof (string),
- "%"PRId64": gfid=%s op_ret=%d, op_errno=%d",
- frame->root->unique,
- uuid_utoa (frame->local), op_ret, op_errno);
+ STACK_UNWIND_STRICT (getxattr, frame, op_ret, op_errno, dict);
- LOG_ELEMENT (conf, string);
- }
-out:
- TRACE_STACK_UNWIND (fsetxattr, frame, op_ret, op_errno, xdata);
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)
-{
- trace_conf_t *conf = NULL;
-
- conf = this->private;
-
- if (!conf->log_file && !conf->log_history)
- goto out;
- if (trace_fop_names[GF_FOP_FGETXATTR].enabled) {
- char string[4096] = {0,};
- snprintf (string, sizeof (string),
- "%"PRId64": gfid=%s op_ret=%d, op_errno=%d,"
- " dict=%p", frame->root->unique,
- uuid_utoa (frame->local), op_ret, op_errno,
- dict);
-
- LOG_ELEMENT (conf, string);
- }
-out:
- TRACE_STACK_UNWIND (fgetxattr, frame, op_ret, op_errno, dict, xdata);
-
- 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)
{
- trace_conf_t *conf = NULL;
-
- conf = this->private;
-
- if (!conf->log_file && !conf->log_history)
- goto out;
if (trace_fop_names[GF_FOP_REMOVEXATTR].enabled) {
- char string[4096] = {0,};
- snprintf (string, sizeof (string),
- "%"PRId64": gfid=%s op_ret=%d, op_errno=%d",
- frame->root->unique,
- uuid_utoa (frame->local), op_ret, op_errno);
-
- LOG_ELEMENT (conf, string);
+ gf_log (this->name, GF_LOG_NORMAL,
+ "%"PRId64": (op_ret=%d, op_errno=%d)",
+ frame->root->unique, op_ret, op_errno);
}
-out:
- TRACE_STACK_UNWIND (removexattr, frame, op_ret, op_errno, xdata);
+
+ STACK_UNWIND_STRICT (removexattr, frame, op_ret, op_errno);
return 0;
}
+
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)
{
- trace_conf_t *conf = NULL;
-
- conf = this->private;
-
- if (!conf->log_file && !conf->log_history)
- goto out;
if (trace_fop_names[GF_FOP_FSYNCDIR].enabled) {
- char string[4096] = {0,};
- snprintf (string, sizeof (string),
- "%"PRId64": gfid=%s op_ret=%d, op_errno=%d",
- frame->root->unique,
- uuid_utoa (frame->local), op_ret, op_errno);
-
- LOG_ELEMENT (conf, string);
+ gf_log (this->name, GF_LOG_NORMAL,
+ "%"PRId64": (op_ret=%d, op_errno=%d)",
+ frame->root->unique, op_ret, op_errno);
}
-out:
- TRACE_STACK_UNWIND (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)
{
- trace_conf_t *conf = NULL;
-
- conf = this->private;
-
- if (!conf->log_file && !conf->log_history)
- goto out;
if (trace_fop_names[GF_FOP_ACCESS].enabled) {
- char string[4096] = {0,};
- snprintf (string, sizeof (string),
- "%"PRId64": gfid=%s op_ret=%d, "
- "op_errno=%d)", frame->root->unique,
- uuid_utoa (frame->local), op_ret, op_errno);
-
- LOG_ELEMENT (conf, string);
+ gf_log (this->name, GF_LOG_NORMAL,
+ "%"PRId64": (op_ret=%d, op_errno=%d)",
+ frame->root->unique, op_ret, op_errno);
}
-out:
- TRACE_STACK_UNWIND (access, frame, op_ret, op_errno, xdata);
+
+ STACK_UNWIND_STRICT (access, frame, op_ret, op_errno);
return 0;
}
+
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 stat *prebuf, struct stat *postbuf)
{
- char prebufstr[4096] = {0, };
- char postbufstr[4096] = {0, };
- trace_conf_t *conf = NULL;
+ char *prebufstr = NULL;
+ char *postbufstr = NULL;
- conf = this->private;
-
- if (!conf->log_file && !conf->log_history)
- goto out;
if (trace_fop_names[GF_FOP_FTRUNCATE].enabled) {
- char string[4096] = {0,};
- if (op_ret == 0) {
- TRACE_STAT_TO_STR (prebuf, prebufstr);
- TRACE_STAT_TO_STR (postbuf, postbufstr);
-
- snprintf (string, sizeof (string),
- "%"PRId64": op_ret=%d, "
- "*prebuf = {%s}, *postbuf = {%s} )",
- frame->root->unique, op_ret,
- prebufstr, postbufstr);
+ if (op_ret >= 0) {
+ prebufstr = trace_stat_to_str (prebuf);
+ postbufstr = trace_stat_to_str (postbuf);
+
+ gf_log (this->name, GF_LOG_NORMAL,
+ "%"PRId64": (op_ret=%d, *prebuf = {%s}, "
+ "*postbuf = {%s} )",
+ frame->root->unique, op_ret,
+ prebufstr, postbufstr);
+
+ if (prebufstr)
+ FREE (prebufstr);
+
+ if (postbufstr)
+ FREE (postbufstr);
+
} else {
- snprintf (string, sizeof (string),
- "%"PRId64": gfid=%s op_ret=%d, "
- "op_errno=%d", frame->root->unique,
- uuid_utoa (frame->local), op_ret,
- op_errno);
+ gf_log (this->name, GF_LOG_NORMAL,
+ "%"PRId64": (op_ret=%d, op_errno=%d)",
+ frame->root->unique, op_ret, op_errno);
}
- LOG_ELEMENT (conf, string);
}
-out:
- TRACE_STACK_UNWIND (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 stat *buf)
{
- char statstr[4096] = {0, };
- trace_conf_t *conf = NULL;
+ char atime_buf[256];
+ char mtime_buf[256];
+ char ctime_buf[256];
- conf = this->private;
-
- if (!conf->log_file && !conf->log_history)
- goto out;
if (trace_fop_names[GF_FOP_FSTAT].enabled) {
- char string[4096] = {0.};
- if (op_ret == 0) {
- TRACE_STAT_TO_STR (buf, statstr);
- snprintf (string, sizeof (string),
- "%"PRId64": gfid=%s op_ret=%d "
- "buf=%s", frame->root->unique,
- uuid_utoa (frame->local), op_ret,
- statstr);
+ if (op_ret >= 0) {
+ strftime (atime_buf, 256, "[%b %d %H:%M:%S]",
+ localtime (&buf->st_atime));
+ strftime (mtime_buf, 256, "[%b %d %H:%M:%S]",
+ localtime (&buf->st_mtime));
+ strftime (ctime_buf, 256, "[%b %d %H:%M:%S]",
+ localtime (&buf->st_ctime));
+
+ gf_log (this->name, GF_LOG_NORMAL,
+ "%"PRId64": (op_ret=%d, *buf {st_dev=%"GF_PRI_DEV", "
+ "st_ino=%"PRIu64", st_mode=%o, st_nlink=%"GF_PRI_NLINK", "
+ "st_uid=%d, st_gid=%d, st_rdev=%"GF_PRI_DEV", st_size=%"PRId64", "
+ "st_blksize=%"GF_PRI_BLKSIZE", st_blocks=%"PRId64", st_atime=%s, "
+ "st_mtime=%s, st_ctime=%s})",
+ frame->root->unique, op_ret, buf->st_dev, buf->st_ino,
+ buf->st_mode, buf->st_nlink, buf->st_uid, buf->st_gid,
+ buf->st_rdev, buf->st_size, buf->st_blksize,
+ buf->st_blocks, atime_buf, mtime_buf, ctime_buf);
} else {
- snprintf (string, sizeof (string),
- "%"PRId64": gfid=%s op_ret=%d, "
- "op_errno=%d", frame->root->unique,
- uuid_utoa (frame->local), op_ret,
- op_errno);
+ gf_log (this->name, GF_LOG_NORMAL,
+ "%"PRId64": (op_ret=%d, op_errno=%d)",
+ frame->root->unique, op_ret, op_errno);
}
- LOG_ELEMENT (conf, string);
}
-out:
- TRACE_STACK_UNWIND (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 flock *lock)
{
- trace_conf_t *conf = NULL;
-
- conf = this->private;
-
- if (!conf->log_file && !conf->log_history)
- goto out;
if (trace_fop_names[GF_FOP_LK].enabled) {
- char string[4096] = {0,};
- if (op_ret == 0) {
- snprintf (string, sizeof (string),
- "%"PRId64": gfid=%s op_ret=%d, "
- "{l_type=%d, l_whence=%d, "
- "l_start=%"PRId64", "
- "l_len=%"PRId64", l_pid=%u})",
- frame->root->unique,
- uuid_utoa (frame->local),
- op_ret, lock->l_type, lock->l_whence,
- lock->l_start, lock->l_len,
- lock->l_pid);
+ if (op_ret >= 0) {
+ gf_log (this->name, GF_LOG_NORMAL,
+ "%"PRId64": (op_ret=%d, {l_type=%d, l_whence=%d, "
+ "l_start=%"PRId64", l_len=%"PRId64", l_pid=%u})",
+ frame->root->unique, op_ret, lock->l_type, lock->l_whence,
+ lock->l_start, lock->l_len, lock->l_pid);
} else {
- snprintf (string, sizeof (string),
- "%"PRId64": gfid=%s op_ret=%d, "
- "op_errno=%d)", frame->root->unique,
- uuid_utoa (frame->local), op_ret,
- op_errno);
+ gf_log (this->name, GF_LOG_NORMAL,
+ "%"PRId64": (op_ret=%d, op_errno=%d)",
+ frame->root->unique, op_ret, op_errno);
}
-
- LOG_ELEMENT (conf, string);
}
-out:
- TRACE_STACK_UNWIND (lk, frame, op_ret, op_errno, lock, xdata);
+
+ STACK_UNWIND_STRICT (lk, frame, op_ret, op_errno, lock);
return 0;
}
+
int
-trace_entrylk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
+trace_setdents_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno)
{
- trace_conf_t *conf = NULL;
-
- conf = this->private;
-
- if (!conf->log_file && !conf->log_history)
- goto out;
- if (trace_fop_names[GF_FOP_ENTRYLK].enabled) {
- char string[4096] = {0,};
- snprintf (string, sizeof (string),
- "%"PRId64": gfid=%s op_ret=%d, op_errno=%d",
- frame->root->unique,
- uuid_utoa (frame->local), op_ret, op_errno);
-
- LOG_ELEMENT (conf, string);
+ if (trace_fop_names[GF_FOP_SETDENTS].enabled) {
+ gf_log (this->name, GF_LOG_NORMAL,
+ "%"PRId64": op_ret=%d, op_errno=%d",
+ frame->root->unique, op_ret, op_errno);
}
-out:
- TRACE_STACK_UNWIND (entrylk, frame, op_ret, op_errno, xdata);
+
+ STACK_UNWIND_STRICT (setdents, 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)
+trace_entrylk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno)
{
- trace_conf_t *conf = NULL;
-
- conf = this->private;
-
- if (!conf->log_file && !conf->log_history)
- goto out;
- if (trace_fop_names[GF_FOP_FENTRYLK].enabled) {
- char string[4096] = {0,};
- snprintf (string, sizeof (string),
- "%"PRId64": gfid=%s op_ret=%d, op_errno=%d",
- frame->root->unique,
- uuid_utoa (frame->local), op_ret, op_errno);
-
- LOG_ELEMENT (conf, string);
+ if (trace_fop_names[GF_FOP_ENTRYLK].enabled) {
+ gf_log (this->name, GF_LOG_NORMAL,
+ "%"PRId64": op_ret=%d, op_errno=%d",
+ frame->root->unique, op_ret, op_errno);
}
-out:
- TRACE_STACK_UNWIND (fentrylk, frame, op_ret, op_errno, xdata);
+
+ STACK_UNWIND_STRICT (entrylk, 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)
{
- trace_conf_t *conf = NULL;
-
- conf = this->private;
-
- if (!conf->log_file && !conf->log_history)
- goto out;
if (trace_fop_names[GF_FOP_XATTROP].enabled) {
- char string[4096] = {0,};
- snprintf (string, sizeof (string),
- "%"PRId64": gfid=%s op_ret=%d, op_errno=%d",
- frame->root->unique,
- uuid_utoa (frame->local), op_ret, op_errno);
-
- LOG_ELEMENT (conf, string);
+ gf_log (this->name, GF_LOG_NORMAL,
+ "%"PRId64": (op_ret=%d, op_errno=%d)",
+ frame->root->unique, op_ret, op_errno);
}
-out:
- TRACE_STACK_UNWIND (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)
{
- trace_conf_t *conf = NULL;
-
- conf = this->private;
-
- if (!conf->log_file && !conf->log_history)
- goto out;
if (trace_fop_names[GF_FOP_FXATTROP].enabled) {
- char string[4096] = {0,};
- snprintf (string, sizeof (string),
- "%"PRId64": gfid=%s op_ret=%d, op_errno=%d",
- frame->root->unique,
- uuid_utoa (frame->local), op_ret, op_errno);
-
- LOG_ELEMENT (conf, string);
+ gf_log (this->name, GF_LOG_NORMAL,
+ "%"PRId64": (op_ret=%d, op_errno=%d)",
+ frame->root->unique, op_ret, op_errno);
}
-out:
- TRACE_STACK_UNWIND (fxattrop, frame, op_ret, op_errno, dict, xdata);
- 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)
-{
- trace_conf_t *conf = NULL;
-
- conf = this->private;
-
- if (!conf->log_file && !conf->log_history)
- goto out;
- if (trace_fop_names[GF_FOP_INODELK].enabled) {
- char string[4096] = {0,};
- snprintf (string, sizeof (string),
- "%"PRId64": gfid=%s op_ret=%d, op_errno=%d",
- frame->root->unique,
- uuid_utoa (frame->local),op_ret, op_errno);
- LOG_ELEMENT (conf, string);
- }
-out:
- TRACE_STACK_UNWIND (inodelk, frame, op_ret, op_errno, xdata);
+ STACK_UNWIND_STRICT (fxattrop, frame, op_ret, op_errno, dict);
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)
-{
- trace_conf_t *conf = NULL;
-
- conf = this->private;
-
- if (!conf->log_file && !conf->log_history)
- goto out;
- if (trace_fop_names[GF_FOP_FINODELK].enabled) {
- char string[4096] = {0,};
- snprintf (string, sizeof (string),
- "%"PRId64": gfid=%s op_ret=%d, op_errno=%d",
- frame->root->unique,
- uuid_utoa (frame->local), op_ret, op_errno);
-
- LOG_ELEMENT (conf, string);
- }
-out:
- TRACE_STACK_UNWIND (finodelk, frame, op_ret, op_errno, xdata);
- return 0;
-}
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)
+trace_inodelk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno)
{
- trace_conf_t *conf = NULL;
-
- conf = this->private;
-
- if (!conf->log_file && !conf->log_history)
- goto out;
- if (trace_fop_names[GF_FOP_RCHECKSUM].enabled) {
- char string[4096] = {0,};
- snprintf (string, sizeof (string),
- "%"PRId64": gfid=%s op_ret=%d op_errno=%d",
- frame->root->unique,
- uuid_utoa (frame->local), op_ret, op_errno);
-
- LOG_ELEMENT (conf, string);
+ if (trace_fop_names[GF_FOP_INODELK].enabled) {
+ gf_log (this->name, GF_LOG_NORMAL,
+ "%"PRId64": op_ret=%d, op_errno=%d",
+ frame->root->unique, op_ret, op_errno);
}
-out:
- TRACE_STACK_UNWIND (rchecksum, frame, op_ret, op_errno, weak_checksum,
- strong_checksum, xdata);
-
+ STACK_UNWIND_STRICT (inodelk, frame, op_ret, op_errno);
return 0;
}
-/* *_cbk section over <----------> fop section start */
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)
{
- trace_conf_t *conf = NULL;
-
- conf = this->private;
-
- if (!conf->log_file && !conf->log_history)
- goto out;
if (trace_fop_names[GF_FOP_ENTRYLK].enabled) {
- char string[4096] = {0,};
- snprintf (string, sizeof (string),
- "%"PRId64": gfid=%s volume=%s, (path=%s "
- "basename=%s, cmd=%s, type=%s)",
- frame->root->unique,
- uuid_utoa (loc->inode->gfid),
- volume, loc->path, basename,
- ((cmd == ENTRYLK_LOCK) ? "ENTRYLK_LOCK" :
- "ENTRYLK_UNLOCK"),
- ((type == ENTRYLK_RDLCK) ? "ENTRYLK_RDLCK" :
- "ENTRYLK_WRLCK"));
-
- frame->local = loc->inode->gfid;
-
- LOG_ELEMENT (conf, string);
+ gf_log (this->name, GF_LOG_NORMAL,
+ "%"PRId64": volume=%s, (loc= {path=%s, ino=%"PRIu64"} basename=%s, cmd=%s, type=%s)",
+ frame->root->unique, volume, loc->path, loc->inode->ino, basename,
+ ((cmd == ENTRYLK_LOCK) ? "ENTRYLK_LOCK" : "ENTRYLK_UNLOCK"),
+ ((type == ENTRYLK_RDLCK) ? "ENTRYLK_RDLCK" : "ENTRYLK_WRLCK"));
}
-out:
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 flock *flock)
{
- char *cmd_str = NULL;
- char *type_str = NULL;
- trace_conf_t *conf = NULL;
-
- conf = this->private;
-
- if (!conf->log_file && !conf->log_history)
- goto out;
if (trace_fop_names[GF_FOP_INODELK].enabled) {
- char string[4096] = {0,};
- switch (cmd) {
-#if F_GETLK != F_GETLK64
- case F_GETLK64:
-#endif
- case F_GETLK:
- cmd_str = "GETLK";
- break;
-
-#if F_SETLK != F_SETLK64
- case F_SETLK64:
-#endif
- case F_SETLK:
- cmd_str = "SETLK";
- break;
-
-#if F_SETLKW != F_SETLKW64
- case F_SETLKW64:
-#endif
- case F_SETLKW:
- cmd_str = "SETLKW";
- break;
-
- default:
- cmd_str = "UNKNOWN";
- break;
- }
-
- switch (flock->l_type) {
- case F_RDLCK:
- type_str = "READ";
- break;
- case F_WRLCK:
- type_str = "WRITE";
- break;
- case F_UNLCK:
- type_str = "UNLOCK";
- break;
- default:
- type_str = "UNKNOWN";
- break;
- }
-
- snprintf (string, sizeof (string),
- "%"PRId64": gfid=%s volume=%s, (path=%s "
- "cmd=%s, type=%s, start=%llu, len=%llu, "
- "pid=%llu)", frame->root->unique,
- uuid_utoa (loc->inode->gfid), volume,
- loc->path, cmd_str, type_str,
- (unsigned long long)flock->l_start,
- (unsigned long long) flock->l_len,
- (unsigned long long) flock->l_pid);
-
- frame->local = loc->inode->gfid;
-
- LOG_ELEMENT (conf, string);
+ gf_log (this->name, GF_LOG_NORMAL,
+ "%"PRId64": volume=%s, (loc {path=%s, ino=%"PRIu64"}, cmd=%s)",
+ frame->root->unique, volume, loc->path, loc->inode->ino,
+ ((cmd == F_SETLK)? "F_SETLK" : "unknown"));
}
-out:
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)
+trace_finodelk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno)
{
- char *cmd_str = NULL;
- char *type_str = NULL;
- trace_conf_t *conf = NULL;
-
- conf = this->private;
-
- if (!conf->log_file && !conf->log_history)
- goto out;
if (trace_fop_names[GF_FOP_FINODELK].enabled) {
- char string[4096] = {0,};
- switch (cmd) {
-#if F_GETLK != F_GETLK64
- case F_GETLK64:
-#endif
- case F_GETLK:
- cmd_str = "GETLK";
- break;
-
-#if F_SETLK != F_SETLK64
- case F_SETLK64:
-#endif
- case F_SETLK:
- cmd_str = "SETLK";
- break;
-
-#if F_SETLKW != F_SETLKW64
- case F_SETLKW64:
-#endif
- case F_SETLKW:
- cmd_str = "SETLKW";
- break;
-
- default:
- cmd_str = "UNKNOWN";
- break;
- }
-
- switch (flock->l_type) {
- case F_RDLCK:
- type_str = "READ";
- break;
- case F_WRLCK:
- type_str = "WRITE";
- break;
- case F_UNLCK:
- type_str = "UNLOCK";
- break;
- default:
- type_str = "UNKNOWN";
- break;
- }
+ gf_log (this->name, GF_LOG_NORMAL,
+ "%"PRId64": op_ret=%d, op_errno=%d",
+ frame->root->unique, op_ret, op_errno);
+ }
- snprintf (string, sizeof (string),
- "%"PRId64": gfid=%s volume=%s, (fd =%p "
- "cmd=%s, type=%s, start=%llu, len=%llu, "
- "pid=%llu)", frame->root->unique,
- uuid_utoa (fd->inode->gfid), volume, fd,
- cmd_str, type_str,
- (unsigned long long) flock->l_start,
- (unsigned long long) flock->l_len,
- (unsigned long long) flock->l_pid);
+ STACK_UNWIND_STRICT (finodelk, frame, op_ret, op_errno);
+ return 0;
+}
- frame->local = fd->inode->gfid;
- LOG_ELEMENT (conf, string);
+int
+trace_finodelk (call_frame_t *frame, xlator_t *this, const char *volume,
+ fd_t *fd, int32_t cmd, struct flock *flock)
+{
+ if (trace_fop_names[GF_FOP_FINODELK].enabled) {
+ gf_log (this->name, GF_LOG_NORMAL,
+ "%"PRId64": volume=%s, (fd=%p, cmd=%s)",
+ frame->root->unique, volume, fd,
+ ((cmd == F_SETLK) ? "F_SETLK" : "unknown"));
}
-out:
+
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)
{
- trace_conf_t *conf = NULL;
-
- conf = this->private;
-
- if (!conf->log_file && !conf->log_history)
- goto out;
if (trace_fop_names[GF_FOP_XATTROP].enabled) {
- char string[4096] = {0,};
- snprintf (string, sizeof (string),
- "%"PRId64": gfid=%s (path=%s flags=%d)",
- frame->root->unique,
- uuid_utoa (loc->inode->gfid), loc->path,
- flags);
+ gf_log (this->name, GF_LOG_NORMAL,
+ "%"PRId64": (path=%s, ino=%"PRIu64" flags=%d)",
+ frame->root->unique, loc->path, loc->inode->ino, flags);
- frame->local = loc->inode->gfid;
-
- LOG_ELEMENT (conf, string);
}
-out:
STACK_WIND (frame, trace_xattrop_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->xattrop,
- loc, flags, dict, xdata);
+ loc, flags, dict);
return 0;
}
+
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)
{
- trace_conf_t *conf = NULL;
-
- conf = this->private;
-
- if (!conf->log_file && !conf->log_history)
- goto out;
if (trace_fop_names[GF_FOP_FXATTROP].enabled) {
- char string[4096] = {0,};
- snprintf (string, sizeof (string),
- "%"PRId64": gfid=%s fd=%p, flags=%d",
- frame->root->unique,
- uuid_utoa (fd->inode->gfid), fd, flags);
+ gf_log (this->name, GF_LOG_NORMAL,
+ "%"PRId64": (fd=%p, flags=%d)",
+ frame->root->unique, fd, flags);
- frame->local = fd->inode->gfid;
-
- LOG_ELEMENT (conf, string);
}
-out:
STACK_WIND (frame, trace_fxattrop_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->fxattrop,
- fd, flags, dict, xdata);
+ fd, flags, dict);
return 0;
}
+
int
trace_lookup (call_frame_t *frame, xlator_t *this,
- loc_t *loc, dict_t *xdata)
+ loc_t *loc, dict_t *xattr_req)
{
- trace_conf_t *conf = NULL;
-
- conf = this->private;
-
- if (!conf->log_file && !conf->log_history)
- goto out;
if (trace_fop_names[GF_FOP_LOOKUP].enabled) {
- char string[4096] = {0,};
/* TODO: print all the keys mentioned in xattr_req */
- snprintf (string, sizeof (string),
- "%"PRId64": gfid=%s path=%s",
- frame->root->unique,
- uuid_utoa (loc->inode->gfid), loc->path);
-
- frame->local = loc->inode->gfid;
-
- LOG_ELEMENT (conf, string);
+ gf_log (this->name, GF_LOG_NORMAL,
+ "%"PRId64": (loc {path=%s, ino=%"PRIu64"})",
+ frame->root->unique, loc->path,
+ loc->inode->ino);
}
-out:
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)
{
- trace_conf_t *conf = NULL;
-
- conf = this->private;
-
- if (!conf->log_file && !conf->log_history)
- goto out;
if (trace_fop_names[GF_FOP_STAT].enabled) {
- char string[4096] = {0,};
- snprintf (string, sizeof (string),
- "%"PRId64": gfid=%s path=%s",
- frame->root->unique,
- uuid_utoa (loc->inode->gfid), loc->path);
-
- frame->local = loc->inode->gfid;
-
- LOG_ELEMENT (conf, string);
+ gf_log (this->name, GF_LOG_NORMAL,
+ "%"PRId64": (loc {path=%s, ino=%"PRIu64"})",
+ frame->root->unique, loc->path, loc->inode->ino);
}
-out:
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)
{
- trace_conf_t *conf = NULL;
-
- conf = this->private;
-
- if (!conf->log_file && !conf->log_history)
- goto out;
if (trace_fop_names[GF_FOP_READLINK].enabled) {
- char string[4096] = {0,};
- snprintf (string, sizeof (string),
- "%"PRId64": gfid=%s path=%s, "
- "size=%"GF_PRI_SIZET")", frame->root->unique,
- uuid_utoa (loc->inode->gfid), loc->path,
- size);
-
- frame->local = loc->inode->gfid;
-
- LOG_ELEMENT (conf, string);
+ gf_log (this->name, GF_LOG_NORMAL,
+ "%"PRId64": (loc {path=%s, ino=%"PRIu64"}, size=%"GF_PRI_SIZET")",
+ frame->root->unique, loc->path, loc->inode->ino, size);
}
-out:
STACK_WIND (frame, trace_readlink_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->readlink,
- loc, size, xdata);
+ loc, size);
return 0;
}
+
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)
{
- trace_conf_t *conf = NULL;
-
- conf = this->private;
-
- if (!conf->log_file && !conf->log_history)
- goto out;
if (trace_fop_names[GF_FOP_MKNOD].enabled) {
- char string[4096] = {0,};
- snprintf (string, sizeof (string),
- "%"PRId64": gfid=%s path=%s mode=%d "
- "umask=0%o, dev=%"GF_PRI_DEV")",
- frame->root->unique,
- uuid_utoa (loc->inode->gfid), loc->path,
- mode, umask, dev);
-
- LOG_ELEMENT (conf, string);
+ gf_log (this->name, GF_LOG_NORMAL,
+ "%"PRId64": (loc {path=%s, ino=%"PRIu64"}, mode=%d, dev=%"GF_PRI_DEV")",
+ frame->root->unique, loc->path, loc->inode->ino, mode, dev);
}
-out:
STACK_WIND (frame, trace_mknod_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->mknod,
- loc, mode, dev, umask, xdata);
+ loc, mode, dev);
return 0;
}
+
int
-trace_mkdir (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
- mode_t umask, dict_t *xdata)
+trace_mkdir (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode)
{
- trace_conf_t *conf = NULL;
-
- conf = this->private;
-
- if (!conf->log_file && !conf->log_history)
- goto out;
if (trace_fop_names[GF_FOP_MKDIR].enabled) {
- char string[4096] = {0,};
- snprintf (string, sizeof (string),
- "%"PRId64": gfid=%s path=%s mode=%d"
- " umask=0%o", frame->root->unique,
- uuid_utoa (loc->inode->gfid), loc->path,
- mode, umask);
-
- LOG_ELEMENT (conf, string);
+ gf_log (this->name, GF_LOG_NORMAL,
+ "%"PRId64": (path=%s, ino=%"PRIu64", mode=%d)",
+ frame->root->unique, loc->path,
+ ((loc->inode)? loc->inode->ino : 0), mode);
}
-out:
STACK_WIND (frame, trace_mkdir_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->mkdir,
- loc, mode, umask, xdata);
+ loc, mode);
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)
{
- trace_conf_t *conf = NULL;
-
- conf = this->private;
-
- if (!conf->log_file && !conf->log_history)
- goto out;
if (trace_fop_names[GF_FOP_UNLINK].enabled) {
- char string[4096] = {0,};
- snprintf (string, sizeof (string),
- "%"PRId64": gfid=%s path=%s flag=%d",
- frame->root->unique,
- uuid_utoa (loc->inode->gfid), loc->path,
- xflag);
-
- frame->local = loc->inode->gfid;
-
- LOG_ELEMENT (conf, string);
+ gf_log (this->name, GF_LOG_NORMAL,
+ "%"PRId64": (loc {path=%s, ino=%"PRIu64"})",
+ frame->root->unique, loc->path, loc->inode->ino);
}
-out:
+
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)
{
- trace_conf_t *conf = NULL;
-
- conf = this->private;
-
- if (!conf->log_file && !conf->log_history)
- goto out;
if (trace_fop_names[GF_FOP_RMDIR].enabled) {
- char string[4096] = {0,};
- snprintf (string, sizeof (string),
- "%"PRId64": gfid=%s path=%s flags=%d",
- frame->root->unique,
- uuid_utoa (loc->inode->gfid), loc->path,
- flags);
-
- frame->local = loc->inode->gfid;
-
- LOG_ELEMENT (conf, string);
+ gf_log (this->name, GF_LOG_NORMAL,
+ "%"PRId64": (loc {path=%s, ino=%"PRIu64"})",
+ frame->root->unique, loc->path, loc->inode->ino);
}
-out:
STACK_WIND (frame, trace_rmdir_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->rmdir,
- loc, flags, xdata);
+ loc);
return 0;
}
+
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)
{
- trace_conf_t *conf = NULL;
-
- conf = this->private;
-
- if (!conf->log_file && !conf->log_history)
- goto out;
if (trace_fop_names[GF_FOP_SYMLINK].enabled) {
- char string[4096] = {0,};
- snprintf (string, sizeof (string),
- "%"PRId64": gfid=%s linkpath=%s, path=%s"
- " umask=0%o", frame->root->unique,
- uuid_utoa (loc->inode->gfid), linkpath,
- loc->path, umask);
-
- LOG_ELEMENT (conf, string);
+ gf_log (this->name, GF_LOG_NORMAL,
+ "%"PRId64": (linkpath=%s, loc {path=%s, ino=%"PRIu64"})",
+ frame->root->unique, linkpath, loc->path,
+ ((loc->inode)? loc->inode->ino : 0));
}
-out:
STACK_WIND (frame, trace_symlink_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->symlink,
- linkpath, loc, umask, xdata);
+ linkpath, loc);
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,};
- trace_conf_t *conf = NULL;
-
- conf = this->private;
-
- if (!conf->log_file && !conf->log_history)
- goto out;
if (trace_fop_names[GF_FOP_RENAME].enabled) {
- char string[4096] = {0,};
- if (newloc->inode)
- uuid_utoa_r (newloc->inode->gfid, newgfid);
- else
- strcpy (newgfid, "0");
-
- uuid_utoa_r (oldloc->inode->gfid, oldgfid);
-
- snprintf (string, sizeof (string),
- "%"PRId64": oldgfid=%s oldpath=%s --> "
- "newgfid=%s newpath=%s",
- frame->root->unique, oldgfid,
- oldloc->path, newgfid, newloc->path);
-
- frame->local = oldloc->inode->gfid;
-
- LOG_ELEMENT (conf, string);
+ gf_log (this->name, GF_LOG_NORMAL,
+ "%"PRId64": (oldloc {path=%s, ino=%"PRIu64"}, "
+ "newloc{path=%s, ino=%"PRIu64"})",
+ frame->root->unique, oldloc->path, oldloc->ino,
+ newloc->path, newloc->ino);
}
-out:
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,};
- trace_conf_t *conf = NULL;
-
- conf = this->private;
-
- if (!conf->log_file && !conf->log_history)
- goto out;
if (trace_fop_names[GF_FOP_LINK].enabled) {
- char string[4096] = {0,};
- if (newloc->inode)
- uuid_utoa_r (newloc->inode->gfid, newgfid);
- else
- strcpy (newgfid, "0");
-
- uuid_utoa_r (oldloc->inode->gfid, oldgfid);
-
- snprintf (string, sizeof (string),
- "%"PRId64": oldgfid=%s oldpath=%s --> "
- "newgfid=%s newpath=%s", frame->root->unique,
- oldgfid, oldloc->path, newgfid,
- newloc->path);
-
- frame->local = oldloc->inode->gfid;
-
- LOG_ELEMENT (conf, string);
+ gf_log (this->name, GF_LOG_NORMAL,
+ "%"PRId64": (oldloc {path=%s, ino=%"PRIu64"}, "
+ "newloc {path=%s, ino=%"PRIu64"})",
+ frame->root->unique, oldloc->path, oldloc->inode->ino,
+ newloc->path, newloc->inode->ino);
}
-out:
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 stat *stbuf, int32_t valid)
{
- uint64_t ia_time = 0;
- char actime_str[256] = {0,};
- char modtime_str[256] = {0,};
- trace_conf_t *conf = NULL;
-
- conf = this->private;
+ char actime_str[256] = {0,};
+ char modtime_str[256] = {0,};
- if (!conf->log_file && !conf->log_history)
- goto out;
if (trace_fop_names[GF_FOP_SETATTR].enabled) {
- char string[4096] = {0,};
if (valid & GF_SET_ATTR_MODE) {
- snprintf (string, sizeof (string),
- "%"PRId64": gfid=%s path=%s mode=%o)",
- frame->root->unique,
- uuid_utoa (loc->inode->gfid),
- loc->path,
- st_mode_from_ia (stbuf->ia_prot,
- stbuf->ia_type));
-
- LOG_ELEMENT (conf, string);
- memset (string, 0 , sizeof (string));
+ gf_log (this->name, GF_LOG_NORMAL,
+ "%"PRId64": (loc {path=%s, ino=%"PRIu64"},"
+ " mode=%o)", frame->root->unique, loc->path,
+ loc->inode->ino, stbuf->st_mode);
}
if (valid & (GF_SET_ATTR_UID | GF_SET_ATTR_GID)) {
- snprintf (string, sizeof (string),
- "%"PRId64": gfid=%s path=%s uid=%o,"
- " gid=%o", frame->root->unique,
- uuid_utoa (loc->inode->gfid),
- loc->path, stbuf->ia_uid,
- stbuf->ia_gid);
-
- LOG_ELEMENT (conf, string);
- memset (string, 0 , sizeof (string));
+ gf_log (this->name, GF_LOG_NORMAL,
+ "%"PRId64": (loc {path=%s, ino=%"PRIu64"},"
+ " uid=%o, gid=%o)",
+ frame->root->unique, loc->path, loc->inode->ino,
+ stbuf->st_uid, stbuf->st_gid);
}
if (valid & (GF_SET_ATTR_ATIME | GF_SET_ATTR_MTIME)) {
- ia_time = stbuf->ia_atime;
strftime (actime_str, 256, "[%b %d %H:%M:%S]",
- localtime ((time_t *)&ia_time));
-
- ia_time = stbuf->ia_mtime;
+ localtime (&stbuf->st_atime));
strftime (modtime_str, 256, "[%b %d %H:%M:%S]",
- localtime ((time_t *)&ia_time));
-
- snprintf (string, sizeof (string),
- "%"PRId64": gfid=%s path=%s "
- "ia_atime=%s, ia_mtime=%s",
- frame->root->unique,
- uuid_utoa (loc->inode->gfid),
- loc->path, actime_str, modtime_str);
+ localtime (&stbuf->st_mtime));
- LOG_ELEMENT (conf, string);
- memset (string, 0 , sizeof (string));
+ gf_log (this->name, GF_LOG_NORMAL,
+ "%"PRId64": (loc {path=%s, ino=%"PRIu64"}, "
+ "*stbuf=%p {st_atime=%s, st_mtime=%s})",
+ frame->root->unique, loc->path, loc->inode->ino,
+ stbuf, actime_str, modtime_str);
}
- frame->local = loc->inode->gfid;
}
-out:
STACK_WIND (frame, trace_setattr_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->setattr,
- loc, stbuf, valid, xdata);
+ loc, stbuf, valid);
return 0;
}
+
int
trace_fsetattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
- struct iatt *stbuf, int32_t valid, dict_t *xdata)
+ struct stat *stbuf, int32_t valid)
{
- uint64_t ia_time = 0;
- char actime_str[256] = {0,};
- char modtime_str[256] = {0,};
- trace_conf_t *conf = NULL;
-
- conf = this->private;
+ char actime_str[256] = {0,};
+ char modtime_str[256] = {0,};
- if (!conf->log_file && !conf->log_history)
- goto out;
if (trace_fop_names[GF_FOP_FSETATTR].enabled) {
- char string[4096] = {0,};
if (valid & GF_SET_ATTR_MODE) {
- snprintf (string, sizeof (string),
- "%"PRId64": gfid=%s fd=%p, mode=%o",
- frame->root->unique,
- uuid_utoa (fd->inode->gfid), fd,
- st_mode_from_ia (stbuf->ia_prot,
- stbuf->ia_type));
-
- LOG_ELEMENT (conf, string);
- memset (string, 0, sizeof (string));
+ gf_log (this->name, GF_LOG_NORMAL,
+ "%"PRId64": (*fd=%p, mode=%o)",
+ frame->root->unique, fd,
+ stbuf->st_mode);
}
if (valid & (GF_SET_ATTR_UID | GF_SET_ATTR_GID)) {
- snprintf (string, sizeof (string),
- "%"PRId64": gfid=%s fd=%p, uid=%o, "
- "gid=%o", frame->root->unique,
- uuid_utoa (fd->inode->gfid),
- fd, stbuf->ia_uid, stbuf->ia_gid);
-
- LOG_ELEMENT (conf, string);
- memset (string, 0, sizeof (string));
+ gf_log (this->name, GF_LOG_NORMAL,
+ "%"PRId64": (*fd=%p, uid=%o, gid=%o)",
+ frame->root->unique, fd,
+ stbuf->st_uid, stbuf->st_gid);
}
if (valid & (GF_SET_ATTR_ATIME | GF_SET_ATTR_MTIME)) {
- ia_time = stbuf->ia_atime;
strftime (actime_str, 256, "[%b %d %H:%M:%S]",
- localtime ((time_t *)&ia_time));
-
- ia_time = stbuf->ia_mtime;
+ localtime (&stbuf->st_atime));
strftime (modtime_str, 256, "[%b %d %H:%M:%S]",
- localtime ((time_t *)&ia_time));
+ localtime (&stbuf->st_mtime));
- snprintf (string, sizeof (string),
- "%"PRId64": gfid=%s fd=%p "
- "ia_atime=%s, ia_mtime=%s",
- frame->root->unique,
- uuid_utoa (fd->inode->gfid),
- fd, actime_str, modtime_str);
-
- LOG_ELEMENT (conf, string);
- memset (string, 0, sizeof (string));
+ gf_log (this->name, GF_LOG_NORMAL,
+ "%"PRId64": (*fd=%p"
+ "*stbuf=%p {st_atime=%s, st_mtime=%s})",
+ frame->root->unique, fd, stbuf, actime_str,
+ modtime_str);
}
- frame->local = fd->inode->gfid;
}
-out:
STACK_WIND (frame, trace_fsetattr_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->fsetattr,
- fd, stbuf, valid, xdata);
+ fd, stbuf, valid);
return 0;
}
+
int
trace_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc,
- off_t offset, dict_t *xdata)
+ off_t offset)
{
- trace_conf_t *conf = NULL;
-
- conf = this->private;
-
- if (!conf->log_file && !conf->log_history)
- goto out;
if (trace_fop_names[GF_FOP_TRUNCATE].enabled) {
- char string[4096] = {0,};
- snprintf (string, sizeof (string),
- "%"PRId64": gfid=%s path=%s, "
- "offset=%"PRId64"", frame->root->unique,
- uuid_utoa (loc->inode->gfid), loc->path,
- offset);
-
- frame->local = loc->inode->gfid;
-
- LOG_ELEMENT (conf, string);
+ gf_log (this->name, GF_LOG_NORMAL,
+ "%"PRId64": (loc {path=%s, ino=%"PRIu64"}, offset=%"PRId64")",
+ frame->root->unique, loc->path, loc->inode->ino, offset);
}
-out:
STACK_WIND (frame, trace_truncate_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->truncate,
- loc, offset, xdata);
+ loc, offset);
return 0;
}
+
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)
{
- trace_conf_t *conf = NULL;
-
- conf = this->private;
-
- if (!conf->log_file && !conf->log_history)
- goto out;
if (trace_fop_names[GF_FOP_OPEN].enabled) {
- char string[4096] = {0,};
- snprintf (string, sizeof (string),
- "%"PRId64": gfid=%s path=%s flags=%d fd=%p",
- frame->root->unique,
- uuid_utoa (loc->inode->gfid), loc->path,
- flags, fd);
-
- frame->local = loc->inode->gfid;
-
- LOG_ELEMENT (conf, string);
+ gf_log (this->name, GF_LOG_NORMAL,
+ "%"PRId64": (loc {path=%s, ino=%"PRIu64"}, flags=%d, "
+ "fd=%p, wbflags=%d)",
+ frame->root->unique, loc->path, loc->inode->ino, flags,
+ fd, wbflags);
}
-out:
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)
{
- trace_conf_t *conf = NULL;
-
- conf = this->private;
-
- if (!conf->log_file && !conf->log_history)
- goto out;
if (trace_fop_names[GF_FOP_CREATE].enabled) {
- char string[4096] = {0,};
- snprintf (string, sizeof (string),
- "%"PRId64": gfid=%s path=%s, fd=%p, "
- "flags=0%o mode=0%o umask=0%o",
- frame->root->unique,
- uuid_utoa (loc->inode->gfid), loc->path,
- fd, flags, mode, umask);
-
- LOG_ELEMENT (conf, string);
+ gf_log (this->name, GF_LOG_NORMAL,
+ "%"PRId64": (loc {path=%s, ino=%"PRIu64"}, flags=0%o mode=0%o)",
+ frame->root->unique, loc->path, loc->inode->ino, flags, mode);
}
-out:
STACK_WIND (frame, trace_create_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->create,
- loc, flags, mode, umask, fd, xdata);
+ loc, flags, mode, fd);
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)
{
- trace_conf_t *conf = NULL;
-
- conf = this->private;
-
- if (!conf->log_file && !conf->log_history)
- goto out;
if (trace_fop_names[GF_FOP_READ].enabled) {
- char string[4096] = {0,};
- snprintf (string, sizeof (string),
- "%"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);
-
- frame->local = fd->inode->gfid;
-
- LOG_ELEMENT (conf, string);
+ gf_log (this->name, GF_LOG_NORMAL,
+ "%"PRId64": (*fd=%p, size=%"GF_PRI_SIZET", offset=%"PRId64")",
+ frame->root->unique, fd, size, offset);
}
-out:
STACK_WIND (frame, trace_readv_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->readv,
- fd, size, offset, flags, xdata);
+ fd, size, offset);
return 0;
}
+
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)
{
- trace_conf_t *conf = NULL;
-
- conf = this->private;
-
- if (!conf->log_file && !conf->log_history)
- goto out;
if (trace_fop_names[GF_FOP_WRITE].enabled) {
- char string[4096] = {0,};
- snprintf (string, sizeof (string),
- "%"PRId64": gfid=%s fd=%p, count=%d, "
- " offset=%"PRId64" flags=0%x)",
- frame->root->unique,
- uuid_utoa (fd->inode->gfid), fd, count,
- offset, flags);
-
- frame->local = fd->inode->gfid;
-
- LOG_ELEMENT (conf, string);
+ gf_log (this->name, GF_LOG_NORMAL,
+ "%"PRId64": (*fd=%p, *vector=%p, count=%d, offset=%"PRId64")",
+ frame->root->unique, fd, vector, count, offset);
}
-out:
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)
{
- trace_conf_t *conf = NULL;
-
- conf = this->private;
-
- if (!conf->log_file && !conf->log_history)
- goto out;
if (trace_fop_names[GF_FOP_STATFS].enabled) {
- char string[4096] = {0,};
- snprintf (string, sizeof (string),
- "%"PRId64": gfid=%s path=%s",
- frame->root->unique, (loc->inode)?
- uuid_utoa (loc->inode->gfid):"0", loc->path);
-
- LOG_ELEMENT (conf, string);
+ gf_log (this->name, GF_LOG_NORMAL,
+ "%"PRId64": (loc {path=%s, ino=%"PRIu64"})",
+ frame->root->unique, loc->path,
+ ((loc->inode)? loc->inode->ino : 0));
}
-out:
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)
{
- trace_conf_t *conf = NULL;
-
- conf = this->private;
-
- if (!conf->log_file && !conf->log_history)
- goto out;
if (trace_fop_names[GF_FOP_FLUSH].enabled) {
- char string[4096] = {0,};
- snprintf (string, sizeof (string),
- "%"PRId64": gfid=%s fd=%p",
- frame->root->unique,
- uuid_utoa (fd->inode->gfid), fd);
-
- frame->local = fd->inode->gfid;
-
- LOG_ELEMENT (conf, string);
+ gf_log (this->name, GF_LOG_NORMAL,
+ "%"PRId64": (*fd=%p)",
+ frame->root->unique, fd);
}
-out:
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)
{
- trace_conf_t *conf = NULL;
-
- conf = this->private;
-
- if (!conf->log_file && !conf->log_history)
- goto out;
if (trace_fop_names[GF_FOP_FSYNC].enabled) {
- char string[4096] = {0,};
- snprintf (string, sizeof (string),
- "%"PRId64": gfid=%s flags=%d fd=%p",
- frame->root->unique,
- uuid_utoa (fd->inode->gfid), flags, fd);
-
- frame->local = fd->inode->gfid;
-
- LOG_ELEMENT (conf, string);
+ gf_log (this->name, GF_LOG_NORMAL,
+ "%"PRId64": (flags=%d, *fd=%p)",
+ frame->root->unique, flags, fd);
}
-out:
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)
{
- trace_conf_t *conf = NULL;
-
- conf = this->private;
-
- if (!conf->log_file && !conf->log_history)
- goto out;
if (trace_fop_names[GF_FOP_SETXATTR].enabled) {
- char string[4096] = {0,};
- snprintf (string, sizeof (string),
- "%"PRId64": gfid=%s path=%s flags=%d",
- frame->root->unique,
- uuid_utoa (loc->inode->gfid), loc->path,
- flags);
-
- frame->local = loc->inode->gfid;
-
- LOG_ELEMENT (conf, string);
+ gf_log (this->name, GF_LOG_NORMAL,
+ "%"PRId64": (loc {path=%s, ino=%"PRIu64"}, dict=%p, flags=%d)",
+ frame->root->unique, loc->path,
+ ((loc->inode)? loc->inode->ino : 0), dict, flags);
}
-out:
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)
{
- trace_conf_t *conf = NULL;
-
- conf = this->private;
-
- if (!conf->log_file && !conf->log_history)
- goto out;
if (trace_fop_names[GF_FOP_GETXATTR].enabled) {
- char string[4096] = {0,};
- snprintf (string, sizeof (string),
- "%"PRId64": gfid=%s path=%s name=%s",
- frame->root->unique,
- uuid_utoa (loc->inode->gfid), loc->path,
- name);
-
- frame->local = loc->inode->gfid;
-
- LOG_ELEMENT (conf, string);
+ gf_log (this->name, GF_LOG_NORMAL,
+ "%"PRId64": (loc {path=%s, ino=%"PRIu64"}), name=%s",
+ frame->root->unique, loc->path,
+ ((loc->inode)? loc->inode->ino : 0), name);
}
-out:
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)
{
- trace_conf_t *conf = NULL;
-
- conf = this->private;
-
- if (!conf->log_file && !conf->log_history)
- goto out;
if (trace_fop_names[GF_FOP_REMOVEXATTR].enabled) {
- char string[4096] = {0,};
- snprintf (string, sizeof (string),
- "%"PRId64": gfid=%s path=%s name=%s",
- frame->root->unique,
- uuid_utoa (loc->inode->gfid), loc->path,
- name);
-
- frame->local = loc->inode->gfid;
-
- LOG_ELEMENT (conf, string);
+ gf_log (this->name, GF_LOG_NORMAL,
+ "%"PRId64": (loc {path=%s, ino=%"PRIu64"}, name=%s)",
+ frame->root->unique, loc->path,
+ ((loc->inode)? loc->inode->ino : 0), name);
}
-out:
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)
{
- trace_conf_t *conf = NULL;
-
- conf = this->private;
-
- if (!conf->log_file && !conf->log_history)
- goto out;
if (trace_fop_names[GF_FOP_OPENDIR].enabled) {
- char string[4096] = {0,};
- snprintf (string, sizeof (string),
- "%"PRId64": gfid=%s path=%s fd=%p",
- frame->root->unique,
- uuid_utoa (loc->inode->gfid), loc->path, fd);
-
- frame->local = loc->inode->gfid;
-
- LOG_ELEMENT (conf, string);
+ gf_log (this->name, GF_LOG_NORMAL,
+ "%"PRId64":( loc {path=%s, ino=%"PRIu64"}, fd=%p)",
+ frame->root->unique, loc->path, loc->inode->ino, fd);
}
-out:
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)
+trace_getdents (call_frame_t *frame, xlator_t *this, fd_t *fd,
+ size_t size, off_t offset, int32_t flag)
{
- trace_conf_t *conf = NULL;
-
- conf = this->private;
+ if (trace_fop_names[GF_FOP_GETDENTS].enabled) {
+ gf_log (this->name, GF_LOG_NORMAL,
+ "%"PRId64": (fd=%p, size=%"GF_PRI_SIZET", offset=%"PRId64", flag=0x%x)",
+ frame->root->unique, fd, size, offset, flag);
+ }
- if (!conf->log_file && !conf->log_history)
- goto out;
- if (trace_fop_names[GF_FOP_READDIRP].enabled) {
- char string[4096] = {0,};
- snprintf (string, sizeof (string),
- "%"PRId64": gfid=%s fd=%p, size=%"GF_PRI_SIZET
- ", offset=%"PRId64" dict=%p",
- frame->root->unique,
- uuid_utoa (fd->inode->gfid), fd, size,
- offset, dict);
+ STACK_WIND (frame, trace_getdents_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->getdents,
+ fd, size, offset, flag);
+ return 0;
+}
- frame->local = fd->inode->gfid;
- LOG_ELEMENT (conf, string);
+int
+trace_readdirp (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
+ off_t offset)
+{
+ if (trace_fop_names[GF_FOP_READDIRP].enabled) {
+ gf_log (this->name, GF_LOG_NORMAL,
+ "%"PRId64": (fd=%p, size=%"GF_PRI_SIZET", offset=%"PRId64")",
+ frame->root->unique, fd, size, offset);
}
-out:
STACK_WIND (frame, trace_readdirp_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->readdirp,
- fd, size, offset, dict);
+ fd, size, offset);
return 0;
}
+
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)
{
- trace_conf_t *conf = NULL;
-
- conf = this->private;
-
- if (!conf->log_file && !conf->log_history)
- goto out;
if (trace_fop_names[GF_FOP_READDIR].enabled) {
- char string[4096] = {0,};
- snprintf (string, sizeof (string),
- "%"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;
-
- LOG_ELEMENT (conf, string);
+ gf_log (this->name, GF_LOG_NORMAL,
+ "%"PRId64": (fd=%p, size=%"GF_PRI_SIZET", offset=%"PRId64")",
+ frame->root->unique, fd, size, offset);
}
-out:
STACK_WIND (frame, trace_readdir_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->readdir,
- fd, size, offset, xdata);
+ fd, size, offset);
return 0;
}
+
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)
{
- trace_conf_t *conf = NULL;
-
- conf = this->private;
-
- if (!conf->log_file && !conf->log_history)
- goto out;
if (trace_fop_names[GF_FOP_FSYNCDIR].enabled) {
- char string[4096] = {0,};
- snprintf (string, sizeof (string),
- "%"PRId64": gfid=%s datasync=%d fd=%p",
- frame->root->unique,
- uuid_utoa (fd->inode->gfid), datasync, fd);
-
- frame->local = fd->inode->gfid;
-
- LOG_ELEMENT (conf, string);
+ gf_log (this->name, GF_LOG_NORMAL,
+ "%"PRId64": (datasync=%d, *fd=%p)",
+ frame->root->unique, datasync, fd);
}
-out:
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)
{
- trace_conf_t *conf = NULL;
-
- conf = this->private;
-
- if (!conf->log_file && !conf->log_history)
- goto out;
if (trace_fop_names[GF_FOP_ACCESS].enabled) {
- char string[4096] = {0,};
- snprintf (string, sizeof (string),
- "%"PRId64": gfid=%s path=%s mask=0%o",
- frame->root->unique,
- uuid_utoa (loc->inode->gfid),
- loc->path, mask);
-
- frame->local = loc->inode->gfid;
-
- LOG_ELEMENT (conf, string);
+ gf_log (this->name, GF_LOG_NORMAL,
+ "%"PRId64": (*loc {path=%s, ino=%"PRIu64"}, mask=0%o)",
+ frame->root->unique, loc->path,
+ ((loc->inode)? loc->inode->ino : 0), mask);
}
-out:
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)
-{
-
- trace_conf_t *conf = NULL;
-
- conf = this->private;
-
- if (!conf->log_file && !conf->log_history)
- goto out;
- if (trace_fop_names[GF_FOP_RCHECKSUM].enabled) {
- char string[4096] = {0,};
- snprintf (string, sizeof (string),
- "%"PRId64": gfid=%s offset=%"PRId64
- "len=%u fd=%p", frame->root->unique,
- uuid_utoa (fd->inode->gfid), offset, len, fd);
-
- frame->local = fd->inode->gfid;
-
- LOG_ELEMENT (conf, string);
- }
-
-out:
- STACK_WIND (frame, trace_rchecksum_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->rchecksum,
- fd, offset, len, xdata);
-
- return 0;
-
-}
-
-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)
-{
- trace_conf_t *conf = NULL;
-
- conf = this->private;
-
- if (!conf->log_file && !conf->log_history)
- goto out;
- if (trace_fop_names[GF_FOP_FENTRYLK].enabled) {
- char string[4096] = {0,};
- snprintf (string, sizeof (string),
- "%"PRId64": gfid=%s volume=%s, (fd=%p "
- "basename=%s, cmd=%s, type=%s)",
- frame->root->unique,
- uuid_utoa (fd->inode->gfid), volume, fd,
- basename,
- ((cmd == ENTRYLK_LOCK) ? "ENTRYLK_LOCK" :
- "ENTRYLK_UNLOCK"),
- ((type == ENTRYLK_RDLCK) ? "ENTRYLK_RDLCK" :
- "ENTRYLK_WRLCK"));
-
- frame->local = fd->inode->gfid;
-
- LOG_ELEMENT (conf, string);
- }
-
-out:
- STACK_WIND (frame, trace_fentrylk_cbk,
- FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->fentrylk,
- volume, fd, basename, cmd, type, xdata);
- return 0;
-
-}
-
-int32_t
-trace_fgetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
- const char *name, dict_t *xdata)
-{
- trace_conf_t *conf = NULL;
-
- conf = this->private;
-
- if (!conf->log_file && !conf->log_history)
- goto out;
- if (trace_fop_names[GF_FOP_FGETXATTR].enabled) {
- char string[4096] = {0,};
- snprintf (string, sizeof (string),
- "%"PRId64": gfid=%s fd=%p name=%s",
- frame->root->unique,
- uuid_utoa (fd->inode->gfid), fd, name);
-
- frame->local = fd->inode->gfid;
-
- LOG_ELEMENT (conf, string);
- }
-
-out:
- STACK_WIND (frame, trace_fgetxattr_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fgetxattr,
- fd, name, xdata);
- 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)
-{
- trace_conf_t *conf = NULL;
-
- conf = this->private;
-
- if (!conf->log_file && !conf->log_history)
- goto out;
- if (trace_fop_names[GF_FOP_FSETXATTR].enabled) {
- char string[4096] = {0,};
- snprintf (string, sizeof (string),
- "%"PRId64": gfid=%s fd=%p flags=%d",
- frame->root->unique,
- uuid_utoa (fd->inode->gfid), fd, flags);
-
- frame->local = fd->inode->gfid;
-
- LOG_ELEMENT (conf, string);
- }
-
-out:
- STACK_WIND (frame, trace_fsetxattr_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fsetxattr,
- fd, dict, flags, xdata);
- 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)
{
- trace_conf_t *conf = NULL;
-
- conf = this->private;
-
- if (!conf->log_file && !conf->log_history)
- goto out;
if (trace_fop_names[GF_FOP_FTRUNCATE].enabled) {
- char string[4096] = {0,};
- snprintf (string, sizeof (string),
- "%"PRId64": gfid=%s offset=%"PRId64" fd=%p",
- frame->root->unique,
- uuid_utoa (fd->inode->gfid), offset, fd);
-
- frame->local = fd->inode->gfid;
-
- LOG_ELEMENT (conf, string);
+ gf_log (this->name, GF_LOG_NORMAL,
+ "%"PRId64": (offset=%"PRId64", *fd=%p)",
+ frame->root->unique, offset, fd);
}
-out:
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)
{
- trace_conf_t *conf = NULL;
-
- conf = this->private;
-
- if (!conf->log_file && !conf->log_history)
- goto out;
if (trace_fop_names[GF_FOP_FSTAT].enabled) {
- char string[4096] = {0,};
- snprintf (string, sizeof (string),
- "%"PRId64": gfid=%s fd=%p",
- frame->root->unique,
- uuid_utoa (fd->inode->gfid), fd);
-
- frame->local = fd->inode->gfid;
-
- LOG_ELEMENT (conf, string);
+ gf_log (this->name, GF_LOG_NORMAL,
+ "%"PRId64": (*fd=%p)",
+ frame->root->unique, fd);
}
-out:
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 flock *lock)
{
- trace_conf_t *conf = NULL;
-
- conf = this->private;
-
- if (!conf->log_file && !conf->log_history)
- goto out;
if (trace_fop_names[GF_FOP_LK].enabled) {
- char string[4096] = {0,};
- snprintf (string, sizeof (string),
- "%"PRId64": gfid=%s fd=%p, cmd=%d, "
- "lock {l_type=%d, "
- "l_whence=%d, l_start=%"PRId64", "
- "l_len=%"PRId64", l_pid=%u})",
- frame->root->unique,
- uuid_utoa (fd->inode->gfid), fd, cmd,
- lock->l_type, lock->l_whence,
- lock->l_start, lock->l_len, lock->l_pid);
-
- frame->local = fd->inode->gfid;
-
- LOG_ELEMENT (conf, string);
+ gf_log (this->name, GF_LOG_NORMAL,
+ "%"PRId64": (*fd=%p, cmd=%d, lock {l_type=%d, l_whence=%d, "
+ "l_start=%"PRId64", l_len=%"PRId64", l_pid=%u})",
+ frame->root->unique, fd, cmd, lock->l_type, lock->l_whence,
+ lock->l_start, lock->l_len, lock->l_pid);
}
-out:
STACK_WIND (frame, trace_lk_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->lk,
- fd, cmd, lock, xdata);
+ fd, cmd, lock);
return 0;
}
-int32_t
-trace_forget (xlator_t *this, inode_t *inode)
-{
- trace_conf_t *conf = NULL;
-
- conf = this->private;
- /* If user want to understand when a lookup happens,
- he should know about 'forget' too */
- if (!conf->log_file && !conf->log_history)
- goto out;
- if (trace_fop_names[GF_FOP_LOOKUP].enabled) {
- char string[4096] = {0,};
- snprintf (string, sizeof (string),
- "gfid=%s", uuid_utoa (inode->gfid));
- LOG_ELEMENT (conf, string);
+int
+trace_setdents (call_frame_t *frame, xlator_t *this, fd_t *fd,
+ int32_t flags, dir_entry_t *entries, int32_t count)
+{
+ if (trace_fop_names[GF_FOP_SETDENTS].enabled) {
+ gf_log (this->name, GF_LOG_NORMAL,
+ "%"PRId64": (*fd=%p, flags=%d, count=%d",
+ frame->root->unique, fd, flags, count);
}
-out:
+ STACK_WIND (frame, trace_setdents_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->setdents,
+ fd, flags, entries, count);
return 0;
}
-int32_t
-trace_releasedir (xlator_t *this, fd_t *fd)
+
+int
+trace_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)
{
- trace_conf_t *conf = NULL;
+ gf_log (this->name, GF_LOG_NORMAL,
+ "%"PRId64": op_ret (%d), op_errno(%d)",
+ frame->root->unique, op_ret, op_errno);
- conf = this->private;
+ STACK_UNWIND_STRICT (checksum, frame, op_ret, op_errno,
+ fchecksum, dchecksum);
- if (!conf->log_file && !conf->log_history)
- goto out;
- if (trace_fop_names[GF_FOP_OPENDIR].enabled) {
- char string[4096] = {0,};
- snprintf (string, sizeof (string),
- "gfid=%s fd=%p",
- uuid_utoa (fd->inode->gfid), fd);
+ return 0;
+}
- LOG_ELEMENT (conf, string);
- }
-out:
+int
+trace_checksum (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flag)
+{
+ gf_log (this->name, GF_LOG_NORMAL,
+ "%"PRId64": loc->path (%s) flag (%d)",
+ frame->root->unique, loc->path, flag);
+
+ STACK_WIND (frame, trace_checksum_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->checksum,
+ loc, flag);
+
return 0;
}
-int32_t
-trace_release (xlator_t *this, fd_t *fd)
+
+int
+trace_stats_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno,
+ struct xlator_stats *stats)
{
- trace_conf_t *conf = NULL;
+ gf_log (this->name, GF_LOG_NORMAL,
+ "%"PRId64": op_ret (%d), op_errno(%d)",
+ frame->root->unique, op_ret, op_errno);
- conf = this->private;
+ STACK_UNWIND (frame, op_ret, op_errno, stats);
+ return 0;
+}
- if (!conf->log_file && !conf->log_history)
- goto out;
- if (trace_fop_names[GF_FOP_OPEN].enabled ||
- trace_fop_names[GF_FOP_CREATE].enabled) {
- char string[4096] = {0,};
- snprintf (string, sizeof (string),
- "gfid=%s fd=%p",
- uuid_utoa (fd->inode->gfid), fd);
- LOG_ELEMENT (conf, string);
- }
+int
+trace_stats (call_frame_t *frame, xlator_t *this, int32_t flags)
+{
+ gf_log (this->name, GF_LOG_NORMAL,
+ "%"PRId64": (flags=%d)",
+ frame->root->unique, flags);
+
+ STACK_WIND (frame, trace_stats_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->mops->stats,
+ flags);
-out:
return 0;
}
@@ -2968,6 +2014,7 @@ enable_all_calls (int enabled)
trace_fop_names[i].enabled = enabled;
}
+
void
enable_call (const char *name, int enabled)
{
@@ -2995,116 +2042,12 @@ process_call_list (const char *list, int include)
}
}
-int32_t
-trace_dump_history (xlator_t *this)
-{
- int ret = -1;
- char key_prefix[GF_DUMP_MAX_BUF_LEN] = {0,};
- trace_conf_t *conf = NULL;
-
- GF_VALIDATE_OR_GOTO ("trace", this, out);
- GF_VALIDATE_OR_GOTO (this->name, this->history, out);
-
- conf = this->private;
- // Is it ok to return silently if log-history option his off?
- if (conf && conf->log_history == _gf_true) {
- gf_proc_dump_build_key (key_prefix, "xlator.debug.trace",
- "history");
- gf_proc_dump_add_section (key_prefix);
- eh_dump (this->history, NULL, dump_history_trace);
- }
- ret = 0;
-
-out:
- return ret;
-}
-
-int32_t
-mem_acct_init (xlator_t *this)
-{
- int ret = -1;
-
- if (!this)
- return ret;
-
- ret = xlator_mem_acct_init (this, gf_trace_mt_end + 1);
-
- if (ret != 0) {
- gf_log (this->name, GF_LOG_ERROR, "Memory accounting init"
- " failed");
- return ret;
- }
-
- return ret;
-}
-
-int
-reconfigure (xlator_t *this, dict_t *options)
-{
- int32_t ret = -1;
- trace_conf_t *conf = NULL;
- char *includes = NULL, *excludes = NULL;
-
- 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);
-
- conf = this->private;
-
- includes = data_to_str (dict_get (options, "include-ops"));
- excludes = data_to_str (dict_get (options, "exclude-ops"));
-
- {
- int i;
- for (i = 0; i < GF_FOP_MAXVALUE; i++) {
- if (gf_fop_list[i])
- strncpy (trace_fop_names[i].name,
- gf_fop_list[i],
- strlen (gf_fop_list[i]));
- else
- strncpy (trace_fop_names[i].name, ":O",
- strlen (":O"));
- trace_fop_names[i].enabled = 1;
- }
- }
-
- if (includes && excludes) {
- gf_log (this->name,
- GF_LOG_ERROR,
- "must specify only one of 'include-ops' and "
- "'exclude-ops'");
- goto out;
- }
-
- if (includes)
- process_call_list (includes, 1);
- if (excludes)
- process_call_list (excludes, 0);
-
- /* Should resizing of the event-history be allowed in reconfigure?
- * for which a new event_history might have to be allocated and the
- * older history has to be freed.
- */
- GF_OPTION_RECONF ("log-file", conf->log_file, options, bool, out);
-
- GF_OPTION_RECONF ("log-history", conf->log_history, options, bool, out);
-
- ret = 0;
-
-out:
- return ret;
-}
int32_t
init (xlator_t *this)
{
dict_t *options = NULL;
char *includes = NULL, *excludes = NULL;
- char *forced_loglevel = NULL;
- eh_t *history = NULL;
- int ret = -1;
- size_t history_size = TRACE_DEFAULT_HISTORY_SIZE;
- trace_conf_t *conf = NULL;
if (!this)
return -1;
@@ -3119,12 +2062,6 @@ init (xlator_t *this)
"dangling volume. check volfile ");
}
- conf = GF_CALLOC (1, sizeof (trace_conf_t), gf_trace_mt_trace_conf_t);
- if (!conf) {
- gf_log (this->name, GF_LOG_ERROR, "cannot allocate "
- "xl->private");
- return -1;
- }
options = this->options;
includes = data_to_str (dict_get (options, "include-ops"));
@@ -3133,13 +2070,8 @@ init (xlator_t *this)
{
int i;
for (i = 0; i < GF_FOP_MAXVALUE; i++) {
- if (gf_fop_list[i])
- strncpy (trace_fop_names[i].name,
- gf_fop_list[i],
- strlen (gf_fop_list[i]));
- else
- strncpy (trace_fop_names[i].name, ":O",
- strlen (":O"));
+ trace_fop_names[i].name = (gf_fop_list[i] ?
+ gf_fop_list[i] : ":O");
trace_fop_names[i].enabled = 1;
}
}
@@ -3147,78 +2079,21 @@ init (xlator_t *this)
if (includes && excludes) {
gf_log (this->name,
GF_LOG_ERROR,
- "must specify only one of 'include-ops' and "
- "'exclude-ops'");
+ "must specify only one of 'include-ops' and 'exclude-ops'");
return -1;
}
-
if (includes)
process_call_list (includes, 1);
if (excludes)
process_call_list (excludes, 0);
+ if (gf_log_get_loglevel () < GF_LOG_NORMAL)
+ gf_log_set_loglevel (GF_LOG_NORMAL);
- GF_OPTION_INIT ("history-size", conf->history_size, size, out);
-
- gf_log (this->name, GF_LOG_INFO, "history size %"GF_PRI_SIZET,
- history_size);
-
- GF_OPTION_INIT ("log-file", conf->log_file, bool, out);
-
- gf_log (this->name, GF_LOG_INFO, "logging to file %s",
- (conf->log_file == _gf_true)?"enabled":"disabled");
-
- GF_OPTION_INIT ("log-history", conf->log_history, bool, out);
-
- gf_log (this->name, GF_LOG_DEBUG, "logging to history %s",
- (conf->log_history == _gf_true)?"enabled":"disabled");
+ /* Set this translator's inode table pointer to child node's pointer. */
+ this->itable = FIRST_CHILD (this)->itable;
- history = eh_new (history_size, _gf_false, NULL);
- if (!history) {
- gf_log (this->name, GF_LOG_ERROR, "event history cannot be "
- "initialized");
- return -1;
- }
-
- this->history = history;
-
- conf->trace_log_level = GF_LOG_INFO;
-
- if (dict_get (options, "force-log-level")) {
- forced_loglevel = data_to_str (dict_get (options,
- "force-log-level"));
- if (!forced_loglevel)
- goto setloglevel;
-
- if (strcmp (forced_loglevel, "INFO") == 0)
- conf->trace_log_level = GF_LOG_INFO;
- else if (strcmp (forced_loglevel, "TRACE") == 0)
- conf->trace_log_level = GF_LOG_TRACE;
- else if (strcmp (forced_loglevel, "ERROR") == 0)
- conf->trace_log_level = GF_LOG_ERROR;
- else if (strcmp (forced_loglevel, "DEBUG") == 0)
- conf->trace_log_level = GF_LOG_DEBUG;
- else if (strcmp (forced_loglevel, "WARNING") == 0)
- conf->trace_log_level = GF_LOG_WARNING;
- else if (strcmp (forced_loglevel, "CRITICAL") == 0)
- conf->trace_log_level = GF_LOG_CRITICAL;
- else if (strcmp (forced_loglevel, "NONE") == 0)
- conf->trace_log_level = GF_LOG_NONE;
- }
-
-setloglevel:
- gf_log_set_loglevel (conf->trace_log_level);
- this->private = conf;
- ret = 0;
-out:
- if (ret == -1) {
- if (history)
- GF_FREE (history);
- if (conf)
- GF_FREE (conf);
- }
-
- return ret;
+ return 0;
}
void
@@ -3227,10 +2102,7 @@ fini (xlator_t *this)
if (!this)
return;
- if (this->history)
- eh_destroy (this->history);
-
- gf_log (this->name, GF_LOG_INFO,
+ gf_log (this->name, GF_LOG_NORMAL,
"trace translator unloaded");
return;
}
@@ -3254,8 +2126,6 @@ struct xlator_fops fops = {
.fsync = trace_fsync,
.setxattr = trace_setxattr,
.getxattr = trace_getxattr,
- .fsetxattr = trace_fsetxattr,
- .fgetxattr = trace_fgetxattr,
.removexattr = trace_removexattr,
.opendir = trace_opendir,
.readdir = trace_readdir,
@@ -3269,19 +2139,21 @@ struct xlator_fops fops = {
.inodelk = trace_inodelk,
.finodelk = trace_finodelk,
.entrylk = trace_entrylk,
- .fentrylk = trace_fentrylk,
.lookup = trace_lookup,
- .rchecksum = trace_rchecksum,
+ .setdents = trace_setdents,
+ .getdents = trace_getdents,
+ .checksum = trace_checksum,
.xattrop = trace_xattrop,
.fxattrop = trace_fxattrop,
.setattr = trace_setattr,
.fsetattr = trace_fsetattr,
};
+struct xlator_mops mops = {
+ .stats = trace_stats,
+};
+
struct xlator_cbks cbks = {
- .release = trace_release,
- .releasedir = trace_releasedir,
- .forget = trace_forget,
};
struct volume_options options[] = {
@@ -3293,21 +2165,5 @@ struct volume_options options[] = {
.type = GF_OPTION_TYPE_STR
/*.value = { ""} */
},
- { .key = {"history-size"},
- .type = GF_OPTION_TYPE_SIZET,
- .default_value = "1024",
- },
- { .key = {"log-file"},
- .type = GF_OPTION_TYPE_BOOL,
- .default_value = "no",
- },
- { .key = {"log-history"},
- .type = GF_OPTION_TYPE_BOOL,
- .default_value = "no",
- },
{ .key = {NULL} },
};
-
-struct xlator_dumpops dumpops = {
- .history = trace_dump_history
-};
diff --git a/xlators/debug/trace/src/trace.h b/xlators/debug/trace/src/trace.h
deleted file mode 100644
index 62d1bc9c921..00000000000
--- a/xlators/debug/trace/src/trace.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- Copyright (c) 2006-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 <time.h>
-#include <errno.h>
-#include "glusterfs.h"
-#include "xlator.h"
-#include "common-utils.h"
-#include "event-history.h"
-#include "logging.h"
-#include "circ-buff.h"
-#include "statedump.h"
-#include "options.h"
-
-#define TRACE_DEFAULT_HISTORY_SIZE 1024
-
-typedef struct {
- /* Since the longest fop name is fremovexattr i.e 12 characters, array size
- * is kept 24, i.e double of the maximum.
- */
- char name[24];
- int enabled;
-} trace_fop_name_t;
-
-trace_fop_name_t trace_fop_names[GF_FOP_MAXVALUE];
-
-typedef struct {
- gf_boolean_t log_file;
- gf_boolean_t log_history;
- size_t history_size;
- int trace_log_level;
-} trace_conf_t;
-
-#define TRACE_STACK_UNWIND(op, frame, params ...) \
- do { \
- frame->local = NULL; \
- STACK_UNWIND_STRICT (op, frame, params); \
- } while (0);
-
-#define LOG_ELEMENT(_conf, _string) \
- do { \
- if (_conf) { \
- if ((_conf->log_history) == _gf_true) \
- gf_log_eh ("%s", _string); \
- if ((_conf->log_file) == _gf_true) \
- gf_log (THIS->name, _conf->trace_log_level, \
- "%s", _string); \
- } \
- } while (0);
diff --git a/xlators/encryption/Makefile.am b/xlators/encryption/Makefile.am
index 36efc6698bd..2cbde680fac 100644
--- a/xlators/encryption/Makefile.am
+++ b/xlators/encryption/Makefile.am
@@ -1,3 +1,3 @@
-SUBDIRS = rot-13 crypt
+SUBDIRS = rot-13
CLEANFILES =
diff --git a/xlators/encryption/crypt/src/Makefile.am b/xlators/encryption/crypt/src/Makefile.am
deleted file mode 100644
index b13f65043d3..00000000000
--- a/xlators/encryption/crypt/src/Makefile.am
+++ /dev/null
@@ -1,24 +0,0 @@
-if ENABLE_CRYPT_XLATOR
-
-xlator_LTLIBRARIES = crypt.la
-xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/encryption
-
-crypt_la_LDFLAGS = -module -avoid-version -lssl -lcrypto
-
-crypt_la_SOURCES = keys.c data.c metadata.c atom.c crypt.c
-crypt_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la
-
-noinst_HEADERS = crypt-common.h crypt-mem-types.h crypt.h metadata.h
-
-AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src
-
-AM_CFLAGS = -Wall $(GF_CFLAGS)
-
-CLEANFILES =
-
-else
-
-noinst_DIST = keys.c data.c metadata.c atom.c crypt.c
-noinst_HEADERS = crypt-common.h crypt-mem-types.h crypt.h metadata.h
-
-endif \ No newline at end of file
diff --git a/xlators/encryption/crypt/src/atom.c b/xlators/encryption/crypt/src/atom.c
deleted file mode 100644
index 1ec41495ca1..00000000000
--- a/xlators/encryption/crypt/src/atom.c
+++ /dev/null
@@ -1,962 +0,0 @@
-/*
- Copyright (c) 2008-2013 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 "defaults.h"
-#include "crypt-common.h"
-#include "crypt.h"
-
-/*
- * Glossary
- *
- *
- * cblock (or cipher block). A logical unit in a file.
- * cblock size is defined as the number of bits
- * in an input (or output) block of the block
- * cipher (*). Cipher block size is a property of
- * cipher algorithm. E.g. cblock size is 64 bits
- * for DES, 128 bits for AES, etc.
- *
- * atomic cipher A cipher algorithm, which requires some chunks of
- * algorithm text to be padded at left and(or) right sides before
- * cipher transaform.
- *
- *
- * block (atom) Minimal chunk of file's data, which doesn't require
- * padding. We'll consider logical units in a file of
- * block size (atom size).
- *
- * cipher algorithm Atomic cipher algorithm, which requires the last
- * with EOF issue incomplete cblock in a file to be padded with some
- * data (usually zeros).
- *
- *
- * operation, which reading/writing from offset, which is not aligned to
- * forms a gap at to atom size
- * the beginning
- *
- *
- * operation, which reading/writing count bytes starting from offset off,
- * forms a gap at so that off+count is not aligned to atom_size
- * the end
- *
- * head block the first atom affected by an operation, which forms
- * a gap at the beginning, or(and) at the end.
- * Сomment. Head block has at least one gap (either at
- * the beginning, or at the end)
- *
- *
- * tail block the last atom different from head, affected by an
- * operation, which forms a gap at the end.
- * Сomment: Tail block has exactly one gap (at the end).
- *
- *
- * partial block head or tail block
- *
- *
- * full block block without gaps.
- *
- *
- * (*) Recommendation for Block Cipher Modes of Operation
- * Methods and Techniques
- * NIST Special Publication 800-38A Edition 2001
- */
-
-/*
- * atom->offset_at()
- */
-static off_t offset_at_head(struct avec_config *conf)
-{
- return conf->aligned_offset;
-}
-
-static off_t offset_at_hole_head(call_frame_t *frame,
- struct object_cipher_info *object)
-{
- return offset_at_head(get_hole_conf(frame));
-}
-
-static off_t offset_at_data_head(call_frame_t *frame,
- struct object_cipher_info *object)
-{
- return offset_at_head(get_data_conf(frame));
-}
-
-
-static off_t offset_at_tail(struct avec_config *conf,
- struct object_cipher_info *object)
-{
- return conf->aligned_offset +
- (conf->off_in_head ? get_atom_size(object) : 0) +
- (conf->nr_full_blocks << get_atom_bits(object));
-}
-
-static off_t offset_at_hole_tail(call_frame_t *frame,
- struct object_cipher_info *object)
-{
- return offset_at_tail(get_hole_conf(frame), object);
-}
-
-
-static off_t offset_at_data_tail(call_frame_t *frame,
- struct object_cipher_info *object)
-{
- return offset_at_tail(get_data_conf(frame), object);
-}
-
-static off_t offset_at_full(struct avec_config *conf,
- struct object_cipher_info *object)
-{
- return conf->aligned_offset +
- (conf->off_in_head ? get_atom_size(object) : 0);
-}
-
-static off_t offset_at_data_full(call_frame_t *frame,
- struct object_cipher_info *object)
-{
- return offset_at_full(get_data_conf(frame), object);
-}
-
-static off_t offset_at_hole_full(call_frame_t *frame,
- struct object_cipher_info *object)
-{
- return offset_at_full(get_hole_conf(frame), object);
-}
-
-/*
- * atom->io_size_nopad()
- */
-
-static uint32_t io_size_nopad_head(struct avec_config *conf,
- struct object_cipher_info *object)
-{
- uint32_t gap_at_beg;
- uint32_t gap_at_end;
-
- check_head_block(conf);
-
- gap_at_beg = conf->off_in_head;
-
- if (has_tail_block(conf) || has_full_blocks(conf) || conf->off_in_tail == 0 )
- gap_at_end = 0;
- else
- gap_at_end = get_atom_size(object) - conf->off_in_tail;
-
- return get_atom_size(object) - (gap_at_beg + gap_at_end);
-}
-
-static uint32_t io_size_nopad_tail(struct avec_config *conf,
- struct object_cipher_info *object)
-{
- check_tail_block(conf);
- return conf->off_in_tail;
-}
-
-static uint32_t io_size_nopad_full(struct avec_config *conf,
- struct object_cipher_info *object)
-{
- check_full_block(conf);
- return get_atom_size(object);
-}
-
-static uint32_t io_size_nopad_data_head(call_frame_t *frame,
- struct object_cipher_info *object)
-{
- return io_size_nopad_head(get_data_conf(frame), object);
-}
-
-static uint32_t io_size_nopad_hole_head(call_frame_t *frame,
- struct object_cipher_info *object)
-{
- return io_size_nopad_head(get_hole_conf(frame), object);
-}
-
-static uint32_t io_size_nopad_data_tail(call_frame_t *frame,
- struct object_cipher_info *object)
-{
- return io_size_nopad_tail(get_data_conf(frame), object);
-}
-
-static uint32_t io_size_nopad_hole_tail(call_frame_t *frame,
- struct object_cipher_info *object)
-{
- return io_size_nopad_tail(get_hole_conf(frame), object);
-}
-
-static uint32_t io_size_nopad_data_full(call_frame_t *frame,
- struct object_cipher_info *object)
-{
- return io_size_nopad_full(get_data_conf(frame), object);
-}
-
-static uint32_t io_size_nopad_hole_full(call_frame_t *frame,
- struct object_cipher_info *object)
-{
- return io_size_nopad_full(get_hole_conf(frame), object);
-}
-
-static uint32_t offset_in_head(struct avec_config *conf)
-{
- check_cursor_head(conf);
-
- return conf->off_in_head;
-}
-
-static uint32_t offset_in_tail(call_frame_t *frame,
- struct object_cipher_info *object)
-{
- return 0;
-}
-
-static uint32_t offset_in_full(struct avec_config *conf,
- struct object_cipher_info *object)
-{
- check_cursor_full(conf);
-
- if (has_head_block(conf))
- return (conf->cursor - 1) << get_atom_bits(object);
- else
- return conf->cursor << get_atom_bits(object);
-}
-
-static uint32_t offset_in_data_head(call_frame_t *frame,
- struct object_cipher_info *object)
-{
- return offset_in_head(get_data_conf(frame));
-}
-
-static uint32_t offset_in_hole_head(call_frame_t *frame,
- struct object_cipher_info *object)
-{
- return offset_in_head(get_hole_conf(frame));
-}
-
-static uint32_t offset_in_data_full(call_frame_t *frame,
- struct object_cipher_info *object)
-{
- return offset_in_full(get_data_conf(frame), object);
-}
-
-static uint32_t offset_in_hole_full(call_frame_t *frame,
- struct object_cipher_info *object)
-{
- return offset_in_full(get_hole_conf(frame), object);
-}
-
-/*
- * atom->rmw()
- */
-/*
- * Pre-conditions:
- * @vec contains plain text of the latest
- * version.
- *
- * Uptodate gaps of the @partial block with
- * this plain text, encrypt the whole block
- * and write the result to disk.
- */
-static int32_t rmw_partial_block(call_frame_t *frame,
- void *cookie,
- xlator_t *this,
- int32_t op_ret,
- int32_t op_errno,
- struct iovec *vec,
- int32_t count,
- struct iatt *stbuf,
- struct iobref *iobref,
- struct rmw_atom *atom)
-{
- size_t was_read = 0;
- uint64_t file_size;
- crypt_local_t *local = frame->local;
- struct object_cipher_info *object = &local->info->cinfo;
-
- struct iovec *partial = atom->get_iovec(frame, 0);
- struct avec_config *conf = atom->get_config(frame);
- end_writeback_handler_t end_writeback_partial_block;
-#if DEBUG_CRYPT
- gf_boolean_t check_last_cblock = _gf_false;
-#endif
- local->op_ret = op_ret;
- local->op_errno = op_errno;
-
- if (op_ret < 0)
- goto exit;
-
- file_size = local->cur_file_size;
- was_read = op_ret;
-
- if (atom->locality == HEAD_ATOM && conf->off_in_head) {
- /*
- * head atom with a non-uptodate gap
- * at the beginning
- *
- * fill the gap with plain text of the
- * latest version. Convert a part of hole
- * (if any) to zeros.
- */
- int32_t i;
- int32_t copied = 0;
- int32_t to_gap; /* amount of data needed to uptodate
- the gap at the beginning */
-#if 0
- int32_t hole = 0; /* The part of the hole which
- * got in the head block */
-#endif /* 0 */
- to_gap = conf->off_in_head;
-
- if (was_read < to_gap) {
- if (file_size >
- offset_at_head(conf) + was_read) {
- /*
- * It is impossible to uptodate
- * head block: too few bytes have
- * been read from disk, so that
- * partial write is impossible.
- *
- * It could happen because of many
- * reasons: IO errors, (meta)data
- * corruption in the local file system,
- * etc.
- */
- gf_log(this->name, GF_LOG_WARNING,
- "Can not uptodate a gap at the beginning");
- local->op_ret = -1;
- local->op_errno = EIO;
- goto exit;
- }
-#if 0
- hole = to_gap - was_read;
-#endif /* 0 */
- to_gap = was_read;
- }
- /*
- * uptodate the gap at the beginning
- */
- for (i = 0; i < count && copied < to_gap; i++) {
- int32_t to_copy;
-
- to_copy = vec[i].iov_len;
- if (to_copy > to_gap - copied)
- to_copy = to_gap - copied;
-
- memcpy(partial->iov_base, vec[i].iov_base, to_copy);
- copied += to_copy;
- }
-#if 0
- /*
- * If possible, convert part of the
- * hole, which got in the head block
- */
- ret = TRY_LOCK(&local->hole_lock);
- if (!ret) {
- if (local->hole_handled)
- /*
- * already converted by
- * crypt_writev_cbk()
- */
- UNLOCK(&local->hole_lock);
- else {
- /*
- * convert the part of the hole
- * which got in the head block
- * to zeros.
- *
- * Update the orig_offset to make
- * sure writev_cbk() won't care
- * about this part of the hole.
- *
- */
- memset(partial->iov_base + to_gap, 0, hole);
-
- conf->orig_offset -= hole;
- conf->orig_size += hole;
- UNLOCK(&local->hole_lock);
- }
- }
- else /*
- * conversion is being performed
- * by crypt_writev_cbk()
- */
- ;
-#endif /* 0 */
- }
- if (atom->locality == TAIL_ATOM ||
- (!has_tail_block(conf) && conf->off_in_tail)) {
- /*
- * tail atom, or head atom with a non-uptodate
- * gap at the end.
- *
- * fill the gap at the end of the block
- * with plain text of the latest version.
- * Pad the result, (if needed)
- */
- int32_t i;
- int32_t to_gap;
- int copied;
- off_t off_in_tail;
- int32_t to_copy;
-
- off_in_tail = conf->off_in_tail;
- to_gap = conf->gap_in_tail;
-
- if (to_gap && was_read < off_in_tail + to_gap) {
- /*
- * It is impossible to uptodate
- * the gap at the end: too few bytes
- * have been read from disk, so that
- * partial write is impossible.
- *
- * It could happen because of many
- * reasons: IO errors, (meta)data
- * corruption in the local file system,
- * etc.
- */
- gf_log(this->name, GF_LOG_WARNING,
- "Can not uptodate a gap at the end");
- local->op_ret = -1;
- local->op_errno = EIO;
- goto exit;
- }
- /*
- * uptodate the gap at the end
- */
- copied = 0;
- to_copy = to_gap;
- for(i = count - 1; i >= 0 && to_copy > 0; i--) {
- uint32_t from_vec, off_in_vec;
-
- off_in_vec = 0;
- from_vec = vec[i].iov_len;
- if (from_vec > to_copy) {
- off_in_vec = from_vec - to_copy;
- from_vec = to_copy;
- }
- memcpy(partial->iov_base +
- off_in_tail + to_gap - copied - from_vec,
- vec[i].iov_base + off_in_vec,
- from_vec);
-
- gf_log(this->name, GF_LOG_DEBUG,
- "uptodate %d bytes at tail. Offset at target(source): %d(%d)",
- (int)from_vec,
- (int)off_in_tail + to_gap - copied - from_vec,
- (int)off_in_vec);
-
- copied += from_vec;
- to_copy -= from_vec;
- }
- partial->iov_len = off_in_tail + to_gap;
-
- if (object_alg_should_pad(object)) {
- int32_t resid = 0;
- resid = partial->iov_len & (object_alg_blksize(object) - 1);
- if (resid) {
- /*
- * append a new EOF padding
- */
- local->eof_padding_size =
- object_alg_blksize(object) - resid;
-
- gf_log(this->name, GF_LOG_DEBUG,
- "set padding size %d",
- local->eof_padding_size);
-
- memset(partial->iov_base + partial->iov_len,
- 1,
- local->eof_padding_size);
- partial->iov_len += local->eof_padding_size;
-#if DEBUG_CRYPT
- gf_log(this->name, GF_LOG_DEBUG,
- "pad cblock with %d zeros:",
- local->eof_padding_size);
- dump_cblock(this,
- (unsigned char *)partial->iov_base +
- partial->iov_len - object_alg_blksize(object));
- check_last_cblock = _gf_true;
-#endif
- }
- }
- }
- /*
- * encrypt the whole block
- */
- encrypt_aligned_iov(object,
- partial,
- 1,
- atom->offset_at(frame, object));
-#if DEBUG_CRYPT
- if (check_last_cblock == _gf_true) {
- gf_log(this->name, GF_LOG_DEBUG,
- "encrypt last cblock with offset %llu",
- (unsigned long long)atom->offset_at(frame, object));
- dump_cblock(this, (unsigned char *)partial->iov_base +
- partial->iov_len - object_alg_blksize(object));
- }
-#endif
- set_local_io_params_writev(frame, object, atom,
- atom->offset_at(frame, object),
- iovec_get_size(partial, 1));
- /*
- * write the whole block to disk
- */
- end_writeback_partial_block = dispatch_end_writeback(local->fop);
- conf->cursor ++;
- STACK_WIND(frame,
- end_writeback_partial_block,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->writev,
- local->fd,
- partial,
- 1,
- atom->offset_at(frame, object),
- local->flags,
- local->iobref_data,
- local->xdata);
-
- gf_log("crypt", GF_LOG_DEBUG,
- "submit partial block: %d bytes from %d offset",
- (int)iovec_get_size(partial, 1),
- (int)atom->offset_at(frame, object));
- exit:
- return 0;
-}
-
-/*
- * Perform a (read-)modify-write sequence.
- * This should be performed only after approval
- * of upper server-side manager, i.e. the caller
- * needs to make sure this is his turn to rmw.
- */
-void submit_partial(call_frame_t *frame,
- xlator_t *this,
- fd_t *fd,
- atom_locality_type ltype)
-{
- int32_t ret;
- dict_t *dict;
- struct rmw_atom *atom;
- crypt_local_t *local = frame->local;
- struct object_cipher_info *object = &local->info->cinfo;
-
- atom = atom_by_types(local->active_setup, ltype);
- /*
- * To perform the "read" component of the read-modify-write
- * sequence the crypt translator does stack_wind to itself.
- *
- * Pass current file size to crypt_readv()
- */
- dict = dict_new();
- if (!dict) {
- /*
- * FIXME: Handle the error
- */
- gf_log("crypt", GF_LOG_WARNING, "Can not alloc dict");
- return;
- }
- ret = dict_set(dict,
- FSIZE_XATTR_PREFIX,
- data_from_uint64(local->cur_file_size));
- if (ret) {
- /*
- * FIXME: Handle the error
- */
- dict_unref(dict);
- gf_log("crypt", GF_LOG_WARNING, "Can not set dict");
- goto exit;
- }
- STACK_WIND(frame,
- atom->rmw,
- this,
- this->fops->readv, /* crypt_readv */
- fd,
- atom->count_to_uptodate(frame, object), /* count */
- atom->offset_at(frame, object), /* offset to read from */
- 0,
- dict);
- exit:
- dict_unref(dict);
-}
-
-/*
- * submit blocks of FULL_ATOM type
- */
-void submit_full(call_frame_t *frame, xlator_t *this)
-{
- crypt_local_t *local = frame->local;
- struct object_cipher_info *object = &local->info->cinfo;
- struct rmw_atom *atom = atom_by_types(local->active_setup, FULL_ATOM);
- uint32_t count; /* total number of full blocks to submit */
- uint32_t granularity; /* number of blocks to submit in one iteration */
-
- uint64_t off_in_file; /* start offset in the file, bytes */
- uint32_t off_in_atom; /* start offset in the atom, blocks */
- uint32_t blocks_written = 0; /* blocks written for this submit */
-
- struct avec_config *conf = atom->get_config(frame);
- end_writeback_handler_t end_writeback_full_block;
- /*
- * Write full blocks by groups of granularity size.
- */
- end_writeback_full_block = dispatch_end_writeback(local->fop);
-
- if (is_ordered_mode(frame)) {
- uint32_t skip = has_head_block(conf) ? 1 : 0;
- count = 1;
- granularity = 1;
- /*
- * calculate start offset using cursor value;
- * here we should take into accout head block,
- * which corresponds to cursor value 0.
- */
- off_in_file = atom->offset_at(frame, object) +
- ((conf->cursor - skip) << get_atom_bits(object));
- off_in_atom = conf->cursor - skip;
- }
- else {
- /*
- * in parallel mode
- */
- count = conf->nr_full_blocks;
- granularity = MAX_IOVEC;
- off_in_file = atom->offset_at(frame, object);
- off_in_atom = 0;
- }
- while (count) {
- uint32_t blocks_to_write = count;
-
- if (blocks_to_write > granularity)
- blocks_to_write = granularity;
- if (conf->type == HOLE_ATOM)
- /*
- * reset iovec before encryption
- */
- memset(atom->get_iovec(frame, 0)->iov_base,
- 0,
- get_atom_size(object));
- /*
- * encrypt the group
- */
- encrypt_aligned_iov(object,
- atom->get_iovec(frame,
- off_in_atom +
- blocks_written),
- blocks_to_write,
- off_in_file + (blocks_written <<
- get_atom_bits(object)));
-
- set_local_io_params_writev(frame, object, atom,
- off_in_file + (blocks_written << get_atom_bits(object)),
- blocks_to_write << get_atom_bits(object));
-
- conf->cursor += blocks_to_write;
-
- STACK_WIND(frame,
- end_writeback_full_block,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->writev,
- local->fd,
- atom->get_iovec(frame, off_in_atom + blocks_written),
- blocks_to_write,
- off_in_file + (blocks_written << get_atom_bits(object)),
- local->flags,
- local->iobref_data ? local->iobref_data : local->iobref,
- local->xdata);
-
- gf_log("crypt", GF_LOG_DEBUG, "submit %d full blocks from %d offset",
- blocks_to_write,
- (int)(off_in_file + (blocks_written << get_atom_bits(object))));
-
- count -= blocks_to_write;
- blocks_written += blocks_to_write;
- }
- return;
-}
-
-static int32_t rmw_data_head(call_frame_t *frame,
- void *cookie,
- xlator_t *this,
- int32_t op_ret,
- int32_t op_errno,
- struct iovec *vec,
- int32_t count,
- struct iatt *stbuf,
- struct iobref *iobref,
- dict_t *xdata)
-{
- return rmw_partial_block(frame,
- cookie,
- this,
- op_ret,
- op_errno,
- vec,
- count,
- stbuf,
- iobref,
- atom_by_types(DATA_ATOM, HEAD_ATOM));
-}
-
-static int32_t rmw_data_tail(call_frame_t *frame,
- void *cookie,
- xlator_t *this,
- int32_t op_ret,
- int32_t op_errno,
- struct iovec *vec,
- int32_t count,
- struct iatt *stbuf,
- struct iobref *iobref,
- dict_t *xdata)
-{
- return rmw_partial_block(frame,
- cookie,
- this,
- op_ret,
- op_errno,
- vec,
- count,
- stbuf,
- iobref,
- atom_by_types(DATA_ATOM, TAIL_ATOM));
-}
-
-static int32_t rmw_hole_head(call_frame_t *frame,
- void *cookie,
- xlator_t *this,
- int32_t op_ret,
- int32_t op_errno,
- struct iovec *vec,
- int32_t count,
- struct iatt *stbuf,
- struct iobref *iobref,
- dict_t *xdata)
-{
- return rmw_partial_block(frame,
- cookie,
- this,
- op_ret,
- op_errno,
- vec,
- count,
- stbuf,
- iobref,
- atom_by_types(HOLE_ATOM, HEAD_ATOM));
-}
-
-static int32_t rmw_hole_tail(call_frame_t *frame,
- void *cookie,
- xlator_t *this,
- int32_t op_ret,
- int32_t op_errno,
- struct iovec *vec,
- int32_t count,
- struct iatt *stbuf,
- struct iobref *iobref,
- dict_t *xdata)
-{
- return rmw_partial_block(frame,
- cookie,
- this,
- op_ret,
- op_errno,
- vec,
- count,
- stbuf,
- iobref,
- atom_by_types(HOLE_ATOM, TAIL_ATOM));
-}
-
-/*
- * atom->count_to_uptodate()
- */
-static uint32_t count_to_uptodate_head(struct avec_config *conf,
- struct object_cipher_info *object)
-{
- if (conf->acount == 1 && conf->off_in_tail)
- return get_atom_size(object);
- else
- /* there is no need to read the whole head block */
- return conf->off_in_head;
-}
-
-static uint32_t count_to_uptodate_tail(struct avec_config *conf,
- struct object_cipher_info *object)
-{
- /* we need to read the whole tail block */
- return get_atom_size(object);
-}
-
-static uint32_t count_to_uptodate_data_head(call_frame_t *frame,
- struct object_cipher_info *object)
-{
- return count_to_uptodate_head(get_data_conf(frame), object);
-}
-
-static uint32_t count_to_uptodate_data_tail(call_frame_t *frame,
- struct object_cipher_info *object)
-{
- return count_to_uptodate_tail(get_data_conf(frame), object);
-}
-
-static uint32_t count_to_uptodate_hole_head(call_frame_t *frame,
- struct object_cipher_info *object)
-{
- return count_to_uptodate_head(get_hole_conf(frame), object);
-}
-
-static uint32_t count_to_uptodate_hole_tail(call_frame_t *frame,
- struct object_cipher_info *object)
-{
- return count_to_uptodate_tail(get_hole_conf(frame), object);
-}
-
-/* atom->get_config() */
-
-static struct avec_config *get_config_data(call_frame_t *frame)
-{
- return &((crypt_local_t *)frame->local)->data_conf;
-}
-
-static struct avec_config *get_config_hole(call_frame_t *frame)
-{
- return &((crypt_local_t *)frame->local)->hole_conf;
-}
-
-/*
- * atom->get_iovec()
- */
-static struct iovec *get_iovec_hole_head(call_frame_t *frame,
- uint32_t count)
-{
- struct avec_config *conf = get_hole_conf(frame);
-
- return conf->avec;
-}
-
-static struct iovec *get_iovec_hole_full(call_frame_t *frame,
- uint32_t count)
-{
- struct avec_config *conf = get_hole_conf(frame);
-
- return conf->avec + (conf->off_in_head ? 1 : 0);
-}
-
-static inline struct iovec *get_iovec_hole_tail(call_frame_t *frame,
- uint32_t count)
-{
- struct avec_config *conf = get_hole_conf(frame);
-
- return conf->avec + (conf->blocks_in_pool - 1);
-}
-
-static inline struct iovec *get_iovec_data_head(call_frame_t *frame,
- uint32_t count)
-{
- struct avec_config *conf = get_data_conf(frame);
-
- return conf->avec;
-}
-
-static inline struct iovec *get_iovec_data_full(call_frame_t *frame,
- uint32_t count)
-{
- struct avec_config *conf = get_data_conf(frame);
-
- return conf->avec + (conf->off_in_head ? 1 : 0) + count;
-}
-
-static inline struct iovec *get_iovec_data_tail(call_frame_t *frame,
- uint32_t count)
-{
- struct avec_config *conf = get_data_conf(frame);
-
- return conf->avec +
- (conf->off_in_head ? 1 : 0) +
- conf->nr_full_blocks;
-}
-
-static struct rmw_atom atoms[LAST_DATA_TYPE][LAST_LOCALITY_TYPE] = {
- [DATA_ATOM][HEAD_ATOM] =
- { .locality = HEAD_ATOM,
- .rmw = rmw_data_head,
- .offset_at = offset_at_data_head,
- .offset_in = offset_in_data_head,
- .get_iovec = get_iovec_data_head,
- .io_size_nopad = io_size_nopad_data_head,
- .count_to_uptodate = count_to_uptodate_data_head,
- .get_config = get_config_data
- },
- [DATA_ATOM][TAIL_ATOM] =
- { .locality = TAIL_ATOM,
- .rmw = rmw_data_tail,
- .offset_at = offset_at_data_tail,
- .offset_in = offset_in_tail,
- .get_iovec = get_iovec_data_tail,
- .io_size_nopad = io_size_nopad_data_tail,
- .count_to_uptodate = count_to_uptodate_data_tail,
- .get_config = get_config_data
- },
- [DATA_ATOM][FULL_ATOM] =
- { .locality = FULL_ATOM,
- .offset_at = offset_at_data_full,
- .offset_in = offset_in_data_full,
- .get_iovec = get_iovec_data_full,
- .io_size_nopad = io_size_nopad_data_full,
- .get_config = get_config_data
- },
- [HOLE_ATOM][HEAD_ATOM] =
- { .locality = HEAD_ATOM,
- .rmw = rmw_hole_head,
- .offset_at = offset_at_hole_head,
- .offset_in = offset_in_hole_head,
- .get_iovec = get_iovec_hole_head,
- .io_size_nopad = io_size_nopad_hole_head,
- .count_to_uptodate = count_to_uptodate_hole_head,
- .get_config = get_config_hole
- },
- [HOLE_ATOM][TAIL_ATOM] =
- { .locality = TAIL_ATOM,
- .rmw = rmw_hole_tail,
- .offset_at = offset_at_hole_tail,
- .offset_in = offset_in_tail,
- .get_iovec = get_iovec_hole_tail,
- .io_size_nopad = io_size_nopad_hole_tail,
- .count_to_uptodate = count_to_uptodate_hole_tail,
- .get_config = get_config_hole
- },
- [HOLE_ATOM][FULL_ATOM] =
- { .locality = FULL_ATOM,
- .offset_at = offset_at_hole_full,
- .offset_in = offset_in_hole_full,
- .get_iovec = get_iovec_hole_full,
- .io_size_nopad = io_size_nopad_hole_full,
- .get_config = get_config_hole
- }
-};
-
-struct rmw_atom *atom_by_types(atom_data_type data,
- atom_locality_type locality)
-{
- return &atoms[data][locality];
-}
-
-/*
- Local variables:
- c-indentation-style: "K&R"
- mode-name: "LC"
- c-basic-offset: 8
- tab-width: 8
- fill-column: 80
- scroll-step: 1
- End:
-*/
diff --git a/xlators/encryption/crypt/src/crypt-common.h b/xlators/encryption/crypt/src/crypt-common.h
deleted file mode 100644
index 7c212ad5d25..00000000000
--- a/xlators/encryption/crypt/src/crypt-common.h
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- Copyright (c) 2008-2013 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 __CRYPT_COMMON_H__
-#define __CRYPT_COMMON_H__
-
-#define INVAL_SUBVERSION_NUMBER (0xff)
-#define CRYPT_INVAL_OP (GF_FOP_NULL)
-
-#define CRYPTO_FORMAT_PREFIX "trusted.glusterfs.crypt.att.cfmt"
-#define FSIZE_XATTR_PREFIX "trusted.glusterfs.crypt.att.size"
-#define SUBREQ_PREFIX "trusted.glusterfs.crypt.msg.sreq"
-#define FSIZE_MSG_PREFIX "trusted.glusterfs.crypt.msg.size"
-#define DE_MSG_PREFIX "trusted.glusterfs.crypt.msg.dent"
-#define REQUEST_ID_PREFIX "trusted.glusterfs.crypt.msg.rqid"
-#define MSGFLAGS_PREFIX "trusted.glusterfs.crypt.msg.xfgs"
-
-
-/* messages for crypt_open() */
-#define MSGFLAGS_REQUEST_MTD_RLOCK 1 /* take read lock and don't unlock */
-#define MSGFLAGS_REQUEST_MTD_WLOCK 2 /* take write lock and don't unlock */
-
-#define AES_BLOCK_BITS (4) /* AES_BLOCK_SIZE == 1 << AES_BLOCK_BITS */
-
-#define noop do {; } while (0)
-#define cassert(cond) ({ switch (-1) { case (cond): case 0: break; } })
-#define __round_mask(x, y) ((__typeof__(x))((y)-1))
-#define round_up(x, y) ((((x)-1) | __round_mask(x, y))+1)
-
-/*
- * Format of file's metadata
- */
-struct crypt_format {
- uint8_t loader_id; /* version of metadata loader */
- uint8_t versioned[0]; /* file's metadata of specific version */
-} __attribute__((packed));
-
-typedef enum {
- AES_CIPHER_ALG,
- LAST_CIPHER_ALG
-} cipher_alg_t;
-
-typedef enum {
- XTS_CIPHER_MODE,
- LAST_CIPHER_MODE
-} cipher_mode_t;
-
-typedef enum {
- MTD_LOADER_V1,
- LAST_MTD_LOADER
-} mtd_loader_id;
-
-static inline void msgflags_set_mtd_rlock(uint32_t *flags)
-{
- *flags |= MSGFLAGS_REQUEST_MTD_RLOCK;
-}
-
-static inline void msgflags_set_mtd_wlock(uint32_t *flags)
-{
- *flags |= MSGFLAGS_REQUEST_MTD_WLOCK;
-}
-
-static inline gf_boolean_t msgflags_check_mtd_rlock(uint32_t *flags)
-{
- return *flags & MSGFLAGS_REQUEST_MTD_RLOCK;
-}
-
-static inline gf_boolean_t msgflags_check_mtd_wlock(uint32_t *flags)
-{
- return *flags & MSGFLAGS_REQUEST_MTD_WLOCK;
-}
-
-static inline gf_boolean_t msgflags_check_mtd_lock(uint32_t *flags)
-{
- return msgflags_check_mtd_rlock(flags) ||
- msgflags_check_mtd_wlock(flags);
-}
-
-/*
- * returns number of logical blocks occupied
- * (maybe partially) by @count bytes
- * at offset @start.
- */
-static inline off_t logical_blocks_occupied(uint64_t start, off_t count,
- int blkbits)
-{
- return ((start + count - 1) >> blkbits) - (start >> blkbits) + 1;
-}
-
-/*
- * are two bytes (represented by offsets @off1
- * and @off2 respectively) in the same logical
- * block.
- */
-static inline int in_same_lblock(uint64_t off1, uint64_t off2,
- int blkbits)
-{
- return off1 >> blkbits == off2 >> blkbits;
-}
-
-static inline void dump_cblock(xlator_t *this, unsigned char *buf)
-{
- gf_log(this->name, GF_LOG_DEBUG,
- "dump cblock: %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x",
- (buf)[0],
- (buf)[1],
- (buf)[2],
- (buf)[3],
- (buf)[4],
- (buf)[5],
- (buf)[6],
- (buf)[7],
- (buf)[8],
- (buf)[9],
- (buf)[10],
- (buf)[11],
- (buf)[12],
- (buf)[13],
- (buf)[14],
- (buf)[15]);
-}
-
-#endif /* __CRYPT_COMMON_H__ */
-
-/*
- Local variables:
- c-indentation-style: "K&R"
- mode-name: "LC"
- c-basic-offset: 8
- tab-width: 8
- fill-column: 80
- scroll-step: 1
- End:
-*/
diff --git a/xlators/encryption/crypt/src/crypt-mem-types.h b/xlators/encryption/crypt/src/crypt-mem-types.h
deleted file mode 100644
index 2eab921fcba..00000000000
--- a/xlators/encryption/crypt/src/crypt-mem-types.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- Copyright (c) 2008-2013 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 __CRYPT_MEM_TYPES_H__
-#define __CRYPT_MEM_TYPES_H__
-
-#include "mem-types.h"
-
-enum gf_crypt_mem_types_ {
- gf_crypt_mt_priv = gf_common_mt_end + 1,
- gf_crypt_mt_inode,
- gf_crypt_mt_data,
- gf_crypt_mt_mtd,
- gf_crypt_mt_loc,
- gf_crypt_mt_iatt,
- gf_crypt_mt_key,
- gf_crypt_mt_iovec,
- gf_crypt_mt_char,
- gf_crypt_mt_end,
-};
-
-#endif /* __CRYPT_MEM_TYPES_H__ */
-
-/*
- Local variables:
- c-indentation-style: "K&R"
- mode-name: "LC"
- c-basic-offset: 8
- tab-width: 8
- fill-column: 80
- scroll-step: 1
- End:
-*/
-
-
-
diff --git a/xlators/encryption/crypt/src/crypt.c b/xlators/encryption/crypt/src/crypt.c
deleted file mode 100644
index ae8cdb2ad24..00000000000
--- a/xlators/encryption/crypt/src/crypt.c
+++ /dev/null
@@ -1,4526 +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 <ctype.h>
-#include <sys/uio.h>
-
-#ifndef _CONFIG_H
-#define _CONFIG_H
-#include "config.h"
-#endif
-
-#include "glusterfs.h"
-#include "xlator.h"
-#include "logging.h"
-#include "defaults.h"
-
-#include "crypt-common.h"
-#include "crypt.h"
-
-static void init_inode_info_head(struct crypt_inode_info *info, fd_t *fd);
-static int32_t init_inode_info_tail(struct crypt_inode_info *info,
- struct master_cipher_info *master);
-static int32_t prepare_for_submit_hole(call_frame_t *frame, xlator_t *this,
- uint64_t from, off_t size);
-static int32_t load_file_size(call_frame_t *frame, void *cookie,
- xlator_t *this, int32_t op_ret, int32_t op_errno,
- dict_t *dict, dict_t *xdata);
-static void do_ordered_submit(call_frame_t *frame, xlator_t *this,
- atom_data_type dtype);
-static void do_parallel_submit(call_frame_t *frame, xlator_t *this,
- atom_data_type dtype);
-static void put_one_call_open(call_frame_t *frame);
-static void put_one_call_readv(call_frame_t *frame, xlator_t *this);
-static void put_one_call_writev(call_frame_t *frame, xlator_t *this);
-static void put_one_call_ftruncate(call_frame_t *frame, xlator_t *this);
-static void free_avec(struct iovec *avec, char **pool, int blocks_in_pool);
-static void free_avec_data(crypt_local_t *local);
-static void free_avec_hole(crypt_local_t *local);
-
-static crypt_local_t *crypt_alloc_local(call_frame_t *frame, xlator_t *this,
- glusterfs_fop_t fop)
-{
- crypt_local_t *local = NULL;
-
- local = mem_get0(this->local_pool);
- if (!local) {
- gf_log(this->name, GF_LOG_ERROR, "out of memory");
- return NULL;
- }
- local->fop = fop;
- LOCK_INIT(&local->hole_lock);
- LOCK_INIT(&local->call_lock);
- LOCK_INIT(&local->rw_count_lock);
-
- frame->local = local;
- return local;
-}
-
-struct crypt_inode_info *get_crypt_inode_info(inode_t *inode, xlator_t *this)
-{
- int ret;
- uint64_t value = 0;
- struct crypt_inode_info *info;
-
- ret = inode_ctx_get(inode, this, &value);
- if (ret == -1) {
- gf_log (this->name, GF_LOG_WARNING,
- "Can not get inode info");
- return NULL;
- }
- info = (struct crypt_inode_info *)(long)value;
- if (info == NULL) {
- gf_log (this->name, GF_LOG_WARNING,
- "Can not obtain inode info");
- return NULL;
- }
- return info;
-}
-
-static struct crypt_inode_info *local_get_inode_info(crypt_local_t *local,
- xlator_t *this)
-{
- if (local->info)
- return local->info;
- local->info = get_crypt_inode_info(local->fd->inode, this);
- return local->info;
-}
-
-static struct crypt_inode_info *alloc_inode_info(crypt_local_t *local,
- loc_t *loc)
-{
- struct crypt_inode_info *info;
-
- info = GF_CALLOC(1, sizeof(*info), gf_crypt_mt_inode);
- if (!info) {
- local->op_ret = -1;
- local->op_errno = ENOMEM;
- gf_log ("crypt", GF_LOG_WARNING,
- "Can not allocate inode info");
- return NULL;
- }
- memset(info, 0, sizeof(*info));
-#if DEBUG_CRYPT
- info->loc = GF_CALLOC(1, sizeof(*loc), gf_crypt_mt_loc);
- if (!info->loc) {
- gf_log("crypt", GF_LOG_WARNING, "Can not allocate loc");
- GF_FREE(info);
- return NULL;
- }
- if (loc_copy(info->loc, loc)){
- GF_FREE(info->loc);
- GF_FREE(info);
- return NULL;
- }
-#endif /* DEBUG_CRYPT */
-
- local->info = info;
- return info;
-}
-
-static void free_inode_info(struct crypt_inode_info *info)
-{
-#if DEBUG_CRYPT
- loc_wipe(info->loc);
- GF_FREE(info->loc);
-#endif
- memset(info, 0, sizeof(*info));
- GF_FREE(info);
-}
-
-int crypt_forget (xlator_t *this, inode_t *inode)
-{
- uint64_t ctx_addr = 0;
- if (!inode_ctx_del (inode, this, &ctx_addr))
- free_inode_info((struct crypt_inode_info *)(long)ctx_addr);
- return 0;
-}
-
-#if DEBUG_CRYPT
-static void check_read(call_frame_t *frame, xlator_t *this, int32_t read,
- struct iovec *vec, int32_t count, struct iatt *stbuf)
-{
- crypt_local_t *local = frame->local;
- struct object_cipher_info *object = get_object_cinfo(local->info);
- struct avec_config *conf = &local->data_conf;
- uint32_t resid = stbuf->ia_size & (object_alg_blksize(object) - 1);
-
- if (read <= 0)
- return;
- if (read != iovec_get_size(vec, count))
- gf_log ("crypt", GF_LOG_DEBUG,
- "op_ret differs from amount of read bytes");
-
- if (object_alg_should_pad(object) && (read & (object_alg_blksize(object) - 1)))
- gf_log ("crypt", GF_LOG_DEBUG,
- "bad amount of read bytes (!= 0 mod(cblock size))");
-
- if (conf->aligned_offset + read >
- stbuf->ia_size + (resid ? object_alg_blksize(object) - resid : 0))
- gf_log ("crypt", GF_LOG_DEBUG,
- "bad amount of read bytes (too large))");
-
-}
-
-#define PT_BYTES_TO_DUMP (32)
-static void dump_plain_text(crypt_local_t *local, struct iovec *avec)
-{
- int32_t to_dump;
- char str[PT_BYTES_TO_DUMP + 1];
-
- if (!avec)
- return;
- to_dump = avec->iov_len;
- if (to_dump > PT_BYTES_TO_DUMP)
- to_dump = PT_BYTES_TO_DUMP;
- memcpy(str, avec->iov_base, to_dump);
- memset(str + to_dump, '0', 1);
- gf_log("crypt", GF_LOG_DEBUG, "Read file: %s", str);
-}
-
-static int32_t data_conf_invariant(struct avec_config *conf)
-{
- return conf->acount ==
- !!has_head_block(conf) +
- !!has_tail_block(conf)+
- conf->nr_full_blocks;
-}
-
-static int32_t hole_conf_invariant(struct avec_config *conf)
-{
- return conf->blocks_in_pool ==
- !!has_head_block(conf) +
- !!has_tail_block(conf)+
- !!has_full_blocks(conf);
-}
-
-static void crypt_check_conf(struct avec_config *conf)
-{
- int32_t ret = 0;
- const char *msg;
-
- switch (conf->type) {
- case DATA_ATOM:
- msg = "data";
- ret = data_conf_invariant(conf);
- break;
- case HOLE_ATOM:
- msg = "hole";
- ret = hole_conf_invariant(conf);
- break;
- default:
- msg = "unknown";
- }
- if (!ret)
- gf_log("crypt", GF_LOG_DEBUG, "bad %s conf", msg);
-}
-
-static void check_buf(call_frame_t *frame, xlator_t *this, struct iatt *buf)
-{
- crypt_local_t *local = frame->local;
- struct object_cipher_info *object = &local->info->cinfo;
- uint64_t local_file_size;
-
- switch(local->fop) {
- case GF_FOP_FTRUNCATE:
- return;
- case GF_FOP_WRITE:
- local_file_size = local->new_file_size;
- break;
- case GF_FOP_READ:
- if (parent_is_crypt_xlator(frame, this))
- return;
- local_file_size = local->cur_file_size;
- break;
- default:
- gf_log("crypt", GF_LOG_DEBUG, "bad file operation");
- return;
- }
- if (buf->ia_size != round_up(local_file_size,
- object_alg_blksize(object)))
- gf_log("crypt", GF_LOG_DEBUG,
- "bad ia_size in buf (%llu), should be %llu",
- (unsigned long long)buf->ia_size,
- (unsigned long long)round_up(local_file_size,
- object_alg_blksize(object)));
-}
-
-#else
-#define check_read(frame, this, op_ret, vec, count, stbuf) noop
-#define dump_plain_text(local, avec) noop
-#define crypt_check_conf(conf) noop
-#define check_buf(frame, this, buf) noop
-#endif /* DEBUG_CRYPT */
-
-/*
- * Pre-conditions:
- * @vec represents a ciphertext of expanded size and
- * aligned offset.
- *
- * Compound a temporal vector @avec with block-aligned
- * components, decrypt and fix it up to represent a chunk
- * of data corresponding to the original size and offset.
- * Pass the result to the next translator.
- */
-int32_t crypt_readv_cbk(call_frame_t *frame,
- void *cookie,
- xlator_t *this,
- int32_t op_ret,
- int32_t op_errno,
- struct iovec *vec,
- int32_t count,
- struct iatt *stbuf,
- struct iobref *iobref,
- dict_t *xdata)
-{
- crypt_local_t *local = frame->local;
- struct avec_config *conf = &local->data_conf;
- struct object_cipher_info *object = &local->info->cinfo;
-
- struct iovec *avec;
- uint32_t i;
- uint32_t to_vec;
- uint32_t to_user;
-
- check_buf(frame, this, stbuf);
- check_read(frame, this, op_ret, vec, count, stbuf);
-
- local->op_ret = op_ret;
- local->op_errno = op_errno;
- local->iobref = iobref_ref(iobref);
-
- local->buf = *stbuf;
- local->buf.ia_size = local->cur_file_size;
-
- if (op_ret <= 0 || count == 0 || vec[0].iov_len == 0)
- goto put_one_call;
-
- if (conf->orig_offset >= local->cur_file_size) {
- local->op_ret = 0;
- goto put_one_call;
- }
- /*
- * correct config params with real file size
- * and actual amount of bytes read
- */
- set_config_offsets(frame, this,
- conf->orig_offset, op_ret, DATA_ATOM, 0);
-
- if (conf->orig_offset + conf->orig_size > local->cur_file_size)
- conf->orig_size = local->cur_file_size - conf->orig_offset;
- /*
- * calculate amount of data to be returned
- * to user.
- */
- to_user = op_ret;
- if (conf->aligned_offset + to_user <= conf->orig_offset) {
- gf_log(this->name, GF_LOG_WARNING, "Incomplete read");
- local->op_ret = -1;
- local->op_errno = EIO;
- goto put_one_call;
- }
- to_user -= (conf->aligned_offset - conf->orig_offset);
-
- if (to_user > conf->orig_size)
- to_user = conf->orig_size;
- local->rw_count = to_user;
-
- op_errno = set_config_avec_data(this, local,
- conf, object, vec, count);
- if (op_errno) {
- local->op_ret = -1;
- local->op_errno = op_errno;
- goto put_one_call;
- }
- avec = conf->avec;
-#if DEBUG_CRYPT
- if (conf->off_in_tail != 0 &&
- conf->off_in_tail < object_alg_blksize(object) &&
- object_alg_should_pad(object))
- gf_log(this->name, GF_LOG_DEBUG, "Bad offset in tail %d",
- conf->off_in_tail);
- if (iovec_get_size(vec, count) != 0 &&
- in_same_lblock(conf->orig_offset + iovec_get_size(vec, count) - 1,
- local->cur_file_size - 1,
- object_alg_blkbits(object))) {
- gf_log(this->name, GF_LOG_DEBUG, "Compound last cblock");
- dump_cblock(this,
- (unsigned char *)(avec[conf->acount - 1].iov_base) +
- avec[conf->acount - 1].iov_len - object_alg_blksize(object));
- dump_cblock(this,
- (unsigned char *)(vec[count - 1].iov_base) +
- vec[count - 1].iov_len - object_alg_blksize(object));
- }
-#endif
- decrypt_aligned_iov(object, avec,
- conf->acount, conf->aligned_offset);
- /*
- * pass proper plain data to user
- */
- avec[0].iov_base += (conf->aligned_offset - conf->orig_offset);
- avec[0].iov_len -= (conf->aligned_offset - conf->orig_offset);
-
- to_vec = to_user;
- for (i = 0; i < conf->acount; i++) {
- if (avec[i].iov_len > to_vec)
- avec[i].iov_len = to_vec;
- to_vec -= avec[i].iov_len;
- }
- put_one_call:
- put_one_call_readv(frame, this);
- return 0;
-}
-
-static int32_t do_readv(call_frame_t *frame,
- void *cookie,
- xlator_t *this,
- int32_t op_ret,
- int32_t op_errno,
- dict_t *dict,
- dict_t *xdata)
-{
- data_t *data;
- crypt_local_t *local = frame->local;
-
- if (op_ret < 0)
- goto error;
- /*
- * extract regular file size
- */
- data = dict_get(dict, FSIZE_XATTR_PREFIX);
- if (!data) {
- gf_log("crypt", GF_LOG_WARNING, "Regular file size not found");
- op_errno = EIO;
- goto error;
- }
- local->cur_file_size = data_to_uint64(data);
-
- get_one_call(frame);
- STACK_WIND(frame,
- crypt_readv_cbk,
- FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->readv,
- local->fd,
- /*
- * FIXME: read amount can be reduced
- */
- local->data_conf.expanded_size,
- local->data_conf.aligned_offset,
- local->flags,
- local->xdata);
- return 0;
- error:
- local->op_ret = -1;
- local->op_errno = op_errno;
-
- get_one_call(frame);
- put_one_call_readv(frame, this);
- return 0;
-}
-
-static int32_t crypt_readv_finodelk_cbk(call_frame_t *frame,
- void *cookie,
- xlator_t *this,
- int32_t op_ret,
- int32_t op_errno,
- dict_t *xdata)
-{
- crypt_local_t *local = frame->local;
-
- if (op_ret < 0)
- goto error;
- /*
- * An access has been granted,
- * retrieve file size
- */
- STACK_WIND(frame,
- do_readv,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fgetxattr,
- local->fd,
- FSIZE_XATTR_PREFIX,
- NULL);
- return 0;
- error:
- fd_unref(local->fd);
- if (local->xdata)
- dict_unref(local->xdata);
- STACK_UNWIND_STRICT(readv,
- frame,
- -1,
- op_errno,
- NULL,
- 0,
- NULL,
- NULL,
- NULL);
- return 0;
-}
-
-static int32_t readv_trivial_completion(call_frame_t *frame,
- void *cookie,
- xlator_t *this,
- int32_t op_ret,
- int32_t op_errno,
- struct iatt *buf,
- dict_t *xdata)
-{
- crypt_local_t *local = frame->local;
-
- local->op_ret = op_ret;
- local->op_errno = op_errno;
-
- if (op_ret < 0) {
- gf_log(this->name, GF_LOG_WARNING,
- "stat failed (%d)", op_errno);
- goto error;
- }
- local->buf = *buf;
- STACK_WIND(frame,
- load_file_size,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->getxattr,
- local->loc,
- FSIZE_XATTR_PREFIX,
- NULL);
- return 0;
- error:
- STACK_UNWIND_STRICT(readv, frame, op_ret, op_errno,
- NULL, 0, NULL, NULL, NULL);
- return 0;
-}
-
-int32_t crypt_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 ret;
- crypt_local_t *local;
- struct crypt_inode_info *info;
- struct gf_flock lock = {0, };
-
-#if DEBUG_CRYPT
- gf_log("crypt", GF_LOG_DEBUG, "reading %d bytes from offset %llu",
- (int)size, (long long)offset);
- if (parent_is_crypt_xlator(frame, this))
- gf_log("crypt", GF_LOG_DEBUG, "parent is crypt");
-#endif
- local = crypt_alloc_local(frame, this, GF_FOP_READ);
- if (!local) {
- ret = ENOMEM;
- goto error;
- }
- if (size == 0)
- goto trivial;
-
- local->fd = fd_ref(fd);
- local->flags = flags;
-
- info = local_get_inode_info(local, this);
- if (info == NULL) {
- ret = EINVAL;
- fd_unref(fd);
- goto error;
- }
- if (!object_alg_atomic(&info->cinfo)) {
- ret = EINVAL;
- fd_unref(fd);
- goto error;
- }
- set_config_offsets(frame, this, offset, size,
- DATA_ATOM, 0);
- if (parent_is_crypt_xlator(frame, this)) {
- data_t *data;
- /*
- * We are called by crypt_writev (or cypt_ftruncate)
- * to perform the "read" component of the read-modify-write
- * (or read-prune-write) sequence for some atom;
- *
- * don't ask for access:
- * it has already been acquired
- *
- * Retrieve current file size
- */
- if (!xdata) {
- gf_log("crypt", GF_LOG_WARNING,
- "Regular file size hasn't been passed");
- ret = EIO;
- goto error;
- }
- data = dict_get(xdata, FSIZE_XATTR_PREFIX);
- if (!data) {
- gf_log("crypt", GF_LOG_WARNING,
- "Regular file size not found");
- ret = EIO;
- goto error;
- }
- local->old_file_size =
- local->cur_file_size = data_to_uint64(data);
-
- get_one_call(frame);
- STACK_WIND(frame,
- crypt_readv_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->readv,
- local->fd,
- /*
- * FIXME: read amount can be reduced
- */
- local->data_conf.expanded_size,
- local->data_conf.aligned_offset,
- flags,
- NULL);
- return 0;
- }
- if (xdata)
- local->xdata = dict_ref(xdata);
-
- lock.l_len = 0;
- lock.l_start = 0;
- lock.l_type = F_RDLCK;
- lock.l_whence = SEEK_SET;
-
- STACK_WIND(frame,
- crypt_readv_finodelk_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->finodelk,
- this->name,
- fd,
- F_SETLKW,
- &lock,
- NULL);
- return 0;
- trivial:
- STACK_WIND(frame,
- readv_trivial_completion,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fstat,
- fd,
- NULL);
- return 0;
- error:
- STACK_UNWIND_STRICT(readv,
- frame,
- -1,
- ret,
- NULL,
- 0,
- NULL,
- NULL,
- NULL);
- return 0;
-}
-
-void set_local_io_params_writev(call_frame_t *frame,
- struct object_cipher_info *object,
- struct rmw_atom *atom,
- off_t io_offset,
- uint32_t io_size)
-{
- crypt_local_t *local = frame->local;
-
- local->io_offset = io_offset;
- local->io_size = io_size;
-
- local->io_offset_nopad =
- atom->offset_at(frame, object) + atom->offset_in(frame, object);
-
- gf_log("crypt", GF_LOG_DEBUG,
- "set nopad offset to %llu",
- (unsigned long long)local->io_offset_nopad);
-
- local->io_size_nopad = atom->io_size_nopad(frame, object);
-
- gf_log("crypt", GF_LOG_DEBUG,
- "set nopad size to %llu",
- (unsigned long long)local->io_size_nopad);
-
- local->update_disk_file_size = 0;
- /*
- * NOTE: eof_padding_size is 0 for all full atoms;
- * For head and tail atoms it will be set up at rmw_partial block()
- */
- local->new_file_size = local->cur_file_size;
-
- if (local->io_offset_nopad + local->io_size_nopad > local->cur_file_size) {
-
- local->new_file_size = local->io_offset_nopad + local->io_size_nopad;
-
- gf_log("crypt", GF_LOG_DEBUG,
- "set new file size to %llu",
- (unsigned long long)local->new_file_size);
-
- local->update_disk_file_size = 1;
- }
-}
-
-void set_local_io_params_ftruncate(call_frame_t *frame,
- struct object_cipher_info *object)
-{
- uint32_t resid;
- crypt_local_t *local = frame->local;
- struct avec_config *conf = &local->data_conf;
-
- resid = conf->orig_offset & (object_alg_blksize(object) - 1);
- if (resid) {
- local->eof_padding_size =
- object_alg_blksize(object) - resid;
- local->new_file_size = conf->aligned_offset;
- local->update_disk_file_size = 0;
- /*
- * file size will be updated
- * in the ->writev() stack,
- * when submitting file tail
- */
- }
- else {
- local->eof_padding_size = 0;
- local->new_file_size = conf->orig_offset;
- local->update_disk_file_size = 1;
- /*
- * file size will be updated
- * in this ->ftruncate stack
- */
- }
-}
-
-static inline void submit_head(call_frame_t *frame, xlator_t *this)
-{
- crypt_local_t *local = frame->local;
- submit_partial(frame, this, local->fd, HEAD_ATOM);
-}
-
-static inline void submit_tail(call_frame_t *frame, xlator_t *this)
-{
- crypt_local_t *local = frame->local;
- submit_partial(frame, this, local->fd, TAIL_ATOM);
-}
-
-static void submit_hole(call_frame_t *frame, xlator_t *this)
-{
- /*
- * hole conversion always means
- * appended write and goes in ordered fashion
- */
- do_ordered_submit(frame, this, HOLE_ATOM);
-}
-
-static void submit_data(call_frame_t *frame, xlator_t *this)
-{
- if (is_ordered_mode(frame)) {
- do_ordered_submit(frame, this, DATA_ATOM);
- return;
- }
- gf_log("crypt", GF_LOG_WARNING, "Bad submit mode");
- get_nr_calls(frame, nr_calls_data(frame));
- do_parallel_submit(frame, this, DATA_ATOM);
- return;
-}
-
-/*
- * heplers called by writev_cbk, fruncate_cbk in ordered mode
- */
-
-static inline int32_t should_submit_hole(crypt_local_t *local)
-{
- struct avec_config *conf = &local->hole_conf;
-
- return conf->avec != NULL;
-}
-
-static inline int32_t should_resume_submit_hole(crypt_local_t *local)
-{
- struct avec_config *conf = &local->hole_conf;
-
- if (local->fop == GF_FOP_WRITE && has_tail_block(conf))
- /*
- * Don't submit a part of hole, which
- * fits into a data block:
- * this part of hole will be converted
- * as a gap filled by zeros in data head
- * block.
- */
- return conf->cursor < conf->acount - 1;
- else
- return conf->cursor < conf->acount;
-}
-
-static inline int32_t should_resume_submit_data(call_frame_t *frame)
-{
- crypt_local_t *local = frame->local;
- struct avec_config *conf = &local->data_conf;
-
- if (is_ordered_mode(frame))
- return conf->cursor < conf->acount;
- /*
- * parallel writes
- */
- return 0;
-}
-
-static inline int32_t should_submit_data_after_hole(crypt_local_t *local)
-{
- return local->data_conf.avec != NULL;
-}
-
-static void update_local_file_params(call_frame_t *frame,
- xlator_t *this,
- struct iatt *prebuf,
- struct iatt *postbuf)
-{
- crypt_local_t *local = frame->local;
-
- check_buf(frame, this, postbuf);
-
- local->prebuf = *prebuf;
- local->postbuf = *postbuf;
-
- local->prebuf.ia_size = local->cur_file_size;
- local->postbuf.ia_size = local->new_file_size;
-
- local->cur_file_size = local->new_file_size;
-}
-
-static int32_t end_writeback_writev(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)
-{
- crypt_local_t *local = frame->local;
-
- local->op_ret = op_ret;
- local->op_errno = op_errno;
-
- if (op_ret <= 0) {
- gf_log(this->name, GF_LOG_WARNING,
- "writev iteration failed");
- goto put_one_call;
- }
- /*
- * op_ret includes paddings (atom's head, atom's tail and EOF)
- */
- if (op_ret < local->io_size) {
- gf_log(this->name, GF_LOG_WARNING,
- "Incomplete writev iteration");
- goto put_one_call;
- }
- op_ret -= local->eof_padding_size;
- local->op_ret = op_ret;
-
- update_local_file_params(frame, this, prebuf, postbuf);
-
- if (data_write_in_progress(local)) {
-
- LOCK(&local->rw_count_lock);
- local->rw_count += op_ret;
- UNLOCK(&local->rw_count_lock);
-
- if (should_resume_submit_data(frame))
- submit_data(frame, this);
- }
- else {
- /*
- * hole conversion is going on;
- * don't take into account written zeros
- */
- if (should_resume_submit_hole(local))
- submit_hole(frame, this);
-
- else if (should_submit_data_after_hole(local))
- submit_data(frame, this);
- }
- put_one_call:
- put_one_call_writev(frame, this);
- return 0;
-}
-
-#define crypt_writev_cbk end_writeback_writev
-
-#define HOLE_WRITE_CHUNK_BITS 12
-#define HOLE_WRITE_CHUNK_SIZE (1 << HOLE_WRITE_CHUNK_BITS)
-
-/*
- * Convert hole of size @size at offset @off to
- * zeros and prepare respective iovecs for submit.
- * The hole lock should be held.
- *
- * Pre-conditions:
- * @local->file_size is set and valid.
- */
-int32_t prepare_for_submit_hole(call_frame_t *frame, xlator_t *this,
- uint64_t off, off_t size)
-{
- int32_t ret;
- crypt_local_t *local = frame->local;
- struct object_cipher_info *object = &local->info->cinfo;
-
- set_config_offsets(frame, this, off, size, HOLE_ATOM, 1);
-
- ret = set_config_avec_hole(this, local,
- &local->hole_conf, object, local->fop);
- crypt_check_conf(&local->hole_conf);
-
- return ret;
-}
-
-/*
- * prepare for submit @count bytes at offset @from
- */
-int32_t prepare_for_submit_data(call_frame_t *frame, xlator_t *this,
- off_t from, int32_t size, struct iovec *vec,
- int32_t vec_count, int32_t setup_gap)
-{
- uint32_t ret;
- crypt_local_t *local = frame->local;
- struct object_cipher_info *object = &local->info->cinfo;
-
- set_config_offsets(frame, this, from, size,
- DATA_ATOM, setup_gap);
-
- ret = set_config_avec_data(this, local,
- &local->data_conf, object, vec, vec_count);
- crypt_check_conf(&local->data_conf);
-
- return ret;
-}
-
-static void free_avec(struct iovec *avec,
- char **pool, int blocks_in_pool)
-{
- if (!avec)
- return;
- GF_FREE(pool);
- GF_FREE(avec);
-}
-
-static void free_avec_data(crypt_local_t *local)
-{
- return free_avec(local->data_conf.avec,
- local->data_conf.pool,
- local->data_conf.blocks_in_pool);
-}
-
-static void free_avec_hole(crypt_local_t *local)
-{
- return free_avec(local->hole_conf.avec,
- local->hole_conf.pool,
- local->hole_conf.blocks_in_pool);
-}
-
-
-static void do_parallel_submit(call_frame_t *frame, xlator_t *this,
- atom_data_type dtype)
-{
- crypt_local_t *local = frame->local;
- struct avec_config *conf;
-
- local->active_setup = dtype;
- conf = conf_by_type(frame, dtype);
-
- if (has_head_block(conf))
- submit_head(frame, this);
-
- if (has_full_blocks(conf))
- submit_full(frame, this);
-
- if (has_tail_block(conf))
- submit_tail(frame, this);
- return;
-}
-
-static void do_ordered_submit(call_frame_t *frame, xlator_t *this,
- atom_data_type dtype)
-{
- crypt_local_t *local = frame->local;
- struct avec_config *conf;
-
- local->active_setup = dtype;
- conf = conf_by_type(frame, dtype);
-
- if (should_submit_head_block(conf)) {
- get_one_call_nolock(frame);
- submit_head(frame, this);
- }
- else if (should_submit_full_block(conf)) {
- get_one_call_nolock(frame);
- submit_full(frame, this);
- }
- else if (should_submit_tail_block(conf)) {
- get_one_call_nolock(frame);
- submit_tail(frame, this);
- }
- else
- gf_log("crypt", GF_LOG_DEBUG,
- "nothing has been submitted in ordered mode");
- return;
-}
-
-static int32_t do_writev(call_frame_t *frame,
- void *cookie,
- xlator_t *this,
- int32_t op_ret,
- int32_t op_errno,
- dict_t *dict,
- dict_t *xdata)
-{
- data_t *data;
- crypt_local_t *local = frame->local;
- struct object_cipher_info *object = &local->info->cinfo;
- /*
- * extract regular file size
- */
- data = dict_get(dict, FSIZE_XATTR_PREFIX);
- if (!data) {
- gf_log("crypt", GF_LOG_WARNING, "Regular file size not found");
- op_ret = -1;
- op_errno = EIO;
- goto error;
- }
- local->old_file_size = local->cur_file_size = data_to_uint64(data);
-
- set_gap_at_end(frame, object, &local->data_conf, DATA_ATOM);
-
- if (local->cur_file_size < local->data_conf.orig_offset) {
- /*
- * Set up hole config
- */
- op_errno = prepare_for_submit_hole(frame,
- this,
- local->cur_file_size,
- local->data_conf.orig_offset - local->cur_file_size);
- if (op_errno) {
- local->op_ret = -1;
- local->op_errno = op_errno;
- goto error;
- }
- }
- if (should_submit_hole(local))
- submit_hole(frame, this);
- else
- submit_data(frame, this);
- return 0;
- error:
- get_one_call_nolock(frame);
- put_one_call_writev(frame, this);
- return 0;
-}
-
-static int32_t crypt_writev_finodelk_cbk(call_frame_t *frame,
- void *cookie,
- xlator_t *this,
- int32_t op_ret,
- int32_t op_errno,
- dict_t *xdata)
-{
- crypt_local_t *local = frame->local;
-
- local->op_ret = op_ret;
- local->op_errno = op_errno;
-
- if (op_ret < 0)
- goto error;
- /*
- * An access has been granted,
- * retrieve file size first
- */
- STACK_WIND(frame,
- do_writev,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fgetxattr,
- local->fd,
- FSIZE_XATTR_PREFIX,
- NULL);
- return 0;
- error:
- get_one_call_nolock(frame);
- put_one_call_writev(frame, this);
- return 0;
-}
-
-static int32_t writev_trivial_completion(call_frame_t *frame,
- void *cookie,
- xlator_t *this,
- int32_t op_ret,
- int32_t op_errno,
- struct iatt *buf,
- dict_t *dict)
-{
- crypt_local_t *local = frame->local;
-
- local->op_ret = op_ret;
- local->op_errno = op_errno;
- local->prebuf = *buf;
- local->postbuf = *buf;
-
- local->prebuf.ia_size = local->cur_file_size;
- local->postbuf.ia_size = local->cur_file_size;
-
- get_one_call(frame);
- put_one_call_writev(frame, this);
- return 0;
-}
-
-int crypt_writev(call_frame_t *frame,
- xlator_t *this,
- fd_t *fd,
- struct iovec *vec,
- int32_t count,
- off_t offset,
- uint32_t flags,
- struct iobref *iobref,
- dict_t *xdata)
-{
- int32_t ret;
- crypt_local_t *local;
- struct crypt_inode_info *info;
- struct gf_flock lock = {0, };
-#if DEBUG_CRYPT
- gf_log ("crypt", GF_LOG_DEBUG, "writing %d bytes from offset %llu",
- (int)iovec_get_size(vec, count), (long long)offset);
-#endif
- local = crypt_alloc_local(frame, this, GF_FOP_WRITE);
- if (!local) {
- ret = ENOMEM;
- goto error;
- }
- local->fd = fd_ref(fd);
-
- if (iobref)
- local->iobref = iobref_ref(iobref);
- /*
- * to update real file size on the server
- */
- local->xattr = dict_new();
- if (!local->xattr) {
- ret = ENOMEM;
- goto error;
- }
- local->flags = flags;
-
- info = local_get_inode_info(local, this);
- if (info == NULL) {
- ret = EINVAL;
- goto error;
- }
- if (!object_alg_atomic(&info->cinfo)) {
- ret = EINVAL;
- goto error;
- }
- if (iovec_get_size(vec, count) == 0)
- goto trivial;
-
- ret = prepare_for_submit_data(frame, this, offset,
- iovec_get_size(vec, count),
- vec, count, 0 /* don't setup gup
- in tail: we don't
- know file size yet */);
- if (ret)
- goto error;
-
- if (parent_is_crypt_xlator(frame, this)) {
- data_t *data;
- /*
- * we are called by shinking crypt_ftruncate(),
- * which doesn't perform hole conversion;
- *
- * don't ask for access:
- * it has already been acquired
- */
-
- /*
- * extract file size
- */
- if (!xdata) {
- gf_log("crypt", GF_LOG_WARNING,
- "Regular file size hasn't been passed");
- ret = EIO;
- goto error;
- }
- data = dict_get(xdata, FSIZE_XATTR_PREFIX);
- if (!data) {
- gf_log("crypt", GF_LOG_WARNING,
- "Regular file size not found");
- ret = EIO;
- goto error;
- }
- local->old_file_size =
- local->cur_file_size = data_to_uint64(data);
-
- submit_data(frame, this);
- return 0;
- }
- if (xdata)
- local->xdata = dict_ref(xdata);
- /*
- * lock the file and retrieve its size
- */
- lock.l_len = 0;
- lock.l_start = 0;
- lock.l_type = F_WRLCK;
- lock.l_whence = SEEK_SET;
-
- STACK_WIND(frame,
- crypt_writev_finodelk_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->finodelk,
- this->name,
- fd,
- F_SETLKW,
- &lock,
- NULL);
- return 0;
- trivial:
- STACK_WIND(frame,
- writev_trivial_completion,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fstat,
- fd,
- NULL);
- return 0;
- error:
- if (local && local->fd)
- fd_unref(fd);
- if (local && local->iobref)
- iobref_unref(iobref);
- if (local && local->xdata)
- dict_unref(xdata);
- if (local && local->xattr)
- dict_unref(local->xattr);
- if (local && local->info)
- free_inode_info(local->info);
-
- STACK_UNWIND_STRICT(writev, frame, -1, ret, NULL, NULL, NULL);
- return 0;
-}
-
-int32_t prepare_for_prune(call_frame_t *frame, xlator_t *this, uint64_t offset)
-{
- set_config_offsets(frame, this,
- offset,
- 0, /* count */
- DATA_ATOM,
- 0 /* since we prune, there is no
- gap in tail to uptodate */);
- return 0;
-}
-
-/*
- * Finish the read-prune-modify sequence
- *
- * Can be invoked as
- * 1) ->ftruncate_cbk() for cblock-aligned, or trivial prune
- * 2) ->writev_cbk() for non-cblock-aligned prune
- */
-
-static int32_t prune_complete(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)
-{
- crypt_local_t *local = frame->local;
-
- local->op_ret = op_ret;
- local->op_errno = op_errno;
-
- update_local_file_params(frame, this, prebuf, postbuf);
-
- put_one_call_ftruncate(frame, this);
- return 0;
-}
-
-/*
- * This is called as ->ftruncate_cbk()
- *
- * Perform the "write" component of the
- * read-prune-write sequence.
- *
- * submuit the rest of the file
- */
-static int32_t prune_submit_file_tail(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)
-{
- crypt_local_t *local = frame->local;
- struct avec_config *conf = &local->data_conf;
- dict_t *dict;
-
- if (op_ret < 0)
- goto put_one_call;
-
- if (local->xdata) {
- dict_unref(local->xdata);
- local->xdata = NULL;
- }
- if (xdata)
- local->xdata = dict_ref(xdata);
-
- dict = dict_new();
- if (!dict) {
- op_errno = ENOMEM;
- goto error;
- }
-
- update_local_file_params(frame, this, prebuf, postbuf);
- local->new_file_size = conf->orig_offset;
-
- /*
- * The rest of the file is a partial block and, hence,
- * should be written via RMW sequence, so the crypt xlator
- * does STACK_WIND to itself.
- *
- * Pass current file size to crypt_writev()
- */
- op_errno = dict_set(dict,
- FSIZE_XATTR_PREFIX,
- data_from_uint64(local->cur_file_size));
- if (op_errno) {
- gf_log("crypt", GF_LOG_WARNING,
- "can not set key to update file size");
- dict_unref(dict);
- goto error;
- }
- gf_log("crypt", GF_LOG_DEBUG,
- "passing current file size (%llu) to crypt_writev",
- (unsigned long long)local->cur_file_size);
- /*
- * Padding will be filled with
- * zeros by rmw_partial_block()
- */
- STACK_WIND(frame,
- prune_complete,
- this,
- this->fops->writev, /* crypt_writev */
- local->fd,
- &local->vec,
- 1,
- conf->aligned_offset, /* offset to write from */
- 0,
- local->iobref,
- dict);
-
- dict_unref(dict);
- return 0;
- error:
- local->op_ret = -1;
- local->op_errno = op_errno;
- put_one_call:
- put_one_call_ftruncate(frame, this);
- return 0;
-}
-
-/*
- * This is called as a callback of ->writev() invoked in behalf
- * of ftruncate(): it can be
- * 1) ordered writes issued by hole conversion in the case of
- * expanded truncate, or
- * 2) an rmw partial data block issued by non-cblock-aligned
- * prune.
- */
-int32_t end_writeback_ftruncate(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)
-{
- crypt_local_t *local = frame->local;
- /*
- * if nothing has been written,
- * then it must be an error
- */
- local->op_ret = op_ret;
- local->op_errno = op_errno;
-
- if (op_ret < 0)
- goto put_one_call;
-
- update_local_file_params(frame, this, prebuf, postbuf);
-
- if (data_write_in_progress(local))
- /* case (2) */
- goto put_one_call;
- /* case (1) */
- if (should_resume_submit_hole(local))
- submit_hole(frame, this);
- /*
- * case of hole, when we should't resume
- */
- put_one_call:
- put_one_call_ftruncate(frame, this);
- return 0;
-}
-
-/*
- * Perform prune and write components of the
- * read-prune-write sequence.
- *
- * Called as ->readv_cbk()
- *
- * Pre-conditions:
- * @vec contains the latest atom of the file
- * (plain text)
- */
-static int32_t prune_write(call_frame_t *frame,
- void *cookie,
- xlator_t *this,
- int32_t op_ret,
- int32_t op_errno,
- struct iovec *vec,
- int32_t count,
- struct iatt *stbuf,
- struct iobref *iobref,
- dict_t *xdata)
-{
- int32_t i;
- size_t to_copy;
- size_t copied = 0;
- crypt_local_t *local = frame->local;
- struct avec_config *conf = &local->data_conf;
-
- local->op_ret = op_ret;
- local->op_errno = op_errno;
- if (op_ret == -1)
- goto put_one_call;
-
- /*
- * At first, uptodate head block
- */
- if (iovec_get_size(vec, count) < conf->off_in_head) {
- gf_log(this->name, GF_LOG_WARNING,
- "Failed to uptodate head block for prune");
- local->op_ret = -1;
- local->op_errno = EIO;
- goto put_one_call;
- }
- local->vec.iov_len = conf->off_in_head;
- local->vec.iov_base = GF_CALLOC(1, local->vec.iov_len,
- gf_crypt_mt_data);
-
- if (local->vec.iov_base == NULL) {
- gf_log(this->name, GF_LOG_WARNING,
- "Failed to calloc head block for prune");
- local->op_ret = -1;
- local->op_errno = ENOMEM;
- goto put_one_call;
- }
- for (i = 0; i < count; i++) {
- to_copy = vec[i].iov_len;
- if (to_copy > local->vec.iov_len - copied)
- to_copy = local->vec.iov_len - copied;
-
- memcpy((char *)local->vec.iov_base + copied,
- vec[i].iov_base,
- to_copy);
- copied += to_copy;
- if (copied == local->vec.iov_len)
- break;
- }
- /*
- * perform prune with aligned offset
- * (i.e. at this step we prune a bit
- * more then it is needed
- */
- STACK_WIND(frame,
- prune_submit_file_tail,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->ftruncate,
- local->fd,
- conf->aligned_offset,
- local->xdata);
- return 0;
- put_one_call:
- put_one_call_ftruncate(frame, this);
- return 0;
-}
-
-/*
- * Perform a read-prune-write sequence
- */
-int32_t read_prune_write(call_frame_t *frame, xlator_t *this)
-{
- int32_t ret = 0;
- dict_t *dict = NULL;
- crypt_local_t *local = frame->local;
- struct avec_config *conf = &local->data_conf;
- struct object_cipher_info *object = &local->info->cinfo;
-
- set_local_io_params_ftruncate(frame, object);
- get_one_call_nolock(frame);
-
- if ((conf->orig_offset & (object_alg_blksize(object) - 1)) == 0) {
- /*
- * cblock-aligned prune:
- * we don't need read and write components,
- * just cut file body
- */
- gf_log("crypt", GF_LOG_DEBUG,
- "prune without RMW (at offset %llu",
- (unsigned long long)conf->orig_offset);
-
- STACK_WIND(frame,
- prune_complete,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->ftruncate,
- local->fd,
- conf->orig_offset,
- local->xdata);
- return 0;
- }
- gf_log("crypt", GF_LOG_DEBUG,
- "prune with RMW (at offset %llu",
- (unsigned long long)conf->orig_offset);
- /*
- * We are about to perform the "read" component of the
- * read-prune-write sequence. It means that we need to
- * read encrypted data from disk and decrypt it.
- * So, the crypt translator does STACK_WIND to itself.
- *
- * Pass current file size to crypt_readv()
-
- */
- dict = dict_new();
- if (!dict) {
- gf_log("crypt", GF_LOG_WARNING, "Can not alloc dict");
- ret = ENOMEM;
- goto exit;
- }
- ret = dict_set(dict,
- FSIZE_XATTR_PREFIX,
- data_from_uint64(local->cur_file_size));
- if (ret) {
- gf_log("crypt", GF_LOG_WARNING, "Can not set dict");
- goto exit;
- }
- STACK_WIND(frame,
- prune_write,
- this,
- this->fops->readv, /* crypt_readv */
- local->fd,
- get_atom_size(object), /* bytes to read */
- conf->aligned_offset, /* offset to read from */
- 0,
- dict);
- exit:
- if (dict)
- dict_unref(dict);
- return ret;
-}
-
-/*
- * File prune is more complicated than expand.
- * First we need to read the latest atom to not lose info
- * needed for proper update. Also we need to make sure that
- * every component of read-prune-write sequence leaves data
- * consistent
- *
- * Non-cblock aligned prune is performed as read-prune-write
- * sequence:
- *
- * 1) read the latest atom;
- * 2) perform cblock-aligned prune
- * 3) issue a write request for the end-of-file
- */
-int32_t prune_file(call_frame_t *frame, xlator_t *this, uint64_t offset)
-{
- int32_t ret;
-
- ret = prepare_for_prune(frame, this, offset);
- if (ret)
- return ret;
- return read_prune_write(frame, this);
-}
-
-int32_t expand_file(call_frame_t *frame, xlator_t *this,
- uint64_t offset)
-{
- int32_t ret;
- crypt_local_t *local = frame->local;
-
- ret = prepare_for_submit_hole(frame, this,
- local->old_file_size,
- offset - local->old_file_size);
- if (ret)
- return ret;
- submit_hole(frame, this);
- return 0;
-}
-
-static int32_t ftruncate_trivial_completion(call_frame_t *frame,
- void *cookie,
- xlator_t *this,
- int32_t op_ret,
- int32_t op_errno,
- struct iatt *buf,
- dict_t *dict)
-{
- crypt_local_t *local = frame->local;
-
- local->op_ret = op_ret;
- local->op_errno = op_errno;
- local->prebuf = *buf;
- local->postbuf = *buf;
-
- local->prebuf.ia_size = local->cur_file_size;
- local->postbuf.ia_size = local->cur_file_size;
-
- get_one_call(frame);
- put_one_call_ftruncate(frame, this);
- return 0;
-}
-
-static int32_t do_ftruncate(call_frame_t *frame,
- void *cookie,
- xlator_t *this,
- int32_t op_ret,
- int32_t op_errno,
- dict_t *dict,
- dict_t *xdata)
-{
- data_t *data;
- crypt_local_t *local = frame->local;
-
- if (op_ret)
- goto error;
- /*
- * extract regular file size
- */
- data = dict_get(dict, FSIZE_XATTR_PREFIX);
- if (!data) {
- gf_log("crypt", GF_LOG_WARNING, "Regular file size not found");
- op_errno = EIO;
- goto error;
- }
- local->old_file_size = local->cur_file_size = data_to_uint64(data);
-
- if (local->data_conf.orig_offset == local->cur_file_size) {
-#if DEBUG_CRYPT
- gf_log("crypt", GF_LOG_DEBUG,
- "trivial ftruncate (current file size %llu)",
- (unsigned long long)local->cur_file_size);
-#endif
- goto trivial;
- }
- else if (local->data_conf.orig_offset < local->cur_file_size) {
-#if DEBUG_CRYPT
- gf_log("crypt", GF_LOG_DEBUG, "prune from %llu to %llu",
- (unsigned long long)local->cur_file_size,
- (unsigned long long)local->data_conf.orig_offset);
-#endif
- op_errno = prune_file(frame,
- this,
- local->data_conf.orig_offset);
- }
- else {
-#if DEBUG_CRYPT
- gf_log("crypt", GF_LOG_DEBUG, "expand from %llu to %llu",
- (unsigned long long)local->cur_file_size,
- (unsigned long long)local->data_conf.orig_offset);
-#endif
- op_errno = expand_file(frame,
- this,
- local->data_conf.orig_offset);
- }
- if (op_errno)
- goto error;
- return 0;
- trivial:
- STACK_WIND(frame,
- ftruncate_trivial_completion,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fstat,
- local->fd,
- NULL);
- return 0;
- error:
- /*
- * finish with ftruncate
- */
- local->op_ret = -1;
- local->op_errno = op_errno;
-
- get_one_call_nolock(frame);
- put_one_call_ftruncate(frame, this);
- return 0;
-}
-
-static int32_t crypt_ftruncate_finodelk_cbk(call_frame_t *frame,
- void *cookie,
- xlator_t *this,
- int32_t op_ret,
- int32_t op_errno,
- dict_t *xdata)
-{
- crypt_local_t *local = frame->local;
-
- local->op_ret = op_ret;
- local->op_errno = op_errno;
-
- if (op_ret < 0)
- goto error;
- /*
- * An access has been granted,
- * retrieve file size first
- */
- STACK_WIND(frame,
- do_ftruncate,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fgetxattr,
- local->fd,
- FSIZE_XATTR_PREFIX,
- NULL);
- return 0;
- error:
- get_one_call_nolock(frame);
- put_one_call_ftruncate(frame, this);
- return 0;
-}
-
-/*
- * ftruncate is performed in 2 steps:
- * . recieve file size;
- * . expand or prune file.
- */
-static int32_t crypt_ftruncate(call_frame_t *frame,
- xlator_t *this,
- fd_t *fd,
- off_t offset,
- dict_t *xdata)
-{
- int32_t ret;
- crypt_local_t *local;
- struct crypt_inode_info *info;
- struct gf_flock lock = {0, };
-
- local = crypt_alloc_local(frame, this, GF_FOP_FTRUNCATE);
- if (!local) {
- ret = ENOMEM;
- goto error;
- }
- local->xattr = dict_new();
- if (!local->xattr) {
- ret = ENOMEM;
- goto error;
- }
- local->fd = fd_ref(fd);
- info = local_get_inode_info(local, this);
- if (info == NULL) {
- ret = EINVAL;
- goto error;
- }
- if (!object_alg_atomic(&info->cinfo)) {
- ret = EINVAL;
- goto error;
- }
- local->data_conf.orig_offset = offset;
- if (xdata)
- local->xdata = dict_ref(xdata);
-
- lock.l_len = 0;
- lock.l_start = 0;
- lock.l_type = F_WRLCK;
- lock.l_whence = SEEK_SET;
-
- STACK_WIND(frame,
- crypt_ftruncate_finodelk_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->finodelk,
- this->name,
- fd,
- F_SETLKW,
- &lock,
- NULL);
- return 0;
- error:
- if (local && local->fd)
- fd_unref(fd);
- if (local && local->xdata)
- dict_unref(xdata);
- if (local && local->xattr)
- dict_unref(local->xattr);
- if (local && local->info)
- free_inode_info(local->info);
-
- STACK_UNWIND_STRICT(ftruncate, frame, -1, ret, NULL, NULL, NULL);
- return 0;
-}
-
-/* ->flush_cbk() */
-int32_t truncate_end(call_frame_t *frame,
- void *cookie,
- xlator_t *this,
- int32_t op_ret,
- int32_t op_errno,
- dict_t *xdata)
-{
- crypt_local_t *local = frame->local;
-
- STACK_UNWIND_STRICT(truncate,
- frame,
- op_ret,
- op_errno,
- &local->prebuf,
- &local->postbuf,
- local->xdata);
- return 0;
-}
-
-/* ftruncate_cbk() */
-int32_t truncate_flush(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)
-{
- crypt_local_t *local = frame->local;
- fd_t *fd = local->fd;
- local->prebuf = *prebuf;
- local->postbuf = *postbuf;
-
- STACK_WIND(frame,
- truncate_end,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->flush,
- fd,
- NULL);
- fd_unref(fd);
- return 0;
-}
-
-/*
- * is called as ->open_cbk()
- */
-static int32_t truncate_begin(call_frame_t *frame,
- void *cookie,
- xlator_t *this,
- int32_t op_ret,
- int32_t op_errno,
- fd_t *fd,
- dict_t *xdata)
-{
- crypt_local_t *local = frame->local;
-
- if (op_ret < 0) {
- fd_unref(fd);
- STACK_UNWIND_STRICT(truncate,
- frame,
- op_ret,
- op_errno, NULL, NULL, NULL);
- return 0;
- }
- /*
- * crypt_truncate() is implemented via crypt_ftruncate(),
- * so the crypt xlator does STACK_WIND to itself here
- */
- STACK_WIND(frame,
- truncate_flush,
- this,
- this->fops->ftruncate, /* crypt_ftruncate */
- fd,
- local->offset,
- NULL);
- return 0;
-}
-
-/*
- * crypt_truncate() is implemented via crypt_ftruncate() as a
- * sequence crypt_open() - crypt_ftruncate() - truncate_flush()
- */
-int32_t crypt_truncate(call_frame_t *frame,
- xlator_t *this,
- loc_t *loc,
- off_t offset,
- dict_t *xdata)
-{
- fd_t *fd;
- crypt_local_t *local;
-
-#if DEBUG_CRYPT
- gf_log(this->name, GF_LOG_DEBUG,
- "truncate file %s at offset %llu",
- loc->path, (unsigned long long)offset);
-#endif
- local = crypt_alloc_local(frame, this, GF_FOP_TRUNCATE);
- if (!local)
- goto error;
-
- fd = fd_create(loc->inode, frame->root->pid);
- if (!fd) {
- gf_log(this->name, GF_LOG_ERROR, "Can not create fd");
- goto error;
- }
- local->fd = fd;
- local->offset = offset;
- local->xdata = xdata;
- STACK_WIND(frame,
- truncate_begin,
- this,
- this->fops->open, /* crypt_open() */
- loc,
- O_RDWR,
- fd,
- NULL);
- return 0;
- error:
- STACK_UNWIND_STRICT(truncate, frame, -1, EINVAL, NULL, NULL, NULL);
- return 0;
-}
-
-end_writeback_handler_t dispatch_end_writeback(glusterfs_fop_t fop)
-{
- switch (fop) {
- case GF_FOP_WRITE:
- return end_writeback_writev;
- case GF_FOP_FTRUNCATE:
- return end_writeback_ftruncate;
- default:
- gf_log("crypt", GF_LOG_WARNING, "Bad wb operation %d", fop);
- return NULL;
- }
-}
-
-/*
- * true, if the caller needs metadata string
- */
-static int32_t is_custom_mtd(dict_t *xdata)
-{
- data_t *data;
- uint32_t flags;
-
- if (!xdata)
- return 0;
-
- data = dict_get(xdata, MSGFLAGS_PREFIX);
- if (!data)
- return 0;
- if (data->len != sizeof(uint32_t)) {
- gf_log("crypt", GF_LOG_WARNING,
- "Bad msgflags size (%d)", data->len);
- return -1;
- }
- flags = *((uint32_t *)data->data);
- return msgflags_check_mtd_lock(&flags);
-}
-
-static int32_t crypt_open_done(call_frame_t *frame,
- void *cookie,
- xlator_t *this,
- int32_t op_ret,
- int32_t op_errno, dict_t *xdata)
-{
- crypt_local_t *local = frame->local;
-
- local->op_ret = op_ret;
- local->op_errno = op_errno;
- if (op_ret < 0)
- gf_log(this->name, GF_LOG_WARNING, "mtd unlock failed (%d)",
- op_errno);
- put_one_call_open(frame);
- return 0;
-}
-
-static void crypt_open_tail(call_frame_t *frame, xlator_t *this)
-{
- struct gf_flock lock = {0, };
- crypt_local_t *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,
- crypt_open_done,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->finodelk,
- this->name,
- local->fd,
- F_SETLKW,
- &lock,
- NULL);
-}
-
-/*
- * load private inode info at open time
- * called as ->fgetxattr_cbk()
- */
-static int load_mtd_open(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 ret;
- gf_boolean_t upload_info;
- data_t *mtd;
- uint64_t value = 0;
- struct crypt_inode_info *info;
- crypt_local_t *local = frame->local;
- crypt_private_t *priv = this->private;
-
- local->op_ret = op_ret;
- local->op_errno = op_errno;
-
- if (local->fd->inode->ia_type == IA_IFLNK)
- goto exit;
- if (op_ret < 0)
- goto exit;
- /*
- * first, check for cached info
- */
- ret = inode_ctx_get(local->fd->inode, this, &value);
- if (ret != -1) {
- info = (struct crypt_inode_info *)(long)value;
- if (info == NULL) {
- gf_log(this->name, GF_LOG_WARNING,
- "Inode info expected, but not found");
- local->op_ret = -1;
- local->op_errno = EIO;
- goto exit;
- }
- /*
- * info has been found in the cache
- */
- upload_info = _gf_false;
- }
- else {
- /*
- * info hasn't been found in the cache.
- */
- info = alloc_inode_info(local, local->loc);
- if (!info) {
- local->op_ret = -1;
- local->op_errno = ENOMEM;
- goto exit;
- }
- init_inode_info_head(info, local->fd);
- upload_info = _gf_true;
- }
- /*
- * extract metadata
- */
- mtd = dict_get(dict, CRYPTO_FORMAT_PREFIX);
- if (!mtd) {
- local->op_ret = -1;
- local->op_errno = ENOENT;
- gf_log (this->name, GF_LOG_WARNING,
- "Format string wasn't found");
- goto exit;
- }
- /*
- * authenticate metadata against the path
- */
- ret = open_format((unsigned char *)mtd->data,
- mtd->len,
- local->loc,
- info,
- get_master_cinfo(priv),
- local,
- upload_info);
- if (ret) {
- local->op_ret = -1;
- local->op_errno = ret;
- goto exit;
- }
- if (upload_info) {
- ret = init_inode_info_tail(info, get_master_cinfo(priv));
- if (ret) {
- local->op_ret = -1;
- local->op_errno = ret;
- goto exit;
- }
- ret = inode_ctx_put(local->fd->inode,
- this, (uint64_t)(long)info);
- if (ret == -1) {
- local->op_ret = -1;
- local->op_errno = EIO;
- goto exit;
- }
- }
- if (local->custom_mtd) {
- /*
- * pass the metadata string to the customer
- */
- ret = dict_set_static_bin(local->xdata,
- CRYPTO_FORMAT_PREFIX,
- mtd->data,
- mtd->len);
- if (ret) {
- local->op_ret = -1;
- local->op_errno = ret;
- goto exit;
- }
- }
- exit:
- if (!local->custom_mtd)
- crypt_open_tail(frame, this);
- else
- put_one_call_open(frame);
- return 0;
-}
-
-static int32_t crypt_open_finodelk_cbk(call_frame_t *frame,
- void *cookie,
- xlator_t *this,
- int32_t op_ret,
- int32_t op_errno,
- dict_t *xdata)
-{
- crypt_local_t *local = frame->local;
-
- local->op_ret = op_ret;
- local->op_errno = op_errno;
-
- if (op_ret < 0) {
- gf_log(this->name, GF_LOG_WARNING, "finodelk (LOCK) failed");
- goto exit;
- }
- STACK_WIND(frame,
- load_mtd_open,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fgetxattr,
- local->fd,
- CRYPTO_FORMAT_PREFIX,
- NULL);
- return 0;
- exit:
- put_one_call_open(frame);
- return 0;
-}
-
-/*
- * verify metadata against the specified pathname
- */
-static int32_t crypt_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)
-{
- struct gf_flock lock = {0, };
- crypt_local_t *local = frame->local;
-
- local->op_ret = op_ret;
- local->op_errno = op_errno;
-
- if (local->fd->inode->ia_type == IA_IFLNK)
- goto exit;
- if (op_ret < 0)
- goto exit;
- if (xdata)
- local->xdata = dict_ref(xdata);
- else if (local->custom_mtd){
- local->xdata = dict_new();
- if (!local->xdata) {
- local->op_ret = -1;
- local->op_errno = ENOMEM;
- gf_log ("crypt", GF_LOG_ERROR,
- "Can not get new dict for mtd string");
- goto exit;
- }
- }
- lock.l_len = 0;
- lock.l_start = 0;
- lock.l_type = local->custom_mtd ? F_WRLCK : F_RDLCK;
- lock.l_whence = SEEK_SET;
-
- STACK_WIND(frame,
- crypt_open_finodelk_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->finodelk,
- this->name,
- fd,
- F_SETLKW,
- &lock,
- NULL);
- return 0;
- exit:
- put_one_call_open(frame);
- return 0;
-}
-
-static int32_t crypt_open(call_frame_t *frame,
- xlator_t *this,
- loc_t *loc,
- int32_t flags,
- fd_t *fd,
- dict_t *xdata)
-{
- int32_t ret = ENOMEM;
- crypt_local_t *local;
-
- local = crypt_alloc_local(frame, this, GF_FOP_OPEN);
- if (!local)
- goto error;
- local->loc = GF_CALLOC(1, sizeof(*loc), gf_crypt_mt_loc);
- if (!local->loc) {
- ret = ENOMEM;
- goto error;
- }
- memset(local->loc, 0, sizeof(*local->loc));
- ret = loc_copy(local->loc, loc);
- if (ret) {
- GF_FREE(local->loc);
- goto error;
- }
- local->fd = fd_ref(fd);
-
- ret = is_custom_mtd(xdata);
- if (ret < 0) {
- loc_wipe(local->loc);
- GF_FREE(local->loc);
- ret = EINVAL;
- goto error;
- }
- local->custom_mtd = ret;
-
- if ((flags & O_ACCMODE) == O_WRONLY)
- /*
- * we can't open O_WRONLY, because
- * we need to do read-modify-write
- */
- flags = (flags & ~O_ACCMODE) | O_RDWR;
- /*
- * Make sure that out translated offsets
- * and counts won't be ignored
- */
- flags &= ~O_APPEND;
- get_one_call_nolock(frame);
- STACK_WIND(frame,
- crypt_open_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->open,
- loc,
- flags,
- fd,
- xdata);
- return 0;
- error:
- STACK_UNWIND_STRICT(open,
- frame,
- -1,
- ret,
- NULL,
- NULL);
- return 0;
-}
-
-static int32_t init_inode_info_tail(struct crypt_inode_info *info,
- struct master_cipher_info *master)
-{
- int32_t ret;
- struct object_cipher_info *object = &info->cinfo;
-
-#if DEBUG_CRYPT
- gf_log("crypt", GF_LOG_DEBUG, "Init inode info for object %s",
- uuid_utoa(info->oid));
-#endif
- ret = data_cipher_algs[object->o_alg][object->o_mode].set_private(info,
- master);
- if (ret) {
- gf_log("crypt", GF_LOG_ERROR, "Set private info failed");
- return ret;
- }
- return 0;
-}
-
-/*
- * Init inode info at ->create() time
- */
-static void init_inode_info_create(struct crypt_inode_info *info,
- struct master_cipher_info *master,
- data_t *data)
-{
- struct object_cipher_info *object;
-
- info->nr_minor = CRYPT_XLATOR_ID;
- memcpy(info->oid, data->data, data->len);
-
- object = &info->cinfo;
-
- object->o_alg = master->m_alg;
- object->o_mode = master->m_mode;
- object->o_block_bits = master->m_block_bits;
- object->o_dkey_size = master->m_dkey_size;
-}
-
-static void init_inode_info_head(struct crypt_inode_info *info, fd_t *fd)
-{
- memcpy(info->oid, fd->inode->gfid, sizeof(uuid_t));
-}
-
-static int32_t crypt_create_done(call_frame_t *frame,
- void *cookie,
- xlator_t *this,
- int32_t op_ret,
- int32_t op_errno, dict_t *xdata)
-{
- crypt_private_t *priv = this->private;
- crypt_local_t *local = frame->local;
- struct crypt_inode_info *info = local->info;
- fd_t *local_fd = local->fd;
- dict_t *local_xdata = local->xdata;
- inode_t *local_inode = local->inode;
-
- if (op_ret < 0) {
- free_inode_info(info);
- goto unwind;
- }
- op_errno = init_inode_info_tail(info, get_master_cinfo(priv));
- if (op_errno) {
- op_ret = -1;
- free_inode_info(info);
- goto unwind;
- }
- /*
- * FIXME: drop major subversion number
- */
- op_ret = inode_ctx_put(local->fd->inode, this, (uint64_t)(long)info);
- if (op_ret == -1) {
- op_errno = EIO;
- free_inode_info(info);
- goto unwind;
- }
- unwind:
- free_format(local);
- STACK_UNWIND_STRICT(create,
- frame,
- op_ret,
- op_errno,
- local_fd,
- local_inode,
- &local->buf,
- &local->prebuf,
- &local->postbuf,
- local_xdata);
- fd_unref(local_fd);
- inode_unref(local_inode);
- if (local_xdata)
- dict_unref(local_xdata);
- return 0;
-}
-
-static int crypt_create_tail(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, };
- crypt_local_t *local = frame->local;
- fd_t *local_fd = local->fd;
- dict_t *local_xdata = local->xdata;
- inode_t *local_inode = local->inode;
-
- dict_unref(local->xattr);
-
- if (op_ret < 0)
- goto error;
-
- 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,
- crypt_create_done,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->finodelk,
- this->name,
- local->fd,
- F_SETLKW,
- &lock,
- NULL);
- return 0;
- error:
- free_inode_info(local->info);
- free_format(local);
-
- STACK_UNWIND_STRICT(create,
- frame,
- op_ret,
- op_errno,
- local_fd,
- local_inode,
- &local->buf,
- &local->prebuf,
- &local->postbuf,
- local_xdata);
-
- fd_unref(local_fd);
- inode_unref(local_inode);
- if (local_xdata)
- dict_unref(local_xdata);
- return 0;
-}
-
-static int32_t crypt_create_finodelk_cbk(call_frame_t *frame,
- void *cookie,
- xlator_t *this,
- int32_t op_ret,
- int32_t op_errno,
- dict_t *xdata)
-{
- crypt_local_t *local = frame->local;
- struct crypt_inode_info *info = local->info;
-
- if (op_ret < 0)
- goto error;
-
- STACK_WIND(frame,
- crypt_create_tail,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fsetxattr,
- local->fd,
- local->xattr, /* CRYPTO_FORMAT_PREFIX */
- 0,
- NULL);
- return 0;
- error:
- free_inode_info(info);
- free_format(local);
- fd_unref(local->fd);
- dict_unref(local->xattr);
- if (local->xdata)
- dict_unref(local->xdata);
-
- STACK_UNWIND_STRICT(create,
- frame,
- op_ret,
- op_errno,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL);
- return 0;
-}
-
-/*
- * Create and store crypt-specific format on disk;
- * Populate cache with private inode info
- */
-static int32_t crypt_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 gf_flock lock = {0, };
- crypt_local_t *local = frame->local;
- struct crypt_inode_info *info = local->info;
-
- if (op_ret < 0)
- goto error;
- if (xdata)
- local->xdata = dict_ref(xdata);
- local->inode = inode_ref(inode);
- local->buf = *buf;
- local->prebuf = *preparent;
- local->postbuf = *postparent;
-
- lock.l_len = 0;
- lock.l_start = 0;
- lock.l_type = F_WRLCK;
- lock.l_whence = SEEK_SET;
-
- STACK_WIND(frame,
- crypt_create_finodelk_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->finodelk,
- this->name,
- local->fd,
- F_SETLKW,
- &lock,
- NULL);
- return 0;
- error:
- free_inode_info(info);
- free_format(local);
- fd_unref(local->fd);
- dict_unref(local->xattr);
-
- STACK_UNWIND_STRICT(create,
- frame,
- op_ret,
- op_errno,
- NULL, NULL, NULL,
- NULL, NULL, NULL);
- return 0;
-}
-
-static int32_t crypt_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)
-{
- int ret;
- data_t *data;
- crypt_local_t *local;
- crypt_private_t *priv;
- struct master_cipher_info *master;
- struct crypt_inode_info *info;
-
- priv = this->private;
- master = get_master_cinfo(priv);
-
- if (master_alg_atomic(master)) {
- /*
- * We can't open O_WRONLY, because we
- * need to do read-modify-write.
- */
- if ((flags & O_ACCMODE) == O_WRONLY)
- flags = (flags & ~O_ACCMODE) | O_RDWR;
- /*
- * Make sure that out translated offsets
- * and counts won't be ignored
- */
- flags &= ~O_APPEND;
- }
- local = crypt_alloc_local(frame, this, GF_FOP_CREATE);
- if (!local) {
- ret = ENOMEM;
- goto error;
- }
- data = dict_get(xdata, "gfid-req");
- if (!data) {
- ret = EINVAL;
- gf_log("crypt", GF_LOG_WARNING, "gfid not found");
- goto error;
- }
- if (data->len != sizeof(uuid_t)) {
- ret = EINVAL;
- gf_log("crypt", GF_LOG_WARNING,
- "bad gfid size (%d), should be %d",
- (int)data->len, (int)sizeof(uuid_t));
- goto error;
- }
- info = alloc_inode_info(local, loc);
- if (!info){
- ret = ENOMEM;
- goto error;
- }
- /*
- * NOTE:
- * format has to be created BEFORE
- * proceeding to the untrusted server
- */
- ret = alloc_format_create(local);
- if (ret) {
- free_inode_info(info);
- goto error;
- }
- init_inode_info_create(info, master, data);
-
- ret = create_format(local->format,
- loc,
- info,
- master);
- if (ret) {
- free_inode_info(info);
- goto error;
- }
- local->xattr = dict_new();
- if (!local->xattr) {
- free_inode_info(info);
- free_format(local);
- goto error;
- }
- ret = dict_set_static_bin(local->xattr,
- CRYPTO_FORMAT_PREFIX,
- local->format,
- new_format_size());
- if (ret) {
- dict_unref(local->xattr);
- free_inode_info(info);
- free_format(local);
- goto error;
- }
- ret = dict_set(local->xattr, FSIZE_XATTR_PREFIX, data_from_uint64(0));
- if (ret) {
- dict_unref(local->xattr);
- free_inode_info(info);
- free_format(local);
- goto error;
- }
- local->fd = fd_ref(fd);
-
- STACK_WIND(frame,
- crypt_create_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->create,
- loc,
- flags,
- mode,
- umask,
- fd,
- xdata);
- return 0;
- error:
- gf_log("crypt", GF_LOG_WARNING, "can not create file");
- STACK_UNWIND_STRICT(create,
- frame,
- -1,
- ret,
- NULL, NULL, NULL,
- NULL, NULL, NULL);
- return 0;
-}
-
-/*
- * FIXME: this should depends on the version of format string
- */
-static int32_t filter_crypt_xattr(dict_t *dict,
- char *key, data_t *value, void *data)
-{
- dict_del(dict, key);
- return 0;
-}
-
-static int32_t crypt_fsetxattr(call_frame_t *frame,
- xlator_t *this,
- fd_t *fd,
- dict_t *dict,
- int32_t flags, dict_t *xdata)
-{
- dict_foreach_fnmatch(dict, "trusted.glusterfs.crypt*",
- filter_crypt_xattr, NULL);
- STACK_WIND(frame,
- default_fsetxattr_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fsetxattr,
- fd,
- dict,
- flags,
- xdata);
- return 0;
-}
-
-/*
- * TBD: verify file metadata before wind
- */
-static int32_t crypt_setxattr(call_frame_t *frame,
- xlator_t *this,
- loc_t *loc,
- dict_t *dict,
- int32_t flags, dict_t *xdata)
-{
- dict_foreach_fnmatch(dict, "trusted.glusterfs.crypt*",
- filter_crypt_xattr, NULL);
- STACK_WIND(frame,
- default_setxattr_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->setxattr,
- loc,
- dict,
- flags,
- xdata);
- return 0;
-}
-
-/*
- * called as flush_cbk()
- */
-static int32_t linkop_end(call_frame_t *frame,
- void *cookie,
- xlator_t *this,
- int32_t op_ret,
- int32_t op_errno,
- dict_t *xdata)
-{
- crypt_local_t *local = frame->local;
- linkop_unwind_handler_t unwind_fn;
- unwind_fn = linkop_unwind_dispatch(local->fop);
-
- local->op_ret = op_ret;
- local->op_errno = op_errno;
-
- if (op_ret < 0 &&
- op_errno == ENOENT &&
- local->loc->inode->ia_type == IA_IFLNK) {
- local->op_ret = 0;
- local->op_errno = 0;
- }
- unwind_fn(frame);
- return 0;
-}
-
-/*
- * unpin inode on the server
- */
-static int32_t link_flush(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)
-{
- crypt_local_t *local = frame->local;
-
- if (op_ret < 0)
- goto error;
- if (local->xdata) {
- dict_unref(local->xdata);
- local->xdata = NULL;
- }
- if (xdata)
- local->xdata = dict_ref(xdata);
- local->inode = inode_ref(inode);
- local->buf = *buf;
- local->prebuf = *preparent;
- local->postbuf = *postparent;
-
- STACK_WIND(frame,
- linkop_end,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->flush,
- local->fd,
- NULL);
- return 0;
- error:
- local->op_ret = -1;
- local->op_errno = op_errno;
- link_unwind(frame);
- return 0;
-}
-
-void link_unwind(call_frame_t *frame)
-{
- crypt_local_t *local = frame->local;
- dict_t *xdata;
- dict_t *xattr;
- inode_t *inode;
-
- if (!local) {
- STACK_UNWIND_STRICT(link,
- frame,
- -1,
- ENOMEM,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL);
- return;
- }
- xdata = local->xdata;
- xattr = local->xattr;
- inode = local->inode;
-
- if (local->loc){
- loc_wipe(local->loc);
- GF_FREE(local->loc);
- }
- if (local->newloc) {
- loc_wipe(local->newloc);
- GF_FREE(local->newloc);
- }
- if (local->fd)
- fd_unref(local->fd);
- if (local->format)
- GF_FREE(local->format);
-
- STACK_UNWIND_STRICT(link,
- frame,
- local->op_ret,
- local->op_errno,
- inode,
- &local->buf,
- &local->prebuf,
- &local->postbuf,
- xdata);
- if (xdata)
- dict_unref(xdata);
- if (xattr)
- dict_unref(xattr);
- if (inode)
- inode_unref(inode);
-}
-
-void link_wind(call_frame_t *frame, xlator_t *this)
-{
- crypt_local_t *local = frame->local;
-
- STACK_WIND(frame,
- link_flush,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->link,
- local->loc,
- local->newloc,
- local->xdata);
-}
-
-/*
- * unlink()
- */
-static int32_t unlink_flush(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)
-{
- crypt_local_t *local = frame->local;
-
- if (op_ret < 0)
- goto error;
- local->prebuf = *preparent;
- local->postbuf = *postparent;
- if (local->xdata) {
- dict_unref(local->xdata);
- local->xdata = NULL;
- }
- if (xdata)
- local->xdata = dict_ref(xdata);
-
- STACK_WIND(frame,
- linkop_end,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->flush,
- local->fd,
- NULL);
- return 0;
- error:
- local->op_ret = -1;
- local->op_errno = op_errno;
- unlink_unwind(frame);
- return 0;
-}
-
-void unlink_unwind(call_frame_t *frame)
-{
- crypt_local_t *local = frame->local;
- dict_t *xdata;
- dict_t *xattr;
-
- if (!local) {
- STACK_UNWIND_STRICT(unlink,
- frame,
- -1,
- ENOMEM,
- NULL,
- NULL,
- NULL);
- return;
- }
- xdata = local->xdata;
- xattr = local->xattr;
- if (local->loc){
- loc_wipe(local->loc);
- GF_FREE(local->loc);
- }
- if (local->fd)
- fd_unref(local->fd);
- if (local->format)
- GF_FREE(local->format);
-
- STACK_UNWIND_STRICT(unlink,
- frame,
- local->op_ret,
- local->op_errno,
- &local->prebuf,
- &local->postbuf,
- xdata);
- if (xdata)
- dict_unref(xdata);
- if (xattr)
- dict_unref(xattr);
-}
-
-void unlink_wind(call_frame_t *frame, xlator_t *this)
-{
- crypt_local_t *local = frame->local;
-
- STACK_WIND(frame,
- unlink_flush,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->unlink,
- local->loc,
- local->flags,
- local->xdata);
-}
-
-void rename_unwind(call_frame_t *frame)
-{
- crypt_local_t *local = frame->local;
- dict_t *xdata;
- dict_t *xattr;
- struct iatt *prenewparent;
- struct iatt *postnewparent;
-
- if (!local) {
- STACK_UNWIND_STRICT(rename,
- frame,
- -1,
- ENOMEM,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL);
- return;
- }
- xdata = local->xdata;
- xattr = local->xattr;
- prenewparent = local->prenewparent;
- postnewparent = local->postnewparent;
-
- if (local->loc){
- loc_wipe(local->loc);
- GF_FREE(local->loc);
- }
- if (local->newloc){
- loc_wipe(local->newloc);
- GF_FREE(local->newloc);
- }
- if (local->fd)
- fd_unref(local->fd);
- if (local->format)
- GF_FREE(local->format);
-
- STACK_UNWIND_STRICT(rename,
- frame,
- local->op_ret,
- local->op_errno,
- &local->buf,
- &local->prebuf,
- &local->postbuf,
- prenewparent,
- postnewparent,
- xdata);
- if (xdata)
- dict_unref(xdata);
- if (xattr)
- dict_unref(xattr);
- if (prenewparent)
- GF_FREE(prenewparent);
- if (postnewparent)
- GF_FREE(postnewparent);
-}
-
-/*
- * called as flush_cbk()
- */
-static int32_t rename_end(call_frame_t *frame,
- void *cookie,
- xlator_t *this,
- int32_t op_ret,
- int32_t op_errno,
- dict_t *xdata)
-{
- crypt_local_t *local = frame->local;
-
- local->op_ret = op_ret;
- local->op_errno = op_errno;
-
- rename_unwind(frame);
- return 0;
-}
-
-static int32_t rename_flush(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)
-{
- crypt_local_t *local = frame->local;
-
- if (op_ret < 0)
- goto error;
- dict_unref(local->xdata);
- local->xdata = NULL;
- if (xdata)
- local->xdata = dict_ref(xdata);
-
- local->buf = *buf;
- local->prebuf = *preoldparent;
- local->postbuf = *postoldparent;
- if (prenewparent) {
- local->prenewparent = GF_CALLOC(1, sizeof(*prenewparent),
- gf_crypt_mt_iatt);
- if (!local->prenewparent) {
- op_errno = ENOMEM;
- goto error;
- }
- *local->prenewparent = *prenewparent;
- }
- if (postnewparent) {
- local->postnewparent = GF_CALLOC(1, sizeof(*postnewparent),
- gf_crypt_mt_iatt);
- if (!local->postnewparent) {
- op_errno = ENOMEM;
- goto error;
- }
- *local->postnewparent = *postnewparent;
- }
- STACK_WIND(frame,
- rename_end,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->flush,
- local->fd,
- NULL);
- return 0;
- error:
- local->op_ret = -1;
- local->op_errno = op_errno;
- rename_unwind(frame);
- return 0;
-}
-
-void rename_wind(call_frame_t *frame, xlator_t *this)
-{
- crypt_local_t *local = frame->local;
-
- STACK_WIND(frame,
- rename_flush,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->rename,
- local->loc,
- local->newloc,
- local->xdata);
-}
-
-static int32_t __do_linkop(call_frame_t *frame,
- void *cookie,
- xlator_t *this,
- int32_t op_ret,
- int32_t op_errno, dict_t *xdata)
-{
- crypt_local_t *local = frame->local;
- linkop_wind_handler_t wind_fn;
- linkop_unwind_handler_t unwind_fn;
-
- wind_fn = linkop_wind_dispatch(local->fop);
- unwind_fn = linkop_unwind_dispatch(local->fop);
-
- local->op_ret = op_ret;
- local->op_errno = op_errno;
-
- if (op_ret >= 0)
- wind_fn(frame, this);
- else {
- gf_log(this->name, GF_LOG_WARNING, "mtd unlock failed (%d)",
- op_errno);
- unwind_fn(frame);
- }
- return 0;
-}
-
-static int32_t do_linkop(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, };
- crypt_local_t *local = frame->local;
- linkop_unwind_handler_t unwind_fn;
-
- unwind_fn = linkop_unwind_dispatch(local->fop);
- local->op_ret = op_ret;
- local->op_errno = op_errno;
-
- if(op_ret < 0)
- goto error;
-
- 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,
- __do_linkop,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->finodelk,
- this->name,
- local->fd,
- F_SETLKW,
- &lock,
- NULL);
- return 0;
- error:
- unwind_fn(frame);
- return 0;
-}
-
-/*
- * Update the metadata string (against the new pathname);
- * submit the result
- */
-static int32_t linkop_begin(call_frame_t *frame,
- void *cookie,
- xlator_t *this,
- int32_t op_ret,
- int32_t op_errno,
- fd_t *fd,
- dict_t *xdata)
-{
- gf_boolean_t upload_info;
- crypt_local_t *local = frame->local;
- crypt_private_t *priv = this->private;
- struct crypt_inode_info *info;
- data_t *old_mtd;
- uint32_t new_mtd_size;
- uint64_t value = 0;
- void (*unwind_fn)(call_frame_t *frame);
- mtd_op_t mop;
-
- unwind_fn = linkop_unwind_dispatch(local->fop);
- mop = linkop_mtdop_dispatch(local->fop);
-
- if (op_ret < 0)
- /*
- * verification failed
- */
- goto error;
-
- old_mtd = dict_get(xdata, CRYPTO_FORMAT_PREFIX);
- if (!old_mtd) {
- op_errno = EIO;
- gf_log (this->name, GF_LOG_DEBUG,
- "Metadata string wasn't found");
- goto error;
- }
- new_mtd_size = format_size(mop, old_mtd->len);
- op_errno = alloc_format(local, new_mtd_size);
- if (op_errno)
- goto error;
- /*
- * check for cached info
- */
- op_ret = inode_ctx_get(fd->inode, this, &value);
- if (op_ret != -1) {
- info = (struct crypt_inode_info *)(long)value;
- if (info == NULL) {
- gf_log (this->name, GF_LOG_WARNING,
- "Inode info was not found");
- op_errno = EINVAL;
- goto error;
- }
- /*
- * info was found in the cache
- */
- local->info = info;
- upload_info = _gf_false;
- }
- else {
- /*
- * info wasn't found in the cache;
- */
- info = alloc_inode_info(local, local->loc);
- if (!info)
- goto error;
- init_inode_info_head(info, fd);
- local->info = info;
- upload_info = _gf_true;
- }
- op_errno = open_format((unsigned char *)old_mtd->data,
- old_mtd->len,
- local->loc,
- info,
- get_master_cinfo(priv),
- local,
- upload_info);
- if (op_errno)
- goto error;
- if (upload_info == _gf_true) {
- op_errno = init_inode_info_tail(info,
- get_master_cinfo(priv));
- if (op_errno)
- goto error;
- op_errno = inode_ctx_put(fd->inode, this,
- (uint64_t)(long)(info));
- if (op_errno == -1) {
- op_errno = EIO;
- goto error;
- }
- }
- /*
- * update the format string (append/update/cup a MAC)
- */
- op_errno = update_format(local->format,
- (unsigned char *)old_mtd->data,
- old_mtd->len,
- local->mac_idx,
- mop,
- local->newloc,
- info,
- get_master_cinfo(priv),
- local);
- if (op_errno)
- goto error;
- /*
- * store the new format string on the server
- */
- if (new_mtd_size) {
- op_errno = dict_set_static_bin(local->xattr,
- CRYPTO_FORMAT_PREFIX,
- local->format,
- new_mtd_size);
- if (op_errno)
- goto error;
- }
- STACK_WIND(frame,
- do_linkop,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->setxattr,
- local->loc,
- local->xattr,
- 0,
- NULL);
- return 0;
- error:
- local->op_ret = -1;
- local->op_errno = op_errno;
- unwind_fn(frame);
- return 0;
-}
-
-static int32_t linkop_grab_local(call_frame_t *frame,
- xlator_t *this,
- loc_t *oldloc,
- loc_t *newloc,
- int flags, dict_t *xdata,
- glusterfs_fop_t op)
-{
- int32_t ret = ENOMEM;
- fd_t *fd;
- crypt_local_t *local;
-
- local = crypt_alloc_local(frame, this, op);
- if (!local)
- goto error;
- if (xdata)
- local->xdata = dict_ref(xdata);
-
- fd = fd_create(oldloc->inode, frame->root->pid);
- if (!fd) {
- gf_log(this->name, GF_LOG_ERROR, "Can not create fd");
- goto error;
- }
- local->fd = fd;
- local->flags = flags;
- local->loc = GF_CALLOC(1, sizeof(*oldloc), gf_crypt_mt_loc);
- if (!local->loc)
- goto error;
- memset(local->loc, 0, sizeof(*local->loc));
- ret = loc_copy(local->loc, oldloc);
- if (ret) {
- GF_FREE(local->loc);
- local->loc = NULL;
- goto error;
- }
- if (newloc) {
- local->newloc = GF_CALLOC(1, sizeof(*newloc), gf_crypt_mt_loc);
- if (!local->newloc) {
- loc_wipe(local->loc);
- GF_FREE(local->loc);
- goto error;
- }
- memset(local->newloc, 0, sizeof(*local->newloc));
- ret = loc_copy(local->newloc, newloc);
- if (ret) {
- loc_wipe(local->loc);
- GF_FREE(local->loc);
- GF_FREE(local->newloc);
- goto error;
- }
- }
- local->xattr = dict_new();
- if (!local->xattr) {
- gf_log(this->name, GF_LOG_ERROR, "Can not create dict");
- ret = ENOMEM;
- goto error;
- }
- return 0;
-
-error:
- if (local) {
- if (local->xdata)
- dict_unref(local->xdata);
- if (local->fd)
- fd_unref(local->fd);
- local->fd = 0;
- local->loc = NULL;
- local->newloc = NULL;
- local->op_ret = -1;
- local->op_errno = ret;
- }
-
- return ret;
-}
-
-/*
- * read and verify locked metadata against the old pathname (via open);
- * update the metadata string in accordance with the new pathname;
- * submit modified metadata;
- * wind;
- */
-static int32_t linkop(call_frame_t *frame,
- xlator_t *this,
- loc_t *oldloc,
- loc_t *newloc,
- int flags,
- dict_t *xdata,
- glusterfs_fop_t op)
-{
- int32_t ret;
- dict_t *dict;
- crypt_local_t *local;
- void (*unwind_fn)(call_frame_t *frame);
- void (*wind_fn)(call_frame_t *frame, xlator_t *this);
-
- wind_fn = linkop_wind_dispatch(op);
- unwind_fn = linkop_unwind_dispatch(op);
-
- ret = linkop_grab_local(frame, this, oldloc, newloc, flags, xdata, op);
- local = frame->local;
- if (ret)
- goto error;
-
- if (local->fd->inode->ia_type == IA_IFLNK)
- goto wind;
-
- dict = dict_new();
- if (!dict) {
- gf_log(this->name, GF_LOG_ERROR, "Can not create dict");
- ret = ENOMEM;
- goto error;
- }
- /*
- * Set a message to crypt_open() that we need
- * locked metadata string.
- * All link operations (link, unlink, rename)
- * need write lock
- */
- msgflags_set_mtd_wlock(&local->msgflags);
- ret = dict_set_static_bin(dict,
- MSGFLAGS_PREFIX,
- &local->msgflags,
- sizeof(local->msgflags));
- if (ret) {
- gf_log(this->name, GF_LOG_ERROR, "Can not set dict");
- dict_unref(dict);
- goto error;
- }
- /*
- * verify metadata against the old pathname
- * and retrieve locked metadata string
- */
- STACK_WIND(frame,
- linkop_begin,
- this,
- this->fops->open, /* crypt_open() */
- oldloc,
- O_RDWR,
- local->fd,
- dict);
- dict_unref(dict);
- return 0;
-
-wind:
- wind_fn(frame, this);
- return 0;
-
-error:
- local->op_ret = -1;
- local->op_errno = ret;
- unwind_fn(frame);
- return 0;
-}
-
-static int32_t crypt_link(call_frame_t *frame, xlator_t *this,
- loc_t *oldloc, loc_t *newloc, dict_t *xdata)
-{
- return linkop(frame, this, oldloc, newloc, 0, xdata, GF_FOP_LINK);
-}
-
-static int32_t crypt_unlink(call_frame_t *frame, xlator_t *this,
- loc_t *loc, int flags, dict_t *xdata)
-{
- return linkop(frame, this, loc, NULL, flags, xdata, GF_FOP_UNLINK);
-}
-
-static int32_t crypt_rename(call_frame_t *frame, xlator_t *this,
- loc_t *oldloc, loc_t *newloc, dict_t *xdata)
-{
- return linkop(frame, this, oldloc, newloc, 0, xdata, GF_FOP_RENAME);
-}
-
-static void put_one_call_open(call_frame_t *frame)
-{
- crypt_local_t *local = frame->local;
- if (put_one_call(local)) {
- fd_t *fd = local->fd;
- loc_t *loc = local->loc;
- dict_t *xdata = local->xdata;
-
- STACK_UNWIND_STRICT(open,
- frame,
- local->op_ret,
- local->op_errno,
- fd,
- xdata);
- fd_unref(fd);
- if (xdata)
- dict_unref(xdata);
- loc_wipe(loc);
- GF_FREE(loc);
- }
-}
-
-static int32_t __crypt_readv_done(call_frame_t *frame,
- void *cookie,
- xlator_t *this,
- int32_t op_ret,
- int32_t op_errno, dict_t *xdata)
-{
- crypt_local_t *local = frame->local;
- fd_t *local_fd = local->fd;
- dict_t *local_xdata = local->xdata;
- /* read deals with data configs only */
- struct iovec *avec = local->data_conf.avec;
- char **pool = local->data_conf.pool;
- int blocks_in_pool = local->data_conf.blocks_in_pool;
- struct iobref *iobref = local->iobref;
- struct iobref *iobref_data = local->iobref_data;
-
- if (op_ret < 0) {
- gf_log(this->name, GF_LOG_WARNING,
- "readv unlock failed (%d)", op_errno);
- if (local->op_ret >= 0) {
- local->op_ret = op_ret;
- local->op_errno = op_errno;
- }
- }
- dump_plain_text(local, avec);
-
- gf_log("crypt", GF_LOG_DEBUG,
- "readv: ret_to_user: %d, iovec len: %d, ia_size: %llu",
- (int)(local->rw_count > 0 ? local->rw_count : local->op_ret),
- (int)(local->rw_count > 0 ? iovec_get_size(avec, local->data_conf.acount) : 0),
- (unsigned long long)local->buf.ia_size);
-
- STACK_UNWIND_STRICT(readv,
- frame,
- local->rw_count > 0 ? local->rw_count : local->op_ret,
- local->op_errno,
- avec,
- avec ? local->data_conf.acount : 0,
- &local->buf,
- local->iobref,
- local_xdata);
-
- free_avec(avec, pool, blocks_in_pool);
- fd_unref(local_fd);
- if (local_xdata)
- dict_unref(local_xdata);
- if (iobref)
- iobref_unref(iobref);
- if (iobref_data)
- iobref_unref(iobref_data);
- return 0;
-}
-
-static void crypt_readv_done(call_frame_t *frame, xlator_t *this)
-{
- if (parent_is_crypt_xlator(frame, this))
- /*
- * don't unlock (it will be done by the parent)
- */
- __crypt_readv_done(frame, NULL, this, 0, 0, NULL);
- else {
- crypt_local_t *local = frame->local;
- struct gf_flock lock = {0, };
-
- 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,
- __crypt_readv_done,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->finodelk,
- this->name,
- local->fd,
- F_SETLKW,
- &lock,
- NULL);
- }
-}
-
-static void put_one_call_readv(call_frame_t *frame, xlator_t *this)
-{
- crypt_local_t *local = frame->local;
- if (put_one_call(local))
- crypt_readv_done(frame, this);
-}
-
-static int32_t __crypt_writev_done(call_frame_t *frame,
- void *cookie,
- xlator_t *this,
- int32_t op_ret,
- int32_t op_errno, dict_t *xdata)
-{
- crypt_local_t *local = frame->local;
- fd_t *local_fd = local->fd;
- dict_t *local_xdata = local->xdata;
- int32_t ret_to_user;
-
- if (local->xattr)
- dict_unref(local->xattr);
- /*
- * Calculate amout of butes to be returned
- * to user. We need to subtract paddings that
- * have been written as a part of atom.
- */
- /*
- * subtract head padding
- */
- if (local->rw_count == 0)
- /*
- * Nothing has been written, it must be an error
- */
- ret_to_user = local->op_ret;
- else if (local->rw_count <= local->data_conf.off_in_head) {
- gf_log("crypt", GF_LOG_WARNING, "Incomplete write");
- ret_to_user = 0;
- }
- else
- ret_to_user = local->rw_count -
- local->data_conf.off_in_head;
- /*
- * subtract tail padding
- */
- if (ret_to_user > local->data_conf.orig_size)
- ret_to_user = local->data_conf.orig_size;
-
- if (local->iobref)
- iobref_unref(local->iobref);
- if (local->iobref_data)
- iobref_unref(local->iobref_data);
- free_avec_data(local);
- free_avec_hole(local);
-
- gf_log("crypt", GF_LOG_DEBUG,
- "writev: ret_to_user: %d", ret_to_user);
-
- STACK_UNWIND_STRICT(writev,
- frame,
- ret_to_user,
- local->op_errno,
- &local->prebuf,
- &local->postbuf,
- local_xdata);
- fd_unref(local_fd);
- if (local_xdata)
- dict_unref(local_xdata);
- return 0;
-}
-
-static int32_t crypt_writev_done(call_frame_t *frame,
- void *cookie,
- xlator_t *this,
- int32_t op_ret,
- int32_t op_errno,
- dict_t *xdata)
-{
- crypt_local_t *local = frame->local;
-
- if (op_ret < 0)
- gf_log("crypt", GF_LOG_WARNING, "can not update file size");
-
- if (parent_is_crypt_xlator(frame, this))
- /*
- * don't unlock (it will be done by the parent)
- */
- __crypt_writev_done(frame, NULL, this, 0, 0, NULL);
- else {
- struct gf_flock lock = {0, };
-
- 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,
- __crypt_writev_done,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->finodelk,
- this->name,
- local->fd,
- F_SETLKW,
- &lock,
- NULL);
- }
- return 0;
-}
-
-static void put_one_call_writev(call_frame_t *frame, xlator_t *this)
-{
- crypt_local_t *local = frame->local;
- if (put_one_call(local)) {
- if (local->update_disk_file_size) {
- int32_t ret;
- /*
- * update file size, unlock the file and unwind
- */
- ret = dict_set(local->xattr,
- FSIZE_XATTR_PREFIX,
- data_from_uint64(local->cur_file_size));
- if (ret) {
- gf_log("crypt", GF_LOG_WARNING,
- "can not set key to update file size");
- crypt_writev_done(frame, NULL,
- this, 0, 0, NULL);
- return;
- }
- gf_log("crypt", GF_LOG_DEBUG,
- "Updating disk file size to %llu",
- (unsigned long long)local->cur_file_size);
- STACK_WIND(frame,
- crypt_writev_done,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fsetxattr,
- local->fd,
- local->xattr, /* CRYPTO_FORMAT_PREFIX */
- 0,
- NULL);
- }
- else
- crypt_writev_done(frame, NULL, this, 0, 0, NULL);
- }
-}
-
-static int32_t __crypt_ftruncate_done(call_frame_t *frame,
- void *cookie,
- xlator_t *this,
- int32_t op_ret,
- int32_t op_errno, dict_t *xdata)
-{
- crypt_local_t *local = frame->local;
- fd_t *local_fd = local->fd;
- dict_t *local_xdata = local->xdata;
- char *iobase = local->vec.iov_base;
-
- if (op_ret < 0) {
- gf_log(this->name, GF_LOG_WARNING,
- "ftruncate unlock failed (%d)", op_errno);
- if (local->op_ret >= 0) {
- local->op_ret = op_ret;
- local->op_errno = op_errno;
- }
- }
- if (local->iobref_data)
- iobref_unref(local->iobref_data);
- free_avec_data(local);
- free_avec_hole(local);
-
- gf_log("crypt", GF_LOG_DEBUG,
- "ftruncate, return to user: presize=%llu, postsize=%llu",
- (unsigned long long)local->prebuf.ia_size,
- (unsigned long long)local->postbuf.ia_size);
-
- STACK_UNWIND_STRICT(ftruncate,
- frame,
- local->op_ret < 0 ? -1 : 0,
- local->op_errno,
- &local->prebuf,
- &local->postbuf,
- local_xdata);
- fd_unref(local_fd);
- if (local_xdata)
- dict_unref(local_xdata);
- if (iobase)
- GF_FREE(iobase);
- return 0;
-}
-
-static int32_t crypt_ftruncate_done(call_frame_t *frame,
- void *cookie,
- xlator_t *this,
- int32_t op_ret,
- int32_t op_errno,
- dict_t *xdata)
-{
- crypt_local_t *local = frame->local;
- struct gf_flock lock = {0, };
-
- dict_unref(local->xattr);
- if (op_ret < 0)
- gf_log("crypt", GF_LOG_WARNING, "can not update file size");
-
- 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,
- __crypt_ftruncate_done,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->finodelk,
- this->name,
- local->fd,
- F_SETLKW,
- &lock,
- NULL);
- return 0;
-}
-
-static void put_one_call_ftruncate(call_frame_t *frame, xlator_t *this)
-{
- crypt_local_t *local = frame->local;
- if (put_one_call(local)) {
- if (local->update_disk_file_size) {
- int32_t ret;
- /*
- * update file size, unlock the file and unwind
- */
- ret = dict_set(local->xattr,
- FSIZE_XATTR_PREFIX,
- data_from_uint64(local->cur_file_size));
- if (ret) {
- gf_log("crypt", GF_LOG_WARNING,
- "can not set key to update file size");
- crypt_ftruncate_done(frame, NULL,
- this, 0, 0, NULL);
- return;
- }
- gf_log("crypt", GF_LOG_DEBUG,
- "Updating disk file size to %llu",
- (unsigned long long)local->cur_file_size);
- STACK_WIND(frame,
- crypt_ftruncate_done,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fsetxattr,
- local->fd,
- local->xattr, /* CRYPTO_FORMAT_PREFIX */
- 0,
- NULL);
- }
- else
- crypt_ftruncate_done(frame, NULL, this, 0, 0, NULL);
- }
-}
-
-/*
- * load regular file size for some FOPs
- */
-static int32_t load_file_size(call_frame_t *frame,
- void *cookie,
- xlator_t *this,
- int32_t op_ret,
- int32_t op_errno,
- dict_t *dict,
- dict_t *xdata)
-{
- data_t *data;
- crypt_local_t *local = frame->local;
-
- dict_t *local_xdata = local->xdata;
- inode_t *local_inode = local->inode;
-
- if (op_ret < 0)
- goto unwind;
- /*
- * load regular file size
- */
- data = dict_get(dict, FSIZE_XATTR_PREFIX);
- if (!data) {
- if (local->xdata)
- dict_unref(local->xdata);
- gf_log("crypt", GF_LOG_WARNING, "Regular file size not found");
- op_ret = -1;
- op_errno = EIO;
- goto unwind;
- }
- local->buf.ia_size = data_to_uint64(data);
-
- gf_log(this->name, GF_LOG_DEBUG,
- "FOP %d: Translate regular file to %llu",
- local->fop,
- (unsigned long long)local->buf.ia_size);
- unwind:
- if (local->fd)
- fd_unref(local->fd);
- if (local->loc) {
- loc_wipe(local->loc);
- GF_FREE(local->loc);
- }
- switch (local->fop) {
- case GF_FOP_FSTAT:
- STACK_UNWIND_STRICT(fstat,
- frame,
- op_ret,
- op_errno,
- op_ret >= 0 ? &local->buf : NULL,
- local->xdata);
- break;
- case GF_FOP_STAT:
- STACK_UNWIND_STRICT(stat,
- frame,
- op_ret,
- op_errno,
- op_ret >= 0 ? &local->buf : NULL,
- local->xdata);
- break;
- case GF_FOP_LOOKUP:
- STACK_UNWIND_STRICT(lookup,
- frame,
- op_ret,
- op_errno,
- op_ret >= 0 ? local->inode : NULL,
- op_ret >= 0 ? &local->buf : NULL,
- local->xdata,
- op_ret >= 0 ? &local->postbuf : NULL);
- break;
- case GF_FOP_READ:
- STACK_UNWIND_STRICT(readv,
- frame,
- op_ret,
- op_errno,
- NULL,
- 0,
- op_ret >= 0 ? &local->buf : NULL,
- NULL,
- NULL);
- break;
- default:
- gf_log(this->name, GF_LOG_WARNING,
- "Improper file operation %d", local->fop);
- }
- if (local_xdata)
- dict_unref(local_xdata);
- if (local_inode)
- inode_unref(local_inode);
- return 0;
-}
-
-static int32_t crypt_stat_common_cbk(call_frame_t *frame,
- void *cookie,
- xlator_t *this,
- int32_t op_ret,
- int32_t op_errno,
- struct iatt *buf, dict_t *xdata)
-{
- crypt_local_t *local = frame->local;
-
- if (op_ret < 0)
- goto unwind;
- if (!IA_ISREG(buf->ia_type))
- goto unwind;
-
- local->buf = *buf;
- if (xdata)
- local->xdata = dict_ref(xdata);
-
- switch (local->fop) {
- case GF_FOP_FSTAT:
- STACK_WIND(frame,
- load_file_size,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fgetxattr,
- local->fd,
- FSIZE_XATTR_PREFIX,
- NULL);
- break;
- case GF_FOP_STAT:
- STACK_WIND(frame,
- load_file_size,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->getxattr,
- local->loc,
- FSIZE_XATTR_PREFIX,
- NULL);
- break;
- default:
- gf_log (this->name, GF_LOG_WARNING,
- "Improper file operation %d", local->fop);
- }
- return 0;
- unwind:
- if (local->fd)
- fd_unref(local->fd);
- if (local->loc) {
- loc_wipe(local->loc);
- GF_FREE(local->loc);
- }
- switch (local->fop) {
- case GF_FOP_FSTAT:
- STACK_UNWIND_STRICT(fstat,
- frame,
- op_ret,
- op_errno,
- op_ret >= 0 ? buf : NULL,
- op_ret >= 0 ? xdata : NULL);
- break;
- case GF_FOP_STAT:
- STACK_UNWIND_STRICT(stat,
- frame,
- op_ret,
- op_errno,
- op_ret >= 0 ? buf : NULL,
- op_ret >= 0 ? xdata : NULL);
- break;
- default:
- gf_log (this->name, GF_LOG_WARNING,
- "Improper file operation %d", local->fop);
- }
- return 0;
-}
-
-static int32_t crypt_fstat(call_frame_t *frame,
- xlator_t *this,
- fd_t *fd, dict_t *xdata)
-{
- crypt_local_t *local;
-
- local = crypt_alloc_local(frame, this, GF_FOP_FSTAT);
- if (!local)
- goto error;
- local->fd = fd_ref(fd);
- STACK_WIND(frame,
- crypt_stat_common_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fstat,
- fd,
- xdata);
- return 0;
- error:
- STACK_UNWIND_STRICT(fstat,
- frame,
- -1,
- ENOMEM,
- NULL,
- NULL);
- return 0;
-}
-
-static int32_t crypt_stat(call_frame_t *frame,
- xlator_t *this,
- loc_t *loc, dict_t *xdata)
-{
- int32_t ret;
- crypt_local_t *local;
-
- local = crypt_alloc_local(frame, this, GF_FOP_STAT);
- if (!local)
- goto error;
- local->loc = GF_CALLOC(1, sizeof(*loc), gf_crypt_mt_loc);
- if (!local->loc)
- goto error;
- memset(local->loc, 0, sizeof(*local->loc));
- ret = loc_copy(local->loc, loc);
- if (ret) {
- GF_FREE(local->loc);
- goto error;
- }
- STACK_WIND(frame,
- crypt_stat_common_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->stat,
- loc,
- xdata);
- return 0;
- error:
- STACK_UNWIND_STRICT(stat,
- frame,
- -1,
- ENOMEM,
- NULL,
- NULL);
- return 0;
-}
-
-static int32_t crypt_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)
-{
- crypt_local_t *local = frame->local;
-
- if (op_ret < 0)
- goto unwind;
- if (!IA_ISREG(buf->ia_type))
- goto unwind;
-
- local->inode = inode_ref(inode);
- local->buf = *buf;
- local->postbuf = *postparent;
- if (xdata)
- local->xdata = dict_ref(xdata);
- uuid_copy(local->loc->gfid, buf->ia_gfid);
-
- STACK_WIND(frame,
- load_file_size,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->getxattr,
- local->loc,
- FSIZE_XATTR_PREFIX,
- NULL);
- return 0;
- unwind:
- loc_wipe(local->loc);
- GF_FREE(local->loc);
- STACK_UNWIND_STRICT(lookup,
- frame,
- op_ret,
- op_errno,
- inode,
- buf,
- xdata,
- postparent);
- return 0;
-}
-
-static int32_t crypt_lookup(call_frame_t *frame,
- xlator_t *this,
- loc_t *loc, dict_t *xdata)
-{
- int32_t ret;
- crypt_local_t *local;
-
- local = crypt_alloc_local(frame, this, GF_FOP_LOOKUP);
- if (!local)
- goto error;
- local->loc = GF_CALLOC(1, sizeof(*loc), gf_crypt_mt_loc);
- if (!local->loc)
- goto error;
- memset(local->loc, 0, sizeof(*local->loc));
- ret = loc_copy(local->loc, loc);
- if (ret) {
- GF_FREE(local->loc);
- goto error;
- }
- gf_log(this->name, GF_LOG_DEBUG, "Lookup %s", loc->path);
- STACK_WIND(frame,
- crypt_lookup_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->lookup,
- loc,
- xdata);
- return 0;
- error:
- STACK_UNWIND_STRICT(lookup,
- frame,
- -1,
- ENOMEM,
- NULL,
- NULL,
- NULL,
- NULL);
- return 0;
-}
-
-/*
- * for every regular directory entry find its real file size
- * and update stat's buf properly
- */
-static int32_t crypt_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)
-{
- gf_dirent_t *entry = NULL;
-
- if (op_ret < 0)
- goto unwind;
-
- list_for_each_entry (entry, (&entries->list), list) {
- data_t *data;
-
- if (!IA_ISREG(entry->d_stat.ia_type))
- continue;
- data = dict_get(entry->dict, FSIZE_XATTR_PREFIX);
- if (!data){
- gf_log("crypt", GF_LOG_WARNING,
- "Regular file size of direntry not found");
- op_errno = EIO;
- op_ret = -1;
- break;
- }
- entry->d_stat.ia_size = data_to_uint64(data);
- }
- unwind:
- STACK_UNWIND_STRICT(readdirp, frame, op_ret, op_errno, entries, xdata);
- return 0;
-}
-
-/*
- * ->readdirp() fills in-core inodes, so we need to set proper
- * file sizes for all directory entries of the parent @fd.
- * Actual updates take place in ->crypt_readdirp_cbk()
- */
-static int32_t crypt_readdirp(call_frame_t *frame, xlator_t *this,
- fd_t *fd, size_t size, off_t offset,
- dict_t *xdata)
-{
- int32_t ret = ENOMEM;
-
- if (!xdata) {
- xdata = dict_new();
- if (!xdata)
- goto error;
- }
- else
- dict_ref(xdata);
- /*
- * make sure that we'll have real file sizes at ->readdirp_cbk()
- */
- ret = dict_set(xdata, FSIZE_XATTR_PREFIX, data_from_uint64(0));
- if (ret) {
- dict_unref(xdata);
- goto error;
- }
- STACK_WIND(frame,
- crypt_readdirp_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->readdirp,
- fd,
- size,
- offset,
- xdata);
- dict_unref(xdata);
- return 0;
- error:
- STACK_UNWIND_STRICT(readdirp, frame, -1, ret, NULL, NULL);
- return 0;
-}
-
-static int32_t crypt_access(call_frame_t *frame,
- xlator_t *this,
- loc_t *loc,
- int32_t mask, dict_t *xdata)
-{
- gf_log(this->name, GF_LOG_WARNING,
- "NFS mounts of encrypted volumes are unsupported");
- STACK_UNWIND_STRICT(access, frame, -1, EPERM, NULL);
- return 0;
-}
-
-int32_t master_set_block_size (xlator_t *this, crypt_private_t *priv,
- dict_t *options)
-{
- uint64_t block_size = 0;
- struct master_cipher_info *master = get_master_cinfo(priv);
-
- if (options != NULL)
- GF_OPTION_RECONF("block-size", block_size, options,
- size_uint64, error);
- else
- GF_OPTION_INIT("block-size", block_size, size_uint64, error);
-
- switch (block_size) {
- case 512:
- master->m_block_bits = 9;
- break;
- case 1024:
- master->m_block_bits = 10;
- break;
- case 2048:
- master->m_block_bits = 11;
- break;
- case 4096:
- master->m_block_bits = 12;
- break;
- default:
- gf_log("crypt", GF_LOG_ERROR,
- "FATAL: unsupported block size %llu",
- (unsigned long long)block_size);
- goto error;
- }
- return 0;
- error:
- return -1;
-}
-
-int32_t master_set_alg(xlator_t *this, crypt_private_t *priv)
-{
- struct master_cipher_info *master = get_master_cinfo(priv);
- master->m_alg = AES_CIPHER_ALG;
- return 0;
-}
-
-int32_t master_set_mode(xlator_t *this, crypt_private_t *priv)
-{
- struct master_cipher_info *master = get_master_cinfo(priv);
- master->m_mode = XTS_CIPHER_MODE;
- return 0;
-}
-
-/*
- * set key size in bits to the master info
- * Pre-conditions: cipher mode in the master info is uptodate.
- */
-static int master_set_data_key_size (xlator_t *this, crypt_private_t *priv,
- dict_t *options)
-{
- int32_t ret;
- uint64_t key_size = 0;
- struct master_cipher_info *master = get_master_cinfo(priv);
-
- if (options != NULL)
- GF_OPTION_RECONF("data-key-size", key_size, options,
- uint64, error);
- else
- GF_OPTION_INIT("data-key-size", key_size, uint64, error);
-
- ret = data_cipher_algs[master->m_alg][master->m_mode].check_key(key_size);
- if (ret) {
- gf_log("crypt", GF_LOG_ERROR,
- "FATAL: wrong bin key size %llu for alg %d mode %d",
- (unsigned long long)key_size,
- (int)master->m_alg,
- (int)master->m_mode);
- goto error;
- }
- master->m_dkey_size = key_size;
- return 0;
- error:
- return -1;
-}
-
-static int is_hex(char *s) {
- return ('0' <= *s && *s <= '9') || ('a' <= *s && *s <= 'f');
-}
-
-static int parse_hex_buf(xlator_t *this, char *src, unsigned char *dst,
- int hex_size)
-{
- int i;
- int hex_byte = 0;
-
- for (i = 0; i < (hex_size / 2); i++) {
- if (!is_hex(src + i*2) || !is_hex(src + i*2 + 1)) {
- gf_log("crypt", GF_LOG_ERROR,
- "FATAL: not hex symbol in key");
- return -1;
- }
- if (sscanf(src + i*2, "%2x", &hex_byte) != 1) {
- gf_log("crypt", GF_LOG_ERROR,
- "FATAL: can not parse hex key");
- return -1;
- }
- dst[i] = hex_byte & 0xff;
- }
- return 0;
-}
-
-/*
- * Parse options;
- * install master volume key
- */
-int32_t master_set_master_vol_key(xlator_t *this, crypt_private_t *priv)
-{
- int32_t ret;
- FILE *file = NULL;
-
- int32_t key_size;
- char *opt_key_file_pathname = NULL;
-
- unsigned char bin_buf[MASTER_VOL_KEY_SIZE];
- char hex_buf[2 * MASTER_VOL_KEY_SIZE];
-
- struct master_cipher_info *master = get_master_cinfo(priv);
- /*
- * extract master key passed via option
- */
- GF_OPTION_INIT("master-key", opt_key_file_pathname, path, bad_key);
-
- if (!opt_key_file_pathname) {
- gf_log(this->name, GF_LOG_ERROR, "FATAL: missing master key");
- return -1;
- }
- gf_log(this->name, GF_LOG_DEBUG, "handling file key %s",
- opt_key_file_pathname);
-
- file = fopen(opt_key_file_pathname, "r");
- if (file == NULL) {
- gf_log(this->name, GF_LOG_ERROR,
- "FATAL: can not open file with master key");
- return -1;
- }
- /*
- * extract hex key
- */
- key_size = fread(hex_buf, 1, sizeof(hex_buf), file);
- if (key_size < sizeof(hex_buf)) {
- gf_log(this->name, GF_LOG_ERROR,
- "FATAL: master key is too short");
- goto bad_key;
- }
- ret = parse_hex_buf(this, hex_buf, bin_buf, key_size);
- if (ret)
- goto bad_key;
- memcpy(master->m_key, bin_buf, MASTER_VOL_KEY_SIZE);
- memset(hex_buf, 0, sizeof(hex_buf));
- fclose(file);
-
- memset(bin_buf, 0, sizeof(bin_buf));
- return 0;
- bad_key:
- gf_log(this->name, GF_LOG_ERROR, "FATAL: bad master key");
- if (file)
- fclose(file);
- memset(bin_buf, 0, sizeof(bin_buf));
- return -1;
-}
-
-/*
- * Derive volume key for object-id authentication
- */
-int32_t master_set_nmtd_vol_key(xlator_t *this, crypt_private_t *priv)
-{
- return get_nmtd_vol_key(get_master_cinfo(priv));
-}
-
-int32_t crypt_init_xlator(xlator_t *this)
-{
- int32_t ret;
- crypt_private_t *priv = this->private;
-
- ret = master_set_alg(this, priv);
- if (ret)
- return ret;
- ret = master_set_mode(this, priv);
- if (ret)
- return ret;
- ret = master_set_block_size(this, priv, NULL);
- if (ret)
- return ret;
- ret = master_set_data_key_size(this, priv, NULL);
- if (ret)
- return ret;
- ret = master_set_master_vol_key(this, priv);
- if (ret)
- return ret;
- return master_set_nmtd_vol_key(this, priv);
-}
-
-static int32_t crypt_alloc_private(xlator_t *this)
-{
- this->private = GF_CALLOC(1, sizeof(crypt_private_t), gf_crypt_mt_priv);
- if (!this->private) {
- gf_log("crypt", GF_LOG_ERROR,
- "Can not allocate memory for private data");
- return ENOMEM;
- }
- return 0;
-}
-
-static void crypt_free_private(xlator_t *this)
-{
- crypt_private_t *priv = this->private;
- if (priv) {
- memset(priv, 0, sizeof(*priv));
- GF_FREE(priv);
- }
-}
-
-int32_t
-mem_acct_init (xlator_t *this)
-{
- int ret = -1;
-
- if (!this)
- return ret;
-
- ret = xlator_mem_acct_init (this, gf_crypt_mt_end);
-
- if (ret != 0) {
- gf_log(this->name, GF_LOG_ERROR, "Memory accounting init"
- "failed");
- return ret;
- }
-
- return ret;
-}
-
-int32_t reconfigure (xlator_t *this, dict_t *options)
-{
- int32_t ret = -1;
- crypt_private_t *priv = NULL;
-
- GF_VALIDATE_OR_GOTO ("crypt", this, error);
- GF_VALIDATE_OR_GOTO (this->name, this->private, error);
- GF_VALIDATE_OR_GOTO (this->name, options, error);
-
- priv = this->private;
-
- ret = master_set_block_size(this, priv, options);
- if (ret) {
- gf_log("this->name", GF_LOG_ERROR,
- "Failed to reconfure block size");
- goto error;
- }
- ret = master_set_data_key_size(this, priv, options);
- if (ret) {
- gf_log("this->name", GF_LOG_ERROR,
- "Failed to reconfure data key size");
- goto error;
- }
- return 0;
- error:
- return ret;
-}
-
-int32_t init(xlator_t *this)
-{
- int32_t ret;
-
- if (!this->children || this->children->next) {
- gf_log ("crypt", GF_LOG_ERROR,
- "FATAL: crypt should have exactly one child");
- return EINVAL;
- }
- if (!this->parents) {
- gf_log (this->name, GF_LOG_WARNING,
- "dangling volume. check volfile ");
- }
- ret = crypt_alloc_private(this);
- if (ret)
- return ret;
- ret = crypt_init_xlator(this);
- if (ret)
- goto error;
- this->local_pool = mem_pool_new(crypt_local_t, 64);
- if (!this->local_pool) {
- gf_log(this->name, GF_LOG_ERROR,
- "failed to create local_t's memory pool");
- ret = ENOMEM;
- goto error;
- }
- gf_log ("crypt", GF_LOG_INFO, "crypt xlator loaded");
- return 0;
- error:
- crypt_free_private(this);
- return ret;
-}
-
-void fini (xlator_t *this)
-{
- crypt_free_private(this);
-}
-
-struct xlator_fops fops = {
- .readv = crypt_readv,
- .writev = crypt_writev,
- .truncate = crypt_truncate,
- .ftruncate = crypt_ftruncate,
- .setxattr = crypt_setxattr,
- .fsetxattr = crypt_fsetxattr,
- .link = crypt_link,
- .unlink = crypt_unlink,
- .rename = crypt_rename,
- .open = crypt_open,
- .create = crypt_create,
- .stat = crypt_stat,
- .fstat = crypt_fstat,
- .lookup = crypt_lookup,
- .readdirp = crypt_readdirp,
- .access = crypt_access
-};
-
-struct xlator_cbks cbks = {
- .forget = crypt_forget
-};
-
-struct volume_options options[] = {
- { .key = {"master-key"},
- .type = GF_OPTION_TYPE_PATH,
- .description = "Pathname of regular file which contains master volume key"
- },
- { .key = {"data-key-size"},
- .type = GF_OPTION_TYPE_SIZET,
- .description = "Data key size (bits)",
- .min = 256,
- .max = 512,
- .default_value = "256",
- },
- { .key = {"block-size"},
- .type = GF_OPTION_TYPE_SIZET,
- .description = "Atom size (bits)",
- .min = 512,
- .max = 4096,
- .default_value = "4096"
- },
- { .key = {NULL} },
-};
-
-/*
- Local variables:
- c-indentation-style: "K&R"
- mode-name: "LC"
- c-basic-offset: 8
- tab-width: 8
- fill-column: 80
- scroll-step: 1
- End:
-*/
diff --git a/xlators/encryption/crypt/src/crypt.h b/xlators/encryption/crypt/src/crypt.h
deleted file mode 100644
index 4a87f016089..00000000000
--- a/xlators/encryption/crypt/src/crypt.h
+++ /dev/null
@@ -1,904 +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 __CRYPT_H__
-#define __CRYPT_H__
-
-#ifndef _CONFIG_H
-#define _CONFIG_H
-#include "config.h"
-#endif
-#include <openssl/aes.h>
-#include <openssl/evp.h>
-#include <openssl/sha.h>
-#include <openssl/hmac.h>
-#include <openssl/cmac.h>
-#include <openssl/modes.h>
-#include "crypt-mem-types.h"
-#include "compat.h"
-
-#define CRYPT_XLATOR_ID (0)
-
-#define MAX_IOVEC_BITS (3)
-#define MAX_IOVEC (1 << MAX_IOVEC_BITS)
-#define KEY_FACTOR_BITS (6)
-
-#define DEBUG_CRYPT (0)
-#define TRIVIAL_TFM (0)
-
-#define CRYPT_MIN_BLOCK_BITS (9)
-#define CRYPT_MAX_BLOCK_BITS (12)
-
-#define MASTER_VOL_KEY_SIZE (32)
-#define NMTD_VOL_KEY_SIZE (16)
-
-#if !defined(GF_LINUX_HOST_OS)
-typedef off_t loff_t;
-#endif
-
-struct crypt_key {
- uint32_t len;
- const char *label;
-};
-
-/*
- * Add new key types to the end of this
- * enumeration but before LAST_KEY_TYPE
- */
-typedef enum {
- MASTER_VOL_KEY,
- NMTD_VOL_KEY,
- NMTD_LINK_KEY,
- EMTD_FILE_KEY,
- DATA_FILE_KEY_256,
- DATA_FILE_KEY_512,
- LAST_KEY_TYPE
-}crypt_key_type;
-
-struct kderive_context {
- const unsigned char *pkey;/* parent key */
- uint32_t pkey_len; /* parent key size, bits */
- uint32_t ckey_len; /* child key size, bits */
- unsigned char *fid; /* fixed input data, NIST 800-108, 5.1 */
- uint32_t fid_len; /* fid len, bytes */
- unsigned char *out; /* contains child keying material */
- uint32_t out_len; /* out len, bytes */
-};
-
-typedef enum {
- DATA_ATOM,
- HOLE_ATOM,
- LAST_DATA_TYPE
-}atom_data_type;
-
-typedef enum {
- HEAD_ATOM,
- TAIL_ATOM,
- FULL_ATOM,
- LAST_LOCALITY_TYPE
-}atom_locality_type;
-
-typedef enum {
- MTD_CREATE,
- MTD_APPEND,
- MTD_OVERWRITE,
- MTD_CUT,
- MTD_LAST_OP
-} mtd_op_t;
-
-struct xts128_context {
- void *key1, *key2;
- block128_f block1,block2;
-};
-
-struct object_cipher_info {
- cipher_alg_t o_alg;
- cipher_mode_t o_mode;
- uint32_t o_block_bits;
- uint32_t o_dkey_size; /* raw data key size in bits */
- union {
- struct {
- unsigned char ivec[16];
- AES_KEY dkey[2];
- AES_KEY tkey; /* key used for tweaking */
- XTS128_CONTEXT xts;
- } aes_xts;
- } u;
-};
-
-struct master_cipher_info {
- /*
- * attributes inherited by newly created regular files
- */
- cipher_alg_t m_alg;
- cipher_mode_t m_mode;
- uint32_t m_block_bits;
- uint32_t m_dkey_size; /* raw key size in bits */
- /*
- * master key
- */
- unsigned char m_key[MASTER_VOL_KEY_SIZE];
- /*
- * volume key for oid authentication
- */
- unsigned char m_nmtd_key[NMTD_VOL_KEY_SIZE];
-};
-
-/*
-* This info is not changed during file's life
- */
-struct crypt_inode_info {
-#if DEBUG_CRYPT
- loc_t *loc; /* pathname that the file has been
- opened, or created with */
-#endif
- uint16_t nr_minor;
- uuid_t oid;
- struct object_cipher_info cinfo;
-};
-
-/*
- * this should locate in secure memory
- */
-typedef struct {
- struct master_cipher_info master;
-} crypt_private_t;
-
-static inline struct master_cipher_info *get_master_cinfo(crypt_private_t *priv)
-{
- return &priv->master;
-}
-
-static inline struct object_cipher_info *get_object_cinfo(struct crypt_inode_info
- *info)
-{
- return &info->cinfo;
-}
-
-/*
- * this describes layouts and properties
- * of atoms in an aligned vector
- */
-struct avec_config {
- uint32_t atom_size;
- atom_data_type type;
- size_t orig_size;
- off_t orig_offset;
- size_t expanded_size;
- off_t aligned_offset;
-
- uint32_t off_in_head;
- uint32_t off_in_tail;
- uint32_t gap_in_tail;
- uint32_t nr_full_blocks;
-
- struct iovec *avec; /* aligned vector */
- uint32_t acount; /* number of avec components. The same
- * as number of occupied logical blocks */
- char **pool;
- uint32_t blocks_in_pool;
- uint32_t cursor; /* makes sense only for ordered writes,
- * so there is no races on this counter.
- *
- * Cursor is per-config object, we don't
- * reset cursor for atoms of different
- * localities (head, tail, full)
- */
-};
-
-
-typedef struct {
- glusterfs_fop_t fop; /* code of FOP this local info built for */
- fd_t *fd;
- inode_t *inode;
- loc_t *loc;
- int32_t mac_idx;
- loc_t *newloc;
- int32_t flags;
- int32_t wbflags;
- struct crypt_inode_info *info;
- struct iobref *iobref;
- struct iobref *iobref_data;
- off_t offset;
-
- uint64_t old_file_size; /* per FOP, retrieved under lock held */
- uint64_t cur_file_size; /* per iteration, before issuing IOs */
- uint64_t new_file_size; /* per iteration, after issuing IOs */
-
- uint64_t io_offset; /* offset of IOs issued per iteration */
- uint64_t io_offset_nopad; /* offset of user's data in the atom */
- uint32_t io_size; /* size of IOs issued per iteration */
- uint32_t io_size_nopad; /* size of user's data in the IOs */
- uint32_t eof_padding_size; /* size od EOF padding in the IOs */
-
- gf_lock_t call_lock; /* protect nr_calls from many cbks */
- int32_t nr_calls;
-
- atom_data_type active_setup; /* which setup (hole or date)
- is currently active */
- /* data setup */
- struct avec_config data_conf;
-
- /* hole setup */
- int hole_conv_in_proggress;
- gf_lock_t hole_lock; /* protect hole config from many cbks */
- int hole_handled;
- struct avec_config hole_conf;
- struct iatt buf;
- struct iatt prebuf;
- struct iatt postbuf;
- struct iatt *prenewparent;
- struct iatt *postnewparent;
- int32_t op_ret;
- int32_t op_errno;
- int32_t rw_count; /* total read or written */
- gf_lock_t rw_count_lock; /* protect the counter above */
- unsigned char *format; /* for create, update format string */
- uint32_t format_size;
- uint32_t msgflags; /* messages for crypt_open() */
- dict_t *xdata;
- dict_t *xattr;
- struct iovec vec; /* contains last file's atom for
- read-prune-write sequence */
- gf_boolean_t custom_mtd;
- /*
- * the next 3 fields are used by readdir and friends
- */
- gf_dirent_t *de; /* directory entry */
- char *de_path; /* pathname of directory entry */
- uint32_t de_prefix_len; /* lenght of the parent's pathname */
- gf_dirent_t *entries;
-
- uint32_t update_disk_file_size:1;
-} crypt_local_t;
-
-/* This represents a (read)modify-write atom */
-struct rmw_atom {
- atom_locality_type locality;
- /*
- * read-modify-write sequence of the atom
- */
- int32_t (*rmw)(call_frame_t *frame,
- void *cookie,
- xlator_t *this,
- int32_t op_ret,
- int32_t op_errno,
- struct iovec *vec,
- int32_t count,
- struct iatt *stbuf,
- struct iobref *iobref,
- dict_t *xdata);
- /*
- * offset of the logical block in a file
- */
- loff_t (*offset_at)(call_frame_t *frame,
- struct object_cipher_info *object);
- /*
- * IO offset in an atom
- */
- uint32_t (*offset_in)(call_frame_t *frame,
- struct object_cipher_info *object);
- /*
- * number of bytes of plain text of this atom that user
- * wants to read/write.
- * It can be smaller than atom_size in the case of head
- * or tail atoms.
- */
- uint32_t (*io_size_nopad)(call_frame_t *frame,
- struct object_cipher_info *object);
- /*
- * which iovec represents the atom
- */
- struct iovec *(*get_iovec)(call_frame_t *frame, uint32_t count);
- /*
- * how many bytes of partial block should be uptodated by
- * reading from disk.
- * This is used to perform a read component of RMW (read-modify-write).
- */
- uint32_t (*count_to_uptodate)(call_frame_t *frame, struct object_cipher_info *object);
- struct avec_config *(*get_config)(call_frame_t *frame);
-};
-
-struct data_cipher_alg {
- gf_boolean_t atomic; /* true means that algorithm requires
- to pad data before cipher transform */
- gf_boolean_t should_pad; /* true means that algorithm requires
- to pad the end of file with extra-data */
- uint32_t blkbits; /* blksize = 1 << blkbits */
- /*
- * any preliminary sanity checks goes here
- */
- int32_t (*init)(void);
- /*
- * set alg-mode specific inode info
- */
- int32_t (*set_private)(struct crypt_inode_info *info,
- struct master_cipher_info *master);
- /*
- * check alg-mode specific data key
- */
- int32_t (*check_key)(uint32_t key_size);
- void (*set_iv)(off_t offset, struct object_cipher_info *object);
- int32_t (*encrypt)(const unsigned char *from, unsigned char *to,
- size_t length, off_t offset, const int enc,
- struct object_cipher_info *object);
-};
-
-/*
- * version-dependent metadata loader
- */
-struct crypt_mtd_loader {
- /*
- * return core format size
- */
- size_t (*format_size)(mtd_op_t op, size_t old_size);
- /*
- * pack version-specific metadata of an object
- * at ->create()
- */
- int32_t (*create_format)(unsigned char *wire,
- loc_t *loc,
- struct crypt_inode_info *info,
- struct master_cipher_info *master);
- /*
- * extract version-specific metadata of an object
- * at ->open() time
- */
- int32_t (*open_format)(unsigned char *wire,
- int32_t len,
- loc_t *loc,
- struct crypt_inode_info *info,
- struct master_cipher_info *master,
- crypt_local_t *local,
- gf_boolean_t load_info);
- int32_t (*update_format)(unsigned char *new,
- unsigned char *old,
- size_t old_len,
- int32_t mac_idx,
- mtd_op_t op,
- loc_t *loc,
- struct crypt_inode_info *info,
- struct master_cipher_info *master,
- crypt_local_t *local);
-};
-
-typedef int32_t (*end_writeback_handler_t)(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);
-typedef void (*linkop_wind_handler_t)(call_frame_t *frame, xlator_t *this);
-typedef void (*linkop_unwind_handler_t)(call_frame_t *frame);
-
-
-/* Declarations */
-
-/* keys.c */
-extern struct crypt_key crypt_keys[LAST_KEY_TYPE];
-int32_t get_nmtd_vol_key(struct master_cipher_info *master);
-int32_t get_nmtd_link_key(loc_t *loc,
- struct master_cipher_info *master,
- unsigned char *result);
-int32_t get_emtd_file_key(struct crypt_inode_info *info,
- struct master_cipher_info *master,
- unsigned char *result);
-int32_t get_data_file_key(struct crypt_inode_info *info,
- struct master_cipher_info *master,
- uint32_t keysize,
- unsigned char *key);
-/* data.c */
-extern struct data_cipher_alg data_cipher_algs[LAST_CIPHER_ALG][LAST_CIPHER_MODE];
-void encrypt_aligned_iov(struct object_cipher_info *object,
- struct iovec *vec,
- int count,
- off_t off);
-void decrypt_aligned_iov(struct object_cipher_info *object,
- struct iovec *vec,
- int count,
- off_t off);
-int32_t align_iov_by_atoms(xlator_t *this,
- crypt_local_t *local,
- struct object_cipher_info *object,
- struct iovec *vec /* input vector */,
- int32_t count /* number of vec components */,
- struct iovec *avec /* aligned vector */,
- char **blocks /* pool of blocks */,
- uint32_t *blocks_allocated,
- struct avec_config *conf);
-int32_t set_config_avec_data(xlator_t *this,
- crypt_local_t *local,
- struct avec_config *conf,
- struct object_cipher_info *object,
- struct iovec *vec,
- int32_t vec_count);
-int32_t set_config_avec_hole(xlator_t *this,
- crypt_local_t *local,
- struct avec_config *conf,
- struct object_cipher_info *object,
- glusterfs_fop_t fop);
-void set_gap_at_end(call_frame_t *frame, struct object_cipher_info *object,
- struct avec_config *conf, atom_data_type dtype);
-void set_config_offsets(call_frame_t *frame,
- xlator_t *this,
- uint64_t offset,
- uint64_t count,
- atom_data_type dtype,
- int32_t setup_gap_in_tail);
-
-/* metadata.c */
-extern struct crypt_mtd_loader mtd_loaders [LAST_MTD_LOADER];
-
-int32_t alloc_format(crypt_local_t *local, size_t size);
-int32_t alloc_format_create(crypt_local_t *local);
-void free_format(crypt_local_t *local);
-size_t format_size(mtd_op_t op, size_t old_size);
-size_t new_format_size(void);
-int32_t open_format(unsigned char *str, int32_t len, loc_t *loc,
- struct crypt_inode_info *info,
- struct master_cipher_info *master, crypt_local_t *local,
- gf_boolean_t load_info);
-int32_t update_format(unsigned char *new, unsigned char *old,
- size_t old_len, int32_t mac_idx, mtd_op_t op, loc_t *loc,
- struct crypt_inode_info *info,
- struct master_cipher_info *master,
- crypt_local_t *local);
-int32_t create_format(unsigned char *wire,
- loc_t *loc,
- struct crypt_inode_info *info,
- struct master_cipher_info *master);
-
-/* atom.c */
-struct rmw_atom *atom_by_types(atom_data_type data,
- atom_locality_type locality);
-void submit_partial(call_frame_t *frame,
- xlator_t *this,
- fd_t *fd,
- atom_locality_type ltype);
-void submit_full(call_frame_t *frame, xlator_t *this);
-
-/* crypt.c */
-
-end_writeback_handler_t dispatch_end_writeback(glusterfs_fop_t fop);
-static size_t iovec_get_size(struct iovec *vec, uint32_t count);
-void set_local_io_params_writev(call_frame_t *frame,
- struct object_cipher_info *object,
- struct rmw_atom *atom, off_t io_offset,
- uint32_t io_size);
-void link_wind(call_frame_t *frame, xlator_t *this);
-void unlink_wind(call_frame_t *frame, xlator_t *this);
-void link_unwind(call_frame_t *frame);
-void unlink_unwind(call_frame_t *frame);
-void rename_wind(call_frame_t *frame, xlator_t *this);
-void rename_unwind(call_frame_t *frame);
-
-/* Inline functions */
-
-static inline size_t iovec_get_size(struct iovec *vec, uint32_t count)
-{
- int i;
- size_t size = 0;
- for (i = 0; i < count; i++)
- size += vec[i].iov_len;
- return size;
-}
-
-static inline int32_t crypt_xlator_id(void)
-{
- return CRYPT_XLATOR_ID;
-}
-
-static inline mtd_loader_id current_mtd_loader(void)
-{
- return MTD_LOADER_V1;
-}
-
-static inline uint32_t master_key_size (void)
-{
- return crypt_keys[MASTER_VOL_KEY].len >> 3;
-}
-
-static inline uint32_t nmtd_vol_key_size (void)
-{
- return crypt_keys[NMTD_VOL_KEY].len >> 3;
-}
-
-static inline uint32_t alg_mode_blkbits(cipher_alg_t alg,
- cipher_mode_t mode)
-{
- return data_cipher_algs[alg][mode].blkbits;
-}
-
-static inline uint32_t alg_mode_blksize(cipher_alg_t alg,
- cipher_mode_t mode)
-{
- return 1 << alg_mode_blkbits(alg, mode);
-}
-
-static inline gf_boolean_t alg_mode_atomic(cipher_alg_t alg,
- cipher_mode_t mode)
-{
- return data_cipher_algs[alg][mode].atomic;
-}
-
-static inline gf_boolean_t alg_mode_should_pad(cipher_alg_t alg,
- cipher_mode_t mode)
-{
- return data_cipher_algs[alg][mode].should_pad;
-}
-
-static inline uint32_t master_alg_blksize(struct master_cipher_info *mr)
-{
- return alg_mode_blksize(mr->m_alg, mr->m_mode);
-}
-
-static inline uint32_t master_alg_blkbits(struct master_cipher_info *mr)
-{
- return alg_mode_blkbits(mr->m_alg, mr->m_mode);
-}
-
-static inline gf_boolean_t master_alg_atomic(struct master_cipher_info *mr)
-{
- return alg_mode_atomic(mr->m_alg, mr->m_mode);
-}
-
-static inline gf_boolean_t master_alg_should_pad(struct master_cipher_info *mr)
-{
- return alg_mode_should_pad(mr->m_alg, mr->m_mode);
-}
-
-static inline uint32_t object_alg_blksize(struct object_cipher_info *ob)
-{
- return alg_mode_blksize(ob->o_alg, ob->o_mode);
-}
-
-static inline uint32_t object_alg_blkbits(struct object_cipher_info *ob)
-{
- return alg_mode_blkbits(ob->o_alg, ob->o_mode);
-}
-
-static inline gf_boolean_t object_alg_atomic(struct object_cipher_info *ob)
-{
- return alg_mode_atomic(ob->o_alg, ob->o_mode);
-}
-
-static inline gf_boolean_t object_alg_should_pad(struct object_cipher_info *ob)
-{
- return alg_mode_should_pad(ob->o_alg, ob->o_mode);
-}
-
-static inline uint32_t aes_raw_key_size(struct master_cipher_info *master)
-{
- return master->m_dkey_size >> 3;
-}
-
-static inline struct avec_config *get_hole_conf(call_frame_t *frame)
-{
- return &(((crypt_local_t *)frame->local)->hole_conf);
-}
-
-static inline struct avec_config *get_data_conf(call_frame_t *frame)
-{
- return &(((crypt_local_t *)frame->local)->data_conf);
-}
-
-static inline int32_t get_atom_bits (struct object_cipher_info *object)
-{
- return object->o_block_bits;
-}
-
-static inline int32_t get_atom_size (struct object_cipher_info *object)
-{
- return 1 << get_atom_bits(object);
-}
-
-static inline int32_t has_head_block(struct avec_config *conf)
-{
- return conf->off_in_head ||
- (conf->acount == 1 && conf->off_in_tail);
-}
-
-static inline int32_t has_tail_block(struct avec_config *conf)
-{
- return conf->off_in_tail && conf->acount > 1;
-}
-
-static inline int32_t has_full_blocks(struct avec_config *conf)
-{
- return conf->nr_full_blocks;
-}
-
-static inline int32_t should_submit_head_block(struct avec_config *conf)
-{
- return has_head_block(conf) && (conf->cursor == 0);
-}
-
-static inline int32_t should_submit_tail_block(struct avec_config *conf)
-{
- return has_tail_block(conf) && (conf->cursor == conf->acount - 1);
-}
-
-static inline int32_t should_submit_full_block(struct avec_config *conf)
-{
- uint32_t start = has_head_block(conf) ? 1 : 0;
-
- return has_full_blocks(conf) &&
- conf->cursor >= start &&
- conf->cursor < start + conf->nr_full_blocks;
-}
-
-#if DEBUG_CRYPT
-static inline void crypt_check_input_len(size_t len,
- struct object_cipher_info *object)
-{
- if (object_alg_should_pad(object) && (len & (object_alg_blksize(object) - 1)))
- gf_log ("crypt", GF_LOG_DEBUG, "bad input len: %d", (int)len);
-}
-
-static inline void check_head_block(struct avec_config *conf)
-{
- if (!has_head_block(conf))
- gf_log("crypt", GF_LOG_DEBUG, "not a head atom");
-}
-
-static inline void check_tail_block(struct avec_config *conf)
-{
- if (!has_tail_block(conf))
- gf_log("crypt", GF_LOG_DEBUG, "not a tail atom");
-}
-
-static inline void check_full_block(struct avec_config *conf)
-{
- if (!has_full_blocks(conf))
- gf_log("crypt", GF_LOG_DEBUG, "not a full atom");
-}
-
-static inline void check_cursor_head(struct avec_config *conf)
-{
- if (!has_head_block(conf))
- gf_log("crypt",
- GF_LOG_DEBUG, "Illegal call of head atom method");
- else if (conf->cursor != 0)
- gf_log("crypt",
- GF_LOG_DEBUG, "Cursor (%d) is not at head atom",
- conf->cursor);
-}
-
-static inline void check_cursor_full(struct avec_config *conf)
-{
- if (!has_full_blocks(conf))
- gf_log("crypt",
- GF_LOG_DEBUG, "Illegal call of full atom method");
- if (has_head_block(conf) && (conf->cursor == 0))
- gf_log("crypt",
- GF_LOG_DEBUG, "Cursor is not at full atom");
-}
-
-/*
- * FIXME: use avec->iov_len to check setup
- */
-static inline int data_local_invariant(crypt_local_t *local)
-{
- return 0;
-}
-
-#else
-#define crypt_check_input_len(len, object) noop
-#define check_head_block(conf) noop
-#define check_tail_block(conf) noop
-#define check_full_block(conf) noop
-#define check_cursor_head(conf) noop
-#define check_cursor_full(conf) noop
-
-#endif /* DEBUG_CRYPT */
-
-static inline struct avec_config *conf_by_type(call_frame_t *frame,
- atom_data_type dtype)
-{
- struct avec_config *conf = NULL;
-
- switch (dtype) {
- case HOLE_ATOM:
- conf = get_hole_conf(frame);
- break;
- case DATA_ATOM:
- conf = get_data_conf(frame);
- break;
- default:
- gf_log("crypt", GF_LOG_DEBUG, "bad atom type");
- }
- return conf;
-}
-
-static inline uint32_t nr_calls_head(struct avec_config *conf)
-{
- return has_head_block(conf) ? 1 : 0;
-}
-
-static inline uint32_t nr_calls_tail(struct avec_config *conf)
-{
- return has_tail_block(conf) ? 1 : 0;
-}
-
-static inline uint32_t nr_calls_full(struct avec_config *conf)
-{
- switch(conf->type) {
- case HOLE_ATOM:
- return has_full_blocks(conf);
- case DATA_ATOM:
- return has_full_blocks(conf) ?
- logical_blocks_occupied(0,
- conf->nr_full_blocks,
- MAX_IOVEC_BITS) : 0;
- default:
- gf_log("crypt", GF_LOG_DEBUG, "bad atom data type");
- return 0;
- }
-}
-
-static inline uint32_t nr_calls(struct avec_config *conf)
-{
- return nr_calls_head(conf) + nr_calls_tail(conf) + nr_calls_full(conf);
-}
-
-static inline uint32_t nr_calls_data(call_frame_t *frame)
-{
- return nr_calls(get_data_conf(frame));
-}
-
-static inline uint32_t nr_calls_hole(call_frame_t *frame)
-{
- return nr_calls(get_hole_conf(frame));
-}
-
-static inline void get_one_call_nolock(call_frame_t *frame)
-{
- crypt_local_t *local = frame->local;
-
- ++local->nr_calls;
-
- //gf_log("crypt", GF_LOG_DEBUG, "get %d calls", 1);
-}
-
-static inline void get_one_call(call_frame_t *frame)
-{
- crypt_local_t *local = frame->local;
-
- LOCK(&local->call_lock);
- get_one_call_nolock(frame);
- UNLOCK(&local->call_lock);
-}
-
-static inline void get_nr_calls_nolock(call_frame_t *frame, int32_t nr)
-{
- crypt_local_t *local = frame->local;
-
- local->nr_calls += nr;
-
- //gf_log("crypt", GF_LOG_DEBUG, "get %d calls", nr);
-}
-
-static inline void get_nr_calls(call_frame_t *frame, int32_t nr)
-{
- crypt_local_t *local = frame->local;
-
- LOCK(&local->call_lock);
- get_nr_calls_nolock(frame, nr);
- UNLOCK(&local->call_lock);
-}
-
-static inline int put_one_call(crypt_local_t *local)
-{
- uint32_t last = 0;
-
- LOCK(&local->call_lock);
- if (--local->nr_calls == 0)
- last = 1;
-
- //gf_log("crypt", GF_LOG_DEBUG, "put %d calls", 1);
-
- UNLOCK(&local->call_lock);
- return last;
-}
-
-static inline int is_appended_write(call_frame_t *frame)
-{
- crypt_local_t *local = frame->local;
- struct avec_config *conf = get_data_conf(frame);
-
- return conf->orig_offset + conf->orig_size > local->old_file_size;
-}
-
-static inline int is_ordered_mode(call_frame_t *frame)
-{
-#if 0
- crypt_local_t *local = frame->local;
- return local->fop == GF_FOP_FTRUNCATE ||
- (local->fop == GF_FOP_WRITE && is_appended_write(frame));
-#endif
- return 1;
-}
-
-static inline int32_t hole_conv_completed(crypt_local_t *local)
-{
- struct avec_config *conf = &local->hole_conf;
- return conf->cursor == conf->acount;
-}
-
-static inline int32_t data_write_in_progress(crypt_local_t *local)
-{
- return local->active_setup == DATA_ATOM;
-}
-
-static inline int32_t parent_is_crypt_xlator(call_frame_t *frame,
- xlator_t *this)
-{
- return frame->parent->this == this;
-}
-
-static inline linkop_wind_handler_t linkop_wind_dispatch(glusterfs_fop_t fop)
-{
- switch(fop){
- case GF_FOP_LINK:
- return link_wind;
- case GF_FOP_UNLINK:
- return unlink_wind;
- case GF_FOP_RENAME:
- return rename_wind;
- default:
- gf_log("crypt", GF_LOG_ERROR, "Bad link operation %d", fop);
- return NULL;
- }
-}
-
-static inline linkop_unwind_handler_t linkop_unwind_dispatch(glusterfs_fop_t fop)
-{
- switch(fop){
- case GF_FOP_LINK:
- return link_unwind;
- case GF_FOP_UNLINK:
- return unlink_unwind;
- case GF_FOP_RENAME:
- return rename_unwind;
- default:
- gf_log("crypt", GF_LOG_ERROR, "Bad link operation %d", fop);
- return NULL;
- }
-}
-
-static inline mtd_op_t linkop_mtdop_dispatch(glusterfs_fop_t fop)
-{
- switch (fop) {
- case GF_FOP_LINK:
- return MTD_APPEND;
- case GF_FOP_UNLINK:
- return MTD_CUT;
- case GF_FOP_RENAME:
- return MTD_OVERWRITE;
- default:
- gf_log("crypt", GF_LOG_WARNING, "Bad link operation %d", fop);
- return MTD_LAST_OP;
- }
-}
-
-#endif /* __CRYPT_H__ */
-
-/*
- Local variables:
- c-indentation-style: "K&R"
- mode-name: "LC"
- c-basic-offset: 8
- tab-width: 8
- fill-column: 80
- scroll-step: 1
- End:
-*/
diff --git a/xlators/encryption/crypt/src/data.c b/xlators/encryption/crypt/src/data.c
deleted file mode 100644
index 762fa554ac2..00000000000
--- a/xlators/encryption/crypt/src/data.c
+++ /dev/null
@@ -1,769 +0,0 @@
-/*
- Copyright (c) 2008-2013 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 "defaults.h"
-#include "crypt-common.h"
-#include "crypt.h"
-
-static void set_iv_aes_xts(off_t offset, struct object_cipher_info *object)
-{
- unsigned char *ivec;
-
- ivec = object->u.aes_xts.ivec;
-
- /* convert the tweak into a little-endian byte
- * array (IEEE P1619/D16, May 2007, section 5.1)
- */
-
- *((uint64_t *)ivec) = htole64(offset);
-
- /* ivec is padded with zeroes */
-}
-
-static int32_t aes_set_keys_common(unsigned char *raw_key, uint32_t key_size,
- AES_KEY *keys)
-{
- int32_t ret;
-
- ret = AES_set_encrypt_key(raw_key,
- key_size,
- &keys[AES_ENCRYPT]);
- if (ret) {
- gf_log("crypt", GF_LOG_ERROR, "Set encrypt key failed");
- return ret;
- }
- ret = AES_set_decrypt_key(raw_key,
- key_size,
- &keys[AES_DECRYPT]);
- if (ret) {
- gf_log("crypt", GF_LOG_ERROR, "Set decrypt key failed");
- return ret;
- }
- return 0;
-}
-
-/*
- * set private cipher info for xts mode
- */
-static int32_t set_private_aes_xts(struct crypt_inode_info *info,
- struct master_cipher_info *master)
-{
- int ret;
- struct object_cipher_info *object = get_object_cinfo(info);
- unsigned char *data_key;
- uint32_t subkey_size;
-
- /* init tweak value */
- memset(object->u.aes_xts.ivec, 0, 16);
-
- data_key = GF_CALLOC(1, object->o_dkey_size, gf_crypt_mt_key);
- if (!data_key)
- return ENOMEM;
-
- /*
- * retrieve data keying meterial
- */
- ret = get_data_file_key(info, master, object->o_dkey_size, data_key);
- if (ret) {
- gf_log("crypt", GF_LOG_ERROR, "Failed to retrieve data key");
- GF_FREE(data_key);
- return ret;
- }
- /*
- * parse compound xts key
- */
- subkey_size = object->o_dkey_size >> 4; /* (xts-key-size-in-bytes / 2) */
- /*
- * install key for data encryption
- */
- ret = aes_set_keys_common(data_key,
- subkey_size << 3, object->u.aes_xts.dkey);
- if (ret) {
- GF_FREE(data_key);
- return ret;
- }
- /*
- * set up key used to encrypt tweaks
- */
- ret = AES_set_encrypt_key(data_key + subkey_size,
- object->o_dkey_size / 2,
- &object->u.aes_xts.tkey);
- if (ret < 0)
- gf_log("crypt", GF_LOG_ERROR, "Set tweak key failed");
-
- GF_FREE(data_key);
- return ret;
-}
-
-static int32_t aes_xts_init(void)
-{
- cassert(AES_BLOCK_SIZE == (1 << AES_BLOCK_BITS));
- return 0;
-}
-
-static int32_t check_key_aes_xts(uint32_t keysize)
-{
- switch(keysize) {
- case 256:
- case 512:
- return 0;
- default:
- break;
- }
- return -1;
-}
-
-static int32_t encrypt_aes_xts(const unsigned char *from,
- unsigned char *to, size_t length,
- off_t offset, const int enc,
- struct object_cipher_info *object)
-{
- XTS128_CONTEXT ctx;
- if (enc) {
- ctx.key1 = &object->u.aes_xts.dkey[AES_ENCRYPT];
- ctx.block1 = (block128_f)AES_encrypt;
- }
- else {
- ctx.key1 = &object->u.aes_xts.dkey[AES_DECRYPT];
- ctx.block1 = (block128_f)AES_decrypt;
- }
- ctx.key2 = &object->u.aes_xts.tkey;
- ctx.block2 = (block128_f)AES_encrypt;
-
- return CRYPTO_xts128_encrypt(&ctx,
- object->u.aes_xts.ivec,
- from,
- to,
- length, enc);
-}
-
-/*
- * Cipher input chunk @from of length @len;
- * @to: result of cipher transform;
- * @off: offset in a file (must be cblock-aligned);
- */
-static void cipher_data(struct object_cipher_info *object,
- char *from,
- char *to,
- off_t off,
- size_t len,
- const int enc)
-{
- crypt_check_input_len(len, object);
-
-#if TRIVIAL_TFM && DEBUG_CRYPT
- return;
-#endif
- data_cipher_algs[object->o_alg][object->o_mode].set_iv(off, object);
- data_cipher_algs[object->o_alg][object->o_mode].encrypt
- ((const unsigned char *)from,
- (unsigned char *)to,
- len,
- off,
- enc,
- object);
-}
-
-#define MAX_CIPHER_CHUNK (1 << 30)
-
-/*
- * Do cipher (encryption/decryption) transform of a
- * continuous region of memory.
- *
- * @len: a number of bytes to transform;
- * @buf: data to transform;
- * @off: offset in a file, should be block-aligned
- * for atomic cipher modes and ksize-aligned
- * for other modes).
- * @dir: direction of transform (encrypt/decrypt).
- */
-static void cipher_region(struct object_cipher_info *object,
- char *from,
- char *to,
- off_t off,
- size_t len,
- int dir)
-{
- while (len > 0) {
- size_t to_cipher;
-
- to_cipher = len;
- if (to_cipher > MAX_CIPHER_CHUNK)
- to_cipher = MAX_CIPHER_CHUNK;
-
- /* this will reset IV */
- cipher_data(object,
- from,
- to,
- off,
- to_cipher,
- dir);
- from += to_cipher;
- to += to_cipher;
- off += to_cipher;
- len -= to_cipher;
- }
-}
-
-/*
- * Do cipher transform (encryption/decryption) of
- * plaintext/ciphertext represented by @vec.
- *
- * Pre-conditions: @vec represents a continuous piece
- * of data in a file at offset @off to be ciphered
- * (encrypted/decrypted).
- * @count is the number of vec's components. All the
- * components must be block-aligned, the caller is
- * responsible for this. @dir is "direction" of
- * transform (encrypt/decrypt).
- */
-static void cipher_aligned_iov(struct object_cipher_info *object,
- struct iovec *vec,
- int count,
- off_t off,
- int32_t dir)
-{
- int i;
- int len = 0;
-
- for (i = 0; i < count; i++) {
- cipher_region(object,
- vec[i].iov_base,
- vec[i].iov_base,
- off + len,
- vec[i].iov_len,
- dir);
- len += vec[i].iov_len;
- }
-}
-
-void encrypt_aligned_iov(struct object_cipher_info *object,
- struct iovec *vec,
- int count,
- off_t off)
-{
- cipher_aligned_iov(object, vec, count, off, 1);
-}
-
-void decrypt_aligned_iov(struct object_cipher_info *object,
- struct iovec *vec,
- int count,
- off_t off)
-{
- cipher_aligned_iov(object, vec, count, off, 0);
-}
-
-#if DEBUG_CRYPT
-static void compound_stream(struct iovec *vec, int count, char *buf, off_t skip)
-{
- int i;
- int off = 0;
- for (i = 0; i < count; i++) {
- memcpy(buf + off,
- vec[i].iov_base + skip,
- vec[i].iov_len - skip);
-
- off += (vec[i].iov_len - skip);
- skip = 0;
- }
-}
-
-static void check_iovecs(struct iovec *vec, int cnt,
- struct iovec *avec, int acnt, uint32_t off_in_head)
-{
- char *s1, *s2;
- uint32_t size, asize;
-
- size = iovec_get_size(vec, cnt);
- asize = iovec_get_size(avec, acnt) - off_in_head;
- if (size != asize) {
- gf_log("crypt", GF_LOG_DEBUG, "size %d is not eq asize %d",
- size, asize);
- return;
- }
- s1 = GF_CALLOC(1, size, gf_crypt_mt_data);
- if (!s1) {
- gf_log("crypt", GF_LOG_DEBUG, "Can not allocate stream ");
- return;
- }
- s2 = GF_CALLOC(1, asize, gf_crypt_mt_data);
- if (!s2) {
- GF_FREE(s1);
- gf_log("crypt", GF_LOG_DEBUG, "Can not allocate stream ");
- return;
- }
- compound_stream(vec, cnt, s1, 0);
- compound_stream(avec, acnt, s2, off_in_head);
- if (memcmp(s1, s2, size))
- gf_log("crypt", GF_LOG_DEBUG, "chunks of different data");
- GF_FREE(s1);
- GF_FREE(s2);
-}
-
-#else
-#define check_iovecs(vec, count, avec, avecn, off) noop
-#endif /* DEBUG_CRYPT */
-
-static char *data_alloc_block(xlator_t *this, crypt_local_t *local,
- int32_t block_size)
-{
- struct iobuf *iobuf = NULL;
-
- iobuf = iobuf_get2(this->ctx->iobuf_pool, block_size);
- if (!iobuf) {
- gf_log("crypt", GF_LOG_ERROR,
- "Failed to get iobuf");
- return NULL;
- }
- if (!local->iobref_data) {
- local->iobref_data = iobref_new();
- if (!local->iobref_data) {
- gf_log("crypt", GF_LOG_ERROR,
- "Failed to get iobref");
- iobuf_unref(iobuf);
- return NULL;
- }
- }
- iobref_add(local->iobref_data, iobuf);
- return iobuf->ptr;
-}
-
-/*
- * Compound @avec, which represent the same data
- * chunk as @vec, but has aligned components of
- * specified block size. Alloc blocks, if needed.
- * In particular, incomplete head and tail blocks
- * must be allocated.
- * Put number of allocated blocks to @num_blocks.
- *
- * Example:
- *
- * input: data chunk represented by 4 components
- * [AB],[BC],[CD],[DE];
- * output: 5 logical blocks (0, 1, 2, 3, 4).
- *
- * A B C D E
- * *-----*+------*-+---*----+--------+-*
- * | || | | | | | |
- * *-+-----+*------+-*---+----*--------*-+------*
- * 0 1 2 3 4
- *
- * 0 - incomplete compound (head);
- * 1, 2 - full compound;
- * 3 - full non-compound (the case of reuse);
- * 4 - incomplete non-compound (tail).
- */
-int32_t align_iov_by_atoms(xlator_t *this,
- crypt_local_t *local,
- struct object_cipher_info *object,
- struct iovec *vec /* input vector */,
- int32_t count /* number of vec components */,
- struct iovec *avec /* aligned vector */,
- char **blocks /* pool of blocks */,
- uint32_t *blocks_allocated,
- struct avec_config *conf)
-{
- int vecn = 0; /* number of the current component in vec */
- int avecn = 0; /* number of the current component in avec */
- off_t vec_off = 0; /* offset in the current vec component,
- * i.e. the number of bytes have already
- * been copied */
- int32_t block_size = get_atom_size(object);
- size_t to_process; /* number of vec's bytes to copy and(or) re-use */
- int32_t off_in_head = conf->off_in_head;
-
- to_process = iovec_get_size(vec, count);
-
- while (to_process > 0) {
- if (off_in_head ||
- vec[vecn].iov_len - vec_off < block_size) {
- /*
- * less than block_size:
- * the case of incomplete (head or tail),
- * or compound block
- */
- size_t copied = 0;
- /*
- * populate the pool with a new block
- */
- blocks[*blocks_allocated] = data_alloc_block(this,
- local,
- block_size);
- if (!blocks[*blocks_allocated])
- return -ENOMEM;
- memset(blocks[*blocks_allocated], 0, off_in_head);
- /*
- * fill the block with vec components
- */
- do {
- size_t to_copy;
-
- to_copy = vec[vecn].iov_len - vec_off;
- if (to_copy > block_size - off_in_head)
- to_copy = block_size - off_in_head;
-
- memcpy(blocks[*blocks_allocated] + off_in_head + copied,
- vec[vecn].iov_base + vec_off,
- to_copy);
-
- copied += to_copy;
- to_process -= to_copy;
-
- vec_off += to_copy;
- if (vec_off == vec[vecn].iov_len) {
- /* finished with this vecn */
- vec_off = 0;
- vecn++;
- }
- } while (copied < (block_size - off_in_head) && to_process > 0);
- /*
- * update avec
- */
- avec[avecn].iov_len = off_in_head + copied;
- avec[avecn].iov_base = blocks[*blocks_allocated];
-
- (*blocks_allocated)++;
- off_in_head = 0;
- } else {
- /*
- * the rest of the current vec component
- * is not less than block_size, so reuse
- * the memory buffer of the component.
- */
- size_t to_reuse;
- to_reuse = (to_process > block_size ?
- block_size :
- to_process);
- avec[avecn].iov_len = to_reuse;
- avec[avecn].iov_base = vec[vecn].iov_base + vec_off;
-
- vec_off += to_reuse;
- if (vec_off == vec[vecn].iov_len) {
- /* finished with this vecn */
- vec_off = 0;
- vecn++;
- }
- to_process -= to_reuse;
- }
- avecn++;
- }
- check_iovecs(vec, count, avec, avecn, conf->off_in_head);
- return 0;
-}
-
-/*
- * allocate and setup aligned vector for data submission
- * Pre-condition: @conf is set.
- */
-int32_t set_config_avec_data(xlator_t *this,
- crypt_local_t *local,
- struct avec_config *conf,
- struct object_cipher_info *object,
- struct iovec *vec,
- int32_t vec_count)
-{
- int32_t ret = ENOMEM;
- struct iovec *avec;
- char **pool;
- uint32_t blocks_in_pool = 0;
-
- conf->type = DATA_ATOM;
-
- avec = GF_CALLOC(conf->acount, sizeof(*avec), gf_crypt_mt_iovec);
- if (!avec)
- return ret;
- pool = GF_CALLOC(conf->acount, sizeof(pool), gf_crypt_mt_char);
- if (!pool) {
- GF_FREE(avec);
- return ret;
- }
- if (!vec) {
- /*
- * degenerated case: no data
- */
- pool[0] = data_alloc_block(this, local, get_atom_size(object));
- if (!pool[0])
- goto free;
- blocks_in_pool = 1;
- avec->iov_base = pool[0];
- avec->iov_len = conf->off_in_tail;
- }
- else {
- ret = align_iov_by_atoms(this, local, object, vec, vec_count,
- avec, pool, &blocks_in_pool, conf);
- if (ret)
- goto free;
- }
- conf->avec = avec;
- conf->pool = pool;
- conf->blocks_in_pool = blocks_in_pool;
- return 0;
- free:
- GF_FREE(avec);
- GF_FREE(pool);
- return ret;
-}
-
-/*
- * allocate and setup aligned vector for hole submission
- */
-int32_t set_config_avec_hole(xlator_t *this,
- crypt_local_t *local,
- struct avec_config *conf,
- struct object_cipher_info *object,
- glusterfs_fop_t fop)
-{
- uint32_t i, idx;
- struct iovec *avec;
- char **pool;
- uint32_t num_blocks;
- uint32_t blocks_in_pool = 0;
-
- conf->type = HOLE_ATOM;
-
- num_blocks = conf->acount -
- (conf->nr_full_blocks ? conf->nr_full_blocks - 1 : 0);
-
- switch (fop) {
- case GF_FOP_WRITE:
- /*
- * hole goes before data
- */
- if (num_blocks == 1 && conf->off_in_tail != 0)
- /*
- * we won't submit a hole which fits into
- * a data atom: this part of hole will be
- * submitted with data write
- */
- return 0;
- break;
- case GF_FOP_FTRUNCATE:
- /*
- * expanding truncate, hole goes after data,
- * and will be submited in any case.
- */
- break;
- default:
- gf_log("crypt", GF_LOG_WARNING,
- "bad file operation %d", fop);
- return 0;
- }
- avec = GF_CALLOC(num_blocks, sizeof(*avec), gf_crypt_mt_iovec);
- if (!avec)
- return ENOMEM;
- pool = GF_CALLOC(num_blocks, sizeof(pool), gf_crypt_mt_char);
- if (!pool) {
- GF_FREE(avec);
- return ENOMEM;
- }
- for (i = 0; i < num_blocks; i++) {
- pool[i] = data_alloc_block(this, local, get_atom_size(object));
- if (pool[i] == NULL)
- goto free;
- blocks_in_pool++;
- }
- if (has_head_block(conf)) {
- /* set head block */
- idx = 0;
- avec[idx].iov_base = pool[idx];
- avec[idx].iov_len = get_atom_size(object);
- memset(avec[idx].iov_base + conf->off_in_head,
- 0,
- get_atom_size(object) - conf->off_in_head);
- }
- if (has_tail_block(conf)) {
- /* set tail block */
- idx = num_blocks - 1;
- avec[idx].iov_base = pool[idx];
- avec[idx].iov_len = get_atom_size(object);
- memset(avec[idx].iov_base, 0, conf->off_in_tail);
- }
- if (has_full_blocks(conf)) {
- /* set full block */
- idx = conf->off_in_head ? 1 : 0;
- avec[idx].iov_base = pool[idx];
- avec[idx].iov_len = get_atom_size(object);
- /*
- * since we re-use the buffer,
- * zeroes will be set every time
- * before encryption, see submit_full()
- */
- }
- conf->avec = avec;
- conf->pool = pool;
- conf->blocks_in_pool = blocks_in_pool;
- return 0;
- free:
- GF_FREE(avec);
- GF_FREE(pool);
- return ENOMEM;
-}
-
-/* A helper for setting up config of partial atoms (which
- * participate in read-modify-write sequence).
- *
- * Calculate and setup precise amount of "extra-bytes"
- * that should be uptodated at the end of partial (not
- * necessarily tail!) block.
- *
- * Pre-condition: local->old_file_size is valid!
- * @conf contains setup, which is enough for correct calculation
- * of has_tail_block(), ->get_offset().
- */
-void set_gap_at_end(call_frame_t *frame, struct object_cipher_info *object,
- struct avec_config *conf, atom_data_type dtype)
-{
- uint32_t to_block;
- crypt_local_t *local = frame->local;
- uint64_t old_file_size = local->old_file_size;
- struct rmw_atom *partial = atom_by_types(dtype,
- has_tail_block(conf) ?
- TAIL_ATOM : HEAD_ATOM);
-
- if (old_file_size <= partial->offset_at(frame, object))
- to_block = 0;
- else {
- to_block = old_file_size - partial->offset_at(frame, object);
- if (to_block > get_atom_size(object))
- to_block = get_atom_size(object);
- }
- if (to_block > conf->off_in_tail)
- conf->gap_in_tail = to_block - conf->off_in_tail;
- else
- /*
- * nothing to uptodate
- */
- conf->gap_in_tail = 0;
-}
-
-/*
- * fill struct avec_config with offsets layouts
- */
-void set_config_offsets(call_frame_t *frame,
- xlator_t *this,
- uint64_t offset,
- uint64_t count,
- atom_data_type dtype,
- int32_t set_gap)
-{
- crypt_local_t *local;
- struct object_cipher_info *object;
- struct avec_config *conf;
- uint32_t resid;
-
- uint32_t atom_size;
- uint32_t atom_bits;
-
- size_t orig_size;
- off_t orig_offset;
- size_t expanded_size;
- off_t aligned_offset;
-
- uint32_t off_in_head = 0;
- uint32_t off_in_tail = 0;
- uint32_t nr_full_blocks;
- int32_t size_full_blocks;
-
- uint32_t acount; /* number of alifned components to write.
- * The same as number of occupied logical
- * blocks (atoms)
- */
- local = frame->local;
- object = &local->info->cinfo;
- conf = (dtype == DATA_ATOM ?
- get_data_conf(frame) : get_hole_conf(frame));
-
- orig_offset = offset;
- orig_size = count;
-
- atom_size = get_atom_size(object);
- atom_bits = get_atom_bits(object);
-
- /*
- * Round-down the start,
- * round-up the end.
- */
- resid = offset & (uint64_t)(atom_size - 1);
-
- if (resid)
- off_in_head = resid;
- aligned_offset = offset - off_in_head;
- expanded_size = orig_size + off_in_head;
-
- /* calculate tail,
- expand size forward */
- resid = (offset + orig_size) & (uint64_t)(atom_size - 1);
-
- if (resid) {
- off_in_tail = resid;
- expanded_size += (atom_size - off_in_tail);
- }
- /*
- * calculate number of occupied blocks
- */
- acount = expanded_size >> atom_bits;
- /*
- * calculate number of full blocks
- */
- size_full_blocks = expanded_size;
- if (off_in_head)
- size_full_blocks -= atom_size;
- if (off_in_tail && size_full_blocks > 0)
- size_full_blocks -= atom_size;
- nr_full_blocks = size_full_blocks >> atom_bits;
-
- conf->atom_size = atom_size;
- conf->orig_size = orig_size;
- conf->orig_offset = orig_offset;
- conf->expanded_size = expanded_size;
- conf->aligned_offset = aligned_offset;
-
- conf->off_in_head = off_in_head;
- conf->off_in_tail = off_in_tail;
- conf->nr_full_blocks = nr_full_blocks;
- conf->acount = acount;
- /*
- * Finally, calculate precise amount of
- * "extra-bytes" that should be uptodated
- * at the end.
- * Only if RMW is expected.
- */
- if (off_in_tail && set_gap)
- set_gap_at_end(frame, object, conf, dtype);
-}
-
-struct data_cipher_alg data_cipher_algs[LAST_CIPHER_ALG][LAST_CIPHER_MODE] = {
- [AES_CIPHER_ALG][XTS_CIPHER_MODE] =
- { .atomic = _gf_true,
- .should_pad = _gf_true,
- .blkbits = AES_BLOCK_BITS,
- .init = aes_xts_init,
- .set_private = set_private_aes_xts,
- .check_key = check_key_aes_xts,
- .set_iv = set_iv_aes_xts,
- .encrypt = encrypt_aes_xts
- }
-};
-
-/*
- Local variables:
- c-indentation-style: "K&R"
- mode-name: "LC"
- c-basic-offset: 8
- tab-width: 8
- fill-column: 80
- scroll-step: 1
- End:
-*/
diff --git a/xlators/encryption/crypt/src/keys.c b/xlators/encryption/crypt/src/keys.c
deleted file mode 100644
index 4a1d3bb5a09..00000000000
--- a/xlators/encryption/crypt/src/keys.c
+++ /dev/null
@@ -1,302 +0,0 @@
-/*
- Copyright (c) 2008-2013 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 "defaults.h"
-#include "crypt-common.h"
-#include "crypt.h"
-
-/* Key hierarchy
-
- +----------------+
- | MASTER_VOL_KEY |
- +-------+--------+
- |
- |
- +----------------+----------------+
- | | |
- | | |
- +-------+------+ +-------+-------+ +------+--------+
- | NMTD_VOL_KEY | | EMTD_FILE_KEY | | DATA_FILE_KEY |
- +-------+------+ +---------------+ +---------------+
- |
- |
- +-------+-------+
- | NMTD_LINK_KEY |
- +---------------+
-
- */
-
-#if DEBUG_CRYPT
-static void check_prf_iters(uint32_t num_iters)
-{
- if (num_iters == 0)
- gf_log ("crypt", GF_LOG_DEBUG,
- "bad number of prf iterations : %d", num_iters);
-}
-#else
-#define check_prf_iters(num_iters) noop
-#endif /* DEBUG_CRYPT */
-
-unsigned char crypt_fake_oid[16] =
- {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
-
-/*
- * derive key in the counter mode using
- * sha256-based HMAC as PRF, see
- * NIST Special Publication 800-108, 5.1)
- */
-
-#define PRF_OUTPUT_SIZE SHA256_DIGEST_LENGTH
-
-static int32_t kderive_init(struct kderive_context *ctx,
- const unsigned char *pkey, /* parent key */
- uint32_t pkey_size, /* parent key size */
- const unsigned char *idctx, /* id-context */
- uint32_t idctx_size,
- crypt_key_type type /* type of child key */)
-{
- unsigned char *pos;
- uint32_t llen = strlen(crypt_keys[type].label);
- /*
- * Compoud the fixed input data for KDF:
- * [i]_2 || Label || 0x00 || Id-Context || [L]_2),
- * NIST SP 800-108, 5.1
- */
- ctx->fid_len =
- sizeof(uint32_t) +
- llen +
- 1 +
- idctx_size +
- sizeof(uint32_t);
-
- ctx->fid = GF_CALLOC(ctx->fid_len, 1, gf_crypt_mt_key);
- if (!ctx->fid)
- return ENOMEM;
- ctx->out_len = round_up(crypt_keys[type].len >> 3,
- PRF_OUTPUT_SIZE);
- ctx->out = GF_CALLOC(ctx->out_len, 1, gf_crypt_mt_key);
- if (!ctx->out) {
- GF_FREE(ctx->fid);
- return ENOMEM;
- }
- ctx->pkey = pkey;
- ctx->pkey_len = pkey_size;
- ctx->ckey_len = crypt_keys[type].len;
-
- pos = ctx->fid;
-
- /* counter will be set up in kderive_rfn() */
- pos += sizeof(uint32_t);
-
- memcpy(pos, crypt_keys[type].label, llen);
- pos += llen;
-
- /* set up zero octet */
- *pos = 0;
- pos += 1;
-
- memcpy(pos, idctx, idctx_size);
- pos += idctx_size;
-
- *((uint32_t *)pos) = htobe32(ctx->ckey_len);
-
- return 0;
-}
-
-static void kderive_update(struct kderive_context *ctx)
-{
- uint32_t i;
- HMAC_CTX hctx;
- unsigned char *pos = ctx->out;
- uint32_t *p_iter = (uint32_t *)ctx->fid;
- uint32_t num_iters = ctx->out_len / PRF_OUTPUT_SIZE;
-
- check_prf_iters(num_iters);
-
- HMAC_CTX_init(&hctx);
- for (i = 0; i < num_iters; i++) {
- /*
- * update the iteration number in the fid
- */
- *p_iter = htobe32(i);
- HMAC_Init_ex(&hctx,
- ctx->pkey, ctx->pkey_len >> 3,
- EVP_sha256(),
- NULL);
- HMAC_Update(&hctx, ctx->fid, ctx->fid_len);
- HMAC_Final(&hctx, pos, NULL);
-
- pos += PRF_OUTPUT_SIZE;
- }
- HMAC_CTX_cleanup(&hctx);
-}
-
-static void kderive_final(struct kderive_context *ctx, unsigned char *child)
-{
- memcpy(child, ctx->out, ctx->ckey_len >> 3);
- GF_FREE(ctx->fid);
- GF_FREE(ctx->out);
- memset(ctx, 0, sizeof(*ctx));
-}
-
-/*
- * derive per-volume key for object ids aithentication
- */
-int32_t get_nmtd_vol_key(struct master_cipher_info *master)
-{
- int32_t ret;
- struct kderive_context ctx;
-
- ret = kderive_init(&ctx,
- master->m_key,
- master_key_size(),
- crypt_fake_oid, sizeof(uuid_t), NMTD_VOL_KEY);
- if (ret)
- return ret;
- kderive_update(&ctx);
- kderive_final(&ctx, master->m_nmtd_key);
- return 0;
-}
-
-/*
- * derive per-link key for aithentication of non-encrypted
- * meta-data (nmtd)
- */
-int32_t get_nmtd_link_key(loc_t *loc,
- struct master_cipher_info *master,
- unsigned char *result)
-{
- int32_t ret;
- struct kderive_context ctx;
-
- ret = kderive_init(&ctx,
- master->m_nmtd_key,
- nmtd_vol_key_size(),
- (const unsigned char *)loc->path,
- strlen(loc->path), NMTD_LINK_KEY);
- if (ret)
- return ret;
- kderive_update(&ctx);
- kderive_final(&ctx, result);
- return 0;
-}
-
-/*
- * derive per-file key for encryption and authentication
- * of encrypted part of metadata (emtd)
- */
-int32_t get_emtd_file_key(struct crypt_inode_info *info,
- struct master_cipher_info *master,
- unsigned char *result)
-{
- int32_t ret;
- struct kderive_context ctx;
-
- ret = kderive_init(&ctx,
- master->m_key,
- master_key_size(),
- info->oid, sizeof(uuid_t), EMTD_FILE_KEY);
- if (ret)
- return ret;
- kderive_update(&ctx);
- kderive_final(&ctx, result);
- return 0;
-}
-
-static int32_t data_key_type_by_size(uint32_t keysize, crypt_key_type *type)
-{
- int32_t ret = 0;
- switch (keysize) {
- case 256:
- *type = DATA_FILE_KEY_256;
- break;
- case 512:
- *type = DATA_FILE_KEY_512;
- break;
- default:
- gf_log("crypt", GF_LOG_ERROR, "Unsupported data key size %d",
- keysize);
- ret = ENOTSUP;
- break;
- }
- return ret;
-}
-
-/*
- * derive per-file key for data encryption
- */
-int32_t get_data_file_key(struct crypt_inode_info *info,
- struct master_cipher_info *master,
- uint32_t keysize,
- unsigned char *key)
-{
- int32_t ret;
- struct kderive_context ctx;
- crypt_key_type type;
-
- ret = data_key_type_by_size(keysize, &type);
- if (ret)
- return ret;
- ret = kderive_init(&ctx,
- master->m_key,
- master_key_size(),
- info->oid, sizeof(uuid_t), type);
- if (ret)
- return ret;
- kderive_update(&ctx);
- kderive_final(&ctx, key);
- return 0;
-}
-
-/*
- * NOTE: Don't change existing keys: it will break compatibility;
- */
-struct crypt_key crypt_keys[LAST_KEY_TYPE] = {
- [MASTER_VOL_KEY] =
- { .len = MASTER_VOL_KEY_SIZE << 3,
- .label = "volume-master",
- },
- [NMTD_VOL_KEY] =
- { .len = NMTD_VOL_KEY_SIZE << 3,
- .label = "volume-nmtd-key-generation"
- },
- [NMTD_LINK_KEY] =
- { .len = 128,
- .label = "link-nmtd-authentication"
- },
- [EMTD_FILE_KEY] =
- { .len = 128,
- .label = "file-emtd-encryption-and-auth"
- },
- [DATA_FILE_KEY_256] =
- { .len = 256,
- .label = "file-data-encryption-256"
- },
- [DATA_FILE_KEY_512] =
- { .len = 512,
- .label = "file-data-encryption-512"
- }
-};
-
-/*
- Local variables:
- c-indentation-style: "K&R"
- mode-name: "LC"
- c-basic-offset: 8
- tab-width: 8
- fill-column: 80
- scroll-step: 1
- End:
-*/
diff --git a/xlators/encryption/crypt/src/metadata.c b/xlators/encryption/crypt/src/metadata.c
deleted file mode 100644
index ebc76c84eb2..00000000000
--- a/xlators/encryption/crypt/src/metadata.c
+++ /dev/null
@@ -1,619 +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 "defaults.h"
-#include "crypt-common.h"
-#include "crypt.h"
-#include "metadata.h"
-
-int32_t alloc_format(crypt_local_t *local, size_t size)
-{
- if (size > 0) {
- local->format = GF_CALLOC(1, size, gf_crypt_mt_mtd);
- if (!local->format)
- return ENOMEM;
- }
- local->format_size = size;
- return 0;
-}
-
-int32_t alloc_format_create(crypt_local_t *local)
-{
- return alloc_format(local, new_format_size());
-}
-
-void free_format(crypt_local_t *local)
-{
- GF_FREE(local->format);
-}
-
-/*
- * Check compatibility with extracted metadata
- */
-static int32_t check_file_metadata(struct crypt_inode_info *info)
-{
- struct object_cipher_info *object = &info->cinfo;
-
- if (info->nr_minor != CRYPT_XLATOR_ID) {
- gf_log("crypt", GF_LOG_WARNING,
- "unsupported minor subversion %d", info->nr_minor);
- return EINVAL;
- }
- if (object->o_alg > LAST_CIPHER_ALG) {
- gf_log("crypt", GF_LOG_WARNING,
- "unsupported cipher algorithm %d",
- object->o_alg);
- return EINVAL;
- }
- if (object->o_mode > LAST_CIPHER_MODE) {
- gf_log("crypt", GF_LOG_WARNING,
- "unsupported cipher mode %d",
- object->o_mode);
- return EINVAL;
- }
- if (object->o_block_bits < CRYPT_MIN_BLOCK_BITS ||
- object->o_block_bits > CRYPT_MAX_BLOCK_BITS) {
- gf_log("crypt", GF_LOG_WARNING, "unsupported block bits %d",
- object->o_block_bits);
- return EINVAL;
- }
- /* TBD: check data key size */
- return 0;
-}
-
-static size_t format_size_v1(mtd_op_t op, size_t old_size)
-{
-
- switch (op) {
- case MTD_CREATE:
- return sizeof(struct mtd_format_v1);
- case MTD_OVERWRITE:
- return old_size;
- case MTD_APPEND:
- return old_size + NMTD_8_MAC_SIZE;
- case MTD_CUT:
- if (old_size > sizeof(struct mtd_format_v1))
- return old_size - NMTD_8_MAC_SIZE;
- else
- return 0;
- default:
- gf_log("crypt", GF_LOG_WARNING, "Bad mtd operation");
- return 0;
- }
-}
-
-/*
- * Calculate size of the updated format string.
- * Returned zero means that we don't need to update the format string.
- */
-size_t format_size(mtd_op_t op, size_t old_size)
-{
- size_t versioned;
-
- versioned = mtd_loaders[current_mtd_loader()].format_size(op,
- old_size - sizeof(struct crypt_format));
- if (versioned != 0)
- return versioned + sizeof(struct crypt_format);
- return 0;
-}
-
-/*
- * size of the format string of newly created file (nr_links = 1)
- */
-size_t new_format_size(void)
-{
- return format_size(MTD_CREATE, 0);
-}
-
-/*
- * Calculate per-link MAC by pathname
- */
-static int32_t calc_link_mac_v1(struct mtd_format_v1 *fmt,
- loc_t *loc,
- unsigned char *result,
- struct crypt_inode_info *info,
- struct master_cipher_info *master)
-{
- int32_t ret;
- unsigned char nmtd_link_key[16];
- CMAC_CTX *cctx;
- size_t len;
-
- ret = get_nmtd_link_key(loc, master, nmtd_link_key);
- if (ret) {
- gf_log("crypt", GF_LOG_ERROR, "Can not get nmtd link key");
- return -1;
- }
- cctx = CMAC_CTX_new();
- if (!cctx) {
- gf_log("crypt", GF_LOG_ERROR, "CMAC_CTX_new failed");
- return -1;
- }
- ret = CMAC_Init(cctx, nmtd_link_key, sizeof(nmtd_link_key),
- EVP_aes_128_cbc(), 0);
- if (!ret) {
- gf_log("crypt", GF_LOG_ERROR, "CMAC_Init failed");
- CMAC_CTX_free(cctx);
- return -1;
- }
- ret = CMAC_Update(cctx, get_NMTD_V1(info), SIZE_OF_NMTD_V1);
- if (!ret) {
- gf_log("crypt", GF_LOG_ERROR, "CMAC_Update failed");
- CMAC_CTX_free(cctx);
- return -1;
- }
- ret = CMAC_Final(cctx, result, &len);
- CMAC_CTX_free(cctx);
- if (!ret) {
- gf_log("crypt", GF_LOG_ERROR, "CMAC_Final failed");
- return -1;
- }
- return 0;
-}
-
-/*
- * Create per-link MAC of index @idx by pathname
- */
-static int32_t create_link_mac_v1(struct mtd_format_v1 *fmt,
- uint32_t idx,
- loc_t *loc,
- struct crypt_inode_info *info,
- struct master_cipher_info *master)
-{
- int32_t ret;
- unsigned char *mac;
- unsigned char cmac[16];
-
- mac = get_NMTD_V1_MAC(fmt) + idx * SIZE_OF_NMTD_V1_MAC;
-
- ret = calc_link_mac_v1(fmt, loc, cmac, info, master);
- if (ret)
- return -1;
- memcpy(mac, cmac, SIZE_OF_NMTD_V1_MAC);
- return 0;
-}
-
-static int32_t create_format_v1(unsigned char *wire,
- loc_t *loc,
- struct crypt_inode_info *info,
- struct master_cipher_info *master)
-{
- int32_t ret;
- struct mtd_format_v1 *fmt;
- unsigned char mtd_key[16];
- AES_KEY EMTD_KEY;
- unsigned char nmtd_link_key[16];
- uint32_t ad;
- GCM128_CONTEXT *gctx;
-
- fmt = (struct mtd_format_v1 *)wire;
-
- fmt->minor_id = info->nr_minor;
- fmt->alg_id = AES_CIPHER_ALG;
- fmt->dkey_factor = master->m_dkey_size >> KEY_FACTOR_BITS;
- fmt->block_bits = master->m_block_bits;
- fmt->mode_id = master->m_mode;
- /*
- * retrieve keys for the parts of metadata
- */
- ret = get_emtd_file_key(info, master, mtd_key);
- if (ret)
- return ret;
- ret = get_nmtd_link_key(loc, master, nmtd_link_key);
- if (ret)
- return ret;
-
- AES_set_encrypt_key(mtd_key, sizeof(mtd_key)*8, &EMTD_KEY);
-
- gctx = CRYPTO_gcm128_new(&EMTD_KEY, (block128_f)AES_encrypt);
-
- /* TBD: Check return values */
-
- CRYPTO_gcm128_setiv(gctx, info->oid, sizeof(uuid_t));
-
- ad = htole32(MTD_LOADER_V1);
- ret = CRYPTO_gcm128_aad(gctx, (const unsigned char *)&ad, sizeof(ad));
- if (ret) {
- gf_log("crypt", GF_LOG_ERROR, " CRYPTO_gcm128_aad failed");
- CRYPTO_gcm128_release(gctx);
- return ret;
- }
- ret = CRYPTO_gcm128_encrypt(gctx,
- get_EMTD_V1(fmt),
- get_EMTD_V1(fmt),
- SIZE_OF_EMTD_V1);
- if (ret) {
- gf_log("crypt", GF_LOG_ERROR, " CRYPTO_gcm128_encrypt failed");
- CRYPTO_gcm128_release(gctx);
- return ret;
- }
- /*
- * set MAC of encrypted part of metadata
- */
- CRYPTO_gcm128_tag(gctx, get_EMTD_V1_MAC(fmt), SIZE_OF_EMTD_V1_MAC);
- CRYPTO_gcm128_release(gctx);
- /*
- * set the first MAC of non-encrypted part of metadata
- */
- return create_link_mac_v1(fmt, 0, loc, info, master);
-}
-
-/*
- * Called by fops:
- * ->create();
- * ->link();
- *
- * Pack common and version-specific parts of file's metadata
- * Pre-conditions: @info contains valid object-id.
- */
-int32_t create_format(unsigned char *wire,
- loc_t *loc,
- struct crypt_inode_info *info,
- struct master_cipher_info *master)
-{
- struct crypt_format *fmt = (struct crypt_format *)wire;
-
- fmt->loader_id = current_mtd_loader();
-
- wire += sizeof(struct crypt_format);
- return mtd_loaders[current_mtd_loader()].create_format(wire, loc,
- info, master);
-}
-
-/*
- * Append or overwrite per-link mac of @mac_idx index
- * in accordance with the new pathname
- */
-int32_t appov_link_mac_v1(unsigned char *new,
- unsigned char *old,
- uint32_t old_size,
- int32_t mac_idx,
- loc_t *loc,
- struct crypt_inode_info *info,
- struct master_cipher_info *master,
- crypt_local_t *local)
-{
- memcpy(new, old, old_size);
- return create_link_mac_v1((struct mtd_format_v1 *)new, mac_idx,
- loc, info, master);
-}
-
-/*
- * Cut per-link mac of @mac_idx index
- */
-static int32_t cut_link_mac_v1(unsigned char *new,
- unsigned char *old,
- uint32_t old_size,
- int32_t mac_idx,
- loc_t *loc,
- struct crypt_inode_info *info,
- struct master_cipher_info *master,
- crypt_local_t *local)
-{
- memcpy(new,
- old,
- sizeof(struct mtd_format_v1) + NMTD_8_MAC_SIZE * (mac_idx - 1));
-
- memcpy(new + sizeof(struct mtd_format_v1) + NMTD_8_MAC_SIZE * (mac_idx - 1),
- old + sizeof(struct mtd_format_v1) + NMTD_8_MAC_SIZE * mac_idx,
- old_size - (sizeof(struct mtd_format_v1) + NMTD_8_MAC_SIZE * mac_idx));
- return 0;
-}
-
-int32_t update_format_v1(unsigned char *new,
- unsigned char *old,
- size_t old_len,
- int32_t mac_idx, /* of old name */
- mtd_op_t op,
- loc_t *loc,
- struct crypt_inode_info *info,
- struct master_cipher_info *master,
- crypt_local_t *local)
-{
- switch (op) {
- case MTD_APPEND:
- mac_idx = 1 + (old_len - sizeof(struct mtd_format_v1))/8;
- case MTD_OVERWRITE:
- return appov_link_mac_v1(new, old, old_len, mac_idx,
- loc, info, master, local);
- case MTD_CUT:
- return cut_link_mac_v1(new, old, old_len, mac_idx,
- loc, info, master, local);
- default:
- gf_log("crypt", GF_LOG_ERROR, "Bad mtd operation %d", op);
- return -1;
- }
-}
-
-/*
- * Called by fops:
- *
- * ->link()
- * ->unlink()
- * ->rename()
- *
- */
-int32_t update_format(unsigned char *new,
- unsigned char *old,
- size_t old_len,
- int32_t mac_idx,
- mtd_op_t op,
- loc_t *loc,
- struct crypt_inode_info *info,
- struct master_cipher_info *master,
- crypt_local_t *local)
-{
- if (!new)
- return 0;
- memcpy(new, old, sizeof(struct crypt_format));
-
- old += sizeof(struct crypt_format);
- new += sizeof(struct crypt_format);
- old_len -= sizeof(struct crypt_format);
-
- return mtd_loaders[current_mtd_loader()].update_format(new, old,
- old_len,
- mac_idx, op,
- loc, info,
- master, local);
-}
-
-/*
- * Perform preliminary checks of found metadata
- * Return < 0 on errors;
- * Return number of object-id MACs (>= 1) on success
- */
-int32_t check_format_v1(uint32_t len, unsigned char *wire)
-{
- uint32_t nr_links;
-
- if (len < sizeof(struct mtd_format_v1)) {
- gf_log("crypt", GF_LOG_ERROR,
- "v1-loader: bad metadata size %d", len);
- goto error;
- }
- len -= sizeof(struct mtd_format_v1);
- if (len % sizeof(nmtd_8_mac_t)) {
- gf_log("crypt", GF_LOG_ERROR,
- "v1-loader: bad metadata format");
- goto error;
- }
- nr_links = 1 + len / sizeof(nmtd_8_mac_t);
- if (nr_links > _POSIX_LINK_MAX)
- goto error;
- return nr_links;
- error:
- return EIO;
-}
-
-/*
- * Verify per-link MAC specified by index @idx
- *
- * return:
- * -1 on errors;
- * 0 on failed verification;
- * 1 on sucessful verification
- */
-static int32_t verify_link_mac_v1(struct mtd_format_v1 *fmt,
- uint32_t idx /* index of the mac to verify */,
- loc_t *loc,
- struct crypt_inode_info *info,
- struct master_cipher_info *master)
-{
- int32_t ret;
- unsigned char *mac;
- unsigned char cmac[16];
-
- mac = get_NMTD_V1_MAC(fmt) + idx * SIZE_OF_NMTD_V1_MAC;
-
- ret = calc_link_mac_v1(fmt, loc, cmac, info, master);
- if (ret)
- return -1;
- if (memcmp(cmac, mac, SIZE_OF_NMTD_V1_MAC))
- return 0;
- return 1;
-}
-
-/*
- * Lookup per-link MAC by pathname.
- *
- * return index of the MAC, if it was found;
- * return < 0 on errors, or if the MAC wasn't found
- */
-static int32_t lookup_link_mac_v1(struct mtd_format_v1 *fmt,
- uint32_t nr_macs,
- loc_t *loc,
- struct crypt_inode_info *info,
- struct master_cipher_info *master)
-{
- int32_t ret;
- uint32_t idx;
-
- for (idx = 0; idx < nr_macs; idx++) {
- ret = verify_link_mac_v1(fmt, idx, loc, info, master);
- if (ret < 0)
- return ret;
- if (ret > 0)
- return idx;
- }
- return -ENOENT;
-}
-
-/*
- * Extract version-specific part of metadata
- */
-static int32_t open_format_v1(unsigned char *wire,
- int32_t len,
- loc_t *loc,
- struct crypt_inode_info *info,
- struct master_cipher_info *master,
- crypt_local_t *local,
- gf_boolean_t load_info)
-{
- int32_t ret;
- int32_t num_nmtd_macs;
- struct mtd_format_v1 *fmt;
- unsigned char mtd_key[16];
- AES_KEY EMTD_KEY;
- GCM128_CONTEXT *gctx;
- uint32_t ad;
- emtd_8_mac_t gmac;
- struct object_cipher_info *object;
-
- num_nmtd_macs = check_format_v1(len, wire);
- if (num_nmtd_macs <= 0)
- return EIO;
-
- ret = lookup_link_mac_v1((struct mtd_format_v1 *)wire,
- num_nmtd_macs, loc, info, master);
- if (ret < 0) {
- gf_log("crypt", GF_LOG_ERROR, "NMTD verification failed");
- return EINVAL;
- }
-
- local->mac_idx = ret;
- if (load_info == _gf_false)
- /* the case of partial open */
- return 0;
-
- fmt = GF_CALLOC(1, len, gf_crypt_mt_mtd);
- if (!fmt)
- return ENOMEM;
- memcpy(fmt, wire, len);
-
- object = &info->cinfo;
-
- ret = get_emtd_file_key(info, master, mtd_key);
- if (ret) {
- gf_log("crypt", GF_LOG_ERROR, "Can not retrieve metadata key");
- goto out;
- }
- /*
- * decrypt encrypted meta-data
- */
- ret = AES_set_encrypt_key(mtd_key, sizeof(mtd_key)*8, &EMTD_KEY);
- if (ret < 0) {
- gf_log("crypt", GF_LOG_ERROR, "Can not set encrypt key");
- ret = EIO;
- goto out;
- }
- gctx = CRYPTO_gcm128_new(&EMTD_KEY, (block128_f)AES_encrypt);
- if (!gctx) {
- gf_log("crypt", GF_LOG_ERROR, "Can not alloc gcm context");
- ret = ENOMEM;
- goto out;
- }
- CRYPTO_gcm128_setiv(gctx, info->oid, sizeof(uuid_t));
-
- ad = htole32(MTD_LOADER_V1);
- ret = CRYPTO_gcm128_aad(gctx, (const unsigned char *)&ad, sizeof(ad));
- if (ret) {
- gf_log("crypt", GF_LOG_ERROR, " CRYPTO_gcm128_aad failed");
- CRYPTO_gcm128_release(gctx);
- ret = EIO;
- goto out;
- }
- ret = CRYPTO_gcm128_decrypt(gctx,
- get_EMTD_V1(fmt),
- get_EMTD_V1(fmt),
- SIZE_OF_EMTD_V1);
- if (ret) {
- gf_log("crypt", GF_LOG_ERROR, " CRYPTO_gcm128_decrypt failed");
- CRYPTO_gcm128_release(gctx);
- ret = EIO;
- goto out;
- }
- /*
- * verify metadata
- */
- CRYPTO_gcm128_tag(gctx, gmac, sizeof(gmac));
- CRYPTO_gcm128_release(gctx);
- if (memcmp(gmac, get_EMTD_V1_MAC(fmt), SIZE_OF_EMTD_V1_MAC)) {
- gf_log("crypt", GF_LOG_ERROR, "EMTD verification failed");
- ret = EINVAL;
- goto out;
- }
- /*
- * load verified metadata to the private part of inode
- */
- info->nr_minor = fmt->minor_id;
-
- object->o_alg = fmt->alg_id;
- object->o_dkey_size = fmt->dkey_factor << KEY_FACTOR_BITS;
- object->o_block_bits = fmt->block_bits;
- object->o_mode = fmt->mode_id;
-
- ret = check_file_metadata(info);
- out:
- GF_FREE(fmt);
- return ret;
-}
-
-/*
- * perform metadata authentication against @loc->path;
- * extract crypt-specific attribtes and populate @info
- * with them (optional)
- */
-int32_t open_format(unsigned char *str,
- int32_t len,
- loc_t *loc,
- struct crypt_inode_info *info,
- struct master_cipher_info *master,
- crypt_local_t *local,
- gf_boolean_t load_info)
-{
- struct crypt_format *fmt;
- if (len < sizeof(*fmt)) {
- gf_log("crypt", GF_LOG_ERROR, "Bad core format");
- return EIO;
- }
- fmt = (struct crypt_format *)str;
-
- if (fmt->loader_id >= LAST_MTD_LOADER) {
- gf_log("crypt", GF_LOG_ERROR,
- "Unsupported loader id %d", fmt->loader_id);
- return EINVAL;
- }
- str += sizeof(*fmt);
- len -= sizeof(*fmt);
-
- return mtd_loaders[fmt->loader_id].open_format(str,
- len,
- loc,
- info,
- master,
- local,
- load_info);
-}
-
-struct crypt_mtd_loader mtd_loaders [LAST_MTD_LOADER] = {
- [MTD_LOADER_V1] =
- {.format_size = format_size_v1,
- .create_format = create_format_v1,
- .open_format = open_format_v1,
- .update_format = update_format_v1
- }
-};
-
-/*
- Local variables:
- c-indentation-style: "K&R"
- mode-name: "LC"
- c-basic-offset: 8
- tab-width: 8
- fill-column: 80
- scroll-step: 1
- End:
-*/
diff --git a/xlators/encryption/crypt/src/metadata.h b/xlators/encryption/crypt/src/metadata.h
deleted file mode 100644
index a92f149ef50..00000000000
--- a/xlators/encryption/crypt/src/metadata.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- Copyright (c) 2008-2013 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 __METADATA_H__
-#define __METADATA_H__
-
-#define NMTD_8_MAC_SIZE (8)
-#define EMTD_8_MAC_SIZE (8)
-
-typedef uint8_t nmtd_8_mac_t[NMTD_8_MAC_SIZE];
-typedef uint8_t emtd_8_mac_t[EMTD_8_MAC_SIZE] ;
-
-/*
- * Version "v1" of file's metadata.
- * Metadata of this version has 4 components:
- *
- * 1) EMTD (Encrypted part of MeTaData);
- * 2) NMTD (Non-encrypted part of MeTaData);
- * 3) EMTD_MAC; (EMTD Message Authentication Code);
- * 4) Array of per-link NMTD MACs (for every (hard)link it includes
- * exactly one MAC)
- */
-struct mtd_format_v1 {
- /* EMTD, encrypted part of meta-data */
- uint8_t alg_id; /* cipher algorithm id (only AES for now) */
- uint8_t mode_id; /* cipher mode id; (only XTS for now) */
- uint8_t block_bits; /* encoded block size */
- uint8_t minor_id; /* client translator id */
- uint8_t dkey_factor; /* encoded size of the data key */
- /* MACs */
- emtd_8_mac_t gmac; /* MAC of the encrypted meta-data, 8 bytes */
- nmtd_8_mac_t omac; /* per-link MACs of the non-encrypted
- * meta-data: at least one such MAC is always
- * present */
-} __attribute__((packed));
-
-/*
- * NMTD, the non-encrypted part of metadata of version "v1"
- * is file's gfid, which is generated on trusted machines.
- */
-#define SIZE_OF_NMTD_V1 (sizeof(uuid_t))
-#define SIZE_OF_EMTD_V1 (offsetof(struct mtd_format_v1, gmac) - \
- offsetof(struct mtd_format_v1, alg_id))
-#define SIZE_OF_NMTD_V1_MAC (NMTD_8_MAC_SIZE)
-#define SIZE_OF_EMTD_V1_MAC (EMTD_8_MAC_SIZE)
-
-static inline unsigned char *get_EMTD_V1(struct mtd_format_v1 *format)
-{
- return &format->alg_id;
-}
-
-static inline unsigned char *get_NMTD_V1(struct crypt_inode_info *info)
-{
- return info->oid;
-}
-
-static inline unsigned char *get_EMTD_V1_MAC(struct mtd_format_v1 *format)
-{
- return format->gmac;
-}
-
-static inline unsigned char *get_NMTD_V1_MAC(struct mtd_format_v1 *format)
-{
- return format->omac;
-}
-
-#endif /* __METADATA_H__ */
diff --git a/xlators/encryption/rot-13/src/Makefile.am b/xlators/encryption/rot-13/src/Makefile.am
index 94e8d18e789..ba5e623d8e2 100644
--- a/xlators/encryption/rot-13/src/Makefile.am
+++ b/xlators/encryption/rot-13/src/Makefile.am
@@ -1,15 +1,14 @@
xlator_LTLIBRARIES = rot-13.la
xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/encryption
-rot_13_la_LDFLAGS = -module -avoid-version
+rot_13_la_LDFLAGS = -module -avoidversion
rot_13_la_SOURCES = rot-13.c
rot_13_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la
noinst_HEADERS = rot-13.h
-AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src
-
-AM_CFLAGS = -Wall $(GF_CFLAGS)
+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/encryption/rot-13/src/rot-13.c b/xlators/encryption/rot-13/src/rot-13.c
index 1bcfe0192f6..d5c702882df 100644
--- a/xlators/encryption/rot-13/src/rot-13.c
+++ b/xlators/encryption/rot-13/src/rot-13.c
@@ -1,12 +1,22 @@
/*
- Copyright (c) 2006-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) 2006-2009 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 <ctype.h>
#include <sys/uio.h>
@@ -22,13 +32,13 @@
#include "rot-13.h"
/*
- * This is a rot13 ``encryption'' xlator. It rot13's data when
- * writing to disk and rot13's it back when reading it.
+ * This is a rot13 ``encryption'' xlator. It rot13's data when
+ * writing to disk and rot13's it back when reading it.
* This xlator is meant as an example, NOT FOR PRODUCTION
* USE ;) (hence no error-checking)
*/
-void
+void
rot13 (char *buf, int len)
{
int i;
@@ -57,16 +67,15 @@ rot13_readv_cbk (call_frame_t *frame,
int32_t op_errno,
struct iovec *vector,
int32_t count,
- struct iatt *stbuf,
- struct iobref *iobref, dict_t *xdata)
+ struct stat *stbuf,
+ 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 (frame, op_ret, op_errno, vector, count, stbuf, iobref);
return 0;
}
@@ -75,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;
}
@@ -91,11 +100,10 @@ rot13_writev_cbk (call_frame_t *frame,
xlator_t *this,
int32_t op_ret,
int32_t op_errno,
- struct iatt *prebuf,
- struct iatt *postbuf, dict_t *xdata)
+ struct stat *prebuf,
+ struct stat *postbuf)
{
- STACK_UNWIND_STRICT (writev, frame, op_ret, op_errno, prebuf, postbuf,
- xdata);
+ STACK_UNWIND (frame, op_ret, op_errno, prebuf, postbuf);
return 0;
}
@@ -104,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;
}
@@ -128,7 +136,7 @@ init (xlator_t *this)
rot_13_private_t *priv = NULL;
if (!this->children || this->children->next) {
- gf_log ("rot13", GF_LOG_ERROR,
+ gf_log ("rot13", GF_LOG_ERROR,
"FATAL: rot13 should have exactly one child");
return -1;
}
@@ -137,11 +145,9 @@ init (xlator_t *this)
gf_log (this->name, GF_LOG_WARNING,
"dangling volume. check volfile ");
}
-
- priv = GF_CALLOC (sizeof (rot_13_private_t), 1, 0);
- if (!priv)
- return -1;
-
+
+ priv = CALLOC (sizeof (rot_13_private_t), 1);
+ ERR_ABORT (priv);
priv->decrypt_read = 1;
priv->encrypt_write = 1;
@@ -150,7 +156,6 @@ init (xlator_t *this)
if (gf_string2boolean (data->data, &priv->encrypt_write) == -1) {
gf_log (this->name, GF_LOG_ERROR,
"encrypt-write takes only boolean options");
- GF_FREE (priv);
return -1;
}
}
@@ -160,7 +165,6 @@ init (xlator_t *this)
if (gf_string2boolean (data->data, &priv->decrypt_read) == -1) {
gf_log (this->name, GF_LOG_ERROR,
"decrypt-read takes only boolean options");
- GF_FREE (priv);
return -1;
}
}
@@ -170,16 +174,13 @@ init (xlator_t *this)
return 0;
}
-void
+void
fini (xlator_t *this)
{
rot_13_private_t *priv = this->private;
-
- if (!priv)
- return;
- this->private = NULL;
- GF_FREE (priv);
-
+
+ FREE (priv);
+
return;
}
@@ -188,14 +189,18 @@ struct xlator_fops fops = {
.writev = rot13_writev
};
-struct xlator_cbks cbks;
+struct xlator_mops mops = {
+};
+
+struct xlator_cbks cbks = {
+};
struct volume_options options[] = {
- { .key = {"encrypt-write"},
+ { .key = {"encrypt-write"},
.type = GF_OPTION_TYPE_BOOL
},
- { .key = {"decrypt-read"},
- .type = GF_OPTION_TYPE_BOOL
+ { .key = {"decrypt-read"},
+ .type = GF_OPTION_TYPE_BOOL
},
{ .key = {NULL} },
};
diff --git a/xlators/encryption/rot-13/src/rot-13.h b/xlators/encryption/rot-13/src/rot-13.h
index 3e9fc19c776..35a2df2da29 100644
--- a/xlators/encryption/rot-13/src/rot-13.h
+++ b/xlators/encryption/rot-13/src/rot-13.h
@@ -1,12 +1,22 @@
/*
- Copyright (c) 2006-2012 Red Hat, Inc. <http://www.redhat.com>
+ Copyright (c) 2006-2009 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 General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that 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 __ROT_13_H__
#define __ROT_13_H__
diff --git a/xlators/features/Makefile.am b/xlators/features/Makefile.am
index 8093441a043..9ac9b6f19de 100644
--- a/xlators/features/Makefile.am
+++ b/xlators/features/Makefile.am
@@ -1,4 +1,3 @@
-SUBDIRS = locks quota read-only mac-compat quiesce marker index barrier \
- protect compress changelog gfid-access $(GLUPY_SUBDIR) qemu-block snapview-client snapview-server # trash path-converter # filter
+SUBDIRS = locks trash path-convertor filter quota
-CLEANFILES =
+CLEANFILES =
diff --git a/xlators/features/barrier/Makefile.am b/xlators/features/barrier/Makefile.am
deleted file mode 100644
index a985f42a877..00000000000
--- a/xlators/features/barrier/Makefile.am
+++ /dev/null
@@ -1,3 +0,0 @@
-SUBDIRS = src
-
-CLEANFILES =
diff --git a/xlators/features/barrier/src/Makefile.am b/xlators/features/barrier/src/Makefile.am
deleted file mode 100644
index 8859be328d3..00000000000
--- a/xlators/features/barrier/src/Makefile.am
+++ /dev/null
@@ -1,16 +0,0 @@
-xlator_LTLIBRARIES = barrier.la
-xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/features
-
-barrier_la_LDFLAGS = -module -avoid-version
-
-barrier_la_SOURCES = barrier.c
-
-barrier_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la
-
-noinst_HEADERS = barrier.h barrier-mem-types.h
-
-AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src
-
-AM_CFLAGS = -Wall $(GF_CFLAGS)
-
-CLEANFILES =
diff --git a/xlators/features/barrier/src/barrier-mem-types.h b/xlators/features/barrier/src/barrier-mem-types.h
deleted file mode 100644
index 36647a66966..00000000000
--- a/xlators/features/barrier/src/barrier-mem-types.h
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- Copyright (c) 2014 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 __BARRIER_MEM_TYPES_H__
-#define __BARRIER_MEM_TYPES_H__
-
-#include "mem-types.h"
-
-enum gf_barrier_mem_types_ {
- gf_barrier_mt_priv_t = gf_common_mt_end + 1,
- gf_barrier_mt_end
-};
-#endif
diff --git a/xlators/features/barrier/src/barrier.c b/xlators/features/barrier/src/barrier.c
deleted file mode 100644
index f2d8d9632ec..00000000000
--- a/xlators/features/barrier/src/barrier.c
+++ /dev/null
@@ -1,664 +0,0 @@
-/*
- Copyright (c) 2014 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 "barrier.h"
-#include "defaults.h"
-#include "call-stub.h"
-
-#include "statedump.h"
-
-int32_t
-barrier_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)
-{
- BARRIER_FOP_CBK (writev, out, frame, this, op_ret, op_errno,
- prebuf, postbuf, xdata);
-out:
- return 0;
-}
-
-int32_t
-barrier_fremovexattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
-{
- BARRIER_FOP_CBK (fremovexattr, out, frame, this, op_ret, op_errno,
- xdata);
-out:
- return 0;
-}
-
-int32_t
-barrier_removexattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
-{
- BARRIER_FOP_CBK (removexattr, out, frame, this, op_ret, op_errno,
- xdata);
-out:
- return 0;
-}
-
-int32_t
-barrier_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)
-{
- BARRIER_FOP_CBK (truncate, out, frame, this, op_ret, op_errno, prebuf,
- postbuf, xdata);
-out:
- return 0;
-}
-
-int32_t
-barrier_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)
-{
- BARRIER_FOP_CBK (ftruncate, out, frame, this, op_ret, op_errno, prebuf,
- postbuf, xdata);
-out:
- return 0;
-}
-
-int32_t
-barrier_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)
-{
- BARRIER_FOP_CBK (rename, out, frame, this, op_ret, op_errno, buf,
- preoldparent, postoldparent, prenewparent,
- postnewparent, xdata);
-out:
- return 0;
-}
-
-int32_t
-barrier_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)
-{
- BARRIER_FOP_CBK (rmdir, out, frame, this, op_ret, op_errno, preparent,
- postparent, xdata);
-out:
- return 0;
-}
-
-int32_t
-barrier_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)
-{
- BARRIER_FOP_CBK (unlink, out, frame, this, op_ret, op_errno, preparent,
- postparent, xdata);
-out:
- return 0;
-}
-
-int32_t
-barrier_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)
-{
- BARRIER_FOP_CBK (fsync, out, frame, this, op_ret, op_errno,
- prebuf, postbuf, xdata);
-out:
- return 0;
-}
-
-int32_t
-barrier_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)
-{
- if (!((flags | fd->flags) & (O_SYNC | O_DSYNC))) {
- STACK_WIND_TAIL (frame, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->writev,
- fd, vector, count, off, flags, iobref, xdata);
-
- return 0;
- }
-
- STACK_WIND (frame, barrier_writev_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->writev, fd, vector, count,
- off, flags, iobref, xdata);
- return 0;
-}
-
-int32_t
-barrier_fremovexattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
- const char *name, dict_t *xdata)
-{
- STACK_WIND (frame, barrier_fremovexattr_cbk, FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->fremovexattr,
- fd, name, xdata);
- return 0;
-}
-
-int32_t
-barrier_removexattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
- const char *name, dict_t *xdata)
-{
- STACK_WIND (frame, barrier_removexattr_cbk, FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->removexattr,
- loc, name, xdata);
- return 0;
-}
-
-int32_t
-barrier_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc,
- off_t offset, dict_t *xdata)
-{
- STACK_WIND (frame, barrier_truncate_cbk, FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->truncate,
- loc, offset, xdata);
- return 0;
-}
-
-int32_t
-barrier_rename (call_frame_t *frame, xlator_t *this, loc_t *oldloc,
- loc_t *newloc, dict_t *xdata)
-{
- STACK_WIND (frame, barrier_rename_cbk, FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->rename,
- oldloc, newloc, xdata);
- return 0;
-}
-
-int
-barrier_rmdir (call_frame_t *frame, xlator_t *this, loc_t *loc, int flags,
- dict_t *xdata)
-{
- STACK_WIND (frame, barrier_rmdir_cbk, FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->rmdir,
- loc, flags, xdata);
- return 0;
-}
-
-int32_t
-barrier_unlink (call_frame_t *frame, xlator_t *this,
- loc_t *loc, int xflag, dict_t *xdata)
-{
- STACK_WIND (frame, barrier_unlink_cbk, FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->unlink,
- loc, xflag, xdata);
- return 0;
-}
-
-int32_t
-barrier_ftruncate (call_frame_t *frame, xlator_t *this, fd_t *fd,
- off_t offset, dict_t *xdata)
-{
- STACK_WIND (frame, barrier_ftruncate_cbk, FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->ftruncate,
- fd, offset, xdata);
- return 0;
-}
-
-int32_t
-barrier_fsync (call_frame_t *frame, xlator_t *this, fd_t *fd,
- int32_t flags, dict_t *xdata)
-{
- STACK_WIND (frame, barrier_fsync_cbk, FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->fsync,
- fd, flags, xdata);
- return 0;
-}
-
-call_stub_t *
-__barrier_dequeue (xlator_t *this, struct list_head *queue)
-{
- call_stub_t *stub = NULL;
- barrier_priv_t *priv = NULL;
-
- priv = this->private;
- GF_ASSERT (priv);
-
- if (list_empty (queue))
- goto out;
-
- stub = list_entry (queue->next, call_stub_t, list);
- list_del_init (&stub->list);
-
-out:
- return stub;
-}
-
-void
-barrier_dequeue_all (xlator_t *this, struct list_head *queue)
-{
- call_stub_t *stub = NULL;
-
- gf_log (this->name, GF_LOG_INFO, "Dequeuing all the barriered fops");
-
- /* TODO: Start the below task in a new thread */
- while ((stub = __barrier_dequeue (this, queue)))
- call_resume (stub);
-
- gf_log (this->name, GF_LOG_INFO, "Dequeuing the barriered fops is "
- "finished");
- return;
-}
-
-void
-barrier_timeout (void *data)
-{
- xlator_t *this = NULL;
- barrier_priv_t *priv = NULL;
- struct list_head queue = {0,};
-
- this = data;
- THIS = this;
- priv = this->private;
-
- INIT_LIST_HEAD (&queue);
-
- gf_log (this->name, GF_LOG_CRITICAL, "Disabling barrier because of "
- "the barrier timeout.");
-
- LOCK (&priv->lock);
- {
- __barrier_disable (this, &queue);
- }
- UNLOCK (&priv->lock);
-
- barrier_dequeue_all (this, &queue);
-
- return;
-}
-
-void
-__barrier_enqueue (xlator_t *this, call_stub_t *stub)
-{
- barrier_priv_t *priv = NULL;
-
- priv = this->private;
- GF_ASSERT (priv);
-
- list_add_tail (&stub->list, &priv->queue);
- priv->queue_size++;
-
- return;
-}
-
-void
-__barrier_disable (xlator_t *this, struct list_head *queue)
-{
- GF_UNUSED int ret = 0;
- barrier_priv_t *priv = NULL;
-
- priv = this->private;
- GF_ASSERT (priv);
-
- if (priv->timer) {
- ret = gf_timer_call_cancel (this->ctx, priv->timer);
- priv->timer = NULL;
- }
-
- list_splice_init (&priv->queue, queue);
- priv->queue_size = 0;
- priv->barrier_enabled = _gf_false;
-}
-
-int
-__barrier_enable (xlator_t *this, barrier_priv_t *priv)
-{
- int ret = -1;
-
- priv->timer = gf_timer_call_after (this->ctx, priv->timeout,
- barrier_timeout, (void *) this);
- if (!priv->timer) {
- gf_log (this->name, GF_LOG_CRITICAL, "Couldn't add barrier "
- "timeout event.");
- goto out;
- }
-
- priv->barrier_enabled = _gf_true;
- ret = 0;
-out:
- return ret;
-}
-
-int
-notify (xlator_t *this, int event, void *data, ...)
-{
- barrier_priv_t *priv = NULL;
- dict_t *dict = NULL;
- gf_boolean_t past = _gf_false;
- int ret = -1;
- gf_boolean_t barrier_enabled = _gf_false;
- struct list_head queue = {0,};
-
- priv = this->private;
- GF_ASSERT (priv);
- INIT_LIST_HEAD (&queue);
-
- switch (event) {
- case GF_EVENT_TRANSLATOR_OP:
- {
- dict = data;
- barrier_enabled = dict_get_str_boolean (dict, "barrier", -1);
-
- if (barrier_enabled == -1) {
- gf_log (this->name, GF_LOG_ERROR, "Could not fetch "
- " barrier key from the dictionary.");
- goto out;
- }
-
- LOCK (&priv->lock);
- {
- past = priv->barrier_enabled;
-
- switch (past) {
- case _gf_false:
- if (barrier_enabled) {
- ret = __barrier_enable (this,priv);
- if (ret)
- goto unlock;
- } else {
- gf_log (this->name, GF_LOG_ERROR,
- "Already disabled.");
- goto unlock;
- }
- break;
-
- case _gf_true:
- if (!barrier_enabled) {
- __barrier_disable(this, &queue);
- } else {
- gf_log (this->name, GF_LOG_ERROR,
- "Already enabled");
- goto unlock;
- }
- break;
- }
- ret = 0;
- }
-unlock:
- UNLOCK (&priv->lock);
-
- if (!list_empty (&queue))
- barrier_dequeue_all (this, &queue);
-
- break;
- }
- default:
- {
- default_notify (this, event, data);
- ret = 0;
- goto out;
- }
- }
-out:
- return ret;
-}
-
-int
-reconfigure (xlator_t *this, dict_t *options)
-{
- barrier_priv_t *priv = NULL;
- gf_boolean_t past = _gf_false;
- int ret = -1;
- gf_boolean_t barrier_enabled = _gf_false;
- uint32_t timeout = {0,};
- struct list_head queue = {0,};
-
- priv = this->private;
- GF_ASSERT (priv);
-
- GF_OPTION_RECONF ("barrier", barrier_enabled, options, bool, out);
- GF_OPTION_RECONF ("barrier-timeout", timeout, options, time, out);
-
- INIT_LIST_HEAD (&queue);
-
- LOCK (&priv->lock);
- {
- past = priv->barrier_enabled;
-
- switch (past) {
- case _gf_false:
- if (barrier_enabled) {
- ret = __barrier_enable (this, priv);
- if (ret) {
- goto unlock;
- }
- }
- break;
-
- case _gf_true:
- if (!barrier_enabled) {
- __barrier_disable (this, &queue);
-
- }
- break;
- }
- priv->timeout.tv_sec = timeout;
- ret = 0;
- }
-unlock:
- UNLOCK (&priv->lock);
-
- if (!list_empty (&queue))
- barrier_dequeue_all (this, &queue);
-
-out:
- return ret;
-}
-
-int32_t
-mem_acct_init (xlator_t *this)
-{
- int ret = -1;
-
- ret = xlator_mem_acct_init (this, gf_barrier_mt_end + 1);
- if (ret)
- gf_log (this->name, GF_LOG_ERROR, "Memory accounting "
- "initialization failed.");
-
- return ret;
-}
-
-int
-init (xlator_t *this)
-{
- int ret = -1;
- barrier_priv_t *priv = NULL;
- uint32_t timeout = {0,};
-
- if (!this->children || this->children->next) {
- gf_log (this->name, GF_LOG_ERROR,
- "'barrier' 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_barrier_mt_priv_t);
- if (!priv)
- goto out;
-
- LOCK_INIT (&priv->lock);
-
- GF_OPTION_INIT ("barrier", priv->barrier_enabled, bool, out);
- GF_OPTION_INIT ("barrier-timeout", timeout, time, out);
- priv->timeout.tv_sec = timeout;
-
- INIT_LIST_HEAD (&priv->queue);
-
- if (priv->barrier_enabled) {
- ret = __barrier_enable (this, priv);
- if (ret == -1)
- goto out;
- }
-
- this->private = priv;
- ret = 0;
-out:
- return ret;
-}
-
-void
-fini (xlator_t *this)
-{
- barrier_priv_t *priv = NULL;
- struct list_head queue = {0,};
-
- priv = this->private;
- if (!priv)
- goto out;
-
- INIT_LIST_HEAD (&queue);
-
- gf_log (this->name, GF_LOG_INFO, "Disabling barriering and dequeuing "
- "all the queued fops");
- LOCK (&priv->lock);
- {
- __barrier_disable (this, &queue);
- }
- UNLOCK (&priv->lock);
-
- if (!list_empty (&queue))
- barrier_dequeue_all (this, &queue);
-
- this->private = NULL;
-
- LOCK_DESTROY (&priv->lock);
- GF_FREE (priv);
-out:
- return;
-}
-
-static void
-barrier_dump_stub (call_stub_t *stub, char *prefix)
-{
- char key[GF_DUMP_MAX_BUF_LEN] = {0,};
-
- gf_proc_dump_build_key (key, prefix, "fop");
- gf_proc_dump_write (key, "%s", gf_fop_list[stub->fop]);
-
- gf_proc_dump_build_key (key, prefix, "gfid");
- gf_proc_dump_write (key, "%s", uuid_utoa (stub->args.loc.gfid));
-
- if (stub->args.loc.path) {
- gf_proc_dump_build_key (key, prefix, "path");
- gf_proc_dump_write (key, "%s", stub->args.loc.path);
- }
- if (stub->args.loc.name) {
- gf_proc_dump_build_key (key, prefix, "name");
- gf_proc_dump_write (key, "%s", stub->args.loc.name);
- }
-
- return;
-}
-
-static void
-__barrier_dump_queue (barrier_priv_t *priv)
-{
- call_stub_t *stub = NULL;
- char key[GF_DUMP_MAX_BUF_LEN] = {0,};
- int i = 0;
-
- GF_VALIDATE_OR_GOTO ("barrier", priv, out);
-
- list_for_each_entry (stub, &priv->queue, list) {
- snprintf (key, sizeof (key), "stub.%d", i++);
- gf_proc_dump_add_section (key);
- barrier_dump_stub(stub, key);
- }
-
-out:
- return;
-}
-
-int
-barrier_dump_priv (xlator_t *this)
-{
- int ret = -1;
- char key[GF_DUMP_MAX_BUF_LEN] = {0,};
- barrier_priv_t *priv = NULL;
-
- GF_VALIDATE_OR_GOTO ("barrier", this, out);
-
- priv = this->private;
- if (!priv)
- return 0;
-
- gf_proc_dump_build_key (key, "xlator.features.barrier", "priv");
- gf_proc_dump_add_section (key);
-
- LOCK (&priv->lock);
- {
- gf_proc_dump_build_key (key, "barrier", "enabled");
- gf_proc_dump_write (key, "%d", priv->barrier_enabled);
- gf_proc_dump_build_key (key, "barrier", "timeout");
- gf_proc_dump_write (key, "%"PRId64, priv->timeout.tv_sec);
- if (priv->barrier_enabled) {
- gf_proc_dump_build_key (key, "barrier", "queue_size");
- gf_proc_dump_write (key, "%d", priv->queue_size);
- __barrier_dump_queue (priv);
- }
- }
- UNLOCK (&priv->lock);
-
-out:
- return ret;
-}
-
-struct xlator_fops fops = {
-
- /* Barrier Class fops */
- .rmdir = barrier_rmdir,
- .unlink = barrier_unlink,
- .rename = barrier_rename,
- .removexattr = barrier_removexattr,
- .fremovexattr = barrier_fremovexattr,
- .truncate = barrier_truncate,
- .ftruncate = barrier_ftruncate,
- .fsync = barrier_fsync,
-
- /* Writes with only O_SYNC flag */
- .writev = barrier_writev,
-};
-
-struct xlator_dumpops dumpops = {
- .priv = barrier_dump_priv,
-};
-
-struct xlator_cbks cbks;
-
-struct volume_options options[] = {
- { .key = {"barrier"},
- .type = GF_OPTION_TYPE_BOOL,
- .default_value = "off",
- .description = "When \"on\", blocks acknowledgements to application "
- "for file operations such as rmdir, rename, unlink, "
- "removexattr, fremovexattr, truncate, ftruncate, "
- "write (with O_SYNC), fsync. It is turned \"off\" by "
- "default."
- },
- { .key = {"barrier-timeout"},
- .type = GF_OPTION_TYPE_TIME,
- .default_value = BARRIER_TIMEOUT,
- .description = "After 'timeout' seconds since the time 'barrier' "
- "option was set to \"on\", acknowledgements to file "
- "operations are no longer blocked and previously "
- "blocked acknowledgements are sent to the application"
- },
- { .key = {NULL} },
-};
diff --git a/xlators/features/barrier/src/barrier.h b/xlators/features/barrier/src/barrier.h
deleted file mode 100644
index 8face9f6512..00000000000
--- a/xlators/features/barrier/src/barrier.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- Copyright (c) 2014 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 __BARRIER_H__
-#define __BARRIER_H__
-
-#include "barrier-mem-types.h"
-#include "xlator.h"
-#include "timer.h"
-#include "call-stub.h"
-
-#define BARRIER_SAFE_ASSIGN(lock, to, value) \
- do { \
- LOCK (&(lock)); \
- { \
- to = value; \
- } \
- UNLOCK (&(lock)); \
- } while (0)
-
-#define BARRIER_FOP_CBK(fop_name, label, frame, this, params ...) \
- do { \
- barrier_priv_t *_priv = NULL; \
- call_stub_t *_stub = NULL; \
- gf_boolean_t _barrier_enabled= _gf_false; \
- struct list_head queue = {0, }; \
- \
- INIT_LIST_HEAD (&queue); \
- \
- _priv = this->private; \
- GF_ASSERT (_priv); \
- \
- LOCK (&_priv->lock); \
- { \
- if (_priv->barrier_enabled) { \
- _barrier_enabled = _priv->barrier_enabled;\
- \
- _stub = fop_##fop_name##_cbk_stub \
- (frame, \
- default_##fop_name##_cbk_resume,\
- params); \
- if (!_stub) { \
- __barrier_disable (this, &queue);\
- goto unlock; \
- } \
- \
- __barrier_enqueue (this, _stub); \
- } \
- } \
-unlock: \
- UNLOCK (&_priv->lock); \
- \
- if (_stub) \
- goto label; \
- \
- if (_barrier_enabled && !_stub) { \
- gf_log (this->name, GF_LOG_CRITICAL, \
- "Failed to barrier FOPs, disabling " \
- "barrier. FOP: %s, ERROR: %s", \
- #fop_name, strerror (ENOMEM)); \
- barrier_dequeue_all (this, &queue); \
- } \
- \
- STACK_UNWIND_STRICT (fop_name, frame, params); \
- goto label; \
- } while (0)
-
-typedef struct {
- gf_timer_t *timer;
- gf_boolean_t barrier_enabled;
- gf_lock_t lock;
- struct list_head queue;
- struct timespec timeout;
- uint32_t queue_size;
-} barrier_priv_t;
-
-int __barrier_enable (xlator_t *this, barrier_priv_t *priv);
-void __barrier_enqueue (xlator_t *this, call_stub_t *stub);
-void __barrier_disable (xlator_t *this, struct list_head *queue);
-void barrier_timeout (void *data);
-void barrier_dequeue_all (xlator_t *this, struct list_head *queue);
-call_stub_t *__barrier_dequeue (xlator_t *this, struct list_head *queue);
-
-#endif
diff --git a/xlators/features/changelog/Makefile.am b/xlators/features/changelog/Makefile.am
deleted file mode 100644
index 153bb685076..00000000000
--- a/xlators/features/changelog/Makefile.am
+++ /dev/null
@@ -1,3 +0,0 @@
-SUBDIRS = src lib
-
-CLEANFILES =
diff --git a/xlators/features/changelog/lib/Makefile.am b/xlators/features/changelog/lib/Makefile.am
deleted file mode 100644
index a985f42a877..00000000000
--- a/xlators/features/changelog/lib/Makefile.am
+++ /dev/null
@@ -1,3 +0,0 @@
-SUBDIRS = src
-
-CLEANFILES =
diff --git a/xlators/features/changelog/lib/examples/c/get-changes.c b/xlators/features/changelog/lib/examples/c/get-changes.c
deleted file mode 100644
index 6d0d0357db9..00000000000
--- a/xlators/features/changelog/lib/examples/c/get-changes.c
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- Copyright (c) 2013 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.
-*/
-
-/**
- * get set of new changes every 10 seconds (just print the file names)
- *
- * Compile it using:
- * gcc -o getchanges `pkg-config --cflags libgfchangelog` get-changes.c \
- * `pkg-config --libs libgfchangelog`
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <sys/un.h>
-#include <limits.h>
-#include <sys/socket.h>
-#include <sys/types.h>
-#include <errno.h>
-
-#include "changelog.h"
-
-#define handle_error(fn) \
- printf ("%s (reason: %s)\n", fn, strerror (errno))
-
-int
-main (int argc, char ** argv)
-{
- int i = 0;
- int ret = 0;
- ssize_t nr_changes = 0;
- ssize_t changes = 0;
- char fbuf[PATH_MAX] = {0,};
-
- /* get changes for brick "/home/vshankar/export/yow/yow-1" */
- ret = gf_changelog_register ("/home/vshankar/exports/yow/yow-1",
- "/tmp/scratch", "/tmp/change.log", 9, 5);
- if (ret) {
- handle_error ("register failed");
- goto out;
- }
-
- while (1) {
- i = 0;
- nr_changes = gf_changelog_scan ();
- if (nr_changes < 0) {
- handle_error ("scan(): ");
- break;
- }
-
- if (nr_changes == 0)
- goto next;
-
- printf ("Got %ld changelog files\n", nr_changes);
-
- while ( (changes =
- gf_changelog_next_change (fbuf, PATH_MAX)) > 0) {
- printf ("changelog file [%d]: %s\n", ++i, fbuf);
-
- /* process changelog */
- /* ... */
- /* ... */
- /* ... */
- /* done processing */
-
- ret = gf_changelog_done (fbuf);
- if (ret)
- handle_error ("gf_changelog_done");
- }
-
- if (changes == -1)
- handle_error ("gf_changelog_next_change");
-
- next:
- sleep (10);
- }
-
- out:
- return ret;
-}
diff --git a/xlators/features/changelog/lib/examples/c/get-history.c b/xlators/features/changelog/lib/examples/c/get-history.c
deleted file mode 100644
index 33eb8c32d4d..00000000000
--- a/xlators/features/changelog/lib/examples/c/get-history.c
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- Copyright (c) 2013 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.
-*/
-
-/**
- * get set of new changes every 10 seconds (just print the file names)
- *
- * Compile it using:
- * gcc -o gethistory `pkg-config --cflags libgfchangelog` get-history.c \
- * `pkg-config --libs libgfchangelog`
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <sys/un.h>
-#include <limits.h>
-#include <sys/socket.h>
-#include <sys/types.h>
-#include <errno.h>
-
-#include "changelog.h"
-
-#define handle_error(fn) \
- printf ("%s (reason: %s)\n", fn, strerror (errno))
-
-int
-main (int argc, char ** argv)
-{
- int i = 0;
- int ret = 0;
- ssize_t nr_changes = 0;
- ssize_t changes = 0;
- char fbuf[PATH_MAX] = {0,};
- unsigned long end_ts = 0;
-
- ret = gf_changelog_register ("/export1/v1/b1",
- "/tmp/scratch_v1", "/tmp/scratch_v1/changes.log",
- 9, 5);
- if (ret) {
- handle_error ("register failed");
- goto out;
- }
-
- int a, b;
- printf ("give the two numbers start and end\t");
- scanf ("%d%d", &a, &b);
- ret = gf_history_changelog ("/export1/v1/b1/.glusterfs/changelogs",a, b, 3, &end_ts);
- if (ret == -1) {
- printf ("history failed");
- goto out;
- }
-
- printf ("end time till when changelog available : %d , ret(%d) \t", end_ts, ret);
- fflush(stdout);
-
- while (1) {
- nr_changes = gf_history_changelog_scan ();
- printf ("scanned, nr_changes : %d\n",nr_changes);
- if (nr_changes < 0) {
- handle_error ("scan(): ");
- break;
- }
-
- if (nr_changes == 0) {
- printf ("done scanning \n");
- goto out;
- }
-
- printf ("Got %ld changelog files\n", nr_changes);
-
- while ( (changes =
- gf_history_changelog_next_change (fbuf, PATH_MAX)) > 0) {
- printf ("changelog file [%d]: %s\n", ++i, fbuf);
-
- /* process changelog */
- /* ... */
- /* ... */
- /* ... */
- /* done processing */
-
- ret = gf_history_changelog_done (fbuf);
- if (ret)
- handle_error ("gf_changelog_done");
- }
- /*
- if (changes == -1)
- handle_error ("gf_changelog_next_change");
- if (nr_changes ==1){
- printf("continue scanning\n");
- }
-
- if(nr_changes == 0){
- printf("done scanning \n");
- goto out;
- }
- */
- }
-
-
-out:
- return ret;
-}
diff --git a/xlators/features/changelog/lib/examples/python/changes.py b/xlators/features/changelog/lib/examples/python/changes.py
deleted file mode 100644
index d21db8eab2e..00000000000
--- a/xlators/features/changelog/lib/examples/python/changes.py
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/usr/bin/python
-
-import os
-import sys
-import time
-import libgfchangelog
-
-cl = libgfchangelog.Changes()
-
-def get_changes(brick, scratch_dir, log_file, log_level, interval):
- change_list = []
- try:
- cl.cl_register(brick, scratch_dir, log_file, log_level)
- while True:
- cl.cl_scan()
- change_list = cl.cl_getchanges()
- if change_list:
- print change_list
- for change in change_list:
- print('done with %s' % (change))
- cl.cl_done(change)
- time.sleep(interval)
- except OSError:
- ex = sys.exc_info()[1]
- print ex
-
-if __name__ == '__main__':
- if len(sys.argv) != 5:
- print("usage: %s <brick> <scratch-dir> <log-file> <fetch-interval>"
- % (sys.argv[0]))
- sys.exit(1)
- get_changes(sys.argv[1], sys.argv[2], sys.argv[3], 9, int(sys.argv[4]))
diff --git a/xlators/features/changelog/lib/examples/python/libgfchangelog.py b/xlators/features/changelog/lib/examples/python/libgfchangelog.py
deleted file mode 100644
index 68ec3baf144..00000000000
--- a/xlators/features/changelog/lib/examples/python/libgfchangelog.py
+++ /dev/null
@@ -1,64 +0,0 @@
-import os
-from ctypes import *
-from ctypes.util import find_library
-
-class Changes(object):
- libgfc = CDLL(find_library("gfchangelog"), use_errno=True)
-
- @classmethod
- def geterrno(cls):
- return get_errno()
-
- @classmethod
- def raise_oserr(cls):
- errn = cls.geterrno()
- raise OSError(errn, os.strerror(errn))
-
- @classmethod
- def _get_api(cls, call):
- return getattr(cls.libgfc, call)
-
- @classmethod
- def cl_register(cls, brick, path, log_file, log_level, retries = 0):
- ret = cls._get_api('gf_changelog_register')(brick, path,
- log_file, log_level, retries)
- if ret == -1:
- cls.raise_oserr()
-
- @classmethod
- def cl_scan(cls):
- ret = cls._get_api('gf_changelog_scan')()
- if ret == -1:
- cls.raise_oserr()
-
- @classmethod
- def cl_startfresh(cls):
- ret = cls._get_api('gf_changelog_start_fresh')()
- if ret == -1:
- cls.raise_oserr()
-
- @classmethod
- def cl_getchanges(cls):
- """ remove hardcoding for path name length """
- def clsort(f):
- return f.split('.')[-1]
- changes = []
- buf = create_string_buffer('\0', 4096)
- call = cls._get_api('gf_changelog_next_change')
-
- while True:
- ret = call(buf, 4096)
- if ret in (0, -1):
- break;
- changes.append(buf.raw[:ret-1])
- if ret == -1:
- cls.raise_oserr()
- # cleanup tracker
- cls.cl_startfresh()
- return sorted(changes, key=clsort)
-
- @classmethod
- def cl_done(cls, clfile):
- ret = cls._get_api('gf_changelog_done')(clfile)
- if ret == -1:
- cls.raise_oserr()
diff --git a/xlators/features/changelog/lib/src/Makefile.am b/xlators/features/changelog/lib/src/Makefile.am
deleted file mode 100644
index 1ae919bfb38..00000000000
--- a/xlators/features/changelog/lib/src/Makefile.am
+++ /dev/null
@@ -1,37 +0,0 @@
-libgfchangelog_la_CFLAGS = -Wall $(GF_CFLAGS) $(GF_DARWIN_LIBGLUSTERFS_CFLAGS) \
- -DDATADIR=\"$(localstatedir)\"
-
-libgfchangelog_la_CPPFLAGS = $(GF_CPPFLAGS) -D__USE_FILE_OFFSET64 -fpic \
- -I../../../src/ -I$(top_srcdir)/libglusterfs/src \
- -I$(top_srcdir)/xlators/features/changelog/src \
- -DDATADIR=\"$(localstatedir)\"
-
-libgfchangelog_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la
-
-libgfchangelog_la_LDFLAGS = $(GF_LDFLAGS) -version-info $(LIBGFCHANGELOG_LT_VERSION)
-
-libgfchangelogdir = $(includedir)/glusterfs/gfchangelog
-lib_LTLIBRARIES = libgfchangelog.la
-
-CONTRIB_BUILDDIR = $(top_builddir)/contrib
-
-libgfchangelog_la_SOURCES = gf-changelog.c gf-changelog-process.c \
- gf-changelog-helpers.c gf-history-changelog.c \
- $(CONTRIBDIR)/uuid/clear.c \
- $(CONTRIBDIR)/uuid/copy.c $(CONTRIBDIR)/uuid/gen_uuid.c \
- $(CONTRIBDIR)/uuid/pack.c $(CONTRIBDIR)/uuid/parse.c \
- $(CONTRIBDIR)/uuid/unparse.c $(CONTRIBDIR)/uuid/uuid_time.c \
- $(CONTRIBDIR)/uuid/compare.c $(CONTRIBDIR)/uuid/isnull.c \
- $(CONTRIBDIR)/uuid/unpack.c
-
-noinst_HEADERS = gf-changelog-helpers.h $(CONTRIBDIR)/uuid/uuidd.h \
- $(CONTRIBDIR)/uuid/uuid.h $(CONTRIBDIR)/uuid/uuidP.h \
- $(CONTRIB_BUILDDIR)/uuid/uuid_types.h
-
-libgfchangelog_HEADERS = changelog.h
-
-CLEANFILES =
-CONFIG_CLEAN_FILES = $(CONTRIB_BUILDDIR)/uuid/uuid_types.h
-
-$(top_builddir)/libglusterfs/src/libglusterfs.la:
- $(MAKE) -C $(top_builddir)/libglusterfs/src/ all
diff --git a/xlators/features/changelog/lib/src/changelog.h b/xlators/features/changelog/lib/src/changelog.h
deleted file mode 100644
index 5cddfb5839c..00000000000
--- a/xlators/features/changelog/lib/src/changelog.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- Copyright (c) 2013 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 _GF_CHANGELOG_H
-#define _GF_CHANGELOG_H
-
-/* API set */
-
-int
-gf_changelog_register (char *brick_path, char *scratch_dir,
- char *log_file, int log_levl, int max_reconnects);
-ssize_t
-gf_changelog_scan ();
-
-int
-gf_changelog_start_fresh ();
-
-ssize_t
-gf_changelog_next_change (char *bufptr, size_t maxlen);
-
-int
-gf_changelog_done (char *file);
-
-#endif
diff --git a/xlators/features/changelog/lib/src/gf-changelog-helpers.c b/xlators/features/changelog/lib/src/gf-changelog-helpers.c
deleted file mode 100644
index f071b057d59..00000000000
--- a/xlators/features/changelog/lib/src/gf-changelog-helpers.c
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- Copyright (c) 2013 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 "changelog-mem-types.h"
-#include "gf-changelog-helpers.h"
-
-ssize_t gf_changelog_read_path (int fd, char *buffer, size_t bufsize)
-{
- return read (fd, buffer, bufsize);
-}
-
-size_t
-gf_changelog_write (int fd, char *buffer, size_t len)
-{
- ssize_t size = 0;
- size_t written = 0;
-
- while (written < len) {
- size = write (fd,
- buffer + written, len - written);
- if (size <= 0)
- break;
-
- written += size;
- }
-
- return written;
-}
-
-void
-gf_rfc3986_encode (unsigned char *s, char *enc, char *estr)
-{
- for (; *s; s++) {
- if (estr[*s])
- sprintf(enc, "%c", estr[*s]);
- else
- sprintf(enc, "%%%02X", *s);
- while (*++enc);
- }
-}
-
-/**
- * thread safe version of readline with buffering
- * (taken from Unix Network Programming Volume I, W.R. Stevens)
- *
- * This is favoured over fgets() as we'd need to ftruncate()
- * (see gf_changelog_scan() API) to record new changelog files.
- * stream open functions does have a truncate like api (although
- * that can be done via @fflush(fp), @ftruncate(fd) and @fseek(fp),
- * but this involves mixing POSIX file descriptors and stream FILE *).
- *
- * NOTE: This implmentation still does work with more than one fd's
- * used to perform gf_readline(). For this very reason it's not
- * made a part of libglusterfs.
- */
-
-static pthread_key_t rl_key;
-static pthread_once_t rl_once = PTHREAD_ONCE_INIT;
-
-static void
-readline_destructor (void *ptr)
-{
- GF_FREE (ptr);
-}
-
-static void
-readline_once (void)
-{
- pthread_key_create (&rl_key, readline_destructor);
-}
-
-static ssize_t
-my_read (read_line_t *tsd, int fd, char *ptr)
-{
- if (tsd->rl_cnt <= 0) {
- if ( (tsd->rl_cnt = read (fd, tsd->rl_buf, MAXLINE)) < 0 )
- return -1;
- else if (tsd->rl_cnt == 0)
- return 0;
- tsd->rl_bufptr = tsd->rl_buf;
- }
-
- tsd->rl_cnt--;
- *ptr = *tsd->rl_bufptr++;
- return 1;
-}
-
-static int
-gf_readline_init_once (read_line_t **tsd)
-{
- if (pthread_once (&rl_once, readline_once) != 0)
- return -1;
-
- *tsd = pthread_getspecific (rl_key);
- if (*tsd)
- goto out;
-
- *tsd = GF_CALLOC (1, sizeof (**tsd),
- gf_changelog_mt_libgfchangelog_rl_t);
- if (!*tsd)
- return -1;
-
- if (pthread_setspecific (rl_key, *tsd) != 0)
- return -1;
-
- out:
- return 0;
-}
-
-ssize_t
-gf_readline (int fd, void *vptr, size_t maxlen)
-{
- size_t n = 0;
- size_t rc = 0;
- char c = ' ';
- char *ptr = NULL;
- read_line_t *tsd = NULL;
-
- if (gf_readline_init_once (&tsd))
- return -1;
-
- ptr = vptr;
- for (n = 1; n < maxlen; n++) {
- if ( (rc = my_read (tsd, fd, &c)) == 1 ) {
- *ptr++ = c;
- if (c == '\n')
- break;
- } else if (rc == 0) {
- *ptr = '\0';
- return (n - 1);
- } else
- return -1;
- }
-
- *ptr = '\0';
- return n;
-
-}
-
-off_t
-gf_lseek (int fd, off_t offset, int whence)
-{
- off_t off = 0;
- read_line_t *tsd = NULL;
-
- if (gf_readline_init_once (&tsd))
- return -1;
-
- if ( (off = lseek (fd, offset, whence)) == -1)
- return -1;
-
- tsd->rl_cnt = 0;
- tsd->rl_bufptr = tsd->rl_buf;
-
- return off;
-}
-
-int
-gf_ftruncate (int fd, off_t length)
-{
- read_line_t *tsd = NULL;
-
- if (gf_readline_init_once (&tsd))
- return -1;
-
- if (ftruncate (fd, 0))
- return -1;
-
- tsd->rl_cnt = 0;
- tsd->rl_bufptr = tsd->rl_buf;
-
- return 0;
-}
diff --git a/xlators/features/changelog/lib/src/gf-changelog-helpers.h b/xlators/features/changelog/lib/src/gf-changelog-helpers.h
deleted file mode 100644
index 9b875d45dcc..00000000000
--- a/xlators/features/changelog/lib/src/gf-changelog-helpers.h
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- Copyright (c) 2013 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 _GF_CHANGELOG_HELPERS_H
-#define _GF_CHANGELOG_HELPERS_H
-
-#include <unistd.h>
-#include <dirent.h>
-#include <limits.h>
-#include <pthread.h>
-
-#include <xlator.h>
-
-#define GF_CHANGELOG_TRACKER "tracker"
-
-#define GF_CHANGELOG_CURRENT_DIR ".current"
-#define GF_CHANGELOG_PROCESSED_DIR ".processed"
-#define GF_CHANGELOG_PROCESSING_DIR ".processing"
-#define GF_CHANGELOG_HISTORY_DIR ".history"
-#define TIMESTAMP_LENGTH 10
-
-#ifndef MAXLINE
-#define MAXLINE 4096
-#endif
-
-#define GF_CHANGELOG_FILL_BUFFER(ptr, ascii, off, len) do { \
- memcpy (ascii + off, ptr, len); \
- off += len; \
- } while (0)
-
-typedef struct read_line {
- int rl_cnt;
- char *rl_bufptr;
- char rl_buf[MAXLINE];
-} read_line_t;
-
-typedef struct gf_changelog {
- xlator_t *this;
-
- /* 'processing' directory stream */
- DIR *gfc_dir;
-
- /* fd to the tracker file */
- int gfc_fd;
-
- /* connection retries */
- int gfc_connretries;
-
- char gfc_sockpath[UNIX_PATH_MAX];
-
- char gfc_brickpath[PATH_MAX];
-
- /* socket for receiving notifications */
- int gfc_sockfd;
-
- char *gfc_working_dir;
-
- /* RFC 3986 string encoding */
- char rfc3986[256];
-
- char gfc_current_dir[PATH_MAX];
- char gfc_processed_dir[PATH_MAX];
- char gfc_processing_dir[PATH_MAX];
-
- pthread_t gfc_changelog_processor;
-
- /* Holds gfc for History API */
- struct gf_changelog *hist_gfc;
-
- /* holds 0 done scanning, 1 keep scanning and -1 error */
- int hist_done;
-} gf_changelog_t;
-
-typedef struct gf_changelog_history_data {
- int len;
-
- int htime_fd;
-
- /* parallelism count */
- int n_parallel;
-
- /* history from, to indexes */
- unsigned long from;
- unsigned long to;
-} gf_changelog_history_data_t;
-
-typedef struct gf_changelog_consume_data {
- /** set of inputs */
-
- /* fd to read from */
- int fd;
-
- /* from @offset */
- off_t offset;
-
- xlator_t *this;
- gf_changelog_t *gfc;
-
- /** set of outputs */
-
- /* return value */
- int retval;
-
- /* journal processed */
- char changelog[PATH_MAX];
-} gf_changelog_consume_data_t;
-
-int
-gf_changelog_notification_init (xlator_t *this, gf_changelog_t *gfc);
-
-void *
-gf_changelog_process (void *data);
-
-ssize_t
-gf_changelog_read_path (int fd, char *buffer, size_t bufsize);
-
-void
-gf_rfc3986_encode (unsigned char *s, char *enc, char *estr);
-
-size_t
-gf_changelog_write (int fd, char *buffer, size_t len);
-
-ssize_t
-gf_readline (int fd, void *vptr, size_t maxlen);
-
-int
-gf_ftruncate (int fd, off_t length);
-
-off_t
-gf_lseek (int fd, off_t offset, int whence);
-
-int
-gf_changelog_consume (xlator_t *this,
- gf_changelog_t *gfc,
- char *from_path, gf_boolean_t no_publish);
-int
-gf_changelog_publish (xlator_t *this, gf_changelog_t *gfc, char *from_path);
-
-#endif
diff --git a/xlators/features/changelog/lib/src/gf-changelog-process.c b/xlators/features/changelog/lib/src/gf-changelog-process.c
deleted file mode 100644
index 83f8928de6d..00000000000
--- a/xlators/features/changelog/lib/src/gf-changelog-process.c
+++ /dev/null
@@ -1,657 +0,0 @@
-/*
- Copyright (c) 2013 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 <unistd.h>
-#include <pthread.h>
-
-#include "uuid.h"
-#include "globals.h"
-#include "glusterfs.h"
-
-#include "gf-changelog-helpers.h"
-
-/* from the changelog translator */
-#include "changelog-misc.h"
-
-extern int byebye;
-
-/**
- * number of gfid records after fop number
- */
-int nr_gfids[] = {
- [GF_FOP_MKNOD] = 1,
- [GF_FOP_MKDIR] = 1,
- [GF_FOP_UNLINK] = 1,
- [GF_FOP_RMDIR] = 1,
- [GF_FOP_SYMLINK] = 1,
- [GF_FOP_RENAME] = 2,
- [GF_FOP_LINK] = 1,
- [GF_FOP_CREATE] = 1,
-};
-
-int nr_extra_recs[] = {
- [GF_FOP_MKNOD] = 3,
- [GF_FOP_MKDIR] = 3,
- [GF_FOP_UNLINK] = 0,
- [GF_FOP_RMDIR] = 0,
- [GF_FOP_SYMLINK] = 0,
- [GF_FOP_RENAME] = 0,
- [GF_FOP_LINK] = 0,
- [GF_FOP_CREATE] = 3,
-};
-
-static char *
-binary_to_ascii (uuid_t uuid)
-{
- return uuid_utoa (uuid);
-}
-
-static char *
-conv_noop (char *ptr) { return ptr; }
-
-#define VERIFY_SEPARATOR(ptr, plen, perr) \
- { \
- if (*(ptr + plen) != '\0') { \
- perr = 1; \
- break; \
- } \
- }
-
-#define MOVER_MOVE(mover, nleft, bytes) \
- { \
- mover += bytes; \
- nleft -= bytes; \
- } \
-
-#define PARSE_GFID(mov, ptr, le, fn, perr) \
- { \
- VERIFY_SEPARATOR (mov, le, perr); \
- ptr = fn (mov); \
- if (!ptr) { \
- perr = 1; \
- break; \
- } \
- }
-
-#define FILL_AND_MOVE(pt, buf, of, mo, nl, le) \
- { \
- GF_CHANGELOG_FILL_BUFFER (pt, buf, of, strlen (pt)); \
- MOVER_MOVE (mo, nl, le); \
- }
-
-
-#define PARSE_GFID_MOVE(ptr, uuid, mover, nleft, perr) \
- { \
- memcpy (uuid, mover, sizeof (uuid_t)); \
- ptr = binary_to_ascii (uuid); \
- if (!ptr) { \
- perr = 1; \
- break; \
- } \
- MOVER_MOVE (mover, nleft, sizeof (uuid_t)); \
- } \
-
-#define LINE_BUFSIZE 3*PATH_MAX /* enough buffer for extra chars too */
-
-/**
- * using mmap() makes parsing easy. fgets() cannot be used here as
- * the binary gfid could contain a line-feed (0x0A), in that case fgets()
- * would read an incomplete line and parsing would fail. using POSIX fds
- * would result is additional code to maintain state in case of partial
- * reads of data (where multiple entries do not fit extirely in the buffer).
- *
- * mmap() gives the flexibility of pointing to an offset in the file
- * without us worrying about reading it in memory (VM does that for us for
- * free).
- */
-
-static int
-gf_changelog_parse_binary (xlator_t *this,
- gf_changelog_t *gfc, int from_fd, int to_fd,
- size_t start_offset, struct stat *stbuf)
-
-{
- int ret = -1;
- off_t off = 0;
- off_t nleft = 0;
- uuid_t uuid = {0,};
- char *ptr = NULL;
- char *bname_start = NULL;
- char *bname_end = NULL;
- char *mover = NULL;
- char *start = NULL;
- char current_mover = ' ';
- size_t blen = 0;
- int parse_err = 0;
- char ascii[LINE_BUFSIZE] = {0,};
-
- nleft = stbuf->st_size;
-
- start = (char *) mmap (NULL, nleft,
- PROT_READ, MAP_PRIVATE, from_fd, 0);
- if (!start) {
- gf_log (this->name, GF_LOG_ERROR,
- "mmap() error (reason: %s)", strerror (errno));
- goto out;
- }
-
- mover = start;
-
- MOVER_MOVE (mover, nleft, start_offset);
-
- while (nleft > 0) {
-
- off = blen = 0;
- ptr = bname_start = bname_end = NULL;
-
- current_mover = *mover;
-
- switch (current_mover) {
- case 'D':
- case 'M':
- MOVER_MOVE (mover, nleft, 1);
- PARSE_GFID_MOVE (ptr, uuid, mover, nleft, parse_err);
-
- break;
-
- case 'E':
- MOVER_MOVE (mover, nleft, 1);
- PARSE_GFID_MOVE (ptr, uuid, mover, nleft, parse_err);
-
- bname_start = mover;
- if ( (bname_end = strchr (mover, '\n')) == NULL ) {
- parse_err = 1;
- break;
- }
-
- blen = bname_end - bname_start;
- MOVER_MOVE (mover, nleft, blen);
-
- break;
-
- default:
- parse_err = 1;
- }
-
- if (parse_err)
- break;
-
- GF_CHANGELOG_FILL_BUFFER (&current_mover, ascii, off, 1);
- GF_CHANGELOG_FILL_BUFFER (" ", ascii, off, 1);
- GF_CHANGELOG_FILL_BUFFER (ptr, ascii, off, strlen (ptr));
- if (blen)
- GF_CHANGELOG_FILL_BUFFER (bname_start,
- ascii, off, blen);
- GF_CHANGELOG_FILL_BUFFER ("\n", ascii, off, 1);
-
- if (gf_changelog_write (to_fd, ascii, off) != off) {
- gf_log (this->name, GF_LOG_ERROR,
- "processing binary changelog failed due to "
- " error in writing ascii change (reason: %s)",
- strerror (errno));
- break;
- }
-
- MOVER_MOVE (mover, nleft, 1);
- }
-
- if ( (nleft == 0) && (!parse_err))
- ret = 0;
-
- if (munmap (start, stbuf->st_size))
- gf_log (this->name, GF_LOG_ERROR,
- "munmap() error (reason: %s)", strerror (errno));
- out:
- return ret;
-}
-
-/**
- * ascii decoder:
- * - separate out one entry from another
- * - use fop name rather than fop number
- */
-static int
-gf_changelog_parse_ascii (xlator_t *this,
- gf_changelog_t *gfc, int from_fd, int to_fd,
- size_t start_offset, struct stat *stbuf)
-{
- int ng = 0;
- int ret = -1;
- int fop = 0;
- int len = 0;
- off_t off = 0;
- off_t nleft = 0;
- char *ptr = NULL;
- char *eptr = NULL;
- char *start = NULL;
- char *mover = NULL;
- int parse_err = 0;
- char current_mover = ' ';
- char ascii[LINE_BUFSIZE] = {0,};
- const char *fopname = NULL;
-
- nleft = stbuf->st_size;
-
- start = (char *) mmap (NULL, nleft,
- PROT_READ, MAP_PRIVATE, from_fd, 0);
- if (!start) {
- gf_log (this->name, GF_LOG_ERROR,
- "mmap() error (reason: %s)", strerror (errno));
- goto out;
- }
-
- mover = start;
-
- MOVER_MOVE (mover, nleft, start_offset);
-
- while (nleft > 0) {
- off = 0;
- current_mover = *mover;
-
- GF_CHANGELOG_FILL_BUFFER (&current_mover, ascii, off, 1);
- GF_CHANGELOG_FILL_BUFFER (" ", ascii, off, 1);
-
- switch (current_mover) {
- case 'D':
- MOVER_MOVE (mover, nleft, 1);
-
- /* target gfid */
- PARSE_GFID (mover, ptr, UUID_CANONICAL_FORM_LEN,
- conv_noop, parse_err);
- FILL_AND_MOVE(ptr, ascii, off,
- mover, nleft, UUID_CANONICAL_FORM_LEN);
- break;
- case 'M':
- MOVER_MOVE (mover, nleft, 1);
-
- /* target gfid */
- PARSE_GFID (mover, ptr, UUID_CANONICAL_FORM_LEN,
- conv_noop, parse_err);
- FILL_AND_MOVE (ptr, ascii, off,
- mover, nleft, UUID_CANONICAL_FORM_LEN);
- FILL_AND_MOVE (" ", ascii, off, mover, nleft, 1);
-
- /* fop */
- len = strlen (mover);
- VERIFY_SEPARATOR (mover, len, parse_err);
-
- fop = atoi (mover);
- if ( (fopname = gf_fop_list[fop]) == NULL) {
- parse_err = 1;
- break;
- }
-
- MOVER_MOVE (mover, nleft, len);
-
- len = strlen (fopname);
- GF_CHANGELOG_FILL_BUFFER (fopname, ascii, off, len);
-
- break;
-
- case 'E':
- MOVER_MOVE (mover, nleft, 1);
-
- /* target gfid */
- PARSE_GFID (mover, ptr, UUID_CANONICAL_FORM_LEN,
- conv_noop, parse_err);
- FILL_AND_MOVE (ptr, ascii, off,
- mover, nleft, UUID_CANONICAL_FORM_LEN);
- FILL_AND_MOVE (" ", ascii, off,
- mover, nleft, 1);
-
- /* fop */
- len = strlen (mover);
- VERIFY_SEPARATOR (mover, len, parse_err);
-
- fop = atoi (mover);
- if ( (fopname = gf_fop_list[fop]) == NULL) {
- parse_err = 1;
- break;
- }
-
- MOVER_MOVE (mover, nleft, len);
-
- len = strlen (fopname);
- GF_CHANGELOG_FILL_BUFFER (fopname, ascii, off, len);
-
- ng = nr_extra_recs[fop];
- for (;ng > 0; ng--) {
- MOVER_MOVE (mover, nleft, 1);
- len = strlen (mover);
- VERIFY_SEPARATOR (mover, len, parse_err);
-
- GF_CHANGELOG_FILL_BUFFER (" ", ascii, off, 1);
- FILL_AND_MOVE (mover, ascii,
- off, mover, nleft, len);
- }
-
- /* pargfid + bname */
- ng = nr_gfids[fop];
- while (ng-- > 0) {
- MOVER_MOVE (mover, nleft, 1);
- len = strlen (mover);
- GF_CHANGELOG_FILL_BUFFER (" ", ascii, off, 1);
-
- PARSE_GFID (mover, ptr, len,
- conv_noop, parse_err);
- eptr = calloc (3, strlen (ptr));
- if (!eptr) {
- parse_err = 1;
- break;
- }
-
- gf_rfc3986_encode ((unsigned char *) ptr,
- eptr, gfc->rfc3986);
- FILL_AND_MOVE (eptr, ascii, off,
- mover, nleft, len);
- free (eptr);
- }
-
- break;
- default:
- parse_err = 1;
- }
-
- if (parse_err)
- break;
-
- GF_CHANGELOG_FILL_BUFFER ("\n", ascii, off, 1);
-
- if (gf_changelog_write (to_fd, ascii, off) != off) {
- gf_log (this->name, GF_LOG_ERROR,
- "processing ascii changelog failed due to "
- " error in writing change (reason: %s)",
- strerror (errno));
- break;
- }
-
- MOVER_MOVE (mover, nleft, 1);
-
- }
-
- if ( (nleft == 0) && (!parse_err))
- ret = 0;
-
- if (munmap (start, stbuf->st_size))
- gf_log (this->name, GF_LOG_ERROR,
- "munmap() error (reason: %s)", strerror (errno));
-
- out:
- return ret;
-}
-
-#define COPY_BUFSIZE 8192
-static int
-gf_changelog_copy (xlator_t *this, int from_fd, int to_fd)
-{
- ssize_t size = 0;
- char buffer[COPY_BUFSIZE+1] = {0,};
-
- while (1) {
- size = read (from_fd, buffer, COPY_BUFSIZE);
- if (size <= 0)
- break;
-
- if (gf_changelog_write (to_fd,
- buffer, size) != size) {
- gf_log (this->name, GF_LOG_ERROR,
- "error processing ascii changlog");
- size = -1;
- break;
- }
- }
-
- return (size < 0 ? -1 : 0);
-}
-
-static int
-gf_changelog_decode (xlator_t *this, gf_changelog_t *gfc, int from_fd,
- int to_fd, struct stat *stbuf, int *zerob)
-{
- int ret = -1;
- int encoding = -1;
- size_t elen = 0;
- char buffer[1024] = {0,};
-
- CHANGELOG_GET_ENCODING (from_fd, buffer, 1024, encoding, elen);
- if (encoding == -1) /* unknown encoding */
- goto out;
-
- if (!CHANGELOG_VALID_ENCODING (encoding))
- goto out;
-
- if (elen == stbuf->st_size) {
- *zerob = 1;
- goto out;
- }
-
- /**
- * start processing after the header
- */
- lseek (from_fd, elen, SEEK_SET);
-
- switch (encoding) {
- case CHANGELOG_ENCODE_BINARY:
- /**
- * this ideally should have been a part of changelog-encoders.c
- * (ie. part of the changelog translator).
- */
- ret = gf_changelog_parse_binary (this, gfc, from_fd,
- to_fd, elen, stbuf);
- break;
-
- case CHANGELOG_ENCODE_ASCII:
- ret = gf_changelog_parse_ascii (this, gfc, from_fd,
- to_fd, elen, stbuf);
- break;
- default:
- ret = gf_changelog_copy (this, from_fd, to_fd);
- }
-
- out:
- return ret;
-}
-
-int
-gf_changelog_publish (xlator_t *this, gf_changelog_t *gfc, char *from_path)
-{
- int ret = 0;
- char dest[PATH_MAX] = {0,};
- char to_path[PATH_MAX] = {0,};
- struct stat stbuf = {0,};
-
- (void) snprintf (to_path, PATH_MAX, "%s%s",
- gfc->gfc_current_dir, basename (from_path));
-
- /* handle zerob file that wont exist in current */
- ret = stat (to_path, &stbuf);
- if (ret){
- if (errno == ENOENT)
- ret = 0;
- goto out;
- }
-
- (void) snprintf (dest, PATH_MAX, "%s%s",
- gfc->gfc_processing_dir, basename (from_path));
-
- ret = rename (to_path, dest);
- if (ret){
- gf_log (this->name, GF_LOG_ERROR,
- "error moving %s to processing dir"
- " (reason: %s)", to_path, strerror (errno));
- }
-
-out:
- return ret;
-}
-
-int
-gf_changelog_consume (xlator_t *this,
- gf_changelog_t *gfc,
- char *from_path, gf_boolean_t no_publish)
-{
- int ret = -1;
- int fd1 = 0;
- int fd2 = 0;
- int zerob = 0;
- struct stat stbuf = {0,};
- char dest[PATH_MAX] = {0,};
- char to_path[PATH_MAX] = {0,};
-
- ret = stat (from_path, &stbuf);
- if (ret || !S_ISREG(stbuf.st_mode)) {
- ret = -1;
- gf_log (this->name, GF_LOG_ERROR,
- "stat failed on changelog file: %s", from_path);
- goto out;
- }
-
- fd1 = open (from_path, O_RDONLY);
- if (fd1 < 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "cannot open changelog file: %s (reason: %s)",
- from_path, strerror (errno));
- goto out;
- }
-
- (void) snprintf (to_path, PATH_MAX, "%s%s",
- gfc->gfc_current_dir, basename (from_path));
- (void) snprintf (dest, PATH_MAX, "%s%s",
- gfc->gfc_processing_dir, basename (from_path));
-
- fd2 = open (to_path, O_CREAT | O_TRUNC | O_RDWR,
- S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
- if (fd2 < 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "cannot create ascii changelog file %s (reason %s)",
- to_path, strerror (errno));
- goto close_fd;
- } else {
- ret = gf_changelog_decode (this, gfc, fd1,
- fd2, &stbuf, &zerob);
-
- close (fd2);
-
- if (!ret) {
- /* move it to processing on a successful
- decode */
- if (no_publish == _gf_true)
- goto close_fd;
- ret = rename (to_path, dest);
- if (ret)
- gf_log (this->name, GF_LOG_ERROR,
- "error moving %s to processing dir"
- " (reason: %s)", to_path,
- strerror (errno));
- }
-
- /* remove it from .current if it's an empty file */
- if (zerob) {
- /* zerob changelogs must be unlinked */
- ret = unlink (to_path);
- if (ret)
- gf_log (this->name, GF_LOG_ERROR,
- "could not unlink %s (reason: %s)",
- to_path, strerror (errno));
- }
- }
-
- close_fd:
- close (fd1);
-
- out:
- return ret;
-}
-
-static char *
-gf_changelog_ext_change (xlator_t *this,
- gf_changelog_t *gfc, char *path, size_t readlen)
-{
- int alo = 0;
- int ret = 0;
- size_t len = 0;
- char *buf = NULL;
-
- buf = path;
- while (len < readlen) {
- if (*buf == '\0') {
- alo = 1;
- gf_log (this->name, GF_LOG_DEBUG,
- "processing changelog: %s", path);
- ret = gf_changelog_consume (this, gfc, path, _gf_false);
- }
-
- if (ret)
- break;
-
- len++; buf++;
- if (alo) {
- alo = 0;
- path = buf;
- }
- }
-
- return (ret) ? NULL : path;
-}
-
-void *
-gf_changelog_process (void *data)
-{
- ssize_t len = 0;
- ssize_t offlen = 0;
- xlator_t *this = NULL;
- char *sbuf = NULL;
- gf_changelog_t *gfc = NULL;
- char from_path[PATH_MAX] = {0,};
-
- gfc = (gf_changelog_t *) data;
- this = gfc->this;
-
- pthread_detach (pthread_self());
-
- for (;;) {
- len = gf_changelog_read_path (gfc->gfc_sockfd,
- from_path + offlen,
- PATH_MAX - offlen);
- if (len < 0)
- continue; /* ignore it for now */
-
- if (len == 0) { /* close() from the changelog translator */
- gf_log (this->name, GF_LOG_INFO, "close from changelog"
- " notification translator.");
-
- if (gfc->gfc_connretries != 1) {
- if (!gf_changelog_notification_init(this, gfc))
- continue;
- }
-
- byebye = 1;
- break;
- }
-
- len += offlen;
- sbuf = gf_changelog_ext_change (this, gfc, from_path, len);
- if (!sbuf) {
- gf_log (this->name, GF_LOG_ERROR,
- "could not extract changelog filename");
- continue;
- }
-
- offlen = 0;
- if (sbuf != (from_path + len)) {
- offlen = from_path + len - sbuf;
- memmove (from_path, sbuf, offlen);
- }
- }
-
- gf_log (this->name, GF_LOG_DEBUG,
- "byebye (%d) from processing thread...", byebye);
- return NULL;
-}
diff --git a/xlators/features/changelog/lib/src/gf-changelog.c b/xlators/features/changelog/lib/src/gf-changelog.c
deleted file mode 100644
index f3f6ffbe976..00000000000
--- a/xlators/features/changelog/lib/src/gf-changelog.c
+++ /dev/null
@@ -1,584 +0,0 @@
-/*
- Copyright (c) 2013 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 <errno.h>
-#include <dirent.h>
-#include <stddef.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-
-#ifndef _GNU_SOURCE
-#define _GNU_SOURCE
-#endif
-#include <string.h>
-
-#include "globals.h"
-#include "glusterfs.h"
-#include "logging.h"
-#include "defaults.h"
-
-#include "gf-changelog-helpers.h"
-
-/* from the changelog translator */
-#include "changelog-misc.h"
-#include "changelog-mem-types.h"
-
-int byebye = 0;
-
-static void
-gf_changelog_cleanup (gf_changelog_t *gfc)
-{
- /* socket */
- if (gfc->gfc_sockfd != -1)
- close (gfc->gfc_sockfd);
- /* tracker fd */
- if (gfc->gfc_fd != -1)
- close (gfc->gfc_fd);
- /* processing dir */
- if (gfc->gfc_dir)
- closedir (gfc->gfc_dir);
-
- if (gfc->gfc_working_dir)
- free (gfc->gfc_working_dir); /* allocated by realpath */
-}
-
-void
-__attribute__ ((constructor)) gf_changelog_ctor (void)
-{
- glusterfs_ctx_t *ctx = NULL;
-
- ctx = glusterfs_ctx_new ();
- if (!ctx)
- return;
-
- if (glusterfs_globals_init (ctx)) {
- free (ctx);
- ctx = NULL;
- return;
- }
-
- THIS->ctx = ctx;
- if (xlator_mem_acct_init (THIS, gf_changelog_mt_end))
- return;
-}
-
-void
-__attribute__ ((destructor)) gf_changelog_dtor (void)
-{
- xlator_t *this = NULL;
- glusterfs_ctx_t *ctx = NULL;
- gf_changelog_t *gfc = NULL;
-
- this = THIS;
- if (!this)
- return;
-
- ctx = this->ctx;
- gfc = this->private;
-
- if (gfc) {
- if (gfc->hist_gfc) {
- gf_changelog_cleanup(gfc->hist_gfc);
- GF_FREE (gfc->hist_gfc);
- }
- gf_changelog_cleanup (gfc);
- GF_FREE (gfc);
- }
-
- if (ctx) {
- pthread_mutex_destroy (&ctx->lock);
- free (ctx);
- ctx = NULL;
- }
-}
-
-
-static int
-gf_changelog_open_dirs (gf_changelog_t *gfc)
-{
- int ret = -1;
- DIR *dir = NULL;
- int tracker_fd = 0;
- char tracker_path[PATH_MAX] = {0,};
-
- (void) snprintf (gfc->gfc_current_dir, PATH_MAX,
- "%s/"GF_CHANGELOG_CURRENT_DIR"/",
- gfc->gfc_working_dir);
- ret = mkdir_p (gfc->gfc_current_dir, 0600, _gf_false);
- if (ret)
- goto out;
-
- (void) snprintf (gfc->gfc_processed_dir, PATH_MAX,
- "%s/"GF_CHANGELOG_PROCESSED_DIR"/",
- gfc->gfc_working_dir);
- ret = mkdir_p (gfc->gfc_processed_dir, 0600, _gf_false);
- if (ret)
- goto out;
-
- (void) snprintf (gfc->gfc_processing_dir, PATH_MAX,
- "%s/"GF_CHANGELOG_PROCESSING_DIR"/",
- gfc->gfc_working_dir);
- ret = mkdir_p (gfc->gfc_processing_dir, 0600, _gf_false);
- if (ret)
- goto out;
-
- dir = opendir (gfc->gfc_processing_dir);
- if (!dir) {
- gf_log ("", GF_LOG_ERROR,
- "opendir() error [reason: %s]", strerror (errno));
- goto out;
- }
-
- gfc->gfc_dir = dir;
-
- (void) snprintf (tracker_path, PATH_MAX,
- "%s/"GF_CHANGELOG_TRACKER, gfc->gfc_working_dir);
-
- tracker_fd = open (tracker_path, O_CREAT | O_APPEND | O_RDWR,
- S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
- if (tracker_fd < 0) {
- closedir (gfc->gfc_dir);
- ret = -1;
- goto out;
- }
-
- gfc->gfc_fd = tracker_fd;
- ret = 0;
- out:
- return ret;
-}
-
-int
-gf_changelog_notification_init (xlator_t *this, gf_changelog_t *gfc)
-{
- int ret = 0;
- int len = 0;
- int tries = 0;
- int sockfd = 0;
- struct sockaddr_un remote;
-
- this = gfc->this;
-
- if (gfc->gfc_sockfd != -1) {
- gf_log (this->name, GF_LOG_INFO,
- "Reconnecting...");
- close (gfc->gfc_sockfd);
- }
-
- sockfd = socket (AF_UNIX, SOCK_STREAM, 0);
- if (sockfd < 0) {
- ret = -1;
- goto out;
- }
-
- CHANGELOG_MAKE_SOCKET_PATH (gfc->gfc_brickpath,
- gfc->gfc_sockpath, UNIX_PATH_MAX);
- gf_log (this->name, GF_LOG_INFO,
- "connecting to changelog socket: %s (brick: %s)",
- gfc->gfc_sockpath, gfc->gfc_brickpath);
-
- remote.sun_family = AF_UNIX;
- strcpy (remote.sun_path, gfc->gfc_sockpath);
-
- len = strlen (remote.sun_path) + sizeof (remote.sun_family);
-
- while (tries < gfc->gfc_connretries) {
- gf_log (this->name, GF_LOG_WARNING,
- "connection attempt %d/%d...",
- tries + 1, gfc->gfc_connretries);
-
- /* initiate a connect */
- if (connect (sockfd, (struct sockaddr *) &remote, len) == 0) {
- gfc->gfc_sockfd = sockfd;
- break;
- }
-
- tries++;
- sleep (2);
- }
-
- if (tries == gfc->gfc_connretries) {
- gf_log (this->name, GF_LOG_ERROR,
- "could not connect to changelog socket!"
- " bailing out...");
- close (sockfd);
- ret = -1;
- } else
- gf_log (this->name, GF_LOG_INFO,
- "connection successful");
-
- out:
- return ret;
-}
-
-int
-gf_changelog_done (char *file)
-{
- int ret = -1;
- char *buffer = NULL;
- xlator_t *this = NULL;
- gf_changelog_t *gfc = NULL;
- char to_path[PATH_MAX] = {0,};
-
- errno = EINVAL;
-
- this = THIS;
- if (!this)
- goto out;
-
- gfc = (gf_changelog_t *) this->private;
- if (!gfc)
- goto out;
-
- if (!file || !strlen (file))
- goto out;
-
- /* make sure 'file' is inside ->gfc_working_dir */
- buffer = realpath (file, NULL);
- if (!buffer)
- goto out;
-
- if (strncmp (gfc->gfc_working_dir,
- buffer, strlen (gfc->gfc_working_dir)))
- goto out;
-
- (void) snprintf (to_path, PATH_MAX, "%s%s",
- gfc->gfc_processed_dir, basename (buffer));
- gf_log (this->name, GF_LOG_DEBUG,
- "moving %s to processed directory", file);
- ret = rename (buffer, to_path);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "cannot move %s to %s (reason: %s)",
- file, to_path, strerror (errno));
- goto out;
- }
-
- ret = 0;
-
- out:
- if (buffer)
- free (buffer); /* allocated by realpath() */
- return ret;
-}
-
-/**
- * @API
- * for a set of changelogs, start from the beginning
- */
-int
-gf_changelog_start_fresh ()
-{
- xlator_t *this = NULL;
- gf_changelog_t *gfc = NULL;
-
- this = THIS;
- if (!this)
- goto out;
-
- errno = EINVAL;
-
- gfc = (gf_changelog_t *) this->private;
- if (!gfc)
- goto out;
-
- if (gf_ftruncate (gfc->gfc_fd, 0))
- goto out;
-
- return 0;
-
- out:
- return -1;
-}
-
-/**
- * @API
- * return the next changelog file entry. zero means all chanelogs
- * consumed.
- */
-ssize_t
-gf_changelog_next_change (char *bufptr, size_t maxlen)
-{
- ssize_t size = -1;
- int tracker_fd = 0;
- xlator_t *this = NULL;
- gf_changelog_t *gfc = NULL;
- char buffer[PATH_MAX] = {0,};
-
- errno = EINVAL;
-
- this = THIS;
- if (!this)
- goto out;
-
- gfc = (gf_changelog_t *) this->private;
- if (!gfc)
- goto out;
-
- tracker_fd = gfc->gfc_fd;
-
- size = gf_readline (tracker_fd, buffer, maxlen);
- if (size < 0) {
- size = -1;
- goto out;
- }
-
- if (size == 0)
- goto out;
-
- memcpy (bufptr, buffer, size - 1);
- bufptr[size - 1] = '\0';
-
-out:
- return size;
-}
-
-/**
- * @API
- * gf_changelog_scan() - scan and generate a list of change entries
- *
- * calling this api multiple times (without calling gf_changlog_done())
- * would result new changelogs(s) being refreshed in the tracker file.
- * This call also acts as a cancellation point for the consumer.
- */
-ssize_t
-gf_changelog_scan ()
-{
- int ret = 0;
- int tracker_fd = 0;
- size_t len = 0;
- size_t off = 0;
- xlator_t *this = NULL;
- size_t nr_entries = 0;
- gf_changelog_t *gfc = NULL;
- struct dirent *entryp = NULL;
- struct dirent *result = NULL;
- char buffer[PATH_MAX] = {0,};
-
- this = THIS;
- if (!this)
- goto out;
-
- gfc = (gf_changelog_t *) this->private;
- if (!gfc)
- goto out;
-
- /**
- * do we need to protect 'byebye' with locks? worst, the
- * consumer would get notified during next scan().
- */
- if (byebye) {
- errno = ECONNREFUSED;
- goto out;
- }
-
- errno = EINVAL;
-
- tracker_fd = gfc->gfc_fd;
-
- if (gf_ftruncate (tracker_fd, 0))
- goto out;
-
- len = offsetof(struct dirent, d_name)
- + pathconf(gfc->gfc_processing_dir, _PC_NAME_MAX) + 1;
- entryp = GF_CALLOC (1, len,
- gf_changelog_mt_libgfchangelog_dirent_t);
- if (!entryp)
- goto out;
-
- rewinddir (gfc->gfc_dir);
- while (1) {
- ret = readdir_r (gfc->gfc_dir, entryp, &result);
- if (ret || !result)
- break;
-
- if ( !strcmp (basename (entryp->d_name), ".")
- || !strcmp (basename (entryp->d_name), "..") )
- continue;
-
- nr_entries++;
-
- GF_CHANGELOG_FILL_BUFFER (gfc->gfc_processing_dir,
- buffer, off,
- strlen (gfc->gfc_processing_dir));
- GF_CHANGELOG_FILL_BUFFER (entryp->d_name, buffer,
- off, strlen (entryp->d_name));
- GF_CHANGELOG_FILL_BUFFER ("\n", buffer, off, 1);
-
- if (gf_changelog_write (tracker_fd, buffer, off) != off) {
- gf_log (this->name, GF_LOG_ERROR,
- "error writing changelog filename"
- " to tracker file");
- break;
- }
- off = 0;
- }
-
- GF_FREE (entryp);
-
- if (!result) {
- if (gf_lseek (tracker_fd, 0, SEEK_SET) != -1)
- return nr_entries;
- }
- out:
- return -1;
-}
-
-/**
- * @API
- * gf_changelog_register() - register a client for updates.
- */
-int
-gf_changelog_register (char *brick_path, char *scratch_dir,
- char *log_file, int log_level, int max_reconnects)
-{
- int i = 0;
- int ret = -1;
- int errn = 0;
- xlator_t *this = NULL;
- gf_changelog_t *gfc = NULL;
- char hist_scratch_dir[PATH_MAX] = {0,};
- struct stat buf = {0,};
-
- this = THIS;
- if (!this->ctx)
- goto out;
-
- errno = ENOMEM;
-
- gfc = GF_CALLOC (1, sizeof (*gfc),
- gf_changelog_mt_libgfchangelog_t);
- if (!gfc)
- goto out;
-
- gfc->this = this;
-
- gfc->gfc_dir = NULL;
- gfc->gfc_fd = gfc->gfc_sockfd = -1;
-
- if (stat (scratch_dir, &buf) && errno == ENOENT) {
- ret = mkdir_p (scratch_dir, 0600, _gf_true);
- if (ret) {
- errn = errno;
- goto cleanup;
- }
- }
-
- gfc->gfc_working_dir = realpath (scratch_dir, NULL);
- if (!gfc->gfc_working_dir) {
- errn = errno;
- goto cleanup;
- }
-
- /* Begin: Changes for History API */
- gfc->hist_gfc = NULL;
-
- gfc->hist_gfc = GF_CALLOC (1, sizeof (*gfc),
- gf_changelog_mt_libgfchangelog_t);
- if (!gfc->hist_gfc)
- goto cleanup;
-
- gfc->hist_gfc->gfc_dir = NULL;
- gfc->hist_gfc->gfc_fd = gfc->hist_gfc->gfc_sockfd = -1;
- gfc->hist_gfc->this = NULL;
-
- (void) strncpy (hist_scratch_dir, scratch_dir, PATH_MAX);
- (void) snprintf (hist_scratch_dir, PATH_MAX,
- "%s/"GF_CHANGELOG_HISTORY_DIR"/",
- gfc->gfc_working_dir);
-
- ret = mkdir_p (hist_scratch_dir, 0600, _gf_false);
- if (ret) {
- errn = errno;
- goto cleanup;
- }
-
- gfc->hist_gfc->gfc_working_dir = realpath (hist_scratch_dir, NULL);
- if (!gfc->hist_gfc->gfc_working_dir) {
- errn = errno;
- goto cleanup;
- }
-
- ret = gf_changelog_open_dirs (gfc->hist_gfc);
- if (ret) {
- errn = errno;
- gf_log (this->name, GF_LOG_ERROR,
- "could not create entries in history scratch dir");
- goto cleanup;
- }
-
- (void) strncpy (gfc->hist_gfc->gfc_brickpath, brick_path, PATH_MAX);
-
- for (i=0; i < 256; i++) {
- gfc->hist_gfc->rfc3986[i] =
- (isalnum(i) || i == '~' ||
- i == '-' || i == '.' || i == '_') ? i : 0;
- }
- /* End: Changes for History API*/
-
- ret = gf_changelog_open_dirs (gfc);
- if (ret) {
- errn = errno;
- gf_log (this->name, GF_LOG_ERROR,
- "could not create entries in scratch dir");
- goto cleanup;
- }
-
- /* passing ident as NULL means to use default ident for syslog */
- if (gf_log_init (this->ctx, log_file, NULL))
- goto cleanup;
-
- gf_log_set_loglevel ((log_level == -1) ? GF_LOG_INFO :
- log_level);
-
- gfc->gfc_connretries = (max_reconnects <= 0) ? 1 : max_reconnects;
- (void) strncpy (gfc->gfc_brickpath, brick_path, PATH_MAX);
-
- ret = gf_changelog_notification_init (this, gfc);
- if (ret) {
- errn = errno;
- goto cleanup;
- }
-
- ret = gf_thread_create (&gfc->gfc_changelog_processor,
- NULL, gf_changelog_process, gfc);
- if (ret) {
- errn = errno;
- gf_log (this->name, GF_LOG_ERROR,
- "error creating changelog processor thread"
- " new changes won't be recorded!!!");
- goto cleanup;
- }
-
- for (i=0; i < 256; i++) {
- gfc->rfc3986[i] =
- (isalnum(i) || i == '~' ||
- i == '-' || i == '.' || i == '_') ? i : 0;
- }
-
- ret = 0;
- this->private = gfc;
-
- goto out;
-
- cleanup:
- if (gfc->hist_gfc) {
- gf_changelog_cleanup (gfc->hist_gfc);
- GF_FREE (gfc->hist_gfc);
- }
- gf_changelog_cleanup (gfc);
- GF_FREE (gfc);
- this->private = NULL;
- errno = errn;
-
- out:
- return ret;
-}
diff --git a/xlators/features/changelog/lib/src/gf-history-changelog.c b/xlators/features/changelog/lib/src/gf-history-changelog.c
deleted file mode 100644
index e7f08b6d663..00000000000
--- a/xlators/features/changelog/lib/src/gf-history-changelog.c
+++ /dev/null
@@ -1,930 +0,0 @@
-#include <errno.h>
-#include <dirent.h>
-#include <stddef.h>
-#include <sys/types.h>
-
-#ifndef _GNU_SOURCE
-#define _GNU_SOURCE
-#endif
-#include <string.h>
-
-#include "globals.h"
-#include "glusterfs.h"
-#include "logging.h"
-#include "syscall.h"
-
-#include "gf-changelog-helpers.h"
-
-/* from the changelog translator */
-#include "changelog-misc.h"
-#include "changelog-mem-types.h"
-
-/**
- * @API
- * gf_history_changelog_done:
- * Move processed history changelog file from .processing
- * to .processed
- *
- * ARGUMENTS:
- * file(IN): path to processed history changelog file in
- * .processing directory.
- *
- * RETURN VALUE:
- * 0: On success.
- * -1: On error.
- */
-int
-gf_history_changelog_done (char *file)
-{
- int ret = -1;
- char *buffer = NULL;
- xlator_t *this = NULL;
- gf_changelog_t *gfc = NULL;
- gf_changelog_t *hist_gfc = NULL;
- char to_path[PATH_MAX] = {0,};
-
- errno = EINVAL;
-
- this = THIS;
- if (!this)
- goto out;
-
- gfc = (gf_changelog_t *) this->private;
- if (!gfc)
- goto out;
-
- hist_gfc = gfc->hist_gfc;
- if (!hist_gfc)
- goto out;
-
- if (!file || !strlen (file))
- goto out;
-
- /* make sure 'file' is inside ->gfc_working_dir */
- buffer = realpath (file, NULL);
- if (!buffer)
- goto out;
-
- if (strncmp (hist_gfc->gfc_working_dir,
- buffer, strlen (hist_gfc->gfc_working_dir)))
- goto out;
-
- (void) snprintf (to_path, PATH_MAX, "%s%s",
- hist_gfc->gfc_processed_dir, basename (buffer));
- gf_log (this->name, GF_LOG_DEBUG,
- "moving %s to processed directory", file);
- ret = rename (buffer, to_path);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "cannot move %s to %s (reason: %s)",
- file, to_path, strerror (errno));
- goto out;
- }
-
- ret = 0;
-
- out:
- if (buffer)
- free (buffer); /* allocated by realpath() */
- return ret;
-}
-
-/**
- * @API
- * gf_history_changelog_start_fresh:
- * For a set of changelogs, start from the begining.
- * It will truncates the history tracker fd.
- *
- * RETURN VALUES:
- * 0: On success.
- * -1: On error.
- */
-int
-gf_history_changelog_start_fresh ()
-{
- xlator_t *this = NULL;
- gf_changelog_t *gfc = NULL;
- gf_changelog_t *hist_gfc = NULL;
-
- this = THIS;
- if (!this)
- goto out;
-
- errno = EINVAL;
-
- gfc = (gf_changelog_t *) this->private;
- if (!gfc)
- goto out;
-
- hist_gfc = gfc->hist_gfc;
- if (!hist_gfc)
- goto out;
-
- if (gf_ftruncate (hist_gfc->gfc_fd, 0))
- goto out;
-
- return 0;
-
- out:
- return -1;
-}
-
-/**
- * @API
- * gf_history_changelog_next_change:
- * Return the next history changelog file entry. Zero means all
- * history chanelogs are consumed.
- *
- * ARGUMENTS:
- * bufptr(OUT): Path to unprocessed history changelog file
- * from tracker file.
- * maxlen(IN): Usually PATH_MAX.
- *
- * RETURN VALUES:
- * size: On success.
- * -1 : On error.
- */
-ssize_t
-gf_history_changelog_next_change (char *bufptr, size_t maxlen)
-{
- ssize_t size = -1;
- int tracker_fd = 0;
- xlator_t *this = NULL;
- gf_changelog_t *gfc = NULL;
- gf_changelog_t *hist_gfc = NULL;
- char buffer[PATH_MAX] = {0,};
-
- errno = EINVAL;
-
- this = THIS;
- if (!this)
- goto out;
-
- gfc = (gf_changelog_t *) this->private;
- if (!gfc)
- goto out;
-
- hist_gfc = gfc->hist_gfc;
- if (!hist_gfc)
- goto out;
-
- tracker_fd = hist_gfc->gfc_fd;
-
- size = gf_readline (tracker_fd, buffer, maxlen);
- if (size < 0) {
- size = -1;
- goto out;
- }
-
- if (size == 0)
- goto out;
-
- memcpy (bufptr, buffer, size - 1);
- bufptr[size - 1] = '\0';
-
-out:
- return size;
-}
-
-/**
- * @API
- * gf_history_changelog_scan:
- * Scan and generate a list of change entries.
- * Calling this api multiple times (without calling gf_changlog_done())
- * would result new changelogs(s) being refreshed in the tracker file.
- * This call also acts as a cancellation point for the consumer.
- *
- * RETURN VALUES:
- * +ve integer : success and keep scanning.(count of changelogs)
- * 0 : success and done scanning.
- * -1 : error.
- *
- * NOTE: After first 0 return call_get_next change for once more time
- * to empty the tracker
- *
- */
-ssize_t
-gf_history_changelog_scan ()
-{
- int ret = 0;
- int tracker_fd = 0;
- size_t len = 0;
- size_t off = 0;
- xlator_t *this = NULL;
- size_t nr_entries = 0;
- gf_changelog_t *gfc = NULL;
- gf_changelog_t *hist_gfc = NULL;
- struct dirent *entryp = NULL;
- struct dirent *result = NULL;
- char buffer[PATH_MAX] = {0,};
- static int is_last_scan = 0;
-
- this = THIS;
- if (!this)
- goto out;
-
- gfc = (gf_changelog_t *) this->private;
- if (!gfc)
- goto out;
-
- hist_gfc = gfc->hist_gfc;
- if (!hist_gfc)
- goto out;
-
- retry:
- if (is_last_scan == 1)
- return 0;
- if (hist_gfc->hist_done == 0)
- is_last_scan = 1;
-
- errno = EINVAL;
- if (hist_gfc->hist_done == -1)
- goto out;
-
- tracker_fd = hist_gfc->gfc_fd;
-
- if (gf_ftruncate (tracker_fd, 0))
- goto out;
-
- len = offsetof (struct dirent, d_name)
- + pathconf (hist_gfc->gfc_processing_dir, _PC_NAME_MAX) + 1;
- entryp = GF_CALLOC (1, len,
- gf_changelog_mt_libgfchangelog_dirent_t);
- if (!entryp)
- goto out;
-
- rewinddir (hist_gfc->gfc_dir);
- while (1) {
- ret = readdir_r (hist_gfc->gfc_dir, entryp, &result);
- if (ret || !result)
- break;
-
- if ( !strcmp (basename (entryp->d_name), ".")
- || !strcmp (basename (entryp->d_name), "..") )
- continue;
-
- nr_entries++;
-
- GF_CHANGELOG_FILL_BUFFER (hist_gfc->gfc_processing_dir,
- buffer, off,
- strlen (hist_gfc->gfc_processing_dir));
- GF_CHANGELOG_FILL_BUFFER (entryp->d_name, buffer,
- off, strlen (entryp->d_name));
- GF_CHANGELOG_FILL_BUFFER ("\n", buffer, off, 1);
-
- if (gf_changelog_write (tracker_fd, buffer, off) != off) {
- gf_log (this->name, GF_LOG_ERROR,
- "error writing changelog filename"
- " to tracker file");
- break;
- }
- off = 0;
- }
-
- GF_FREE (entryp);
-
- gf_log (this->name, GF_LOG_DEBUG,
- "hist_done %d, is_last_scan: %d", hist_gfc->hist_done, is_last_scan);
-
- if (!result) {
- if (gf_lseek (tracker_fd, 0, SEEK_SET) != -1) {
- if (nr_entries > 0)
- return nr_entries;
- else {
- sleep(1);
- goto retry;
- }
- }
- }
- out:
- return -1;
-}
-
-/*
- * Gets timestamp value at the changelog path at index.
- * Returns 0 on success(updates given time-stamp), -1 on failure.
- */
-int
-gf_history_get_timestamp (int fd, int index, int len,
- unsigned long *ts)
-{
- xlator_t *this = NULL;
- int n_read = -1;
- char path_buf[PATH_MAX]= {0,};
- char *iter = path_buf;
- size_t offset = index * (len+1);
- unsigned long value = 0;
- int ret = 0;
-
- this = THIS;
- if (!this) {
- return -1;
- }
-
- n_read = pread (fd, path_buf, len, offset);
- if (n_read < 0 ) {
- ret = -1;
- gf_log ( this->name, GF_LOG_ERROR,
- "could not read from htime file");
- goto out;
- }
- iter+= len - TIMESTAMP_LENGTH;
- sscanf (iter, "%lu",&value);
-out:
- if(ret == 0)
- *ts = value;
- return ret;
-}
-
-/*
- * Function to ensure correctness of search
- * Checks whether @value is there next to @target_index or not
- */
-int
-gf_history_check ( int fd, int target_index, unsigned long value, int len)
-{
- int ret = 0;
- unsigned long ts1 = 0;
- unsigned long ts2 = 0;
-
- if (target_index == 0) {
- ret = gf_history_get_timestamp (fd, target_index, len, &ts1);
- if (ret == -1)
- goto out;
- if (value <= ts1)
- goto out;
- else {
- ret = -1;
- goto out;
- }
- }
-
- ret = gf_history_get_timestamp (fd, target_index, len, &ts1);
- if (ret ==-1)
- goto out;
- ret = gf_history_get_timestamp (fd, target_index -1, len, &ts2);
- if (ret ==-1)
- goto out;
-
- if ( (value <= ts1) && (value > ts2) ) {
- goto out;
- }
- else
- ret = -1;
-out:
- return ret;
-}
-
-/*
- * This is a "binary search" based search function which checks neighbours
- * for in-range availability of the value to be searched and provides the
- * index at which the changelog file nearest to the requested timestamp(value)
- * can be read from.
- *
- * Actual offset can be calculated as (index* (len+1) ).
- * "1" is because the changelog paths are null terminated.
- *
- * @path : Htime file to search in
- * @value : time stamp to search
- * @from : start index to search
- * @to : end index to search
- * @len : length of fixes length strings seperated by null
- */
-
-int
-gf_history_b_search (int fd, unsigned long value,
- unsigned long from, unsigned long to, int len)
-{
- int m_index = -1;
- unsigned long cur_value = 0;
- unsigned long ts1 = 0;
- int ret = 0;
-
- m_index = (from + to)/2;
-
- if ( (to - from) <=1 ) {
- /* either one or 2 changelogs left */
- if ( to != from ) {
- /* check if value is less or greater than to
- * return accordingly
- */
- ret = gf_history_get_timestamp (fd, from, len, &ts1);
- if (ret ==-1)
- goto out;
- if ( ts1 >= value) {
- /* actually compatision should be
- * exactly == but considering
- *
- * case of only 2 changelogs in htime file
- */
- return from;
- }
- else
- return to;
- }
- else
- return to;
- }
-
- ret = gf_history_get_timestamp (fd, m_index, len, &cur_value);
- if (ret == -1)
- goto out;
- if (cur_value == value) {
- return m_index;
- }
- else if (value > cur_value) {
- ret = gf_history_get_timestamp (fd, m_index+1, len, &cur_value);
- if (ret == -1)
- goto out;
- if (value < cur_value)
- return m_index + 1;
- else
- return gf_history_b_search (fd, value,
- m_index+1, to, len);
- }
- else {
- if (m_index ==0) {
- /* we are sure that values exists
- * in this htime file
- */
- return 0;
- }
- else {
- ret = gf_history_get_timestamp (fd, m_index-1, len,
- &cur_value);
- if (ret == -1)
- goto out;
- if (value > cur_value) {
- return m_index;
- }
- else
- return gf_history_b_search (fd, value, from,
- m_index-1, len);
- }
- }
-out:
- return -1;
-}
-
-void *
-gf_changelog_consume_wrap (void* data)
-{
- int ret = -1;
- ssize_t nread = 0;
- xlator_t *this = NULL;
- gf_changelog_consume_data_t *ccd = NULL;
-
- ccd = (gf_changelog_consume_data_t *) data;
- this = ccd->this;
-
- ccd->retval = -1;
-
- nread = pread (ccd->fd, ccd->changelog, PATH_MAX, ccd->offset);
- if (nread < 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "cannot read from history metadata file (reason %s)",
- strerror (errno));
- goto out;
- }
-
- /* TODO: handle short reads and EOF. */
-
- ret = gf_changelog_consume (ccd->this,
- ccd->gfc, ccd->changelog, _gf_true);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "could not parse changelog: %s", ccd->changelog);
- goto out;
- }
-
- ccd->retval = 0;
-
- out:
- return NULL;
-}
-
-/**
- * "gf_history_consume" is a worker function for history.
- * parses and moves changelogs files from index "from"
- * to index "to" in open htime file whose fd is "fd".
- */
-
-#define MAX_PARALLELS 10
-
-void *
-gf_history_consume (void * data)
-{
- xlator_t *this = NULL;
- gf_changelog_t *gfc = NULL;
- gf_changelog_t *hist_gfc = NULL;
- int ret = 0;
- int iter = 0;
- int fd = -1;
- int from = -1;
- int to = -1;
- int len = -1;
- int n_parallel = 0;
- int n_envoked = 0;
- gf_boolean_t publish = _gf_true;
- pthread_t th_id[MAX_PARALLELS] = {0,};
- gf_changelog_history_data_t *hist_data = NULL;
- gf_changelog_consume_data_t ccd[MAX_PARALLELS] = {{0},};
- gf_changelog_consume_data_t *curr = NULL;
-
- hist_data = (gf_changelog_history_data_t *) data;
- if (hist_data == NULL) {
- ret = -1;
- goto out;
- }
-
- fd = hist_data->htime_fd;
- from = hist_data->from;
- to = hist_data->to;
- len = hist_data->len;
- n_parallel = hist_data->n_parallel;
-
- this = THIS;
- if (!this) {
- ret = -1;
- goto out;
- }
-
- gfc = (gf_changelog_t *) this->private;
- if (!gfc) {
- ret = -1;
- goto out;
- }
-
- hist_gfc = gfc->hist_gfc;
- if (!hist_gfc) {
- ret = -1;
- goto out;
- }
-
- while (from <= to) {
- n_envoked = 0;
-
- for (iter = 0 ; (iter < n_parallel) && (from <= to); iter++) {
- curr = &ccd[iter];
-
- curr->this = this;
- curr->gfc = hist_gfc;
- curr->fd = fd;
- curr->offset = from * (len + 1);
-
- curr->retval = 0;
- memset (curr->changelog, '\0', PATH_MAX);
-
- ret = pthread_create (&th_id[iter], NULL,
- gf_changelog_consume_wrap, curr);
- if (ret) {
- gf_log ( this->name, GF_LOG_ERROR,
- "could not create consume-thread"
- " reason (%s)", strerror (ret));
- ret = -1;
- goto sync;
- } else
- n_envoked++;
-
- from++;
- }
-
- sync:
- for (iter = 0; iter < n_envoked; iter++) {
- ret = pthread_join (th_id[iter], NULL);
- if (ret) {
- publish = _gf_false;
- gf_log (this->name, GF_LOG_ERROR,
- "pthread_join() error %s",
- strerror (ret));
- /* try to join the rest */
- continue;
- }
-
- if (publish == _gf_false)
- continue;
-
- curr = &ccd[iter];
- if (ccd->retval) {
- publish = _gf_false;
- gf_log (this->name, GF_LOG_ERROR,
- "parsing error, ceased publishing...");
- continue;
- }
-
- ret = gf_changelog_publish (curr->this,
- curr->gfc, curr->changelog);
- if (ret) {
- publish = _gf_false;
- gf_log (this->name, GF_LOG_ERROR,
- "publish error, ceased publishing...");
- }
- }
- }
-
- /* informing "parsing done". */
- hist_gfc->hist_done = (publish == _gf_true) ? 0 : -1;
-
-out:
- if (fd != -1)
- close (fd);
- GF_FREE (hist_data);
- return NULL;
-}
-
-/**
- * @API
- * gf_history_changelog() : Get/parse historical changelogs and get them ready
- * for consumption.
- *
- * Arguments:
- * @changelog_dir : Directory location from where history changelogs are
- * supposed to be consumed.
- * @start: Unix timestamp FROM where changelogs should be consumed.
- * @end: Unix timestamp TO where changelogsshould be consumed.
- * @n_parallel : degree of parallelism while changelog parsing.
- * @actual_end : the end time till where changelogs are available.
- *
- * Return:
- * Returns <timestamp> on success, the last time till where changelogs are
- * available.
- * Returns -1 on failure(error).
- */
-
-#define MAKE_HTIME_FILE_PATH(htime_file, htime_dir, htime_bname) do { \
- strcpy (htime_file, htime_dir); \
- strcat (htime_file, "/"); \
- strcat (htime_file, htime_bname); \
- } while (0)
-
-/**
- * Extract timestamp range from a historical metadata file
- * Returns:
- * 0 : Success ({min,max}_ts with the appropriate values)
- * -1 : Failure
- * -2 : Ignore this metadata file and process next
- */
-int
-gf_changelog_extract_min_max (const char *dname, const char *htime_dir,
- int *fd, unsigned long *total,
- unsigned long *min_ts, unsigned long *max_ts)
-{
- int ret = -1;
- xlator_t *this = NULL;
- char htime_file[PATH_MAX] = {0,};
- struct stat stbuf = {0,};
- char *iter = NULL;
- char x_value[30] = {0,};
-
- this = THIS;
-
- MAKE_HTIME_FILE_PATH (htime_file, htime_dir, dname);
-
- iter = (htime_file + strlen (htime_file) - TIMESTAMP_LENGTH);
- sscanf (iter ,"%lu",min_ts);
-
- ret = stat (htime_file, &stbuf);
- if (ret) {
- ret = -1;
- gf_log (this->name, GF_LOG_ERROR,
- "stat() failed on htime file %s (reason %s)",
- htime_file, strerror (errno));
- goto out;
- }
-
- /* ignore everything except regular files */
- if (!S_ISREG (stbuf.st_mode)) {
- ret = -2;
- goto out;
- }
-
- *fd = open (htime_file, O_RDONLY);
- if (*fd < 0) {
- ret = -1;
- gf_log (this->name, GF_LOG_ERROR,
- "open() failed for htime %s (reasong %s)",
- htime_file, strerror (errno));
- goto out;
- }
-
- /* Looks good, extract max timestamp */
- ret = sys_fgetxattr (*fd, HTIME_KEY, x_value, sizeof (x_value));
- if (ret < 0) {
- ret = -1;
- gf_log (this->name, GF_LOG_ERROR,
- "error extracting max timstamp from htime file"
- " %s (reason %s)", htime_file, strerror (errno));
- goto out;
- }
-
- sscanf (x_value, "%lu:%lu", max_ts, total);
- gf_log (this->name, GF_LOG_INFO,
- "MIN: %lu, MAX: %lu, TOTAL CHANGELOGS: %lu",
- *min_ts, *max_ts, *total);
-
- ret = 0;
-
- out:
- return ret;
-}
-
-int
-gf_history_changelog (char* changelog_dir, unsigned long start,
- unsigned long end, int n_parallel,
- unsigned long *actual_end)
-{
- int ret = 0;
- int len = -1;
- int fd = -1;
- int n_read = -1;
- unsigned long min_ts = 0;
- unsigned long max_ts = 0;
- unsigned long end2 = 0;
- unsigned long ts1 = 0;
- unsigned long ts2 = 0;
- unsigned long to = 0;
- unsigned long from = 0;
- unsigned long total_changelog = 0;
- xlator_t *this = NULL;
- gf_changelog_t *gfc = NULL;
- gf_changelog_t *hist_gfc = NULL;
- gf_changelog_history_data_t *hist_data = NULL;
- DIR *dirp = NULL;
- struct dirent *dp = NULL;
- pthread_t consume_th = 0;
- char htime_dir[PATH_MAX] = {0,};
- char buffer[PATH_MAX] = {0,};
-
- pthread_attr_t attr;
-
- ret = pthread_attr_init (&attr);
- if (ret != 0) {
- return -1;
- }
-
- this = THIS;
- if (!this) {
- ret = -1;
- goto out;
- }
-
- gfc = (gf_changelog_t *) this->private;
- if (!gfc) {
- ret = -1;
- goto out;
- }
-
- hist_gfc = (gf_changelog_t *) gfc->hist_gfc;
- if (!hist_gfc) {
- ret = -1;
- goto out;
- }
-
- /* basic sanity check */
- if (start > end || n_parallel <= 0) {
- ret = -1;
- goto out;
- }
-
- /* cap parallelism count */
- if (n_parallel > MAX_PARALLELS)
- n_parallel = MAX_PARALLELS;
-
- CHANGELOG_FILL_HTIME_DIR (changelog_dir, htime_dir);
-
- dirp = opendir (htime_dir);
- if (dirp == NULL) {
- gf_log (this->name, GF_LOG_ERROR,
- "open dir on htime failed : %s (reason: %s)",
- htime_dir, strerror (errno));
- ret = -1;
- goto out;
- }
-
- while ((dp = readdir (dirp)) != NULL) {
- ret = gf_changelog_extract_min_max (dp->d_name, htime_dir,
- &fd, &total_changelog,
- &min_ts, &max_ts);
- if (ret) {
- if (-2 == ret)
- continue;
- goto out;
- }
-
- if (start >= min_ts && start < max_ts) {
- /**
- * TODO: handle short reads later...
- */
- n_read = read (fd, buffer, PATH_MAX);
- if (n_read < 0) {
- ret = -1;
- gf_log ( this->name, GF_LOG_ERROR,
- "unable to read htime file");
- goto out;
- }
-
- len = strlen (buffer);
-
- /**
- * search @start in the htime file returning it's index
- * (@from)
- */
- from = gf_history_b_search (fd, start, 0,
- total_changelog - 1, len);
-
- /* ensuring correctness of gf_b_search */
- if (gf_history_check (fd, from, start, len) != 0) {
- ret = -1;
- gf_log (this->name, GF_LOG_ERROR,
- "wrong result for start: %lu idx: %lu",
- start, from);
- goto out;
- }
-
- end2 = (end <= max_ts) ? end : max_ts;
-
- /**
- * search @end2 in htime file returning it's index (@to)
- */
- to = gf_history_b_search (fd, end2,
- 0, total_changelog - 1, len);
-
- if (gf_history_check (fd, to, end2, len) != 0) {
- ret = -1;
- gf_log (this->name, GF_LOG_ERROR,
- "wrong result for start: %lu idx: %lu",
- end2, to);
- goto out;
- }
-
- ret = gf_history_get_timestamp (fd, from, len, &ts1);
- if (ret == -1)
- goto out;
-
- ret = gf_history_get_timestamp (fd, to, len, &ts2);
- if (ret == -1)
- goto out;
-
- gf_log (this->name, GF_LOG_INFO,
- "FINAL: from: %lu, to: %lu, changes: %lu",
- ts1, ts2, (to - from + 1));
-
- hist_data = GF_CALLOC (1,
- sizeof (gf_changelog_history_data_t),
- gf_changelog_mt_history_data_t);
-
- hist_data->htime_fd = fd;
- hist_data->from = from;
- hist_data->to = to;
- hist_data->len = len;
- hist_data->n_parallel = n_parallel;
-
- ret = pthread_attr_setdetachstate
- (&attr, PTHREAD_CREATE_DETACHED);
- if (ret != 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "unable to sets the detach"
- " state attribute, reason(%s)",
- strerror (ret));
- ret = -1;
- goto out;
- }
-
- /* spawn a thread for background parsing & publishing */
- ret = pthread_create (&consume_th, &attr,
- gf_history_consume, hist_data);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "creation of consume parent-thread"
- " failed. reason(%s)", strerror (ret));
- ret = -1;
- goto out;
- }
-
- goto out;
-
- } /* end of range check */
-
- } /* end of readdir() */
-
- if (!from || !to)
- ret = -1;
-
-out:
- if (dirp != NULL)
- closedir (dirp);
-
- if (ret < 0) {
- if (fd != -1)
- close (fd);
- GF_FREE (hist_data);
- (void) pthread_attr_destroy (&attr);
-
- return ret;
- }
-
- hist_gfc->hist_done = 1;
- *actual_end = ts2;
-
- return ret;
-}
diff --git a/xlators/features/changelog/src/Makefile.am b/xlators/features/changelog/src/Makefile.am
deleted file mode 100644
index b7a170ebf07..00000000000
--- a/xlators/features/changelog/src/Makefile.am
+++ /dev/null
@@ -1,20 +0,0 @@
-xlator_LTLIBRARIES = changelog.la
-
-xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/features
-
-noinst_HEADERS = changelog-helpers.h changelog-mem-types.h changelog-rt.h \
- changelog-misc.h changelog-encoders.h changelog-notifier.h
-
-changelog_la_LDFLAGS = -module -avoid-version
-
-changelog_la_SOURCES = changelog.c changelog-rt.c changelog-helpers.c \
- changelog-encoders.c changelog-notifier.c changelog-barrier.c
-changelog_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la
-
-AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src -fPIC \
- -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -D$(GF_HOST_OS) \
- -DDATADIR=\"$(localstatedir)\"
-
-AM_CFLAGS = -Wall $(GF_CFLAGS)
-
-CLEANFILES =
diff --git a/xlators/features/changelog/src/changelog-barrier.c b/xlators/features/changelog/src/changelog-barrier.c
deleted file mode 100644
index 22cfa617e1b..00000000000
--- a/xlators/features/changelog/src/changelog-barrier.c
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- Copyright (c) 2014 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 "changelog-helpers.h"
-#include "call-stub.h"
-
-/* Enqueue a stub*/
-void
-__chlog_barrier_enqueue (xlator_t *this, call_stub_t *stub)
-{
- changelog_priv_t *priv = NULL;
-
- priv = this->private;
- GF_ASSERT (priv);
-
- list_add_tail (&stub->list, &priv->queue);
- priv->queue_size++;
-
- return;
-}
-
-/* Dequeue a stub */
-call_stub_t *
-__chlog_barrier_dequeue (xlator_t *this, struct list_head *queue)
-{
- call_stub_t *stub = NULL;
- changelog_priv_t *priv = NULL;
-
- priv = this->private;
- GF_ASSERT (priv);
-
- if (list_empty (queue))
- goto out;
-
- stub = list_entry (queue->next, call_stub_t, list);
- list_del_init (&stub->list);
-
-out:
- return stub;
-}
-
-/* Dequeue all the stubs and call corresponding resume functions */
-void
-chlog_barrier_dequeue_all (xlator_t *this, struct list_head *queue)
-{
- call_stub_t *stub = NULL;
-
- gf_log (this->name, GF_LOG_INFO,
- "Dequeuing all the changelog barriered fops");
-
- while ((stub = __chlog_barrier_dequeue (this, queue)))
- call_resume (stub);
-
- gf_log (this->name, GF_LOG_INFO,
- "Dequeuing changelog barriered fops is finished");
- return;
-}
-
-/* Function called on changelog barrier timeout */
-void
-chlog_barrier_timeout (void *data)
-{
- xlator_t *this = NULL;
- changelog_priv_t *priv = NULL;
- struct list_head queue = {0,};
-
- this = data;
- THIS = this;
- priv = this->private;
-
- INIT_LIST_HEAD (&queue);
-
- gf_log (this->name, GF_LOG_ERROR,
- "Disabling changelog barrier because of the timeout.");
-
- LOCK (&priv->lock);
- {
- __chlog_barrier_disable (this, &queue);
- }
- UNLOCK (&priv->lock);
-
- chlog_barrier_dequeue_all (this, &queue);
-
- return;
-}
-
-/* Disable changelog barrier enable flag */
-void
-__chlog_barrier_disable (xlator_t *this, struct list_head *queue)
-{
- changelog_priv_t *priv = this->private;
- GF_ASSERT (priv);
-
- if (priv->timer) {
- gf_timer_call_cancel (this->ctx, priv->timer);
- priv->timer = NULL;
- }
-
- list_splice_init (&priv->queue, queue);
- priv->queue_size = 0;
- priv->barrier_enabled = _gf_false;
-}
-
-/* Enable chagelog barrier enable with timer */
-int
-__chlog_barrier_enable (xlator_t *this, changelog_priv_t *priv)
-{
- int ret = -1;
-
- priv->timer = gf_timer_call_after (this->ctx, priv->timeout,
- chlog_barrier_timeout, (void *)this);
- if (!priv->timer) {
- gf_log (this->name, GF_LOG_CRITICAL,
- "Couldn't add changelog barrier timeout event.");
- goto out;
- }
-
- priv->barrier_enabled = _gf_true;
- ret = 0;
-out:
- return ret;
-}
diff --git a/xlators/features/changelog/src/changelog-encoders.c b/xlators/features/changelog/src/changelog-encoders.c
deleted file mode 100644
index 08626ee2f22..00000000000
--- a/xlators/features/changelog/src/changelog-encoders.c
+++ /dev/null
@@ -1,197 +0,0 @@
-/*
- Copyright (c) 2013 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 "changelog-encoders.h"
-
-size_t
-entry_fn (void *data, char *buffer, gf_boolean_t encode)
-{
- char *tmpbuf = NULL;
- size_t bufsz = 0;
- struct changelog_entry_fields *ce = NULL;
-
- ce = (struct changelog_entry_fields *) data;
-
- if (encode) {
- tmpbuf = uuid_utoa (ce->cef_uuid);
- CHANGELOG_FILL_BUFFER (buffer, bufsz, tmpbuf, strlen (tmpbuf));
- } else {
- CHANGELOG_FILL_BUFFER (buffer, bufsz,
- ce->cef_uuid, sizeof (uuid_t));
- }
-
- CHANGELOG_FILL_BUFFER (buffer, bufsz, "/", 1);
- CHANGELOG_FILL_BUFFER (buffer, bufsz,
- ce->cef_bname, strlen (ce->cef_bname));
- return bufsz;
-}
-
-size_t
-fop_fn (void *data, char *buffer, gf_boolean_t encode)
-{
- char buf[10] = {0,};
- size_t bufsz = 0;
- glusterfs_fop_t fop = 0;
-
- fop = *(glusterfs_fop_t *) data;
-
- if (encode) {
- (void) snprintf (buf, sizeof (buf), "%d", fop);
- CHANGELOG_FILL_BUFFER (buffer, bufsz, buf, strlen (buf));
- } else
- CHANGELOG_FILL_BUFFER (buffer, bufsz, &fop, sizeof (fop));
-
- return bufsz;
-}
-
-size_t
-number_fn (void *data, char *buffer, gf_boolean_t encode)
-{
- size_t bufsz = 0;
- unsigned int nr = 0;
- char buf[20] = {0,};
-
- nr = *(unsigned int *) data;
-
- if (encode) {
- (void) snprintf (buf, sizeof (buf), "%u", nr);
- CHANGELOG_FILL_BUFFER (buffer, bufsz, buf, strlen (buf));
- } else
- CHANGELOG_FILL_BUFFER (buffer, bufsz, &nr, sizeof (unsigned int));
-
- return bufsz;
-}
-
-void
-entry_free_fn (void *data)
-{
- changelog_opt_t *co = data;
-
- if (!co)
- return;
-
- GF_FREE (co->co_entry.cef_bname);
-}
-
-/**
- * try to write all data in one shot
- */
-
-static inline void
-changelog_encode_write_xtra (changelog_log_data_t *cld,
- char *buffer, size_t *off, gf_boolean_t encode)
-{
- int i = 0;
- size_t offset = 0;
- void *data = NULL;
- changelog_opt_t *co = NULL;
-
- offset = *off;
-
- co = (changelog_opt_t *) cld->cld_ptr;
-
- for (; i < cld->cld_xtra_records; i++, co++) {
- CHANGELOG_FILL_BUFFER (buffer, offset, "\0", 1);
-
- switch (co->co_type) {
- case CHANGELOG_OPT_REC_FOP:
- data = &co->co_fop;
- break;
- case CHANGELOG_OPT_REC_ENTRY:
- data = &co->co_entry;
- break;
- case CHANGELOG_OPT_REC_UINT32:
- data = &co->co_uint32;
- break;
- }
-
- if (co->co_convert)
- offset += co->co_convert (data,
- buffer + offset, encode);
- else /* no coversion: write it out as it is */
- CHANGELOG_FILL_BUFFER (buffer, offset,
- data, co->co_len);
- }
-
- *off = offset;
-}
-
-int
-changelog_encode_ascii (xlator_t *this, changelog_log_data_t *cld)
-{
- size_t off = 0;
- size_t gfid_len = 0;
- char *gfid_str = NULL;
- char *buffer = NULL;
- changelog_priv_t *priv = NULL;
-
- priv = this->private;
-
- gfid_str = uuid_utoa (cld->cld_gfid);
- gfid_len = strlen (gfid_str);
-
- /* extra bytes for decorations */
- buffer = alloca (gfid_len + cld->cld_ptr_len + 10);
- CHANGELOG_STORE_ASCII (priv, buffer,
- off, gfid_str, gfid_len, cld);
-
- if (cld->cld_xtra_records)
- changelog_encode_write_xtra (cld, buffer, &off, _gf_true);
-
- CHANGELOG_FILL_BUFFER (buffer, off, "\0", 1);
-
- return changelog_write_change (priv, buffer, off);
-}
-
-int
-changelog_encode_binary (xlator_t *this, changelog_log_data_t *cld)
-{
- size_t off = 0;
- char *buffer = NULL;
- changelog_priv_t *priv = NULL;
-
- priv = this->private;
-
- /* extra bytes for decorations */
- buffer = alloca (sizeof (uuid_t) + cld->cld_ptr_len + 10);
- CHANGELOG_STORE_BINARY (priv, buffer, off, cld->cld_gfid, cld);
-
- if (cld->cld_xtra_records)
- changelog_encode_write_xtra (cld, buffer, &off, _gf_false);
-
- CHANGELOG_FILL_BUFFER (buffer, off, "\0", 1);
-
- return changelog_write_change (priv, buffer, off);
-}
-
-static struct changelog_encoder
-cb_encoder[] = {
- [CHANGELOG_ENCODE_BINARY] =
- {
- .encoder = CHANGELOG_ENCODE_BINARY,
- .encode = changelog_encode_binary,
- },
- [CHANGELOG_ENCODE_ASCII] =
- {
- .encoder = CHANGELOG_ENCODE_ASCII,
- .encode = changelog_encode_ascii,
- },
-};
-
-void
-changelog_encode_change( changelog_priv_t * priv)
-{
- priv->ce = &cb_encoder[priv->encode_mode];
-}
diff --git a/xlators/features/changelog/src/changelog-encoders.h b/xlators/features/changelog/src/changelog-encoders.h
deleted file mode 100644
index c5dcc8a77d9..00000000000
--- a/xlators/features/changelog/src/changelog-encoders.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- Copyright (c) 2013 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 _CHANGELOG_ENCODERS_H
-#define _CHANGELOG_ENCODERS_H
-
-#include "xlator.h"
-#include "defaults.h"
-
-#include "changelog-helpers.h"
-
-#define CHANGELOG_STORE_ASCII(priv, buf, off, gfid, gfid_len, cld) do { \
- CHANGELOG_FILL_BUFFER (buffer, off, \
- priv->maps[cld->cld_type], 1); \
- CHANGELOG_FILL_BUFFER (buffer, \
- off, gfid, gfid_len); \
- } while (0)
-
-#define CHANGELOG_STORE_BINARY(priv, buf, off, gfid, cld) do { \
- CHANGELOG_FILL_BUFFER (buffer, off, \
- priv->maps[cld->cld_type], 1); \
- CHANGELOG_FILL_BUFFER (buffer, \
- off, gfid, sizeof (uuid_t)); \
- } while (0)
-
-size_t
-entry_fn (void *data, char *buffer, gf_boolean_t encode);
-size_t
-fop_fn (void *data, char *buffer, gf_boolean_t encode);
-size_t
-number_fn (void *data, char *buffer, gf_boolean_t encode);
-void
-entry_free_fn (void *data);
-int
-changelog_encode_binary (xlator_t *, changelog_log_data_t *);
-int
-changelog_encode_ascii (xlator_t *, changelog_log_data_t *);
-void
-changelog_encode_change(changelog_priv_t *);
-
-#endif /* _CHANGELOG_ENCODERS_H */
diff --git a/xlators/features/changelog/src/changelog-helpers.c b/xlators/features/changelog/src/changelog-helpers.c
deleted file mode 100644
index 9dccf45187c..00000000000
--- a/xlators/features/changelog/src/changelog-helpers.c
+++ /dev/null
@@ -1,1339 +0,0 @@
-/*
- Copyright (c) 2013 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 "xlator.h"
-#include "defaults.h"
-#include "logging.h"
-#include "iobuf.h"
-#include "syscall.h"
-
-#include "changelog-helpers.h"
-#include "changelog-mem-types.h"
-
-#include "changelog-encoders.h"
-#include <pthread.h>
-
-static inline void
-__mask_cancellation (xlator_t *this)
-{
- int ret = 0;
-
- ret = pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, NULL);
- if (ret)
- gf_log (this->name, GF_LOG_WARNING,
- "failed to disable thread cancellation");
-}
-
-static inline void
-__unmask_cancellation (xlator_t *this)
-{
- int ret = 0;
-
- ret = pthread_setcancelstate (PTHREAD_CANCEL_ENABLE, NULL);
- if (ret)
- gf_log (this->name, GF_LOG_WARNING,
- "failed to enable thread cancellation");
-}
-
-static void
-changelog_cleanup_free_mutex (void *arg_mutex)
-{
- pthread_mutex_t *p_mutex = (pthread_mutex_t*) arg_mutex;
-
- if (p_mutex)
- pthread_mutex_unlock(p_mutex);
-}
-
-void
-changelog_thread_cleanup (xlator_t *this, pthread_t thr_id)
-{
- int ret = 0;
- void *retval = NULL;
-
- /* send a cancel request to the thread */
- ret = pthread_cancel (thr_id);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "could not cancel thread (reason: %s)",
- strerror (errno));
- goto out;
- }
-
- ret = pthread_join (thr_id, &retval);
- if (ret || (retval != PTHREAD_CANCELED)) {
- gf_log (this->name, GF_LOG_ERROR,
- "cancel request not adhered as expected"
- " (reason: %s)", strerror (errno));
- }
-
- out:
- return;
-}
-
-inline void *
-changelog_get_usable_buffer (changelog_local_t *local)
-{
- changelog_log_data_t *cld = NULL;
-
- if (!local)
- return NULL;
-
- cld = &local->cld;
- if (!cld->cld_iobuf)
- return NULL;
-
- return cld->cld_iobuf->ptr;
-}
-
-inline void
-changelog_set_usable_record_and_length (changelog_local_t *local,
- size_t len, int xr)
-{
- changelog_log_data_t *cld = NULL;
-
- cld = &local->cld;
-
- cld->cld_ptr_len = len;
- cld->cld_xtra_records = xr;
-}
-
-void
-changelog_local_cleanup (xlator_t *xl, changelog_local_t *local)
-{
- int i = 0;
- changelog_opt_t *co = NULL;
- changelog_log_data_t *cld = NULL;
-
- if (!local)
- return;
-
- cld = &local->cld;
-
- /* cleanup dynamic allocation for extra records */
- if (cld->cld_xtra_records) {
- co = (changelog_opt_t *) cld->cld_ptr;
- for (; i < cld->cld_xtra_records; i++, co++)
- if (co->co_free)
- co->co_free (co);
- }
-
- CHANGELOG_IOBUF_UNREF (cld->cld_iobuf);
-
- if (local->inode)
- inode_unref (local->inode);
-
- mem_put (local);
-}
-
-inline int
-changelog_write (int fd, char *buffer, size_t len)
-{
- ssize_t size = 0;
- size_t written = 0;
-
- while (written < len) {
- size = write (fd,
- buffer + written, len - written);
- if (size <= 0)
- break;
-
- written += size;
- }
-
- return (written != len);
-}
-
-int
-htime_update (xlator_t *this,
- changelog_priv_t *priv, unsigned long ts,
- char * buffer)
-{
- char changelog_path[PATH_MAX+1] = {0,};
- int len = -1;
- char x_value[25] = {0,};
- /* time stamp(10) + : (1) + rolltime (12 ) + buffer (2) */
- int ret = 0;
-
- if (priv->htime_fd ==-1) {
- gf_log (this->name, GF_LOG_ERROR,
- "Htime fd not available for updation");
- ret = -1;
- goto out;
- }
- strcpy (changelog_path, buffer);
- len = strlen (changelog_path);
- changelog_path[len] = '\0'; /* redundant */
-
- if (changelog_write (priv->htime_fd, (void*) changelog_path, len+1 ) < 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "Htime file content write failed");
- ret =-1;
- goto out;
- }
-
- sprintf (x_value,"%lu:%d",ts, priv->rollover_count);
-
- if (sys_fsetxattr (priv->htime_fd, HTIME_KEY, x_value,
- strlen (x_value), XATTR_REPLACE)) {
- gf_log (this->name, GF_LOG_ERROR,
- "Htime xattr updation failed, "
- "reason (%s)",strerror (errno));
- goto out;
- }
-
- priv->rollover_count +=1;
-
-out:
- return ret;
-}
-
-static int
-changelog_rollover_changelog (xlator_t *this,
- changelog_priv_t *priv, unsigned long ts)
-{
- int ret = -1;
- int notify = 0;
- char *bname = NULL;
- char ofile[PATH_MAX] = {0,};
- char nfile[PATH_MAX] = {0,};
-
- if (priv->changelog_fd != -1) {
- ret = fsync (priv->changelog_fd);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "fsync failed (reason: %s)",
- strerror (errno));
- }
- close (priv->changelog_fd);
- priv->changelog_fd = -1;
- }
-
- (void) snprintf (ofile, PATH_MAX,
- "%s/"CHANGELOG_FILE_NAME, priv->changelog_dir);
- (void) snprintf (nfile, PATH_MAX,
- "%s/"CHANGELOG_FILE_NAME".%lu",
- priv->changelog_dir, ts);
-
- ret = rename (ofile, nfile);
- if (!ret)
- notify = 1;
-
- if (ret && (errno == ENOENT)) {
- ret = 0;
- goto out;
- }
-
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "error renaming %s -> %s (reason %s)",
- ofile, nfile, strerror (errno));
- }
-
- if (!ret) {
- ret = htime_update (this, priv, ts, nfile);
- if (ret == -1) {
- gf_log (this->name, GF_LOG_ERROR,
- "could not update htime file");
- goto out;
- }
- }
-
- if (notify) {
- bname = basename (nfile);
- gf_log (this->name, GF_LOG_DEBUG, "notifying: %s", bname);
- ret = changelog_write (priv->wfd, bname, strlen (bname) + 1);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to send file name to notify thread"
- " (reason: %s)", strerror (errno));
- } else {
- /* If this is explicit rollover initiated by snapshot,
- * wakeup reconfigure thread waiting for changelog to
- * rollover
- */
- if (priv->explicit_rollover) {
- priv->explicit_rollover = _gf_false;
- ret = pthread_mutex_lock (
- &priv->bn.bnotify_mutex);
- CHANGELOG_PTHREAD_ERROR_HANDLE_0 (ret, out);
- {
- priv->bn.bnotify = _gf_false;
- ret = pthread_cond_signal (
- &priv->bn.bnotify_cond);
- CHANGELOG_PTHREAD_ERROR_HANDLE_0 (ret,
- out);
- gf_log (this->name, GF_LOG_INFO,
- "Changelog published: %s and"
- " signalled bnotify", bname);
- }
- ret = pthread_mutex_unlock (
- &priv->bn.bnotify_mutex);
- CHANGELOG_PTHREAD_ERROR_HANDLE_0 (ret, out);
- }
- }
- }
-
- out:
- return ret;
-}
-
-/* Returns 0 on successful creation of htime file
- * returns -1 on failure or error
- */
-int
-htime_open (xlator_t *this,
- changelog_priv_t * priv, unsigned long ts)
-{
- int fd = -1;
- int ret = 0;
- char ht_dir_path[PATH_MAX] = {0,};
- char ht_file_path[PATH_MAX] = {0,};
- int flags = 0;
-
- CHANGELOG_FILL_HTIME_DIR(priv->changelog_dir, ht_dir_path);
-
- /* get the htime file name in ht_file_path */
- (void) snprintf (ht_file_path,PATH_MAX,"%s/%s.%lu",ht_dir_path,
- HTIME_FILE_NAME, ts);
-
- flags |= (O_CREAT | O_RDWR | O_SYNC);
- fd = open (ht_file_path, flags,
- S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
- if (fd < 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "unable to open/create htime file: %s"
- "(reason: %s)", ht_file_path, strerror (errno));
- ret = -1;
- goto out;
-
- }
-
- if (sys_fsetxattr (fd, HTIME_KEY, HTIME_INITIAL_VALUE,
- sizeof (HTIME_INITIAL_VALUE)-1, 0)) {
- gf_log (this->name, GF_LOG_ERROR,
- "Htime xattr initialization failed");
- ret = -1;
- goto out;
- }
-
- /* save this htime_fd in priv->htime_fd */
- priv->htime_fd = fd;
- /* initialize rollover-number in priv to 1 */
- priv->rollover_count = 1;
-
-out:
- return ret;
-}
-
-/* Description:
- * Opens the snap changelog to log call path fops in it.
- * This changelos name is "CHANGELOG.SNAP", stored in
- * path ".glusterfs/changelogs/csnap".
- * Returns:
- * 0 : On success.
- * -1 : On failure.
- */
-int
-changelog_snap_open (xlator_t *this,
- changelog_priv_t *priv)
-{
- int fd = -1;
- int ret = 0;
- int flags = 0;
- char buffer[1024] = {0,};
- char c_snap_path[PATH_MAX] = {0,};
- char csnap_dir_path[PATH_MAX] = {0,};
-
- CHANGELOG_FILL_CSNAP_DIR(priv->changelog_dir, csnap_dir_path);
-
- (void) snprintf (c_snap_path, PATH_MAX,
- "%s/"CSNAP_FILE_NAME,
- csnap_dir_path);
-
- flags |= (O_CREAT | O_RDWR | O_TRUNC);
-
- fd = open (c_snap_path, flags,
- S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
- if (fd < 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "unable to open %s file "
- "reason:(%s)", c_snap_path, strerror (errno));
- ret = -1;
- goto out;
- }
- priv->c_snap_fd = fd;
-
- (void) snprintf (buffer, 1024, CHANGELOG_HEADER,
- CHANGELOG_VERSION_MAJOR,
- CHANGELOG_VERSION_MINOR,
- priv->ce->encoder);
- ret = changelog_snap_write_change (priv, buffer, strlen (buffer));
- if (ret < 0) {
- close (priv->c_snap_fd);
- priv->c_snap_fd = -1;
- goto out;
- }
-
-out:
- return ret;
-}
-
-/*
- * Description:
- * Starts logging fop details in CSNAP journal.
- * Returns:
- * 0 : On success.
- * -1 : On Failure.
- */
-int
-changelog_snap_logging_start (xlator_t *this,
- changelog_priv_t *priv)
-{
- int ret = 0;
-
- ret = changelog_snap_open (this, priv);
- gf_log (this->name, GF_LOG_INFO,
- "Now starting to log in call path");
-
- return ret;
-}
-
-/*
- * Description:
- * Stops logging fop details in CSNAP journal.
- * Returns:
- * 0 : On success.
- * -1 : On Failure.
- */
-int
-changelog_snap_logging_stop (xlator_t *this,
- changelog_priv_t *priv)
-{
- int ret = 0;
-
- close (priv->c_snap_fd);
- priv->c_snap_fd = -1;
-
- gf_log (this->name, GF_LOG_INFO,
- "Stopped to log in call path");
-
- return ret;
-}
-
-int
-changelog_open (xlator_t *this,
- changelog_priv_t *priv)
-{
- int fd = 0;
- int ret = -1;
- int flags = 0;
- char buffer[1024] = {0,};
- char changelog_path[PATH_MAX] = {0,};
-
- (void) snprintf (changelog_path, PATH_MAX,
- "%s/"CHANGELOG_FILE_NAME,
- priv->changelog_dir);
-
- flags |= (O_CREAT | O_RDWR);
- if (priv->fsync_interval == 0)
- flags |= O_SYNC;
-
- fd = open (changelog_path, flags,
- S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
- if (fd < 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "unable to open/create changelog file %s"
- " (reason: %s). change-logging will be"
- " inactive", changelog_path, strerror (errno));
- goto out;
- }
-
- priv->changelog_fd = fd;
-
- (void) snprintf (buffer, 1024, CHANGELOG_HEADER,
- CHANGELOG_VERSION_MAJOR,
- CHANGELOG_VERSION_MINOR,
- priv->ce->encoder);
- ret = changelog_write_change (priv, buffer, strlen (buffer));
- if (ret) {
- close (priv->changelog_fd);
- priv->changelog_fd = -1;
- goto out;
- }
-
- ret = 0;
-
- out:
- return ret;
-}
-
-int
-changelog_start_next_change (xlator_t *this,
- changelog_priv_t *priv,
- unsigned long ts, gf_boolean_t finale)
-{
- int ret = -1;
-
- ret = changelog_rollover_changelog (this, priv, ts);
-
- if (!ret && !finale)
- ret = changelog_open (this, priv);
-
- return ret;
-}
-
-/**
- * return the length of entry
- */
-inline size_t
-changelog_entry_length ()
-{
- return sizeof (changelog_log_data_t);
-}
-
-int
-changelog_fill_rollover_data (changelog_log_data_t *cld, gf_boolean_t is_last)
-{
- struct timeval tv = {0,};
-
- cld->cld_type = CHANGELOG_TYPE_ROLLOVER;
-
- if (gettimeofday (&tv, NULL))
- return -1;
-
- cld->cld_roll_time = (unsigned long) tv.tv_sec;
- cld->cld_finale = is_last;
- return 0;
-}
-
-int
-changelog_snap_write_change (changelog_priv_t *priv, char *buffer, size_t len)
-{
- return changelog_write (priv->c_snap_fd, buffer, len);
-}
-
-int
-changelog_write_change (changelog_priv_t *priv, char *buffer, size_t len)
-{
- return changelog_write (priv->changelog_fd, buffer, len);
-}
-
-/*
- * Descriptions:
- * Writes fop details in ascii format to CSNAP.
- * Issues:
- * Not Encoding agnostic.
- * Returns:
- * 0 : On Success.
- * -1 : On Failure.
- */
-int
-changelog_snap_handle_ascii_change (xlator_t *this,
- changelog_log_data_t *cld)
-{
- size_t off = 0;
- size_t gfid_len = 0;
- char *gfid_str = NULL;
- char *buffer = NULL;
- changelog_priv_t *priv = NULL;
- int ret = 0;
-
- if (this == NULL) {
- ret = -1;
- goto out;
- }
-
- priv = this->private;
-
- if (priv == NULL) {
- ret = -1;
- goto out;
- }
-
- gfid_str = uuid_utoa (cld->cld_gfid);
- gfid_len = strlen (gfid_str);
-
- /* extra bytes for decorations */
- buffer = alloca (gfid_len + cld->cld_ptr_len + 10);
- CHANGELOG_STORE_ASCII (priv, buffer,
- off, gfid_str, gfid_len, cld);
-
- CHANGELOG_FILL_BUFFER (buffer, off, "\0", 1);
-
- ret = changelog_snap_write_change (priv, buffer, off);
-
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "error writing csnap to disk");
- }
- gf_log (this->name, GF_LOG_INFO,
- "Successfully wrote to csnap");
- ret = 0;
-out:
- return ret;
-}
-
-inline int
-changelog_handle_change (xlator_t *this,
- changelog_priv_t *priv, changelog_log_data_t *cld)
-{
- int ret = 0;
-
- if (CHANGELOG_TYPE_IS_ROLLOVER (cld->cld_type)) {
- changelog_encode_change (priv);
- ret = changelog_start_next_change (this, priv,
- cld->cld_roll_time,
- cld->cld_finale);
- if (ret)
- gf_log (this->name, GF_LOG_ERROR,
- "Problem rolling over changelog(s)");
- goto out;
- }
-
- /**
- * case when there is reconfigure done (disabling changelog) and there
- * are still fops that have updates in prgress.
- */
- if (priv->changelog_fd == -1)
- return 0;
-
- if (CHANGELOG_TYPE_IS_FSYNC (cld->cld_type)) {
- ret = fsync (priv->changelog_fd);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "fsync failed (reason: %s)",
- strerror (errno));
- }
- goto out;
- }
-
- ret = priv->ce->encode (this, cld);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "error writing changelog to disk");
- }
-
- out:
- return ret;
-}
-
-changelog_local_t *
-changelog_local_init (xlator_t *this, inode_t *inode,
- uuid_t gfid, int xtra_records,
- gf_boolean_t update_flag)
-{
- changelog_local_t *local = NULL;
- struct iobuf *iobuf = NULL;
-
- /**
- * We relax the presence of inode if @update_flag is true.
- * The caller (implmentation of the fop) needs to be careful to
- * not blindly use local->inode.
- */
- if (!update_flag && !inode) {
- gf_log_callingfn (this->name, GF_LOG_WARNING,
- "inode needed for version checking !!!");
- goto out;
- }
-
- if (xtra_records) {
- iobuf = iobuf_get2 (this->ctx->iobuf_pool,
- xtra_records * CHANGELOG_OPT_RECORD_LEN);
- if (!iobuf)
- goto out;
- }
-
- local = mem_get0 (this->local_pool);
- if (!local) {
- CHANGELOG_IOBUF_UNREF (iobuf);
- goto out;
- }
-
- local->update_no_check = update_flag;
-
- uuid_copy (local->cld.cld_gfid, gfid);
-
- local->cld.cld_iobuf = iobuf;
- local->cld.cld_xtra_records = 0; /* set by the caller */
-
- if (inode)
- local->inode = inode_ref (inode);
-
- out:
- return local;
-}
-
-int
-changelog_forget (xlator_t *this, inode_t *inode)
-{
- uint64_t ctx_addr = 0;
- changelog_inode_ctx_t *ctx = NULL;
-
- inode_ctx_del (inode, this, &ctx_addr);
- if (!ctx_addr)
- return 0;
-
- ctx = (changelog_inode_ctx_t *) (long) ctx_addr;
- GF_FREE (ctx);
-
- return 0;
-}
-
-int
-changelog_inject_single_event (xlator_t *this,
- changelog_priv_t *priv,
- changelog_log_data_t *cld)
-{
- return priv->cd.dispatchfn (this, priv, priv->cd.cd_data, cld, NULL);
-}
-
-/* Wait till all the black fops are drained */
-void
-changelog_drain_black_fops (xlator_t *this, changelog_priv_t *priv)
-{
- int ret = 0;
-
- /* clean up framework of pthread_mutex is required here as
- * 'reconfigure' terminates the changelog_rollover thread
- * on graph change.
- */
- pthread_cleanup_push (changelog_cleanup_free_mutex,
- &priv->dm.drain_black_mutex);
- ret = pthread_mutex_lock (&priv->dm.drain_black_mutex);
- if (ret)
- gf_log (this->name, GF_LOG_ERROR, "pthread error:"
- " Error:%d", ret);
- while (priv->dm.black_fop_cnt > 0) {
- gf_log (this->name, GF_LOG_DEBUG,
- "Condtional wait on black fops: %ld",
- priv->dm.black_fop_cnt);
- priv->dm.drain_wait_black = _gf_true;
- ret = pthread_cond_wait (&priv->dm.drain_black_cond,
- &priv->dm.drain_black_mutex);
- if (ret)
- gf_log (this->name, GF_LOG_ERROR, "pthread"
- " cond wait failed: Error:%d", ret);
- }
- priv->dm.drain_wait_black = _gf_false;
- ret = pthread_mutex_unlock (&priv->dm.drain_black_mutex);
- pthread_cleanup_pop (0);
- if (ret)
- gf_log (this->name, GF_LOG_ERROR, "pthread error:"
- " Error:%d", ret);
- gf_log (this->name, GF_LOG_DEBUG,
- "Woke up: Conditional wait on black fops");
-}
-
-/* Wait till all the white fops are drained */
-void
-changelog_drain_white_fops (xlator_t *this, changelog_priv_t *priv)
-{
- int ret = 0;
-
- /* clean up framework of pthread_mutex is required here as
- * 'reconfigure' terminates the changelog_rollover thread
- * on graph change.
- */
- pthread_cleanup_push (changelog_cleanup_free_mutex,
- &priv->dm.drain_white_mutex);
- ret = pthread_mutex_lock (&priv->dm.drain_white_mutex);
- if (ret)
- gf_log (this->name, GF_LOG_ERROR, "pthread error:"
- " Error:%d", ret);
- while (priv->dm.white_fop_cnt > 0) {
- gf_log (this->name, GF_LOG_DEBUG,
- "Condtional wait on white fops : %ld",
- priv->dm.white_fop_cnt);
- priv->dm.drain_wait_white = _gf_true;
- ret = pthread_cond_wait (&priv->dm.drain_white_cond,
- &priv->dm.drain_white_mutex);
- if (ret)
- gf_log (this->name, GF_LOG_ERROR, "pthread"
- " cond wait failed: Error:%d", ret);
- }
- priv->dm.drain_wait_white = _gf_false;
- ret = pthread_mutex_unlock (&priv->dm.drain_white_mutex);
- if (ret)
- gf_log (this->name, GF_LOG_ERROR, "pthread error:"
- " Error:%d", ret);
- pthread_cleanup_pop (0);
- gf_log (this->name, GF_LOG_DEBUG,
- "Woke up: Conditional wait on white fops");
-}
-
-/**
- * TODO: these threads have many thing in common (wake up after
- * a certain time etc..). move them into separate routine.
- */
-void *
-changelog_rollover (void *data)
-{
- int ret = 0;
- xlator_t *this = NULL;
- struct timeval tv = {0,};
- changelog_log_data_t cld = {0,};
- changelog_time_slice_t *slice = NULL;
- changelog_priv_t *priv = data;
- int max_fd = 0;
- char buf[1] = {0};
- int len = 0;
-
- fd_set rset;
-
- this = priv->cr.this;
- slice = &priv->slice;
-
- while (1) {
- (void) pthread_testcancel();
-
- tv.tv_sec = priv->rollover_time;
- tv.tv_usec = 0;
- FD_ZERO(&rset);
- FD_SET(priv->cr.rfd, &rset);
- max_fd = priv->cr.rfd;
- max_fd = max_fd + 1;
-
- /* It seems there is a race between actual rollover and explicit
- * rollover. But it is handled. If actual rollover is being
- * done and the explicit rollover event comes, the event is
- * not missed. The next select will immediately wakeup to
- * handle explicit wakeup.
- */
-
- ret = select (max_fd, &rset, NULL, NULL, &tv);
- if (ret == -1) {
- gf_log (this->name, GF_LOG_ERROR,
- "select failed: %s", strerror(errno));
- continue;
- } else if (ret && FD_ISSET(priv->cr.rfd, &rset)) {
- gf_log (this->name, GF_LOG_INFO,
- "Explicit wakeup of select on barrier notify");
- len = read(priv->cr.rfd, buf, 1);
- if (len == 0) {
- gf_log (this->name, GF_LOG_ERROR, "BUG: Got EOF"
- " from reconfigure notification pipe");
- continue;
- }
- if (len < 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to read wakeup data");
- continue;
- }
- /* Lock is not required as same thread is modifying.*/
- priv->explicit_rollover = _gf_true;
- } else {
- gf_log (this->name, GF_LOG_DEBUG,
- "select wokeup on timeout");
- }
-
- /* Reading curent_color without lock is fine here
- * as it is only modified here and is next to reading.
- */
- if (priv->current_color == FOP_COLOR_BLACK) {
- LOCK(&priv->lock);
- priv->current_color = FOP_COLOR_WHITE;
- UNLOCK(&priv->lock);
- gf_log (this->name, GF_LOG_DEBUG, "Black fops"
- " to be drained:%ld",priv->dm.black_fop_cnt);
- changelog_drain_black_fops (this, priv);
- } else {
- LOCK(&priv->lock);
- priv->current_color = FOP_COLOR_BLACK;
- UNLOCK(&priv->lock);
- gf_log (this->name, GF_LOG_DEBUG, "White fops"
- " to be drained:%ld",priv->dm.white_fop_cnt);
- changelog_drain_white_fops (this, priv);
- }
-
- /* Adding delay of 1 second only during explicit rollover:
- *
- * Changelog rollover can happen either due to actual
- * or the explict rollover during snapshot. Actual
- * rollover is controlled by tuneable called 'rollover-time'.
- * The minimum granularity for rollover-time is 1 second.
- * Explicit rollover is asynchronous in nature and happens
- * during snapshot.
- *
- * Basically, rollover renames the current CHANGELOG file
- * to CHANGELOG.TIMESTAMP. Let's assume, at time 't1',
- * actual and explicit rollover raced against each
- * other and actual rollover won the race renaming the
- * CHANGELOG file to CHANGELOG.t1 and opens a new
- * CHANGELOG file. There is high chance that, an immediate
- * explicit rollover at time 't1' can happen with in the same
- * second to rename CHANGELOG file to CHANGELOG.t1 resulting in
- * purging the earlier CHANGELOG.t1 file created by actual
- * rollover. So adding a delay of 1 second guarantees unique
- * CHANGELOG.TIMESTAMP during explicit rollover.
- */
- if (priv->explicit_rollover == _gf_true)
- sleep (1);
-
- ret = changelog_fill_rollover_data (&cld, _gf_false);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "failed to fill rollover data");
- continue;
- }
-
- __mask_cancellation (this);
-
- LOCK (&priv->lock);
- {
- ret = changelog_inject_single_event (this, priv, &cld);
- if (!ret)
- SLICE_VERSION_UPDATE (slice);
- }
- UNLOCK (&priv->lock);
-
- __unmask_cancellation (this);
- }
-
- return NULL;
-}
-
-void *
-changelog_fsync_thread (void *data)
-{
- int ret = 0;
- xlator_t *this = NULL;
- struct timeval tv = {0,};
- changelog_log_data_t cld = {0,};
- changelog_priv_t *priv = data;
-
- this = priv->cf.this;
- cld.cld_type = CHANGELOG_TYPE_FSYNC;
-
- while (1) {
- (void) pthread_testcancel();
-
- tv.tv_sec = priv->fsync_interval;
- tv.tv_usec = 0;
-
- ret = select (0, NULL, NULL, NULL, &tv);
- if (ret)
- continue;
-
- __mask_cancellation (this);
-
- ret = changelog_inject_single_event (this, priv, &cld);
- if (ret)
- gf_log (this->name, GF_LOG_ERROR,
- "failed to inject fsync event");
-
- __unmask_cancellation (this);
- }
-
- return NULL;
-}
-
-/* macros for inode/changelog version checks */
-
-#define INODE_VERSION_UPDATE(priv, inode, iver, slice, type) do { \
- LOCK (&inode->lock); \
- { \
- LOCK (&priv->lock); \
- { \
- *iver = slice->changelog_version[type]; \
- } \
- UNLOCK (&priv->lock); \
- } \
- UNLOCK (&inode->lock); \
- } while (0)
-
-#define INODE_VERSION_EQUALS_SLICE(priv, ver, slice, type, upd) do { \
- LOCK (&priv->lock); \
- { \
- upd = (ver == slice->changelog_version[type]) \
- ? _gf_false : _gf_true; \
- } \
- UNLOCK (&priv->lock); \
- } while (0)
-
-static int
-__changelog_inode_ctx_set (xlator_t *this,
- inode_t *inode, changelog_inode_ctx_t *ctx)
-{
- uint64_t ctx_addr = (uint64_t) ctx;
- return __inode_ctx_set (inode, this, &ctx_addr);
-}
-
-/**
- * one shot routine to get the address and the value of a inode version
- * for a particular type.
- */
-static changelog_inode_ctx_t *
-__changelog_inode_ctx_get (xlator_t *this,
- inode_t *inode, unsigned long **iver,
- unsigned long *version, changelog_log_type type)
-{
- int ret = 0;
- uint64_t ctx_addr = 0;
- changelog_inode_ctx_t *ctx = NULL;
-
- ret = __inode_ctx_get (inode, this, &ctx_addr);
- if (ret < 0)
- ctx_addr = 0;
- if (ctx_addr != 0) {
- ctx = (changelog_inode_ctx_t *) (long)ctx_addr;
- goto out;
- }
-
- ctx = GF_CALLOC (1, sizeof (*ctx), gf_changelog_mt_inode_ctx_t);
- if (!ctx)
- goto out;
-
- ret = __changelog_inode_ctx_set (this, inode, ctx);
- if (ret) {
- GF_FREE (ctx);
- ctx = NULL;
- }
-
- out:
- if (ctx && iver && version) {
- *iver = CHANGELOG_INODE_VERSION_TYPE (ctx, type);
- *version = **iver;
- }
-
- return ctx;
-}
-
-static changelog_inode_ctx_t *
-changelog_inode_ctx_get (xlator_t *this,
- inode_t *inode, unsigned long **iver,
- unsigned long *version, changelog_log_type type)
-{
- changelog_inode_ctx_t *ctx = NULL;
-
- LOCK (&inode->lock);
- {
- ctx = __changelog_inode_ctx_get (this,
- inode, iver, version, type);
- }
- UNLOCK (&inode->lock);
-
- return ctx;
-}
-
-/**
- * This is the main update routine. Locking has been made granular so as to
- * maximize parallelism of fops - I'll try to explain it below using execution
- * timelines.
- *
- * Basically, the contention is between multiple execution threads of this
- * routine and the roll-over thread. So, instead of having a big lock, we hold
- * granular locks: inode->lock and priv->lock. Now I'll explain what happens
- * when there is an update and a roll-over at just about the same time.
- * NOTE:
- * - the dispatcher itself synchronizes updates via it's own lock
- * - the slice version in incremented by the roll-over thread
- *
- * Case 1: When the rollover thread wins before the inode version can be
- * compared with the slice version.
- *
- * [updater] | [rollover]
- * |
- * | <SLICE: 1, 1, 1>
- * <changelog_update> |
- * <changelog_inode_ctx_get> |
- * <CTX: 1, 1, 1> |
- * | <dispatch-rollover-event>
- * | LOCK (&priv->lock)
- * | <SLICE_VERSION_UPDATE>
- * | <SLICE: 2, 2, 2>
- * | UNLOCK (&priv->lock)
- * |
- * LOCK (&priv->lock) |
- * <INODE_VERSION_EQUALS_SLICE> |
- * I: 1 <-> S: 2 |
- * update: true |
- * UNLOCK (&priv->lock) |
- * |
- * <if update == true> |
- * <dispath-update-event> |
- * <INODE_VERSION_UPDATE> |
- * LOCK (&inode->lock) |
- * LOCK (&priv->lock) |
- * <CTX: 2, 1, 1> |
- * UNLOCK (&priv->lock) |
- * UNLOCK (&inode->lock) |
- *
- * Therefore, the change gets recorded in the next change (no lost change). If
- * the slice version was ahead of the inode version (say I:1, S: 2), then
- * anyway the comparison would result in a update (I: 1, S: 3).
- *
- * If the rollover time is too less, then there is another contention when the
- * updater tries to bring up inode version to the slice version (this is also
- * the case when the roll-over thread wakes up during INODE_VERSION_UPDATE.
- *
- * <CTX: 1, 1, 1> | <SLICE: 2, 2, 2>
- * |
- * |
- * <dispath-update-event> |
- * <INODE_VERSION_UPDATE> |
- * LOCK (&inode->lock) |
- * LOCK (&priv->lock) |
- * <CTX: 2, 1, 1> |
- * UNLOCK (&priv->lock) |
- * UNLOCK (&inode->lock) |
- * | <dispatch-rollover-event>
- * | LOCK (&priv->lock)
- * | <SLICE_VERSION_UPDATE>
- * | <SLICE: 3, 3, 3>
- * | UNLOCK (&priv->lock)
- *
- *
- * Case 2: When the fop thread wins
- *
- * [updater] | [rollover]
- * |
- * | <SLICE: 1, 1, 1>
- * <changelog_update> |
- * <changelog_inode_ctx_get> |
- * <CTX: 0, 0, 0> |
- * |
- * LOCK (&priv->lock) |
- * <INODE_VERSION_EQUALS_SLICE> |
- * I: 0 <-> S: 1 |
- * update: true |
- * UNLOCK (&priv->lock) |
- * | <dispatch-rollover-event>
- * | LOCK (&priv->lock)
- * | <SLICE_VERSION_UPDATE>
- * | <SLICE: 2, 2, 2>
- * | UNLOCK (&priv->lock)
- * <if update == true> |
- * <dispath-update-event> |
- * <INODE_VERSION_UPDATE> |
- * LOCK (&inode->lock) |
- * LOCK (&priv->lock) |
- * <CTX: 2, 0, 0> |
- * UNLOCK (&priv->lock) |
- * UNLOCK (&inode->lock) |
- *
- * Here again, if the inode version was equal to the slice version (I: 1, S: 1)
- * then there is no need to record an update (as the equality of the two version
- * signifies an update was recorded in the current time slice).
- */
-inline void
-changelog_update (xlator_t *this, changelog_priv_t *priv,
- changelog_local_t *local, changelog_log_type type)
-{
- int ret = 0;
- unsigned long *iver = NULL;
- unsigned long version = 0;
- inode_t *inode = NULL;
- changelog_time_slice_t *slice = NULL;
- changelog_inode_ctx_t *ctx = NULL;
- changelog_log_data_t *cld_0 = NULL;
- changelog_log_data_t *cld_1 = NULL;
- changelog_local_t *next_local = NULL;
- gf_boolean_t need_upd = _gf_true;
-
- slice = &priv->slice;
-
- /**
- * for fops that do not require inode version checking
- */
- if (local->update_no_check)
- goto update;
-
- inode = local->inode;
-
- ctx = changelog_inode_ctx_get (this,
- inode, &iver, &version, type);
- if (!ctx)
- goto update;
-
- INODE_VERSION_EQUALS_SLICE (priv, version, slice, type, need_upd);
-
- update:
- if (need_upd) {
- cld_0 = &local->cld;
- cld_0->cld_type = type;
-
- if ( (next_local = local->prev_entry) != NULL ) {
- cld_1 = &next_local->cld;
- cld_1->cld_type = type;
- }
-
- ret = priv->cd.dispatchfn (this, priv,
- priv->cd.cd_data, cld_0, cld_1);
-
- /**
- * update after the dispatcher has successfully done
- * it's job.
- */
- if (!local->update_no_check && iver && !ret)
- INODE_VERSION_UPDATE (priv, inode, iver, slice, type);
- }
-
- return;
-}
-
-/* Begin: Geo-rep snapshot dependency changes */
-
-/* changelog_color_fop_and_inc_cnt: Assign color and inc fop cnt.
- *
- * Assigning color and increment of corresponding fop count should happen
- * in a lock (i.e., there should be no window between them). If it does not,
- * we might miss draining those fops which are colored but not yet incremented
- * the count. Let's assume black fops are draining. If the black fop count
- * reaches zero, we say draining is completed but we miss black fops which are
- * not incremented fop count but color is assigned black.
- */
-
-inline void
-changelog_color_fop_and_inc_cnt (xlator_t *this, changelog_priv_t *priv,
- changelog_local_t *local)
-{
- if (!priv || !local)
- return;
-
- LOCK (&priv->lock);
- {
- local->color = priv->current_color;
- changelog_inc_fop_cnt (this, priv, local);
- }
- UNLOCK (&priv->lock);
-}
-
-/* Increments the respective fop counter based on the fop color */
-inline void
-changelog_inc_fop_cnt (xlator_t *this, changelog_priv_t *priv,
- changelog_local_t *local)
-{
- int ret = 0;
-
- if (local) {
- if (local->color == FOP_COLOR_BLACK) {
- ret = pthread_mutex_lock (&priv->dm.drain_black_mutex);
- CHANGELOG_PTHREAD_ERROR_HANDLE_0 (ret, out);
- {
- priv->dm.black_fop_cnt++;
- }
- ret = pthread_mutex_unlock(&priv->dm.drain_black_mutex);
- CHANGELOG_PTHREAD_ERROR_HANDLE_0 (ret, out);
- } else {
- ret = pthread_mutex_lock (&priv->dm.drain_white_mutex);
- CHANGELOG_PTHREAD_ERROR_HANDLE_0 (ret, out);
- {
- priv->dm.white_fop_cnt++;
- }
- ret = pthread_mutex_unlock(&priv->dm.drain_white_mutex);
- CHANGELOG_PTHREAD_ERROR_HANDLE_0 (ret, out);
- }
- }
- out:
- return;
-}
-
-/* Decrements the respective fop counter based on the fop color */
-inline void
-changelog_dec_fop_cnt (xlator_t *this, changelog_priv_t *priv,
- changelog_local_t *local)
-{
- int ret = 0;
-
- if (local) {
- if (local->color == FOP_COLOR_BLACK) {
- ret = pthread_mutex_lock (&priv->dm.drain_black_mutex);
- CHANGELOG_PTHREAD_ERROR_HANDLE_0 (ret, out);
- {
- priv->dm.black_fop_cnt--;
- if (priv->dm.black_fop_cnt == 0 &&
- priv->dm.drain_wait_black == _gf_true) {
- ret = pthread_cond_signal (
- &priv->dm.drain_black_cond);
- CHANGELOG_PTHREAD_ERROR_HANDLE_0 (ret,
- out);
- gf_log (this->name, GF_LOG_DEBUG,
- "Signalled draining of black");
- }
- }
- ret = pthread_mutex_unlock(&priv->dm.drain_black_mutex);
- CHANGELOG_PTHREAD_ERROR_HANDLE_0 (ret, out);
- } else {
- ret = pthread_mutex_lock (&priv->dm.drain_white_mutex);
- CHANGELOG_PTHREAD_ERROR_HANDLE_0 (ret, out);
- {
- priv->dm.white_fop_cnt--;
- if (priv->dm.white_fop_cnt == 0 &&
- priv->dm.drain_wait_white == _gf_true) {
- ret = pthread_cond_signal (
- &priv->dm.drain_white_cond);
- CHANGELOG_PTHREAD_ERROR_HANDLE_0 (ret,
- out);
- gf_log (this->name, GF_LOG_DEBUG,
- "Signalled draining of white");
- }
- }
- ret = pthread_mutex_unlock(&priv->dm.drain_white_mutex);
- CHANGELOG_PTHREAD_ERROR_HANDLE_0 (ret, out);
- }
- }
- out:
- return;
-}
-
-/* Write to a pipe setup between changelog main thread and changelog
- * rollover thread to initiate explicit rollover of changelog journal.
- */
-inline int
-changelog_barrier_notify (changelog_priv_t *priv, char *buf)
-{
- int ret = 0;
-
- LOCK(&priv->lock);
- ret = changelog_write (priv->cr_wfd, buf, 1);
- UNLOCK(&priv->lock);
- return ret;
-}
-
-/* Clean up flags set on barrier notification */
-inline void
-changelog_barrier_cleanup (xlator_t *this, changelog_priv_t *priv,
- struct list_head *queue)
-{
- int ret = 0;
-
- LOCK (&priv->bflags.lock);
- priv->bflags.barrier_ext = _gf_false;
- UNLOCK (&priv->bflags.lock);
-
- ret = pthread_mutex_lock (&priv->bn.bnotify_mutex);
- CHANGELOG_PTHREAD_ERROR_HANDLE_0 (ret, out);
- {
- priv->bn.bnotify = _gf_false;
- }
- ret = pthread_mutex_unlock (&priv->bn.bnotify_mutex);
- CHANGELOG_PTHREAD_ERROR_HANDLE_0 (ret, out);
-
- /* Disable changelog barrier and dequeue fops */
- LOCK (&priv->lock);
- {
- if (priv->barrier_enabled == _gf_true)
- __chlog_barrier_disable (this, queue);
- else
- ret = -1;
- }
- UNLOCK (&priv->lock);
- if (ret == 0)
- chlog_barrier_dequeue_all(this, queue);
-
- out:
- return;
-}
-/* End: Geo-Rep snapshot dependency changes */
diff --git a/xlators/features/changelog/src/changelog-helpers.h b/xlators/features/changelog/src/changelog-helpers.h
deleted file mode 100644
index d8f80465922..00000000000
--- a/xlators/features/changelog/src/changelog-helpers.h
+++ /dev/null
@@ -1,608 +0,0 @@
-/*
- Copyright (c) 2013 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 _CHANGELOG_HELPERS_H
-#define _CHANGELOG_HELPERS_H
-
-#include "locking.h"
-#include "timer.h"
-#include "pthread.h"
-#include "iobuf.h"
-
-#include "changelog-misc.h"
-#include "call-stub.h"
-
-/**
- * the changelog entry
- */
-typedef struct changelog_log_data {
- /* rollover related */
- unsigned long cld_roll_time;
-
- /* reopen changelog? */
- gf_boolean_t cld_finale;
-
- changelog_log_type cld_type;
-
- /**
- * sincd gfid is _always_ a necessity, it's not a part
- * of the iobuf. by doing this we do not add any overhead
- * for data and metadata related fops.
- */
- uuid_t cld_gfid;
-
- /**
- * iobufs are used for optionals records: pargfid, path,
- * write offsets etc.. It's the fop implementers job
- * to allocate (iobuf_get() in the fop) and get unref'ed
- * in the callback (CHANGELOG_STACK_UNWIND).
- */
- struct iobuf *cld_iobuf;
-
-#define cld_ptr cld_iobuf->ptr
-
- /**
- * after allocation you can point this to the length of
- * usable data, but make sure it does not exceed the
- * the size of the requested iobuf.
- */
- size_t cld_iobuf_len;
-
-#define cld_ptr_len cld_iobuf_len
-
- /**
- * number of optional records
- */
- int cld_xtra_records;
-} changelog_log_data_t;
-
-/**
- * holder for dispatch function and private data
- */
-
-typedef struct changelog_priv changelog_priv_t;
-
-typedef struct changelog_dispatcher {
- void *cd_data;
- int (*dispatchfn) (xlator_t *, changelog_priv_t *, void *,
- changelog_log_data_t *, changelog_log_data_t *);
-} changelog_dispatcher_t;
-
-struct changelog_bootstrap {
- changelog_mode_t mode;
- int (*ctor) (xlator_t *, changelog_dispatcher_t *);
- int (*dtor) (xlator_t *, changelog_dispatcher_t *);
-};
-
-struct changelog_encoder {
- changelog_encoder_t encoder;
- int (*encode) (xlator_t *, changelog_log_data_t *);
-};
-
-
-/* xlator private */
-
-typedef struct changelog_time_slice {
- /**
- * just in case we need nanosecond granularity some day.
- * field is unused as of now (maybe we'd need it later).
- */
- struct timeval tv_start;
-
- /**
- * version of changelog file, incremented each time changes
- * rollover.
- */
- unsigned long changelog_version[CHANGELOG_MAX_TYPE];
-} changelog_time_slice_t;
-
-typedef struct changelog_rollover {
- /* rollover thread */
- pthread_t rollover_th;
-
- xlator_t *this;
-
- /* read end of pipe used as event from barrier on snapshot */
- int rfd;
-} changelog_rollover_t;
-
-typedef struct changelog_fsync {
- /* fsync() thread */
- pthread_t fsync_th;
-
- xlator_t *this;
-} changelog_fsync_t;
-
-# define CHANGELOG_MAX_CLIENTS 5
-typedef struct changelog_notify {
- /* reader end of the pipe */
- int rfd;
-
- /* notifier thread */
- pthread_t notify_th;
-
- /* unique socket path */
- char sockpath[UNIX_PATH_MAX];
-
- int socket_fd;
-
- /**
- * simple array of accept()'ed fds. Not scalable at all
- * for large number of clients, but it's okay as we have
- * a ahrd limit in this version (@CHANGELOG_MAX_CLIENTS).
- */
- int client_fd[CHANGELOG_MAX_CLIENTS];
-
- xlator_t *this;
-} changelog_notify_t;
-
-/* Draining during changelog rollover (for geo-rep snapshot dependency):
- * --------------------------------------------------------------------
- * The introduction of draining of in-transit fops during changelog rollover
- * (both explicit/timeout triggered) requires coloring of fops. Basically the
- * implementation requires two counters, one counter which keeps the count of
- * current intransit fops which should end up in current changelog and the other
- * counter to keep track of incoming fops which should be drained as part of
- * next changelog rollover event. The fops are colored w.r.t these counters.
- * The fops that are to be drained as part of current changelog rollover is
- * given one color and the fops which keep incoming during this and not
- * necessarily should end up in current changelog and should be drained as part
- * of next changelog rollover are given other color. The color switching
- * continues with each changelog rollover. Two colors(black and white) are
- * chosen here and initially black is chosen is default.
- */
-
-typedef enum chlog_fop_color {
- FOP_COLOR_BLACK,
- FOP_COLOR_WHITE
-}chlog_fop_color_t;
-
-/* Barrier notify variable */
-typedef struct barrier_notify {
- pthread_mutex_t bnotify_mutex;
- pthread_cond_t bnotify_cond;
- gf_boolean_t bnotify;
-}barrier_notify_t;
-
-/* Two separate mutex and conditional variable set is used
- * to drain white and black fops. */
-
-typedef struct drain_mgmt {
- pthread_mutex_t drain_black_mutex;
- pthread_cond_t drain_black_cond;
- pthread_mutex_t drain_white_mutex;
- pthread_cond_t drain_white_cond;
- /* Represents black fops count in-transit */
- unsigned long black_fop_cnt;
- /* Represents white fops count in-transit */
- unsigned long white_fop_cnt;
- gf_boolean_t drain_wait_black;
- gf_boolean_t drain_wait_white;
-}drain_mgmt_t;
-
-/* External barrier as a result of snap on/off indicating flag*/
-typedef struct barrier_flags {
- gf_lock_t lock;
- gf_boolean_t barrier_ext;
-}barrier_flags_t;
-
-
-struct changelog_priv {
- gf_boolean_t active;
-
- /* to generate unique socket file per brick */
- char *changelog_brick;
-
- /* logging directory */
- char *changelog_dir;
-
- /* htime directory */
- char *htime_dir;
-
- /* one file for all changelog types */
- int changelog_fd;
-
- /* htime fd for current changelog session */
- int htime_fd;
-
- /* c_snap_fd is fd for call-path changelog */
- int c_snap_fd;
-
- /* rollover_count used by htime */
- int rollover_count;
-
- gf_lock_t lock;
-
- /* lock to synchronize CSNAP updation */
- gf_lock_t c_snap_lock;
-
- /* writen end of the pipe */
- int wfd;
-
- /* rollover time */
- int32_t rollover_time;
-
- /* fsync() interval */
- int32_t fsync_interval;
-
- /* changelog type maps */
- const char *maps[CHANGELOG_MAX_TYPE];
-
- /* time slicer */
- changelog_time_slice_t slice;
-
- /* context of the updater */
- changelog_dispatcher_t cd;
-
- /* context of the rollover thread */
- changelog_rollover_t cr;
-
- /* context of fsync thread */
- changelog_fsync_t cf;
-
- /* context of the notifier thread */
- changelog_notify_t cn;
-
- /* operation mode */
- changelog_mode_t op_mode;
-
- /* bootstrap routine for 'current' logger */
- struct changelog_bootstrap *cb;
-
- /* encoder mode */
- changelog_encoder_t encode_mode;
-
- /* encoder */
- struct changelog_encoder *ce;
-
- /* snapshot dependency changes */
-
- /* Draining of fops*/
- drain_mgmt_t dm;
-
- /* Represents the active color. Initially by default black */
- chlog_fop_color_t current_color;
-
- /* write end of pipe to do explicit rollover on barrier during snap */
- int cr_wfd;
-
- /* flag to determine explicit rollover is triggered */
- gf_boolean_t explicit_rollover;
-
- /* barrier notification variable protected by mutex */
- barrier_notify_t bn;
-
- /* barrier on/off indicating flags */
- barrier_flags_t bflags;
-
- /* changelog barrier on/off indicating flag */
- gf_boolean_t barrier_enabled;
- struct list_head queue;
- uint32_t queue_size;
- gf_timer_t *timer;
- struct timespec timeout;
-
-};
-
-struct changelog_local {
- inode_t *inode;
- gf_boolean_t update_no_check;
-
- changelog_log_data_t cld;
-
- /**
- * ->prev_entry is used in cases when there needs to be
- * additional changelog entry for the parent (eg. rename)
- * It's analogous to ->next in single linked list world,
- * but we call it as ->prev_entry... ha ha ha
- */
- struct changelog_local *prev_entry;
-
- /* snap dependency changes */
- chlog_fop_color_t color;
-};
-
-typedef struct changelog_local changelog_local_t;
-
-/* inode version is stored in inode ctx */
-typedef struct changelog_inode_ctx {
- unsigned long iversion[CHANGELOG_MAX_TYPE];
-} changelog_inode_ctx_t;
-
-#define CHANGELOG_INODE_VERSION_TYPE(ctx, type) &(ctx->iversion[type])
-
-/**
- * Optional Records:
- * fops that need to save additional information request a array of
- * @changelog_opt_t struct. The array is allocated via @iobufs.
- */
-typedef enum {
- CHANGELOG_OPT_REC_FOP,
- CHANGELOG_OPT_REC_ENTRY,
- CHANGELOG_OPT_REC_UINT32,
-} changelog_optional_rec_type_t;
-
-struct changelog_entry_fields {
- uuid_t cef_uuid;
- char *cef_bname;
-};
-
-typedef struct {
- /**
- * @co_covert can be used to do post-processing of the record before
- * it's persisted to the CHANGELOG. If this is NULL, then the record
- * is persisted as per it's in memory format.
- */
- size_t (*co_convert) (void *data, char *buffer, gf_boolean_t encode);
-
- /* release routines */
- void (*co_free) (void *data);
-
- /* type of the field */
- changelog_optional_rec_type_t co_type;
-
- /**
- * sizeof of the 'valid' field in the union. This field is not used if
- * @co_convert is specified.
- */
- size_t co_len;
-
- union {
- unsigned int co_uint32;
- glusterfs_fop_t co_fop;
- struct changelog_entry_fields co_entry;
- };
-} changelog_opt_t;
-
-#define CHANGELOG_OPT_RECORD_LEN sizeof (changelog_opt_t)
-
-/**
- * helpers routines
- */
-
-void
-changelog_thread_cleanup (xlator_t *this, pthread_t thr_id);
-
-void *
-changelog_get_usable_buffer (changelog_local_t *local);
-
-void
-changelog_set_usable_record_and_length (changelog_local_t *local,
- size_t len, int xr);
-void
-changelog_local_cleanup (xlator_t *xl, changelog_local_t *local);
-changelog_local_t *
-changelog_local_init (xlator_t *this, inode_t *inode, uuid_t gfid,
- int xtra_records, gf_boolean_t update_flag);
-int
-changelog_start_next_change (xlator_t *this,
- changelog_priv_t *priv,
- unsigned long ts, gf_boolean_t finale);
-int
-changelog_open (xlator_t *this, changelog_priv_t *priv);
-int
-changelog_fill_rollover_data (changelog_log_data_t *cld, gf_boolean_t is_last);
-int
-changelog_inject_single_event (xlator_t *this,
- changelog_priv_t *priv,
- changelog_log_data_t *cld);
-size_t
-changelog_entry_length ();
-int
-changelog_write (int fd, char *buffer, size_t len);
-int
-changelog_write_change (changelog_priv_t *priv, char *buffer, size_t len);
-int
-changelog_handle_change (xlator_t *this,
- changelog_priv_t *priv, changelog_log_data_t *cld);
-void
-changelog_update (xlator_t *this, changelog_priv_t *priv,
- changelog_local_t *local, changelog_log_type type);
-void *
-changelog_rollover (void *data);
-void *
-changelog_fsync_thread (void *data);
-int
-changelog_forget (xlator_t *this, inode_t *inode);
-int
-htime_update (xlator_t *this, changelog_priv_t *priv,
- unsigned long ts, char * buffer);
-int
-htime_open (xlator_t *this, changelog_priv_t * priv, unsigned long ts);
-
-/* Geo-Rep snapshot dependency changes */
-void
-changelog_color_fop_and_inc_cnt (xlator_t *this, changelog_priv_t *priv,
- changelog_local_t *local);
-void
-changelog_inc_fop_cnt (xlator_t *this, changelog_priv_t *priv,
- changelog_local_t *local);
-void
-changelog_dec_fop_cnt (xlator_t *this, changelog_priv_t *priv,
- changelog_local_t *local);
-int
-changelog_barrier_notify (changelog_priv_t *priv, char* buf);
-void
-changelog_barrier_cleanup (xlator_t *this, changelog_priv_t *priv,
- struct list_head *queue);
-void
-changelog_drain_white_fops (xlator_t *this, changelog_priv_t *priv);
-void
-changelog_drain_black_fops (xlator_t *this, changelog_priv_t *priv);
-
-/* Crash consistency of changelog wrt snapshot */
-int
-changelog_snap_logging_stop ( xlator_t *this, changelog_priv_t *priv);
-int
-changelog_snap_logging_start ( xlator_t *this, changelog_priv_t *priv);
-int
-changelog_snap_open ( xlator_t *this, changelog_priv_t *priv);
-int
-changelog_snap_handle_ascii_change (xlator_t *this,
- changelog_log_data_t *cld);
-int
-changelog_snap_write_change (changelog_priv_t *priv, char *buffer, size_t len);
-/* Changelog barrier routines */
-void __chlog_barrier_enqueue (xlator_t *this, call_stub_t *stub);
-void __chlog_barrier_disable (xlator_t *this, struct list_head *queue);
-void chlog_barrier_dequeue_all (xlator_t *this, struct list_head *queue);
-call_stub_t *__chlog_barrier_dequeue (xlator_t *this, struct list_head *queue);
-int __chlog_barrier_enable (xlator_t *this, changelog_priv_t *priv);
-
-
-/* macros */
-
-#define CHANGELOG_STACK_UNWIND(fop, frame, params ...) do { \
- changelog_local_t *__local = NULL; \
- xlator_t *__xl = NULL; \
- if (frame) { \
- __local = frame->local; \
- __xl = frame->this; \
- frame->local = NULL; \
- } \
- STACK_UNWIND_STRICT (fop, frame, params); \
- changelog_local_cleanup (__xl, __local); \
- if (__local && __local->prev_entry) \
- changelog_local_cleanup (__xl, \
- __local->prev_entry); \
- } while (0)
-
-#define CHANGELOG_IOBUF_REF(iobuf) do { \
- if (iobuf) \
- iobuf_ref (iobuf); \
- } while (0)
-
-#define CHANGELOG_IOBUF_UNREF(iobuf) do { \
- if (iobuf) \
- iobuf_unref (iobuf); \
- } while (0)
-
-#define CHANGELOG_FILL_BUFFER(buffer, off, val, len) do { \
- memcpy (buffer + off, val, len); \
- off += len; \
- } while (0)
-
-#define SLICE_VERSION_UPDATE(slice) do { \
- int i = 0; \
- for (; i < CHANGELOG_MAX_TYPE; i++) { \
- slice->changelog_version[i]++; \
- } \
- } while (0)
-
-#define CHANGELOG_FILL_UINT32(co, number, converter, xlen) do { \
- co->co_convert = converter; \
- co->co_free = NULL; \
- co->co_type = CHANGELOG_OPT_REC_UINT32; \
- co->co_uint32 = number; \
- xlen += sizeof (unsigned int); \
- } while (0)
-
-#define CHANGLOG_FILL_FOP_NUMBER(co, fop, converter, xlen) do { \
- co->co_convert = converter; \
- co->co_free = NULL; \
- co->co_type = CHANGELOG_OPT_REC_FOP; \
- co->co_fop = fop; \
- xlen += sizeof (fop); \
- } while (0)
-
-#define CHANGELOG_FILL_ENTRY(co, pargfid, bname, \
- converter, freefn, xlen, label) \
- do { \
- co->co_convert = converter; \
- co->co_free = freefn; \
- co->co_type = CHANGELOG_OPT_REC_ENTRY; \
- uuid_copy (co->co_entry.cef_uuid, pargfid); \
- co->co_entry.cef_bname = gf_strdup(bname); \
- if (!co->co_entry.cef_bname) \
- goto label; \
- xlen += (UUID_CANONICAL_FORM_LEN + strlen (bname)); \
- } while (0)
-
-#define CHANGELOG_INIT(this, local, inode, gfid, xrec) \
- local = changelog_local_init (this, inode, gfid, xrec, _gf_false)
-
-#define CHANGELOG_INIT_NOCHECK(this, local, inode, gfid, xrec) \
- local = changelog_local_init (this, inode, gfid, xrec, _gf_true)
-
-#define CHANGELOG_NOT_ACTIVE_THEN_GOTO(frame, priv, label) do { \
- if (!priv->active) \
- goto label; \
- /* ignore rebalance process's activity. */ \
- if (frame->root->pid == GF_CLIENT_PID_DEFRAG) \
- goto label; \
- } while (0)
-
-/* If it is a METADATA entry and fop num being GF_FOP_NULL, don't
- * log in the changelog as it is of no use. And also if it is
- * logged, since slicing version checking is done for metadata
- * entries, the subsequent entries with valid fop num which falls
- * to same changelog will be missed. Hence check for boundary
- * condition.
- */
-#define CHANGELOG_OP_BOUNDARY_CHECK(frame, label) do { \
- if (frame->root->op <= GF_FOP_NULL || \
- frame->root->op >= GF_FOP_MAXVALUE) \
- goto label; \
- } while (0)
-
-/**
- * ignore internal fops for all clients except AFR self-heal daemon
- */
-#define CHANGELOG_IF_INTERNAL_FOP_THEN_GOTO(frame, dict, label) do { \
- if ((frame->root->pid != GF_CLIENT_PID_AFR_SELF_HEALD) \
- && dict \
- && dict_get (dict, GLUSTERFS_INTERNAL_FOP_KEY)) \
- goto label; \
- } while (0)
-
-#define CHANGELOG_COND_GOTO(priv, cond, label) do { \
- if (!priv->active || cond) \
- goto label; \
- } while (0)
-
-/* Begin: Geo-Rep snapshot dependency changes */
-
-#define DICT_ERROR -1
-#define BARRIER_OFF 0
-#define BARRIER_ON 1
-#define DICT_DEFAULT 2
-
-#define CHANGELOG_NOT_ON_THEN_GOTO(priv, ret, label) do { \
- if (!priv->active) { \
- gf_log (this->name, GF_LOG_WARNING, \
- "Changelog is not active, return success"); \
- ret = 0; \
- goto label; \
- } \
- } while (0)
-
-/* Log pthread error and goto label */
-#define CHANGELOG_PTHREAD_ERROR_HANDLE_0(ret, label) do { \
- if (ret) { \
- gf_log (this->name, GF_LOG_ERROR, \
- "pthread error: Error: %d", ret); \
- ret = -1; \
- goto label; \
- } \
- } while (0)
-
-/* Log pthread error, set flag and goto label */
-#define CHANGELOG_PTHREAD_ERROR_HANDLE_1(ret, label, flag) do { \
- if (ret) { \
- gf_log (this->name, GF_LOG_ERROR, \
- "pthread error: Error: %d", ret); \
- ret = -1; \
- flag = _gf_true; \
- goto label; \
- } \
- } while (0)
-/* End: Geo-Rep snapshot dependency changes */
-
-#endif /* _CHANGELOG_HELPERS_H */
diff --git a/xlators/features/changelog/src/changelog-mem-types.h b/xlators/features/changelog/src/changelog-mem-types.h
deleted file mode 100644
index e1fa319a715..00000000000
--- a/xlators/features/changelog/src/changelog-mem-types.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- Copyright (c) 2013 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 _CHANGELOG_MEM_TYPES_H
-#define _CHANGELOG_MEM_TYPES_H
-
-#include "mem-types.h"
-
-enum gf_changelog_mem_types {
- gf_changelog_mt_priv_t = gf_common_mt_end + 1,
- gf_changelog_mt_str_t = gf_common_mt_end + 2,
- gf_changelog_mt_batch_t = gf_common_mt_end + 3,
- gf_changelog_mt_rt_t = gf_common_mt_end + 4,
- gf_changelog_mt_inode_ctx_t = gf_common_mt_end + 5,
- gf_changelog_mt_libgfchangelog_t = gf_common_mt_end + 6,
- gf_changelog_mt_libgfchangelog_rl_t = gf_common_mt_end + 7,
- gf_changelog_mt_libgfchangelog_dirent_t = gf_common_mt_end + 8,
- gf_changelog_mt_changelog_buffer_t = gf_common_mt_end + 9,
- gf_changelog_mt_history_data_t = gf_common_mt_end + 10,
- gf_changelog_mt_end
-};
-
-#endif
diff --git a/xlators/features/changelog/src/changelog-misc.h b/xlators/features/changelog/src/changelog-misc.h
deleted file mode 100644
index 58b10961463..00000000000
--- a/xlators/features/changelog/src/changelog-misc.h
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- Copyright (c) 2013 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 _CHANGELOG_MISC_H
-#define _CHANGELOG_MISC_H
-
-#include "glusterfs.h"
-#include "common-utils.h"
-
-#define CHANGELOG_MAX_TYPE 3
-#define CHANGELOG_FILE_NAME "CHANGELOG"
-#define HTIME_FILE_NAME "HTIME"
-#define CSNAP_FILE_NAME "CHANGELOG.SNAP"
-#define HTIME_KEY "trusted.glusterfs.htime"
-#define HTIME_INITIAL_VALUE "0:0"
-
-#define CHANGELOG_VERSION_MAJOR 1
-#define CHANGELOG_VERSION_MINOR 1
-
-#define CHANGELOG_UNIX_SOCK DEFAULT_VAR_RUN_DIRECTORY"/changelog-%s.sock"
-
-/**
- * header starts with the version and the format of the changelog.
- * 'version' not much of a use now.
- */
-#define CHANGELOG_HEADER \
- "GlusterFS Changelog | version: v%d.%d | encoding : %d\n"
-
-#define CHANGELOG_MAKE_SOCKET_PATH(brick_path, sockpath, len) do { \
- char md5_sum[MD5_DIGEST_LENGTH*2+1] = {0,}; \
- md5_wrapper((unsigned char *) brick_path, \
- strlen(brick_path), \
- md5_sum); \
- (void) snprintf (sockpath, len, \
- CHANGELOG_UNIX_SOCK, md5_sum); \
- } while (0)
-
-/**
- * ... used by libgfchangelog.
- */
-#define CHANGELOG_GET_ENCODING(fd, buffer, len, enc, enc_len) do { \
- FILE *fp; \
- int fd_dup, maj, min; \
- \
- enc = -1; \
- fd_dup = dup (fd); \
- \
- if (fd_dup != -1) { \
- fp = fdopen (fd_dup, "r"); \
- if (fp) { \
- if (fgets (buffer, len, fp)) { \
- elen = strlen (buffer); \
- sscanf (buffer, \
- CHANGELOG_HEADER, \
- &maj, &min, &enc); \
- } \
- fclose (fp); \
- } else { \
- close (fd_dup); \
- } \
- } \
- } while (0)
-
-#define CHANGELOG_FILL_HTIME_DIR(changelog_dir, path) do { \
- strcpy (path, changelog_dir); \
- strcat (path, "/htime"); \
- } while(0)
-
-#define CHANGELOG_FILL_CSNAP_DIR(changelog_dir, path) do { \
- strcpy (path, changelog_dir); \
- strcat (path, "/csnap"); \
- } while(0)
-/**
- * everything after 'CHANGELOG_TYPE_ENTRY' are internal types
- * (ie. none of the fops trigger this type of event), hence
- * CHANGELOG_MAX_TYPE = 3
- */
-typedef enum {
- CHANGELOG_TYPE_DATA = 0,
- CHANGELOG_TYPE_METADATA,
- CHANGELOG_TYPE_ENTRY,
- CHANGELOG_TYPE_ROLLOVER,
- CHANGELOG_TYPE_FSYNC,
-} changelog_log_type;
-
-/* operation modes - RT for now */
-typedef enum {
- CHANGELOG_MODE_RT = 0,
-} changelog_mode_t;
-
-/* encoder types */
-
-typedef enum {
- CHANGELOG_ENCODE_MIN = 0,
- CHANGELOG_ENCODE_BINARY,
- CHANGELOG_ENCODE_ASCII,
- CHANGELOG_ENCODE_MAX,
-} changelog_encoder_t;
-
-#define CHANGELOG_VALID_ENCODING(enc) \
- (enc > CHANGELOG_ENCODE_MIN && enc < CHANGELOG_ENCODE_MAX)
-
-#define CHANGELOG_TYPE_IS_ENTRY(type) (type == CHANGELOG_TYPE_ENTRY)
-#define CHANGELOG_TYPE_IS_ROLLOVER(type) (type == CHANGELOG_TYPE_ROLLOVER)
-#define CHANGELOG_TYPE_IS_FSYNC(type) (type == CHANGELOG_TYPE_FSYNC)
-
-#endif /* _CHANGELOG_MISC_H */
diff --git a/xlators/features/changelog/src/changelog-notifier.c b/xlators/features/changelog/src/changelog-notifier.c
deleted file mode 100644
index 5f3d063a8ad..00000000000
--- a/xlators/features/changelog/src/changelog-notifier.c
+++ /dev/null
@@ -1,314 +0,0 @@
-/*
- Copyright (c) 2013 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 "changelog-notifier.h"
-
-#include <pthread.h>
-
-inline static void
-changelog_notify_clear_fd (changelog_notify_t *cn, int i)
-{
- cn->client_fd[i] = -1;
-}
-
-inline static void
-changelog_notify_save_fd (changelog_notify_t *cn, int i, int fd)
-{
- cn->client_fd[i] = fd;
-}
-
-static int
-changelog_notify_insert_fd (xlator_t *this, changelog_notify_t *cn, int fd)
-{
- int i = 0;
- int ret = 0;
-
- for (; i < CHANGELOG_MAX_CLIENTS; i++) {
- if (cn->client_fd[i] == -1)
- break;
- }
-
- if (i == CHANGELOG_MAX_CLIENTS) {
- /**
- * this case should not be hit as listen() would limit
- * the number of completely established connections.
- */
- gf_log (this->name, GF_LOG_WARNING,
- "hit max client limit (%d)", CHANGELOG_MAX_CLIENTS);
- ret = -1;
- }
- else
- changelog_notify_save_fd (cn, i, fd);
-
- return ret;
-}
-
-static void
-changelog_notify_fill_rset (changelog_notify_t *cn, fd_set *rset, int *maxfd)
-{
- int i = 0;
-
- FD_ZERO (rset);
-
- FD_SET (cn->socket_fd, rset);
- *maxfd = cn->socket_fd;
-
- FD_SET (cn->rfd, rset);
- *maxfd = max (*maxfd, cn->rfd);
-
- for (; i < CHANGELOG_MAX_CLIENTS; i++) {
- if (cn->client_fd[i] != -1) {
- FD_SET (cn->client_fd[i], rset);
- *maxfd = max (*maxfd, cn->client_fd[i]);
- }
- }
-
- *maxfd = *maxfd + 1;
-}
-
-static int
-changelog_notify_client (changelog_notify_t *cn, char *path, ssize_t len)
-{
- int i = 0;
- int ret = 0;
-
- for (; i < CHANGELOG_MAX_CLIENTS; i++) {
- if (cn->client_fd[i] == -1)
- continue;
-
- if (changelog_write (cn->client_fd[i],
- path, len)) {
- ret = -1;
-
- close (cn->client_fd[i]);
- changelog_notify_clear_fd (cn, i);
- }
- }
-
- return ret;
-}
-
-static void
-changelog_notifier_init (changelog_notify_t *cn)
-{
- int i = 0;
-
- cn->socket_fd = -1;
-
- for (; i < CHANGELOG_MAX_CLIENTS; i++) {
- changelog_notify_clear_fd (cn, i);
- }
-}
-
-static void
-changelog_close_client_conn (changelog_notify_t *cn)
-{
- int i = 0;
-
- for (; i < CHANGELOG_MAX_CLIENTS; i++) {
- if (cn->client_fd[i] == -1)
- continue;
-
- close (cn->client_fd[i]);
- changelog_notify_clear_fd (cn, i);
- }
-}
-
-static void
-changelog_notifier_cleanup (void *arg)
-{
- changelog_notify_t *cn = NULL;
-
- cn = (changelog_notify_t *) arg;
-
- changelog_close_client_conn (cn);
-
- if (cn->socket_fd != -1)
- close (cn->socket_fd);
-
- if (cn->rfd)
- close (cn->rfd);
-
- if (unlink (cn->sockpath))
- gf_log ("", GF_LOG_WARNING,
- "could not unlink changelog socket file"
- " %s (reason: %s", cn->sockpath, strerror (errno));
-}
-
-void *
-changelog_notifier (void *data)
-{
- int i = 0;
- int fd = 0;
- int max_fd = 0;
- int len = 0;
- ssize_t readlen = 0;
- xlator_t *this = NULL;
- changelog_priv_t *priv = NULL;
- changelog_notify_t *cn = NULL;
- struct sockaddr_un local = {0,};
- char path[PATH_MAX] = {0,};
- char abspath[PATH_MAX] = {0,};
-
- char buffer;
- fd_set rset;
-
- priv = (changelog_priv_t *) data;
-
- cn = &priv->cn;
- this = cn->this;
-
- pthread_cleanup_push (changelog_notifier_cleanup, cn);
-
- changelog_notifier_init (cn);
-
- cn->socket_fd = socket (AF_UNIX, SOCK_STREAM, 0);
- if (cn->socket_fd < 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "changelog socket error (reason: %s)",
- strerror (errno));
- goto out;
- }
-
- CHANGELOG_MAKE_SOCKET_PATH (priv->changelog_brick,
- cn->sockpath, UNIX_PATH_MAX);
- if (unlink (cn->sockpath) < 0) {
- if (errno != ENOENT) {
- gf_log (this->name, GF_LOG_ERROR,
- "Could not unlink changelog socket file (%s)"
- " (reason: %s)",
- CHANGELOG_UNIX_SOCK, strerror (errno));
- goto cleanup;
- }
- }
-
- local.sun_family = AF_UNIX;
- strcpy (local.sun_path, cn->sockpath);
-
- len = strlen (local.sun_path) + sizeof (local.sun_family);
-
- /* bind to the unix domain socket */
- if (bind (cn->socket_fd, (struct sockaddr *) &local, len) < 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "Could not bind to changelog socket (reason: %s)",
- strerror (errno));
- goto cleanup;
- }
-
- /* listen for incoming connections */
- if (listen (cn->socket_fd, CHANGELOG_MAX_CLIENTS) < 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "listen() error on changelog socket (reason: %s)",
- strerror (errno));
- goto cleanup;
- }
-
- /**
- * simple select() on all to-be-read file descriptors. This method
- * though old school works pretty well when you have a handfull of
- * fd's to be watched (clients).
- *
- * Future TODO: move this to epoll based notification facility if
- * number of clients increase.
- */
- for (;;) {
- changelog_notify_fill_rset (cn, &rset, &max_fd);
-
- if (select (max_fd, &rset, NULL, NULL, NULL) < 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "select() returned -1 (reason: %s)",
- strerror (errno));
- sleep (2);
- continue;
- }
-
- if (FD_ISSET (cn->socket_fd, &rset)) {
- fd = accept (cn->socket_fd, NULL, NULL);
- if (fd < 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "accept error on changelog socket"
- " (reason: %s)", strerror (errno));
- } else if (changelog_notify_insert_fd (this, cn, fd)) {
- gf_log (this->name, GF_LOG_ERROR,
- "hit max client limit");
- }
- }
-
- if (FD_ISSET (cn->rfd, &rset)) {
- /**
- * read changelog filename and notify all connected
- * clients.
- */
- readlen = 0;
- while (readlen < PATH_MAX) {
- len = read (cn->rfd, &path[readlen++], 1);
- if (len == -1) {
- break;
- }
-
- if (len == 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "rollover thread sent EOF"
- " on pipe - possibly a crash.");
- /* be blunt and close all connections */
- pthread_exit(NULL);
- }
-
- if (path[readlen - 1] == '\0')
- break;
- }
-
- /* should we close all client connections here too? */
- if (len < 0 || readlen == PATH_MAX) {
- gf_log (this->name, GF_LOG_ERROR,
- "Could not get pathname from rollover"
- " thread or pathname too long");
- goto process_rest;
- }
-
- (void) snprintf (abspath, PATH_MAX,
- "%s/%s", priv->changelog_dir, path);
- if (changelog_notify_client (cn, abspath,
- strlen (abspath) + 1))
- gf_log (this->name, GF_LOG_ERROR,
- "could not notify some clients with new"
- " changelogs");
- }
-
- process_rest:
- for (i = 0; i < CHANGELOG_MAX_CLIENTS; i++) {
- if ( (fd = cn->client_fd[i]) == -1 )
- continue;
-
- if (FD_ISSET (fd, &rset)) {
- /**
- * the only data we accept from the client is a
- * disconnect. Anything else is treated as bogus
- * and is silently discarded (also warned!!!).
- */
- if ( (readlen = read (fd, &buffer, 1)) <= 0 ) {
- close (fd);
- changelog_notify_clear_fd (cn, i);
- } else {
- /* silently discard data and log */
- gf_log (this->name, GF_LOG_WARNING,
- "misbehaving changelog client");
- }
- }
- }
-
- }
-
- cleanup:;
- pthread_cleanup_pop (1);
-
- out:
- return NULL;
-}
diff --git a/xlators/features/changelog/src/changelog-notifier.h b/xlators/features/changelog/src/changelog-notifier.h
deleted file mode 100644
index 55e728356e6..00000000000
--- a/xlators/features/changelog/src/changelog-notifier.h
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- Copyright (c) 2013 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 _CHANGELOG_NOTIFIER_H
-#define _CHANGELOG_NOTIFIER_H
-
-#include "changelog-helpers.h"
-
-void *
-changelog_notifier (void *data);
-
-#endif
diff --git a/xlators/features/changelog/src/changelog-rt.c b/xlators/features/changelog/src/changelog-rt.c
deleted file mode 100644
index c147f68ca85..00000000000
--- a/xlators/features/changelog/src/changelog-rt.c
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- Copyright (c) 2013 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 "xlator.h"
-#include "defaults.h"
-#include "logging.h"
-
-#include "changelog-rt.h"
-#include "changelog-mem-types.h"
-
-int
-changelog_rt_init (xlator_t *this, changelog_dispatcher_t *cd)
-{
- changelog_rt_t *crt = NULL;
-
- crt = GF_CALLOC (1, sizeof (*crt),
- gf_changelog_mt_rt_t);
- if (!crt)
- return -1;
-
- LOCK_INIT (&crt->lock);
-
- cd->cd_data = crt;
- cd->dispatchfn = &changelog_rt_enqueue;
-
- return 0;
-}
-
-int
-changelog_rt_fini (xlator_t *this, changelog_dispatcher_t *cd)
-{
- changelog_rt_t *crt = NULL;
-
- crt = cd->cd_data;
-
- LOCK_DESTROY (&crt->lock);
- GF_FREE (crt);
-
- return 0;
-}
-
-int
-changelog_rt_enqueue (xlator_t *this, changelog_priv_t *priv, void *cbatch,
- changelog_log_data_t *cld_0, changelog_log_data_t *cld_1)
-{
- int ret = 0;
- changelog_rt_t *crt = NULL;
-
- crt = (changelog_rt_t *) cbatch;
-
- LOCK (&crt->lock);
- {
- ret = changelog_handle_change (this, priv, cld_0);
- if (!ret && cld_1)
- ret = changelog_handle_change (this, priv, cld_1);
- }
- UNLOCK (&crt->lock);
-
- return ret;
-}
diff --git a/xlators/features/changelog/src/changelog-rt.h b/xlators/features/changelog/src/changelog-rt.h
deleted file mode 100644
index 1fc2bbc5bb9..00000000000
--- a/xlators/features/changelog/src/changelog-rt.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- Copyright (c) 2013 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 _CHANGELOG_RT_H
-#define _CHANGELOG_RT_H
-
-#include "locking.h"
-#include "timer.h"
-#include "pthread.h"
-
-#include "changelog-helpers.h"
-
-/* unused as of now - may be you would need it later */
-typedef struct changelog_rt {
- gf_lock_t lock;
-} changelog_rt_t;
-
-int
-changelog_rt_init (xlator_t *this, changelog_dispatcher_t *cd);
-int
-changelog_rt_fini (xlator_t *this, changelog_dispatcher_t *cd);
-int
-changelog_rt_enqueue (xlator_t *this, changelog_priv_t *priv, void *cbatch,
- changelog_log_data_t *cld_0, changelog_log_data_t *cld_1);
-
-#endif /* _CHANGELOG_RT_H */
diff --git a/xlators/features/changelog/src/changelog.c b/xlators/features/changelog/src/changelog.c
deleted file mode 100644
index d2e30f7f001..00000000000
--- a/xlators/features/changelog/src/changelog.c
+++ /dev/null
@@ -1,2502 +0,0 @@
-/*
- Copyright (c) 2013 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 "xlator.h"
-#include "defaults.h"
-#include "logging.h"
-#include "iobuf.h"
-
-#include "changelog-rt.h"
-#include "changelog-helpers.h"
-
-#include "changelog-encoders.h"
-#include "changelog-mem-types.h"
-
-#include <pthread.h>
-
-#include "changelog-notifier.h"
-
-static struct changelog_bootstrap
-cb_bootstrap[] = {
- {
- .mode = CHANGELOG_MODE_RT,
- .ctor = changelog_rt_init,
- .dtor = changelog_rt_fini,
- },
-};
-
-/* Entry operations - TYPE III */
-
-/**
- * entry operations do not undergo inode version checking.
- */
-
-/* {{{ */
-
-/* rmdir */
-
-int32_t
-changelog_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)
-{
- changelog_priv_t *priv = NULL;
- changelog_local_t *local = NULL;
-
- priv = this->private;
- local = frame->local;
-
- CHANGELOG_COND_GOTO (priv, ((op_ret < 0) || !local), unwind);
-
- changelog_update (this, priv, local, CHANGELOG_TYPE_ENTRY);
-
- unwind:
- changelog_dec_fop_cnt (this, priv, local);
- CHANGELOG_STACK_UNWIND (rmdir, frame, op_ret, op_errno,
- preparent, postparent, xdata);
- return 0;
-}
-
-int32_t
-changelog_rmdir_resume (call_frame_t *frame, xlator_t *this,
- loc_t *loc, int xflags, dict_t *xdata)
-{
- changelog_priv_t *priv = NULL;
-
- priv = this->private;
-
- gf_log (this->name, GF_LOG_DEBUG, "Dequeue rmdir");
- changelog_color_fop_and_inc_cnt (this, priv, frame->local);
- STACK_WIND (frame, changelog_rmdir_cbk,
- FIRST_CHILD (this), FIRST_CHILD (this)->fops->rmdir,
- loc, xflags, xdata);
- return 0;
-}
-
-int32_t
-changelog_rmdir (call_frame_t *frame, xlator_t *this,
- loc_t *loc, int xflags, dict_t *xdata)
-{
- size_t xtra_len = 0;
- changelog_priv_t *priv = NULL;
- changelog_opt_t *co = NULL;
- call_stub_t *stub = NULL;
- struct list_head queue = {0, };
- gf_boolean_t barrier_enabled = _gf_false;
-
- INIT_LIST_HEAD (&queue);
-
- priv = this->private;
- CHANGELOG_NOT_ACTIVE_THEN_GOTO (frame, priv, wind);
-
- CHANGELOG_INIT_NOCHECK (this, frame->local,
- NULL, loc->inode->gfid, 2);
-
- co = changelog_get_usable_buffer (frame->local);
- if (!co)
- goto wind;
-
- CHANGLOG_FILL_FOP_NUMBER (co, frame->root->op, fop_fn, xtra_len);
-
- co++;
- CHANGELOG_FILL_ENTRY (co, loc->pargfid, loc->name,
- entry_fn, entry_free_fn, xtra_len, wind);
-
- changelog_set_usable_record_and_length (frame->local, xtra_len, 2);
-
-/* changelog barrier */
- /* Color assignment and increment of fop_cnt for rmdir/unlink/rename
- * should be made with in priv lock if changelog barrier is not enabled.
- * Because if counter is not incremented yet, draining wakes up and
- * publishes the changelog but later these fops might hit the disk and
- * present in snapped volume but where as the intention is these fops
- * should not be present in snapped volume.
- */
- LOCK (&priv->lock);
- {
- if ((barrier_enabled = priv->barrier_enabled)) {
- stub = fop_rmdir_stub (frame, changelog_rmdir_resume,
- loc, xflags, xdata);
- if (!stub)
- __chlog_barrier_disable (this, &queue);
- else
- __chlog_barrier_enqueue (this, stub);
- } else {
- ((changelog_local_t *)frame->local)->color
- = priv->current_color;
- changelog_inc_fop_cnt (this, priv, frame->local);
- }
- }
- UNLOCK (&priv->lock);
-
- if (barrier_enabled && stub) {
- gf_log (this->name, GF_LOG_DEBUG, "Enqueue rmdir");
- goto out;
- }
- if (barrier_enabled && !stub) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to barrier FOPs, disabling changelog barrier "
- "FOP: rmdir, ERROR: %s", strerror (ENOMEM));
- chlog_barrier_dequeue_all (this, &queue);
- }
-
-/* changelog barrier */
-
- wind:
- STACK_WIND (frame, changelog_rmdir_cbk,
- FIRST_CHILD (this), FIRST_CHILD (this)->fops->rmdir,
- loc, xflags, xdata);
- out:
- return 0;
-}
-
-/* unlink */
-
-int32_t
-changelog_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)
-{
- changelog_priv_t *priv = NULL;
- changelog_local_t *local = NULL;
-
- priv = this->private;
- local = frame->local;
-
- CHANGELOG_COND_GOTO (priv, ((op_ret < 0) || !local), unwind);
-
- changelog_update (this, priv, local, CHANGELOG_TYPE_ENTRY);
-
- unwind:
- changelog_dec_fop_cnt (this, priv, local);
- CHANGELOG_STACK_UNWIND (unlink, frame, op_ret, op_errno,
- preparent, postparent, xdata);
- return 0;
-}
-
-int32_t
-changelog_unlink_resume (call_frame_t *frame, xlator_t *this,
- loc_t *loc, int xflags, dict_t *xdata)
-{
- changelog_priv_t *priv = NULL;
-
- priv = this->private;
-
- gf_log (this->name, GF_LOG_DEBUG, "Dequeue unlink");
- changelog_color_fop_and_inc_cnt (this, priv, frame->local);
- STACK_WIND (frame, changelog_unlink_cbk,
- FIRST_CHILD (this), FIRST_CHILD (this)->fops->unlink,
- loc, xflags, xdata);
- return 0;
-}
-
-int32_t
-changelog_unlink (call_frame_t *frame, xlator_t *this,
- loc_t *loc, int xflags, dict_t *xdata)
-{
- size_t xtra_len = 0;
- changelog_priv_t *priv = NULL;
- changelog_opt_t *co = NULL;
- call_stub_t *stub = NULL;
- struct list_head queue = {0, };
- gf_boolean_t barrier_enabled = _gf_false;
-
- INIT_LIST_HEAD (&queue);
-
- priv = this->private;
- CHANGELOG_NOT_ACTIVE_THEN_GOTO (frame, priv, wind);
- CHANGELOG_IF_INTERNAL_FOP_THEN_GOTO (frame, xdata, wind);
-
- CHANGELOG_INIT_NOCHECK (this, frame->local, NULL, loc->inode->gfid, 2);
-
- co = changelog_get_usable_buffer (frame->local);
- if (!co)
- goto wind;
-
- CHANGLOG_FILL_FOP_NUMBER (co, frame->root->op, fop_fn, xtra_len);
-
- co++;
- CHANGELOG_FILL_ENTRY (co, loc->pargfid, loc->name,
- entry_fn, entry_free_fn, xtra_len, wind);
-
- changelog_set_usable_record_and_length (frame->local, xtra_len, 2);
-
-/* changelog barrier */
- LOCK (&priv->lock);
- {
- if ((barrier_enabled = priv->barrier_enabled)) {
- stub = fop_unlink_stub (frame, changelog_unlink_resume,
- loc, xflags, xdata);
- if (!stub)
- __chlog_barrier_disable (this, &queue);
- else
- __chlog_barrier_enqueue (this, stub);
- } else {
- ((changelog_local_t *)frame->local)->color
- = priv->current_color;
- changelog_inc_fop_cnt (this, priv, frame->local);
- }
- }
- UNLOCK (&priv->lock);
-
- if (barrier_enabled && stub) {
- gf_log (this->name, GF_LOG_DEBUG, "Enqueue unlink");
- goto out;
- }
- if (barrier_enabled && !stub) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to barrier FOPs, disabling changelog barrier "
- "FOP: unlink, ERROR: %s", strerror (ENOMEM));
- chlog_barrier_dequeue_all (this, &queue);
- }
-
-/* changelog barrier */
-
- wind:
- STACK_WIND (frame, changelog_unlink_cbk,
- FIRST_CHILD (this), FIRST_CHILD (this)->fops->unlink,
- loc, xflags, xdata);
- out:
- return 0;
-}
-
-/* rename */
-
-int32_t
-changelog_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)
-{
- changelog_priv_t *priv = NULL;
- changelog_local_t *local = NULL;
-
- priv = this->private;
- local = frame->local;
-
- CHANGELOG_COND_GOTO (priv, ((op_ret < 0) || !local), unwind);
-
- changelog_update (this, priv, local, CHANGELOG_TYPE_ENTRY);
-
- unwind:
- changelog_dec_fop_cnt (this, priv, local);
- CHANGELOG_STACK_UNWIND (rename, frame, op_ret, op_errno,
- buf, preoldparent, postoldparent,
- prenewparent, postnewparent, xdata);
- return 0;
-}
-
-
-int32_t
-changelog_rename_resume (call_frame_t *frame, xlator_t *this,
- loc_t *oldloc, loc_t *newloc, dict_t *xdata)
-{
- changelog_priv_t *priv = NULL;
-
- priv = this->private;
-
- gf_log (this->name, GF_LOG_DEBUG, "Dequeue rename");
- changelog_color_fop_and_inc_cnt (this, priv, frame->local);
- STACK_WIND (frame, changelog_rename_cbk,
- FIRST_CHILD (this), FIRST_CHILD (this)->fops->rename,
- oldloc, newloc, xdata);
- return 0;
-}
-
-int32_t
-changelog_rename (call_frame_t *frame, xlator_t *this,
- loc_t *oldloc, loc_t *newloc, dict_t *xdata)
-{
- size_t xtra_len = 0;
- changelog_priv_t *priv = NULL;
- changelog_opt_t *co = NULL;
- call_stub_t *stub = NULL;
- struct list_head queue = {0, };
- gf_boolean_t barrier_enabled = _gf_false;
-
- INIT_LIST_HEAD (&queue);
-
- priv = this->private;
- CHANGELOG_NOT_ACTIVE_THEN_GOTO (frame, priv, wind);
-
- /* 3 == fop + oldloc + newloc */
- CHANGELOG_INIT_NOCHECK (this, frame->local,
- NULL, oldloc->inode->gfid, 3);
-
- co = changelog_get_usable_buffer (frame->local);
- if (!co)
- goto wind;
-
- CHANGLOG_FILL_FOP_NUMBER (co, frame->root->op, fop_fn, xtra_len);
-
- co++;
- CHANGELOG_FILL_ENTRY (co, oldloc->pargfid, oldloc->name,
- entry_fn, entry_free_fn, xtra_len, wind);
-
- co++;
- CHANGELOG_FILL_ENTRY (co, newloc->pargfid, newloc->name,
- entry_fn, entry_free_fn, xtra_len, wind);
-
- changelog_set_usable_record_and_length (frame->local, xtra_len, 3);
-/* changelog barrier */
- LOCK (&priv->lock);
- {
- if ((barrier_enabled = priv->barrier_enabled)) {
- stub = fop_rename_stub (frame, changelog_rename_resume,
- oldloc, newloc, xdata);
- if (!stub)
- __chlog_barrier_disable (this, &queue);
- else
- __chlog_barrier_enqueue (this, stub);
- } else {
- ((changelog_local_t *)frame->local)->color
- = priv->current_color;
- changelog_inc_fop_cnt (this, priv, frame->local);
- }
- }
- UNLOCK (&priv->lock);
-
- if (barrier_enabled && stub) {
- gf_log (this->name, GF_LOG_DEBUG, "Enqueue rename");
- goto out;
- }
- if (barrier_enabled && !stub) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to barrier FOPs, disabling changelog barrier "
- "FOP: rename, ERROR: %s", strerror (ENOMEM));
- chlog_barrier_dequeue_all (this, &queue);
- }
-/* changelog barrier */
-
- wind:
- STACK_WIND (frame, changelog_rename_cbk,
- FIRST_CHILD (this), FIRST_CHILD (this)->fops->rename,
- oldloc, newloc, xdata);
- out:
- return 0;
-}
-
-/* link */
-
-int32_t
-changelog_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)
-{
- changelog_priv_t *priv = NULL;
- changelog_local_t *local = NULL;
-
- priv = this->private;
- local = frame->local;
-
- CHANGELOG_COND_GOTO (priv, ((op_ret < 0) || !local), unwind);
-
- changelog_update (this, priv, local, CHANGELOG_TYPE_ENTRY);
-
- unwind:
- changelog_dec_fop_cnt (this, priv, local);
- CHANGELOG_STACK_UNWIND (link, frame, op_ret, op_errno,
- inode, buf, preparent, postparent, xdata);
- return 0;
-}
-
-int32_t
-changelog_link_resume (call_frame_t *frame, xlator_t *this,
- loc_t *oldloc, loc_t *newloc, dict_t *xdata)
-{
- changelog_priv_t *priv = NULL;
-
- GF_VALIDATE_OR_GOTO ("changelog", this, out);
- GF_VALIDATE_OR_GOTO ("changelog", this->fops, out);
- GF_VALIDATE_OR_GOTO ("changelog", frame, out);
-
- priv = this->private;
-
- gf_log (this->name, GF_LOG_DEBUG, "Dequeuing link");
- changelog_color_fop_and_inc_cnt (this, priv, frame->local);
- STACK_WIND (frame, changelog_link_cbk,
- FIRST_CHILD (this), FIRST_CHILD (this)->fops->link,
- oldloc, newloc, xdata);
- return 0;
-out:
- return -1;
-}
-int32_t
-changelog_link (call_frame_t *frame,
- xlator_t *this, loc_t *oldloc,
- loc_t *newloc, dict_t *xdata)
-{
- size_t xtra_len = 0;
- changelog_priv_t *priv = NULL;
- changelog_opt_t *co = NULL;
- call_stub_t *stub = NULL;
- struct list_head queue = {0, };
- gf_boolean_t barrier_enabled = _gf_false;
-
- priv = this->private;
-
- CHANGELOG_NOT_ACTIVE_THEN_GOTO (frame, priv, wind);
- CHANGELOG_IF_INTERNAL_FOP_THEN_GOTO (frame, xdata, wind);
-
- CHANGELOG_INIT_NOCHECK (this, frame->local, NULL, oldloc->gfid, 2);
-
- co = changelog_get_usable_buffer (frame->local);
- if (!co)
- goto wind;
-
- CHANGLOG_FILL_FOP_NUMBER (co, frame->root->op, fop_fn, xtra_len);
-
- co++;
- CHANGELOG_FILL_ENTRY (co, newloc->pargfid, newloc->name,
- entry_fn, entry_free_fn, xtra_len, wind);
-
- changelog_set_usable_record_and_length (frame->local, xtra_len, 2);
-
- LOCK (&priv->lock);
- {
- if ((barrier_enabled = priv->barrier_enabled)) {
- stub = fop_link_stub (frame, changelog_link_resume,
- oldloc, newloc, xdata);
- if (!stub)
- __chlog_barrier_disable (this, &queue);
- else
- __chlog_barrier_enqueue (this, stub);
- } else {
- ((changelog_local_t *)frame->local)->color
- = priv->current_color;
- changelog_inc_fop_cnt (this, priv, frame->local);
- }
- }
- UNLOCK (&priv->lock);
-
- if (barrier_enabled && stub) {
- gf_log (this->name, GF_LOG_DEBUG, "Enqueued link");
- goto out;
- }
-
- if (barrier_enabled && !stub) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to barrier FOPs, disabling changelog barrier "
- "FOP: link, ERROR: %s", strerror (ENOMEM));
- chlog_barrier_dequeue_all (this, &queue);
- }
- wind:
- STACK_WIND (frame, changelog_link_cbk,
- FIRST_CHILD (this), FIRST_CHILD (this)->fops->link,
- oldloc, newloc, xdata);
-out:
- return 0;
-}
-
-/* mkdir */
-
-int32_t
-changelog_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)
-{
- changelog_priv_t *priv = NULL;
- changelog_local_t *local = NULL;
-
- priv = this->private;
- local = frame->local;
-
- CHANGELOG_COND_GOTO (priv, ((op_ret < 0) || !local), unwind);
-
- changelog_update (this, priv, local, CHANGELOG_TYPE_ENTRY);
-
- unwind:
- changelog_dec_fop_cnt (this, priv, local);
- CHANGELOG_STACK_UNWIND (mkdir, frame, op_ret, op_errno,
- inode, buf, preparent, postparent, xdata);
- return 0;
-}
-
-int32_t
-changelog_mkdir_resume (call_frame_t *frame, xlator_t *this,
- loc_t *loc, mode_t mode,
- mode_t umask, dict_t *xdata)
-{
- changelog_priv_t *priv = NULL;
-
- GF_VALIDATE_OR_GOTO ("changelog", this, out);
- GF_VALIDATE_OR_GOTO ("changelog", this->fops, out);
- GF_VALIDATE_OR_GOTO ("changelog", frame, out);
-
- priv = this->private;
-
- gf_log (this->name, GF_LOG_DEBUG, "Dequeuing mkdir");
- changelog_color_fop_and_inc_cnt (this, priv, frame->local);
- STACK_WIND (frame, changelog_mkdir_cbk,
- FIRST_CHILD (this), FIRST_CHILD (this)->fops->mkdir,
- loc, mode, umask, xdata);
- return 0;
-out:
- return -1;
-}
-
-int32_t
-changelog_mkdir (call_frame_t *frame, xlator_t *this,
- loc_t *loc, mode_t mode, mode_t umask, dict_t *xdata)
-{
- int ret = -1;
- uuid_t gfid = {0,};
- void *uuid_req = NULL;
- size_t xtra_len = 0;
- changelog_priv_t *priv = NULL;
- changelog_opt_t *co = NULL;
- call_stub_t *stub = NULL;
- struct list_head queue = {0, };
- gf_boolean_t barrier_enabled = _gf_false;
-
- priv = this->private;
- CHANGELOG_NOT_ACTIVE_THEN_GOTO (frame, priv, wind);
-
- ret = dict_get_ptr (xdata, "gfid-req", &uuid_req);
- if (ret) {
- gf_log (this->name, GF_LOG_DEBUG,
- "failed to get gfid from dict");
- goto wind;
- }
- uuid_copy (gfid, uuid_req);
-
- CHANGELOG_INIT_NOCHECK (this, frame->local, NULL, gfid, 5);
-
- co = changelog_get_usable_buffer (frame->local);
- if (!co)
- goto wind;
-
- CHANGLOG_FILL_FOP_NUMBER (co, frame->root->op, fop_fn, xtra_len);
- co++;
-
- CHANGELOG_FILL_UINT32 (co, S_IFDIR | mode, number_fn, xtra_len);
- co++;
-
- CHANGELOG_FILL_UINT32 (co, frame->root->uid, number_fn, xtra_len);
- co++;
-
- CHANGELOG_FILL_UINT32 (co, frame->root->gid, number_fn, xtra_len);
- co++;
-
- CHANGELOG_FILL_ENTRY (co, loc->pargfid, loc->name,
- entry_fn, entry_free_fn, xtra_len, wind);
-
- changelog_set_usable_record_and_length (frame->local, xtra_len, 5);
-
- LOCK (&priv->lock);
- {
- if ((barrier_enabled = priv->barrier_enabled)) {
- stub = fop_mkdir_stub (frame, changelog_mkdir_resume,
- loc, mode, umask, xdata);
- if (!stub)
- __chlog_barrier_disable (this, &queue);
- else
- __chlog_barrier_enqueue (this, stub);
- } else {
- ((changelog_local_t *)frame->local)->color
- = priv->current_color;
- changelog_inc_fop_cnt (this, priv, frame->local);
- }
- }
- UNLOCK (&priv->lock);
-
- if (barrier_enabled && stub) {
- gf_log (this->name, GF_LOG_DEBUG, "Enqueued mkdir");
- goto out;
- }
-
- if (barrier_enabled && !stub) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to barrier FOPs, disabling changelog barrier "
- "FOP: mkdir, ERROR: %s", strerror (ENOMEM));
- chlog_barrier_dequeue_all (this, &queue);
- }
-
- wind:
- STACK_WIND (frame, changelog_mkdir_cbk,
- FIRST_CHILD (this), FIRST_CHILD (this)->fops->mkdir,
- loc, mode, umask, xdata);
-out:
- return 0;
-}
-
-/* symlink */
-
-int32_t
-changelog_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)
-{
- changelog_priv_t *priv = NULL;
- changelog_local_t *local = NULL;
-
- priv = this->private;
- local = frame->local;
-
- CHANGELOG_COND_GOTO (priv, ((op_ret < 0) || !local), unwind);
-
- changelog_update (this, priv, local, CHANGELOG_TYPE_ENTRY);
-
- unwind:
- changelog_dec_fop_cnt (this, priv, local);
- CHANGELOG_STACK_UNWIND (symlink, frame, op_ret, op_errno,
- inode, buf, preparent, postparent, xdata);
- return 0;
-}
-
-
-int32_t
-changelog_symlink_resume (call_frame_t *frame, xlator_t *this,
- const char *linkname, loc_t *loc,
- mode_t umask, dict_t *xdata)
-{
- changelog_priv_t *priv = NULL;
-
- GF_VALIDATE_OR_GOTO ("changelog", this, out);
- GF_VALIDATE_OR_GOTO ("changelog", this->fops, out);
- GF_VALIDATE_OR_GOTO ("changelog", frame, out);
-
- priv = this->private;
-
- gf_log (this->name, GF_LOG_DEBUG, "Dequeuing symlink");
- changelog_color_fop_and_inc_cnt (this, priv, frame->local);
- STACK_WIND (frame, changelog_symlink_cbk,
- FIRST_CHILD (this), FIRST_CHILD (this)->fops->symlink,
- linkname, loc, umask, xdata);
- return 0;
-out:
- return -1;
-}
-
-int32_t
-changelog_symlink (call_frame_t *frame, xlator_t *this,
- const char *linkname, loc_t *loc,
- mode_t umask, dict_t *xdata)
-{
- int ret = -1;
- size_t xtra_len = 0;
- uuid_t gfid = {0,};
- void *uuid_req = NULL;
- changelog_priv_t *priv = NULL;
- changelog_opt_t *co = NULL;
- call_stub_t *stub = NULL;
- struct list_head queue = {0, };
- gf_boolean_t barrier_enabled = _gf_false;
-
- priv = this->private;
- CHANGELOG_NOT_ACTIVE_THEN_GOTO (frame, priv, wind);
-
- ret = dict_get_ptr (xdata, "gfid-req", &uuid_req);
- if (ret) {
- gf_log (this->name, GF_LOG_DEBUG,
- "failed to get gfid from dict");
- goto wind;
- }
- uuid_copy (gfid, uuid_req);
-
- CHANGELOG_INIT_NOCHECK (this, frame->local, NULL, gfid, 2);
-
- co = changelog_get_usable_buffer (frame->local);
- if (!co)
- goto wind;
-
- CHANGLOG_FILL_FOP_NUMBER (co, frame->root->op, fop_fn, xtra_len);
- co++;
-
- CHANGELOG_FILL_ENTRY (co, loc->pargfid, loc->name,
- entry_fn, entry_free_fn, xtra_len, wind);
-
- changelog_set_usable_record_and_length (frame->local, xtra_len, 2);
-
- LOCK (&priv->lock);
- {
- if ((barrier_enabled = priv->barrier_enabled)) {
- stub = fop_symlink_stub (frame,
- changelog_symlink_resume,
- linkname, loc, umask, xdata);
- if (!stub)
- __chlog_barrier_disable (this, &queue);
- else
- __chlog_barrier_enqueue (this, stub);
- } else {
- ((changelog_local_t *)frame->local)->color
- = priv->current_color;
- changelog_inc_fop_cnt (this, priv, frame->local);
- }
- }
- UNLOCK (&priv->lock);
-
- if (barrier_enabled && stub) {
- gf_log (this->name, GF_LOG_DEBUG, "Enqueued symlink");
- goto out;
- }
-
- if (barrier_enabled && !stub) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to barrier FOPs, disabling changelog barrier "
- "FOP: symlink, ERROR: %s", strerror (ENOMEM));
- chlog_barrier_dequeue_all (this, &queue);
- }
-
- wind:
- STACK_WIND (frame, changelog_symlink_cbk,
- FIRST_CHILD (this), FIRST_CHILD (this)->fops->symlink,
- linkname, loc, umask, xdata);
-out:
- return 0;
-}
-
-/* mknod */
-
-int32_t
-changelog_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)
-{
- changelog_priv_t *priv = NULL;
- changelog_local_t *local = NULL;
-
- priv = this->private;
- local = frame->local;
-
- CHANGELOG_COND_GOTO (priv, ((op_ret < 0) || !local), unwind);
-
- changelog_update (this, priv, local, CHANGELOG_TYPE_ENTRY);
-
- unwind:
- changelog_dec_fop_cnt (this, priv, local);
- CHANGELOG_STACK_UNWIND (mknod, frame, op_ret, op_errno,
- inode, buf, preparent, postparent, xdata);
- return 0;
-}
-
-int32_t
-changelog_mknod_resume (call_frame_t *frame, xlator_t *this,
- loc_t *loc, mode_t mode, dev_t rdev,
- mode_t umask, dict_t *xdata)
-{
- changelog_priv_t *priv = NULL;
-
- GF_VALIDATE_OR_GOTO ("changelog", this, out);
- GF_VALIDATE_OR_GOTO ("changelog", this->fops, out);
- GF_VALIDATE_OR_GOTO ("changelog", frame, out);
-
- priv = this->private;
-
- gf_log (this->name, GF_LOG_DEBUG, "Dequeuing mknod");
- changelog_color_fop_and_inc_cnt (this, priv, frame->local);
- STACK_WIND (frame, changelog_mknod_cbk,
- FIRST_CHILD (this), FIRST_CHILD (this)->fops->mknod,
- loc, mode, rdev, umask, xdata);
- return 0;
-out:
- return -1;
-}
-
-int32_t
-changelog_mknod (call_frame_t *frame,
- xlator_t *this, loc_t *loc,
- mode_t mode, dev_t dev, mode_t umask, dict_t *xdata)
-{
- int ret = -1;
- uuid_t gfid = {0,};
- void *uuid_req = NULL;
- size_t xtra_len = 0;
- changelog_priv_t *priv = NULL;
- changelog_opt_t *co = NULL;
- call_stub_t *stub = NULL;
- struct list_head queue = {0, };
- gf_boolean_t barrier_enabled = _gf_false;
-
- priv = this->private;
- CHANGELOG_NOT_ACTIVE_THEN_GOTO (frame, priv, wind);
- CHANGELOG_IF_INTERNAL_FOP_THEN_GOTO (frame, xdata, wind);
-
- ret = dict_get_ptr (xdata, "gfid-req", &uuid_req);
- if (ret) {
- gf_log (this->name, GF_LOG_DEBUG,
- "failed to get gfid from dict");
- goto wind;
- }
- uuid_copy (gfid, uuid_req);
-
- CHANGELOG_INIT_NOCHECK (this, frame->local, NULL, gfid, 5);
-
- co = changelog_get_usable_buffer (frame->local);
- if (!co)
- goto wind;
-
- CHANGLOG_FILL_FOP_NUMBER (co, frame->root->op, fop_fn, xtra_len);
- co++;
-
- CHANGELOG_FILL_UINT32 (co, mode, number_fn, xtra_len);
- co++;
-
- CHANGELOG_FILL_UINT32 (co, frame->root->uid, number_fn, xtra_len);
- co++;
-
- CHANGELOG_FILL_UINT32 (co, frame->root->gid, number_fn, xtra_len);
- co++;
-
- CHANGELOG_FILL_ENTRY (co, loc->pargfid, loc->name,
- entry_fn, entry_free_fn, xtra_len, wind);
-
- changelog_set_usable_record_and_length (frame->local, xtra_len, 5);
-
- LOCK (&priv->lock);
- {
- if ((barrier_enabled = priv->barrier_enabled)) {
- stub = fop_mknod_stub (frame, changelog_mknod_resume,
- loc, mode, dev, umask, xdata);
- if (!stub)
- __chlog_barrier_disable (this, &queue);
- else
- __chlog_barrier_enqueue (this, stub);
- } else {
- ((changelog_local_t *)frame->local)->color
- = priv->current_color;
- changelog_inc_fop_cnt (this, priv, frame->local);
- }
- }
- UNLOCK (&priv->lock);
-
- if (barrier_enabled && stub) {
- gf_log (this->name, GF_LOG_DEBUG, "Enqueued mknod");
- goto out;
- }
-
- if (barrier_enabled && !stub) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to barrier FOPs, disabling changelog barrier "
- "FOP: mknod, ERROR: %s", strerror (ENOMEM));
- chlog_barrier_dequeue_all (this, &queue);
- }
-
- wind:
- STACK_WIND (frame, changelog_mknod_cbk,
- FIRST_CHILD (this), FIRST_CHILD (this)->fops->mknod,
- loc, mode, dev, umask, xdata);
-out:
- return 0;
-}
-
-/* creat */
-
-int32_t
-changelog_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)
-{
- changelog_priv_t *priv = NULL;
- changelog_local_t *local = NULL;
-
- priv = this->private;
- local = frame->local;
-
- CHANGELOG_COND_GOTO (priv, ((op_ret < 0) || !local), unwind);
-
- changelog_update (this, priv, local, CHANGELOG_TYPE_ENTRY);
-
- unwind:
- changelog_dec_fop_cnt (this, priv, local);
- CHANGELOG_STACK_UNWIND (create, frame,
- op_ret, op_errno, fd, inode,
- buf, preparent, postparent, xdata);
- return 0;
-}
-
-int32_t
-changelog_create_resume (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)
-{
- changelog_priv_t *priv = NULL;
-
- GF_VALIDATE_OR_GOTO ("changelog", this, out);
- GF_VALIDATE_OR_GOTO ("changelog", this->fops, out);
- GF_VALIDATE_OR_GOTO ("changelog", frame, out);
-
- priv = this->private;
-
- gf_log (this->name, GF_LOG_DEBUG, "Dequeuing create");
- changelog_color_fop_and_inc_cnt (this, priv, frame->local);
- STACK_WIND (frame, changelog_create_cbk,
- FIRST_CHILD (this), FIRST_CHILD (this)->fops->create,
- loc, flags, mode, umask, fd, xdata);
- return 0;
-
-out:
- return -1;
-}
-
-int32_t
-changelog_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)
-{
- int ret = -1;
- uuid_t gfid = {0,};
- void *uuid_req = NULL;
- changelog_opt_t *co = NULL;
- changelog_priv_t *priv = NULL;
- size_t xtra_len = 0;
- call_stub_t *stub = NULL;
- struct list_head queue = {0, };
- gf_boolean_t barrier_enabled = _gf_false;
-
- priv = this->private;
- CHANGELOG_NOT_ACTIVE_THEN_GOTO (frame, priv, wind);
-
- ret = dict_get_ptr (xdata, "gfid-req", &uuid_req);
- if (ret) {
- gf_log (this->name, GF_LOG_DEBUG,
- "failed to get gfid from dict");
- goto wind;
- }
- uuid_copy (gfid, uuid_req);
-
- /* init with two extra records */
- CHANGELOG_INIT_NOCHECK (this, frame->local, NULL, gfid, 5);
- if (!frame->local)
- goto wind;
-
- co = changelog_get_usable_buffer (frame->local);
- if (!co)
- goto wind;
-
- CHANGLOG_FILL_FOP_NUMBER (co, frame->root->op, fop_fn, xtra_len);
- co++;
-
- CHANGELOG_FILL_UINT32 (co, mode, number_fn, xtra_len);
- co++;
-
- CHANGELOG_FILL_UINT32 (co, frame->root->uid, number_fn, xtra_len);
- co++;
-
- CHANGELOG_FILL_UINT32 (co, frame->root->gid, number_fn, xtra_len);
- co++;
-
- CHANGELOG_FILL_ENTRY (co, loc->pargfid, loc->name,
- entry_fn, entry_free_fn, xtra_len, wind);
-
- changelog_set_usable_record_and_length (frame->local, xtra_len, 5);
-
- LOCK (&priv->lock);
- {
- if ((barrier_enabled = priv->barrier_enabled)) {
- stub = fop_create_stub (frame, changelog_create_resume,
- loc, flags, mode, umask, fd,
- xdata);
- if (!stub)
- __chlog_barrier_disable (this, &queue);
- else
- __chlog_barrier_enqueue (this, stub);
- } else {
- ((changelog_local_t *)frame->local)->color
- = priv->current_color;
- changelog_inc_fop_cnt (this, priv, frame->local);
- }
- }
- UNLOCK (&priv->lock);
-
- if (barrier_enabled && stub) {
- gf_log (this->name, GF_LOG_DEBUG, "Enqueued create");
- goto out;
- }
-
- if (barrier_enabled && !stub) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to barrier FOPs, disabling changelog barrier "
- "FOP: create, ERROR: %s", strerror (ENOMEM));
- chlog_barrier_dequeue_all (this, &queue);
- }
-
- wind:
- STACK_WIND (frame, changelog_create_cbk,
- FIRST_CHILD (this), FIRST_CHILD (this)->fops->create,
- loc, flags, mode, umask, fd, xdata);
-out:
- return 0;
-}
-
-/* }}} */
-
-
-/* Metadata modification fops - TYPE II */
-
-/* {{{ */
-
-/* {f}setattr */
-
-int32_t
-changelog_fsetattr_cbk (call_frame_t *frame,
- void *cookie, xlator_t *this, int32_t op_ret,
- int32_t op_errno, struct iatt *preop_stbuf,
- struct iatt *postop_stbuf, dict_t *xdata)
-{
- changelog_priv_t *priv = NULL;
- changelog_local_t *local = NULL;
-
- priv = this->private;
- local = frame->local;
-
- CHANGELOG_COND_GOTO (priv, ((op_ret < 0) || !local), unwind);
-
- changelog_update (this, priv, local, CHANGELOG_TYPE_METADATA);
-
- unwind:
- changelog_dec_fop_cnt (this, priv, local);
- CHANGELOG_STACK_UNWIND (fsetattr, frame, op_ret, op_errno,
- preop_stbuf, postop_stbuf, xdata);
-
- return 0;
-
-
-}
-
-int32_t
-changelog_fsetattr (call_frame_t *frame,
- xlator_t *this, fd_t *fd,
- struct iatt *stbuf, int32_t valid, dict_t *xdata)
-{
- changelog_priv_t *priv = NULL;
- changelog_opt_t *co = NULL;
- size_t xtra_len = 0;
-
- priv = this->private;
- CHANGELOG_NOT_ACTIVE_THEN_GOTO (frame, priv, wind);
-
- CHANGELOG_OP_BOUNDARY_CHECK (frame, wind);
-
- CHANGELOG_INIT (this, frame->local,
- fd->inode, fd->inode->gfid, 1);
- if (!frame->local)
- goto wind;
-
- co = changelog_get_usable_buffer (frame->local);
- if (!co)
- goto wind;
-
- CHANGLOG_FILL_FOP_NUMBER (co, frame->root->op, fop_fn, xtra_len);
-
- changelog_set_usable_record_and_length (frame->local, xtra_len, 1);
-
- wind:
- changelog_color_fop_and_inc_cnt (this, priv, frame->local);
- STACK_WIND (frame, changelog_fsetattr_cbk,
- FIRST_CHILD (this), FIRST_CHILD (this)->fops->fsetattr,
- fd, stbuf, valid, xdata);
- return 0;
-
-
-}
-
-int32_t
-changelog_setattr_cbk (call_frame_t *frame,
- void *cookie, xlator_t *this, int32_t op_ret,
- int32_t op_errno, struct iatt *preop_stbuf,
- struct iatt *postop_stbuf, dict_t *xdata)
-{
- changelog_priv_t *priv = NULL;
- changelog_local_t *local = NULL;
-
- priv = this->private;
- local = frame->local;
-
- CHANGELOG_COND_GOTO (priv, ((op_ret < 0) || !local), unwind);
-
- changelog_update (this, priv, local, CHANGELOG_TYPE_METADATA);
-
- unwind:
- changelog_dec_fop_cnt (this, priv, local);
- CHANGELOG_STACK_UNWIND (setattr, frame, op_ret, op_errno,
- preop_stbuf, postop_stbuf, xdata);
-
- return 0;
-}
-
-int32_t
-changelog_setattr (call_frame_t *frame,
- xlator_t *this, loc_t *loc,
- struct iatt *stbuf, int32_t valid, dict_t *xdata)
-{
- changelog_priv_t *priv = NULL;
- changelog_opt_t *co = NULL;
- size_t xtra_len = 0;
-
- priv = this->private;
- CHANGELOG_NOT_ACTIVE_THEN_GOTO (frame, priv, wind);
-
- CHANGELOG_OP_BOUNDARY_CHECK (frame, wind);
-
- CHANGELOG_INIT (this, frame->local,
- loc->inode, loc->inode->gfid, 1);
- if (!frame->local)
- goto wind;
-
- co = changelog_get_usable_buffer (frame->local);
- if (!co)
- goto wind;
-
- CHANGLOG_FILL_FOP_NUMBER (co, frame->root->op, fop_fn, xtra_len);
-
- changelog_set_usable_record_and_length (frame->local, xtra_len, 1);
-
- wind:
- changelog_color_fop_and_inc_cnt (this, priv, frame->local);
- STACK_WIND (frame, changelog_setattr_cbk,
- FIRST_CHILD (this), FIRST_CHILD (this)->fops->setattr,
- loc, stbuf, valid, xdata);
- return 0;
-}
-
-/* {f}removexattr */
-
-int32_t
-changelog_fremovexattr_cbk (call_frame_t *frame,
- void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
-{
- changelog_priv_t *priv = NULL;
- changelog_local_t *local = NULL;
-
- priv = this->private;
- local = frame->local;
-
- CHANGELOG_COND_GOTO (priv, ((op_ret < 0) || !local), unwind);
-
- changelog_update (this, priv, local, CHANGELOG_TYPE_METADATA);
-
- unwind:
- changelog_dec_fop_cnt (this, priv, local);
- CHANGELOG_STACK_UNWIND (fremovexattr, frame, op_ret, op_errno, xdata);
-
- return 0;
-}
-
-int32_t
-changelog_fremovexattr (call_frame_t *frame, xlator_t *this,
- fd_t *fd, const char *name, dict_t *xdata)
-{
- changelog_priv_t *priv = NULL;
- changelog_opt_t *co = NULL;
- size_t xtra_len = 0;
-
- priv = this->private;
- CHANGELOG_NOT_ACTIVE_THEN_GOTO (frame, priv, wind);
-
- CHANGELOG_OP_BOUNDARY_CHECK (frame, wind);
-
- CHANGELOG_INIT (this, frame->local,
- fd->inode, fd->inode->gfid, 1);
-
- co = changelog_get_usable_buffer (frame->local);
- if (!co)
- goto wind;
-
- CHANGLOG_FILL_FOP_NUMBER (co, frame->root->op, fop_fn, xtra_len);
-
- changelog_set_usable_record_and_length (frame->local, xtra_len, 1);
-
- wind:
- changelog_color_fop_and_inc_cnt (this, priv, frame->local);
- STACK_WIND (frame, changelog_fremovexattr_cbk,
- FIRST_CHILD (this), FIRST_CHILD (this)->fops->fremovexattr,
- fd, name, xdata);
- return 0;
-}
-
-int32_t
-changelog_removexattr_cbk (call_frame_t *frame,
- void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
-{
- changelog_priv_t *priv = NULL;
- changelog_local_t *local = NULL;
-
- priv = this->private;
- local = frame->local;
-
- CHANGELOG_COND_GOTO (priv, ((op_ret < 0) || !local), unwind);
-
- changelog_update (this, priv, local, CHANGELOG_TYPE_METADATA);
-
- unwind:
- changelog_dec_fop_cnt (this, priv, local);
- CHANGELOG_STACK_UNWIND (removexattr, frame, op_ret, op_errno, xdata);
-
- return 0;
-}
-
-int32_t
-changelog_removexattr (call_frame_t *frame, xlator_t *this,
- loc_t *loc, const char *name, dict_t *xdata)
-{
- changelog_priv_t *priv = NULL;
- changelog_opt_t *co = NULL;
- size_t xtra_len = 0;
-
- priv = this->private;
- CHANGELOG_NOT_ACTIVE_THEN_GOTO (frame, priv, wind);
-
- CHANGELOG_OP_BOUNDARY_CHECK (frame, wind);
-
- CHANGELOG_INIT (this, frame->local,
- loc->inode, loc->inode->gfid, 1);
-
- co = changelog_get_usable_buffer (frame->local);
- if (!co)
- goto wind;
-
- CHANGLOG_FILL_FOP_NUMBER (co, frame->root->op, fop_fn, xtra_len);
-
- changelog_set_usable_record_and_length (frame->local, xtra_len, 1);
-
- wind:
- changelog_color_fop_and_inc_cnt (this, priv, frame->local);
- STACK_WIND (frame, changelog_removexattr_cbk,
- FIRST_CHILD (this), FIRST_CHILD (this)->fops->removexattr,
- loc, name, xdata);
- return 0;
-}
-
-/* {f}setxattr */
-
-int32_t
-changelog_setxattr_cbk (call_frame_t *frame,
- void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
-{
- changelog_priv_t *priv = NULL;
- changelog_local_t *local = NULL;
-
- priv = this->private;
- local = frame->local;
-
- CHANGELOG_COND_GOTO (priv, ((op_ret < 0) || !local), unwind);
-
- changelog_update (this, priv, local, CHANGELOG_TYPE_METADATA);
-
- unwind:
- changelog_dec_fop_cnt (this, priv, local);
- CHANGELOG_STACK_UNWIND (setxattr, frame, op_ret, op_errno, xdata);
-
- return 0;
-}
-
-int32_t
-changelog_setxattr (call_frame_t *frame,
- xlator_t *this, loc_t *loc,
- dict_t *dict, int32_t flags, dict_t *xdata)
-{
- changelog_priv_t *priv = NULL;
- changelog_opt_t *co = NULL;
- size_t xtra_len = 0;
-
- priv = this->private;
- CHANGELOG_NOT_ACTIVE_THEN_GOTO (frame, priv, wind);
-
- CHANGELOG_OP_BOUNDARY_CHECK (frame, wind);
-
- CHANGELOG_INIT (this, frame->local,
- loc->inode, loc->inode->gfid, 1);
-
- co = changelog_get_usable_buffer (frame->local);
- if (!co)
- goto wind;
-
- CHANGLOG_FILL_FOP_NUMBER (co, frame->root->op, fop_fn, xtra_len);
-
- changelog_set_usable_record_and_length (frame->local, xtra_len, 1);
-
- wind:
- changelog_color_fop_and_inc_cnt (this, priv, frame->local);
- STACK_WIND (frame, changelog_setxattr_cbk,
- FIRST_CHILD (this), FIRST_CHILD (this)->fops->setxattr,
- loc, dict, flags, xdata);
- return 0;
-}
-
-int32_t
-changelog_fsetxattr_cbk (call_frame_t *frame,
- void *cookie, xlator_t *this, int32_t op_ret,
- int32_t op_errno, dict_t *xdata)
-{
- changelog_priv_t *priv = NULL;
- changelog_local_t *local = NULL;
-
- priv = this->private;
- local = frame->local;
-
- CHANGELOG_COND_GOTO (priv, ((op_ret < 0) || !local), unwind);
-
- changelog_update (this, priv, local, CHANGELOG_TYPE_METADATA);
-
- unwind:
- changelog_dec_fop_cnt (this, priv, local);
- CHANGELOG_STACK_UNWIND (fsetxattr, frame, op_ret, op_errno, xdata);
-
- return 0;
-}
-
-int32_t
-changelog_fsetxattr (call_frame_t *frame,
- xlator_t *this, fd_t *fd, dict_t *dict,
- int32_t flags, dict_t *xdata)
-{
- changelog_priv_t *priv = NULL;
- changelog_opt_t *co = NULL;
- size_t xtra_len = 0;
-
- priv = this->private;
- CHANGELOG_NOT_ACTIVE_THEN_GOTO (frame, priv, wind);
-
- CHANGELOG_OP_BOUNDARY_CHECK (frame, wind);
-
- CHANGELOG_INIT (this, frame->local,
- fd->inode, fd->inode->gfid, 1);
-
- co = changelog_get_usable_buffer (frame->local);
- if (!co)
- goto wind;
-
- CHANGLOG_FILL_FOP_NUMBER (co, frame->root->op, fop_fn, xtra_len);
-
- changelog_set_usable_record_and_length (frame->local, xtra_len, 1);
-
- wind:
- changelog_color_fop_and_inc_cnt (this, priv, frame->local);
- STACK_WIND (frame, changelog_fsetxattr_cbk,
- FIRST_CHILD (this), FIRST_CHILD (this)->fops->fsetxattr,
- fd, dict, flags, xdata);
- return 0;
-}
-
-/* }}} */
-
-
-/* Data modification fops - TYPE I */
-
-/* {{{ */
-
-/* {f}truncate() */
-
-int32_t
-changelog_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)
-{
- changelog_priv_t *priv = NULL;
- changelog_local_t *local = NULL;
-
- priv = this->private;
- local = frame->local;
-
- CHANGELOG_COND_GOTO (priv, ((op_ret < 0) || !local), unwind);
-
- changelog_update (this, priv, local, CHANGELOG_TYPE_DATA);
-
- unwind:
- changelog_dec_fop_cnt (this, priv, local);
- CHANGELOG_STACK_UNWIND (truncate, frame,
- op_ret, op_errno, prebuf, postbuf, xdata);
- return 0;
-}
-
-int32_t
-changelog_truncate (call_frame_t *frame,
- xlator_t *this, loc_t *loc, off_t offset, dict_t *xdata)
-{
- changelog_priv_t *priv = NULL;
-
- priv = this->private;
- CHANGELOG_NOT_ACTIVE_THEN_GOTO (frame, priv, wind);
-
- CHANGELOG_INIT (this, frame->local,
- loc->inode, loc->inode->gfid, 0);
- LOCK(&priv->c_snap_lock);
- {
- if (priv->c_snap_fd != -1 &&
- priv->barrier_enabled == _gf_true) {
- changelog_snap_handle_ascii_change (this,
- &( ((changelog_local_t *)(frame->local))->cld));
- }
- }
- UNLOCK(&priv->c_snap_lock);
-
-
- wind:
- changelog_color_fop_and_inc_cnt (this, priv, frame->local);
- STACK_WIND (frame, changelog_truncate_cbk,
- FIRST_CHILD (this), FIRST_CHILD (this)->fops->truncate,
- loc, offset, xdata);
- return 0;
-}
-
-int32_t
-changelog_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)
-{
- changelog_priv_t *priv = NULL;
- changelog_local_t *local = NULL;
-
- priv = this->private;
- local = frame->local;
-
- CHANGELOG_COND_GOTO (priv, ((op_ret < 0) || !local), unwind);
-
- changelog_update (this, priv, local, CHANGELOG_TYPE_DATA);
-
- unwind:
- changelog_dec_fop_cnt (this, priv, local);
- CHANGELOG_STACK_UNWIND (ftruncate, frame,
- op_ret, op_errno, prebuf, postbuf, xdata);
- return 0;
-}
-
-int32_t
-changelog_ftruncate (call_frame_t *frame,
- xlator_t *this, fd_t *fd, off_t offset, dict_t *xdata)
-{
- changelog_priv_t *priv = NULL;
-
- priv = this->private;
- CHANGELOG_NOT_ACTIVE_THEN_GOTO (frame, priv, wind);
-
- CHANGELOG_INIT (this, frame->local,
- fd->inode, fd->inode->gfid, 0);
- LOCK(&priv->c_snap_lock);
- {
- if (priv->c_snap_fd != -1 &&
- priv->barrier_enabled == _gf_true) {
- changelog_snap_handle_ascii_change (this,
- &( ((changelog_local_t *)(frame->local))->cld));
- }
- }
- UNLOCK(&priv->c_snap_lock);
-
- wind:
- changelog_color_fop_and_inc_cnt (this, priv, frame->local);
- STACK_WIND (frame, changelog_ftruncate_cbk,
- FIRST_CHILD (this), FIRST_CHILD (this)->fops->ftruncate,
- fd, offset, xdata);
- return 0;
-}
-
-/* writev() */
-
-int32_t
-changelog_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)
-{
- changelog_priv_t *priv = NULL;
- changelog_local_t *local = NULL;
-
- priv = this->private;
- local = frame->local;
-
- CHANGELOG_COND_GOTO (priv, ((op_ret <= 0) || !local), unwind);
-
- changelog_update (this, priv, local, CHANGELOG_TYPE_DATA);
-
- unwind:
- changelog_dec_fop_cnt (this, priv, local);
- CHANGELOG_STACK_UNWIND (writev, frame,
- op_ret, op_errno, prebuf, postbuf, xdata);
- return 0;
-}
-
-int32_t
-changelog_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)
-{
- changelog_priv_t *priv = NULL;
-
- priv = this->private;
- CHANGELOG_NOT_ACTIVE_THEN_GOTO (frame, priv, wind);
-
- CHANGELOG_INIT (this, frame->local,
- fd->inode, fd->inode->gfid, 0);
- LOCK(&priv->c_snap_lock);
- {
- if (priv->c_snap_fd != -1 &&
- priv->barrier_enabled == _gf_true) {
- changelog_snap_handle_ascii_change (this,
- &( ((changelog_local_t *)(frame->local))->cld));
- }
- }
- UNLOCK(&priv->c_snap_lock);
-
- wind:
- changelog_color_fop_and_inc_cnt (this, priv, frame->local);
- STACK_WIND (frame, changelog_writev_cbk, FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->writev, fd, vector,
- count, offset, flags, iobref, xdata);
- return 0;
-}
-
-/* }}} */
-
-/**
- * The
- * - @init ()
- * - @fini ()
- * - @reconfigure ()
- * ... and helper routines
- */
-
-/**
- * needed if there are more operation modes in the future.
- */
-static void
-changelog_assign_opmode (changelog_priv_t *priv, char *mode)
-{
- if ( strncmp (mode, "realtime", 8) == 0 ) {
- priv->op_mode = CHANGELOG_MODE_RT;
- }
-}
-
-static void
-changelog_assign_encoding (changelog_priv_t *priv, char *enc)
-{
- if ( strncmp (enc, "binary", 6) == 0 ) {
- priv->encode_mode = CHANGELOG_ENCODE_BINARY;
- } else if ( strncmp (enc, "ascii", 5) == 0 ) {
- priv->encode_mode = CHANGELOG_ENCODE_ASCII;
- }
-}
-
-static void
-changelog_assign_barrier_timeout(changelog_priv_t *priv, uint32_t timeout)
-{
- LOCK (&priv->lock);
- {
- priv->timeout.tv_sec = timeout;
- }
- UNLOCK (&priv->lock);
-}
-
-/* cleanup any helper threads that are running */
-static void
-changelog_cleanup_helper_threads (xlator_t *this, changelog_priv_t *priv)
-{
- int ret = 0;
-
- if (priv->cr.rollover_th) {
- changelog_thread_cleanup (this, priv->cr.rollover_th);
- priv->cr.rollover_th = 0;
- ret = close (priv->cr_wfd);
- if (ret)
- gf_log (this->name, GF_LOG_ERROR,
- "error closing write end of rollover pipe"
- " (reason: %s)", strerror (errno));
- }
-
- if (priv->cf.fsync_th) {
- changelog_thread_cleanup (this, priv->cf.fsync_th);
- priv->cf.fsync_th = 0;
- }
-}
-
-/* spawn helper thread; cleaning up in case of errors */
-static int
-changelog_spawn_helper_threads (xlator_t *this, changelog_priv_t *priv)
-{
- int ret = 0;
- int flags = 0;
- int pipe_fd[2] = {0, 0};
-
- /* Geo-Rep snapshot dependency:
- *
- * To implement explicit rollover of changlog journal on barrier
- * notification, a pipe is created to communicate between
- * 'changelog_rollover' thread and changelog main thread. The select
- * call used to wait till roll-over time in changelog_rollover thread
- * is modified to wait on read end of the pipe. When barrier
- * notification comes (i.e, in 'reconfigure'), select in
- * changelog_rollover thread is woken up explicitly by writing into
- * the write end of the pipe in 'reconfigure'.
- */
-
- ret = pipe (pipe_fd);
- if (ret == -1) {
- gf_log (this->name, GF_LOG_ERROR,
- "Cannot create pipe (reason: %s)", strerror (errno));
- goto out;
- }
-
- /* writer is non-blocking */
- flags = fcntl (pipe_fd[1], F_GETFL);
- flags |= O_NONBLOCK;
-
- ret = fcntl (pipe_fd[1], F_SETFL, flags);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "failed to set O_NONBLOCK flag");
- goto out;
- }
-
- priv->cr_wfd = pipe_fd[1];
- priv->cr.rfd = pipe_fd[0];
-
- priv->cr.this = this;
- ret = gf_thread_create (&priv->cr.rollover_th,
- NULL, changelog_rollover, priv);
- if (ret)
- goto out;
-
- if (priv->fsync_interval) {
- priv->cf.this = this;
- ret = gf_thread_create (&priv->cf.fsync_th,
- NULL, changelog_fsync_thread, priv);
- }
-
- if (ret)
- changelog_cleanup_helper_threads (this, priv);
-
- out:
- return ret;
-}
-
-/* cleanup the notifier thread */
-static int
-changelog_cleanup_notifier (xlator_t *this, changelog_priv_t *priv)
-{
- int ret = 0;
-
- if (priv->cn.notify_th) {
- changelog_thread_cleanup (this, priv->cn.notify_th);
- priv->cn.notify_th = 0;
-
- ret = close (priv->wfd);
- if (ret)
- gf_log (this->name, GF_LOG_ERROR,
- "error closing writer end of notifier pipe"
- " (reason: %s)", strerror (errno));
- }
-
- return ret;
-}
-
-/* spawn the notifier thread - nop if already running */
-static int
-changelog_spawn_notifier (xlator_t *this, changelog_priv_t *priv)
-{
- int ret = 0;
- int flags = 0;
- int pipe_fd[2] = {0, 0};
-
- if (priv->cn.notify_th)
- goto out; /* notifier thread already running */
-
- ret = pipe (pipe_fd);
- if (ret == -1) {
- gf_log (this->name, GF_LOG_ERROR,
- "Cannot create pipe (reason: %s)", strerror (errno));
- goto out;
- }
-
- /* writer is non-blocking */
- flags = fcntl (pipe_fd[1], F_GETFL);
- flags |= O_NONBLOCK;
-
- ret = fcntl (pipe_fd[1], F_SETFL, flags);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "failed to set O_NONBLOCK flag");
- goto out;
- }
-
- priv->wfd = pipe_fd[1];
-
- priv->cn.this = this;
- priv->cn.rfd = pipe_fd[0];
-
- ret = gf_thread_create (&priv->cn.notify_th,
- NULL, changelog_notifier, priv);
-
- out:
- return ret;
-}
-
-int
-notify (xlator_t *this, int event, void *data, ...)
-{
- changelog_priv_t *priv = NULL;
- dict_t *dict = NULL;
- char buf[1] = {1};
- int barrier = DICT_DEFAULT;
- gf_boolean_t bclean_req = _gf_false;
- int ret = 0;
- struct list_head queue = {0, };
-
- INIT_LIST_HEAD (&queue);
-
- priv = this->private;
- if (!priv)
- goto out;
-
- if (event == GF_EVENT_TRANSLATOR_OP) {
-
- dict = data;
-
- barrier = dict_get_str_boolean (dict, "barrier", DICT_DEFAULT);
-
- switch (barrier) {
- case DICT_ERROR:
- gf_log (this->name, GF_LOG_ERROR,
- "Barrier dict_get_str_boolean failed");
- ret = -1;
- goto out;
-
- case BARRIER_OFF:
- gf_log (this->name, GF_LOG_INFO,
- "Barrier off notification");
-
- CHANGELOG_NOT_ON_THEN_GOTO(priv, ret, out);
- LOCK(&priv->c_snap_lock);
- {
- changelog_snap_logging_stop (this, priv);
- }
- UNLOCK(&priv->c_snap_lock);
-
- LOCK (&priv->bflags.lock);
- {
- if (priv->bflags.barrier_ext == _gf_false)
- ret = -1;
- }
- UNLOCK (&priv->bflags.lock);
-
- if (ret == -1 ) {
- gf_log (this->name, GF_LOG_ERROR, "Received"
- " another barrier off notification"
- " while already off");
- goto out;
- }
-
- /* Stop changelog barrier and dequeue all fops */
- LOCK (&priv->lock);
- {
- if (priv->barrier_enabled == _gf_true)
- __chlog_barrier_disable (this, &queue);
- else
- ret = -1;
- }
- UNLOCK (&priv->lock);
- /* If ret = -1, then changelog barrier is already
- * disabled because of error or timeout.
- */
- if (ret == 0) {
- chlog_barrier_dequeue_all(this, &queue);
- gf_log(this->name, GF_LOG_INFO,
- "Disabled changelog barrier");
- } else {
- gf_log (this->name, GF_LOG_ERROR,
- "Changelog barrier already disabled");
- }
-
- LOCK (&priv->bflags.lock);
- {
- priv->bflags.barrier_ext = _gf_false;
- }
- UNLOCK (&priv->bflags.lock);
-
- goto out;
-
- case BARRIER_ON:
- gf_log (this->name, GF_LOG_INFO,
- "Barrier on notification");
-
- CHANGELOG_NOT_ON_THEN_GOTO(priv, ret, out);
- LOCK(&priv->c_snap_lock);
- {
- changelog_snap_logging_start (this, priv);
- }
- UNLOCK(&priv->c_snap_lock);
-
- LOCK (&priv->bflags.lock);
- {
- if (priv->bflags.barrier_ext == _gf_true)
- ret = -1;
- else
- priv->bflags.barrier_ext = _gf_true;
- }
- UNLOCK (&priv->bflags.lock);
-
- if (ret == -1 ) {
- gf_log (this->name, GF_LOG_ERROR, "Received"
- " another barrier on notification when"
- " last one is not served yet");
- goto out;
- }
-
- ret = pthread_mutex_lock (&priv->bn.bnotify_mutex);
- CHANGELOG_PTHREAD_ERROR_HANDLE_1 (ret, out,
- bclean_req);
- {
- priv->bn.bnotify = _gf_true;
- }
- ret = pthread_mutex_unlock (&priv->bn.bnotify_mutex);
- CHANGELOG_PTHREAD_ERROR_HANDLE_1 (ret, out,
- bclean_req);
-
- /* Start changelog barrier */
- LOCK (&priv->lock);
- {
- ret = __chlog_barrier_enable (this, priv);
- }
- UNLOCK (&priv->lock);
- if (ret == -1) {
- changelog_barrier_cleanup (this, priv, &queue);
- goto out;
- }
-
- gf_log(this->name, GF_LOG_INFO,
- "Enabled changelog barrier");
-
- ret = changelog_barrier_notify(priv, buf);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Explicit roll over: write failed");
- changelog_barrier_cleanup (this, priv, &queue);
- ret = -1;
- goto out;
- }
-
- ret = pthread_mutex_lock (&priv->bn.bnotify_mutex);
- CHANGELOG_PTHREAD_ERROR_HANDLE_1 (ret, out,
- bclean_req);
- {
- /* The while condition check is required here to
- * handle spurious wakeup of cond wait that can
- * happen with pthreads. See man page */
- while (priv->bn.bnotify == _gf_true) {
- ret = pthread_cond_wait (
- &priv->bn.bnotify_cond,
- &priv->bn.bnotify_mutex);
- CHANGELOG_PTHREAD_ERROR_HANDLE_1 (ret,
- out,
- bclean_req);
- }
- }
- ret = pthread_mutex_unlock (&priv->bn.bnotify_mutex);
- CHANGELOG_PTHREAD_ERROR_HANDLE_1 (ret, out, bclean_req);
- gf_log (this->name, GF_LOG_INFO,
- "Woke up: bnotify conditional wait");
-
- ret = 0;
- goto out;
-
- case DICT_DEFAULT:
- gf_log (this->name, GF_LOG_ERROR,
- "barrier key not found");
- ret = -1;
- goto out;
-
- default:
- gf_log (this->name, GF_LOG_ERROR,
- "Something went bad in dict_get_str_boolean");
- ret = -1;
- goto out;
- }
- } else {
- ret = default_notify (this, event, data);
- }
-
- out:
- if (bclean_req)
- changelog_barrier_cleanup (this, priv, &queue);
-
- return ret;
-}
-
-int32_t
-mem_acct_init (xlator_t *this)
-{
- int ret = -1;
-
- if (!this)
- return ret;
-
- ret = xlator_mem_acct_init (this, gf_changelog_mt_end + 1);
-
- if (ret != 0) {
- gf_log (this->name, GF_LOG_WARNING, "Memory accounting"
- " init failed");
- return ret;
- }
-
- return ret;
-}
-
-static int
-changelog_init (xlator_t *this, changelog_priv_t *priv)
-{
- int i = 0;
- int ret = -1;
- struct timeval tv = {0,};
- changelog_log_data_t cld = {0,};
-
- ret = gettimeofday (&tv, NULL);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "gettimeofday() failure");
- goto out;
- }
-
- priv->slice.tv_start = tv;
-
- priv->maps[CHANGELOG_TYPE_DATA] = "D ";
- priv->maps[CHANGELOG_TYPE_METADATA] = "M ";
- priv->maps[CHANGELOG_TYPE_ENTRY] = "E ";
-
- for (; i < CHANGELOG_MAX_TYPE; i++) {
- /* start with version 1 */
- priv->slice.changelog_version[i] = 1;
- }
-
- if (!priv->active)
- return ret;
-
- /* spawn the notifier thread */
- ret = changelog_spawn_notifier (this, priv);
- if (ret)
- goto out;
-
- /**
- * start with a fresh changelog file every time. this is done
- * in case there was an encoding change. so... things are kept
- * simple here.
- */
- ret = changelog_fill_rollover_data (&cld, _gf_false);
- if(ret)
- goto out;
-
- ret = htime_open (this, priv, cld.cld_roll_time);
- /* call htime open with cld's rollover_time */
- if (ret)
- goto out;
-
- LOCK (&priv->lock);
- {
- ret = changelog_inject_single_event (this, priv, &cld);
- }
- UNLOCK (&priv->lock);
-
- /* ... and finally spawn the helpers threads */
- ret = changelog_spawn_helper_threads (this, priv);
-
- out:
- return ret;
-}
-
-/* Init all pthread condition variables and locks in changelog*/
-static int
-changelog_pthread_init (xlator_t *this, changelog_priv_t *priv)
-{
- gf_boolean_t bn_mutex_init = _gf_false;
- gf_boolean_t bn_cond_init = _gf_false;
- gf_boolean_t dm_mutex_black_init = _gf_false;
- gf_boolean_t dm_cond_black_init = _gf_false;
- gf_boolean_t dm_mutex_white_init = _gf_false;
- gf_boolean_t dm_cond_white_init = _gf_false;
- int ret = 0;
-
- if ((ret = pthread_mutex_init(&priv->bn.bnotify_mutex, NULL)) != 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "bnotify pthread_mutex_init failed (%d)", ret);
- ret = -1;
- goto out;
- }
- bn_mutex_init = _gf_true;
-
- if ((ret = pthread_cond_init(&priv->bn.bnotify_cond, NULL)) != 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "bnotify pthread_cond_init failed (%d)", ret);
- ret = -1;
- goto out;
- }
- bn_cond_init = _gf_true;
-
- if ((ret = pthread_mutex_init(&priv->dm.drain_black_mutex, NULL)) != 0)
- {
- gf_log (this->name, GF_LOG_ERROR,
- "drain_black pthread_mutex_init failed (%d)", ret);
- ret = -1;
- goto out;
- }
- dm_mutex_black_init = _gf_true;
-
- if ((ret = pthread_cond_init(&priv->dm.drain_black_cond, NULL)) != 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "drain_black pthread_cond_init failed (%d)", ret);
- ret = -1;
- goto out;
- }
- dm_cond_black_init = _gf_true;
-
- if ((ret = pthread_mutex_init(&priv->dm.drain_white_mutex, NULL)) != 0)
- {
- gf_log (this->name, GF_LOG_ERROR,
- "drain_white pthread_mutex_init failed (%d)", ret);
- ret = -1;
- goto out;
- }
- dm_mutex_white_init = _gf_true;
-
- if ((ret = pthread_cond_init(&priv->dm.drain_white_cond, NULL)) != 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "drain_white pthread_cond_init failed (%d)", ret);
- ret = -1;
- goto out;
- }
- dm_cond_white_init = _gf_true;
- out:
- if (ret) {
- if (bn_mutex_init)
- pthread_mutex_destroy(&priv->bn.bnotify_mutex);
- if (bn_cond_init)
- pthread_cond_destroy (&priv->bn.bnotify_cond);
- if (dm_mutex_black_init)
- pthread_mutex_destroy(&priv->dm.drain_black_mutex);
- if (dm_cond_black_init)
- pthread_cond_destroy (&priv->dm.drain_black_cond);
- if (dm_mutex_white_init)
- pthread_mutex_destroy(&priv->dm.drain_white_mutex);
- if (dm_cond_white_init)
- pthread_cond_destroy (&priv->dm.drain_white_cond);
- }
- return ret;
-}
-
-/* Destroy all pthread condition variables and locks in changelog */
-static inline void
-changelog_pthread_destroy (changelog_priv_t *priv)
-{
- pthread_mutex_destroy (&priv->bn.bnotify_mutex);
- pthread_cond_destroy (&priv->bn.bnotify_cond);
- pthread_mutex_destroy (&priv->dm.drain_black_mutex);
- pthread_cond_destroy (&priv->dm.drain_black_cond);
- pthread_mutex_destroy (&priv->dm.drain_white_mutex);
- pthread_cond_destroy (&priv->dm.drain_white_cond);
- LOCK_DESTROY (&priv->bflags.lock);
-}
-
-int
-reconfigure (xlator_t *this, dict_t *options)
-{
- int ret = 0;
- char *tmp = NULL;
- changelog_priv_t *priv = NULL;
- gf_boolean_t active_earlier = _gf_true;
- gf_boolean_t active_now = _gf_true;
- changelog_time_slice_t *slice = NULL;
- changelog_log_data_t cld = {0,};
- char htime_dir[PATH_MAX] = {0,};
- char csnap_dir[PATH_MAX] = {0,};
- struct timeval tv = {0,};
- uint32_t timeout = 0;
-
- priv = this->private;
- if (!priv)
- goto out;
-
- ret = -1;
- active_earlier = priv->active;
-
- /* first stop the rollover and the fsync thread */
- changelog_cleanup_helper_threads (this, priv);
-
- GF_OPTION_RECONF ("changelog-dir", tmp, options, str, out);
- if (!tmp) {
- gf_log (this->name, GF_LOG_ERROR,
- "\"changelog-dir\" option is not set");
- goto out;
- }
-
- GF_FREE (priv->changelog_dir);
- priv->changelog_dir = gf_strdup (tmp);
- if (!priv->changelog_dir)
- goto out;
-
- ret = mkdir_p (priv->changelog_dir, 0600, _gf_true);
-
- if (ret)
- goto out;
- CHANGELOG_FILL_HTIME_DIR(priv->changelog_dir, htime_dir);
- ret = mkdir_p (htime_dir, 0600, _gf_true);
-
- if (ret)
- goto out;
-
- CHANGELOG_FILL_CSNAP_DIR(priv->changelog_dir, csnap_dir);
- ret = mkdir_p (csnap_dir, 0600, _gf_true);
-
- if (ret)
- goto out;
-
- GF_OPTION_RECONF ("changelog", active_now, options, bool, out);
-
- /**
- * changelog_handle_change() handles changes that could possibly
- * have been submit changes before changelog deactivation.
- */
- if (!active_now)
- priv->active = _gf_false;
-
- GF_OPTION_RECONF ("op-mode", tmp, options, str, out);
- changelog_assign_opmode (priv, tmp);
-
- tmp = NULL;
-
- GF_OPTION_RECONF ("encoding", tmp, options, str, out);
- changelog_assign_encoding (priv, tmp);
-
- GF_OPTION_RECONF ("rollover-time",
- priv->rollover_time, options, int32, out);
- GF_OPTION_RECONF ("fsync-interval",
- priv->fsync_interval, options, int32, out);
- GF_OPTION_RECONF ("changelog-barrier-timeout",
- timeout, options, time, out);
- changelog_assign_barrier_timeout (priv, timeout);
-
- if (active_now || active_earlier) {
- ret = changelog_fill_rollover_data (&cld, !active_now);
- if (ret)
- goto out;
-
- slice = &priv->slice;
-
- LOCK (&priv->lock);
- {
- ret = changelog_inject_single_event (this, priv, &cld);
- if (!ret && active_now)
- SLICE_VERSION_UPDATE (slice);
- }
- UNLOCK (&priv->lock);
-
- if (ret)
- goto out;
-
- if (active_now) {
- if (!active_earlier) {
- if (gettimeofday(&tv, NULL) ) {
- gf_log (this->name, GF_LOG_ERROR,
- "unable to fetch htime");
- ret = -1;
- goto out;
- }
- htime_open(this, priv, tv.tv_sec);
- }
- ret = changelog_spawn_notifier (this, priv);
- if (!ret)
- ret = changelog_spawn_helper_threads (this,
- priv);
- } else
- ret = changelog_cleanup_notifier (this, priv);
- }
-
- out:
- if (ret) {
- ret = changelog_cleanup_notifier (this, priv);
- } else {
- gf_log (this->name, GF_LOG_DEBUG,
- "changelog reconfigured");
- if (active_now)
- priv->active = _gf_true;
- }
-
- return ret;
-}
-
-int32_t
-init (xlator_t *this)
-{
- int ret = -1;
- char *tmp = NULL;
- changelog_priv_t *priv = NULL;
- gf_boolean_t cond_lock_init = _gf_false;
- char htime_dir[PATH_MAX] = {0,};
- char csnap_dir[PATH_MAX] = {0,};
- uint32_t timeout = 0;
-
- GF_VALIDATE_OR_GOTO ("changelog", this, out);
-
- if (!this->children || this->children->next) {
- gf_log (this->name, GF_LOG_ERROR,
- "translator needs a single subvolume");
- goto out;
- }
-
- if (!this->parents) {
- gf_log (this->name, GF_LOG_ERROR,
- "dangling volume. please check volfile");
- goto out;
- }
-
- priv = GF_CALLOC (1, sizeof (*priv), gf_changelog_mt_priv_t);
- if (!priv)
- goto out;
-
- this->local_pool = mem_pool_new (changelog_local_t, 64);
- if (!this->local_pool) {
- gf_log (this->name, GF_LOG_ERROR,
- "failed to create local memory pool");
- goto out;
- }
-
- LOCK_INIT (&priv->lock);
- LOCK_INIT (&priv->c_snap_lock);
-
- GF_OPTION_INIT ("changelog-brick", tmp, str, out);
- if (!tmp) {
- gf_log (this->name, GF_LOG_ERROR,
- "\"changelog-brick\" option is not set");
- goto out;
- }
-
- priv->changelog_brick = gf_strdup (tmp);
- if (!priv->changelog_brick)
- goto out;
- tmp = NULL;
-
- GF_OPTION_INIT ("changelog-dir", tmp, str, out);
- if (!tmp) {
- gf_log (this->name, GF_LOG_ERROR,
- "\"changelog-dir\" option is not set");
- goto out;
- }
-
- priv->changelog_dir = gf_strdup (tmp);
- if (!priv->changelog_dir)
- goto out;
- tmp = NULL;
-
- /**
- * create the directory even if change-logging would be inactive
- * so that consumers can _look_ into it (finding nothing...)
- */
- ret = mkdir_p (priv->changelog_dir, 0600, _gf_true);
-
- if (ret)
- goto out;
-
- CHANGELOG_FILL_HTIME_DIR(priv->changelog_dir, htime_dir);
- ret = mkdir_p (htime_dir, 0600, _gf_true);
- if (ret)
- goto out;
-
- CHANGELOG_FILL_CSNAP_DIR(priv->changelog_dir, csnap_dir);
- ret = mkdir_p (csnap_dir, 0600, _gf_true);
- if (ret)
- goto out;
-
- GF_OPTION_INIT ("changelog", priv->active, bool, out);
-
- GF_OPTION_INIT ("op-mode", tmp, str, out);
- changelog_assign_opmode (priv, tmp);
-
- tmp = NULL;
-
- GF_OPTION_INIT ("encoding", tmp, str, out);
- changelog_assign_encoding (priv, tmp);
-
- GF_OPTION_INIT ("rollover-time", priv->rollover_time, int32, out);
-
- GF_OPTION_INIT ("fsync-interval", priv->fsync_interval, int32, out);
- GF_OPTION_INIT ("changelog-barrier-timeout", timeout, time, out);
- priv->timeout.tv_sec = timeout;
-
- changelog_encode_change(priv);
-
- GF_ASSERT (cb_bootstrap[priv->op_mode].mode == priv->op_mode);
- priv->cb = &cb_bootstrap[priv->op_mode];
-
- /* ... now bootstrap the logger */
- ret = priv->cb->ctor (this, &priv->cd);
- if (ret)
- goto out;
-
- priv->changelog_fd = -1;
-
- /* snap dependency changes */
- priv->dm.black_fop_cnt = 0;
- priv->dm.white_fop_cnt = 0;
- priv->dm.drain_wait_black = _gf_false;
- priv->dm.drain_wait_white = _gf_false;
- priv->current_color = FOP_COLOR_BLACK;
- priv->explicit_rollover = _gf_false;
- /* Mutex is not needed as threads are not spawned yet */
- priv->bn.bnotify = _gf_false;
- ret = changelog_pthread_init (this, priv);
- if (ret)
- goto out;
-
- LOCK_INIT (&priv->bflags.lock);
- cond_lock_init = _gf_true;
- priv->bflags.barrier_ext = _gf_false;
-
- /* Changelog barrier init */
- INIT_LIST_HEAD (&priv->queue);
- priv->barrier_enabled = _gf_false;
-
- ret = changelog_init (this, priv);
- if (ret)
- goto out;
-
- gf_log (this->name, GF_LOG_DEBUG, "changelog translator loaded");
-
- out:
- if (ret) {
- if (this && this->local_pool)
- mem_pool_destroy (this->local_pool);
- if (priv) {
- if (priv->cb) {
- ret = priv->cb->dtor (this, &priv->cd);
- if (ret)
- gf_log (this->name, GF_LOG_ERROR,
- "error in cleanup during init()");
- }
- GF_FREE (priv->changelog_brick);
- GF_FREE (priv->changelog_dir);
- if (cond_lock_init)
- changelog_pthread_destroy (priv);
- GF_FREE (priv);
- }
- this->private = NULL;
- } else
- this->private = priv;
-
- return ret;
-}
-
-void
-fini (xlator_t *this)
-{
- int ret = -1;
- changelog_priv_t *priv = NULL;
-
- priv = this->private;
-
- if (priv) {
- ret = priv->cb->dtor (this, &priv->cd);
- if (ret)
- gf_log (this->name, GF_LOG_ERROR,
- "error in fini");
- mem_pool_destroy (this->local_pool);
- GF_FREE (priv->changelog_brick);
- GF_FREE (priv->changelog_dir);
- changelog_pthread_destroy (priv);
- GF_FREE (priv);
- }
-
- this->private = NULL;
-
- return;
-}
-
-struct xlator_fops fops = {
- .mknod = changelog_mknod,
- .mkdir = changelog_mkdir,
- .create = changelog_create,
- .symlink = changelog_symlink,
- .writev = changelog_writev,
- .truncate = changelog_truncate,
- .ftruncate = changelog_ftruncate,
- .link = changelog_link,
- .rename = changelog_rename,
- .unlink = changelog_unlink,
- .rmdir = changelog_rmdir,
- .setattr = changelog_setattr,
- .fsetattr = changelog_fsetattr,
- .setxattr = changelog_setxattr,
- .fsetxattr = changelog_fsetxattr,
- .removexattr = changelog_removexattr,
- .fremovexattr = changelog_fremovexattr,
-};
-
-struct xlator_cbks cbks = {
- .forget = changelog_forget,
-};
-
-struct volume_options options[] = {
- {.key = {"changelog"},
- .type = GF_OPTION_TYPE_BOOL,
- .default_value = "off",
- .description = "enable/disable change-logging"
- },
- {.key = {"changelog-brick"},
- .type = GF_OPTION_TYPE_PATH,
- .description = "brick path to generate unique socket file name."
- " should be the export directory of the volume strictly."
- },
- {.key = {"changelog-dir"},
- .type = GF_OPTION_TYPE_PATH,
- .description = "directory for the changelog files"
- },
- {.key = {"op-mode"},
- .type = GF_OPTION_TYPE_STR,
- .default_value = "realtime",
- .value = {"realtime"},
- .description = "operation mode - futuristic operation modes"
- },
- {.key = {"encoding"},
- .type = GF_OPTION_TYPE_STR,
- .default_value = "ascii",
- .value = {"binary", "ascii"},
- .description = "encoding type for changelogs"
- },
- {.key = {"rollover-time"},
- .default_value = "15",
- .type = GF_OPTION_TYPE_TIME,
- .description = "time to switch to a new changelog file (in seconds)"
- },
- {.key = {"fsync-interval"},
- .type = GF_OPTION_TYPE_TIME,
- .default_value = "5",
- .description = "do not open CHANGELOG file with O_SYNC mode."
- " instead perform fsync() at specified intervals"
- },
- { .key = {"changelog-barrier-timeout"},
- .type = GF_OPTION_TYPE_TIME,
- .default_value = BARRIER_TIMEOUT,
- .description = "After 'timeout' seconds since the time 'barrier' "
- "option was set to \"on\", unlink/rmdir/rename "
- "operations are no longer blocked and previously "
- "blocked fops are allowed to go through"
- },
- {.key = {NULL}
- },
-};
diff --git a/xlators/features/compress/Makefile.am b/xlators/features/compress/Makefile.am
deleted file mode 100644
index a985f42a877..00000000000
--- a/xlators/features/compress/Makefile.am
+++ /dev/null
@@ -1,3 +0,0 @@
-SUBDIRS = src
-
-CLEANFILES =
diff --git a/xlators/features/compress/src/Makefile.am b/xlators/features/compress/src/Makefile.am
deleted file mode 100644
index 4c7c8102255..00000000000
--- a/xlators/features/compress/src/Makefile.am
+++ /dev/null
@@ -1,17 +0,0 @@
-xlator_LTLIBRARIES = cdc.la
-
-xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/features
-
-noinst_HEADERS = cdc.h cdc-mem-types.h
-
-cdc_la_LDFLAGS = -module -avoid-version $(LIBZ_LIBS)
-
-cdc_la_SOURCES = cdc.c cdc-helper.c
-cdc_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la
-
-AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src -fPIC \
- -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -D$(GF_HOST_OS) $(LIBZ_CFLAGS)
-
-AM_CFLAGS = -Wall $(GF_CFLAGS)
-
-CLEANFILES =
diff --git a/xlators/features/compress/src/cdc-helper.c b/xlators/features/compress/src/cdc-helper.c
deleted file mode 100644
index 79d60a4924b..00000000000
--- a/xlators/features/compress/src/cdc-helper.c
+++ /dev/null
@@ -1,547 +0,0 @@
-/*
- Copyright (c) 2013 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 "cdc.h"
-#include "cdc-mem-types.h"
-
-#ifdef HAVE_LIB_Z
-#include "zlib.h"
-#endif
-
-#ifdef HAVE_LIB_Z
-/* gzip header looks something like this
- * (RFC 1950)
- *
- * +---+---+---+---+---+---+---+---+---+---+
- * |ID1|ID2|CM |FLG| MTIME |XFL|OS |
- * +---+---+---+---+---+---+---+---+---+---+
- *
- * Data is usually sent without this header i.e
- * Data sent = <compressed-data> + trailer(8)
- * The trailer contains the checksum.
- *
- * gzip_header is added only during debugging.
- * Refer to the function cdc_dump_iovec_to_disk
- */
-static const char gzip_header[10] =
- {
- '\037', '\213', Z_DEFLATED, 0,
- 0, 0, 0, 0,
- 0, GF_CDC_OS_ID
- };
-
-static int32_t
-cdc_next_iovec (xlator_t *this, cdc_info_t *ci)
-{
- int ret = -1;
-
- ci->ncount++;
- /* check for iovec overflow -- should not happen */
- if (ci->ncount == MAX_IOVEC) {
- gf_log (this->name, GF_LOG_ERROR,
- "Zlib output buffer overflow"
- " ->ncount (%d) | ->MAX_IOVEC (%d)",
- ci->ncount, MAX_IOVEC);
- goto out;
- }
-
- ret = 0;
-
- out:
- return ret;
-}
-
-static void
-cdc_put_long (unsigned char *string, unsigned long x)
-{
- string[0] = (unsigned char) (x & 0xff);
- string[1] = (unsigned char) ((x & 0xff00) >> 8);
- string[2] = (unsigned char) ((x & 0xff0000) >> 16);
- string[3] = (unsigned char) ((x & 0xff000000) >> 24);
-}
-
-static unsigned long
-cdc_get_long (unsigned char *buf)
-{
- return ((unsigned long) buf[0])
- | (((unsigned long) buf[1]) << 8)
- | (((unsigned long) buf[2]) << 16)
- | (((unsigned long) buf[3]) << 24);
-}
-
-static int32_t
-cdc_init_gzip_trailer (xlator_t *this, cdc_priv_t *priv, cdc_info_t *ci)
-{
- int ret = -1;
- char *buf = NULL;
-
- ret = cdc_next_iovec (this, ci);
- if (ret)
- goto out;
-
- buf = CURR_VEC(ci).iov_base =
- (char *) GF_CALLOC (1, GF_CDC_VALIDATION_SIZE,
- gf_cdc_mt_gzip_trailer_t);
-
- if (!CURR_VEC(ci).iov_base)
- goto out;
-
- CURR_VEC(ci).iov_len = GF_CDC_VALIDATION_SIZE;
-
- cdc_put_long ((unsigned char *)&buf[0], ci->crc);
- cdc_put_long ((unsigned char *)&buf[4], ci->stream.total_in);
-
- ret = 0;
-
- out:
- return ret;
-}
-
-static int32_t
-cdc_alloc_iobuf_and_init_vec (xlator_t *this,
- cdc_priv_t *priv, cdc_info_t *ci,
- int size)
-{
- int ret = -1;
- int alloc_len = 0;
- struct iobuf *iobuf = NULL;
-
- ret = cdc_next_iovec (this, ci);
- if (ret)
- goto out;
-
- alloc_len = size ? size : ci->buffer_size;
-
- iobuf = iobuf_get2 (this->ctx->iobuf_pool, alloc_len);
- if (!iobuf)
- goto out;
-
- ret = iobref_add (ci->iobref, iobuf);
- if (ret)
- goto out;
-
- /* Initialize this iovec */
- CURR_VEC(ci).iov_base = iobuf->ptr;
- CURR_VEC(ci).iov_len = alloc_len;
-
- ret = 0;
-
- out:
- return ret;
-}
-
-static void
-cdc_init_zlib_output_stream (cdc_priv_t *priv, cdc_info_t *ci, int size)
-{
- ci->stream.next_out = (unsigned char *) CURR_VEC(ci).iov_base;
- ci->stream.avail_out = size ? size : ci->buffer_size;
-}
-
-/* This routine is for testing and debugging only.
- * Data written = header(10) + <compressed-data> + trailer(8)
- * So each gzip dump file is at least 18 bytes in size.
- */
-void
-cdc_dump_iovec_to_disk (xlator_t *this, cdc_info_t *ci, const char *file)
-{
- int i = 0;
- int fd = 0;
- size_t written = 0;
- size_t total_written = 0;
-
- fd = open (file, O_WRONLY|O_CREAT|O_TRUNC, 0777 );
- if (fd < 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "Cannot open file: %s", file);
- return;
- }
-
- written = write (fd, (char *) gzip_header, 10);
- total_written += written;
- for (i = 0; i < ci->ncount; i++) {
- written = write (fd, (char *) ci->vec[i].iov_base, ci->vec[i].iov_len);
- total_written += written;
- }
-
- gf_log (this->name, GF_LOG_DEBUG,
- "dump'd %zu bytes to %s", total_written, GF_CDC_DEBUG_DUMP_FILE );
-
- close (fd);
-}
-
-static int32_t
-cdc_flush_libz_buffer (cdc_priv_t *priv, xlator_t *this, cdc_info_t *ci,
- int (*libz_func)(z_streamp, int),
- int flush)
-{
- int32_t ret = Z_OK;
- int done = 0;
- unsigned int deflate_len = 0;
-
- for (;;) {
- deflate_len = ci->buffer_size - ci->stream.avail_out;
-
- if (deflate_len != 0) {
- CURR_VEC(ci).iov_len = deflate_len;
-
- ret = cdc_alloc_iobuf_and_init_vec (this, priv, ci, 0);
- if (ret) {
- ret = Z_MEM_ERROR;
- break;
- }
-
- /* Re-position Zlib output buffer */
- cdc_init_zlib_output_stream (priv, ci, 0);
- }
-
- if (done) {
- ci->ncount--;
- break;
- }
-
- ret = libz_func (&ci->stream, flush);
-
- if (ret == Z_BUF_ERROR) {
- ret = Z_OK;
- ci->ncount--;
- break;
- }
-
- done = (ci->stream.avail_out != 0 || ret == Z_STREAM_END);
-
- if (ret != Z_OK && ret != Z_STREAM_END)
- break;
- }
-
- return ret;
-}
-
-static int32_t
-do_cdc_compress (struct iovec *vec, xlator_t *this, cdc_priv_t *priv,
- cdc_info_t *ci)
-{
- int ret = -1;
-
- /* Initialize defalte */
- ret = deflateInit2 (&ci->stream, priv->cdc_level, Z_DEFLATED,
- priv->window_size, priv->mem_level,
- Z_DEFAULT_STRATEGY);
-
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "unable to init Zlib (retval: %d)", ret);
- goto out;
- }
-
- ret = cdc_alloc_iobuf_and_init_vec (this, priv, ci, 0);
- if (ret)
- goto out;
-
- /* setup output buffer */
- cdc_init_zlib_output_stream (priv, ci, 0);
-
- /* setup input buffer */
- ci->stream.next_in = (unsigned char *) vec->iov_base;
- ci->stream.avail_in = vec->iov_len;
-
- ci->crc = crc32 (ci->crc, (const Bytef *) vec->iov_base, vec->iov_len);
-
- gf_log (this->name, GF_LOG_DEBUG, "crc=%lu len=%d buffer_size=%d",
- ci->crc, ci->stream.avail_in, ci->buffer_size);
-
- /* compress !! */
- while (ci->stream.avail_in != 0) {
- if (ci->stream.avail_out == 0) {
-
- CURR_VEC(ci).iov_len = ci->buffer_size;
-
- ret = cdc_alloc_iobuf_and_init_vec (this, priv, ci, 0);
- if (ret)
- break;
-
- /* Re-position Zlib output buffer */
- cdc_init_zlib_output_stream (priv, ci, 0);
- }
-
- ret = deflate (&ci->stream, Z_NO_FLUSH);
- if (ret != Z_OK)
- break;
- }
-
- out:
- return ret;
-}
-
-int32_t
-cdc_compress (xlator_t *this, cdc_priv_t *priv, cdc_info_t *ci,
- dict_t **xdata)
-{
- int ret = -1;
- int i = 0;
-
- ci->iobref = iobref_new ();
- if (!ci->iobref)
- goto out;
-
- if (!*xdata) {
- *xdata = dict_new ();
- if (!*xdata) {
- gf_log (this->name, GF_LOG_ERROR, "Cannot allocate xdata"
- " dict");
- goto out;
- }
- }
-
- /* data */
- for (i = 0; i < ci->count; i++) {
- ret = do_cdc_compress (&ci->vector[i], this, priv, ci);
- if (ret != Z_OK)
- goto deflate_cleanup_out;
- }
-
- /* flush zlib buffer */
- ret = cdc_flush_libz_buffer (priv, this, ci, deflate, Z_FINISH);
- if (!(ret == Z_OK || ret == Z_STREAM_END)) {
- gf_log (this->name, GF_LOG_ERROR,
- "Compression Error: ret (%d)", ret);
- ret = -1;
- goto deflate_cleanup_out;
- }
-
- /* trailer */
- ret = cdc_init_gzip_trailer (this, priv, ci);
- if (ret)
- goto deflate_cleanup_out;
-
- gf_log (this->name, GF_LOG_DEBUG,
- "Compressed %ld to %ld bytes",
- ci->stream.total_in, ci->stream.total_out);
-
- ci->nbytes = ci->stream.total_out + GF_CDC_VALIDATION_SIZE;
-
- /* set deflated canary value for identification */
- ret = dict_set_int32 (*xdata, GF_CDC_DEFLATE_CANARY_VAL, 1);
- if (ret) {
- /* Send uncompressed data if we can't _tell_ the client
- * that deflated data is on it's way. So, we just log
- * the faliure and continue as usual.
- */
- gf_log (this->name, GF_LOG_ERROR,
- "Data deflated, but could not set canary"
- " value in dict for identification");
- }
-
- /* This is to be used in testing */
- if ( priv->debug ) {
- cdc_dump_iovec_to_disk (this, ci, GF_CDC_DEBUG_DUMP_FILE );
- }
-
- deflate_cleanup_out:
- (void) deflateEnd(&ci->stream);
-
- out:
- return ret;
-}
-
-
-/* deflate content is checked by the presence of a canary
- * value in the dict as the key
- */
-static int32_t
-cdc_check_content_for_deflate (dict_t *xdata)
-{
- return dict_get (xdata, GF_CDC_DEFLATE_CANARY_VAL) ? -1 : 0;
-}
-
-static unsigned long
-cdc_extract_crc (char *trailer)
-{
- return cdc_get_long ((unsigned char *) &trailer[0]);
-}
-
-static unsigned long
-cdc_extract_size (char *trailer)
-{
- return cdc_get_long ((unsigned char *) &trailer[4]);
-}
-
-static int32_t
-cdc_validate_inflate (cdc_info_t *ci, unsigned long crc,
- unsigned long len)
-{
- return !((crc == ci->crc)
- /* inflated length is hidden inside
- * Zlib stream struct */
- && (len == ci->stream.total_out));
-}
-
-static int32_t
-do_cdc_decompress (xlator_t *this, cdc_priv_t *priv, cdc_info_t *ci)
-{
- int ret = -1;
- int i = 0;
- int len = 0;
- char *inflte = NULL;
- char *trailer = NULL;
- struct iovec vec = {0,};
- unsigned long computed_crc = 0;
- unsigned long computed_len = 0;
-
- ret = inflateInit2 (&ci->stream, priv->window_size);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Zlib: Unable to initialize inflate");
- goto out;
- }
-
- vec = THIS_VEC(ci, 0);
-
- trailer = (char *) (((char *) vec.iov_base) + vec.iov_len
- - GF_CDC_VALIDATION_SIZE);
-
- /* CRC of uncompressed data */
- computed_crc = cdc_extract_crc (trailer);
-
- /* size of uncomrpessed data */
- computed_len = cdc_extract_size (trailer);
-
- gf_log (this->name, GF_LOG_DEBUG, "crc=%lu len=%lu buffer_size=%d",
- computed_crc, computed_len, ci->buffer_size);
-
- inflte = vec.iov_base ;
- len = vec.iov_len - GF_CDC_VALIDATION_SIZE;
-
- /* allocate buffer of the original length of the data */
- ret = cdc_alloc_iobuf_and_init_vec (this, priv, ci, 0);
- if (ret)
- goto out;
-
- /* setup output buffer */
- cdc_init_zlib_output_stream (priv, ci, 0);
-
- /* setup input buffer */
- ci->stream.next_in = (unsigned char *) inflte;
- ci->stream.avail_in = len;
-
- while (ci->stream.avail_in != 0) {
- if (ci->stream.avail_out == 0) {
- CURR_VEC(ci).iov_len = ci->buffer_size;
-
- ret = cdc_alloc_iobuf_and_init_vec (this, priv, ci, 0);
- if (ret)
- break;
-
- /* Re-position Zlib output buffer */
- cdc_init_zlib_output_stream (priv, ci, 0);
- }
-
- ret = inflate (&ci->stream, Z_NO_FLUSH);
- if (ret == Z_STREAM_ERROR)
- break;
- }
-
- /* flush zlib buffer */
- ret = cdc_flush_libz_buffer (priv, this, ci, inflate, Z_SYNC_FLUSH);
- if (!(ret == Z_OK || ret == Z_STREAM_END)) {
- gf_log (this->name, GF_LOG_ERROR,
- "Decompression Error: ret (%d)", ret);
- ret = -1;
- goto out;
- }
-
- /* compute CRC of the uncompresses data to check for
- * correctness */
-
- for (i = 0; i < ci->ncount; i++) {
- ci->crc = crc32 (ci->crc,
- (const Bytef *) ci->vec[i].iov_base,
- ci->vec[i].iov_len);
- }
-
- /* validate inflated data */
- ret = cdc_validate_inflate (ci, computed_crc, computed_len);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Checksum or length mismatched in inflated data");
- }
-
- out:
- return ret;
-}
-
-int32_t
-cdc_decompress (xlator_t *this, cdc_priv_t *priv, cdc_info_t *ci,
- dict_t *xdata)
-{
- int32_t ret = -1;
-
- /* check for deflate content */
- if (!cdc_check_content_for_deflate (xdata)) {
- gf_log (this->name, GF_LOG_DEBUG,
- "Content not deflated, passing through ...");
- goto passthrough_out;
- }
-
- ci->iobref = iobref_new ();
- if (!ci->iobref)
- goto passthrough_out;
-
- /* do we need to do this? can we assume that one iovec
- * will hold per request data every time?
- *
- * server/client protocol seems to deal with a single
- * iovec even if op_ret > 1M. So, it looks ok to
- * assume that a single iovec will contain all the
- * data (This saves us a lot from finding the trailer
- * and the data since it could have been split-up onto
- * two adjacent iovec's.
- *
- * But, in case this translator is loaded above quick-read
- * for some reason, then it's entirely possible that we get
- * multiple iovec's...
- *
- * This case (handled below) is not tested. (by loading the
- * xlator below quick-read)
- */
-
- /* @@ I_HOPE_THIS_IS_NEVER_HIT */
- if (ci->count > 1) {
- gf_log (this->name, GF_LOG_WARNING, "unable to handle"
- " multiple iovecs (%d in number)", ci->count);
- goto inflate_cleanup_out;
- /* TODO: coallate all iovecs in one */
- }
-
- ret = do_cdc_decompress (this, priv, ci);
- if (ret)
- goto inflate_cleanup_out;
-
- ci->nbytes = ci->stream.total_out;
-
- gf_log (this->name, GF_LOG_DEBUG,
- "Inflated %ld to %ld bytes",
- ci->stream.total_in, ci->stream.total_out);
-
- inflate_cleanup_out:
- (void) inflateEnd (&ci->stream);
-
- passthrough_out:
- return ret;
-}
-
-#endif
diff --git a/xlators/features/compress/src/cdc-mem-types.h b/xlators/features/compress/src/cdc-mem-types.h
deleted file mode 100644
index ead2c70ba6e..00000000000
--- a/xlators/features/compress/src/cdc-mem-types.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- Copyright (c) 2013 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 __CDC_MEM_TYPES_H
-#define __CDC_MEM_TYPES_H
-
-#include "mem-types.h"
-
-enum gf_cdc_mem_types {
- gf_cdc_mt_priv_t = gf_common_mt_end + 1,
- gf_cdc_mt_vec_t = gf_common_mt_end + 2,
- gf_cdc_mt_gzip_trailer_t = gf_common_mt_end + 3,
- gf_cdc_mt_end = gf_common_mt_end + 4,
-};
-
-#endif
diff --git a/xlators/features/compress/src/cdc.c b/xlators/features/compress/src/cdc.c
deleted file mode 100644
index 67fc52505e5..00000000000
--- a/xlators/features/compress/src/cdc.c
+++ /dev/null
@@ -1,361 +0,0 @@
-/*
- Copyright (c) 2013 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 <sys/uio.h>
-
-#ifndef _CONFIG_H
-#define _CONFIG_H
-#include "config.h"
-#endif
-
-#include "xlator.h"
-#include "defaults.h"
-#include "logging.h"
-
-#include "cdc.h"
-#include "cdc-mem-types.h"
-
-static void
-cdc_cleanup_iobref (cdc_info_t *ci)
-{
- assert(ci->iobref != NULL);
- iobref_clear (ci->iobref);
-}
-
-int32_t
-cdc_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)
-{
- int ret = -1;
- cdc_priv_t *priv = NULL;
- cdc_info_t ci = {0,};
-
- GF_VALIDATE_OR_GOTO ("cdc", this, default_out);
- GF_VALIDATE_OR_GOTO (this->name, frame, default_out);
-
- priv = this->private;
-
- if (op_ret <= 0)
- goto default_out;
-
- if ( (priv->min_file_size != 0)
- && (op_ret < priv->min_file_size) )
- goto default_out;
-
- ci.count = count;
- ci.ibytes = op_ret;
- ci.vector = vector;
- ci.buf = NULL;
- ci.iobref = NULL;
- ci.ncount = 0;
- ci.crc = 0;
- ci.buffer_size = GF_CDC_DEF_BUFFERSIZE;
-
-/* A readv compresses on the server side and decompresses on the client side
- */
- if (priv->op_mode == GF_CDC_MODE_SERVER) {
- ret = cdc_compress (this, priv, &ci, &xdata);
- } else if (priv->op_mode == GF_CDC_MODE_CLIENT) {
- ret = cdc_decompress (this, priv, &ci, xdata);
- } else {
- gf_log (this->name, GF_LOG_ERROR,
- "Invalid operation mode (%d)", priv->op_mode);
- }
-
- if (ret)
- goto default_out;
-
- STACK_UNWIND_STRICT (readv, frame, ci.nbytes, op_errno,
- ci.vec, ci.ncount, stbuf, iobref,
- xdata);
- cdc_cleanup_iobref (&ci);
- return 0;
-
- default_out:
- STACK_UNWIND_STRICT (readv, frame, op_ret, op_errno,
- vector, count, stbuf, iobref, xdata);
- return 0;
-}
-
-int32_t
-cdc_readv (call_frame_t *frame, xlator_t *this,
- fd_t *fd, size_t size, off_t offset, uint32_t flags,
- dict_t *xdata)
-{
- fop_readv_cbk_t cbk = NULL;
-
-#ifdef HAVE_LIB_Z
- cbk = cdc_readv_cbk;
-#else
- cbk = default_readv_cbk;
-#endif
- STACK_WIND (frame, cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->readv,
- fd, size, offset, flags, xdata);
- return 0;
-}
-
-int32_t
-cdc_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)
-{
-
- STACK_UNWIND_STRICT (writev, frame, op_ret, op_errno, prebuf, postbuf, xdata);
- return 0;
-}
-
-int32_t
-cdc_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)
-{
- int ret = -1;
- cdc_priv_t *priv = NULL;
- cdc_info_t ci = {0,};
- size_t isize = 0;
-
- GF_VALIDATE_OR_GOTO ("cdc", this, default_out);
- GF_VALIDATE_OR_GOTO (this->name, frame, default_out);
-
- priv = this->private;
-
- isize = iov_length(vector, count);
-
- if (isize <= 0)
- goto default_out;
-
- if ( (priv->min_file_size != 0) && (isize < priv->min_file_size) )
- goto default_out;
-
- ci.count = count;
- ci.ibytes = isize;
- ci.vector = vector;
- ci.buf = NULL;
- ci.iobref = NULL;
- ci.ncount = 0;
- ci.crc = 0;
- ci.buffer_size = GF_CDC_DEF_BUFFERSIZE;
-
-/* A writev compresses on the client side and decompresses on the server side
- */
- if (priv->op_mode == GF_CDC_MODE_CLIENT) {
- ret = cdc_compress (this, priv, &ci, &xdata);
- } else if (priv->op_mode == GF_CDC_MODE_SERVER) {
- ret = cdc_decompress (this, priv, &ci, xdata);
- } else {
- gf_log (this->name, GF_LOG_ERROR, "Invalid operation mode (%d) ", priv->op_mode);
- }
-
- if (ret)
- goto default_out;
-
- STACK_WIND (frame,
- cdc_writev_cbk,
- FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->writev,
- fd, ci.vec, ci.ncount, offset, flags,
- iobref, xdata);
-
- cdc_cleanup_iobref (&ci);
- return 0;
-
- default_out:
- STACK_WIND (frame,
- cdc_writev_cbk,
- FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->writev,
- fd, vector, count, offset, flags,
- iobref, xdata);
- return 0;
-}
-
-int32_t
-mem_acct_init (xlator_t *this)
-{
- int ret = -1;
-
- if (!this)
- return ret;
-
- ret = xlator_mem_acct_init (this, gf_cdc_mt_end);
-
- if (ret != 0) {
- gf_log(this->name, GF_LOG_ERROR, "Memory accounting init"
- "failed");
- return ret;
- }
-
- return ret;
-}
-
-int32_t
-init (xlator_t *this)
-{
- int ret = -1;
- char *temp_str = NULL;
- cdc_priv_t *priv = NULL;
-
- GF_VALIDATE_OR_GOTO ("cdc", this, err);
-
- if (!this->children || this->children->next) {
- gf_log (this->name, GF_LOG_ERROR,
- "Need subvolume == 1");
- goto err;
- }
-
- if (!this->parents) {
- gf_log (this->name, GF_LOG_WARNING,
- "Dangling volume. Check volfile");
- }
-
- priv = GF_CALLOC (1, sizeof (*priv), gf_cdc_mt_priv_t);
- if (!priv) {
- goto err;
- }
-
- /* Check if debug mode is turned on */
- GF_OPTION_INIT ("debug", priv->debug, bool, err);
- if( priv->debug ) {
- gf_log (this->name, GF_LOG_DEBUG, "CDC debug option turned on");
- }
-
- /* Set Gzip Window Size */
- GF_OPTION_INIT ("window-size", priv->window_size, int32, err);
- if ( (priv->window_size > GF_CDC_MAX_WINDOWSIZE)
- || (priv->window_size < GF_CDC_DEF_WINDOWSIZE) ) {
- gf_log (this->name, GF_LOG_WARNING,
- "Invalid gzip window size (%d), using default",
- priv->window_size);
- priv->window_size = GF_CDC_DEF_WINDOWSIZE;
- }
-
- /* Set Gzip (De)Compression Level */
- GF_OPTION_INIT ("compression-level", priv->cdc_level, int32, err);
- if ( ((priv->cdc_level < 1) || (priv->cdc_level > 9))
- && (priv->cdc_level != GF_CDC_DEF_COMPRESSION) ) {
- gf_log (this->name, GF_LOG_WARNING,
- "Invalid gzip (de)compression level (%d),"
- " using default", priv->cdc_level);
- priv->cdc_level = GF_CDC_DEF_COMPRESSION;
- }
-
- /* Set Gzip Memory Level */
- GF_OPTION_INIT ("mem-level", priv->mem_level, int32, err);
- if ( (priv->mem_level < 1) || (priv->mem_level > 9) ) {
- gf_log (this->name, GF_LOG_WARNING,
- "Invalid gzip memory level, using the default");
- priv->mem_level = GF_CDC_DEF_MEMLEVEL;
- }
-
- /* Set min file size to enable compression */
- GF_OPTION_INIT ("min-size", priv->min_file_size, int32, err);
-
- /* Mode of operation - Server/Client */
- ret = dict_get_str (this->options, "mode", &temp_str);
- if (ret) {
- gf_log (this->name, GF_LOG_CRITICAL,
- "Operation mode not specified !!");
- goto err;
- }
-
- if (GF_CDC_MODE_IS_CLIENT (temp_str)) {
- priv->op_mode = GF_CDC_MODE_CLIENT;
- } else if (GF_CDC_MODE_IS_SERVER (temp_str)) {
- priv->op_mode = GF_CDC_MODE_SERVER;
- } else {
- gf_log (this->name, GF_LOG_CRITICAL,
- "Bogus operation mode (%s) specified", temp_str);
- goto err;
- }
-
- this->private = priv;
- gf_log (this->name, GF_LOG_DEBUG, "CDC xlator loaded in (%s) mode",temp_str);
- return 0;
-
- err:
- if (priv)
- GF_FREE (priv);
-
- return -1;
-}
-
-void
-fini (xlator_t *this)
-{
- cdc_priv_t *priv = this->private;
-
- if (priv)
- GF_FREE (priv);
- this->private = NULL;
- return;
-}
-
-struct xlator_fops fops = {
- .readv = cdc_readv,
- .writev = cdc_writev,
-};
-
-struct xlator_cbks cbks = {
-};
-
-struct volume_options options[] = {
- { .key = {"window-size"},
- .default_value = "-15",
- .type = GF_OPTION_TYPE_INT,
- .description = "Size of the zlib history buffer."
- },
- { .key = {"mem-level"},
- .default_value = "8",
- .type = GF_OPTION_TYPE_INT,
- .description = "Memory allocated for internal compression state. "
- "1 uses minimum memory but is slow and reduces "
- "compression ratio; memLevel=9 uses maximum memory "
- "for optimal speed. The default value is 8."
- },
- { .key = {"compression-level"},
- .default_value = "-1",
- .type = GF_OPTION_TYPE_INT,
- .description = "Compression levels \n"
- "0 : no compression, 1 : best speed, \n"
- "9 : best compression, -1 : default compression "
- },
- { .key = {"min-size"},
- .default_value = "0",
- .type = GF_OPTION_TYPE_INT,
- .description = "Data is compressed only when its size exceeds this."
- },
- { .key = {"mode"},
- .value = {"server", "client"},
- .type = GF_OPTION_TYPE_STR,
- .description = "Set on the basis of where the xlator is loaded. "
- "This option should NOT be configured by user."
- },
- { .key = {"debug"},
- .default_value = "false",
- .type = GF_OPTION_TYPE_BOOL,
- .description = "This is used in testing. Will dump compressed data "
- "to disk as a gzip file."
- },
- { .key = {NULL}
- },
-};
diff --git a/xlators/features/compress/src/cdc.h b/xlators/features/compress/src/cdc.h
deleted file mode 100644
index 71f4d2317bb..00000000000
--- a/xlators/features/compress/src/cdc.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- Copyright (c) 2013 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 __CDC_H
-#define __CDC_H
-
-#ifdef HAVE_LIB_Z
-#include "zlib.h"
-#endif
-
-#include "xlator.h"
-
-#ifndef MAX_IOVEC
-#define MAX_IOVEC 16
-#endif
-
-typedef struct cdc_priv {
- int window_size;
- int mem_level;
- int cdc_level;
- int min_file_size;
- int op_mode;
- gf_boolean_t debug;
- gf_lock_t lock;
-} cdc_priv_t;
-
-typedef struct cdc_info {
- /* input bits */
- int count;
- int32_t ibytes;
- struct iovec *vector;
- struct iatt *buf;
-
- /* output bits */
- int ncount;
- int nbytes;
- int buffer_size;
- struct iovec vec[MAX_IOVEC];
- struct iobref *iobref;
-
- /* zlib bits */
-#ifdef HAVE_LIB_Z
- z_stream stream;
-#endif
- unsigned long crc;
-} cdc_info_t;
-
-#define NVEC(ci) (ci->ncount - 1)
-#define CURR_VEC(ci) ci->vec[ci->ncount - 1]
-#define THIS_VEC(ci, i) ci->vector[i]
-
-/* Gzip defaults */
-#define GF_CDC_DEF_WINDOWSIZE -15 /* default value */
-#define GF_CDC_MAX_WINDOWSIZE -8 /* max value */
-
-#ifdef HAVE_LIB_Z
-#define GF_CDC_DEF_COMPRESSION Z_DEFAULT_COMPRESSION
-#else
-#define GF_CDC_DEF_COMPRESSION -1
-#endif
-
-#define GF_CDC_DEF_MEMLEVEL 8
-#define GF_CDC_DEF_BUFFERSIZE 262144 // 256K - default compression buffer size
-
-/* Operation mode
- * If xlator is loaded on client, readv decompresses and writev compresses
- * If xlator is loaded on server, readv compresses and writev decompresses
- */
-#define GF_CDC_MODE_CLIENT 0
-#define GF_CDC_MODE_SERVER 1
-
-/* min size of data to do cmpression
- * 0 == compress even 1byte
- */
-#define GF_CDC_MIN_CHUNK_SIZE 0
-
-#define GF_CDC_VALIDATION_SIZE 8
-
-#define GF_CDC_OS_ID 0xFF
-#define GF_CDC_DEFLATE_CANARY_VAL "deflate"
-#define GF_CDC_DEBUG_DUMP_FILE "/tmp/cdcdump.gz"
-
-#define GF_CDC_MODE_IS_CLIENT(m) \
- (strcmp (m, "client") == 0)
-
-#define GF_CDC_MODE_IS_SERVER(m) \
- (strcmp (m, "server") == 0)
-
-int32_t
-cdc_compress (xlator_t *this,
- cdc_priv_t *priv,
- cdc_info_t *ci,
- dict_t **xdata);
-int32_t
-cdc_decompress (xlator_t *this,
- cdc_priv_t *priv,
- cdc_info_t *ci,
- dict_t *xdata);
-
-#endif
diff --git a/xlators/features/filter/src/Makefile.am b/xlators/features/filter/src/Makefile.am
index d1fda8b0a9d..cda5f07675b 100644
--- a/xlators/features/filter/src/Makefile.am
+++ b/xlators/features/filter/src/Makefile.am
@@ -1,16 +1,13 @@
xlator_LTLIBRARIES = filter.la
xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/testing/features
-filter_la_LDFLAGS = -module -avoid-version
+filter_la_LDFLAGS = -module -avoidversion
filter_la_SOURCES = filter.c
filter_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la
-noinst_HEADERS = filter-mem-types.h
-
-AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src
-
-AM_CFLAGS = -Wall $(GF_CFLAGS)
+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/features/filter/src/filter-mem-types.h b/xlators/features/filter/src/filter-mem-types.h
deleted file mode 100644
index 47a17249b8d..00000000000
--- a/xlators/features/filter/src/filter-mem-types.h
+++ /dev/null
@@ -1,20 +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 __FILTER_MEM_TYPES_H__
-#define __FILTER_MEM_TYPES_H__
-
-#include "mem-types.h"
-
-enum gf_filter_mem_types_ {
- gf_filter_mt_gf_filter = gf_common_mt_end + 1,
- gf_filter_mt_end
-};
-#endif
-
diff --git a/xlators/features/filter/src/filter.c b/xlators/features/filter/src/filter.c
index 1d4887b7143..1d50991137a 100644
--- a/xlators/features/filter/src/filter.c
+++ b/xlators/features/filter/src/filter.c
@@ -1,12 +1,22 @@
/*
- 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-2009 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"
@@ -20,7 +30,6 @@
#include "logging.h"
#include "dict.h"
#include "xlator.h"
-#include "filter-mem-types.h"
#define GF_FILTER_NOBODY_UID 65534
#define GF_FILTER_NOBODY_GID 65534
@@ -150,36 +159,36 @@ update_frame (call_frame_t *frame,
/* if 'root' don't change the uid/gid */
static int32_t
-update_stat (struct iatt *stbuf,
+update_stat (struct stat *stbuf,
struct gf_filter *filter)
{
int32_t idx = 0;
for (idx = 0; idx < filter->translate_num_uid_entries; idx++) {
- if (stbuf->ia_uid == GF_FILTER_ROOT_UID)
+ if (stbuf->st_uid == GF_FILTER_ROOT_UID)
continue;
- if ((stbuf->ia_uid >= filter->translate_input_uid[idx][0]) &&
- (stbuf->ia_uid <= filter->translate_input_uid[idx][1])) {
- stbuf->ia_uid = filter->translate_output_uid[idx];
+ if ((stbuf->st_uid >= filter->translate_input_uid[idx][0]) &&
+ (stbuf->st_uid <= filter->translate_input_uid[idx][1])) {
+ stbuf->st_uid = filter->translate_output_uid[idx];
break;
}
}
for (idx = 0; idx < filter->translate_num_gid_entries; idx++) {
- if (stbuf->ia_gid == GF_FILTER_ROOT_GID)
+ if (stbuf->st_gid == GF_FILTER_ROOT_GID)
continue;
- if ((stbuf->ia_gid >= filter->translate_input_gid[idx][0]) &&
- (stbuf->ia_gid <= filter->translate_input_gid[idx][1])) {
- stbuf->ia_gid = filter->translate_output_gid[idx];
+ if ((stbuf->st_gid >= filter->translate_input_gid[idx][0]) &&
+ (stbuf->st_gid <= filter->translate_input_gid[idx][1])) {
+ stbuf->st_gid = filter->translate_output_gid[idx];
break;
}
}
if (filter->fixed_uid_set) {
- stbuf->ia_uid = filter->fixed_uid;
+ stbuf->st_uid = filter->fixed_uid;
}
if (filter->fixed_gid_set) {
- stbuf->ia_gid = filter->fixed_gid;
+ stbuf->st_gid = filter->fixed_gid;
}
return 0;
@@ -192,14 +201,14 @@ filter_lookup_cbk (call_frame_t *frame,
int32_t op_ret,
int32_t op_errno,
inode_t *inode,
- struct iatt *buf,
+ struct stat *buf,
dict_t *dict,
- struct iatt *postparent)
+ struct stat *postparent)
{
int ret = 0;
if (op_ret >= 0) {
update_stat (buf, this->private);
- ret = inode_ctx_put (inode, this, (uint64_t)(long)buf->ia_uid);
+ ret = inode_ctx_put (inode, this, (uint64_t)(long)buf->st_uid);
if (ret == -1) {
gf_log (this->name, GF_LOG_ERROR,
"couldn't set context");
@@ -233,7 +242,7 @@ filter_stat_cbk (call_frame_t *frame,
xlator_t *this,
int32_t op_ret,
int32_t op_errno,
- struct iatt *buf)
+ struct stat *buf)
{
if (op_ret >= 0) {
update_stat (buf, this->private);
@@ -261,8 +270,8 @@ filter_setattr_cbk (call_frame_t *frame,
xlator_t *this,
int32_t op_ret,
int32_t op_errno,
- struct iatt *preop,
- struct iatt *postop)
+ struct stat *preop,
+ struct stat *postop)
{
if (op_ret >= 0) {
update_stat (preop, this->private);
@@ -276,7 +285,7 @@ int32_t
filter_setattr (call_frame_t *frame,
xlator_t *this,
loc_t *loc,
- struct iatt *stbuf,
+ struct stat *stbuf,
int32_t valid)
{
int32_t ret = 0;
@@ -317,8 +326,8 @@ filter_fsetattr_cbk (call_frame_t *frame,
xlator_t *this,
int32_t op_ret,
int32_t op_errno,
- struct iatt *preop,
- struct iatt *postop)
+ struct stat *preop,
+ struct stat *postop)
{
if (op_ret >= 0) {
update_stat (preop, this->private);
@@ -335,7 +344,7 @@ int32_t
filter_fsetattr (call_frame_t *frame,
xlator_t *this,
fd_t *fd,
- struct iatt *stbuf,
+ struct stat *stbuf,
int32_t valid)
{
STACK_WIND (frame,
@@ -354,8 +363,8 @@ filter_truncate_cbk (call_frame_t *frame,
xlator_t *this,
int32_t op_ret,
int32_t op_errno,
- struct iatt *prebuf,
- struct iatt *postbuf)
+ struct stat *prebuf,
+ struct stat *postbuf)
{
if (op_ret >= 0) {
update_stat (prebuf, this->private);
@@ -406,8 +415,8 @@ filter_ftruncate_cbk (call_frame_t *frame,
xlator_t *this,
int32_t op_ret,
int32_t op_errno,
- struct iatt *prebuf,
- struct iatt *postbuf)
+ struct stat *prebuf,
+ struct stat *postbuf)
{
if (op_ret >= 0) {
update_stat (prebuf, this->private);
@@ -440,7 +449,7 @@ filter_readlink_cbk (call_frame_t *frame,
int32_t op_ret,
int32_t op_errno,
const char *path,
- struct iatt *sbuf)
+ struct stat *sbuf)
{
if (op_ret >= 0)
update_stat (sbuf, this->private);
@@ -485,15 +494,15 @@ filter_mknod_cbk (call_frame_t *frame,
int32_t op_ret,
int32_t op_errno,
inode_t *inode,
- struct iatt *buf,
- struct iatt *preparent,
- struct iatt *postparent)
+ struct stat *buf,
+ struct stat *preparent,
+ struct stat *postparent)
{
int ret = 0;
if (op_ret >= 0) {
update_stat (buf, this->private);
- ret = inode_ctx_put (inode, this, (uint64_t)(long)buf->ia_uid);
+ ret = inode_ctx_put (inode, this, (uint64_t)(long)buf->st_uid);
if (ret == -1) {
gf_log (this->name, GF_LOG_ERROR,
"couldn't set context");
@@ -551,14 +560,14 @@ filter_mkdir_cbk (call_frame_t *frame,
int32_t op_ret,
int32_t op_errno,
inode_t *inode,
- struct iatt *buf,
- struct iatt *preparent,
- struct iatt *postparent)
+ struct stat *buf,
+ struct stat *preparent,
+ struct stat *postparent)
{
int ret = 0;
if (op_ret >= 0) {
update_stat (buf, this->private);
- ret = inode_ctx_put (inode, this, (uint64_t)(long)buf->ia_uid);
+ ret = inode_ctx_put (inode, this, (uint64_t)(long)buf->st_uid);
if (ret == -1) {
gf_log (this->name, GF_LOG_ERROR,
"couldn't set context");
@@ -614,8 +623,8 @@ filter_unlink_cbk (call_frame_t *frame,
xlator_t *this,
int32_t op_ret,
int32_t op_errno,
- struct iatt *preparent,
- struct iatt *postparent)
+ struct stat *preparent,
+ struct stat *postparent)
{
if (op_ret >= 0) {
update_stat (preparent, this->private);
@@ -670,8 +679,8 @@ filter_rmdir_cbk (call_frame_t *frame,
xlator_t *this,
int32_t op_ret,
int32_t op_errno,
- struct iatt *preparent,
- struct iatt *postparent)
+ struct stat *preparent,
+ struct stat *postparent)
{
if (op_ret >= 0) {
update_stat (preparent, this->private);
@@ -727,14 +736,14 @@ filter_symlink_cbk (call_frame_t *frame,
int32_t op_ret,
int32_t op_errno,
inode_t *inode,
- struct iatt *buf,
- struct iatt *preparent,
- struct iatt *postparent)
+ struct stat *buf,
+ struct stat *preparent,
+ struct stat *postparent)
{
int ret = 0;
if (op_ret >= 0) {
update_stat (buf, this->private);
- ret = inode_ctx_put (inode, this, (uint64_t)(long)buf->ia_uid);
+ ret = inode_ctx_put (inode, this, (uint64_t)(long)buf->st_uid);
if (ret == -1) {
gf_log (this->name, GF_LOG_ERROR,
"couldn't set context");
@@ -791,11 +800,11 @@ filter_rename_cbk (call_frame_t *frame,
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)
+ struct stat *buf,
+ struct stat *preoldparent,
+ struct stat *postoldparent,
+ struct stat *prenewparent,
+ struct stat *postnewparent)
{
if (op_ret >= 0) {
update_stat (buf, this->private);
@@ -866,14 +875,14 @@ filter_link_cbk (call_frame_t *frame,
int32_t op_ret,
int32_t op_errno,
inode_t *inode,
- struct iatt *buf,
- struct iatt *preparent,
- struct iatt *postparent)
+ struct stat *buf,
+ struct stat *preparent,
+ struct stat *postparent)
{
int ret = 0;
if (op_ret >= 0) {
update_stat (buf, this->private);
- ret = inode_ctx_put (inode, this, (uint64_t)(long)buf->ia_uid);
+ ret = inode_ctx_put (inode, this, (uint64_t)(long)buf->st_uid);
if (ret == -1) {
gf_log (this->name, GF_LOG_ERROR,
"couldn't set context");
@@ -920,14 +929,14 @@ filter_create_cbk (call_frame_t *frame,
int32_t op_errno,
fd_t *fd,
inode_t *inode,
- struct iatt *buf,
- struct iatt *preparent,
- struct iatt *postparent)
+ struct stat *buf,
+ struct stat *preparent,
+ struct stat *postparent)
{
int ret = 0;
if (op_ret >= 0) {
update_stat (buf, this->private);
- ret = inode_ctx_put (inode, this, (uint64_t)(long)buf->ia_uid);
+ ret = inode_ctx_put (inode, this, (uint64_t)(long)buf->st_uid);
if (ret == -1) {
gf_log (this->name, GF_LOG_ERROR,
"couldn't set context");
@@ -1044,7 +1053,7 @@ filter_readv_cbk (call_frame_t *frame,
int32_t op_errno,
struct iovec *vector,
int32_t count,
- struct iatt *stbuf,
+ struct stat *stbuf,
struct iobref *iobref)
{
if (op_ret >= 0) {
@@ -1084,8 +1093,8 @@ filter_writev_cbk (call_frame_t *frame,
xlator_t *this,
int32_t op_ret,
int32_t op_errno,
- struct iatt *prebuf,
- struct iatt *postbuf)
+ struct stat *prebuf,
+ struct stat *postbuf)
{
if (op_ret >= 0) {
update_stat (prebuf, this->private);
@@ -1136,7 +1145,7 @@ filter_fstat_cbk (call_frame_t *frame,
xlator_t *this,
int32_t op_ret,
int32_t op_errno,
- struct iatt *buf)
+ struct stat *buf)
{
if (op_ret >= 0) {
update_stat (buf, this->private);
@@ -1346,25 +1355,6 @@ filter_removexattr (call_frame_t *frame,
return 0;
}
-int32_t
-mem_acct_init (xlator_t *this)
-{
- int ret = -1;
-
- if (!this)
- return ret;
-
- ret = xlator_mem_acct_init (this, gf_filter_mt_end + 1);
-
- if (ret != 0) {
- gf_log (this->name, GF_LOG_ERROR, "Memory accounting init"
- "failed");
- return ret;
- }
-
- return ret;
-}
-
int32_t
init (xlator_t *this)
{
@@ -1394,7 +1384,7 @@ init (xlator_t *this)
"dangling volume. check volfile ");
}
- filter = GF_CALLOC (sizeof (*filter), 1, gf_filter_mt_gf_filter);
+ filter = CALLOC (sizeof (*filter), 1);
ERR_ABORT (filter);
if (dict_get (this->options, "read-only")) {
@@ -1429,11 +1419,11 @@ init (xlator_t *this)
option_data = dict_get (this->options, "translate-uid");
value = strtok_r (option_data->data, ",", &tmp_str);
while (value) {
- dup_str = gf_strdup (value);
+ dup_str = strdup (value);
input_value_str1 = strtok_r (dup_str, "=", &tmp_str1);
if (input_value_str1) {
/* Check for n-m */
- char *temp_string = gf_strdup (input_value_str1);
+ char *temp_string = strdup (input_value_str1);
input_value_str2 = strtok_r (temp_string, "-", &tmp_str2);
if (gf_string2int (input_value_str2, &input_value) != 0) {
gf_log (this->name, GF_LOG_ERROR,
@@ -1452,7 +1442,7 @@ init (xlator_t *this)
}
}
filter->translate_input_uid[filter->translate_num_uid_entries][1] = input_value;
- GF_FREE (temp_string);
+ FREE (temp_string);
output_value_str = strtok_r (NULL, "=", &tmp_str1);
if (output_value_str) {
if (gf_string2int (output_value_str, &output_value) != 0) {
@@ -1481,7 +1471,7 @@ init (xlator_t *this)
if (filter->translate_num_uid_entries == GF_MAXIMUM_FILTERING_ALLOWED)
break;
value = strtok_r (NULL, ",", &tmp_str);
- GF_FREE (dup_str);
+ FREE (dup_str);
}
}
@@ -1493,11 +1483,11 @@ init (xlator_t *this)
option_data = dict_get (this->options, "translate-gid");
value = strtok_r (option_data->data, ",", &tmp_str);
while (value) {
- dup_str = gf_strdup (value);
+ dup_str = strdup (value);
input_value_str1 = strtok_r (dup_str, "=", &tmp_str1);
if (input_value_str1) {
/* Check for n-m */
- char *temp_string = gf_strdup (input_value_str1);
+ char *temp_string = strdup (input_value_str1);
input_value_str2 = strtok_r (temp_string, "-", &tmp_str2);
if (gf_string2int (input_value_str2, &input_value) != 0) {
gf_log (this->name, GF_LOG_ERROR,
@@ -1516,7 +1506,7 @@ init (xlator_t *this)
}
}
filter->translate_input_gid[filter->translate_num_gid_entries][1] = input_value;
- GF_FREE (temp_string);
+ FREE (temp_string);
output_value_str = strtok_r (NULL, "=", &tmp_str1);
if (output_value_str) {
if (gf_string2int (output_value_str, &output_value) != 0) {
@@ -1546,7 +1536,7 @@ init (xlator_t *this)
if (filter->translate_num_gid_entries == GF_MAXIMUM_FILTERING_ALLOWED)
break;
value = strtok_r (NULL, ",", &tmp_str);
- GF_FREE (dup_str);
+ FREE (dup_str);
}
}
@@ -1557,7 +1547,7 @@ init (xlator_t *this)
option_data = dict_get (this->options, "filter-uid");
value = strtok_r (option_data->data, ",", &tmp_str);
while (value) {
- dup_str = gf_strdup (value);
+ dup_str = strdup (value);
/* Check for n-m */
input_value_str1 = strtok_r (dup_str, "-", &tmp_str1);
if (gf_string2int (input_value_str1, &input_value) != 0) {
@@ -1587,7 +1577,7 @@ init (xlator_t *this)
if (filter->filter_num_uid_entries == GF_MAXIMUM_FILTERING_ALLOWED)
break;
value = strtok_r (NULL, ",", &tmp_str);
- GF_FREE (dup_str);
+ FREE (dup_str);
}
filter->partial_filter = 1;
}
@@ -1599,7 +1589,7 @@ init (xlator_t *this)
option_data = dict_get (this->options, "filter-gid");
value = strtok_r (option_data->data, ",", &tmp_str);
while (value) {
- dup_str = gf_strdup (value);
+ dup_str = strdup (value);
/* Check for n-m */
input_value_str1 = strtok_r (dup_str, "-", &tmp_str1);
if (gf_string2int (input_value_str1, &input_value) != 0) {
@@ -1629,7 +1619,7 @@ init (xlator_t *this)
if (filter->filter_num_gid_entries == GF_MAXIMUM_FILTERING_ALLOWED)
break;
value = strtok_r (NULL, ",", &tmp_str);
- GF_FREE (dup_str);
+ FREE (dup_str);
}
gf_log (this->name, GF_LOG_ERROR, "this option is not supported currently.. exiting");
return -1;
@@ -1670,7 +1660,7 @@ fini (xlator_t *this)
{
struct gf_filter *filter = this->private;
- GF_FREE (filter);
+ FREE (filter);
return;
}
@@ -1702,6 +1692,9 @@ struct xlator_fops fops = {
.fsetattr = filter_fsetattr,
};
+struct xlator_mops mops = {
+};
+
struct xlator_cbks cbks = {
};
diff --git a/xlators/features/gfid-access/src/Makefile.am b/xlators/features/gfid-access/src/Makefile.am
deleted file mode 100644
index db53affaab3..00000000000
--- a/xlators/features/gfid-access/src/Makefile.am
+++ /dev/null
@@ -1,15 +0,0 @@
-xlator_LTLIBRARIES = gfid-access.la
-xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/features
-
-gfid_access_la_LDFLAGS = -module -avoid-version
-
-gfid_access_la_SOURCES = gfid-access.c
-gfid_access_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la
-
-noinst_HEADERS = gfid-access.h gfid-access-mem-types.h
-
-AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src
-
-AM_CFLAGS = -Wall $(GF_CFLAGS)
-
-CLEANFILES =
diff --git a/xlators/features/gfid-access/src/gfid-access-mem-types.h b/xlators/features/gfid-access/src/gfid-access-mem-types.h
deleted file mode 100644
index 168d67b431f..00000000000
--- a/xlators/features/gfid-access/src/gfid-access-mem-types.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- Copyright (c) 2013 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 _GFID_ACCESS_MEM_TYPES_H
-#define _GFID_ACCESS_MEM_TYPES_H
-
-#include "mem-types.h"
-
-enum gf_changelog_mem_types {
- gf_gfid_access_mt_priv_t = gf_common_mt_end + 1,
- gf_gfid_access_mt_gfid_t,
- gf_gfid_access_mt_end
-};
-
-#endif
-
diff --git a/xlators/features/gfid-access/src/gfid-access.c b/xlators/features/gfid-access/src/gfid-access.c
deleted file mode 100644
index 512f9749348..00000000000
--- a/xlators/features/gfid-access/src/gfid-access.c
+++ /dev/null
@@ -1,1413 +0,0 @@
-/*
- Copyright (c) 2013 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 "gfid-access.h"
-#include "inode.h"
-#include "byte-order.h"
-
-
-int
-ga_valid_inode_loc_copy (loc_t *dst, loc_t *src, xlator_t *this)
-{
- int ret = 0;
- uint64_t value = 0;
-
- /* if its an entry operation, on the virtual */
- /* directory inode as parent, we need to handle */
- /* it properly */
- ret = loc_copy (dst, src);
- if (ret < 0)
- goto out;
-
- /*
- * Change ALL virtual inodes with real-inodes in loc
- */
- if (dst->parent) {
- ret = inode_ctx_get (dst->parent, this, &value);
- if (ret < 0) {
- ret = 0; //real-inode
- goto out;
- }
- inode_unref (dst->parent);
- dst->parent = inode_ref ((inode_t*)value);
- uuid_copy (dst->pargfid, dst->parent->gfid);
- }
-
- if (dst->inode) {
- ret = inode_ctx_get (dst->inode, this, &value);
- if (ret < 0) {
- ret = 0; //real-inode
- goto out;
- }
- inode_unref (dst->inode);
- dst->inode = inode_ref ((inode_t*)value);
- uuid_copy (dst->gfid, dst->inode->gfid);
- }
-out:
-
- return ret;
-}
-
-void
-ga_newfile_args_free (ga_newfile_args_t *args)
-{
- if (!args)
- goto out;
-
- GF_FREE (args->bname);
-
- if (S_ISLNK (args->st_mode) && args->args.symlink.linkpath) {
- GF_FREE (args->args.symlink.linkpath);
- args->args.symlink.linkpath = NULL;
- }
-
- mem_put (args);
-out:
- return;
-}
-
-
-void
-ga_heal_args_free (ga_heal_args_t *args)
-{
- if (!args)
- goto out;
-
- GF_FREE (args->bname);
-
- mem_put (args);
-out:
- return;
-}
-
-
-ga_newfile_args_t *
-ga_newfile_parse_args (xlator_t *this, data_t *data)
-{
- ga_newfile_args_t *args = NULL;
- ga_private_t *priv = NULL;
- int len = 0;
- int blob_len = 0;
- int min_len = 0;
- void *blob = NULL;
-
- priv = this->private;
-
- blob = data->data;
- blob_len = data->len;
-
- min_len = sizeof (args->uid) + sizeof (args->gid) + sizeof (args->gfid)
- + sizeof (args->st_mode) + 2 + 2;
- if (blob_len < min_len) {
- gf_log (this->name, GF_LOG_ERROR,
- "Invalid length: Total length is less "
- "than minimum length.");
- goto err;
- }
-
- args = mem_get0 (priv->newfile_args_pool);
- if (args == NULL)
- goto err;
-
- args->uid = ntoh32 (*(uint32_t *)blob);
- blob += sizeof (uint32_t);
- blob_len -= sizeof (uint32_t);
-
- args->gid = ntoh32 (*(uint32_t *)blob);
- blob += sizeof (uint32_t);
- blob_len -= sizeof (uint32_t);
-
- memcpy (args->gfid, blob, sizeof (args->gfid));
- blob += sizeof (args->gfid);
- blob_len -= sizeof (args->gfid);
-
- args->st_mode = ntoh32 (*(uint32_t *)blob);
- blob += sizeof (uint32_t);
- blob_len -= sizeof (uint32_t);
-
- len = strnlen (blob, blob_len);
- if (len == blob_len) {
- gf_log (this->name, GF_LOG_ERROR,
- "gfid: %s. No null byte present.",
- args->gfid);
- goto err;
- }
-
- args->bname = GF_CALLOC (1, (len + 1), gf_common_mt_char);
- if (args->bname == NULL)
- goto err;
-
- memcpy (args->bname, blob, (len + 1));
- blob += (len + 1);
- blob_len -= (len + 1);
-
- if (S_ISDIR (args->st_mode)) {
- if (blob_len < sizeof (uint32_t)) {
- gf_log (this->name, GF_LOG_ERROR,
- "gfid: %s. Invalid length",
- args->gfid);
- goto err;
- }
- args->args.mkdir.mode = ntoh32 (*(uint32_t *)blob);
- blob += sizeof (uint32_t);
- blob_len -= sizeof (uint32_t);
-
- if (blob_len < sizeof (uint32_t)) {
- gf_log (this->name, GF_LOG_ERROR,
- "gfid: %s. Invalid length",
- args->gfid);
- goto err;
- }
- args->args.mkdir.umask = ntoh32 (*(uint32_t *)blob);
- blob += sizeof (uint32_t);
- blob_len -= sizeof (uint32_t);
- if (blob_len < 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "gfid: %s. Invalid length",
- args->gfid);
- goto err;
- }
- } else if (S_ISLNK (args->st_mode)) {
- len = strnlen (blob, blob_len);
- if (len == blob_len) {
- gf_log (this->name, GF_LOG_ERROR,
- "gfid: %s. Invalid length",
- args->gfid);
- goto err;
- }
- args->args.symlink.linkpath = GF_CALLOC (1, len + 1,
- gf_common_mt_char);
- if (args->args.symlink.linkpath == NULL)
- goto err;
-
- memcpy (args->args.symlink.linkpath, blob, (len + 1));
- blob += (len + 1);
- blob_len -= (len + 1);
- } else {
- if (blob_len < sizeof (uint32_t)) {
- gf_log (this->name, GF_LOG_ERROR,
- "gfid: %s. Invalid length",
- args->gfid);
- goto err;
- }
- args->args.mknod.mode = ntoh32 (*(uint32_t *)blob);
- blob += sizeof (uint32_t);
- blob_len -= sizeof (uint32_t);
-
- if (blob_len < sizeof (uint32_t)) {
- gf_log (this->name, GF_LOG_ERROR,
- "gfid: %s. Invalid length",
- args->gfid);
- goto err;
- }
- args->args.mknod.rdev = ntoh32 (*(uint32_t *)blob);
- blob += sizeof (uint32_t);
- blob_len -= sizeof (uint32_t);
-
- if (blob_len < sizeof (uint32_t)) {
- gf_log (this->name, GF_LOG_ERROR,
- "gfid: %s. Invalid length",
- args->gfid);
- goto err;
- }
- args->args.mknod.umask = ntoh32 (*(uint32_t *)blob);
- blob += sizeof (uint32_t);
- blob_len -= sizeof (uint32_t);
- }
-
- if (blob_len) {
- gf_log (this->name, GF_LOG_ERROR,
- "gfid: %s. Invalid length",
- args->gfid);
- goto err;
- }
-
- return args;
-
-err:
- if (args)
- ga_newfile_args_free (args);
-
- return NULL;
-}
-
-ga_heal_args_t *
-ga_heal_parse_args (xlator_t *this, data_t *data)
-{
- ga_heal_args_t *args = NULL;
- ga_private_t *priv = NULL;
- void *blob = NULL;
- int len = 0;
- int blob_len = 0;
-
- blob = data->data;
- blob_len = data->len;
-
- priv = this->private;
-
- /* bname should at least contain a character */
- if (blob_len < (sizeof (args->gfid) + 2))
- goto err;
-
- args = mem_get0 (priv->heal_args_pool);
- if (!args)
- goto err;
-
- memcpy (args->gfid, blob, sizeof (args->gfid));
- blob += sizeof (args->gfid);
- blob_len -= sizeof (args->gfid);
-
- len = strnlen (blob, blob_len);
- if (len == blob_len)
- goto err;
-
- args->bname = GF_CALLOC (1, len + 1, gf_common_mt_char);
- if (!args->bname)
- goto err;
-
- memcpy (args->bname, blob, len);
- blob_len -= (len + 1);
-
- if (blob_len)
- goto err;
-
- return args;
-
-err:
- if (args)
- ga_heal_args_free (args);
-
- return NULL;
-}
-
-static int32_t
-ga_fill_tmp_loc (loc_t *loc, xlator_t *this, uuid_t gfid,
- char *bname, dict_t *xdata, loc_t *new_loc)
-{
- int ret = -1;
- uint64_t value = 0;
- inode_t *parent = NULL;
- uuid_t *gfid_ptr = NULL;
-
- parent = loc->inode;
- ret = inode_ctx_get (loc->inode, this, &value);
- if (!ret) {
- parent = (void *)value;
- if (uuid_is_null (parent->gfid))
- parent = loc->inode;
- }
-
- /* parent itself should be looked up */
- uuid_copy (new_loc->pargfid, parent->gfid);
- new_loc->parent = inode_ref (parent);
-
- new_loc->inode = inode_grep (parent->table, parent, bname);
- if (!new_loc->inode) {
- new_loc->inode = inode_new (parent->table);
- uuid_copy (new_loc->inode->gfid, gfid);
- }
-
- loc_path (new_loc, bname);
- if (new_loc->path) {
- new_loc->name = strrchr (new_loc->path, '/');
- if (new_loc->name)
- new_loc->name++;
- }
-
- gfid_ptr = GF_CALLOC (1, sizeof(uuid_t), gf_common_mt_uuid_t);
- if (!gfid_ptr) {
- ret = -1;
- goto out;
- }
- uuid_copy (*gfid_ptr, gfid);
- ret = dict_set_dynptr (xdata, "gfid-req", gfid_ptr, sizeof (uuid_t));
- if (ret < 0)
- goto out;
-
- ret = 0;
-
-out:
- if (ret && gfid_ptr)
- GF_FREE (gfid_ptr);
- return ret;
-}
-
-
-
-static gf_boolean_t
-__is_gfid_access_dir (uuid_t gfid)
-{
- uuid_t aux_gfid;
-
- memset (aux_gfid, 0, 16);
- aux_gfid[15] = GF_AUX_GFID;
-
- if (uuid_compare (gfid, aux_gfid) == 0)
- return _gf_true;
-
- return _gf_false;
-}
-
-int32_t
-ga_forget (xlator_t *this, inode_t *inode)
-{
- int ret = -1;
- uint64_t value = 0;
- inode_t *tmp_inode = NULL;
-
- ret = inode_ctx_del (inode, this, &value);
- if (ret)
- goto out;
-
- tmp_inode = (void *)value;
- inode_unref (tmp_inode);
-
-out:
- return 0;
-}
-
-
-static int
-ga_heal_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno,
- inode_t *inode, struct iatt *stat, dict_t *dict,
- struct iatt *postparent)
-{
- call_frame_t *orig_frame = NULL;
-
- orig_frame = frame->local;
- frame->local = NULL;
-
- /* don't worry about inode linking and other stuff. They'll happen on
- * the next lookup.
- */
- STACK_DESTROY (frame->root);
-
- STACK_UNWIND_STRICT (setxattr, orig_frame, op_ret, op_errno, dict);
-
- return 0;
-}
-
-static int32_t
-ga_newentry_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)
-{
- ga_local_t *local = NULL;
-
- local = frame->local;
- frame->local = NULL;
-
- /* don't worry about inode linking and other stuff. They'll happen on
- * the next lookup.
- */
- STACK_DESTROY (frame->root);
-
- STACK_UNWIND_STRICT (setxattr, local->orig_frame, op_ret,
- op_errno, xdata);
-
- loc_wipe (&local->loc);
- mem_put (local);
-
- return 0;
-}
-
-static int
-ga_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)
-{
- ga_local_t *local = NULL;
- struct iatt temp_stat = {0,};
-
- local = frame->local;
-
- /* no need to proceed if things don't look good here */
- if (op_ret == -1)
- goto done;
-
- temp_stat.ia_uid = local->uid;
- temp_stat.ia_gid = local->gid;
-
- STACK_WIND (frame, ga_newentry_setattr_cbk, FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->setattr, &local->loc, &temp_stat,
- (GF_SET_ATTR_UID | GF_SET_ATTR_GID), xdata);
-
- return 0;
-
-done:
- /* don't worry about inode linking and other stuff. They'll happen on
- * the next lookup.
- */
- frame->local = NULL;
- STACK_DESTROY (frame->root);
-
- STACK_UNWIND_STRICT (setxattr, local->orig_frame, op_ret,
- op_errno, xdata);
-
- loc_wipe (&local->loc);
- mem_put (local);
-
- return 0;
-}
-
-int32_t
-ga_new_entry (call_frame_t *frame, xlator_t *this, loc_t *loc, data_t *data,
- dict_t *xdata)
-{
- int ret = -1;
- ga_newfile_args_t *args = NULL;
- loc_t tmp_loc = {0,};
- call_frame_t *new_frame = NULL;
- mode_t mode = 0;
- ga_local_t *local = NULL;
- uuid_t gfid = {0,};
-
- args = ga_newfile_parse_args (this, data);
- if (!args)
- goto out;
-
- ret = uuid_parse (args->gfid, gfid);
- if (ret)
- goto out;
-
- if (!xdata) {
- xdata = dict_new ();
- } else {
- xdata = dict_ref (xdata);
- }
-
- if (!xdata) {
- ret = -1;
- goto out;
- }
-
- ret = ga_fill_tmp_loc (loc, this, gfid,
- args->bname, xdata, &tmp_loc);
- if (ret)
- goto out;
-
- new_frame = copy_frame (frame);
- if (!new_frame)
- goto out;
-
- local = mem_get0 (this->local_pool);
- local->orig_frame = frame;
-
- local->uid = args->uid;
- local->gid = args->gid;
-
- loc_copy (&local->loc, &tmp_loc);
-
- new_frame->local = local;
-
- if (S_ISDIR (args->st_mode)) {
- STACK_WIND (new_frame, ga_newentry_cbk,
- FIRST_CHILD(this), FIRST_CHILD(this)->fops->mkdir,
- &tmp_loc, args->args.mkdir.mode,
- args->args.mkdir.umask, xdata);
- } else if (S_ISLNK (args->st_mode)) {
- STACK_WIND (new_frame, ga_newentry_cbk,
- FIRST_CHILD(this), FIRST_CHILD(this)->fops->symlink,
- args->args.symlink.linkpath,
- &tmp_loc, 0, xdata);
- } else {
- /* use 07777 (4 7s) for considering the Sticky bits etc) */
- mode = (S_IFMT & args->st_mode) |
- (07777 & args->args.mknod.mode);;
-
- STACK_WIND (new_frame, ga_newentry_cbk,
- FIRST_CHILD(this), FIRST_CHILD(this)->fops->mknod,
- &tmp_loc, mode,
- args->args.mknod.rdev, args->args.mknod.umask,
- xdata);
- }
-
- ret = 0;
-out:
- ga_newfile_args_free (args);
-
- if (xdata)
- dict_unref (xdata);
-
- loc_wipe (&tmp_loc);
-
- return ret;
-}
-
-int32_t
-ga_heal_entry (call_frame_t *frame, xlator_t *this, loc_t *loc, data_t *data,
- dict_t *xdata)
-{
- int ret = -1;
- ga_heal_args_t *args = NULL;
- loc_t tmp_loc = {0,};
- call_frame_t *new_frame = NULL;
- uuid_t gfid = {0,};
-
- args = ga_heal_parse_args (this, data);
- if (!args)
- goto out;
-
- ret = uuid_parse (args->gfid, gfid);
- if (ret)
- goto out;
-
- if (!xdata)
- xdata = dict_new ();
- else
- xdata = dict_ref (xdata);
-
- if (!xdata) {
- ret = -1;
- goto out;
- }
-
- ret = ga_fill_tmp_loc (loc, this, gfid, args->bname,
- xdata, &tmp_loc);
- if (ret)
- goto out;
-
- new_frame = copy_frame (frame);
- if (!new_frame)
- goto out;
-
- new_frame->local = (void *)frame;
-
- STACK_WIND (new_frame, ga_heal_cbk, FIRST_CHILD (this),
- FIRST_CHILD(this)->fops->lookup,
- &tmp_loc, xdata);
-
- ret = 0;
-out:
- if (args)
- ga_heal_args_free (args);
-
- loc_wipe (&tmp_loc);
-
- if (xdata)
- dict_unref (xdata);
-
- return ret;
-}
-
-int32_t
-ga_setxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno,
- dict_t *xdata)
-{
- STACK_UNWIND_STRICT (setxattr, frame, op_ret, op_errno, xdata);
- return 0;
-}
-
-int32_t
-ga_setxattr (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *dict,
- int32_t flags, dict_t *xdata)
-{
- data_t *data = NULL;
- int op_errno = ENOMEM;
- int ret = 0;
- loc_t ga_loc = {0, };
-
- GFID_ACCESS_INODE_OP_CHECK (loc, op_errno, err);
-
- data = dict_get (dict, GF_FUSE_AUX_GFID_NEWFILE);
- if (data) {
- ret = ga_new_entry (frame, this, loc, data, xdata);
- if (ret)
- goto err;
- return 0;
- }
-
- data = dict_get (dict, GF_FUSE_AUX_GFID_HEAL);
- if (data) {
- ret = ga_heal_entry (frame, this, loc, data, xdata);
- if (ret)
- goto err;
- return 0;
- }
-
- //If the inode is a virtual inode change the inode otherwise perform
- //the operation on same inode
- ret = ga_valid_inode_loc_copy (&ga_loc, loc, this);
- if (ret < 0)
- goto err;
-
- STACK_WIND (frame, ga_setxattr_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->setxattr, &ga_loc, dict, flags,
- xdata);
-
- loc_wipe (&ga_loc);
- return 0;
-err:
- STACK_UNWIND_STRICT (setxattr, frame, -1, op_errno, xdata);
- return 0;
-}
-
-
-int32_t
-ga_virtual_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)
-{
- int j = 0;
- int i = 0;
- int ret = 0;
- uint64_t temp_ino = 0;
- inode_t *cbk_inode = NULL;
- inode_t *true_inode = NULL;
- uuid_t random_gfid = {0,};
- inode_t *linked_inode = NULL;
-
- if (frame->local)
- cbk_inode = frame->local;
- else
- cbk_inode = inode_ref (inode);
-
- frame->local = NULL;
- if (op_ret)
- goto unwind;
-
- if (!IA_ISDIR (buf->ia_type))
- goto unwind;
-
- /* need to send back a different inode for linking in itable */
- if (cbk_inode == inode) {
- /* check if the inode is in the 'itable' or
- if its just previously discover()'d inode */
- true_inode = inode_find (inode->table, buf->ia_gfid);
- if (!true_inode) {
- /* This unref is for 'inode_ref()' done in beginning.
- This is needed as cbk_inode is allocated new inode
- whose unref is taken at the end*/
- inode_unref (cbk_inode);
- cbk_inode = inode_new (inode->table);
-
- if (!cbk_inode) {
- op_ret = -1;
- op_errno = ENOMEM;
- goto unwind;
- }
- /* the inode is not present in itable, ie, the actual
- path is not yet looked up. Use the current inode
- itself for now */
-
- linked_inode = inode_link (inode, NULL, NULL, buf);
- inode = linked_inode;
- } else {
- /* 'inode_ref()' has been done in inode_find() */
- inode = true_inode;
- }
-
- ret = inode_ctx_put (cbk_inode, this, (uint64_t)inode);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING,
- "failed to set the inode ctx with"
- "the actual inode");
- if (inode)
- inode_unref (inode);
- }
- inode = NULL;
- }
-
- if (!uuid_is_null (cbk_inode->gfid)) {
- /* if the previous linked inode is used, use the
- same gfid */
- uuid_copy (random_gfid, cbk_inode->gfid);
- } else {
- /* replace the buf->ia_gfid to a random gfid
- for directory, for files, what we received is fine */
- uuid_generate (random_gfid);
- }
-
- uuid_copy (buf->ia_gfid, random_gfid);
-
- for (i = 15; i > (15 - 8); i--) {
- temp_ino += (uint64_t)(buf->ia_gfid[i]) << j;
- j += 8;
- }
- buf->ia_ino = temp_ino;
-
-unwind:
- /* Lookup on non-existing gfid returns ESTALE.
- Convert into ENOENT for virtual lookup*/
- if (op_errno == ESTALE)
- op_errno = ENOENT;
-
- STACK_UNWIND_STRICT (lookup, frame, op_ret, op_errno, cbk_inode, buf,
- xdata, postparent);
-
- /* Also handles inode_unref of frame->local if done in ga_lookup */
- if (cbk_inode)
- inode_unref (cbk_inode);
-
- return 0;
-}
-
-int32_t
-ga_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)
-{
- ga_private_t *priv = NULL;
-
- /* if the entry in question is not 'root',
- then follow the normal path */
- if (op_ret || !__is_root_gfid(buf->ia_gfid))
- goto unwind;
-
- priv = this->private;
-
- /* do we need to copy root stbuf everytime? */
- /* mostly yes, as we want to have the 'stat' info show latest
- in every _cbk() */
-
- /* keep the reference for root stat buf */
- priv->root_stbuf = *buf;
- priv->gfiddir_stbuf = priv->root_stbuf;
- priv->gfiddir_stbuf.ia_gfid[15] = GF_AUX_GFID;
- priv->gfiddir_stbuf.ia_ino = GF_AUX_GFID;
-
-unwind:
- STACK_UNWIND_STRICT (lookup, frame, op_ret, op_errno, inode, buf,
- xdata, postparent);
- return 0;
-}
-
-int32_t
-ga_lookup (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
-{
- ga_private_t *priv = NULL;
- int ret = -1;
- uuid_t tmp_gfid = {0,};
- loc_t tmp_loc = {0,};
- uint64_t value = 0;
- inode_t *inode = NULL;
- inode_t *true_inode = NULL;
- int32_t op_errno = ENOENT;
-
- /* if its discover(), no need for any action here */
- if (!loc->name)
- goto wind;
-
- /* if its revalidate, and inode is not of type directory,
- proceed with 'wind' */
- if (loc->inode && loc->inode->ia_type &&
- !IA_ISDIR (loc->inode->ia_type)) {
-
- /* a revalidate on ".gfid/<dentry>" is possible, check for it */
- if (((loc->parent &&
- __is_gfid_access_dir (loc->parent->gfid)) ||
- __is_gfid_access_dir (loc->pargfid))) {
-
- /* here, just send 'loc->gfid' and 'loc->inode' */
- tmp_loc.inode = inode_ref (loc->inode);
- uuid_copy (tmp_loc.gfid, loc->inode->gfid);
-
- STACK_WIND (frame, default_lookup_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->lookup,
- &tmp_loc, xdata);
-
- inode_unref (tmp_loc.inode);
-
- return 0;
- }
-
- /* not something to bother, continue the flow */
- goto wind;
- }
-
- priv = this->private;
-
- /* need to check if the lookup is on virtual dir */
- if ((loc->name && !strcmp (GF_GFID_DIR, loc->name)) &&
- ((loc->parent && __is_root_gfid (loc->parent->gfid)) ||
- __is_root_gfid (loc->pargfid))) {
- /* this means, the query is on '/.gfid', return the fake stat,
- and say success */
-
- STACK_UNWIND_STRICT (lookup, frame, 0, 0, loc->inode,
- &priv->gfiddir_stbuf, xdata,
- &priv->root_stbuf);
- return 0;
- }
-
- /* now, check if the lookup() is on an existing entry,
- but on gfid-path */
- if (!((loc->parent && __is_gfid_access_dir (loc->parent->gfid)) ||
- __is_gfid_access_dir (loc->pargfid))) {
- if (!loc->parent)
- goto wind;
-
- ret = inode_ctx_get (loc->parent, this, &value);
- if (ret)
- goto wind;
-
- inode = (inode_t *) value;
-
- ret = loc_copy_overload_parent (&tmp_loc, loc, inode);
- if (ret)
- goto err;
-
- STACK_WIND (frame, ga_lookup_cbk, FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->lookup, &tmp_loc, xdata);
-
- loc_wipe (&tmp_loc);
- return 0;
- }
-
- /* make sure the 'basename' is actually a 'canonical-gfid',
- otherwise, return error */
- ret = uuid_parse (loc->name, tmp_gfid);
- if (ret)
- goto err;
-
- /* if its fresh lookup, go ahead and send it down, if not,
- for directory, we need indirection to actual dir inode */
- if (!(loc->inode && loc->inode->ia_type))
- goto discover;
-
- /* revalidate on directory */
- ret = inode_ctx_get (loc->inode, this, &value);
- if (ret)
- goto err;
-
- inode = (void *)value;
-
- /* valid inode, already looked up, work on that */
- if (inode->ia_type)
- goto discover;
-
- /* check if the inode is in the 'itable' or
- if its just previously discover()'d inode */
- true_inode = inode_find (loc->inode->table, tmp_gfid);
- if (true_inode) {
- /* time do another lookup and update the context
- with proper inode */
- op_errno = ESTALE;
- /* 'inode_ref()' done in inode_find */
- inode_unref (true_inode);
- goto err;
- }
-
-discover:
- /* for the virtual entries, we don't need to send 'gfid-req' key, as
- for these entries, we don't want to 'set' a new gfid */
- if (xdata)
- dict_del (xdata, "gfid-req");
-
- uuid_copy (tmp_loc.gfid, tmp_gfid);
-
- /* if revalidate, then we need to have the proper reference */
- if (inode) {
- tmp_loc.inode = inode_ref (inode);
- frame->local = inode_ref (loc->inode);
- } else {
- tmp_loc.inode = inode_ref (loc->inode);
- }
-
- STACK_WIND (frame, ga_virtual_lookup_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->lookup, &tmp_loc, xdata);
-
- inode_unref (tmp_loc.inode);
-
- return 0;
-
-wind:
- /* used for all the normal lookup path */
- STACK_WIND (frame, ga_lookup_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->lookup, loc, xdata);
-
- return 0;
-
-err:
- STACK_UNWIND_STRICT (lookup, frame, -1, op_errno, loc->inode,
- &priv->gfiddir_stbuf, xdata,
- &priv->root_stbuf);
- return 0;
-}
-
-int
-ga_mkdir (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
- mode_t umask, dict_t *xdata)
-{
- int op_errno = ENOMEM;
-
- GFID_ACCESS_ENTRY_OP_CHECK (loc, op_errno, err);
-
- STACK_WIND (frame, default_mkdir_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->mkdir, loc, mode, umask,
- xdata);
-
- return 0;
-
-err:
- STACK_UNWIND_STRICT (mkdir, frame, -1, op_errno, loc->inode,
- NULL, NULL, NULL, xdata);
- return 0;
-}
-
-
-int
-ga_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)
-{
- int op_errno = ENOMEM;
-
- GFID_ACCESS_ENTRY_OP_CHECK (loc, op_errno, err);
-
- STACK_WIND (frame, default_create_cbk,
- FIRST_CHILD(this), FIRST_CHILD(this)->fops->create,
- loc, flags, mode, umask, fd, xdata);
- return 0;
-err:
- STACK_UNWIND_STRICT (create, frame, -1, op_errno, NULL,
- NULL, NULL, NULL, NULL, xdata);
-
- return 0;
-
-}
-
-int
-ga_symlink (call_frame_t *frame, xlator_t *this, const char *linkname,
- loc_t *loc, mode_t umask, dict_t *xdata)
-{
- int op_errno = ENOMEM;
-
- GFID_ACCESS_ENTRY_OP_CHECK (loc, op_errno, err);
-
- STACK_WIND (frame, default_symlink_cbk,
- FIRST_CHILD(this), FIRST_CHILD(this)->fops->symlink,
- linkname, loc, umask, xdata);
- return 0;
-err:
- STACK_UNWIND_STRICT (symlink, frame, -1, op_errno, NULL,
- NULL, NULL, NULL, xdata);
-
- return 0;
-}
-
-int
-ga_mknod (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
- dev_t rdev, mode_t umask, dict_t *xdata)
-{
- int op_errno = ENOMEM;
-
- GFID_ACCESS_ENTRY_OP_CHECK (loc, op_errno, err);
-
- STACK_WIND (frame, default_mknod_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->mknod, loc, mode, rdev,
- umask, xdata);
-
- return 0;
-err:
- STACK_UNWIND_STRICT (mknod, frame, -1, op_errno, NULL,
- NULL, NULL, NULL, xdata);
-
- return 0;
-}
-
-int
-ga_rmdir (call_frame_t *frame, xlator_t *this, loc_t *loc, int flag,
- dict_t *xdata)
-{
- int op_errno = ENOMEM;
- int ret = -1;
- loc_t ga_loc = {0, };
-
- GFID_ACCESS_ENTRY_OP_CHECK (loc, op_errno, err);
-
- ret = ga_valid_inode_loc_copy (&ga_loc, loc, this);
- if (ret < 0)
- goto err;
-
- STACK_WIND (frame, default_rmdir_cbk,
- FIRST_CHILD(this), FIRST_CHILD(this)->fops->rmdir,
- &ga_loc, flag, xdata);
-
- loc_wipe (&ga_loc);
- return 0;
-err:
- STACK_UNWIND_STRICT (rmdir, frame, -1, op_errno, NULL,
- NULL, xdata);
-
- return 0;
-}
-
-int
-ga_unlink (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t xflag,
- dict_t *xdata)
-{
- int op_errno = ENOMEM;
- int ret = -1;
- loc_t ga_loc = {0, };
-
- GFID_ACCESS_ENTRY_OP_CHECK (loc, op_errno, err);
-
- ret = ga_valid_inode_loc_copy (&ga_loc, loc, this);
- if (ret < 0)
- goto err;
-
- STACK_WIND (frame, default_unlink_cbk,
- FIRST_CHILD(this), FIRST_CHILD(this)->fops->unlink,
- &ga_loc, xflag, xdata);
-
- loc_wipe (&ga_loc);
- return 0;
-err:
- STACK_UNWIND_STRICT (unlink, frame, -1, op_errno, NULL,
- NULL, xdata);
-
- return 0;
-}
-
-int
-ga_rename (call_frame_t *frame, xlator_t *this,
- loc_t *oldloc, loc_t *newloc, dict_t *xdata)
-{
- int op_errno = ENOMEM;
- int ret = 0;
- loc_t ga_oldloc = {0, };
- loc_t ga_newloc = {0, };
-
- GFID_ACCESS_ENTRY_OP_CHECK (oldloc, op_errno, err);
- GFID_ACCESS_ENTRY_OP_CHECK (newloc, op_errno, err);
-
- ret = ga_valid_inode_loc_copy (&ga_oldloc, oldloc, this);
- if (ret < 0)
- goto err;
-
- ret = ga_valid_inode_loc_copy (&ga_newloc, newloc, this);
- if (ret < 0) {
- loc_wipe (&ga_oldloc);
- goto err;
- }
-
- STACK_WIND (frame, default_rename_cbk,
- FIRST_CHILD(this), FIRST_CHILD(this)->fops->rename,
- &ga_oldloc, &ga_newloc, xdata);
-
- loc_wipe (&ga_newloc);
- loc_wipe (&ga_oldloc);
- return 0;
-err:
- STACK_UNWIND_STRICT (rename, frame, -1, op_errno, NULL,
- NULL, NULL, NULL, NULL, xdata);
-
- return 0;
-}
-
-
-int
-ga_link (call_frame_t *frame, xlator_t *this,
- loc_t *oldloc, loc_t *newloc, dict_t *xdata)
-{
- int op_errno = ENOMEM;
- int ret = 0;
- loc_t ga_oldloc = {0, };
- loc_t ga_newloc = {0, };
-
- GFID_ACCESS_ENTRY_OP_CHECK (oldloc, op_errno, err);
- GFID_ACCESS_ENTRY_OP_CHECK (newloc, op_errno, err);
-
- ret = ga_valid_inode_loc_copy (&ga_oldloc, oldloc, this);
- if (ret < 0)
- goto err;
-
- ret = ga_valid_inode_loc_copy (&ga_newloc, newloc, this);
- if (ret < 0) {
- loc_wipe (&ga_oldloc);
- goto err;
- }
-
- STACK_WIND (frame, default_link_cbk,
- FIRST_CHILD(this), FIRST_CHILD(this)->fops->link,
- &ga_oldloc, &ga_newloc, xdata);
-
- loc_wipe (&ga_newloc);
- loc_wipe (&ga_oldloc);
- return 0;
-
-err:
- STACK_UNWIND_STRICT (link, frame, -1, op_errno, NULL,
- NULL, NULL, NULL, xdata);
-
- return 0;
-}
-
-int32_t
-ga_opendir (call_frame_t *frame, xlator_t *this, loc_t *loc,
- fd_t *fd, dict_t *xdata)
-{
- int op_errno = ENOMEM;
-
- GFID_ACCESS_INODE_OP_CHECK (loc, op_errno, err);
-
- /* also check if the loc->inode itself is virtual
- inode, if yes, return with failure, mainly because we
- can't handle all the readdirp and other things on it. */
- if (inode_ctx_get (loc->inode, this, NULL) == 0) {
- op_errno = ENOTSUP;
- goto err;
- }
-
- STACK_WIND (frame, default_opendir_cbk,
- FIRST_CHILD(this), FIRST_CHILD(this)->fops->opendir,
- loc, fd, xdata);
- return 0;
-err:
- STACK_UNWIND_STRICT (opendir, frame, -1, op_errno, NULL, xdata);
-
- return 0;
-}
-
-int32_t
-ga_getxattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
- const char *name, dict_t *xdata)
-{
- int op_errno = ENOMEM;
- int ret = -1;
- loc_t ga_loc = {0, };
-
- GFID_ACCESS_INODE_OP_CHECK (loc, op_errno, err);
- ret = ga_valid_inode_loc_copy (&ga_loc, loc, this);
- if (ret < 0)
- goto err;
-
- STACK_WIND (frame, default_getxattr_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->getxattr, &ga_loc, name, xdata);
-
- loc_wipe (&ga_loc);
-
- return 0;
-err:
- STACK_UNWIND_STRICT (getxattr, frame, -1, op_errno, NULL, xdata);
-
- return 0;
-}
-
-int32_t
-ga_stat (call_frame_t *frame, xlator_t *this, loc_t *loc,
- dict_t *xdata)
-{
- int op_errno = ENOMEM;
- int ret = -1;
- loc_t ga_loc = {0, };
- ga_private_t *priv = NULL;
-
- priv = this->private;
- /* If stat is on ".gfid" itself, do not wind further,
- * return fake stat and return success.
- */
- if (__is_gfid_access_dir(loc->gfid))
- goto out;
-
- ret = ga_valid_inode_loc_copy (&ga_loc, loc, this);
- if (ret < 0)
- goto err;
-
- STACK_WIND (frame, default_stat_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->stat, &ga_loc, xdata);
-
- loc_wipe (&ga_loc);
- return 0;
-
-err:
- STACK_UNWIND_STRICT (stat, frame, -1, op_errno, NULL, xdata);
-
- return 0;
-
-out:
- STACK_UNWIND_STRICT (stat, frame, 0, 0, &priv->gfiddir_stbuf, xdata);
- return 0;
-}
-
-int32_t
-ga_setattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
- struct iatt *stbuf, int32_t valid,
- dict_t *xdata)
-{
- int op_errno = ENOMEM;
- int ret = -1;
- loc_t ga_loc = {0, };
-
- GFID_ACCESS_INODE_OP_CHECK (loc, op_errno, err);
- ret = ga_valid_inode_loc_copy (&ga_loc, loc, this);
- if (ret < 0)
- goto err;
-
- STACK_WIND (frame, default_setattr_cbk, FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->setattr, &ga_loc, stbuf, valid,
- xdata);
-
- loc_wipe (&ga_loc);
- return 0;
-err:
- STACK_UNWIND_STRICT (setattr, frame, -1, op_errno, NULL, NULL, xdata);
-
- return 0;
-}
-
-int32_t
-ga_removexattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
- const char *name, dict_t *xdata)
-{
- int op_errno = ENOMEM;
- int ret = -1;
- loc_t ga_loc = {0, };
-
- GFID_ACCESS_INODE_OP_CHECK (loc, op_errno, err);
- ret = ga_valid_inode_loc_copy (&ga_loc, loc, this);
- if (ret < 0)
- goto err;
-
- STACK_WIND (frame, default_removexattr_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->removexattr, &ga_loc, name,
- xdata);
-
- loc_wipe (&ga_loc);
- return 0;
-
-err:
- STACK_UNWIND_STRICT (removexattr, frame, -1, op_errno, xdata);
-
- return 0;
-}
-
-
-int32_t
-mem_acct_init (xlator_t *this)
-{
- int ret = -1;
-
- if (!this)
- return ret;
-
- ret = xlator_mem_acct_init (this, gf_gfid_access_mt_end + 1);
-
- if (ret != 0) {
- gf_log (this->name, GF_LOG_WARNING, "Memory accounting"
- " init failed");
- return ret;
- }
-
- return ret;
-}
-
-int32_t
-init (xlator_t *this)
-{
- ga_private_t *priv = NULL;
- int ret = -1;
-
- if (!this->children || this->children->next) {
- gf_log (this->name, GF_LOG_ERROR,
- "not configured with exactly one child. exiting");
- goto out;
- }
-
- /* This can be the top of graph in certain cases */
- if (!this->parents) {
- gf_log (this->name, GF_LOG_DEBUG,
- "dangling volume. check volfile ");
- }
-
- /* TODO: define a mem-type structure */
- priv = GF_CALLOC (1, sizeof (*priv), gf_gfid_access_mt_priv_t);
- if (!priv)
- goto out;
-
- priv->newfile_args_pool = mem_pool_new (ga_newfile_args_t, 512);
- if (!priv->newfile_args_pool)
- goto out;
-
- priv->heal_args_pool = mem_pool_new (ga_heal_args_t, 512);
- if (!priv->heal_args_pool)
- goto out;
-
- this->local_pool = mem_pool_new (ga_local_t, 16);
- if (!this->local_pool) {
- 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 && priv) {
- if (priv->newfile_args_pool)
- mem_pool_destroy (priv->newfile_args_pool);
- GF_FREE (priv);
- }
-
- return ret;
-}
-
-void
-fini (xlator_t *this)
-{
- ga_private_t *priv = NULL;
- priv = this->private;
- this->private = NULL;
-
- if (priv) {
- if (priv->newfile_args_pool)
- mem_pool_destroy (priv->newfile_args_pool);
- if (priv->heal_args_pool)
- mem_pool_destroy (priv->heal_args_pool);
- GF_FREE (priv);
- }
-
- return;
-}
-
-
-struct xlator_fops fops = {
- .lookup = ga_lookup,
-
- /* entry fops */
- .mkdir = ga_mkdir,
- .mknod = ga_mknod,
- .create = ga_create,
- .symlink = ga_symlink,
- .link = ga_link,
- .unlink = ga_unlink,
- .rmdir = ga_rmdir,
- .rename = ga_rename,
-
- /* handle any other directory operations here */
- .opendir = ga_opendir,
- .stat = ga_stat,
- .setattr = ga_setattr,
- .getxattr = ga_getxattr,
- .removexattr = ga_removexattr,
-
- /* special fop to handle more entry creations */
- .setxattr = ga_setxattr,
-};
-
-struct xlator_cbks cbks = {
- .forget = ga_forget,
-};
-
-struct volume_options options[] = {
- /* This translator doesn't take any options, or provide any options */
- { .key = {NULL} },
-};
diff --git a/xlators/features/gfid-access/src/gfid-access.h b/xlators/features/gfid-access/src/gfid-access.h
deleted file mode 100644
index 5c7a95af4c8..00000000000
--- a/xlators/features/gfid-access/src/gfid-access.h
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- Copyright (c) 2013 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 __GFID_ACCESS_H__
-#define __GFID_ACCESS_H__
-
-#ifndef _CONFIG_H
-#define _CONFIG_H
-#include "config.h"
-#endif
-
-#include "glusterfs.h"
-#include "logging.h"
-#include "dict.h"
-#include "xlator.h"
-#include "defaults.h"
-#include "gfid-access-mem-types.h"
-
-#define UUID_CANONICAL_FORM_LEN 36
-
-#define GF_FUSE_AUX_GFID_NEWFILE "glusterfs.gfid.newfile"
-#define GF_FUSE_AUX_GFID_HEAL "glusterfs.gfid.heal"
-
-#define GF_GFID_KEY "GLUSTERFS_GFID"
-#define GF_GFID_DIR ".gfid"
-#define GF_AUX_GFID 0xd
-
-#define GFID_ACCESS_ENTRY_OP_CHECK(loc,err,lbl) do { \
- /* need to check if the lookup is on virtual dir */ \
- if ((loc->name && !strcmp (GF_GFID_DIR, loc->name)) && \
- ((loc->parent && \
- __is_root_gfid (loc->parent->gfid)) || \
- __is_root_gfid (loc->pargfid))) { \
- err = ENOTSUP; \
- goto lbl; \
- } \
- \
- /* now, check if the lookup() is on an existing */ \
- /* entry, but on gfid-path */ \
- if ((loc->parent && \
- __is_gfid_access_dir (loc->parent->gfid)) || \
- __is_gfid_access_dir (loc->pargfid)) { \
- err = EPERM; \
- goto lbl; \
- } \
- } while (0)
-
-#define GFID_ACCESS_INODE_OP_CHECK(loc,err,lbl) do { \
- /*Check if it is on .gfid*/ \
- if (__is_gfid_access_dir(loc->gfid)) { \
- err = ENOTSUP; \
- goto lbl; \
- } \
- } while (0)
-typedef struct {
- unsigned int uid;
- unsigned int gid;
- char gfid[UUID_CANONICAL_FORM_LEN + 1];
- unsigned int st_mode;
- char *bname;
-
- union {
- struct _symlink_in {
- char *linkpath;
- } __attribute__ ((__packed__)) symlink;
-
- struct _mknod_in {
- unsigned int mode;
- unsigned int rdev;
- unsigned int umask;
- } __attribute__ ((__packed__)) mknod;
-
- struct _mkdir_in {
- unsigned int mode;
- unsigned int umask;
- } __attribute__ ((__packed__)) mkdir;
- } __attribute__ ((__packed__)) args;
-} __attribute__((__packed__)) ga_newfile_args_t;
-
-typedef struct {
- char gfid[UUID_CANONICAL_FORM_LEN + 1];
- char *bname; /* a null terminated basename */
-} __attribute__((__packed__)) ga_heal_args_t;
-
-struct ga_private {
- /* root inode's stbuf */
- struct iatt root_stbuf;
- struct iatt gfiddir_stbuf;
- struct mem_pool *newfile_args_pool;
- struct mem_pool *heal_args_pool;
-};
-typedef struct ga_private ga_private_t;
-
-struct __ga_local {
- call_frame_t *orig_frame;
- unsigned int uid;
- unsigned int gid;
- loc_t loc;
-};
-typedef struct __ga_local ga_local_t;
-
-#endif /* __GFID_ACCESS_H__ */
diff --git a/xlators/features/glupy/Makefile.am b/xlators/features/glupy/Makefile.am
deleted file mode 100644
index 060429ecf0f..00000000000
--- a/xlators/features/glupy/Makefile.am
+++ /dev/null
@@ -1,3 +0,0 @@
-SUBDIRS = src examples
-
-CLEANFILES =
diff --git a/xlators/features/glupy/doc/README.md b/xlators/features/glupy/doc/README.md
deleted file mode 100644
index 2d7b30ef694..00000000000
--- a/xlators/features/glupy/doc/README.md
+++ /dev/null
@@ -1,44 +0,0 @@
-This is just the very start for a GlusterFS[1] meta-translator that will
-allow translator code to be written in Python. It's based on the standard
-Python embedding (not extending) techniques, plus a dash of the ctypes module.
-The interface is a pretty minimal adaptation of the dispatches and callbacks
-from the C API[2] to Python, as follows:
-
-* Dispatch functions and callbacks must be defined on an "xlator" class
- derived from gluster.Translator so that they'll be auto-registered with
- the C translator during initialization.
-
-* For each dispatch or callback function you want to intercept, you define a
- Python function using the xxx\_fop\_t or xxx\_cbk\_t decorator.
-
-* The arguments for each operation are different, so you'll need to refer to
- the C API. GlusterFS-specific types are used (though only loc\_t is fully
- defined so far) and type correctness is enforced by ctypes.
-
-* If you do intercept a dispatch function, it is your responsibility to call
- xxx\_wind (like STACK\_WIND in the C API but operation-specific) to pass
- the request to the next translator. If you do not intercept a function, it
- will default the same way as for C (pass through to the same operation with
- the same arguments on the first child translator).
-
-* If you intercept a callback function, it is your responsibility to call
- xxx\_unwind (like STACK\_UNWIND\_STRICT in the C API) to pass the request back
- to the caller.
-
-So far only the lookup and create operations are handled this way, to support
-the "negative lookup" example. Now that the basic infrastructure is in place,
-adding more functions should be very quick, though with that much boilerplate I
-might pause to write a code generator. I also plan to add structure
-definitions and interfaces for some of the utility functions in libglusterfs
-(especially those having to do with inode and fd context) in the fairly near
-future. Note that you can also use ctypes to get at anything not explicitly
-exposed to Python already.
-
-_If you're coming here because of the Linux Journal article, please note that
-the code has evolved since that was written. The version that matches the
-article is here:_
-
-https://github.com/jdarcy/glupy/tree/4bbae91ba459ea46ef32f2966562492e4ca9187a
-
-[1] http://www.gluster.org
-[2] http://hekafs.org/dist/xlator_api_2.html
diff --git a/xlators/features/glupy/doc/TESTING b/xlators/features/glupy/doc/TESTING
deleted file mode 100644
index e05f17f498f..00000000000
--- a/xlators/features/glupy/doc/TESTING
+++ /dev/null
@@ -1,9 +0,0 @@
-Loading a translator written in Python using the glupy meta translator
--------------------------------------------------------------------------------
-'test.vol' is a simple volfile with the debug-trace Python translator on top
-of a brick. The volfile can be mounted using the following command.
-
-$ glusterfs --debug -f test.vol /path/to/mntpt
-
-If then file operations are performed on the newly mounted file system, log
-output would be printed by the Python translator on the standard output.
diff --git a/xlators/features/glupy/doc/test.vol b/xlators/features/glupy/doc/test.vol
deleted file mode 100644
index 0751a488c1f..00000000000
--- a/xlators/features/glupy/doc/test.vol
+++ /dev/null
@@ -1,10 +0,0 @@
-volume vol-posix
- type storage/posix
- option directory /path/to/brick
-end-volume
-
-volume vol-glupy
- type features/glupy
- option module-name debug-trace
- subvolumes vol-posix
-end-volume
diff --git a/xlators/features/glupy/examples/Makefile.am b/xlators/features/glupy/examples/Makefile.am
deleted file mode 100644
index c26abeaafb6..00000000000
--- a/xlators/features/glupy/examples/Makefile.am
+++ /dev/null
@@ -1,5 +0,0 @@
-xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/features
-
-glupyexamplesdir = $(xlatordir)/glupy
-
-glupyexamples_PYTHON = negative.py helloworld.py debug-trace.py
diff --git a/xlators/features/glupy/examples/debug-trace.py b/xlators/features/glupy/examples/debug-trace.py
deleted file mode 100644
index 6eef1b58b8f..00000000000
--- a/xlators/features/glupy/examples/debug-trace.py
+++ /dev/null
@@ -1,775 +0,0 @@
-import sys
-import stat
-from uuid import UUID
-from time import strftime, localtime
-from gluster.glupy import *
-
-# This translator was written primarily to test the fop entry point definitions
-# and structure definitions in 'glupy.py'.
-
-# It is similar to the C language debug-trace translator, which logs the
-# arguments passed to the fops and their corresponding cbk functions.
-
-dl.get_id.restype = c_long
-dl.get_id.argtypes = [ POINTER(call_frame_t) ]
-
-dl.get_rootunique.restype = c_uint64
-dl.get_rootunique.argtypes = [ POINTER(call_frame_t) ]
-
-def uuid2str (gfid):
- return str(UUID(''.join(map("{0:02x}".format, gfid))))
-
-
-def st_mode_from_ia (prot, filetype):
- st_mode = 0
- type_bit = 0
- prot_bit = 0
-
- if filetype == IA_IFREG:
- type_bit = stat.S_IFREG
- elif filetype == IA_IFDIR:
- type_bit = stat.S_IFDIR
- elif filetype == IA_IFLNK:
- type_bit = stat.S_IFLNK
- elif filetype == IA_IFBLK:
- type_bit = stat.S_IFBLK
- elif filetype == IA_IFCHR:
- type_bit = stat.S_IFCHR
- elif filetype == IA_IFIFO:
- type_bit = stat.S_IFIFO
- elif filetype == IA_IFSOCK:
- type_bit = stat.S_IFSOCK
- elif filetype == IA_INVAL:
- pass
-
-
- if prot.suid:
- prot_bit |= stat.S_ISUID
- if prot.sgid:
- prot_bit |= stat.S_ISGID
- if prot.sticky:
- prot_bit |= stat.S_ISVTX
-
- if prot.owner.read:
- prot_bit |= stat.S_IRUSR
- if prot.owner.write:
- prot_bit |= stat.S_IWUSR
- if prot.owner.execn:
- prot_bit |= stat.S_IXUSR
-
- if prot.group.read:
- prot_bit |= stat.S_IRGRP
- if prot.group.write:
- prot_bit |= stat.S_IWGRP
- if prot.group.execn:
- prot_bit |= stat.S_IXGRP
-
- if prot.other.read:
- prot_bit |= stat.S_IROTH
- if prot.other.write:
- prot_bit |= stat.S_IWOTH
- if prot.other.execn:
- prot_bit |= stat.S_IXOTH
-
- st_mode = (type_bit | prot_bit)
-
- return st_mode
-
-
-def trace_stat2str (buf):
- gfid = uuid2str(buf.contents.ia_gfid)
- mode = st_mode_from_ia(buf.contents.ia_prot, buf.contents.ia_type)
- atime_buf = strftime("[%b %d %H:%M:%S]",
- localtime(buf.contents.ia_atime))
- mtime_buf = strftime("[%b %d %H:%M:%S]",
- localtime(buf.contents.ia_mtime))
- ctime_buf = strftime("[%b %d %H:%M:%S]",
- localtime(buf.contents.ia_ctime))
- return ("(gfid={0:s}, ino={1:d}, mode={2:o}, nlink={3:d}, uid ={4:d}, "+
- "gid ={5:d}, size={6:d}, blocks={7:d}, atime={8:s}, mtime={9:s}, "+
- "ctime={10:s})").format(gfid, buf.contents.ia_no, mode,
- buf.contents.ia_nlink,
- buf.contents.ia_uid,
- buf.contents.ia_gid,
- buf.contents.ia_size,
- buf.contents.ia_blocks,
- atime_buf, mtime_buf,
- ctime_buf)
-
-class xlator(Translator):
-
- def __init__(self, c_this):
- Translator.__init__(self, c_this)
- self.gfids = {}
-
- def lookup_fop(self, frame, this, loc, xdata):
- unique = dl.get_rootunique(frame)
- key = dl.get_id(frame)
- gfid = uuid2str(loc.contents.gfid)
- print("GLUPY TRACE LOOKUP FOP- {0:d}: gfid={1:s}; " +
- "path={2:s}").format(unique, gfid, loc.contents.path)
- self.gfids[key] = gfid
- dl.wind_lookup(frame, POINTER(xlator_t)(), loc, xdata)
- return 0
-
- def lookup_cbk(self, frame, cookie, this, op_ret, op_errno,
- inode, buf, xdata, postparent):
- unique =dl.get_rootunique(frame)
- key =dl.get_id(frame)
- if op_ret == 0:
- gfid = uuid2str(buf.contents.ia_gfid)
- statstr = trace_stat2str(buf)
- postparentstr = trace_stat2str(postparent)
- print("GLUPY TRACE LOOKUP CBK- {0:d}: gfid={1:s}; "+
- "op_ret={2:d}; *buf={3:s}; " +
- "*postparent={4:s}").format(unique, gfid,
- op_ret, statstr,
- postparentstr)
- else:
- gfid = self.gfids[key]
- print("GLUPY TRACE LOOKUP CBK - {0:d}: gfid={1:s};" +
- " op_ret={2:d}; op_errno={3:d}").format(unique,
- gfid,
- op_ret,
- op_errno)
- del self.gfids[key]
- dl.unwind_lookup(frame, cookie, this, op_ret, op_errno,
- inode, buf, xdata, postparent)
- return 0
-
- def create_fop(self, frame, this, loc, flags, mode, umask, fd,
- xdata):
- unique = dl.get_rootunique(frame)
- gfid = uuid2str(loc.contents.gfid)
- print("GLUPY TRACE CREATE FOP- {0:d}: gfid={1:s}; path={2:s}; " +
- "fd={3:s}; flags=0{4:o}; mode=0{5:o}; " +
- "umask=0{6:o}").format(unique, gfid, loc.contents.path,
- fd, flags, mode, umask)
- dl.wind_create(frame, POINTER(xlator_t)(), loc, flags,mode,
- umask, fd, xdata)
- return 0
-
- def create_cbk(self, frame, cookie, this, op_ret, op_errno, fd,
- inode, buf, preparent, postparent, xdata):
- unique = dl.get_rootunique(frame)
- if op_ret >= 0:
- gfid = uuid2str(inode.contents.gfid)
- statstr = trace_stat2str(buf)
- preparentstr = trace_stat2str(preparent)
- postparentstr = trace_stat2str(postparent)
- print("GLUPY TRACE CREATE CBK- {0:d}: gfid={1:s};" +
- " op_ret={2:d}; fd={3:s}; *stbuf={4:s}; " +
- "*preparent={5:s};" +
- " *postparent={6:s}").format(unique, gfid, op_ret,
- fd, statstr,
- preparentstr,
- postparentstr)
- else:
- print ("GLUPY TRACE CREATE CBK- {0:d}: op_ret={1:d}; " +
- "op_errno={2:d}").format(unique, op_ret, op_errno)
- dl.unwind_create(frame, cookie, this, op_ret, op_errno, fd,
- inode, buf, preparent, postparent, xdata)
- return 0
-
- def open_fop(self, frame, this, loc, flags, fd, xdata):
- unique = dl.get_rootunique(frame)
- key = dl.get_id(frame)
- gfid = uuid2str(loc.contents.inode.contents.gfid)
- print("GLUPY TRACE OPEN FOP- {0:d}: gfid={1:s}; path={2:s}; "+
- "flags={3:d}; fd={4:s}").format(unique, gfid,
- loc.contents.path, flags,
- fd)
- self.gfids[key] = gfid
- dl.wind_open(frame, POINTER(xlator_t)(), loc, flags, fd, xdata)
- return 0
-
- def open_cbk(self, frame, cookie, this, op_ret, op_errno, fd, xdata):
- unique = dl.get_rootunique(frame)
- key = dl.get_id(frame)
- gfid = self.gfids[key]
- print("GLUPY TRACE OPEN CBK- {0:d}: gfid={1:s}; op_ret={2:d}; "
- "op_errno={3:d}; *fd={4:s}").format(unique, gfid,
- op_ret, op_errno, fd)
- del self.gfids[key]
- dl.unwind_open(frame, cookie, this, op_ret, op_errno, fd,
- xdata)
- return 0
-
- def readv_fop(self, frame, this, fd, size, offset, flags, xdata):
- unique = dl.get_rootunique(frame)
- key = dl.get_id(frame)
- gfid = uuid2str(fd.contents.inode.contents.gfid)
- print("GLUPY TRACE READV FOP- {0:d}: gfid={1:s}; "+
- "fd={2:s}; size ={3:d}; offset={4:d}; " +
- "flags=0{5:x}").format(unique, gfid, fd, size, offset,
- flags)
- self.gfids[key] = gfid
- dl.wind_readv (frame, POINTER(xlator_t)(), fd, size, offset,
- flags, xdata)
- return 0
-
- def readv_cbk(self, frame, cookie, this, op_ret, op_errno, vector,
- count, buf, iobref, xdata):
- unique = dl.get_rootunique(frame)
- key = dl.get_id(frame)
- gfid = self.gfids[key]
- if op_ret >= 0:
- statstr = trace_stat2str(buf)
- print("GLUPY TRACE READV CBK- {0:d}: gfid={1:s}, "+
- "op_ret={2:d}; *buf={3:s};").format(unique, gfid,
- op_ret,
- statstr)
-
- else:
- print("GLUPY TRACE READV CBK- {0:d}: gfid={1:s}, "+
- "op_ret={2:d}; op_errno={3:d}").format(unique,
- gfid,
- op_ret,
- op_errno)
- del self.gfids[key]
- dl.unwind_readv (frame, cookie, this, op_ret, op_errno,
- vector, count, buf, iobref, xdata)
- return 0
-
- def writev_fop(self, frame, this, fd, vector, count, offset, flags,
- iobref, xdata):
- unique = dl.get_rootunique(frame)
- key = dl.get_id(frame)
- gfid = uuid2str(fd.contents.inode.contents.gfid)
- print("GLUPY TRACE WRITEV FOP- {0:d}: gfid={1:s}; " +
- "fd={2:s}; count={3:d}; offset={4:d}; " +
- "flags=0{5:x}").format(unique, gfid, fd, count, offset,
- flags)
- self.gfids[key] = gfid
- dl.wind_writev(frame, POINTER(xlator_t)(), fd, vector, count,
- offset, flags, iobref, xdata)
- return 0
-
- def writev_cbk(self, frame, cookie, this, op_ret, op_errno, prebuf,
- postbuf, xdata):
- unique = dl.get_rootunique(frame)
- key = dl.get_id(frame)
- if op_ret >= 0:
- preopstr = trace_stat2str(prebuf)
- postopstr = trace_stat2str(postbuf)
- print("GLUPY TRACE WRITEV CBK- {0:d}: op_ret={1:d}; " +
- "*prebuf={2:s}; " +
- "*postbuf={3:s}").format(unique, op_ret, preopstr,
- postopstr)
- else:
- gfid = self.gfids[key]
- print("GLUPY TRACE WRITEV CBK- {0:d}: gfid={1:s}; "+
- "op_ret={2:d}; op_errno={3:d}").format(unique,
- gfid,
- op_ret,
- op_errno)
- del self.gfids[key]
- dl.unwind_writev (frame, cookie, this, op_ret, op_errno,
- prebuf, postbuf, xdata)
- return 0
-
- def opendir_fop(self, frame, this, loc, fd, xdata):
- unique = dl.get_rootunique(frame)
- key = dl.get_id(frame)
- gfid = uuid2str(loc.contents.inode.contents.gfid)
- print("GLUPY TRACE OPENDIR FOP- {0:d}: gfid={1:s}; path={2:s}; "+
- "fd={3:s}").format(unique, gfid, loc.contents.path, fd)
- self.gfids[key] = gfid
- dl.wind_opendir(frame, POINTER(xlator_t)(), loc, fd, xdata)
- return 0
-
- def opendir_cbk(self, frame, cookie, this, op_ret, op_errno, fd,
- xdata):
- unique = dl.get_rootunique(frame)
- key = dl.get_id(frame)
- gfid = self.gfids[key]
- print("GLUPY TRACE OPENDIR CBK- {0:d}: gfid={1:s}; op_ret={2:d};"+
- " op_errno={3:d}; fd={4:s}").format(unique, gfid, op_ret,
- op_errno, fd)
- del self.gfids[key]
- dl.unwind_opendir(frame, cookie, this, op_ret, op_errno,
- fd, xdata)
- return 0
-
- def readdir_fop(self, frame, this, fd, size, offset, xdata):
- unique = dl.get_rootunique(frame)
- key = dl.get_id(frame)
- gfid = uuid2str(fd.contents.inode.contents.gfid)
- print("GLUPY TRACE READDIR FOP- {0:d}: gfid={1:s}; fd={2:s}; " +
- "size={3:d}; offset={4:d}").format(unique, gfid, fd, size,
- offset)
- self.gfids[key] = gfid
- dl.wind_readdir(frame, POINTER(xlator_t)(), fd, size, offset,
- xdata)
- return 0
-
- def readdir_cbk(self, frame, cookie, this, op_ret, op_errno, buf,
- xdata):
- unique = dl.get_rootunique(frame)
- key = dl.get_id(frame)
- gfid = self.gfids[key]
- print("GLUPY TRACE READDIR CBK- {0:d}: gfid={1:s}; op_ret={2:d};"+
- " op_errno={3:d}").format(unique, gfid, op_ret, op_errno)
- del self.gfids[key]
- dl.unwind_readdir(frame, cookie, this, op_ret, op_errno, buf,
- xdata)
- return 0
-
- def readdirp_fop(self, frame, this, fd, size, offset, dictionary):
- unique = dl.get_rootunique(frame)
- key = dl.get_id(frame)
- gfid = uuid2str(fd.contents.inode.contents.gfid)
- print("GLUPY TRACE READDIRP FOP- {0:d}: gfid={1:s}; fd={2:s}; "+
- " size={3:d}; offset={4:d}").format(unique, gfid, fd, size,
- offset)
- self.gfids[key] = gfid
- dl.wind_readdirp(frame, POINTER(xlator_t)(), fd, size, offset,
- dictionary)
- return 0
-
- def readdirp_cbk(self, frame, cookie, this, op_ret, op_errno, buf,
- xdata):
- unique = dl.get_rootunique(frame)
- key = dl.get_id(frame)
- gfid = self.gfids[key]
- print("GLUPY TRACE READDIRP CBK- {0:d}: gfid={1:s}; "+
- "op_ret={2:d}; op_errno={3:d}").format(unique, gfid,
- op_ret, op_errno)
- del self.gfids[key]
- dl.unwind_readdirp(frame, cookie, this, op_ret, op_errno, buf,
- xdata)
- return 0
-
- def mkdir_fop(self, frame, this, loc, mode, umask, xdata):
- unique = dl.get_rootunique(frame)
- gfid = uuid2str(loc.contents.inode.contents.gfid)
- print("GLUPY TRACE MKDIR FOP- {0:d}: gfid={1:s}; path={2:s}; " +
- "mode={3:d}; umask=0{4:o}").format(unique, gfid,
- loc.contents.path, mode,
- umask)
- dl.wind_mkdir(frame, POINTER(xlator_t)(), loc, mode, umask,
- xdata)
- return 0
-
- def mkdir_cbk(self, frame, cookie, this, op_ret, op_errno, inode, buf,
- preparent, postparent, xdata):
- unique = dl.get_rootunique(frame)
- if op_ret == 0:
- gfid = uuid2str(inode.contents.gfid)
- statstr = trace_stat2str(buf)
- preparentstr = trace_stat2str(preparent)
- postparentstr = trace_stat2str(postparent)
- print("GLUPY TRACE MKDIR CBK- {0:d}: gfid={1:s}; "+
- "op_ret={2:d}; *stbuf={3:s}; *prebuf={4:s}; "+
- "*postbuf={5:s} ").format(unique, gfid, op_ret,
- statstr,
- preparentstr,
- postparentstr)
- else:
- print("GLUPY TRACE MKDIR CBK- {0:d}: op_ret={1:d}; "+
- "op_errno={2:d}").format(unique, op_ret, op_errno)
- dl.unwind_mkdir(frame, cookie, this, op_ret, op_errno, inode,
- buf, preparent, postparent, xdata)
- return 0
-
- def rmdir_fop(self, frame, this, loc, flags, xdata):
- unique = dl.get_rootunique(frame)
- key = dl.get_id(frame)
- gfid = uuid2str(loc.contents.inode.contents.gfid)
- print("GLUPY TRACE RMDIR FOP- {0:d}: gfid={1:s}; path={2:s}; "+
- "flags={3:d}").format(unique, gfid, loc.contents.path,
- flags)
- self.gfids[key] = gfid
- dl.wind_rmdir(frame, POINTER(xlator_t)(), loc, flags, xdata)
- return 0
-
- def rmdir_cbk(self, frame, cookie, this, op_ret, op_errno, preparent,
- postparent, xdata):
- unique = dl.get_rootunique(frame)
- key = dl.get_id(frame)
- gfid = self.gfids[key]
- if op_ret == 0:
- preparentstr = trace_stat2str(preparent)
- postparentstr = trace_stat2str(postparent)
- print("GLUPY TRACE RMDIR CBK- {0:d}: gfid={1:s}; "+
- "op_ret={2:d}; *prebuf={3:s}; "+
- "*postbuf={4:s}").format(unique, gfid, op_ret,
- preparentstr,
- postparentstr)
- else:
- print("GLUPY TRACE RMDIR CBK- {0:d}: gfid={1:s}; "+
- "op_ret={2:d}; op_errno={3:d}").format(unique,
- gfid,
- op_ret,
- op_errno)
- del self.gfids[key]
- dl.unwind_rmdir(frame, cookie, this, op_ret, op_errno,
- preparent, postparent, xdata)
- return 0
-
- def stat_fop(self, frame, this, loc, xdata):
- unique = dl.get_rootunique(frame)
- key = dl.get_id(frame)
- gfid = uuid2str(loc.contents.inode.contents.gfid)
- print("GLUPY TRACE STAT FOP- {0:d}: gfid={1:s}; " +
- " path={2:s}").format(unique, gfid, loc.contents.path)
- self.gfids[key] = gfid
- dl.wind_stat(frame, POINTER(xlator_t)(), loc, xdata)
- return 0
-
- def stat_cbk(self, frame, cookie, this, op_ret, op_errno, buf,
- xdata):
- unique = dl.get_rootunique(frame)
- key = dl.get_id(frame)
- gfid = self.gfids[key]
- if op_ret == 0:
- statstr = trace_stat2str(buf)
- print("GLUPY TRACE STAT CBK- {0:d}: gfid={1:s}; "+
- "op_ret={2:d}; *buf={3:s};").format(unique,
- gfid,
- op_ret,
- statstr)
- else:
- print("GLUPY TRACE STAT CBK- {0:d}: gfid={1:s}; "+
- "op_ret={2:d}; op_errno={3:d}").format(unique,
- gfid,
- op_ret,
- op_errno)
- del self.gfids[key]
- dl.unwind_stat(frame, cookie, this, op_ret, op_errno,
- buf, xdata)
- return 0
-
- def fstat_fop(self, frame, this, fd, xdata):
- unique = dl.get_rootunique(frame)
- key = dl.get_id(frame)
- gfid = uuid2str(fd.contents.inode.contents.gfid)
- print("GLUPY TRACE FSTAT FOP- {0:d}: gfid={1:s}; " +
- "fd={2:s}").format(unique, gfid, fd)
- self.gfids[key] = gfid
- dl.wind_fstat(frame, POINTER(xlator_t)(), fd, xdata)
- return 0
-
- def fstat_cbk(self, frame, cookie, this, op_ret, op_errno, buf,
- xdata):
- unique = dl.get_rootunique(frame)
- key = dl.get_id(frame)
- gfid = self.gfids[key]
- if op_ret == 0:
- statstr = trace_stat2str(buf)
- print("GLUPY TRACE FSTAT CBK- {0:d}: gfid={1:s} "+
- " op_ret={2:d}; *buf={3:s}").format(unique,
- gfid,
- op_ret,
- statstr)
- else:
- print("GLUPY TRACE FSTAT CBK- {0:d}: gfid={1:s} "+
- "op_ret={2:d}; op_errno={3:d}").format(unique.
- gfid,
- op_ret,
- op_errno)
- del self.gfids[key]
- dl.unwind_fstat(frame, cookie, this, op_ret, op_errno,
- buf, xdata)
- return 0
-
- def statfs_fop(self, frame, this, loc, xdata):
- unique = dl.get_rootunique(frame)
- if loc.contents.inode:
- gfid = uuid2str(loc.contents.inode.contents.gfid)
- else:
- gfid = "0"
- print("GLUPY TRACE STATFS FOP- {0:d}: gfid={1:s}; "+
- "path={2:s}").format(unique, gfid, loc.contents.path)
- dl.wind_statfs(frame, POINTER(xlator_t)(), loc, xdata)
- return 0
-
- def statfs_cbk(self, frame, cookie, this, op_ret, op_errno, buf,
- xdata):
- unique = dl.get_rootunique(frame)
- if op_ret == 0:
- #TBD: print buf (pointer to an iovec type object)
- print("GLUPY TRACE STATFS CBK {0:d}: "+
- "op_ret={1:d}").format(unique, op_ret)
- else:
- print("GLUPY TRACE STATFS CBK- {0:d}"+
- "op_ret={1:d}; op_errno={2:d}").format(unique,
- op_ret,
- op_errno)
- dl.unwind_statfs(frame, cookie, this, op_ret, op_errno,
- buf, xdata)
- return 0
-
- def getxattr_fop(self, frame, this, loc, name, xdata):
- unique = dl.get_rootunique(frame)
- key = dl.get_id(frame)
- gfid = uuid2str(loc.contents.inode.contents.gfid)
- print("GLUPY TRACE GETXATTR FOP- {0:d}: gfid={1:s}; path={2:s};"+
- " name={3:s}").format(unique, gfid, loc.contents.path,
- name)
- self.gfids[key]=gfid
- dl.wind_getxattr(frame, POINTER(xlator_t)(), loc, name, xdata)
- return 0
-
- def getxattr_cbk(self, frame, cookie, this, op_ret, op_errno,
- dictionary, xdata):
- unique = dl.get_rootunique(frame)
- key = dl.get_id(frame)
- gfid = self.gfids[key]
- print("GLUPY TRACE GETXATTR CBK- {0:d}: gfid={1:s}; "+
- "op_ret={2:d}; op_errno={3:d}; "+
- " dictionary={4:s}").format(unique, gfid, op_ret, op_errno,
- dictionary)
- del self.gfids[key]
- dl.unwind_getxattr(frame, cookie, this, op_ret, op_errno,
- dictionary, xdata)
- return 0
-
- def fgetxattr_fop(self, frame, this, fd, name, xdata):
- unique = dl.get_rootunique(frame)
- key = dl.get_id(frame)
- gfid = uuid2str(fd.contents.inode.contents.gfid)
- print("GLUPY TRACE FGETXATTR FOP- {0:d}: gfid={1:s}; fd={2:s}; "+
- "name={3:s}").format(unique, gfid, fd, name)
- self.gfids[key] = gfid
- dl.wind_fgetxattr(frame, POINTER(xlator_t)(), fd, name, xdata)
- return 0
-
- def fgetxattr_cbk(self, frame, cookie, this, op_ret, op_errno,
- dictionary, xdata):
- unique = dl.get_rootunique(frame)
- key = dl.get_id(frame)
- gfid = self.gfids[key]
- print("GLUPY TRACE FGETXATTR CBK- {0:d}: gfid={1:s}; "+
- "op_ret={2:d}; op_errno={3:d};"+
- " dictionary={4:s}").format(unique, gfid, op_ret,
- op_errno, dictionary)
- del self.gfids[key]
- dl.unwind_fgetxattr(frame, cookie, this, op_ret, op_errno,
- dictionary, xdata)
- return 0
-
- def setxattr_fop(self, frame, this, loc, dictionary, flags, xdata):
- unique = dl.get_rootunique(frame)
- key = dl.get_id(frame)
- gfid = uuid2str(loc.contents.inode.contents.gfid)
- print("GLUPY TRACE SETXATTR FOP- {0:d}: gfid={1:s}; path={2:s};"+
- " flags={3:d}").format(unique, gfid, loc.contents.path,
- flags)
- self.gfids[key] = gfid
- dl.wind_setxattr(frame, POINTER(xlator_t)(), loc, dictionary,
- flags, xdata)
- return 0
-
- def setxattr_cbk(self, frame, cookie, this, op_ret, op_errno, xdata):
- unique = dl.get_rootunique(frame)
- key = dl.get_id(frame)
- gfid = self.gfids[key]
- print("GLUPY TRACE SETXATTR CBK- {0:d}: gfid={1:s}; "+
- "op_ret={2:d}; op_errno={3:d}").format(unique, gfid,
- op_ret, op_errno)
- del self.gfids[key]
- dl.unwind_setxattr(frame, cookie, this, op_ret, op_errno,
- xdata)
- return 0
-
- def fsetxattr_fop(self, frame, this, fd, dictionary, flags, xdata):
- unique = dl.get_rootunique(frame)
- key = dl.get_id(frame)
- gfid = uuid2str(fd.contents.inode.contents.gfid)
- print("GLUPY TRACE FSETXATTR FOP- {0:d}: gfid={1:s}; fd={2:p}; "+
- "flags={3:d}").format(unique, gfid, fd, flags)
- self.gfids[key] = gfid
- dl.wind_fsetxattr(frame, POINTER(xlator_t)(), fd, dictionary,
- flags, xdata)
- return 0
-
- def fsetxattr_cbk(self, frame, cookie, this, op_ret, op_errno, xdata):
- unique = dl.get_rootunique(frame)
- key = dl.get_id(frame)
- gfid = self.gfids[key]
- print("GLUPY TRACE FSETXATTR CBK- {0:d}: gfid={1:s}; "+
- "op_ret={2:d}; op_errno={3:d}").format(unique, gfid,
- op_ret, op_errno)
- del self.gfids[key]
- dl.unwind_fsetxattr(frame, cookie, this, op_ret, op_errno,
- xdata)
- return 0
-
- def removexattr_fop(self, frame, this, loc, name, xdata):
- unique = dl.get_rootunique(frame)
- key = dl.get_id(frame)
- gfid = uuid2str(loc.contents.inode.contents.gfid)
- print("GLUPY TRACE REMOVEXATTR FOP- {0:d}: gfid={1:s}; "+
- "path={2:s}; name={3:s}").format(unique, gfid,
- loc.contents.path,
- name)
- self.gfids[key] = gfid
- dl.wind_removexattr(frame, POINTER(xlator_t)(), loc, name,
- xdata)
- return 0
-
- def removexattr_cbk(self, frame, cookie, this, op_ret, op_errno,
- xdata):
- unique = dl.get_rootunique(frame)
- key = dl.get_id(frame)
- gfid = self.gfids[key]
- print("GLUPY TRACE REMOVEXATTR CBK- {0:d}: gfid={1:s} "+
- " op_ret={2:d}; op_errno={3:d}").format(unique, gfid,
- op_ret, op_errno)
- del self.gfids[key]
- dl.unwind_removexattr(frame, cookie, this, op_ret, op_errno,
- xdata)
- return 0
-
- def link_fop(self, frame, this, oldloc, newloc, xdata):
- unique = dl.get_rootunique(frame)
- key = dl.get_id(frame)
- if (newloc.contents.inode):
- newgfid = uuid2str(newloc.contents.inode.contents.gfid)
- else:
- newgfid = "0"
- oldgfid = uuid2str(oldloc.contents.inode.contents.gfid)
- print("GLUPY TRACE LINK FOP-{0:d}: oldgfid={1:s}; oldpath={2:s};"+
- "newgfid={3:s};"+
- "newpath={4:s}").format(unique, oldgfid,
- oldloc.contents.path,
- newgfid,
- newloc.contents.path)
- self.gfids[key] = oldgfid
- dl.wind_link(frame, POINTER(xlator_t)(), oldloc, newloc,
- xdata)
- return 0
-
- def link_cbk(self, frame, cookie, this, op_ret, op_errno, inode, buf,
- preparent, postparent, xdata):
- unique = dl.get_rootunique(frame)
- key = dl.get_id(frame)
- gfid = self.gfids[key]
- if op_ret == 0:
- statstr = trace_stat2str(buf)
- preparentstr = trace_stat2str(preparent)
- postparentstr = trace_stat2str(postparent)
- print("GLUPY TRACE LINK CBK- {0:d}: op_ret={1:d} "+
- "*stbuf={2:s}; *prebuf={3:s}; "+
- "*postbuf={4:s} ").format(unique, op_ret, statstr,
- preparentstr,
- postparentstr)
- else:
- print("GLUPY TRACE LINK CBK- {0:d}: gfid={1:s}; "+
- "op_ret={2:d}; "+
- "op_errno={3:d}").format(unique, gfid,
- op_ret, op_errno)
- del self.gfids[key]
- dl.unwind_link(frame, cookie, this, op_ret, op_errno, inode,
- buf, preparent, postparent, xdata)
- return 0
-
- def unlink_fop(self, frame, this, loc, xflag, xdata):
- unique = dl.get_rootunique(frame)
- key = dl.get_id(frame)
- gfid = uuid2str(loc.contents.inode.contents.gfid)
- print("GLUPY TRACE UNLINK FOP- {0:d}; gfid={1:s}; path={2:s}; "+
- "flag={3:d}").format(unique, gfid, loc.contents.path,
- xflag)
- self.gfids[key] = gfid
- dl.wind_unlink(frame, POINTER(xlator_t)(), loc, xflag,
- xdata)
- return 0
-
- def unlink_cbk(self, frame, cookie, this, op_ret, op_errno,
- preparent, postparent, xdata):
- unique = dl.get_rootunique(frame)
- key = dl.get_id(frame)
- gfid = self.gfids[key]
- if op_ret == 0:
- preparentstr = trace_stat2str(preparent)
- postparentstr = trace_stat2str(postparent)
- print("GLUPY TRACE UNLINK CBK- {0:d}: gfid ={1:s}; "+
- "op_ret={2:d}; *prebuf={3:s}; "+
- "*postbuf={4:s} ").format(unique, gfid, op_ret,
- preparentstr,
- postparentstr)
- else:
- print("GLUPY TRACE UNLINK CBK: {0:d}: gfid ={1:s}; "+
- "op_ret={2:d}; "+
- "op_errno={3:d}").format(unique, gfid, op_ret,
- op_errno)
- del self.gfids[key]
- dl.unwind_unlink(frame, cookie, this, op_ret, op_errno,
- preparent, postparent, xdata)
- return 0
-
- def readlink_fop(self, frame, this, loc, size, xdata):
- unique = dl.get_rootunique(frame)
- key = dl.get_id(frame)
- gfid = uuid2str(loc.contents.inode.contents.gfid)
- print("GLUPY TRACE READLINK FOP- {0:d}: gfid={1:s}; path={2:s};"+
- " size={3:d}").format(unique, gfid, loc.contents.path,
- size)
- self.gfids[key] = gfid
- dl.wind_readlink(frame, POINTER(xlator_t)(), loc, size,
- xdata)
- return 0
-
- def readlink_cbk(self, frame, cookie, this, op_ret, op_errno,
- buf, stbuf, xdata):
- unique = dl.get_rootunique(frame)
- key = dl.get_id(frame)
- gfid = self.gfids[key]
- if op_ret == 0:
- statstr = trace_stat2str(stbuf)
- print("GLUPY TRACE READLINK CBK- {0:d}: gfid={1:s} "+
- " op_ret={2:d}; op_errno={3:d}; *prebuf={4:s}; "+
- "*postbuf={5:s} ").format(unique, gfid,
- op_ret, op_errno,
- buf, statstr)
- else:
- print("GLUPY TRACE READLINK CBK- {0:d}: gfid={1:s} "+
- " op_ret={2:d}; op_errno={3:d}").format(unique,
- gfid,
- op_ret,
- op_errno)
- del self.gfids[key]
- dl.unwind_readlink(frame, cookie, this, op_ret, op_errno, buf,
- stbuf, xdata)
- return 0
-
- def symlink_fop(self, frame, this, linkpath, loc, umask, xdata):
- unique = dl.get_rootunique(frame)
- key = dl.get_id(frame)
- gfid = uuid2str(loc.contents.inode.contents.gfid)
- print("GLUPY TRACE SYMLINK FOP- {0:d}: gfid={1:s}; "+
- "linkpath={2:s}; path={3:s};"+
- "umask=0{4:o}").format(unique, gfid, linkpath,
- loc.contents.path, umask)
- self.gfids[key] = gfid
- dl.wind_symlink(frame, POINTER(xlator_t)(), linkpath, loc,
- umask, xdata)
- return 0
-
- def symlink_cbk(self, frame, cookie, this, op_ret, op_errno,
- inode, buf, preparent, postparent, xdata):
- unique = dl.get_rootunique(frame)
- key = dl.get_id(frame)
- gfid = self.gfids[key]
- if op_ret == 0:
- statstr = trace_stat2str(buf)
- preparentstr = trace_stat2str(preparent)
- postparentstr = trace_stat2str(postparent)
- print("GLUPY TRACE SYMLINK CBK- {0:d}: gfid={1:s}; "+
- "op_ret={2:d}; *stbuf={3:s}; *preparent={4:s}; "+
- "*postparent={5:s}").format(unique, gfid,
- op_ret, statstr,
- preparentstr,
- postparentstr)
- else:
- print("GLUPY TRACE SYMLINK CBK- {0:d}: gfid={1:s}; "+
- "op_ret={2:d}; op_errno={3:d}").format(unique,
- gfid,
- op_ret,
- op_errno)
- del self.gfids[key]
- dl.unwind_symlink(frame, cookie, this, op_ret, op_errno,
- inode, buf, preparent, postparent, xdata)
- return 0
diff --git a/xlators/features/glupy/examples/helloworld.py b/xlators/features/glupy/examples/helloworld.py
deleted file mode 100644
index b565a4e5bc3..00000000000
--- a/xlators/features/glupy/examples/helloworld.py
+++ /dev/null
@@ -1,19 +0,0 @@
-import sys
-from gluster.glupy import *
-
-class xlator (Translator):
-
- def __init__(self, c_this):
- Translator.__init__(self, c_this)
-
- def lookup_fop(self, frame, this, loc, xdata):
- print "Python xlator: Hello!"
- dl.wind_lookup(frame, POINTER(xlator_t)(), loc, xdata)
- return 0
-
- def lookup_cbk(self, frame, cookie, this, op_ret, op_errno, inode, buf,
- xdata, postparent):
- print "Python xlator: Hello again!"
- dl.unwind_lookup(frame, cookie, this, op_ret, op_errno, inode, buf,
- xdata, postparent)
- return 0
diff --git a/xlators/features/glupy/examples/negative.py b/xlators/features/glupy/examples/negative.py
deleted file mode 100644
index e7a4fc07ced..00000000000
--- a/xlators/features/glupy/examples/negative.py
+++ /dev/null
@@ -1,91 +0,0 @@
-import sys
-from uuid import UUID
-from gluster.glupy import *
-
-# Negative-lookup-caching example. If a file wasn't there the last time we
-# looked, it's probably still not there. This translator keeps track of
-# those failed lookups for us, and returns ENOENT without needing to pass the
-# call any further for repeated requests.
-
-# If we were doing this for real, we'd need separate caches for each xlator
-# instance. The easiest way to do this would be to have xlator.__init__
-# "register" each instance in a module-global dict, with the key as the C
-# translator address and the value as the xlator object itself. For testing
-# and teaching, it's sufficient just to have one cache. The keys are parent
-# GFIDs, and the entries are lists of names within that parent that we know
-# don't exist.
-cache = {}
-
-# TBD: we need a better way of handling per-request data (frame->local in C).
-dl.get_id.restype = c_long
-dl.get_id.argtypes = [ POINTER(call_frame_t) ]
-
-def uuid2str (gfid):
- return str(UUID(''.join(map("{0:02x}".format, gfid))))
-
-class xlator (Translator):
-
- def __init__ (self, c_this):
- self.requests = {}
- Translator.__init__(self,c_this)
-
- def lookup_fop (self, frame, this, loc, xdata):
- pargfid = uuid2str(loc.contents.pargfid)
- print "lookup FOP: %s:%s" % (pargfid, loc.contents.name)
- # Check the cache.
- if cache.has_key(pargfid):
- if loc.contents.name in cache[pargfid]:
- print "short-circuiting for %s:%s" % (pargfid,
- loc.contents.name)
- dl.unwind_lookup(frame,0,this,-1,2,None,None,None,None)
- return 0
- key = dl.get_id(frame)
- self.requests[key] = (pargfid, loc.contents.name[:])
- # TBD: get real child xl from init, pass it here
- dl.wind_lookup(frame,POINTER(xlator_t)(),loc,xdata)
- return 0
-
- def lookup_cbk (self, frame, cookie, this, op_ret, op_errno, inode, buf,
- xdata, postparent):
- print "lookup CBK: %d (%d)" % (op_ret, op_errno)
- key = dl.get_id(frame)
- pargfid, name = self.requests[key]
- # Update the cache.
- if op_ret == 0:
- print "found %s, removing from cache" % name
- if cache.has_key(pargfid):
- cache[pargfid].discard(name)
- elif op_errno == 2: # ENOENT
- print "failed to find %s, adding to cache" % name
- if cache.has_key(pargfid):
- cache[pargfid].add(name)
- else:
- cache[pargfid] = set([name])
- del self.requests[key]
- dl.unwind_lookup(frame,cookie,this,op_ret,op_errno,
- inode,buf,xdata,postparent)
- return 0
-
- def create_fop (self, frame, this, loc, flags, mode, umask, fd, xdata):
- pargfid = uuid2str(loc.contents.pargfid)
- print "create FOP: %s:%s" % (pargfid, loc.contents.name)
- key = dl.get_id(frame)
- self.requests[key] = (pargfid, loc.contents.name[:])
- # TBD: get real child xl from init, pass it here
- dl.wind_create(frame,POINTER(xlator_t)(),loc,flags,mode,umask,fd,xdata)
- return 0
-
- def create_cbk (self, frame, cookie, this, op_ret, op_errno, fd, inode,
- buf, preparent, postparent, xdata):
- print "create CBK: %d (%d)" % (op_ret, op_errno)
- key = dl.get_id(frame)
- pargfid, name = self.requests[key]
- # Update the cache.
- if op_ret == 0:
- print "created %s, removing from cache" % name
- if cache.has_key(pargfid):
- cache[pargfid].discard(name)
- del self.requests[key]
- dl.unwind_create(frame,cookie,this,op_ret,op_errno,fd,inode,buf,
- preparent,postparent,xdata)
- return 0
diff --git a/xlators/features/glupy/src/Makefile.am b/xlators/features/glupy/src/Makefile.am
deleted file mode 100644
index 2ac0d99cd5f..00000000000
--- a/xlators/features/glupy/src/Makefile.am
+++ /dev/null
@@ -1,24 +0,0 @@
-xlator_LTLIBRARIES = glupy.la
-
-# Ensure GLUSTER_PYTHON_PATH is passed to glupy.so
-xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/features
-glupydir = $(xlatordir)/glupy
-AM_CPPFLAGS = $(PYTHONDEV_CPPFLAGS) $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src -isystem $(BUILD_PYTHON_INC)
-AM_CFLAGS = $(PYTHONDEV_CFLAGS) -Wall -fno-strict-aliasing -DGLUSTER_PYTHON_PATH=\"$(glupydir)\" -DPATH_GLUSTERFS_GLUPY_MODULE=\"${xlatordir}/glupy${shrext_cmds}\" $(GF_CFLAGS)
-
-# Flags to build glupy.so with
-glupy_la_LDFLAGS = $(PYTHONDEV_LDFLAGS) -module -avoid-version -nostartfiles
-glupy_la_SOURCES = glupy.c
-glupy_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la \
- -lpthread -l$(BUILD_PYTHON_LIB)
-
-noinst_HEADERS = glupy.h
-
-# Install __init__.py into the Python site-packages area
-pyglupydir = @BUILD_PYTHON_SITE_PACKAGES@/gluster
-pyglupy_PYTHON = __init__.py
-
-# Install glupy/__init_-.py into the Python site-packages area
-SUBDIRS = glupy
-
-CLEANFILES =
diff --git a/xlators/features/glupy/src/__init__.py.in b/xlators/features/glupy/src/__init__.py.in
deleted file mode 100644
index e69de29bb2d..00000000000
--- a/xlators/features/glupy/src/__init__.py.in
+++ /dev/null
diff --git a/xlators/features/glupy/src/glupy.c b/xlators/features/glupy/src/glupy.c
deleted file mode 100644
index 7bb88c0a0ae..00000000000
--- a/xlators/features/glupy/src/glupy.c
+++ /dev/null
@@ -1,2501 +0,0 @@
-/*
- Copyright (c) 2006-2014 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 <ctype.h>
-#include <sys/uio.h>
-#include <Python.h>
-
-#ifndef _CONFIG_H
-#define _CONFIG_H
-#include "config.h"
-#endif
-
-#include "glusterfs.h"
-#include "xlator.h"
-#include "logging.h"
-#include "defaults.h"
-
-#include "glupy.h"
-
-/* UTILITY FUNCTIONS FOR FOP-SPECIFIC CODE */
-
-pthread_key_t gil_init_key;
-
-PyGILState_STATE
-glupy_enter (void)
-{
- if (!pthread_getspecific(gil_init_key)) {
- PyEval_ReleaseLock();
- (void)pthread_setspecific(gil_init_key,(void *)1);
- }
-
- return PyGILState_Ensure();
-}
-
-void
-glupy_leave (PyGILState_STATE gstate)
-{
- PyGILState_Release(gstate);
-}
-
-/* FOP: LOOKUP */
-
-int32_t
-glupy_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)
-{
- glupy_private_t *priv = this->private;
- PyGILState_STATE gstate;
- int32_t ret;
-
- if (!priv->cbks[GLUPY_LOOKUP]) {
- goto unwind;
- }
-
- gstate = glupy_enter();
- ret = ((fop_lookup_cbk_t)(priv->cbks[GLUPY_LOOKUP]))(
- frame, cookie, this, op_ret, op_errno,
- inode, buf, xdata, postparent);
- glupy_leave(gstate);
-
- return ret;
-
-unwind:
- frame->local = NULL;
- STACK_UNWIND_STRICT (lookup, frame, op_ret, op_errno, inode, buf,
- xdata, postparent);
- return 0;
-}
-
-int32_t
-glupy_lookup (call_frame_t *frame, xlator_t *this, loc_t *loc,
- dict_t *xdata)
-{
- glupy_private_t *priv = this->private;
- PyGILState_STATE gstate;
- int32_t ret;
- static long next_id = 0;
-
- if (!priv->fops[GLUPY_LOOKUP]) {
- goto wind;
- }
-
- gstate = glupy_enter();
- frame->local = (void *)++next_id;
- ret = ((fop_lookup_t)(priv->fops[GLUPY_LOOKUP]))(
- frame, this, loc, xdata);
- glupy_leave(gstate);
-
- return ret;
-
-wind:
- STACK_WIND (frame, glupy_lookup_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->lookup, loc, xdata);
- return 0;
-}
-
-void
-wind_lookup (call_frame_t *frame, xlator_t *xl, loc_t *loc, dict_t *xdata)
-{
- xlator_t *this = THIS;
-
- if (!xl || (xl == this)) {
- xl = FIRST_CHILD(this);
- }
-
- STACK_WIND(frame,glupy_lookup_cbk,xl,xl->fops->lookup,loc,xdata);
-}
-
-void
-unwind_lookup (call_frame_t *frame, long cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, inode_t *inode,
- struct iatt *buf, dict_t *xdata, struct iatt *postparent)
-{
- frame->local = NULL;
- STACK_UNWIND_STRICT(lookup,frame,op_ret,op_errno,
- inode,buf,xdata,postparent);
-}
-
-void
-set_lookup_fop (long py_this, fop_lookup_t fop)
-{
- glupy_private_t *priv = ((xlator_t *)py_this)->private;
-
- priv->fops[GLUPY_LOOKUP] = (long)fop;
-}
-
-void
-set_lookup_cbk (long py_this, fop_lookup_cbk_t cbk)
-{
- glupy_private_t *priv = ((xlator_t *)py_this)->private;
-
- priv->cbks[GLUPY_LOOKUP] = (long)cbk;
-}
-
-/* FOP: CREATE */
-
-int32_t
-glupy_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)
-{
- glupy_private_t *priv = this->private;
- PyGILState_STATE gstate;
- int32_t ret;
-
- if (!priv->cbks[GLUPY_CREATE]) {
- goto unwind;
- }
-
- gstate = glupy_enter();
- ret = ((fop_create_cbk_t)(priv->cbks[GLUPY_CREATE]))(
- frame, cookie, this, op_ret, op_errno,
- fd, inode, buf, preparent, postparent, xdata);
- glupy_leave(gstate);
-
- return ret;
-
-unwind:
- frame->local = NULL;
- STACK_UNWIND_STRICT (create, frame, op_ret, op_errno, fd, inode, buf,
- preparent, postparent, xdata);
- return 0;
-}
-
-int32_t
-glupy_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)
-{
- glupy_private_t *priv = this->private;
- PyGILState_STATE gstate;
- int32_t ret;
- static long next_id = 0;
-
- if (!priv->fops[GLUPY_CREATE]) {
- goto wind;
- }
-
- gstate = glupy_enter();
- frame->local = (void *)++next_id;
- ret = ((fop_create_t)(priv->fops[GLUPY_CREATE]))(
- frame, this, loc, flags, mode, umask, fd, xdata);
- glupy_leave(gstate);
-
- return ret;
-
-wind:
- STACK_WIND (frame, glupy_create_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->create, loc, flags, mode, umask,
- fd, xdata);
- return 0;
-}
-
-void
-wind_create (call_frame_t *frame, xlator_t *xl, loc_t *loc, int32_t flags,
- mode_t mode, mode_t umask, fd_t *fd, dict_t *xdata)
-{
- xlator_t *this = THIS;
-
- if (!xl || (xl == this)) {
- xl = FIRST_CHILD(this);
- }
-
- STACK_WIND (frame, glupy_create_cbk,xl, xl->fops->create,
- loc, flags, mode, umask, fd, xdata);
-}
-
-void
-unwind_create (call_frame_t *frame, long 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)
-{
- frame->local = NULL;
- STACK_UNWIND_STRICT (create, frame, op_ret, op_errno, fd, inode, buf,
- preparent, postparent, xdata);
-}
-
-void
-set_create_fop (long py_this, fop_create_t fop)
-{
- glupy_private_t *priv = ((xlator_t *)py_this)->private;
-
- priv->fops[GLUPY_CREATE] = (long)fop;
-}
-
-void
-set_create_cbk (long py_this, fop_create_cbk_t cbk)
-{
- glupy_private_t *priv = ((xlator_t *)py_this)->private;
-
- priv->cbks[GLUPY_CREATE] = (long)cbk;
-}
-
-/* FOP: OPEN */
-
-int32_t
-glupy_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)
-{
- glupy_private_t *priv = this->private;
- PyGILState_STATE gstate;
- int32_t ret;
-
- if (!priv->cbks[GLUPY_OPEN]) {
- goto unwind;
- }
-
- gstate = glupy_enter();
- ret = ((fop_open_cbk_t)(priv->cbks[GLUPY_OPEN]))(
- frame, cookie, this, op_ret, op_errno,
- fd, xdata);
- glupy_leave(gstate);
-
- return ret;
-
-unwind:
- frame->local = NULL;
- STACK_UNWIND_STRICT (open, frame, op_ret, op_errno, fd, xdata);
- return 0;
-}
-
-int32_t
-glupy_open (call_frame_t *frame, xlator_t *this, loc_t *loc,
- int32_t flags, fd_t *fd, dict_t *xdata)
-{
- glupy_private_t *priv = this->private;
- PyGILState_STATE gstate;
- int32_t ret;
- static long next_id = 0;
-
- if (!priv->fops[GLUPY_OPEN]) {
- goto wind;
- }
-
- gstate = glupy_enter();
- frame->local = (void *)++next_id;
- ret = ((fop_open_t)(priv->fops[GLUPY_OPEN]))(
- frame, this, loc, flags, fd, xdata);
- glupy_leave(gstate);
-
- return ret;
-
-wind:
- STACK_WIND (frame, glupy_open_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->open, loc, flags, fd, xdata);
- return 0;
-}
-
-void
-wind_open (call_frame_t *frame, xlator_t *xl, loc_t *loc, int32_t flags,
- fd_t *fd, dict_t *xdata)
-{
- xlator_t *this = THIS;
-
- if (!xl || (xl == this)) {
- xl = FIRST_CHILD(this);
- }
-
- STACK_WIND (frame, glupy_open_cbk, xl, xl->fops->open, loc, flags,
- fd, xdata);
-}
-
-void
-unwind_open (call_frame_t *frame, long cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, fd_t *fd, dict_t *xdata)
-{
- frame->local = NULL;
- STACK_UNWIND_STRICT (open, frame, op_ret, op_errno, fd, xdata);
-}
-
-void
-set_open_fop (long py_this, fop_open_t fop)
-{
- glupy_private_t *priv = ((xlator_t *)py_this)->private;
- priv->fops[GLUPY_OPEN] = (long)fop;
-}
-
-void
-set_open_cbk (long py_this, fop_open_cbk_t cbk)
-{
- glupy_private_t *priv = ((xlator_t *)py_this)->private;
- priv->cbks[GLUPY_OPEN] = (long)cbk;
-}
-
-/* FOP: READV */
-
-int32_t
-glupy_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)
-{
- glupy_private_t *priv = this->private;
- PyGILState_STATE gstate;
- int32_t ret;
-
- if (!priv->cbks[GLUPY_READV]) {
- goto unwind;
- }
-
- gstate = glupy_enter();
- ret = ((fop_readv_cbk_t)(priv->cbks[GLUPY_READV]))(
- frame, cookie, this, op_ret, op_errno,
- vector, count, stbuf, iobref, xdata);
- glupy_leave(gstate);
-
- return ret;
-
-unwind:
- frame->local = NULL;
- STACK_UNWIND_STRICT (readv, frame, op_ret, op_errno, vector,
- count, stbuf, iobref, xdata);
- return 0;
-}
-
-int32_t
-glupy_readv (call_frame_t *frame, xlator_t *this, fd_t *fd,
- size_t size, off_t offset, uint32_t flags, dict_t *xdata)
-{
- glupy_private_t *priv = this->private;
- PyGILState_STATE gstate;
- int32_t ret;
- static long next_id = 0;
-
- if (!priv->fops[GLUPY_READV]) {
- goto wind;
- }
-
- gstate = glupy_enter();
- frame->local = (void *)++next_id;
- ret = ((fop_readv_t)(priv->fops[GLUPY_READV]))(
- frame, this, fd, size, offset, flags, xdata);
- glupy_leave(gstate);
-
- return ret;
-
-wind:
- STACK_WIND (frame, glupy_readv_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->readv, fd, size, offset,
- flags, xdata);
- return 0;
-}
-
-void
-wind_readv (call_frame_t *frame, xlator_t *xl, fd_t *fd, size_t size,
- off_t offset, uint32_t flags, dict_t *xdata)
-{
- xlator_t *this = THIS;
-
- if (!xl || (xl == this)) {
- xl = FIRST_CHILD(this);
- }
-
- STACK_WIND (frame, glupy_readv_cbk, xl, xl->fops->readv, fd, size,
- offset, flags, xdata);
-}
-
-void
-unwind_readv (call_frame_t *frame, long 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)
-{
- frame->local = NULL;
- STACK_UNWIND_STRICT (readv, frame, op_ret, op_errno, vector,
- count, stbuf, iobref, xdata);
-}
-
-void
-set_readv_fop (long py_this, fop_readv_t fop)
-{
- glupy_private_t *priv = ((xlator_t *)py_this)->private;
- priv->fops[GLUPY_READV] = (long)fop;
-}
-
-void
-set_readv_cbk (long py_this, fop_readv_cbk_t cbk)
-{
- glupy_private_t *priv = ((xlator_t *)py_this)->private;
- priv->cbks[GLUPY_READV] = (long)cbk;
-}
-
-/* FOP: WRITEV */
-
-int32_t
-glupy_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)
-{
- glupy_private_t *priv = this->private;
- PyGILState_STATE gstate;
- int32_t ret;
-
- if (!priv->cbks[GLUPY_WRITEV]) {
- goto unwind;
- }
-
- gstate = glupy_enter();
- ret = ((fop_writev_cbk_t)(priv->cbks[GLUPY_WRITEV]))(
- frame, cookie, this, op_ret, op_errno,
- prebuf, postbuf, xdata);
- glupy_leave(gstate);
-
- return ret;
-
-unwind:
- frame->local = NULL;
- STACK_UNWIND_STRICT (writev, frame, op_ret, op_errno, prebuf,
- postbuf, xdata);
- return 0;
-}
-
-int32_t
-glupy_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)
-{
- glupy_private_t *priv = this->private;
- PyGILState_STATE gstate;
- int32_t ret;
- static long next_id = 0;
-
- if (!priv->fops[GLUPY_WRITEV]) {
- goto wind;
- }
-
- gstate = glupy_enter();
- frame->local = (void *)++next_id;
- ret = ((fop_writev_t)(priv->fops[GLUPY_WRITEV]))(
- frame, this, fd, vector, count, offset, flags,
- iobref, xdata);
- glupy_leave(gstate);
-
- return ret;
-
-wind:
- STACK_WIND (frame, glupy_writev_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->writev, fd, vector, count,
- offset, flags, iobref, xdata);
- return 0;
-}
-
-void
-wind_writev (call_frame_t *frame, xlator_t *xl, fd_t *fd, struct iovec *vector,
- int32_t count, off_t offset, uint32_t flags, struct iobref *iobref,
- dict_t *xdata)
-{
- xlator_t *this = THIS;
-
- if (!xl || (xl == this)) {
- xl = FIRST_CHILD(this);
- }
-
- STACK_WIND (frame, glupy_writev_cbk, xl, xl->fops->writev, fd, vector,
- count, offset, flags, iobref, xdata);
-}
-
-void
-unwind_writev (call_frame_t *frame, long cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
- struct iatt *postbuf, dict_t *xdata)
-{
- frame->local = NULL;
- STACK_UNWIND_STRICT (writev, frame, op_ret, op_errno, prebuf,
- postbuf, xdata);
-}
-
-void
-set_writev_fop (long py_this, fop_writev_t fop)
-{
- glupy_private_t *priv = ((xlator_t *)py_this)->private;
- priv->fops[GLUPY_WRITEV] = (long)fop;
-}
-
-void
-set_writev_cbk (long py_this, fop_writev_cbk_t cbk)
-{
- glupy_private_t *priv = ((xlator_t *)py_this)->private;
- priv->cbks[GLUPY_WRITEV] = (long)cbk;
-}
-
-
-/* FOP: OPENDIR */
-
-int32_t
-glupy_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)
-{
- glupy_private_t *priv = this->private;
- PyGILState_STATE gstate;
- int32_t ret;
-
- if (!priv->cbks[GLUPY_OPENDIR]) {
- goto unwind;
- }
-
- gstate = glupy_enter();
- ret = ((fop_opendir_cbk_t)(priv->cbks[GLUPY_OPENDIR]))(
- frame, cookie, this, op_ret, op_errno,
- fd, xdata);
- glupy_leave(gstate);
-
- return ret;
-
-unwind:
- frame->local = NULL;
- STACK_UNWIND_STRICT (opendir, frame, op_ret, op_errno, fd, xdata);
- return 0;
-}
-
-int32_t
-glupy_opendir (call_frame_t *frame, xlator_t *this, loc_t *loc,
- fd_t *fd, dict_t *xdata)
-{
- glupy_private_t *priv = this->private;
- PyGILState_STATE gstate;
- int32_t ret;
- static long next_id = 0;
-
- if (!priv->fops[GLUPY_OPENDIR]) {
- goto wind;
- }
-
- gstate = glupy_enter();
- frame->local = (void *)++next_id;
- ret = ((fop_opendir_t)(priv->fops[GLUPY_OPENDIR]))(
- frame, this, loc, fd, xdata);
- glupy_leave(gstate);
-
- return ret;
-
-wind:
- STACK_WIND (frame, glupy_opendir_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->opendir, loc, fd, xdata);
- return 0;
-}
-
-void
-wind_opendir (call_frame_t *frame, xlator_t *xl, loc_t *loc, fd_t *fd, dict_t *xdata)
-{
- xlator_t *this = THIS;
-
- if (!xl || (xl == this)) {
- xl = FIRST_CHILD(this);
- }
-
- STACK_WIND(frame,glupy_opendir_cbk,xl,xl->fops->opendir,loc,fd,xdata);
-}
-
-void
-unwind_opendir (call_frame_t *frame, long cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, fd_t *fd, dict_t *xdata)
-{
- frame->local = NULL;
- STACK_UNWIND_STRICT(opendir,frame,op_ret,op_errno,
- fd,xdata);
-}
-
-void
-set_opendir_fop (long py_this, fop_opendir_t fop)
-{
- glupy_private_t *priv = ((xlator_t *)py_this)->private;
-
- priv->fops[GLUPY_OPENDIR] = (long)fop;
-}
-
-void
-set_opendir_cbk (long py_this, fop_opendir_cbk_t cbk)
-{
- glupy_private_t *priv = ((xlator_t *)py_this)->private;
-
- priv->cbks[GLUPY_OPENDIR] = (long)cbk;
-}
-
-/* FOP: READDIR */
-
-int32_t
-glupy_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)
-{
- glupy_private_t *priv = this->private;
- PyGILState_STATE gstate;
- int32_t ret;
-
- if (!priv->cbks[GLUPY_READDIR]) {
- goto unwind;
- }
-
- gstate = glupy_enter();
- ret = ((fop_readdir_cbk_t)(priv->cbks[GLUPY_READDIR]))(
- frame, cookie, this, op_ret, op_errno,
- entries, xdata);
- glupy_leave(gstate);
-
- return ret;
-
-unwind:
- frame->local = NULL;
- STACK_UNWIND_STRICT (readdir, frame, op_ret, op_errno, entries,
- xdata);
- return 0;
-}
-
-int32_t
-glupy_readdir (call_frame_t *frame, xlator_t *this, fd_t *fd,
- size_t size, off_t offset, dict_t *xdata)
-{
- glupy_private_t *priv = this->private;
- PyGILState_STATE gstate;
- int32_t ret;
- static long next_id = 0;
-
- if (!priv->fops[GLUPY_READDIR]) {
- goto wind;
- }
-
- gstate = glupy_enter();
- frame->local = (void *)++next_id;
- ret = ((fop_readdir_t)(priv->fops[GLUPY_READDIR]))(
- frame, this, fd, size, offset, xdata);
- glupy_leave(gstate);
-
- return ret;
-
-wind:
- STACK_WIND (frame, glupy_readdir_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->readdir,fd, size, offset, xdata);
- return 0;
-}
-
-void
-wind_readdir(call_frame_t *frame, xlator_t *xl, fd_t *fd, size_t size,
- off_t offset, dict_t *xdata)
-{
- xlator_t *this = THIS;
-
- if (!xl || (xl == this)) {
- xl = FIRST_CHILD(this);
- }
-
- STACK_WIND(frame,glupy_readdir_cbk,xl,xl->fops->readdir,fd,size,offset,xdata);
-}
-
-void
-unwind_readdir (call_frame_t *frame, long cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, gf_dirent_t *entries,
- dict_t *xdata)
-{
- frame->local = NULL;
- STACK_UNWIND_STRICT(readdir,frame,op_ret,op_errno,
- entries, xdata);
-}
-
-void
-set_readdir_fop (long py_this, fop_readdir_t fop)
-{
- glupy_private_t *priv = ((xlator_t *)py_this)->private;
-
- priv->fops[GLUPY_READDIR] = (long)fop;
-}
-
-void
-set_readdir_cbk (long py_this, fop_readdir_cbk_t cbk)
-{
- glupy_private_t *priv = ((xlator_t *)py_this)->private;
-
- priv->cbks[GLUPY_READDIR] = (long)cbk;
-}
-
-
-/* FOP: READDIRP */
-
-int32_t
-glupy_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)
-{
- glupy_private_t *priv = this->private;
- PyGILState_STATE gstate;
- int32_t ret;
-
- if (!priv->cbks[GLUPY_READDIRP]) {
- goto unwind;
- }
-
- gstate = glupy_enter();
- ret = ((fop_readdirp_cbk_t)(priv->cbks[GLUPY_READDIRP]))(
- frame, cookie, this, op_ret, op_errno,
- entries, xdata);
- glupy_leave(gstate);
-
- return ret;
-
-unwind:
- frame->local = NULL;
- STACK_UNWIND_STRICT (readdirp, frame, op_ret, op_errno, entries,
- xdata);
- return 0;
-}
-
-int32_t
-glupy_readdirp (call_frame_t *frame, xlator_t *this, fd_t *fd,
- size_t size, off_t offset, dict_t *xdata)
-{
- glupy_private_t *priv = this->private;
- PyGILState_STATE gstate;
- int32_t ret;
- static long next_id = 0;
-
- if (!priv->fops[GLUPY_READDIRP]) {
- goto wind;
- }
-
- gstate = glupy_enter();
- frame->local = (void *)++next_id;
- ret = ((fop_readdirp_t)(priv->fops[GLUPY_READDIRP]))(
- frame, this, fd, size, offset, xdata);
- glupy_leave(gstate);
-
- return ret;
-
-wind:
- STACK_WIND (frame, glupy_readdirp_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->readdirp,fd, size, offset, xdata);
- return 0;
-}
-
-void
-wind_readdirp (call_frame_t *frame, xlator_t *xl, fd_t *fd, size_t size,
- off_t offset, dict_t *xdata)
-{
- xlator_t *this = THIS;
-
- if (!xl || (xl == this)) {
- xl = FIRST_CHILD(this);
- }
-
- STACK_WIND(frame,glupy_readdirp_cbk,xl,xl->fops->readdirp,fd,size,offset,xdata);
-}
-
-void
-unwind_readdirp (call_frame_t *frame, long cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, gf_dirent_t *entries,
- dict_t *xdata)
-{
- frame->local = NULL;
- STACK_UNWIND_STRICT(readdirp,frame,op_ret,op_errno,
- entries, xdata);
-}
-
-void
-set_readdirp_fop (long py_this, fop_readdirp_t fop)
-{
- glupy_private_t *priv = ((xlator_t *)py_this)->private;
-
- priv->fops[GLUPY_READDIRP] = (long)fop;
-}
-
-void
-set_readdirp_cbk (long py_this, fop_readdirp_cbk_t cbk)
-{
- glupy_private_t *priv = ((xlator_t *)py_this)->private;
-
- priv->cbks[GLUPY_READDIRP] = (long)cbk;
-}
-
-
-/* FOP:STAT */
-
-int32_t
-glupy_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)
-{
- glupy_private_t *priv = this->private;
- PyGILState_STATE gstate;
- int32_t ret;
-
- if (!priv->cbks[GLUPY_STAT]) {
- goto unwind;
- }
-
- gstate = glupy_enter();
- ret = ((fop_stat_cbk_t)(priv->cbks[GLUPY_STAT]))(
- frame, cookie, this, op_ret, op_errno,
- buf, xdata);
- glupy_leave(gstate);
-
- return ret;
-
-unwind:
- frame->local = NULL;
- STACK_UNWIND_STRICT (stat, frame, op_ret, op_errno, buf, xdata);
- return 0;
-}
-
-int32_t
-glupy_stat (call_frame_t *frame, xlator_t *this, loc_t *loc,
- dict_t *xdata)
-{
- glupy_private_t *priv = this->private;
- PyGILState_STATE gstate;
- int32_t ret;
- static long next_id = 0;
-
- if (!priv->fops[GLUPY_STAT]) {
- goto wind;
- }
-
- gstate = glupy_enter();
- frame->local = (void *)++next_id;
- ret = ((fop_stat_t)(priv->fops[GLUPY_STAT]))(
- frame, this, loc, xdata);
- glupy_leave(gstate);
-
- return ret;
-
-wind:
- STACK_WIND (frame, glupy_stat_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->stat, loc, xdata);
- return 0;
-}
-
-void
-wind_stat (call_frame_t *frame, xlator_t *xl, loc_t *loc, dict_t *xdata)
-{
- xlator_t *this = THIS;
-
- if (!xl || (xl == this)) {
- xl = FIRST_CHILD(this);
- }
-
- STACK_WIND(frame,glupy_stat_cbk,xl,xl->fops->stat,loc,xdata);
-}
-
-void
-unwind_stat (call_frame_t *frame, long cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct iatt *buf,
- dict_t *xdata)
-{
- frame->local = NULL;
- STACK_UNWIND_STRICT(stat,frame,op_ret,op_errno,
- buf,xdata);
-}
-
-void
-set_stat_fop (long py_this, fop_stat_t fop)
-{
- glupy_private_t *priv = ((xlator_t *)py_this)->private;
-
- priv->fops[GLUPY_STAT] = (long)fop;
-}
-
-void
-set_stat_cbk (long py_this, fop_stat_cbk_t cbk)
-{
- glupy_private_t *priv = ((xlator_t *)py_this)->private;
-
- priv->cbks[GLUPY_STAT] = (long)cbk;
-}
-
-
-/* FOP: FSTAT */
-
-int32_t
-glupy_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)
-{
- glupy_private_t *priv = this->private;
- PyGILState_STATE gstate;
- int32_t ret;
-
- if (!priv->cbks[GLUPY_FSTAT]) {
- goto unwind;
- }
-
- gstate = glupy_enter();
- ret = ((fop_fstat_cbk_t)(priv->cbks[GLUPY_FSTAT]))(
- frame, cookie, this, op_ret, op_errno,
- buf, xdata);
- glupy_leave(gstate);
-
- return ret;
-
-unwind:
- frame->local = NULL;
- STACK_UNWIND_STRICT (fstat, frame, op_ret, op_errno, buf, xdata);
- return 0;
-}
-
-int32_t
-glupy_fstat (call_frame_t *frame, xlator_t *this, fd_t *fd,
- dict_t *xdata)
-{
- glupy_private_t *priv = this->private;
- PyGILState_STATE gstate;
- int32_t ret;
- static long next_id = 0;
-
- if (!priv->fops[GLUPY_FSTAT]) {
- goto wind;
- }
-
- gstate = glupy_enter();
- frame->local = (void *)++next_id;
- ret = ((fop_fstat_t)(priv->fops[GLUPY_FSTAT]))(
- frame, this, fd, xdata);
- glupy_leave(gstate);
-
- return ret;
-
-wind:
- STACK_WIND (frame, glupy_fstat_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fstat, fd, xdata);
- return 0;
-}
-
-void
-wind_fstat (call_frame_t *frame, xlator_t *xl, fd_t *fd, dict_t *xdata)
-{
- xlator_t *this = THIS;
-
- if (!xl || (xl == this)) {
- xl = FIRST_CHILD(this);
- }
-
- STACK_WIND(frame,glupy_fstat_cbk,xl,xl->fops->fstat,fd,xdata);
-}
-
-void
-unwind_fstat (call_frame_t *frame, long cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct iatt *buf,
- dict_t *xdata)
-{
- frame->local = NULL;
- STACK_UNWIND_STRICT(fstat,frame,op_ret,op_errno,
- buf,xdata);
-}
-
-void
-set_fstat_fop (long py_this, fop_fstat_t fop)
-{
- glupy_private_t *priv = ((xlator_t *)py_this)->private;
-
- priv->fops[GLUPY_FSTAT] = (long)fop;
-}
-
-void
-set_fstat_cbk (long py_this, fop_fstat_cbk_t cbk)
-{
- glupy_private_t *priv = ((xlator_t *)py_this)->private;
-
- priv->cbks[GLUPY_FSTAT] = (long)cbk;
-}
-
-/* FOP:STATFS */
-
-int32_t
-glupy_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)
-{
- glupy_private_t *priv = this->private;
- PyGILState_STATE gstate;
- int32_t ret;
-
- if (!priv->cbks[GLUPY_STATFS]) {
- goto unwind;
- }
-
- gstate = glupy_enter();
- ret = ((fop_statfs_cbk_t)(priv->cbks[GLUPY_STATFS]))(
- frame, cookie, this, op_ret, op_errno,
- buf, xdata);
- glupy_leave(gstate);
-
- return ret;
-
-unwind:
- frame->local = NULL;
- STACK_UNWIND_STRICT (statfs, frame, op_ret, op_errno, buf, xdata);
- return 0;
-}
-
-int32_t
-glupy_statfs (call_frame_t *frame, xlator_t *this, loc_t *loc,
- dict_t *xdata)
-{
- glupy_private_t *priv = this->private;
- PyGILState_STATE gstate;
- int32_t ret;
- static long next_id = 0;
-
- if (!priv->fops[GLUPY_STATFS]) {
- goto wind;
- }
-
- gstate = glupy_enter();
- frame->local = (void *)++next_id;
- ret = ((fop_statfs_t)(priv->fops[GLUPY_STATFS]))(
- frame, this, loc, xdata);
- glupy_leave(gstate);
-
- return ret;
-
-wind:
- STACK_WIND (frame, glupy_statfs_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->statfs, loc, xdata);
- return 0;
-}
-
-void
-wind_statfs (call_frame_t *frame, xlator_t *xl, loc_t *loc, dict_t *xdata)
-{
- xlator_t *this = THIS;
-
- if (!xl || (xl == this)) {
- xl = FIRST_CHILD(this);
- }
-
- STACK_WIND(frame,glupy_statfs_cbk,xl,xl->fops->statfs,loc,xdata);
-}
-
-void
-unwind_statfs (call_frame_t *frame, long cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct statvfs *buf,
- dict_t *xdata)
-{
- frame->local = NULL;
- STACK_UNWIND_STRICT(statfs,frame,op_ret,op_errno,
- buf,xdata);
-}
-
-void
-set_statfs_fop (long py_this, fop_statfs_t fop)
-{
- glupy_private_t *priv = ((xlator_t *)py_this)->private;
-
- priv->fops[GLUPY_STATFS] = (long)fop;
-}
-
-void
-set_statfs_cbk (long py_this, fop_statfs_cbk_t cbk)
-{
- glupy_private_t *priv = ((xlator_t *)py_this)->private;
-
- priv->cbks[GLUPY_STATFS] = (long)cbk;
-}
-
-
-/* FOP: SETXATTR */
-
-int32_t
-glupy_setxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
-{
- glupy_private_t *priv = this->private;
- PyGILState_STATE gstate;
- int32_t ret;
-
- if (!priv->cbks[GLUPY_SETXATTR]) {
- goto unwind;
- }
-
- gstate = glupy_enter();
- ret = ((fop_setxattr_cbk_t)(priv->cbks[GLUPY_SETXATTR]))(
- frame, cookie, this, op_ret, op_errno,
- xdata);
- glupy_leave(gstate);
-
- return ret;
-
-unwind:
- frame->local = NULL;
- STACK_UNWIND_STRICT (setxattr, frame, op_ret, op_errno, xdata);
- return 0;
-}
-
-int32_t
-glupy_setxattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
- dict_t *dict, int32_t flags, dict_t *xdata)
-{
- glupy_private_t *priv = this->private;
- PyGILState_STATE gstate;
- int32_t ret;
- static long next_id = 0;
-
- if (!priv->fops[GLUPY_SETXATTR]) {
- goto wind;
- }
-
- gstate = glupy_enter();
- frame->local = (void *)++next_id;
- ret = ((fop_setxattr_t)(priv->fops[GLUPY_SETXATTR]))(
- frame, this, loc, dict, flags, xdata);
- glupy_leave(gstate);
-
- return ret;
-
-wind:
- STACK_WIND (frame, glupy_setxattr_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->setxattr, loc, dict,
- flags, xdata);
- return 0;
-}
-
-void
-wind_setxattr (call_frame_t *frame, xlator_t *xl, loc_t *loc,
- dict_t *dict, int32_t flags, dict_t *xdata)
-{
- xlator_t *this = THIS;
-
- if (!xl || (xl == this)) {
- xl = FIRST_CHILD(this);
- }
-
- STACK_WIND (frame, glupy_setxattr_cbk, xl, xl->fops->setxattr,
- loc, dict, flags, xdata);
-}
-
-
-void
-unwind_setxattr (call_frame_t *frame, long cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
-{
- frame->local = NULL;
- STACK_UNWIND_STRICT (setxattr, frame, op_ret, op_errno, xdata);
-
-}
-
-void
-set_setxattr_fop (long py_this, fop_setxattr_t fop)
-{
- glupy_private_t *priv = ((xlator_t *)py_this)->private;
-
- priv->fops[GLUPY_SETXATTR] = (long)fop;
-}
-
-void
-set_setxattr_cbk (long py_this, fop_setxattr_cbk_t cbk)
-{
- glupy_private_t *priv = ((xlator_t *)py_this)->private;
-
- priv->cbks[GLUPY_SETXATTR] = (long)cbk;
-}
-
-/* FOP: GETXATTR */
-
-int32_t
-glupy_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)
-{
- glupy_private_t *priv = this->private;
- PyGILState_STATE gstate;
- int32_t ret;
-
- if (!priv->cbks[GLUPY_GETXATTR]) {
- goto unwind;
- }
-
- gstate = glupy_enter();
- ret = ((fop_getxattr_cbk_t)(priv->cbks[GLUPY_GETXATTR]))(
- frame, cookie, this, op_ret, op_errno, dict,
- xdata);
- glupy_leave(gstate);
-
- return ret;
-
-unwind:
- frame->local = NULL;
- STACK_UNWIND_STRICT (getxattr, frame, op_ret, op_errno, dict,
- xdata);
- return 0;
-}
-
-int32_t
-glupy_getxattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
- const char *name, dict_t *xdata)
-{
- glupy_private_t *priv = this->private;
- PyGILState_STATE gstate;
- int32_t ret;
- static long next_id = 0;
-
- if (!priv->fops[GLUPY_GETXATTR]) {
- goto wind;
- }
-
- gstate = glupy_enter();
- frame->local = (void *)++next_id;
- ret = ((fop_getxattr_t)(priv->fops[GLUPY_GETXATTR]))(
- frame, this, loc, name, xdata);
- glupy_leave(gstate);
-
- return ret;
-
-wind:
- STACK_WIND (frame, glupy_getxattr_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->getxattr, loc, name,
- xdata);
- return 0;
-}
-
-void
-wind_getxattr (call_frame_t *frame, xlator_t *xl, loc_t *loc,
- const char *name, dict_t *xdata)
-{
- xlator_t *this = THIS;
-
- if (!xl || (xl == this)) {
- xl = FIRST_CHILD(this);
- }
-
- STACK_WIND (frame, glupy_getxattr_cbk, xl, xl->fops->getxattr,
- loc, name, xdata);
-}
-
-
-void
-unwind_getxattr (call_frame_t *frame, long cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *dict,
- dict_t *xdata)
-{
- frame->local = NULL;
- STACK_UNWIND_STRICT (getxattr, frame, op_ret, op_errno, dict,
- xdata);
-
-}
-
-
-void
-set_getxattr_fop (long py_this, fop_getxattr_t fop)
-{
- glupy_private_t *priv = ((xlator_t *)py_this)->private;
-
- priv->fops[GLUPY_GETXATTR] = (long)fop;
-}
-
-
-void
-set_getxattr_cbk (long py_this, fop_getxattr_cbk_t cbk)
-{
- glupy_private_t *priv = ((xlator_t *)py_this)->private;
-
- priv->cbks[GLUPY_GETXATTR] = (long)cbk;
-}
-
-/* FOP: FSETXATTR */
-
-int32_t
-glupy_fsetxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
-{
- glupy_private_t *priv = this->private;
- PyGILState_STATE gstate;
- int32_t ret;
-
- if (!priv->cbks[GLUPY_FSETXATTR]) {
- goto unwind;
- }
-
- gstate = glupy_enter();
- ret = ((fop_fsetxattr_cbk_t)(priv->cbks[GLUPY_FSETXATTR]))(
- frame, cookie, this, op_ret, op_errno,
- xdata);
- glupy_leave(gstate);
-
- return ret;
-
-unwind:
- frame->local = NULL;
- STACK_UNWIND_STRICT (fsetxattr, frame, op_ret, op_errno, xdata);
- return 0;
-}
-
-int32_t
-glupy_fsetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
- dict_t *dict, int32_t flags, dict_t *xdata)
-{
- glupy_private_t *priv = this->private;
- PyGILState_STATE gstate;
- int32_t ret;
- static long next_id = 0;
-
- if (!priv->fops[GLUPY_FSETXATTR]) {
- goto wind;
- }
-
- gstate = glupy_enter();
- frame->local = (void *)++next_id;
- ret = ((fop_fsetxattr_t)(priv->fops[GLUPY_FSETXATTR]))(
- frame, this, fd, dict, flags, xdata);
- glupy_leave(gstate);
-
- return ret;
-
-wind:
- STACK_WIND (frame, glupy_fsetxattr_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fsetxattr, fd, dict,
- flags, xdata);
- return 0;
-}
-
-void
-wind_fsetxattr (call_frame_t *frame, xlator_t *xl, fd_t *fd,
- dict_t *dict, int32_t flags, dict_t *xdata)
-{
- xlator_t *this = THIS;
-
- if (!xl || (xl == this)) {
- xl = FIRST_CHILD(this);
- }
-
- STACK_WIND (frame, glupy_fsetxattr_cbk, xl, xl->fops->fsetxattr,
- fd, dict, flags, xdata);
-}
-
-
-void
-unwind_fsetxattr (call_frame_t *frame, long cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
-{
- frame->local = NULL;
- STACK_UNWIND_STRICT (fsetxattr, frame, op_ret, op_errno, xdata);
-
-}
-
-void
-set_fsetxattr_fop (long py_this, fop_fsetxattr_t fop)
-{
- glupy_private_t *priv = ((xlator_t *)py_this)->private;
-
- priv->fops[GLUPY_FSETXATTR] = (long)fop;
-}
-
-void
-set_fsetxattr_cbk (long py_this, fop_fsetxattr_cbk_t cbk)
-{
- glupy_private_t *priv = ((xlator_t *)py_this)->private;
-
- priv->cbks[GLUPY_FSETXATTR] = (long)cbk;
-}
-
-/* FOP: FGETXATTR */
-
-int32_t
-glupy_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)
-{
- glupy_private_t *priv = this->private;
- PyGILState_STATE gstate;
- int32_t ret;
-
- if (!priv->cbks[GLUPY_FGETXATTR]) {
- goto unwind;
- }
-
- gstate = glupy_enter();
- ret = ((fop_fgetxattr_cbk_t)(priv->cbks[GLUPY_FGETXATTR]))(
- frame, cookie, this, op_ret, op_errno, dict,
- xdata);
- glupy_leave(gstate);
-
- return ret;
-
-unwind:
- frame->local = NULL;
- STACK_UNWIND_STRICT (fgetxattr, frame, op_ret, op_errno, dict,
- xdata);
- return 0;
-}
-
-int32_t
-glupy_fgetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
- const char *name, dict_t *xdata)
-{
- glupy_private_t *priv = this->private;
- PyGILState_STATE gstate;
- int32_t ret;
- static long next_id = 0;
-
- if (!priv->fops[GLUPY_FGETXATTR]) {
- goto wind;
- }
-
- gstate = glupy_enter();
- frame->local = (void *)++next_id;
- ret = ((fop_fgetxattr_t)(priv->fops[GLUPY_FGETXATTR]))(
- frame, this, fd, name, xdata);
- glupy_leave(gstate);
-
- return ret;
-
-wind:
- STACK_WIND (frame, glupy_fgetxattr_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fgetxattr, fd, name,
- xdata);
- return 0;
-}
-
-void
-wind_fgetxattr (call_frame_t *frame, xlator_t *xl, fd_t *fd,
- const char *name, dict_t *xdata)
-{
- xlator_t *this = THIS;
-
- if (!xl || (xl == this)) {
- xl = FIRST_CHILD(this);
- }
-
- STACK_WIND (frame, glupy_fgetxattr_cbk, xl, xl->fops->fgetxattr,
- fd, name, xdata);
-}
-
-
-void
-unwind_fgetxattr (call_frame_t *frame, long cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *dict,
- dict_t *xdata)
-{
- frame->local = NULL;
- STACK_UNWIND_STRICT (fgetxattr, frame, op_ret, op_errno, dict,
- xdata);
-
-}
-
-
-void
-set_fgetxattr_fop (long py_this, fop_fgetxattr_t fop)
-{
- glupy_private_t *priv = ((xlator_t *)py_this)->private;
-
- priv->fops[GLUPY_FGETXATTR] = (long)fop;
-}
-
-
-void
-set_fgetxattr_cbk (long py_this, fop_fgetxattr_cbk_t cbk)
-{
- glupy_private_t *priv = ((xlator_t *)py_this)->private;
-
- priv->cbks[GLUPY_FGETXATTR] = (long)cbk;
-}
-
-/* FOP:REMOVEXATTR */
-
-int32_t
-glupy_removexattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
-{
- glupy_private_t *priv = this->private;
- PyGILState_STATE gstate;
- int32_t ret;
-
- if (!priv->cbks[GLUPY_REMOVEXATTR]) {
- goto unwind;
- }
-
- gstate = glupy_enter();
- ret = ((fop_removexattr_cbk_t)(priv->cbks[GLUPY_REMOVEXATTR]))(
- frame, cookie, this, op_ret, op_errno, xdata);
- glupy_leave(gstate);
-
- return ret;
-
-unwind:
- frame->local = NULL;
- STACK_UNWIND_STRICT (removexattr, frame, op_ret, op_errno, xdata);
- return 0;
-}
-
-int32_t
-glupy_removexattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
- const char *name, dict_t *xdata)
-{
- glupy_private_t *priv = this->private;
- PyGILState_STATE gstate;
- int32_t ret;
- static long next_id = 0;
-
- if (!priv->fops[GLUPY_REMOVEXATTR]) {
- goto wind;
- }
-
- gstate = glupy_enter();
- frame->local = (void *)++next_id;
- ret = ((fop_removexattr_t)(priv->fops[GLUPY_REMOVEXATTR]))(
- frame, this, loc, name, xdata);
- glupy_leave(gstate);
-
- return ret;
-
-wind:
- STACK_WIND (frame, glupy_removexattr_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->removexattr, loc, name,
- xdata);
- return 0;
-}
-
-void
-wind_removexattr (call_frame_t *frame, xlator_t *xl, loc_t *loc,
- const char *name, dict_t *xdata)
-{
- xlator_t *this = THIS;
-
- if (!xl || (xl == this)) {
- xl = FIRST_CHILD(this);
- }
-
- STACK_WIND (frame, glupy_removexattr_cbk, xl, xl->fops->removexattr,
- loc, name, xdata);
-}
-
-
-void
-unwind_removexattr (call_frame_t *frame, long cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
-{
- frame->local = NULL;
- STACK_UNWIND_STRICT (removexattr, frame, op_ret, op_errno, xdata);
-
-}
-
-void
-set_removexattr_fop (long py_this, fop_removexattr_t fop)
-{
- glupy_private_t *priv = ((xlator_t *)py_this)->private;
-
- priv->fops[GLUPY_REMOVEXATTR] = (long)fop;
-}
-
-void
-set_removexattr_cbk (long py_this, fop_removexattr_cbk_t cbk)
-{
- glupy_private_t *priv = ((xlator_t *)py_this)->private;
-
- priv->cbks[GLUPY_REMOVEXATTR] = (long)cbk;
-}
-
-
-/* FOP:FREMOVEXATTR */
-
-int32_t
-glupy_fremovexattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
-{
- glupy_private_t *priv = this->private;
- PyGILState_STATE gstate;
- int32_t ret;
-
- if (!priv->cbks[GLUPY_FREMOVEXATTR]) {
- goto unwind;
- }
-
- gstate = glupy_enter();
- ret = ((fop_fremovexattr_cbk_t)(priv->cbks[GLUPY_FREMOVEXATTR]))(
- frame, cookie, this, op_ret, op_errno, xdata);
- glupy_leave(gstate);
-
- return ret;
-
-unwind:
- frame->local = NULL;
- STACK_UNWIND_STRICT (fremovexattr, frame, op_ret, op_errno, xdata);
- return 0;
-}
-
-int32_t
-glupy_fremovexattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
- const char *name, dict_t *xdata)
-{
- glupy_private_t *priv = this->private;
- PyGILState_STATE gstate;
- int32_t ret;
- static long next_id = 0;
-
- if (!priv->fops[GLUPY_FREMOVEXATTR]) {
- goto wind;
- }
-
- gstate = glupy_enter();
- frame->local = (void *)++next_id;
- ret = ((fop_fremovexattr_t)(priv->fops[GLUPY_FREMOVEXATTR]))(
- frame, this, fd, name, xdata);
- glupy_leave(gstate);
-
- return ret;
-
-wind:
- STACK_WIND (frame, glupy_fremovexattr_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fremovexattr, fd, name,
- xdata);
- return 0;
-}
-
-void
-wind_fremovexattr (call_frame_t *frame, xlator_t *xl, fd_t *fd,
- const char *name, dict_t *xdata)
-{
- xlator_t *this = THIS;
-
- if (!xl || (xl == this)) {
- xl = FIRST_CHILD(this);
- }
-
- STACK_WIND (frame, glupy_fremovexattr_cbk, xl, xl->fops->fremovexattr,
- fd, name, xdata);
-}
-
-
-void
-unwind_fremovexattr (call_frame_t *frame, long cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
-{
- frame->local = NULL;
- STACK_UNWIND_STRICT (fremovexattr, frame, op_ret, op_errno, xdata);
-
-}
-
-void
-set_fremovexattr_fop (long py_this, fop_fremovexattr_t fop)
-{
- glupy_private_t *priv = ((xlator_t *)py_this)->private;
-
- priv->fops[GLUPY_FREMOVEXATTR] = (long)fop;
-}
-
-void
-set_fremovexattr_cbk (long py_this, fop_fremovexattr_cbk_t cbk)
-{
- glupy_private_t *priv = ((xlator_t *)py_this)->private;
-
- priv->cbks[GLUPY_FREMOVEXATTR] = (long)cbk;
-}
-
-
-/* FOP: LINK*/
-int32_t
-glupy_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)
-{
- glupy_private_t *priv = this->private;
- PyGILState_STATE gstate;
- int32_t ret;
-
- if (!priv->cbks[GLUPY_LINK]) {
- goto unwind;
- }
-
- gstate = glupy_enter();
- ret = ((fop_link_cbk_t)(priv->cbks[GLUPY_LINK]))(
- frame, cookie, this, op_ret, op_errno,
- inode, buf, preparent, postparent, xdata);
- glupy_leave(gstate);
-
- return ret;
-
-unwind:
- frame->local = NULL;
- STACK_UNWIND_STRICT (link, frame, op_ret, op_errno, inode, buf,
- preparent, postparent, xdata);
- return 0;
-}
-
-int32_t
-glupy_link(call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc,
- dict_t *xdata)
-{
- glupy_private_t *priv = this->private;
- PyGILState_STATE gstate;
- int32_t ret;
- static long next_id = 0;
-
- if (!priv->fops[GLUPY_LINK]) {
- goto wind;
- }
-
- gstate = glupy_enter();
- frame->local = (void *)++next_id;
- ret = ((fop_link_t)(priv->fops[GLUPY_LINK]))(
- frame, this, oldloc, newloc, xdata);
- glupy_leave(gstate);
-
- return ret;
-
-wind:
- STACK_WIND (frame, glupy_link_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->link, oldloc, newloc,
- xdata);
- return 0;
-}
-
-void
-wind_link (call_frame_t *frame, xlator_t *xl, loc_t *oldloc, loc_t *newloc,
- dict_t *xdata)
-{
- xlator_t *this = THIS;
-
- if (!xl || (xl == this)) {
- xl = FIRST_CHILD(this);
- }
-
- STACK_WIND (frame, glupy_link_cbk, xl, xl->fops->link,
- oldloc, newloc, xdata);
-}
-
-void
-unwind_link (call_frame_t *frame, long 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)
-{
- frame->local = NULL;
- STACK_UNWIND_STRICT (link, frame, op_ret, op_errno, inode, buf,
- preparent, postparent, xdata);
-}
-
-void
-set_link_fop (long py_this, fop_link_t fop)
-{
- glupy_private_t *priv = ((xlator_t *)py_this)->private;
-
- priv->fops[GLUPY_LINK] = (long)fop;
-}
-
-void
-set_link_cbk (long py_this, fop_link_cbk_t cbk)
-{
- glupy_private_t *priv = ((xlator_t *)py_this)->private;
-
- priv->cbks[GLUPY_LINK] = (long)cbk;
-}
-
-/* FOP: SYMLINK*/
-int32_t
-glupy_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)
-{
- glupy_private_t *priv = this->private;
- PyGILState_STATE gstate;
- int32_t ret;
-
- if (!priv->cbks[GLUPY_SYMLINK]) {
- goto unwind;
- }
-
- gstate = glupy_enter();
- ret = ((fop_symlink_cbk_t)(priv->cbks[GLUPY_SYMLINK]))(
- frame, cookie, this, op_ret, op_errno,
- inode, buf, preparent, postparent, xdata);
- glupy_leave(gstate);
-
- return ret;
-
-unwind:
- frame->local = NULL;
- STACK_UNWIND_STRICT (symlink, frame, op_ret, op_errno, inode, buf,
- preparent, postparent, xdata);
- return 0;
-}
-
-int32_t
-glupy_symlink(call_frame_t *frame, xlator_t *this, const char *linkname,
- loc_t *loc, mode_t umask, dict_t *xdata)
-{
- glupy_private_t *priv = this->private;
- PyGILState_STATE gstate;
- int32_t ret;
- static long next_id = 0;
-
- if (!priv->fops[GLUPY_SYMLINK]) {
- goto wind;
- }
-
- gstate = glupy_enter();
- frame->local = (void *)++next_id;
- ret = ((fop_symlink_t)(priv->fops[GLUPY_SYMLINK]))(
- frame, this, linkname, loc, umask, xdata);
- glupy_leave(gstate);
-
- return ret;
-
-wind:
- STACK_WIND (frame, glupy_symlink_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->symlink, linkname, loc,
- umask, xdata);
- return 0;
-}
-
-void
-wind_symlink (call_frame_t *frame, xlator_t *xl, const char *linkname,
- loc_t *loc, mode_t umask, dict_t *xdata)
-{
- xlator_t *this = THIS;
-
- if (!xl || (xl == this)) {
- xl = FIRST_CHILD(this);
- }
-
- STACK_WIND (frame, glupy_symlink_cbk, xl, xl->fops->symlink,
- linkname, loc, umask, xdata);
-}
-
-void
-unwind_symlink (call_frame_t *frame, long 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)
-{
- frame->local = NULL;
- STACK_UNWIND_STRICT (symlink, frame, op_ret, op_errno, inode, buf,
- preparent, postparent, xdata);
-}
-
-void
-set_symlink_fop (long py_this, fop_symlink_t fop)
-{
- glupy_private_t *priv = ((xlator_t *)py_this)->private;
-
- priv->fops[GLUPY_SYMLINK] = (long)fop;
-}
-
-void
-set_symlink_cbk (long py_this, fop_symlink_cbk_t cbk)
-{
- glupy_private_t *priv = ((xlator_t *)py_this)->private;
-
- priv->cbks[GLUPY_SYMLINK] = (long)cbk;
-}
-
-
-/* FOP: READLINK */
-int32_t
-glupy_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)
-{
- glupy_private_t *priv = this->private;
- PyGILState_STATE gstate;
- int32_t ret;
-
- if (!priv->cbks[GLUPY_READLINK]) {
- goto unwind;
- }
-
- gstate = glupy_enter();
- ret = ((fop_readlink_cbk_t)(priv->cbks[GLUPY_READLINK]))(
- frame, cookie, this, op_ret, op_errno,
- path, buf, xdata);
- glupy_leave(gstate);
-
- return ret;
-
-unwind:
- frame->local = NULL;
- STACK_UNWIND_STRICT (readlink, frame, op_ret, op_errno, path,
- buf, xdata);
- return 0;
-}
-
-int32_t
-glupy_readlink (call_frame_t *frame, xlator_t *this, loc_t *loc,
- size_t size, dict_t *xdata)
-{
- glupy_private_t *priv = this->private;
- PyGILState_STATE gstate;
- int32_t ret;
- static long next_id = 0;
-
- if (!priv->fops[GLUPY_READLINK]) {
- goto wind;
- }
-
- gstate = glupy_enter();
- frame->local = (void *)++next_id;
- ret = ((fop_readlink_t)(priv->fops[GLUPY_READLINK]))(
- frame, this, loc, size, xdata);
- glupy_leave(gstate);
-
- return ret;
-
-wind:
- STACK_WIND (frame, glupy_readlink_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->readlink, loc,
- size, xdata);
- return 0;
-}
-
-void
-wind_readlink (call_frame_t *frame, xlator_t *xl, loc_t *loc,
- size_t size, dict_t *xdata)
-{
- xlator_t *this = THIS;
-
- if (!xl || (xl == this)) {
- xl = FIRST_CHILD(this);
- }
-
- STACK_WIND (frame, glupy_readlink_cbk, xl, xl->fops->readlink,
- loc, size, xdata);
-}
-
-void
-unwind_readlink (call_frame_t *frame, long cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, const char *path,
- struct iatt *buf, dict_t *xdata)
-{
- frame->local = NULL;
- STACK_UNWIND_STRICT (readlink, frame, op_ret, op_errno, path, buf,
- xdata);
-}
-
-void
-set_readlink_fop (long py_this, fop_readlink_t fop)
-{
- glupy_private_t *priv = ((xlator_t *)py_this)->private;
-
- priv->fops[GLUPY_READLINK] = (long)fop;
-}
-
-void
-set_readlink_cbk (long py_this, fop_readlink_cbk_t cbk)
-{
- glupy_private_t *priv = ((xlator_t *)py_this)->private;
-
- priv->cbks[GLUPY_READLINK] = (long)cbk;
-}
-
-
-/* FOP: UNLINK */
-
-int32_t
-glupy_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)
-{
- glupy_private_t *priv = this->private;
- PyGILState_STATE gstate;
- int32_t ret;
-
- if (!priv->cbks[GLUPY_UNLINK]) {
- goto unwind;
- }
-
- gstate = glupy_enter();
- ret = ((fop_unlink_cbk_t)(priv->cbks[GLUPY_UNLINK]))(
- frame, cookie, this, op_ret, op_errno,
- preparent, postparent, xdata);
- glupy_leave(gstate);
-
- return ret;
-
-unwind:
- frame->local = NULL;
- STACK_UNWIND_STRICT (unlink, frame, op_ret, op_errno, preparent,
- postparent, xdata);
- return 0;
-}
-
-int32_t
-glupy_unlink (call_frame_t *frame, xlator_t *this, loc_t *loc,
- int xflags, dict_t *xdata)
-{
- glupy_private_t *priv = this->private;
- PyGILState_STATE gstate;
- int32_t ret;
- static long next_id = 0;
-
- if (!priv->fops[GLUPY_UNLINK]) {
- goto wind;
- }
-
- gstate = glupy_enter();
- frame->local = (void *)++next_id;
- ret = ((fop_unlink_t)(priv->fops[GLUPY_UNLINK]))(
- frame, this, loc, xflags, xdata);
- glupy_leave(gstate);
-
- return ret;
-
-wind:
- STACK_WIND (frame, glupy_unlink_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->unlink, loc,
- xflags, xdata);
- return 0;
-}
-
-void
-wind_unlink (call_frame_t *frame, xlator_t *xl, loc_t *loc,
- int xflags, dict_t *xdata)
-{
- xlator_t *this = THIS;
-
- if (!xl || (xl == this)) {
- xl = FIRST_CHILD(this);
- }
-
- STACK_WIND (frame, glupy_unlink_cbk, xl, xl->fops->unlink,
- loc, xflags, xdata);
-}
-
-void
-unwind_unlink (call_frame_t *frame, long cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno,
- struct iatt *preparent, struct iatt *postparent,
- dict_t *xdata)
-{
- frame->local = NULL;
- STACK_UNWIND_STRICT (unlink, frame, op_ret, op_errno,
- preparent, postparent, xdata);
-}
-
-void
-set_unlink_fop (long py_this, fop_unlink_t fop)
-{
- glupy_private_t *priv = ((xlator_t *)py_this)->private;
-
- priv->fops[GLUPY_UNLINK] = (long)fop;
-}
-
-void
-set_unlink_cbk (long py_this, fop_unlink_cbk_t cbk)
-{
- glupy_private_t *priv = ((xlator_t *)py_this)->private;
-
- priv->cbks[GLUPY_UNLINK] = (long)cbk;
-}
-
-
-/* FOP: MKDIR */
-
-int32_t
-glupy_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)
-{
- glupy_private_t *priv = this->private;
- PyGILState_STATE gstate;
- int32_t ret;
-
- if (!priv->cbks[GLUPY_MKDIR]) {
- goto unwind;
- }
-
- gstate = glupy_enter();
- ret = ((fop_mkdir_cbk_t)(priv->cbks[GLUPY_MKDIR]))(
- frame, cookie, this, op_ret, op_errno,
- inode, buf, preparent, postparent, xdata);
- glupy_leave(gstate);
-
- return ret;
-
-unwind:
- frame->local = NULL;
- STACK_UNWIND_STRICT (mkdir, frame, op_ret, op_errno, inode, buf,
- preparent, postparent, xdata);
- return 0;
-}
-
-int32_t
-glupy_mkdir (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
- mode_t umask, dict_t *xdata)
-{
- glupy_private_t *priv = this->private;
- PyGILState_STATE gstate;
- int32_t ret;
- static long next_id = 0;
-
- if (!priv->fops[GLUPY_MKDIR]) {
- goto wind;
- }
-
- gstate = glupy_enter();
- frame->local = (void *)++next_id;
- ret = ((fop_mkdir_t)(priv->fops[GLUPY_MKDIR]))(
- frame, this, loc, mode, umask, xdata);
- glupy_leave(gstate);
-
- return ret;
-
-wind:
- STACK_WIND (frame, glupy_mkdir_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->mkdir, loc, mode, umask,
- xdata);
- return 0;
-}
-
-void
-wind_mkdir (call_frame_t *frame, xlator_t *xl, loc_t *loc, mode_t mode,
- mode_t umask, dict_t *xdata)
-{
-
- xlator_t *this = THIS;
-
- if (!xl || (xl == this)) {
- xl = FIRST_CHILD(this);
- }
-
- STACK_WIND (frame, glupy_mkdir_cbk, xl, xl->fops->mkdir,
- loc, mode, umask, xdata);
-}
-
-void
-unwind_mkdir (call_frame_t *frame, long 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)
-{
- frame->local = NULL;
- STACK_UNWIND_STRICT (mkdir, frame, op_ret, op_errno, inode, buf,
- preparent, postparent, xdata);
-}
-
-void
-set_mkdir_fop (long py_this, fop_mkdir_t fop)
-{
- glupy_private_t *priv = ((xlator_t *)py_this)->private;
-
- priv->fops[GLUPY_MKDIR] = (long)fop;
-}
-
-void
-set_mkdir_cbk (long py_this, fop_mkdir_cbk_t cbk)
-{
- glupy_private_t *priv = ((xlator_t *)py_this)->private;
-
- priv->cbks[GLUPY_MKDIR] = (long)cbk;
-}
-
-
-/* FOP: RMDIR */
-
-int32_t
-glupy_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)
-{
- glupy_private_t *priv = this->private;
- PyGILState_STATE gstate;
- int32_t ret;
-
- if (!priv->cbks[GLUPY_RMDIR]) {
- goto unwind;
- }
-
- gstate = glupy_enter();
- ret = ((fop_rmdir_cbk_t)(priv->cbks[GLUPY_RMDIR]))(
- frame, cookie, this, op_ret, op_errno,
- preparent, postparent, xdata);
- glupy_leave(gstate);
-
- return ret;
-
-unwind:
- frame->local = NULL;
- STACK_UNWIND_STRICT (rmdir, frame, op_ret, op_errno, preparent,
- postparent, xdata);
- return 0;
-}
-
-int32_t
-glupy_rmdir (call_frame_t *frame, xlator_t *this, loc_t *loc,
- int xflags, dict_t *xdata)
-{
- glupy_private_t *priv = this->private;
- PyGILState_STATE gstate;
- int32_t ret;
- static long next_id = 0;
-
- if (!priv->fops[GLUPY_RMDIR]) {
- goto wind;
- }
-
- gstate = glupy_enter();
- frame->local = (void *)++next_id;
- ret = ((fop_rmdir_t)(priv->fops[GLUPY_RMDIR]))(
- frame, this, loc, xflags, xdata);
- glupy_leave(gstate);
-
- return ret;
-
-wind:
- STACK_WIND (frame, glupy_rmdir_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->rmdir, loc,
- xflags, xdata);
- return 0;
-}
-
-void
-wind_rmdir (call_frame_t *frame, xlator_t *xl, loc_t *loc,
- int xflags, dict_t *xdata)
-{
-
- xlator_t *this = THIS;
-
- if (!xl || (xl == this)) {
- xl = FIRST_CHILD(this);
- }
-
- STACK_WIND (frame, glupy_rmdir_cbk, xl, xl->fops->rmdir,
- loc, xflags, xdata);
-}
-
-void
-unwind_rmdir (call_frame_t *frame, long cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno,
- struct iatt *preparent, struct iatt *postparent,
- dict_t *xdata)
-{
- frame->local = NULL;
- STACK_UNWIND_STRICT (rmdir, frame, op_ret, op_errno,
- preparent, postparent, xdata);
-}
-
-void
-set_rmdir_fop (long py_this, fop_rmdir_t fop)
-{
- glupy_private_t *priv = ((xlator_t *)py_this)->private;
-
- priv->fops[GLUPY_RMDIR] = (long)fop;
-}
-
-void
-set_rmdir_cbk (long py_this, fop_rmdir_cbk_t cbk)
-{
- glupy_private_t *priv = ((xlator_t *)py_this)->private;
-
- priv->cbks[GLUPY_RMDIR] = (long)cbk;
-}
-
-
-/* NON-FOP-SPECIFIC CODE */
-
-
-long
-get_id (call_frame_t *frame)
-{
- return (long)(frame->local);
-}
-
-uint64_t
-get_rootunique (call_frame_t *frame)
-{
- return frame->root->unique;
-}
-
-int32_t
-mem_acct_init (xlator_t *this)
-{
- int ret = -1;
-
- if (!this)
- return ret;
-
- ret = xlator_mem_acct_init (this, gf_glupy_mt_end);
-
- if (ret != 0) {
- gf_log(this->name, GF_LOG_ERROR, "Memory accounting init"
- " failed");
- return ret;
- }
-
- return ret;
-}
-
-int32_t
-init (xlator_t *this)
-{
- glupy_private_t *priv = NULL;
- char *module_name = NULL;
- PyObject *py_mod_name = NULL;
- PyObject *py_init_func = NULL;
- PyObject *py_args = NULL;
- PyObject *syspath = NULL;
- PyObject *path = NULL;
- PyObject *error_type = NULL;
- PyObject *error_msg = NULL;
- PyObject *error_bt = NULL;
- static gf_boolean_t py_inited = _gf_false;
- void * err_cleanup = &&err_return;
-
- if (dict_get_str(this->options,"module-name",&module_name) != 0) {
- gf_log (this->name, GF_LOG_ERROR, "missing module-name");
- return -1;
- }
-
- priv = GF_CALLOC (1, sizeof (glupy_private_t), gf_glupy_mt_priv);
- if (!priv) {
- goto *err_cleanup;
- }
- this->private = priv;
- err_cleanup = &&err_free_priv;
-
- if (!py_inited) {
- /*
- * This must be done before Py_Initialize(),
- * because it will duplicate the environment,
- * and fail to see later environment updates.
- */
- setenv("PATH_GLUSTERFS_GLUPY_MODULE",
- PATH_GLUSTERFS_GLUPY_MODULE, 1);
-
- Py_Initialize();
- PyEval_InitThreads();
-
- (void)pthread_key_create(&gil_init_key,NULL);
- (void)pthread_setspecific(gil_init_key,(void *)1);
-
- /* PyEval_InitThreads takes this "for" us. No thanks. */
- PyEval_ReleaseLock();
- py_inited = _gf_true;
- }
-
- /* Adjust python's path */
- syspath = PySys_GetObject("path");
- path = PyString_FromString(GLUSTER_PYTHON_PATH);
- PyList_Append(syspath, path);
- Py_DECREF(path);
-
- py_mod_name = PyString_FromString(module_name);
- if (!py_mod_name) {
- gf_log (this->name, GF_LOG_ERROR, "could not create name");
- if (PyErr_Occurred()) {
- PyErr_Fetch (&error_type, &error_msg, &error_bt);
- gf_log (this->name, GF_LOG_ERROR, "Python error: %s",
- PyString_AsString(error_msg));
- }
- goto *err_cleanup;
- }
-
- gf_log (this->name, GF_LOG_DEBUG, "py_mod_name = %s", module_name);
- priv->py_module = PyImport_Import(py_mod_name);
- Py_DECREF(py_mod_name);
- if (!priv->py_module) {
- gf_log (this->name, GF_LOG_ERROR, "Python import of %s failed",
- module_name);
- if (PyErr_Occurred()) {
- PyErr_Fetch (&error_type, &error_msg, &error_bt);
- gf_log (this->name, GF_LOG_ERROR, "Python error: %s",
- PyString_AsString(error_msg));
- }
- goto *err_cleanup;
- }
- gf_log (this->name, GF_LOG_INFO, "Import of %s succeeded", module_name);
- err_cleanup = &&err_deref_module;
-
- py_init_func = PyObject_GetAttrString(priv->py_module, "xlator");
- if (!py_init_func || !PyCallable_Check(py_init_func)) {
- gf_log (this->name, GF_LOG_ERROR, "missing init func");
- if (PyErr_Occurred()) {
- PyErr_Fetch (&error_type, &error_msg, &error_bt);
- gf_log (this->name, GF_LOG_ERROR, "Python error: %s",
- PyString_AsString(error_msg));
- }
- goto *err_cleanup;
- }
- err_cleanup = &&err_deref_init;
-
- py_args = PyTuple_New(1);
- if (!py_args) {
- gf_log (this->name, GF_LOG_ERROR, "could not create args");
- if (PyErr_Occurred()) {
- PyErr_Fetch (&error_type, &error_msg, &error_bt);
- gf_log (this->name, GF_LOG_ERROR, "Python error: %s",
- PyString_AsString(error_msg));
- }
- goto *err_cleanup;
- }
- PyTuple_SetItem(py_args,0,PyLong_FromLong((long)this));
-
- /* TBD: pass in list of children */
- priv->py_xlator = PyObject_CallObject(py_init_func, py_args);
- Py_DECREF(py_args);
- if (!priv->py_xlator) {
- gf_log (this->name, GF_LOG_ERROR, "Python init failed");
- if (PyErr_Occurred()) {
- PyErr_Fetch (&error_type, &error_msg, &error_bt);
- gf_log (this->name, GF_LOG_ERROR, "Python error: %s",
- PyString_AsString(error_msg));
- }
- goto *err_cleanup;
- }
- gf_log (this->name, GF_LOG_DEBUG, "init returned %p", priv->py_xlator);
-
- return 0;
-
-err_deref_init:
- Py_DECREF(py_init_func);
-err_deref_module:
- Py_DECREF(priv->py_module);
-err_free_priv:
- GF_FREE(priv);
-err_return:
- return -1;
-}
-
-void
-fini (xlator_t *this)
-{
- glupy_private_t *priv = this->private;
-
- if (!priv)
- return;
- Py_DECREF(priv->py_xlator);
- Py_DECREF(priv->py_module);
- this->private = NULL;
- GF_FREE (priv);
-
- return;
-}
-
-struct xlator_fops fops = {
- .lookup = glupy_lookup,
- .create = glupy_create,
- .open = glupy_open,
- .readv = glupy_readv,
- .writev = glupy_writev,
- .opendir = glupy_opendir,
- .readdir = glupy_readdir,
- .stat = glupy_stat,
- .fstat = glupy_fstat,
- .setxattr = glupy_setxattr,
- .getxattr = glupy_getxattr,
- .fsetxattr = glupy_fsetxattr,
- .fgetxattr = glupy_fgetxattr,
- .removexattr = glupy_removexattr,
- .fremovexattr = glupy_fremovexattr,
- .link = glupy_link,
- .unlink = glupy_unlink,
- .readlink = glupy_readlink,
- .symlink = glupy_symlink,
- .mkdir = glupy_mkdir,
- .rmdir = glupy_rmdir,
- .statfs = glupy_statfs,
- .readdirp = glupy_readdirp
-};
-
-struct xlator_cbks cbks = {
-};
-
-struct volume_options options[] = {
- { .key = {NULL} },
-};
diff --git a/xlators/features/glupy/src/glupy.h b/xlators/features/glupy/src/glupy.h
deleted file mode 100644
index e61d000b889..00000000000
--- a/xlators/features/glupy/src/glupy.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- Copyright (c) 2006-2014 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 __GLUPY_H__
-#define __GLUPY_H__
-
-#ifndef _CONFIG_H
-#define _CONFIG_H
-#include "config.h"
-#endif
-#include "mem-types.h"
-
-enum {
- GLUPY_LOOKUP = 0,
- GLUPY_CREATE,
- GLUPY_OPEN,
- GLUPY_READV,
- GLUPY_WRITEV,
- GLUPY_OPENDIR,
- GLUPY_READDIR,
- GLUPY_READDIRP,
- GLUPY_STAT,
- GLUPY_FSTAT,
- GLUPY_STATFS,
- GLUPY_SETXATTR,
- GLUPY_GETXATTR,
- GLUPY_FSETXATTR,
- GLUPY_FGETXATTR,
- GLUPY_REMOVEXATTR,
- GLUPY_FREMOVEXATTR,
- GLUPY_LINK,
- GLUPY_UNLINK,
- GLUPY_READLINK,
- GLUPY_SYMLINK,
- GLUPY_MKNOD,
- GLUPY_MKDIR,
- GLUPY_RMDIR,
- GLUPY_N_FUNCS
-};
-
-typedef struct {
- PyObject *py_module;
- PyObject *py_xlator;
- long fops[GLUPY_N_FUNCS];
- long cbks[GLUPY_N_FUNCS];
-} glupy_private_t;
-
-enum gf_glupy_mem_types_ {
- gf_glupy_mt_priv = gf_common_mt_end + 1,
- gf_glupy_mt_end
-};
-
-#endif /* __GLUPY_H__ */
diff --git a/xlators/features/glupy/src/glupy/Makefile.am b/xlators/features/glupy/src/glupy/Makefile.am
deleted file mode 100644
index 573d2da12e1..00000000000
--- a/xlators/features/glupy/src/glupy/Makefile.am
+++ /dev/null
@@ -1,5 +0,0 @@
-# Install __init__.py into the Python site-packages area
-pyglupydir = @BUILD_PYTHON_SITE_PACKAGES@/gluster/glupy
-pyglupy_PYTHON = __init__.py
-
-CLEANFILES =
diff --git a/xlators/features/glupy/src/glupy/__init__.py b/xlators/features/glupy/src/glupy/__init__.py
deleted file mode 100644
index b9fc3700fa6..00000000000
--- a/xlators/features/glupy/src/glupy/__init__.py
+++ /dev/null
@@ -1,852 +0,0 @@
-##
-## Copyright (c) 2006-2014 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.
-##
-
-import sys
-import os
-from ctypes import *
-
-dl = CDLL(os.getenv("PATH_GLUSTERFS_GLUPY_MODULE", ""),RTLD_GLOBAL)
-
-
-class call_frame_t (Structure):
- pass
-
-class dev_t (Structure):
- pass
-
-
-class dict_t (Structure):
- pass
-
-
-class gf_dirent_t (Structure):
- pass
-
-
-class iobref_t (Structure):
- pass
-
-
-class iovec_t (Structure):
- pass
-
-
-class list_head (Structure):
- pass
-
-list_head._fields_ = [
- ("next", POINTER(list_head)),
- ("prev", POINTER(list_head))
- ]
-
-
-class rwxperm_t (Structure):
- _fields_ = [
- ("read", c_uint8, 1),
- ("write", c_uint8, 1),
- ("execn", c_uint8, 1)
- ]
-
-
-class statvfs_t (Structure):
- pass
-
-
-class xlator_t (Structure):
- pass
-
-
-class ia_prot_t (Structure):
- _fields_ = [
- ("suid", c_uint8, 1),
- ("sgid", c_uint8, 1),
- ("sticky", c_uint8, 1),
- ("owner", rwxperm_t),
- ("group", rwxperm_t),
- ("other", rwxperm_t)
- ]
-
-# For checking file type.
-(IA_INVAL, IA_IFREG, IA_IFDIR, IA_IFLNK, IA_IFBLK, IA_IFCHR, IA_IFIFO,
- IA_IFSOCK) = xrange(8)
-
-
-class iatt_t (Structure):
- _fields_ = [
- ("ia_no", c_uint64),
- ("ia_gfid", c_ubyte * 16),
- ("ia_dev", c_uint64),
- ("ia_type", c_uint),
- ("ia_prot", ia_prot_t),
- ("ia_nlink", c_uint32),
- ("ia_uid", c_uint32),
- ("ia_gid", c_uint32),
- ("ia_rdev", c_uint64),
- ("ia_size", c_uint64),
- ("ia_blksize", c_uint32),
- ("ia_blocks", c_uint64),
- ("ia_atime", c_uint32 ),
- ("ia_atime_nsec", c_uint32),
- ("ia_mtime", c_uint32),
- ("ia_mtime_nsec", c_uint32),
- ("ia_ctime", c_uint32),
- ("ia_ctime_nsec", c_uint32)
- ]
-
-
-class mem_pool (Structure):
- _fields_ = [
- ("list", list_head),
- ("hot_count", c_int),
- ("cold_count", c_int),
- ("lock", c_void_p),
- ("padded_sizeof_type", c_ulong),
- ("pool", c_void_p),
- ("pool_end", c_void_p),
- ("real_sizeof_type", c_int),
- ("alloc_count", c_uint64),
- ("pool_misses", c_uint64),
- ("max_alloc", c_int),
- ("curr_stdalloc", c_int),
- ("max_stdalloc", c_int),
- ("name", c_char_p),
- ("global_list", list_head)
- ]
-
-
-class U_ctx_key_inode (Union):
- _fields_ = [
- ("key", c_uint64),
- ("xl_key", POINTER(xlator_t))
- ]
-
-
-class U_ctx_value1 (Union):
- _fields_ = [
- ("value1", c_uint64),
- ("ptr1", c_void_p)
- ]
-
-
-class U_ctx_value2 (Union):
- _fields_ = [
- ("value2", c_uint64),
- ("ptr2", c_void_p)
- ]
-
-class inode_ctx (Structure):
- _anonymous_ = ("u_key","u_value1","u_value2",)
- _fields_ = [
- ("u_key", U_ctx_key_inode),
- ("u_value1", U_ctx_value1),
- ("u_value2", U_ctx_value2)
- ]
-
-class inode_t (Structure):
- pass
-
-class inode_table_t (Structure):
- _fields_ = [
- ("lock", c_void_p),
- ("hashsize", c_size_t),
- ("name", c_char_p),
- ("root", POINTER(inode_t)),
- ("xl", POINTER(xlator_t)),
- ("lru_limit", c_uint32),
- ("inode_hash", POINTER(list_head)),
- ("name_hash", POINTER(list_head)),
- ("active", list_head),
- ("active_size", c_uint32),
- ("lru", list_head),
- ("lru_size", c_uint32),
- ("purge", list_head),
- ("purge_size", c_uint32),
- ("inode_pool", POINTER(mem_pool)),
- ("dentry_pool", POINTER(mem_pool)),
- ("fd_mem_pool", POINTER(mem_pool))
- ]
-
-inode_t._fields_ = [
- ("table", POINTER(inode_table_t)),
- ("gfid", c_ubyte * 16),
- ("lock", c_void_p),
- ("nlookup", c_uint64),
- ("fd_count", c_uint32),
- ("ref", c_uint32),
- ("ia_type", c_uint),
- ("fd_list", list_head),
- ("dentry_list", list_head),
- ("hashv", list_head),
- ("listv", list_head),
- ("ctx", POINTER(inode_ctx))
- ]
-
-
-
-class U_ctx_key_fd (Union):
- _fields_ = [
- ("key", c_uint64),
- ("xl_key", c_void_p)
- ]
-
-class fd_lk_ctx (Structure):
- _fields_ = [
- ("lk_list", list_head),
- ("ref", c_int),
- ("lock", c_void_p)
- ]
-
-class fd_ctx (Structure):
- _anonymous_ = ("u_key","u_value1")
- _fields_ = [
- ("u_key", U_ctx_key_fd),
- ("u_value1", U_ctx_value1)
- ]
-
-class fd_t (Structure):
- _fields_ = [
- ("pid", c_uint64),
- ("flags", c_int32),
- ("refcount", c_int32),
- ("inode_list", list_head),
- ("inode", POINTER(inode_t)),
- ("lock", c_void_p),
- ("ctx", POINTER(fd_ctx)),
- ("xl_count", c_int),
- ("lk_ctx", POINTER(fd_lk_ctx)),
- ("anonymous", c_uint)
- ]
-
-class loc_t (Structure):
- _fields_ = [
- ("path", c_char_p),
- ("name", c_char_p),
- ("inode", POINTER(inode_t)),
- ("parent", POINTER(inode_t)),
- ("gfid", c_ubyte * 16),
- ("pargfid", c_ubyte * 16),
- ]
-
-
-
-def _init_op (a_class, fop, cbk, wind, unwind):
- # Decorators, used by translators. We could pass the signatures as
- # parameters, but it's actually kind of nice to keep them around for
- # inspection.
- a_class.fop_type = apply(CFUNCTYPE,a_class.fop_sig)
- a_class.cbk_type = apply(CFUNCTYPE,a_class.cbk_sig)
- # Dispatch-function registration.
- fop.restype = None
- fop.argtypes = [ c_long, a_class.fop_type ]
- # Callback-function registration.
- cbk.restype = None
- cbk.argtypes = [ c_long, a_class.cbk_type ]
- # STACK_WIND function.
- wind.restype = None
- wind.argtypes = list(a_class.fop_sig[1:])
- # STACK_UNWIND function.
- unwind.restype = None
- unwind.argtypes = list(a_class.cbk_sig[1:])
-
-class OpLookup:
- fop_sig = (c_int, POINTER(call_frame_t), POINTER(xlator_t),
- POINTER(loc_t), POINTER(dict_t))
- cbk_sig = (c_int, POINTER(call_frame_t), c_long, POINTER(xlator_t),
- c_int, c_int, POINTER(inode_t), POINTER(iatt_t),
- POINTER(dict_t), POINTER(iatt_t))
-_init_op (OpLookup, dl.set_lookup_fop, dl.set_lookup_cbk,
- dl.wind_lookup, dl.unwind_lookup)
-
-class OpCreate:
- fop_sig = (c_int, POINTER(call_frame_t), POINTER(xlator_t),
- POINTER(loc_t), c_int, c_uint, c_uint, POINTER(fd_t),
- POINTER(dict_t))
- cbk_sig = (c_int, POINTER(call_frame_t), c_long, POINTER(xlator_t),
- c_int, c_int, POINTER(fd_t), POINTER(inode_t),
- POINTER(iatt_t), POINTER(iatt_t), POINTER(iatt_t),
- POINTER(dict_t))
-_init_op (OpCreate, dl.set_create_fop, dl.set_create_cbk,
- dl.wind_create, dl.unwind_create)
-
-class OpOpen:
- fop_sig = (c_int, POINTER(call_frame_t), POINTER(xlator_t),
- POINTER(loc_t), c_int, POINTER(fd_t), POINTER(dict_t))
- cbk_sig = (c_int, POINTER(call_frame_t), c_long, POINTER(xlator_t),
- c_int, c_int, POINTER(fd_t), POINTER(dict_t))
-_init_op (OpOpen, dl.set_open_fop, dl.set_open_cbk,
- dl.wind_open, dl.unwind_open)
-
-class OpReadv:
- fop_sig = (c_int, POINTER(call_frame_t), POINTER(xlator_t),
- POINTER(fd_t), c_size_t, c_long, c_uint32, POINTER(dict_t))
- cbk_sig = (c_int, POINTER(call_frame_t), c_long, POINTER(xlator_t),
- c_int, c_int, POINTER(iovec_t), c_int, POINTER(iatt_t),
- POINTER(iobref_t), POINTER(dict_t))
-_init_op (OpReadv, dl.set_readv_fop, dl.set_readv_cbk,
- dl.wind_readv, dl.unwind_readv)
-class OpWritev:
- fop_sig = (c_int, POINTER(call_frame_t), POINTER(xlator_t),
- POINTER(fd_t), POINTER(iovec_t), c_int, c_long, c_uint32,
- POINTER(iobref_t), POINTER(dict_t))
- cbk_sig = (c_int, POINTER(call_frame_t), c_long, POINTER(xlator_t),
- c_int, c_int, POINTER(iatt_t), POINTER(iatt_t),
- POINTER(dict_t))
-_init_op (OpWritev, dl.set_writev_fop, dl.set_writev_cbk,
- dl.wind_writev, dl.unwind_writev)
-
-class OpOpendir:
- fop_sig = (c_int, POINTER(call_frame_t), POINTER(xlator_t),
- POINTER(loc_t), POINTER(fd_t) ,POINTER(dict_t))
- cbk_sig = (c_int, POINTER(call_frame_t), c_long, POINTER(xlator_t),
- c_int, c_int, POINTER(fd_t), POINTER(dict_t))
-_init_op (OpOpendir, dl.set_opendir_fop, dl.set_opendir_cbk,
- dl.wind_opendir, dl.unwind_opendir)
-
-class OpReaddir:
- fop_sig = (c_int, POINTER(call_frame_t), POINTER(xlator_t),
- POINTER(fd_t), c_size_t, c_long, POINTER(dict_t))
- cbk_sig = (c_int, POINTER(call_frame_t), c_long, POINTER(xlator_t),
- c_int, c_int, POINTER(gf_dirent_t), POINTER(dict_t))
-_init_op (OpReaddir, dl.set_readdir_fop, dl.set_readdir_cbk,
- dl.wind_readdir, dl.unwind_readdir)
-
-class OpReaddirp:
- fop_sig = (c_int, POINTER(call_frame_t), POINTER(xlator_t),
- POINTER(fd_t), c_size_t, c_long, POINTER(dict_t))
- cbk_sig = (c_int, POINTER(call_frame_t), c_long, POINTER(xlator_t),
- c_int, c_int, POINTER(gf_dirent_t), POINTER(dict_t))
-_init_op (OpReaddirp, dl.set_readdirp_fop, dl.set_readdirp_cbk,
- dl.wind_readdirp, dl.unwind_readdirp)
-
-class OpStat:
- fop_sig = (c_int, POINTER(call_frame_t), POINTER(xlator_t),
- POINTER(loc_t), POINTER(dict_t))
- cbk_sig = (c_int, POINTER(call_frame_t), c_long, POINTER(xlator_t),
- c_int, c_int, POINTER(iatt_t), POINTER(dict_t))
-_init_op (OpStat, dl.set_stat_fop, dl.set_stat_cbk,
- dl.wind_stat, dl.unwind_stat)
-
-class OpFstat:
- fop_sig = (c_int, POINTER(call_frame_t), POINTER(xlator_t),
- POINTER(fd_t), POINTER(dict_t))
- cbk_sig = (c_int, POINTER(call_frame_t), c_long, POINTER(xlator_t),
- c_int, c_int, POINTER(iatt_t), POINTER(dict_t))
-_init_op (OpFstat, dl.set_fstat_fop, dl.set_fstat_cbk,
- dl.wind_fstat, dl.unwind_fstat)
-
-class OpStatfs:
- fop_sig = (c_int, POINTER(call_frame_t), POINTER(xlator_t),
- POINTER(loc_t), POINTER(dict_t))
- cbk_sig = (c_int, POINTER(call_frame_t), c_long, POINTER(xlator_t),
- c_int, c_int, POINTER(statvfs_t), POINTER(dict_t))
-_init_op (OpStatfs, dl.set_statfs_fop, dl.set_statfs_cbk,
- dl.wind_statfs, dl.unwind_statfs)
-
-
-class OpSetxattr:
- fop_sig = (c_int, POINTER(call_frame_t), POINTER(xlator_t),
- POINTER(loc_t), POINTER(dict_t), c_int32,
- POINTER (dict_t))
- cbk_sig = (c_int, POINTER(call_frame_t), c_long, POINTER(xlator_t),
- c_int, c_int, POINTER(dict_t))
-_init_op (OpSetxattr, dl.set_setxattr_fop, dl.set_setxattr_cbk,
- dl.wind_setxattr, dl.unwind_setxattr)
-
-class OpGetxattr:
- fop_sig = (c_int, POINTER(call_frame_t), POINTER(xlator_t),
- POINTER(loc_t), c_char_p, POINTER (dict_t))
- cbk_sig = (c_int, POINTER(call_frame_t), c_long, POINTER(xlator_t),
- c_int, c_int, POINTER(dict_t), POINTER(dict_t))
-_init_op (OpGetxattr, dl.set_getxattr_fop, dl.set_getxattr_cbk,
- dl.wind_getxattr, dl.unwind_getxattr)
-
-class OpFsetxattr:
- fop_sig = (c_int, POINTER(call_frame_t), POINTER(xlator_t),
- POINTER(fd_t), POINTER(dict_t), c_int32,
- POINTER (dict_t))
- cbk_sig = (c_int, POINTER(call_frame_t), c_long, POINTER(xlator_t),
- c_int, c_int, POINTER(dict_t))
-_init_op (OpFsetxattr, dl.set_fsetxattr_fop, dl.set_fsetxattr_cbk,
- dl.wind_fsetxattr, dl.unwind_fsetxattr)
-
-class OpFgetxattr:
- fop_sig = (c_int, POINTER(call_frame_t), POINTER(xlator_t),
- POINTER(fd_t), c_char_p, POINTER (dict_t))
- cbk_sig = (c_int, POINTER(call_frame_t), c_long, POINTER(xlator_t),
- c_int, c_int, POINTER(dict_t), POINTER(dict_t))
-_init_op (OpFgetxattr, dl.set_fgetxattr_fop, dl.set_fgetxattr_cbk,
- dl.wind_fgetxattr, dl.unwind_fgetxattr)
-
-class OpRemovexattr:
- fop_sig = (c_int, POINTER(call_frame_t), POINTER(xlator_t),
- POINTER(loc_t), c_char_p, POINTER(dict_t))
- cbk_sig = (c_int, POINTER(call_frame_t), c_long, POINTER(xlator_t),
- c_int, c_int, POINTER(dict_t))
-_init_op (OpRemovexattr, dl.set_removexattr_fop, dl.set_removexattr_cbk,
- dl.wind_removexattr, dl.unwind_removexattr)
-
-
-class OpFremovexattr:
- fop_sig = (c_int, POINTER(call_frame_t), POINTER(xlator_t),
- POINTER(fd_t), c_char_p, POINTER(dict_t))
- cbk_sig = (c_int, POINTER(call_frame_t), c_long, POINTER(xlator_t),
- c_int, c_int, POINTER(dict_t))
-_init_op (OpFremovexattr, dl.set_fremovexattr_fop, dl.set_fremovexattr_cbk,
- dl.wind_fremovexattr, dl.unwind_fremovexattr)
-
-class OpLink:
- fop_sig = (c_int, POINTER(call_frame_t), POINTER(xlator_t),
- POINTER(loc_t), POINTER(loc_t), POINTER(dict_t))
- cbk_sig = (c_int, POINTER(call_frame_t), c_long, POINTER(xlator_t),
- c_int, c_int, POINTER(inode_t), POINTER(iatt_t),
- POINTER(iatt_t), POINTER(iatt_t), POINTER(dict_t))
-_init_op (OpLink, dl.set_link_fop, dl.set_link_cbk,
- dl.wind_link, dl.unwind_link)
-
-class OpSymlink:
- fop_sig = (c_int, POINTER(call_frame_t), POINTER(xlator_t),
- c_char_p, POINTER(loc_t), c_uint, POINTER(dict_t))
- cbk_sig = (c_int, POINTER(call_frame_t), c_long, POINTER(xlator_t),
- c_int, c_int, POINTER(inode_t), POINTER(iatt_t),
- POINTER(iatt_t), POINTER(iatt_t), POINTER(dict_t))
-_init_op (OpSymlink, dl.set_symlink_fop, dl.set_symlink_cbk,
- dl.wind_symlink, dl.unwind_symlink)
-
-class OpUnlink:
- fop_sig = (c_int, POINTER(call_frame_t), POINTER(xlator_t),
- POINTER(loc_t), c_int, POINTER(dict_t))
- cbk_sig = (c_int, POINTER(call_frame_t), c_long, POINTER(xlator_t),
- c_int, c_int, POINTER(iatt_t), POINTER(iatt_t),
- POINTER(dict_t))
-_init_op (OpUnlink, dl.set_unlink_fop, dl.set_unlink_cbk,
- dl.wind_unlink, dl.unwind_unlink)
-
-class OpReadlink:
- fop_sig = (c_int, POINTER(call_frame_t), POINTER(xlator_t),
- POINTER(loc_t), c_size_t, POINTER(dict_t))
- cbk_sig = (c_int, POINTER(call_frame_t), c_long, POINTER(xlator_t),
- c_int, c_int, c_char_p, POINTER(iatt_t), POINTER(dict_t))
-_init_op (OpReadlink, dl.set_readlink_fop, dl.set_readlink_cbk,
- dl.wind_readlink, dl.unwind_readlink)
-
-class OpMkdir:
- fop_sig = (c_int, POINTER(call_frame_t), POINTER(xlator_t),
- POINTER(loc_t), c_uint, c_uint, POINTER(dict_t))
- cbk_sig = (c_int, POINTER(call_frame_t), c_long, POINTER(xlator_t),
- c_int, c_int, POINTER(inode_t), POINTER(iatt_t),
- POINTER(iatt_t), POINTER(iatt_t), POINTER(dict_t))
-_init_op (OpMkdir, dl.set_mkdir_fop, dl.set_mkdir_cbk,
- dl.wind_mkdir, dl.unwind_mkdir)
-
-class OpRmdir:
- fop_sig = (c_int, POINTER(call_frame_t), POINTER(xlator_t),
- POINTER(loc_t), c_int, POINTER(dict_t))
- cbk_sig = (c_int, POINTER(call_frame_t), c_long, POINTER(xlator_t),
- c_int, c_int, POINTER(iatt_t), POINTER(iatt_t),
- POINTER(dict_t))
-_init_op (OpRmdir, dl.set_rmdir_fop, dl.set_rmdir_cbk,
- dl.wind_rmdir, dl.unwind_rmdir)
-
-
-class Translator:
- def __init__ (self, c_this):
- # This is only here to keep references to the stubs we create,
- # because ctypes doesn't and glupy.so can't because it doesn't
- # get a pointer to the actual Python object. It's a dictionary
- # instead of a list in case we ever allow changing fops/cbks
- # after initialization and need to look them up.
- self.stub_refs = {}
- funcs = dir(self.__class__)
- if "lookup_fop" in funcs:
- @OpLookup.fop_type
- def stub (frame, this, loc, xdata, s=self):
- return s.lookup_fop (frame, this, loc, xdata)
- self.stub_refs["lookup_fop"] = stub
- dl.set_lookup_fop(c_this,stub)
- if "lookup_cbk" in funcs:
- @OpLookup.cbk_type
- def stub (frame, cookie, this, op_ret, op_errno, inode,
- buf, xdata, postparent, s=self):
- return s.lookup_cbk(frame, cookie, this, op_ret,
- op_errno, inode, buf, xdata,
- postparent)
- self.stub_refs["lookup_cbk"] = stub
- dl.set_lookup_cbk(c_this,stub)
- if "create_fop" in funcs:
- @OpCreate.fop_type
- def stub (frame, this, loc, flags, mode, umask, fd,
- xdata, s=self):
- return s.create_fop (frame, this, loc, flags,
- mode, umask, fd, xdata)
- self.stub_refs["create_fop"] = stub
- dl.set_create_fop(c_this,stub)
- if "create_cbk" in funcs:
- @OpCreate.cbk_type
- def stub (frame, cookie, this, op_ret, op_errno, fd,
- inode, buf, preparent, postparent, xdata,
- s=self):
- return s.create_cbk (frame, cookie, this,
- op_ret, op_errno, fd,
- inode, buf, preparent,
- postparent, xdata)
- self.stub_refs["create_cbk"] = stub
- dl.set_create_cbk(c_this,stub)
- if "open_fop" in funcs:
- @OpOpen.fop_type
- def stub (frame, this, loc, flags, fd,
- xdata, s=self):
- return s.open_fop (frame, this, loc, flags,
- fd, xdata)
- self.stub_refs["open_fop"] = stub
- dl.set_open_fop(c_this,stub)
- if "open_cbk" in funcs:
- @OpOpen.cbk_type
- def stub (frame, cookie, this, op_ret, op_errno, fd,
- xdata, s=self):
- return s.open_cbk (frame, cookie, this,
- op_ret, op_errno, fd,
- xdata)
- self.stub_refs["open_cbk"] = stub
- dl.set_open_cbk(c_this,stub)
- if "readv_fop" in funcs:
- @OpReadv.fop_type
- def stub (frame, this, fd, size, offset, flags,
- xdata, s=self):
- return s.readv_fop (frame, this, fd, size,
- offset, flags, xdata)
- self.stub_refs["readv_fop"] = stub
- dl.set_readv_fop(c_this,stub)
- if "readv_cbk" in funcs:
- @OpReadv.cbk_type
- def stub (frame, cookie, this, op_ret, op_errno,
- vector, count, stbuf, iobref, xdata,
- s=self):
- return s.readv_cbk (frame, cookie, this,
- op_ret, op_errno, vector,
- count, stbuf, iobref,
- xdata)
- self.stub_refs["readv_cbk"] = stub
- dl.set_readv_cbk(c_this,stub)
- if "writev_fop" in funcs:
- @OpWritev.fop_type
- def stub (frame, this, fd, vector, count,
- offset, flags, iobref, xdata, s=self):
- return s.writev_fop (frame, this, fd, vector,
- count, offset, flags,
- iobref, xdata)
- self.stub_refs["writev_fop"] = stub
- dl.set_writev_fop(c_this,stub)
- if "writev_cbk" in funcs:
- @OpWritev.cbk_type
- def stub (frame, cookie, this, op_ret, op_errno,
- prebuf, postbuf, xdata, s=self):
- return s.writev_cbk (frame, cookie, this,
- op_ret, op_errno, prebuf,
- postbuf, xdata)
- self.stub_refs["writev_cbk"] = stub
- dl.set_writev_cbk(c_this,stub)
- if "opendir_fop" in funcs:
- @OpOpendir.fop_type
- def stub (frame, this, loc, fd, xdata, s=self):
- return s.opendir_fop (frame, this, loc, fd,
- xdata)
- self.stub_refs["opendir_fop"] = stub
- dl.set_opendir_fop(c_this,stub)
- if "opendir_cbk" in funcs:
- @OpOpendir.cbk_type
- def stub (frame, cookie, this, op_ret, op_errno, fd,
- xdata, s=self):
- return s.opendir_cbk(frame, cookie, this,
- op_ret, op_errno, fd,
- xdata)
- self.stub_refs["opendir_cbk"] = stub
- dl.set_opendir_cbk(c_this,stub)
- if "readdir_fop" in funcs:
- @OpReaddir.fop_type
- def stub (frame, this, fd, size, offset, xdata, s=self):
- return s.readdir_fop (frame, this, fd, size,
- offset, xdata)
- self.stub_refs["readdir_fop"] = stub
- dl.set_readdir_fop(c_this,stub)
- if "readdir_cbk" in funcs:
- @OpReaddir.cbk_type
- def stub (frame, cookie, this, op_ret, op_errno,
- entries, xdata, s=self):
- return s.readdir_cbk(frame, cookie, this,
- op_ret, op_errno, entries,
- xdata)
- self.stub_refs["readdir_cbk"] = stub
- dl.set_readdir_cbk(c_this,stub)
- if "readdirp_fop" in funcs:
- @OpReaddirp.fop_type
- def stub (frame, this, fd, size, offset, xdata, s=self):
- return s.readdirp_fop (frame, this, fd, size,
- offset, xdata)
- self.stub_refs["readdirp_fop"] = stub
- dl.set_readdirp_fop(c_this,stub)
- if "readdirp_cbk" in funcs:
- @OpReaddirp.cbk_type
- def stub (frame, cookie, this, op_ret, op_errno,
- entries, xdata, s=self):
- return s.readdirp_cbk (frame, cookie, this,
- op_ret, op_errno,
- entries, xdata)
- self.stub_refs["readdirp_cbk"] = stub
- dl.set_readdirp_cbk(c_this,stub)
- if "stat_fop" in funcs:
- @OpStat.fop_type
- def stub (frame, this, loc, xdata, s=self):
- return s.stat_fop (frame, this, loc, xdata)
- self.stub_refs["stat_fop"] = stub
- dl.set_stat_fop(c_this,stub)
- if "stat_cbk" in funcs:
- @OpStat.cbk_type
- def stub (frame, cookie, this, op_ret, op_errno, buf,
- xdata, s=self):
- return s.stat_cbk(frame, cookie, this, op_ret,
- op_errno, buf, xdata)
- self.stub_refs["stat_cbk"] = stub
- dl.set_stat_cbk(c_this,stub)
- if "fstat_fop" in funcs:
- @OpFstat.fop_type
- def stub (frame, this, fd, xdata, s=self):
- return s.fstat_fop (frame, this, fd, xdata)
- self.stub_refs["fstat_fop"] = stub
- dl.set_fstat_fop(c_this,stub)
- if "fstat_cbk" in funcs:
- @OpFstat.cbk_type
- def stub (frame, cookie, this, op_ret, op_errno, buf,
- xdata, s=self):
- return s.fstat_cbk(frame, cookie, this, op_ret,
- op_errno, buf, xdata)
- self.stub_refs["fstat_cbk"] = stub
- dl.set_fstat_cbk(c_this,stub)
- if "statfs_fop" in funcs:
- @OpStatfs.fop_type
- def stub (frame, this, loc, xdata, s=self):
- return s.statfs_fop (frame, this, loc, xdata)
- self.stub_refs["statfs_fop"] = stub
- dl.set_statfs_fop(c_this,stub)
- if "statfs_cbk" in funcs:
- @OpStatfs.cbk_type
- def stub (frame, cookie, this, op_ret, op_errno, buf,
- xdata, s=self):
- return s.statfs_cbk (frame, cookie, this,
- op_ret, op_errno, buf,
- xdata)
- self.stub_refs["statfs_cbk"] = stub
- dl.set_statfs_cbk(c_this,stub)
- if "setxattr_fop" in funcs:
- @OpSetxattr.fop_type
- def stub (frame, this, loc, dictionary, flags, xdata,
- s=self):
- return s.setxattr_fop (frame, this, loc,
- dictionary, flags,
- xdata)
- self.stub_refs["setxattr_fop"] = stub
- dl.set_setxattr_fop(c_this,stub)
- if "setxattr_cbk" in funcs:
- @OpSetxattr.cbk_type
- def stub (frame, cookie, this, op_ret, op_errno, xdata,
- s=self):
- return s.setxattr_cbk(frame, cookie, this,
- op_ret, op_errno, xdata)
- self.stub_refs["setxattr_cbk"] = stub
- dl.set_setxattr_cbk(c_this,stub)
- if "getxattr_fop" in funcs:
- @OpGetxattr.fop_type
- def stub (frame, this, loc, name, xdata, s=self):
- return s.getxattr_fop (frame, this, loc, name,
- xdata)
- self.stub_refs["getxattr_fop"] = stub
- dl.set_getxattr_fop(c_this,stub)
- if "getxattr_cbk" in funcs:
- @OpGetxattr.cbk_type
- def stub (frame, cookie, this, op_ret, op_errno,
- dictionary, xdata, s=self):
- return s.getxattr_cbk(frame, cookie, this,
- op_ret, op_errno,
- dictionary, xdata)
- self.stub_refs["getxattr_cbk"] = stub
- dl.set_getxattr_cbk(c_this,stub)
- if "fsetxattr_fop" in funcs:
- @OpFsetxattr.fop_type
- def stub (frame, this, fd, dictionary, flags, xdata,
- s=self):
- return s.fsetxattr_fop (frame, this, fd,
- dictionary, flags,
- xdata)
- self.stub_refs["fsetxattr_fop"] = stub
- dl.set_fsetxattr_fop(c_this,stub)
- if "fsetxattr_cbk" in funcs:
- @OpFsetxattr.cbk_type
- def stub (frame, cookie, this, op_ret, op_errno, xdata,
- s=self):
- return s.fsetxattr_cbk(frame, cookie, this,
- op_ret, op_errno, xdata)
- self.stub_refs["fsetxattr_cbk"] = stub
- dl.set_fsetxattr_cbk(c_this,stub)
- if "fgetxattr_fop" in funcs:
- @OpFgetxattr.fop_type
- def stub (frame, this, fd, name, xdata, s=self):
- return s.fgetxattr_fop (frame, this, fd, name,
- xdata)
- self.stub_refs["fgetxattr_fop"] = stub
- dl.set_fgetxattr_fop(c_this,stub)
- if "fgetxattr_cbk" in funcs:
- @OpFgetxattr.cbk_type
- def stub (frame, cookie, this, op_ret, op_errno,
- dictionary, xdata, s=self):
- return s.fgetxattr_cbk(frame, cookie, this,
- op_ret, op_errno,
- dictionary, xdata)
- self.stub_refs["fgetxattr_cbk"] = stub
- dl.set_fgetxattr_cbk(c_this,stub)
- if "removexattr_fop" in funcs:
- @OpRemovexattr.fop_type
- def stub (frame, this, loc, name, xdata, s=self):
- return s.removexattr_fop (frame, this, loc,
- name, xdata)
- self.stub_refs["removexattr_fop"] = stub
- dl.set_removexattr_fop(c_this,stub)
- if "removexattr_cbk" in funcs:
- @OpRemovexattr.cbk_type
- def stub (frame, cookie, this, op_ret, op_errno,
- xdata, s=self):
- return s.removexattr_cbk(frame, cookie, this,
- op_ret, op_errno,
- xdata)
- self.stub_refs["removexattr_cbk"] = stub
- dl.set_removexattr_cbk(c_this,stub)
- if "fremovexattr_fop" in funcs:
- @OpFremovexattr.fop_type
- def stub (frame, this, fd, name, xdata, s=self):
- return s.fremovexattr_fop (frame, this, fd,
- name, xdata)
- self.stub_refs["fremovexattr_fop"] = stub
- dl.set_fremovexattr_fop(c_this,stub)
- if "fremovexattr_cbk" in funcs:
- @OpFremovexattr.cbk_type
- def stub (frame, cookie, this, op_ret, op_errno,
- xdata, s=self):
- return s.fremovexattr_cbk(frame, cookie, this,
- op_ret, op_errno,
- xdata)
- self.stub_refs["fremovexattr_cbk"] = stub
- dl.set_fremovexattr_cbk(c_this,stub)
- if "link_fop" in funcs:
- @OpLink.fop_type
- def stub (frame, this, oldloc, newloc,
- xdata, s=self):
- return s.link_fop (frame, this, oldloc,
- newloc, xdata)
- self.stub_refs["link_fop"] = stub
- dl.set_link_fop(c_this,stub)
- if "link_cbk" in funcs:
- @OpLink.cbk_type
- def stub (frame, cookie, this, op_ret, op_errno,
- inode, buf, preparent, postparent, xdata,
- s=self):
- return s.link_cbk (frame, cookie, this,
- op_ret, op_errno, inode,
- buf, preparent,
- postparent, xdata)
- self.stub_refs["link_cbk"] = stub
- dl.set_link_cbk(c_this,stub)
- if "symlink_fop" in funcs:
- @OpSymlink.fop_type
- def stub (frame, this, linkname, loc,
- umask, xdata, s=self):
- return s.symlink_fop (frame, this, linkname,
- loc, umask, xdata)
- self.stub_refs["symlink_fop"] = stub
- dl.set_symlink_fop(c_this,stub)
- if "symlink_cbk" in funcs:
- @OpSymlink.cbk_type
- def stub (frame, cookie, this, op_ret, op_errno,
- inode, buf, preparent, postparent, xdata,
- s=self):
- return s.symlink_cbk (frame, cookie, this,
- op_ret, op_errno, inode,
- buf, preparent,
- postparent, xdata)
- self.stub_refs["symlink_cbk"] = stub
- dl.set_symlink_cbk(c_this,stub)
- if "unlink_fop" in funcs:
- @OpUnlink.fop_type
- def stub (frame, this, loc, xflags,
- xdata, s=self):
- return s.unlink_fop (frame, this, loc,
- xflags, xdata)
- self.stub_refs["unlink_fop"] = stub
- dl.set_unlink_fop(c_this,stub)
- if "unlink_cbk" in funcs:
- @OpUnlink.cbk_type
- def stub (frame, cookie, this, op_ret, op_errno,
- preparent, postparent, xdata, s=self):
- return s.unlink_cbk (frame, cookie, this,
- op_ret, op_errno,
- preparent, postparent,
- xdata)
- self.stub_refs["unlink_cbk"] = stub
- dl.set_unlink_cbk(c_this,stub)
- if "readlink_fop" in funcs:
- @OpReadlink.fop_type
- def stub (frame, this, loc, size,
- xdata, s=self):
- return s.readlink_fop (frame, this, loc,
- size, xdata)
- self.stub_refs["readlink_fop"] = stub
- dl.set_readlink_fop(c_this,stub)
- if "readlink_cbk" in funcs:
- @OpReadlink.cbk_type
- def stub (frame, cookie, this, op_ret, op_errno,
- path, buf, xdata, s=self):
- return s.readlink_cbk (frame, cookie, this,
- op_ret, op_errno,
- path, buf, xdata)
- self.stub_refs["readlink_cbk"] = stub
- dl.set_readlink_cbk(c_this,stub)
- if "mkdir_fop" in funcs:
- @OpMkdir.fop_type
- def stub (frame, this, loc, mode, umask, xdata,
- s=self):
- return s.mkdir_fop (frame, this, loc, mode,
- umask, xdata)
- self.stub_refs["mkdir_fop"] = stub
- dl.set_mkdir_fop(c_this,stub)
- if "mkdir_cbk" in funcs:
- @OpMkdir.cbk_type
- def stub (frame, cookie, this, op_ret, op_errno, inode,
- buf, preparent, postparent, xdata, s=self):
- return s.mkdir_cbk (frame, cookie, this,
- op_ret, op_errno, inode,
- buf, preparent,
- postparent, xdata)
- self.stub_refs["mkdir_cbk"] = stub
- dl.set_mkdir_cbk(c_this,stub)
- if "rmdir_fop" in funcs:
- @OpRmdir.fop_type
- def stub (frame, this, loc, xflags,
- xdata, s=self):
- return s.rmdir_fop (frame, this, loc,
- xflags, xdata)
- self.stub_refs["rmdir_fop"] = stub
- dl.set_rmdir_fop(c_this,stub)
- if "rmdir_cbk" in funcs:
- @OpRmdir.cbk_type
- def stub (frame, cookie, this, op_ret, op_errno,
- preparent, postparent, xdata, s=self):
- return s.rmdir_cbk (frame, cookie, this,
- op_ret, op_errno,
- preparent, postparent,
- xdata)
- self.stub_refs["rmdir_cbk"] = stub
- dl.set_rmdir_cbk(c_this,stub)
diff --git a/xlators/features/glupy/src/setup.py.in b/xlators/features/glupy/src/setup.py.in
deleted file mode 100644
index b9ee02c2b4a..00000000000
--- a/xlators/features/glupy/src/setup.py.in
+++ /dev/null
@@ -1,24 +0,0 @@
-from distutils.core import setup
-
-DESC = """GlusterFS is a clustered file-system capable of scaling to
-several petabytes. It aggregates various storage bricks over Infiniband
-RDMA or TCP/IP interconnect into one large parallel network file system.
-GlusterFS is one of the most sophisticated file systems in terms of
-features and extensibility. It borrows a powerful concept called
-Translators from GNU Hurd kernel. Much of the code in GlusterFS is in
-user space and easily manageable.
-
-This package contains Glupy, the Python translator interface for GlusterFS."""
-
-setup(
- name='glusterfs-glupy',
- version='@PACKAGE_VERSION@',
- description='Glupy is the Python translator interface for GlusterFS',
- long_description=DESC,
- author='Gluster Community',
- author_email='gluster-devel@gluster.org',
- license='LGPLv3',
- url='http://gluster.org/',
- package_dir={'gluster':''},
- packages=['gluster']
-)
diff --git a/xlators/features/index/Makefile.am b/xlators/features/index/Makefile.am
deleted file mode 100644
index a985f42a877..00000000000
--- a/xlators/features/index/Makefile.am
+++ /dev/null
@@ -1,3 +0,0 @@
-SUBDIRS = src
-
-CLEANFILES =
diff --git a/xlators/features/index/src/Makefile.am b/xlators/features/index/src/Makefile.am
deleted file mode 100644
index 73bb8972e70..00000000000
--- a/xlators/features/index/src/Makefile.am
+++ /dev/null
@@ -1,17 +0,0 @@
-xlator_LTLIBRARIES = index.la
-xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/features
-
-index_la_LDFLAGS = -module -avoid-version
-
-index_la_SOURCES = index.c
-index_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la
-
-noinst_HEADERS = index.h index-mem-types.h
-
-AM_CPPFLAGS = $(GF_CPPFLAGS) \
- -I$(top_srcdir)/libglusterfs/src -I$(top_srcdir)/rpc/xdr/src \
- -I$(top_srcdir)/rpc/rpc-lib/src
-
-AM_CFLAGS = -Wall $(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 553d492dfbf..00000000000
--- a/xlators/features/index/src/index-mem-types.h
+++ /dev/null
@@ -1,22 +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 __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 50e2e0ab54d..00000000000
--- a/xlators/features/index/src/index.c
+++ /dev/null
@@ -1,1348 +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 "index.h"
-#include "options.h"
-#include "glusterfs3-xdr.h"
-#include "syscall.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 int
-is_index_file_current (char *filename, uuid_t priv_index)
-{
- char *current_index = alloca (strlen ("xattrop-") + GF_UUID_BUF_SIZE);
-
- sprintf (current_index, "xattrop-%s", uuid_utoa(priv_index));
- return (!strcmp(filename, current_index));
-}
-
-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;
-
- if (is_index_file_current (filename, priv->index))
- return;
-
- 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, index_fd_ctx_t *fctx, DIR *dir, off_t off,
- size_t size, gf_dirent_t *entries)
-{
- off_t in_case = -1;
- off_t last_off = 0;
- 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);
-#ifndef GF_LINUX_HOST_OS
- if ((u_long)telldir(dir) != off && off != fctx->dir_eof) {
- gf_log (THIS->name, GF_LOG_ERROR,
- "seekdir(0x%llx) failed on dir=%p: "
- "Invalid argument (offset reused from "
- "another DIR * structure?)", off, dir);
- errno = EINVAL;
- count = -1;
- goto out;
- }
-#endif /* GF_LINUX_HOST_OS */
- }
-
- while (filled <= size) {
- in_case = (u_long)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);
-#ifndef GF_LINUX_HOST_OS
- if ((u_long)telldir(dir) != in_case &&
- in_case != fctx->dir_eof) {
- gf_log (THIS->name, GF_LOG_ERROR,
- "seekdir(0x%llx) failed on dir=%p: "
- "Invalid argument (offset reused from "
- "another DIR * structure?)",
- in_case, dir);
- errno = EINVAL;
- count = -1;
- goto out;
- }
-#endif /* GF_LINUX_HOST_OS */
- 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;
- }
- /*
- * we store the offset of next entry here, which is
- * probably not intended, but code using syncop_readdir()
- * (glfs-heal.c, afr-self-heald.c, pump.c) rely on it
- * for directory read resumption.
- */
- last_off = (u_long)telldir(dir);
- this_entry->d_off = last_off;
- 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;
- /* Remember EOF offset for later detection */
- fctx->dir_eof = last_off;
- }
-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 = sys_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 = sys_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;
-}
-
-static int
-_check_key_is_zero_filled (dict_t *d, char *k, data_t *v,
- void *tmp)
-{
- if (mem_0filled ((const char*)v->data, v->len)) {
- /* -1 means, no more iterations, treat as 'break' */
- return -1;
- }
- return 0;
-}
-
-void
-_index_action (xlator_t *this, inode_t *inode, gf_boolean_t zero_xattr)
-{
- int ret = 0;
- index_inode_ctx_t *ctx = NULL;
-
- 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?"del":"add", 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
-_xattrop_index_action (xlator_t *this, inode_t *inode, dict_t *xattr)
-{
- gf_boolean_t zero_xattr = _gf_true;
- int ret = 0;
-
- ret = dict_foreach (xattr, _check_key_is_zero_filled, NULL);
- if (ret == -1)
- zero_xattr = _gf_false;
- _index_action (this, inode, zero_xattr);
- 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);
-}
-
-static inline gf_boolean_t
-index_xattrop_track (loc_t *loc, gf_xattrop_flags_t flags, dict_t *dict)
-{
- return (flags == GF_XATTROP_ADD_ARRAY);
-}
-
-static 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;
- }
- fctx->dir_eof = -1;
-
- 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)
-{
- //In wind phase bring the gfid into index. This way if the brick crashes
- //just after posix performs xattrop before _cbk reaches index xlator
- //we will still have the gfid in index.
- _index_action (this, frame->local, _gf_false);
-
- 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)
-{
- //In wind phase bring the gfid into index. This way if the brick crashes
- //just after posix performs xattrop before _cbk reaches index xlator
- //we will still have the gfid in index.
- _index_action (this, frame->local, _gf_false);
- 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;
-}
-
-uint64_t
-index_entry_count (xlator_t *this, char *subdir)
-{
- index_priv_t *priv = NULL;
- char index_dir[PATH_MAX];
- DIR *dirp = NULL;
- uint64_t count = 0;
- struct dirent buf;
- struct dirent *entry = NULL;
-
- priv = this->private;
-
- make_index_dir_path (priv->index_basepath, subdir,
- index_dir, sizeof (index_dir));
-
- dirp = opendir (index_dir);
- if (!dirp)
- return 0;
-
- while (readdir_r (dirp, &buf, &entry) == 0) {
- if (!entry)
- break;
- if (!strcmp (entry->d_name, ".") ||
- !strcmp (entry->d_name, ".."))
- continue;
- if (!strncmp (entry->d_name, subdir, strlen (subdir)))
- continue;
- count++;
- }
- closedir (dirp);
-
- return count;
-}
-
-
-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;
- uint64_t count = 0;
-
- priv = this->private;
-
- xattr = dict_new ();
- if (!xattr) {
- ret = -ENOMEM;
- goto done;
- }
-
- if (strcmp (name, GF_XATTROP_INDEX_GFID) == 0) {
- 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;
- }
- } else if (strcmp (name, GF_XATTROP_INDEX_COUNT) == 0) {
- count = index_entry_count (this, XATTROP_SUBDIR);
-
- ret = dict_set_uint64 (xattr, (char *)name, count);
- if (ret) {
- ret = -ENOMEM;
- gf_log (this->name, GF_LOG_ERROR, "xattrop index "
- "count 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, fctx, 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;
- index_priv_t *priv = NULL;
-
- priv = this->private;
-
- if (!name || (strcmp (GF_XATTROP_INDEX_GFID, name) &&
- strcmp (GF_XATTROP_INDEX_COUNT, 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_opendir (call_frame_t *frame, xlator_t *this,
- loc_t *loc, fd_t *fd, dict_t *xdata)
-{
- index_priv_t *priv = NULL;
-
- priv = this->private;
- if (uuid_compare (fd->inode->gfid, priv->xattrop_vgfid))
- goto normal;
-
- frame->local = NULL;
- STACK_UNWIND_STRICT (opendir, frame, 0, 0, fd, NULL);
- return 0;
-
-normal:
- STACK_WIND (frame, default_opendir_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->opendir, loc, fd, xdata);
- 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 = index_dir_create (this, XATTROP_SUBDIR);
- if (ret < 0)
- goto out;
-
- ret = gf_thread_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) {
- ret = closedir (fctx->dir);
- if (ret)
- gf_log (this->name, GF_LOG_ERROR, "closedir error: %s", strerror (errno));
- }
-
- 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,
- .opendir = index_opendir,
- .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 206d280e519..00000000000
--- a/xlators/features/index/src/index.h
+++ /dev/null
@@ -1,60 +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 __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;
- off_t dir_eof;
-} 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 0f79731b415..ab545cb1cab 100644
--- a/xlators/features/locks/src/Makefile.am
+++ b/xlators/features/locks/src/Makefile.am
@@ -1,18 +1,15 @@
xlator_LTLIBRARIES = locks.la
xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/features
-locks_la_LDFLAGS = -module -avoid-version
+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
+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
-AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src
-
-
-AM_CFLAGS = -Wall -fno-strict-aliasing $(GF_CFLAGS)
+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 =
@@ -20,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 75593b8988c..00000000000
--- a/xlators/features/locks/src/clear.c
+++ /dev/null
@@ -1,423 +0,0 @@
-/*
- Copyright (c) 2006-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 <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);
-
- __pl_entrylk_unref (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);
-
- __pl_entrylk_unref (elock);
- }
- }
- pthread_mutex_unlock (&pl_inode->mutex);
-
- grant_blocked_entry_locks (this, pl_inode, 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 511f3f74ae5..00000000000
--- a/xlators/features/locks/src/clear.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- Copyright (c) 2006-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 __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 e0a5f7c0533..9b712bb32bb 100644
--- a/xlators/features/locks/src/common.c
+++ b/xlators/features/locks/src/common.c
@@ -1,12 +1,22 @@
/*
- Copyright (c) 2006-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) 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
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that 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>
@@ -35,20 +45,22 @@ __insert_and_merge (pl_inode_t *pl_inode, posix_lock_t *lock);
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;
- dom = GF_CALLOC (1, sizeof (*dom),
- gf_locks_mt_pl_dom_list_t);
+ dom = CALLOC (1, sizeof (*dom));
if (!dom)
- goto out;
+ return NULL;
- dom->domain = gf_strdup(volume);
- if (!dom->domain)
- goto out;
+
+ dom->domain = strdup(volume);
+ if (!dom->domain) {
+ gf_log ("posix-locks", GF_LOG_TRACE,
+ "Out of Memory");
+ return NULL;
+ }
gf_log ("posix-locks", GF_LOG_TRACE,
"New domain allocated: %s", dom->domain);
@@ -59,12 +71,6 @@ __allocate_domain (const char *volume)
INIT_LIST_HEAD (&dom->inodelk_list);
INIT_LIST_HEAD (&dom->blocked_inodelks);
-out:
- if (dom && (NULL == dom->domain)) {
- GF_FREE (dom);
- dom = NULL;
- }
-
return dom;
}
@@ -76,28 +82,19 @@ get_domain (pl_inode_t *pl_inode, const char *volume)
{
pl_dom_list_t *dom = NULL;
- GF_VALIDATE_OR_GOTO ("posix-locks", pl_inode, out);
- GF_VALIDATE_OR_GOTO ("posix-locks", volume, out);
+ list_for_each_entry (dom, &pl_inode->dom_list, inode_list) {
+ if (strcmp (dom->domain, volume) == 0)
+ goto found;
- 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;
- }
- dom = __allocate_domain (volume);
- if (dom)
- list_add (&dom->inode_list, &pl_inode->dom_list);
}
-unlock:
- pthread_mutex_unlock (&pl_inode->mutex);
- if (dom) {
- gf_log ("posix-locks", GF_LOG_TRACE, "Domain %s found", volume);
- } else {
- gf_log ("posix-locks", GF_LOG_TRACE, "Domain %s not found", volume);
- }
-out:
+
+ dom = allocate_domain(volume);
+
+ if (dom)
+ list_add (&dom->inode_list, &pl_inode->dom_list);
+found:
+
return dom;
}
@@ -107,25 +104,33 @@ fd_to_fdnum (fd_t *fd)
return ((unsigned long) fd);
}
-fd_t *
-fd_from_fdnum (posix_lock_t *lock)
-{
- return ((fd_t *) lock->fd_num);
-}
-
int
__pl_inode_is_empty (pl_inode_t *pl_inode)
{
- return (list_empty (&pl_inode->ext_list));
+ pl_dom_list_t *dom = NULL;
+ int is_empty = 1;
+
+ if (!list_empty (&pl_inode->ext_list))
+ is_empty = 0;
+
+ list_for_each_entry (dom, &pl_inode->dom_list, inode_list) {
+ if (!list_empty (&dom->entrylk_list))
+ is_empty = 0;
+
+ if (!list_empty (&dom->inodelk_list))
+ is_empty = 0;
+ }
+
+ return is_empty;
}
void
pl_print_locker (char *str, int size, xlator_t *this, call_frame_t *frame)
{
- snprintf (str, size, "Pid=%llu, lk-owner=%s, Client=%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),
- frame->root->client,
+ (unsigned long long) frame->root->lk_owner,
+ (void *)frame->root->trans,
(unsigned long long) frame->root->unique);
}
@@ -148,24 +153,25 @@ pl_print_lockee (char *str, int size, fd_t *fd, loc_t *loc)
}
if (loc && loc->path) {
- ipath = gf_strdup (loc->path);
+ ipath = strdup (loc->path);
} else {
ret = inode_path (inode, NULL, &ipath);
if (ret <= 0)
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)
+ FREE (ipath);
}
void
pl_print_lock (char *str, int size, int cmd,
- struct gf_flock *flock, gf_lkowner_t *owner)
+ struct flock *flock, uint64_t owner)
{
char *cmd_str = NULL;
char *type_str = NULL;
@@ -213,17 +219,17 @@ 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);
}
void
pl_trace_in (xlator_t *this, call_frame_t *frame, fd_t *fd, loc_t *loc,
- int cmd, struct gf_flock *flock, const char *domain)
+ int cmd, struct flock *flock, const char *domain)
{
posix_locks_private_t *priv = NULL;
char pl_locker[256];
@@ -240,9 +246,9 @@ 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,
+ gf_log (this->name, GF_LOG_NORMAL,
"[REQUEST] Locker = {%s} Lockee = {%s} Lock = {%s}",
pl_locker, pl_lockee, pl_lock);
}
@@ -271,7 +277,7 @@ pl_print_verdict (char *str, int size, int op_ret, int op_errno)
void
pl_trace_out (xlator_t *this, call_frame_t *frame, fd_t *fd, loc_t *loc,
- int cmd, struct gf_flock *flock, int op_ret, int op_errno, const char *domain)
+ int cmd, struct flock *flock, int op_ret, int op_errno, const char *domain)
{
posix_locks_private_t *priv = NULL;
@@ -290,11 +296,11 @@ 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);
- gf_log (this->name, GF_LOG_INFO,
+ gf_log (this->name, GF_LOG_NORMAL,
"[%s] Locker = {%s} Lockee = {%s} Lock = {%s}",
verdict, pl_locker, pl_lockee, pl_lock);
}
@@ -302,7 +308,7 @@ pl_trace_out (xlator_t *this, call_frame_t *frame, fd_t *fd, loc_t *loc,
void
pl_trace_block (xlator_t *this, call_frame_t *frame, fd_t *fd, loc_t *loc,
- int cmd, struct gf_flock *flock, const char *domain)
+ int cmd, struct flock *flock, const char *domain)
{
posix_locks_private_t *priv = NULL;
@@ -320,9 +326,9 @@ 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,
+ gf_log (this->name, GF_LOG_NORMAL,
"[BLOCKED] Locker = {%s} Lockee = {%s} Lock = {%s}",
pl_locker, pl_lockee, pl_lock);
}
@@ -349,7 +355,7 @@ pl_trace_flush (xlator_t *this, call_frame_t *frame, fd_t *fd)
pl_print_locker (pl_locker, 256, this, frame);
pl_print_lockee (pl_lockee, 256, fd, NULL);
- gf_log (this->name, GF_LOG_INFO,
+ gf_log (this->name, GF_LOG_NORMAL,
"[FLUSH] Locker = {%s} Lockee = {%s}",
pl_locker, pl_lockee);
}
@@ -367,7 +373,7 @@ pl_trace_release (xlator_t *this, fd_t *fd)
pl_print_lockee (pl_lockee, 256, fd, NULL);
- gf_log (this->name, GF_LOG_INFO,
+ gf_log (this->name, GF_LOG_NORMAL,
"[RELEASE] Lockee = {%s}", pl_lockee);
}
@@ -378,7 +384,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);
@@ -392,17 +397,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);
}
@@ -410,79 +411,72 @@ pl_inode_t *
pl_inode_get (xlator_t *this, inode_t *inode)
{
uint64_t tmp_pl_inode = 0;
- pl_inode_t *pl_inode = NULL;
- int ret = 0;
+ pl_inode_t *pl_inode = NULL;
+ mode_t st_mode = 0;
+ int ret = 0;
+
+ 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 = CALLOC (1, sizeof (*pl_inode));
+ if (!pl_inode) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory.");
+ goto out;
+ }
- 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;
- }
+ gf_log (this->name, GF_LOG_TRACE,
+ "Allocating new pl inode");
- gf_log (this->name, GF_LOG_TRACE,
- "Allocating new pl inode");
+ st_mode = inode->st_mode;
+ if ((st_mode & S_ISGID) && !(st_mode & S_IXGRP))
+ pl_inode->mandatory = 1;
- 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);
- uuid_copy (pl_inode->gfid, inode->gfid);
+ pthread_mutex_init (&pl_inode->mutex, NULL);
- __inode_ctx_put (inode, this, (uint64_t)(long)(pl_inode));
- }
-unlock:
- UNLOCK (&inode->lock);
+ INIT_LIST_HEAD (&pl_inode->dom_list);
+ INIT_LIST_HEAD (&pl_inode->ext_list);
+ INIT_LIST_HEAD (&pl_inode->rw_list);
+
+ ret = inode_ctx_put (inode, this, (uint64_t)(long)(pl_inode));
- return pl_inode;
+out:
+ return pl_inode;
}
/* Create a new posix_lock_t */
posix_lock_t *
-new_posix_lock (struct gf_flock *flock, client_t *client, pid_t client_pid,
- gf_lkowner_t *owner, fd_t *fd)
+new_posix_lock (struct flock *flock, transport_t *transport, pid_t client_pid,
+ uint64_t owner, fd_t *fd)
{
- posix_lock_t *lock = NULL;
+ posix_lock_t *lock = NULL;
- GF_VALIDATE_OR_GOTO ("posix-locks", flock, out);
- GF_VALIDATE_OR_GOTO ("posix-locks", client, out);
- GF_VALIDATE_OR_GOTO ("posix-locks", fd, out);
-
- lock = GF_CALLOC (1, sizeof (posix_lock_t),
- gf_locks_mt_posix_lock_t);
- if (!lock) {
- goto out;
- }
+ lock = CALLOC (1, sizeof (posix_lock_t));
+ if (!lock) {
+ return NULL;
+ }
- lock->fl_start = flock->l_start;
- lock->fl_type = flock->l_type;
+ lock->fl_start = flock->l_start;
+ lock->fl_type = flock->l_type;
- if (flock->l_len == 0)
- lock->fl_end = LLONG_MAX;
- else
- lock->fl_end = flock->l_start + flock->l_len - 1;
+ if (flock->l_len == 0)
+ lock->fl_end = LLONG_MAX;
+ else
+ lock->fl_end = flock->l_start + flock->l_len - 1;
- lock->client = client;
+ lock->transport = transport;
lock->fd_num = fd_to_fdnum (fd);
lock->fd = fd;
- lock->client_pid = client_pid;
- lock->owner = *owner;
+ lock->client_pid = client_pid;
+ lock->owner = owner;
- INIT_LIST_HEAD (&lock->list);
+ INIT_LIST_HEAD (&lock->list);
-out:
- return lock;
+ return lock;
}
@@ -490,7 +484,7 @@ out:
void
__delete_lock (pl_inode_t *pl_inode, posix_lock_t *lock)
{
- list_del_init (&lock->list);
+ list_del_init (&lock->list);
}
@@ -498,37 +492,31 @@ __delete_lock (pl_inode_t *pl_inode, posix_lock_t *lock)
void
__destroy_lock (posix_lock_t *lock)
{
- GF_FREE (lock);
+ free (lock);
}
-/* Convert a posix_lock to a struct gf_flock */
+/* Convert a posix_lock to a struct flock */
void
-posix_lock_to_flock (posix_lock_t *lock, struct gf_flock *flock)
+posix_lock_to_flock (posix_lock_t *lock, struct flock *flock)
{
- flock->l_pid = lock->client_pid;
- flock->l_type = lock->fl_type;
- flock->l_start = lock->fl_start;
- flock->l_owner = lock->owner;
+ flock->l_pid = lock->client_pid;
+ flock->l_type = lock->fl_type;
+ flock->l_start = lock->fl_start;
- if (lock->fl_end == LLONG_MAX)
- flock->l_len = 0;
- else
- flock->l_len = lock->fl_end - lock->fl_start + 1;
+ if (lock->fl_end == LLONG_MAX)
+ flock->l_len = 0;
+ else
+ flock->l_len = lock->fl_end - lock->fl_start + 1;
}
/* Insert the lock into the inode's lock list */
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;
+ return;
}
@@ -536,14 +524,14 @@ __insert_lock (pl_inode_t *pl_inode, posix_lock_t *lock)
int
locks_overlap (posix_lock_t *l1, posix_lock_t *l2)
{
- /*
- Note:
- FUSE always gives us absolute offsets, so no need to worry
- about SEEK_CUR or SEEK_END
- */
-
- return ((l1->fl_end >= l2->fl_start) &&
- (l2->fl_end >= l1->fl_start));
+ /*
+ Note:
+ FUSE always gives us absolute offsets, so no need to worry
+ about SEEK_CUR or SEEK_END
+ */
+
+ return ((l1->fl_end >= l2->fl_start) &&
+ (l2->fl_end >= l1->fl_start));
}
@@ -552,8 +540,8 @@ int
same_owner (posix_lock_t *l1, posix_lock_t *l2)
{
- return (is_same_lkowner (&l1->owner, &l2->owner) &&
- (l1->client == l2->client));
+ return ((l1->owner == l2->owner) &&
+ (l1->transport == l2->transport));
}
@@ -562,15 +550,15 @@ same_owner (posix_lock_t *l1, posix_lock_t *l2)
void
__delete_unlck_locks (pl_inode_t *pl_inode)
{
- posix_lock_t *l = NULL;
- posix_lock_t *tmp = NULL;
+ posix_lock_t *l = NULL;
+ posix_lock_t *tmp = NULL;
- list_for_each_entry_safe (l, tmp, &pl_inode->ext_list, list) {
- if (l->fl_type == F_UNLCK) {
- __delete_lock (pl_inode, l);
- __destroy_lock (l);
- }
- }
+ list_for_each_entry_safe (l, tmp, &pl_inode->ext_list, list) {
+ if (l->fl_type == F_UNLCK) {
+ __delete_lock (pl_inode, l);
+ __destroy_lock (l);
+ }
+ }
}
@@ -578,160 +566,86 @@ __delete_unlck_locks (pl_inode_t *pl_inode)
static posix_lock_t *
add_locks (posix_lock_t *l1, posix_lock_t *l2)
{
- posix_lock_t *sum = NULL;
+ posix_lock_t *sum = NULL;
- sum = GF_CALLOC (1, sizeof (posix_lock_t),
- gf_locks_mt_posix_lock_t);
- if (!sum)
- return NULL;
+ sum = CALLOC (1, sizeof (posix_lock_t));
+ if (!sum)
+ return NULL;
- sum->fl_start = min (l1->fl_start, l2->fl_start);
- sum->fl_end = max (l1->fl_end, l2->fl_end);
+ sum->fl_start = min (l1->fl_start, l2->fl_start);
+ sum->fl_end = max (l1->fl_end, l2->fl_end);
- return sum;
+ return sum;
}
/* Subtract two locks */
struct _values {
- posix_lock_t *locks[3];
+ posix_lock_t *locks[3];
};
/* {big} must always be contained inside {small} */
static struct _values
subtract_locks (posix_lock_t *big, posix_lock_t *small)
{
-
- struct _values v = { .locks = {0, 0, 0} };
-
- if ((big->fl_start == small->fl_start) &&
- (big->fl_end == small->fl_end)) {
- /* both edges coincide with big */
- v.locks[0] = GF_CALLOC (1, sizeof (posix_lock_t),
- gf_locks_mt_posix_lock_t);
- if (!v.locks[0])
- goto out;
- memcpy (v.locks[0], big, sizeof (posix_lock_t));
- v.locks[0]->fl_type = small->fl_type;
- goto done;
- }
-
- if ((small->fl_start > big->fl_start) &&
- (small->fl_end < big->fl_end)) {
- /* both edges lie inside big */
- v.locks[0] = GF_CALLOC (1, sizeof (posix_lock_t),
- gf_locks_mt_posix_lock_t);
- if (!v.locks[0])
- goto out;
-
- v.locks[1] = GF_CALLOC (1, sizeof (posix_lock_t),
- gf_locks_mt_posix_lock_t);
- if (!v.locks[1])
- goto out;
-
- v.locks[2] = GF_CALLOC (1, sizeof (posix_lock_t),
- gf_locks_mt_posix_lock_t);
- if (!v.locks[1])
- goto out;
-
- memcpy (v.locks[0], big, sizeof (posix_lock_t));
- v.locks[0]->fl_end = small->fl_start - 1;
-
- memcpy (v.locks[1], small, sizeof (posix_lock_t));
-
- memcpy (v.locks[2], big, sizeof (posix_lock_t));
- v.locks[2]->fl_start = small->fl_end + 1;
- goto done;
-
- }
-
- /* one edge coincides with big */
- if (small->fl_start == big->fl_start) {
- v.locks[0] = GF_CALLOC (1, sizeof (posix_lock_t),
- gf_locks_mt_posix_lock_t);
- if (!v.locks[0])
- goto out;
-
- v.locks[1] = GF_CALLOC (1, sizeof (posix_lock_t),
- gf_locks_mt_posix_lock_t);
- if (!v.locks[1])
- goto out;
-
- memcpy (v.locks[0], big, sizeof (posix_lock_t));
- v.locks[0]->fl_start = small->fl_end + 1;
-
- memcpy (v.locks[1], small, sizeof (posix_lock_t));
- goto done;
- }
-
- if (small->fl_end == big->fl_end) {
- v.locks[0] = GF_CALLOC (1, sizeof (posix_lock_t),
- gf_locks_mt_posix_lock_t);
- if (!v.locks[0])
- goto out;
-
- v.locks[1] = GF_CALLOC (1, sizeof (posix_lock_t),
- gf_locks_mt_posix_lock_t);
- if (!v.locks[1])
- goto out;
-
- memcpy (v.locks[0], big, sizeof (posix_lock_t));
- v.locks[0]->fl_end = small->fl_start - 1;
-
- memcpy (v.locks[1], small, sizeof (posix_lock_t));
- goto done;
- }
-
- GF_ASSERT (0);
- gf_log ("posix-locks", GF_LOG_ERROR, "Unexpected case in subtract_locks");
-
-out:
- if (v.locks[0]) {
- GF_FREE (v.locks[0]);
- v.locks[0] = NULL;
- }
- if (v.locks[1]) {
- GF_FREE (v.locks[1]);
- v.locks[1] = NULL;
- }
- if (v.locks[2]) {
- GF_FREE (v.locks[2]);
- v.locks[2] = NULL;
+ struct _values v = { .locks = {0, 0, 0} };
+
+ if ((big->fl_start == small->fl_start) &&
+ (big->fl_end == small->fl_end)) {
+ /* both edges coincide with big */
+ v.locks[0] = CALLOC (1, sizeof (posix_lock_t));
+ ERR_ABORT (v.locks[0]);
+ memcpy (v.locks[0], big, sizeof (posix_lock_t));
+ v.locks[0]->fl_type = small->fl_type;
+ }
+ else if ((small->fl_start > big->fl_start) &&
+ (small->fl_end < big->fl_end)) {
+ /* both edges lie inside big */
+ v.locks[0] = CALLOC (1, sizeof (posix_lock_t));
+ ERR_ABORT (v.locks[0]);
+ v.locks[1] = CALLOC (1, sizeof (posix_lock_t));
+ ERR_ABORT (v.locks[1]);
+ v.locks[2] = CALLOC (1, sizeof (posix_lock_t));
+ ERR_ABORT (v.locks[2]);
+
+ memcpy (v.locks[0], big, sizeof (posix_lock_t));
+ v.locks[0]->fl_end = small->fl_start - 1;
+
+ memcpy (v.locks[1], small, sizeof (posix_lock_t));
+ memcpy (v.locks[2], big, sizeof (posix_lock_t));
+ v.locks[2]->fl_start = small->fl_end + 1;
+ }
+ /* one edge coincides with big */
+ else if (small->fl_start == big->fl_start) {
+ v.locks[0] = CALLOC (1, sizeof (posix_lock_t));
+ ERR_ABORT (v.locks[0]);
+ v.locks[1] = CALLOC (1, sizeof (posix_lock_t));
+ ERR_ABORT (v.locks[1]);
+
+ memcpy (v.locks[0], big, sizeof (posix_lock_t));
+ v.locks[0]->fl_start = small->fl_end + 1;
+
+ memcpy (v.locks[1], small, sizeof (posix_lock_t));
+ }
+ else if (small->fl_end == big->fl_end) {
+ v.locks[0] = CALLOC (1, sizeof (posix_lock_t));
+ ERR_ABORT (v.locks[0]);
+ v.locks[1] = CALLOC (1, sizeof (posix_lock_t));
+ ERR_ABORT (v.locks[1]);
+
+ memcpy (v.locks[0], big, sizeof (posix_lock_t));
+ v.locks[0]->fl_end = small->fl_start - 1;
+
+ memcpy (v.locks[1], small, sizeof (posix_lock_t));
+ }
+ else {
+ gf_log ("posix-locks", GF_LOG_ERROR,
+ "Unexpected case in subtract_locks. Please send "
+ "a bug report to gluster-devel@nongnu.org");
}
-done:
return v;
}
-static posix_lock_t *
-first_conflicting_overlap (pl_inode_t *pl_inode, posix_lock_t *lock)
-{
- posix_lock_t *l = NULL;
- posix_lock_t *conf = NULL;
-
- pthread_mutex_lock (&pl_inode->mutex);
- {
- list_for_each_entry (l, &pl_inode->ext_list, list) {
- if (l->blocked)
- continue;
-
- if (locks_overlap (l, lock)) {
- if (same_owner (l, lock))
- continue;
-
- if ((l->fl_type == F_WRLCK) ||
- (lock->fl_type == F_WRLCK)) {
- conf = l;
- goto unlock;
- }
- }
- }
- }
-unlock:
- pthread_mutex_unlock (&pl_inode->mutex);
-
- return conf;
-}
-
/*
Start searching from {begin}, and return the first lock that
conflicts, NULL if no conflict
@@ -790,8 +704,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;
@@ -800,7 +712,7 @@ __insert_and_merge (pl_inode_t *pl_inode, posix_lock_t *lock)
sum = add_locks (lock, conf);
sum->fl_type = lock->fl_type;
- sum->client = lock->client;
+ sum->transport = lock->transport;
sum->fd_num = lock->fd_num;
sum->client_pid = lock->client_pid;
sum->owner = lock->owner;
@@ -809,8 +721,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;
@@ -818,7 +728,7 @@ __insert_and_merge (pl_inode_t *pl_inode, posix_lock_t *lock)
sum = add_locks (lock, conf);
sum->fl_type = conf->fl_type;
- sum->client = conf->client;
+ sum->transport = conf->transport;
sum->fd_num = conf->fd_num;
sum->client_pid = conf->client_pid;
sum->owner = conf->owner;
@@ -838,8 +748,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]);
}
@@ -893,8 +801,7 @@ __grant_blocked_locks (xlator_t *this, pl_inode_t *pl_inode, struct list_head *g
list_del_init (&l->list);
if (__is_lock_grantable (pl_inode, l)) {
- conf = GF_CALLOC (1, sizeof (*conf),
- gf_locks_mt_posix_lock_t);
+ conf = CALLOC (1, sizeof (*conf));
if (!conf) {
l->blocked = 1;
@@ -908,9 +815,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);
@@ -946,10 +854,9 @@ 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);
+ FREE (lock);
}
return;
@@ -959,14 +866,14 @@ static int
pl_send_prelock_unlock (xlator_t *this, pl_inode_t *pl_inode,
posix_lock_t *old_lock)
{
- struct gf_flock flock = {0,};
+ struct flock flock = {0,};
posix_lock_t *unlock_lock = NULL;
struct list_head granted_list;
posix_lock_t *tmp = NULL;
posix_lock_t *lock = NULL;
- int ret = -1;
+ int ret = 0;
INIT_LIST_HEAD (&granted_list);
@@ -976,11 +883,15 @@ pl_send_prelock_unlock (xlator_t *this, pl_inode_t *pl_inode,
flock.l_len = old_lock->user_flock.l_len;
- unlock_lock = new_posix_lock (&flock, old_lock->client,
- old_lock->client_pid, &old_lock->owner,
+ unlock_lock = new_posix_lock (&flock, old_lock->transport,
+ old_lock->client_pid, old_lock->owner,
old_lock->fd);
- GF_VALIDATE_OR_GOTO (this->name, unlock_lock, out);
- ret = 0;
+ if (!unlock_lock) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory");
+ ret = -1;
+ goto out;
+ }
__insert_and_merge (pl_inode, unlock_lock);
@@ -992,13 +903,13 @@ 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);
+ FREE (lock);
}
out:
+
return ret;
}
@@ -1012,38 +923,33 @@ pl_setlk (xlator_t *this, pl_inode_t *pl_inode, posix_lock_t *lock,
pthread_mutex_lock (&pl_inode->mutex);
{
- /* Send unlock before the actual lock to
- prevent lock upgrade / downgrade
- problems only if:
- - it is a blocking call
- - it has other conflicting locks
+ /* Send unlock before the actual blocking lock
+ to support lock upgrades / downgrades.
*/
-
- if (can_block &&
- !(__is_lock_grantable (pl_inode, lock))) {
- ret = pl_send_prelock_unlock (this, pl_inode,
- lock);
- if (ret)
- gf_log (this->name, GF_LOG_DEBUG,
- "Could not send pre-lock "
- "unlock");
- }
+ if (can_block) {
+ ret = pl_send_prelock_unlock (this, pl_inode,
+ lock);
+ if (ret)
+ gf_log (this->name, GF_LOG_DEBUG,
+ "Could not send pre-lock "
+ "unlock");
+ }
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;
@@ -1051,10 +957,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;
@@ -1076,7 +982,7 @@ pl_getlk (pl_inode_t *pl_inode, posix_lock_t *lock)
{
posix_lock_t *conf = NULL;
- conf = first_conflicting_overlap (pl_inode, lock);
+ conf = first_overlap (pl_inode, lock);
if (conf == NULL) {
lock->fl_type = F_UNLCK;
@@ -1085,4 +991,3 @@ pl_getlk (pl_inode_t *pl_inode, posix_lock_t *lock)
return conf;
}
-
diff --git a/xlators/features/locks/src/common.h b/xlators/features/locks/src/common.h
index 5ec630ee857..133a4f7227a 100644
--- a/xlators/features/locks/src/common.h
+++ b/xlators/features/locks/src/common.h
@@ -1,41 +1,28 @@
/*
- Copyright (c) 2006-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) 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
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that 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 __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, client=%p"
-#define GRNTD_AT "granted at %s"
-#define BLKD_AT "blocked at %s"
-#define CONN_ID "connection-id=%s"
-#define DUMP_BLKD_FMT DUMP_GEN_FMT", "CONN_ID", "BLKD_AT
-#define DUMP_GRNTD_FMT DUMP_GEN_FMT", "CONN_ID", "GRNTD_AT
-#define DUMP_BLKD_GRNTD_FMT DUMP_GEN_FMT", "CONN_ID", "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, client_t *client, pid_t client_pid,
- gf_lkowner_t *owner, fd_t *fd);
+new_posix_lock (struct flock *flock, transport_t *transport, pid_t client_pid,
+ uint64_t owner, fd_t *fd);
pl_inode_t *
pl_inode_get (xlator_t *this, inode_t *inode);
@@ -51,7 +38,7 @@ void
grant_blocked_locks (xlator_t *this, pl_inode_t *inode);
void
-posix_lock_to_flock (posix_lock_t *lock, struct gf_flock *flock);
+posix_lock_to_flock (posix_lock_t *lock, struct flock *flock);
int
locks_overlap (posix_lock_t *l1, posix_lock_t *l2);
@@ -67,39 +54,34 @@ pl_dom_list_t *
get_domain (pl_inode_t *pl_inode, const char *volume);
void
-grant_blocked_inode_locks (xlator_t *this, pl_inode_t *pl_inode,
- pl_dom_list_t *dom);
+grant_blocked_inode_locks (xlator_t *this, pl_inode_t *pl_inode, pl_dom_list_t *dom);
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,
- pl_dom_list_t *dom);
+ pl_entry_lock_t *unlocked, pl_dom_list_t *dom);
void pl_update_refkeeper (xlator_t *this, inode_t *inode);
int32_t
-__get_inodelk_count (xlator_t *this, pl_inode_t *pl_inode, char *domname);
-int32_t
-get_inodelk_count (xlator_t *this, inode_t *inode, char *domname);
+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,
- int cmd, struct gf_flock *flock, const char *domain);
+ int cmd, struct flock *flock, const char *domain);
void pl_trace_out (xlator_t *this, call_frame_t *frame, fd_t *fd, loc_t *loc,
- int cmd, struct gf_flock *flock, int op_ret, int op_errno, const char *domain);
+ int cmd, struct flock *flock, int op_ret, int op_errno, const char *domain);
void pl_trace_block (xlator_t *this, call_frame_t *frame, fd_t *fd, loc_t *loc,
- int cmd, struct gf_flock *flock, const char *domain);
+ int cmd, struct flock *flock, const char *domain);
void pl_trace_flush (xlator_t *this, call_frame_t *frame, fd_t *fd);
@@ -126,7 +108,7 @@ void
pl_print_locker (char *str, int size, xlator_t *this, call_frame_t *frame);
void
-pl_print_inodelk (char *str, int size, int cmd, struct gf_flock *flock, const char *domain);
+pl_print_inodelk (char *str, int size, int cmd, struct flock *flock, const char *domain);
void
pl_trace_release (xlator_t *this, fd_t *fd);
@@ -134,25 +116,4 @@ pl_trace_release (xlator_t *this, fd_t *fd);
unsigned long
fd_to_fdnum (fd_t *fd);
-fd_t *
-fd_from_fdnum (posix_lock_t *lock);
-
-int
-pl_reserve_setlk (xlator_t *this, pl_inode_t *pl_inode, posix_lock_t *lock,
- int can_block);
-int
-reservelks_equal (posix_lock_t *l1, posix_lock_t *l2);
-
-int
-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);
-
-void __pl_inodelk_unref (pl_inode_lock_t *lock);
-void __pl_entrylk_unref (pl_entry_lock_t *lock);
-
#endif /* __COMMON_H__ */
diff --git a/xlators/features/locks/src/entrylk.c b/xlators/features/locks/src/entrylk.c
index 04ffd6d387b..9109740f33f 100644
--- a/xlators/features/locks/src/entrylk.c
+++ b/xlators/features/locks/src/entrylk.c
@@ -1,12 +1,22 @@
/*
- Copyright (c) 2006-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) 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
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that 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"
@@ -23,58 +33,30 @@
#include "locks.h"
#include "common.h"
-
-void
-__pl_entrylk_unref (pl_entry_lock_t *lock)
-{
- lock->ref--;
- if (!lock->ref) {
- GF_FREE ((char *)lock->basename);
- GF_FREE (lock->connection_id);
- GF_FREE (lock);
- }
-}
-
-
-static void
-__pl_entrylk_ref (pl_entry_lock_t *lock)
-{
- lock->ref++;
-}
-
-
static pl_entry_lock_t *
new_entrylk_lock (pl_inode_t *pinode, const char *basename, entrylk_type type,
- const char *domain, call_frame_t *frame, char *conn_id)
+ transport_t *trans, pid_t client_pid, uint64_t owner, const char *volume)
+
{
- pl_entry_lock_t *newlock = NULL;
+ pl_entry_lock_t *newlock = NULL;
- newlock = GF_CALLOC (1, sizeof (pl_entry_lock_t),
- gf_locks_mt_pl_entry_lock_t);
- if (!newlock) {
- goto out;
- }
+ newlock = CALLOC (1, sizeof (pl_entry_lock_t));
+ if (!newlock) {
+ goto out;
+ }
- newlock->basename = basename ? gf_strdup (basename) : NULL;
- newlock->type = type;
- newlock->client = frame->root->client;
- newlock->client_pid = frame->root->pid;
- newlock->volume = domain;
- newlock->owner = frame->root->lk_owner;
- newlock->frame = frame;
- newlock->this = frame->this;
-
- if (conn_id) {
- newlock->connection_id = gf_strdup (conn_id);
- }
+ newlock->basename = basename ? 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);
- INIT_LIST_HEAD (&newlock->client_list);
+ INIT_LIST_HEAD (&newlock->domain_list);
+ INIT_LIST_HEAD (&newlock->blocked_locks);
- __pl_entrylk_ref (newlock);
out:
- return newlock;
+ return newlock;
}
@@ -94,64 +76,55 @@ out:
static int
names_conflict (const char *n1, const char *n2)
{
- return all_names (n1) || all_names (n2) || !strcmp (n1, n2);
+ return all_names (n1) || all_names (n2) || !strcmp (n1, 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) &&
- (l1->client == l2->client));
-}
-/* Just as in inodelk, allow conflicting name locks from same (lk_owner, conn)*/
-static inline int
-__conflicting_entrylks (pl_entry_lock_t *l1, pl_entry_lock_t *l2)
-{
- if (names_conflict (l1->basename, l2->basename)
- && !__same_entrylk_owner (l1, l2))
- return 1;
-
- return 0;
+ return ((l1->owner == l2->owner) &&
+ (l1->trans == l2->trans));
}
+
/**
- * entrylk_grantable - is this lock grantable?
+ * lock_grantable - is this lock grantable?
* @inode: inode in which to look
* @basename: name we're trying to lock
* @type: type of lock
*/
static pl_entry_lock_t *
-__entrylk_grantable (pl_dom_list_t *dom, pl_entry_lock_t *lock)
+__lock_grantable (pl_dom_list_t *dom, const char *basename, entrylk_type type)
{
- pl_entry_lock_t *tmp = NULL;
+ pl_entry_lock_t *lock = NULL;
- if (list_empty (&dom->entrylk_list))
- return NULL;
+ if (list_empty (&dom->entrylk_list))
+ return NULL;
- list_for_each_entry (tmp, &dom->entrylk_list, domain_list) {
- if (__conflicting_entrylks (tmp, lock))
- return tmp;
- }
+ list_for_each_entry (lock, &dom->entrylk_list, domain_list) {
+ if (names_conflict (lock->basename, basename))
+ return lock;
+ }
- return NULL;
+ return NULL;
}
static pl_entry_lock_t *
-__blocked_entrylk_conflict (pl_dom_list_t *dom, pl_entry_lock_t *lock)
+__blocked_lock_conflict (pl_dom_list_t *dom, const char *basename, entrylk_type type)
{
- pl_entry_lock_t *tmp = NULL;
+ pl_entry_lock_t *lock = NULL;
- if (list_empty (&dom->blocked_entrylks))
- return NULL;
+ if (list_empty (&dom->blocked_entrylks))
+ return NULL;
- list_for_each_entry (tmp, &dom->blocked_entrylks, blocked_locks) {
- if (names_conflict (tmp->basename, lock->basename))
- return lock;
- }
+ list_for_each_entry (lock, &dom->blocked_entrylks, blocked_locks) {
+ if (names_conflict (lock->basename, basename))
+ return lock;
+ }
- return NULL;
+ return NULL;
}
static int
@@ -159,23 +132,23 @@ __owner_has_lock (pl_dom_list_t *dom, pl_entry_lock_t *newlock)
{
pl_entry_lock_t *lock = NULL;
- list_for_each_entry (lock, &dom->entrylk_list, domain_list) {
- if (__same_entrylk_owner (lock, newlock))
- return 1;
- }
+ list_for_each_entry (lock, &dom->entrylk_list, domain_list) {
+ if (__same_entrylk_owner (lock, newlock))
+ return 1;
+ }
- list_for_each_entry (lock, &dom->blocked_entrylks, blocked_locks) {
- if (__same_entrylk_owner (lock, newlock))
- return 1;
- }
+ list_for_each_entry (lock, &dom->blocked_entrylks, blocked_locks) {
+ if (__same_entrylk_owner (lock, newlock))
+ return 1;
+ }
- return 0;
+ return 0;
}
static int
names_equal (const char *n1, const char *n2)
{
- return (n1 == NULL && n2 == NULL) || (n1 && n2 && !strcmp (n1, n2));
+ return (n1 == NULL && n2 == NULL) || (n1 && n2 && !strcmp (n1, n2));
}
void
@@ -239,7 +212,7 @@ entrylk_trace_in (xlator_t *this, call_frame_t *frame, const char *domain,
pl_print_lockee (pl_lockee, 256, fd, loc);
pl_print_entrylk (pl_entrylk, 256, cmd, type, basename, domain);
- gf_log (this->name, GF_LOG_INFO,
+ gf_log (this->name, GF_LOG_NORMAL,
"[REQUEST] Locker = {%s} Lockee = {%s} Lock = {%s}",
pl_locker, pl_lockee, pl_entrylk);
}
@@ -266,7 +239,7 @@ entrylk_trace_out (xlator_t *this, call_frame_t *frame, const char *domain,
pl_print_entrylk (pl_entrylk, 256, cmd, type, basename, domain);
pl_print_verdict (verdict, 32, op_ret, op_errno);
- gf_log (this->name, GF_LOG_INFO,
+ gf_log (this->name, GF_LOG_NORMAL,
"[%s] Locker = {%s} Lockee = {%s} Lock = {%s}",
verdict, pl_locker, pl_lockee, pl_entrylk);
}
@@ -292,7 +265,7 @@ entrylk_trace_block (xlator_t *this, call_frame_t *frame, const char *volume,
pl_print_lockee (pl_lockee, 256, fd, loc);
pl_print_entrylk (pl_entrylk, 256, cmd, type, basename, volume);
- gf_log (this->name, GF_LOG_INFO,
+ gf_log (this->name, GF_LOG_NORMAL,
"[BLOCKED] Locker = {%s} Lockee = {%s} Lock = {%s}",
pl_locker, pl_lockee, pl_entrylk);
}
@@ -310,39 +283,25 @@ entrylk_trace_block (xlator_t *this, call_frame_t *frame, const char *volume,
static pl_entry_lock_t *
__find_most_matching_lock (pl_dom_list_t *dom, const char *basename)
{
- pl_entry_lock_t *lock;
- pl_entry_lock_t *all = NULL;
- pl_entry_lock_t *exact = NULL;
-
- if (list_empty (&dom->entrylk_list))
- return NULL;
-
- list_for_each_entry (lock, &dom->entrylk_list, domain_list) {
- if (all_names (lock->basename))
- all = lock;
- else if (names_equal (lock->basename, basename))
- exact = lock;
- }
-
- return (exact ? exact : all);
-}
-
-static pl_entry_lock_t*
-__find_matching_lock (pl_dom_list_t *dom, pl_entry_lock_t *lock)
-{
- pl_entry_lock_t *tmp = NULL;
+ pl_entry_lock_t *lock;
+ pl_entry_lock_t *all = NULL;
+ pl_entry_lock_t *exact = NULL;
+
+ if (list_empty (&dom->entrylk_list))
+ return NULL;
+
+ list_for_each_entry (lock, &dom->entrylk_list, domain_list) {
+ if (all_names (lock->basename))
+ all = lock;
+ else if (names_equal (lock->basename, basename))
+ exact = lock;
+ }
- list_for_each_entry (tmp, &dom->entrylk_list, domain_list) {
- if (names_equal (lock->basename, tmp->basename)
- && __same_entrylk_owner (lock, tmp)
- && (lock->type == tmp->type))
- return tmp;
- }
- return NULL;
+ return (exact ? exact : all);
}
/**
- * __lock_entrylk - lock a name in a directory
+ * __lock_name - lock a name in a directory
* @inode: inode for the directory in which to lock
* @basename: name of the entry to lock
* if null, lock the entire directory
@@ -353,358 +312,397 @@ __find_matching_lock (pl_dom_list_t *dom, pl_entry_lock_t *lock)
*/
int
-__lock_entrylk (xlator_t *this, pl_inode_t *pinode, pl_entry_lock_t *lock,
- int nonblock, pl_dom_list_t *dom)
+__lock_name (pl_inode_t *pinode, const char *basename, entrylk_type type,
+ call_frame_t *frame, pl_dom_list_t *dom, xlator_t *this, int nonblock)
{
- pl_entry_lock_t *conf = NULL;
- int ret = -EAGAIN;
+ pl_entry_lock_t *lock = NULL;
+ pl_entry_lock_t *conf = NULL;
+ transport_t *trans = NULL;
+ pid_t client_pid = 0;
+ 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, owner, dom->domain);
+ if (!lock) {
+ ret = -ENOMEM;
+ goto out;
+ }
- conf = __entrylk_grantable (dom, lock);
- if (conf) {
- ret = -EAGAIN;
- if (nonblock)
- goto out;
+ conf = __lock_grantable (dom, basename, type);
+ if (conf) {
+ ret = -EAGAIN;
+ if (nonblock)
+ goto out;
- gettimeofday (&lock->blkd_time, NULL);
- list_add_tail (&lock->blocked_locks, &dom->blocked_entrylks);
+ lock->frame = frame;
+ lock->this = this;
- gf_log (this->name, GF_LOG_TRACE,
- "Blocking lock: {pinode=%p, basename=%s}",
- pinode, lock->basename);
+ list_add_tail (&lock->blocked_locks, &dom->blocked_entrylks);
- goto out;
- }
+ gf_log (this->name, GF_LOG_TRACE,
+ "Blocking lock: {pinode=%p, basename=%s}",
+ pinode, basename);
+
+ goto out;
+ }
- /* To prevent blocked locks starvation, check if there are any blocked
- * locks thay may conflict with this lock. If there is then don't grant
- * the lock. BUT grant the lock if the owner already has lock to allow
- * nested locks.
- * Example: SHD from Machine1 takes (gfid, basename=257-length-name)
- * and is granted.
- * SHD from machine2 takes (gfid, basename=NULL) and is blocked.
- * When SHD from Machine1 takes (gfid, basename=NULL) it needs to be
- * granted, without which self-heal can't progress.
- * TODO: Find why 'owner_has_lock' is checked even for blocked locks.
- */
- if (__blocked_entrylk_conflict (dom, lock) && !(__owner_has_lock (dom, lock))) {
+ if ( __blocked_lock_conflict (dom, basename, type) && !(__owner_has_lock (dom, lock))) {
ret = -EAGAIN;
if (nonblock)
goto out;
+ 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_DEBUG,
- "Lock is grantable, but blocking to prevent starvation");
gf_log (this->name, GF_LOG_TRACE,
- "Blocking lock: {pinode=%p, basename=%s}",
- pinode, lock->basename);
+ "Lock is grantable, but blocking to prevent starvation");
+ gf_log (this->name, GF_LOG_TRACE,
+ "Blocking lock: {pinode=%p, basename=%s}",
+ pinode, basename);
- goto out;
+ goto out;
}
+ switch (type) {
- __pl_entrylk_ref (lock);
- gettimeofday (&lock->granted_time, NULL);
- list_add (&lock->domain_list, &dom->entrylk_list);
+ case ENTRYLK_WRLCK:
+ list_add (&lock->domain_list, &dom->entrylk_list);
+ break;
- ret = 0;
+ default:
+
+ gf_log (this->name, GF_LOG_DEBUG,
+ "Invalid type for entrylk specified: %d", type);
+ ret = -EINVAL;
+ goto out;
+ }
+
+ ret = 0;
out:
- return ret;
+ return ret;
}
/**
- * __unlock_entrylk - unlock a name in a directory
+ * __unlock_name - unlock a name in a directory
* @inode: inode for the directory to unlock in
* @basename: name of the entry to unlock
* if null, unlock the entire directory
*/
pl_entry_lock_t *
-__unlock_entrylk (pl_dom_list_t *dom, pl_entry_lock_t *lock)
+__unlock_name (pl_dom_list_t *dom, const char *basename, entrylk_type type)
{
- pl_entry_lock_t *ret_lock = NULL;
+ pl_entry_lock_t *lock = NULL;
+ pl_entry_lock_t *ret_lock = NULL;
- ret_lock = __find_matching_lock (dom, lock);
+ lock = __find_most_matching_lock (dom, basename);
- if (ret_lock) {
- list_del_init (&ret_lock->domain_list);
- } else {
- gf_log ("locks", GF_LOG_ERROR, "unlock on %s "
- "(type=ENTRYLK_WRLCK) attempted but no matching lock "
- "found", lock->basename);
- }
-
- return ret_lock;
-}
+ if (!lock) {
+ gf_log ("locks", GF_LOG_DEBUG,
+ "unlock on %s (type=ENTRYLK_WRLCK) attempted but no matching lock found",
+ basename);
+ goto out;
+ }
-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;
+ if (names_equal (lock->basename, basename)
+ && lock->type == type) {
- 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 = __find_most_matching_lock (dom, basename);
- if (conf && conf->basename) {
- entrylk = 1;
- break;
- }
- }
- }
- pthread_mutex_unlock (&pinode->mutex);
+ if (type == ENTRYLK_WRLCK) {
+ list_del (&lock->domain_list);
+ ret_lock = lock;
+ }
+ } else {
+ gf_log ("locks", GF_LOG_DEBUG,
+ "Unlock for a non-existing lock!");
+ goto out;
+ }
out:
- return entrylk;
+ return ret_lock;
}
+
void
__grant_blocked_entry_locks (xlator_t *this, pl_inode_t *pl_inode,
- pl_dom_list_t *dom, struct list_head *granted)
+ pl_dom_list_t *dom, struct list_head *granted)
{
- int bl_ret = 0;
- pl_entry_lock_t *bl = NULL;
- pl_entry_lock_t *tmp = NULL;
+ int bl_ret = 0;
+ pl_entry_lock_t *bl = NULL;
+ pl_entry_lock_t *tmp = NULL;
struct list_head blocked_list;
INIT_LIST_HEAD (&blocked_list);
list_splice_init (&dom->blocked_entrylks, &blocked_list);
+
+ list_for_each_entry_safe (bl, tmp, &blocked_list,
+ blocked_locks) {
- list_for_each_entry_safe (bl, tmp, &blocked_list, blocked_locks) {
+ list_del_init (&bl->blocked_locks);
- list_del_init (&bl->blocked_locks);
- bl_ret = __lock_entrylk (bl->this, pl_inode, bl, 0, dom);
+ gf_log ("locks", GF_LOG_TRACE,
+ "Trying to unblock: {pinode=%p, basename=%s}",
+ pl_inode, bl->basename);
- if (bl_ret == 0) {
- list_add (&bl->blocked_locks, granted);
- }
- }
- return;
+ bl_ret = __lock_name (pl_inode, bl->basename, bl->type,
+ bl->frame, dom, bl->this, 0);
+
+ if (bl_ret == 0) {
+ list_add (&bl->blocked_locks, granted);
+ } else {
+ if (bl->basename)
+ FREE (bl->basename);
+ FREE (bl);
+ }
+ }
+ return;
}
/* Grants locks if possible which are blocked on a lock */
void
grant_blocked_entry_locks (xlator_t *this, pl_inode_t *pl_inode,
- pl_dom_list_t *dom)
+ pl_entry_lock_t *unlocked, pl_dom_list_t *dom)
{
- struct list_head granted_list;
- pl_entry_lock_t *tmp = NULL;
- pl_entry_lock_t *lock = NULL;
+ struct list_head granted_list;
+ pl_entry_lock_t *tmp = NULL;
+ pl_entry_lock_t *lock = NULL;
- INIT_LIST_HEAD (&granted_list);
+ INIT_LIST_HEAD (&granted_list);
- pthread_mutex_lock (&pl_inode->mutex);
- {
- __grant_blocked_entry_locks (this, pl_inode, dom,
- &granted_list);
- }
- pthread_mutex_unlock (&pl_inode->mutex);
+ pthread_mutex_lock (&pl_inode->mutex);
+ {
+ __grant_blocked_entry_locks (this, pl_inode, dom, &granted_list);
+ }
+ pthread_mutex_unlock (&pl_inode->mutex);
+
+ list_for_each_entry_safe (lock, tmp, &granted_list, blocked_locks) {
+ list_del_init (&lock->blocked_locks);
- list_for_each_entry_safe (lock, tmp, &granted_list, blocked_locks) {
entrylk_trace_out (this, lock->frame, NULL, NULL, NULL,
lock->basename, ENTRYLK_LOCK, lock->type,
0, 0);
- STACK_UNWIND_STRICT (entrylk, lock->frame, 0, 0, NULL);
- lock->frame = NULL;
+ STACK_UNWIND_STRICT (entrylk, lock->frame, 0, 0);
+
+ FREE (lock->basename);
+ FREE (lock);
}
- pthread_mutex_lock (&pl_inode->mutex);
- {
- list_for_each_entry_safe (lock, tmp, &granted_list, blocked_locks) {
- list_del_init (&lock->blocked_locks);
- __pl_entrylk_unref (lock);
+ FREE (unlocked->basename);
+ FREE (unlocked);
+
+ return;
+}
+
+/**
+ * release_entry_locks_for_transport: release all entry locks from this
+ * transport for this loc_t
+ */
+
+static int
+release_entry_locks_for_transport (xlator_t *this, pl_inode_t *pinode,
+ pl_dom_list_t *dom, transport_t *trans)
+{
+ pl_entry_lock_t *lock = NULL;
+ pl_entry_lock_t *tmp = NULL;
+ struct list_head granted;
+ struct list_head released;
+
+ INIT_LIST_HEAD (&granted);
+ INIT_LIST_HEAD (&released);
+
+ pthread_mutex_lock (&pinode->mutex);
+ {
+ list_for_each_entry_safe (lock, tmp, &dom->blocked_entrylks,
+ blocked_locks) {
+ if (lock->trans != trans)
+ continue;
+
+ list_del_init (&lock->blocked_locks);
+
+ gf_log (this->name, GF_LOG_TRACE,
+ "releasing lock on held by "
+ "{transport=%p}",trans);
+
+ list_add (&lock->blocked_locks, &released);
+
+ }
+
+ list_for_each_entry_safe (lock, tmp, &dom->entrylk_list,
+ domain_list) {
+ if (lock->trans != trans)
+ continue;
+
+ list_del_init (&lock->domain_list);
+
+ gf_log (this->name, GF_LOG_TRACE,
+ "releasing lock on held by "
+ "{transport=%p}",trans);
+
+ FREE (lock->basename);
+ FREE (lock);
}
+
+ __grant_blocked_entry_locks (this, pinode, dom, &granted);
+
}
- pthread_mutex_unlock (&pl_inode->mutex);
- return;
-}
+ pthread_mutex_unlock (&pinode->mutex);
+
+ list_for_each_entry_safe (lock, tmp, &released, blocked_locks) {
+ list_del_init (&lock->blocked_locks);
+
+ STACK_UNWIND_STRICT (entrylk, lock->frame, -1, EAGAIN);
+
+ if (lock->basename)
+ FREE (lock->basename);
+ FREE (lock);
+
+ }
+ list_for_each_entry_safe (lock, tmp, &granted, blocked_locks) {
+ list_del_init (&lock->blocked_locks);
+
+ STACK_UNWIND_STRICT (entrylk, lock->frame, 0, 0);
+
+ if (lock->basename)
+ FREE (lock->basename);
+ FREE (lock);
+ }
+
+ return 0;
+}
/* Common entrylk code called by pl_entrylk and pl_fentrylk */
int
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,
- dict_t *xdata)
-
+ entrylk_cmd cmd, entrylk_type type, loc_t *loc, fd_t *fd)
{
- int32_t op_ret = -1;
- int32_t op_errno = 0;
- int ret = -1;
- char unwind = 1;
- GF_UNUSED int dict_ret = -1;
- pl_inode_t *pinode = NULL;
- pl_entry_lock_t *reqlock = NULL;
- pl_entry_lock_t *unlocked = NULL;
- pl_dom_list_t *dom = NULL;
- char *conn_id = NULL;
- pl_ctx_t *ctx = NULL;
- int nonblock = 0;
- gf_boolean_t need_inode_unref = _gf_false;
-
- if (xdata)
- dict_ret = dict_get_str (xdata, "connection-id", &conn_id);
-
- pinode = pl_inode_get (this, inode);
- if (!pinode) {
- op_errno = ENOMEM;
- goto out;
- }
-
- if (frame->root->client) {
- ctx = pl_ctx_get (frame->root->client, this);
- if (!ctx) {
- op_errno = ENOMEM;
- gf_log (this->name, GF_LOG_INFO, "pl_ctx_get() failed");
- goto unwind;
- }
+ int32_t op_ret = -1;
+ int32_t op_errno = 0;
+
+ transport_t * transport = NULL;
+ pid_t pid = -1;
+ uint64_t owner = -1;
+
+ pl_inode_t * pinode = NULL;
+ int ret = -1;
+ pl_entry_lock_t *unlocked = NULL;
+ char unwind = 1;
+
+ pl_dom_list_t *dom = NULL;
+
+ pinode = pl_inode_get (this, inode);
+ if (!pinode) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory.");
+ op_errno = ENOMEM;
+ goto out;
}
- dom = get_domain (pinode, volume);
- if (!dom){
- op_errno = ENOMEM;
- goto out;
- }
+ dom = get_domain (pinode, volume);
+ if (!dom){
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory");
+ op_errno = ENOMEM;
+ goto out;
+ }
entrylk_trace_in (this, frame, volume, fd, loc, basename, cmd, type);
- reqlock = new_entrylk_lock (pinode, basename, type, dom->domain, frame,
- conn_id);
- if (!reqlock) {
- op_ret = -1;
- op_errno = ENOMEM;
- goto unwind;
- }
+ pid = frame->root->pid;
+ owner = (uint64_t)(long) frame->root;
+ transport = frame->root->trans;
- /* Ideally, AFTER a successful lock (both blocking and non-blocking) or
- * an unsuccessful blocking lock operation, the inode needs to be ref'd.
- *
- * But doing so might give room to a race where the lock-requesting
- * client could send a DISCONNECT just before this thread refs the inode
- * after the locking is done, and the epoll thread could unref the inode
- * in cleanup which means the inode's refcount would come down to 0, and
- * the call to pl_forget() at this point destroys @pinode. Now when
- * the io-thread executing this function tries to access pinode,
- * it could crash on account of illegal memory access.
- *
- * To get around this problem, the inode is ref'd once even before
- * adding the lock into client_list as a precautionary measure.
- * This way even if there are DISCONNECTs, there will always be 1 extra
- * ref on the inode, so @pinode is still alive until after the
- * current stack unwinds.
- */
- pinode->inode = inode_ref (inode);
+ if (pid == 0) {
+ /*
+ this is a special case that means release
+ all locks from this transport
+ */
- switch (cmd) {
- case ENTRYLK_LOCK_NB:
- nonblock = 1;
- /* fall through */
+ gf_log (this->name, GF_LOG_TRACE,
+ "Releasing locks for transport %p", transport);
+
+ release_entry_locks_for_transport (this, pinode, dom, transport);
+ op_ret = 0;
+
+ goto out;
+ }
+
+ switch (cmd) {
case ENTRYLK_LOCK:
- if (ctx)
- pthread_mutex_lock (&ctx->lock);
- pthread_mutex_lock (&pinode->mutex);
- {
- reqlock->pinode = pinode;
-
- ret = __lock_entrylk (this, pinode, reqlock, nonblock, dom);
- if (ret == 0) {
- reqlock->frame = NULL;
- op_ret = 0;
- } else {
- op_errno = -ret;
- }
-
- if (ctx && (!ret || !nonblock))
- list_add (&reqlock->client_list,
- &ctx->entrylk_lockers);
-
- if (ret == -EAGAIN && !nonblock) {
- /* blocked */
+ pthread_mutex_lock (&pinode->mutex);
+ {
+ ret = __lock_name (pinode, basename, type,
+ frame, dom, this, 0);
+ }
+ pthread_mutex_unlock (&pinode->mutex);
+
+ if (ret < 0) {
+ if (ret == -EAGAIN)
unwind = 0;
- } else {
- __pl_entrylk_unref (reqlock);
- }
-
- /* For all but the case where a non-blocking lock
- * attempt fails, the extra ref taken before the switch
- * block must be negated.
- */
- if ((ret == -EAGAIN) && (nonblock))
- need_inode_unref = _gf_true;
- }
- pthread_mutex_unlock (&pinode->mutex);
- if (ctx)
- pthread_mutex_unlock (&ctx->lock);
+ op_errno = -ret;
+ goto out;
+ }
+
break;
- case ENTRYLK_UNLOCK:
- if (ctx)
- pthread_mutex_lock (&ctx->lock);
- pthread_mutex_lock (&pinode->mutex);
- {
- /* Irrespective of whether unlock succeeds or not,
- * the extra inode ref that was done before the switch
- * block must be negated. Towards this,
- * @need_inode_unref flag is set unconditionally here.
- */
- need_inode_unref = _gf_true;
- unlocked = __unlock_entrylk (dom, reqlock);
- if (unlocked) {
- list_del_init (&unlocked->client_list);
- __pl_entrylk_unref (unlocked);
- op_ret = 0;
- } else {
- op_errno = EINVAL;
- }
- __pl_entrylk_unref (reqlock);
- }
- pthread_mutex_unlock (&pinode->mutex);
- if (ctx)
- pthread_mutex_unlock (&ctx->lock);
+ case ENTRYLK_LOCK_NB:
+ pthread_mutex_lock (&pinode->mutex);
+ {
+ ret = __lock_name (pinode, basename, type,
+ frame, dom, this, 1);
+ }
+ pthread_mutex_unlock (&pinode->mutex);
- grant_blocked_entry_locks (this, pinode, dom);
+ if (ret < 0) {
+ op_errno = -ret;
+ goto out;
+ }
- break;
+ break;
- default:
- inode_unref (pinode->inode);
- gf_log (this->name, GF_LOG_ERROR,
- "Unexpected case in entrylk (cmd=%d). Please file"
- "a bug report at http://bugs.gluster.com", cmd);
- goto out;
- }
- if (need_inode_unref)
- inode_unref (pinode->inode);
+ case ENTRYLK_UNLOCK:
+ pthread_mutex_lock (&pinode->mutex);
+ {
+ unlocked = __unlock_name (dom, basename, type);
+ }
+ pthread_mutex_unlock (&pinode->mutex);
- /* The following (extra) unref corresponds to the ref that
- * was done at the time the lock was granted.
- */
- if ((cmd == ENTRYLK_UNLOCK) && (op_ret == 0))
- inode_unref (pinode->inode);
+ if (unlocked)
+ grant_blocked_entry_locks (this, pinode, unlocked, dom);
-out:
+ break;
+
+ default:
+ gf_log (this->name, GF_LOG_ERROR,
+ "Unexpected case in entrylk (cmd=%d). Please file"
+ "a bug report at http://bugs.gluster.com", cmd);
+ goto out;
+ }
- if (unwind) {
+ op_ret = 0;
+out:
+ pl_update_refkeeper (this, inode);
+ if (unwind) {
entrylk_trace_out (this, frame, volume, fd, loc, basename,
cmd, type, op_ret, op_errno);
-unwind:
- STACK_UNWIND_STRICT (entrylk, frame, op_ret, op_errno, NULL);
- } else {
+
+ STACK_UNWIND_STRICT (entrylk, frame, op_ret, op_errno);
+ } else {
entrylk_trace_block (this, frame, volume, fd, loc, basename,
cmd, type);
}
- return 0;
+
+ return 0;
}
/**
@@ -715,11 +713,11 @@ unwind:
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)
+ const char *volume, loc_t *loc, const char *basename,
+ entrylk_cmd cmd, entrylk_type type)
{
- pl_common_entrylk (frame, this, volume, loc->inode, basename, cmd,
- type, loc, NULL, xdata);
+
+ pl_common_entrylk (frame, this, volume, loc->inode, basename, cmd, type, loc, NULL);
return 0;
}
@@ -734,133 +732,16 @@ pl_entrylk (call_frame_t *frame, xlator_t *this,
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)
{
- pl_common_entrylk (frame, this, volume, fd->inode, basename, cmd,
- type, NULL, fd, xdata);
-
- return 0;
-}
-
-static void
-pl_entrylk_log_cleanup (pl_entry_lock_t *lock)
-{
- pl_inode_t *pinode = NULL;
-
- pinode = lock->pinode;
-
- gf_log (THIS->name, GF_LOG_WARNING,
- "releasing lock on %s held by "
- "{client=%p, pid=%"PRId64" lk-owner=%s}",
- uuid_utoa (pinode->gfid), lock->client,
- (uint64_t) lock->client_pid, lkowner_utoa (&lock->owner));
-}
-
-
-/* Release all entrylks from this client */
-int
-pl_entrylk_client_cleanup (xlator_t *this, pl_ctx_t *ctx)
-{
- pl_entry_lock_t *tmp = NULL;
- pl_entry_lock_t *l = NULL;
- pl_dom_list_t *dom = NULL;
- pl_inode_t *pinode = NULL;
-
- struct list_head released;
- struct list_head unwind;
-
- INIT_LIST_HEAD (&released);
- INIT_LIST_HEAD (&unwind);
-
- pthread_mutex_lock (&ctx->lock);
- {
- list_for_each_entry_safe (l, tmp, &ctx->entrylk_lockers,
- client_list) {
- list_del_init (&l->client_list);
-
- pl_entrylk_log_cleanup (l);
-
- pinode = l->pinode;
-
- pthread_mutex_lock (&pinode->mutex);
- {
- /* If the entrylk object is part of granted list but not
- * blocked list, then perform the following actions:
- * i. delete the object from granted list;
- * ii. grant other locks (from other clients) that may
- * have been blocked on this entrylk; and
- * iii. unref the object.
- *
- * If the entrylk object (L1) is part of both granted
- * and blocked lists, then this means that a parallel
- * unlock on another entrylk (L2 say) may have 'granted'
- * L1 and added it to 'granted' list in
- * __grant_blocked_entry_locks() (although using the
- * 'blocked_locks' member). In that case, the cleanup
- * codepath must try and grant other overlapping
- * blocked entrylks from other clients, now that L1 is
- * out of their way and then unref L1 in the end, and
- * leave it to the other thread (the one executing
- * unlock codepath) to unwind L1's frame, delete it from
- * blocked_locks list, and perform the last unref on L1.
- *
- * If the entrylk object (L1) is part of blocked list
- * only, the cleanup code path must:
- * i. delete it from the blocked_locks list inside
- * this critical section,
- * ii. unwind its frame with EAGAIN,
- * iii. try and grant blocked entry locks from other
- * clients that were otherwise grantable, but were
- * blocked to avoid leaving L1 to starve forever.
- * iv. unref the object.
- */
- if (!list_empty (&l->domain_list)) {
- list_del_init (&l->domain_list);
- list_add_tail (&l->client_list,
- &released);
- } else {
- list_del_init (&l->blocked_locks);
- list_add_tail (&l->client_list,
- &unwind);
- }
- }
- pthread_mutex_unlock (&pinode->mutex);
- }
- }
- pthread_mutex_unlock (&ctx->lock);
-
- list_for_each_entry_safe (l, tmp, &unwind, client_list) {
- list_del_init (&l->client_list);
-
- if (l->frame)
- STACK_UNWIND_STRICT (entrylk, l->frame, -1, EAGAIN,
- NULL);
- list_add_tail (&l->client_list, &released);
- }
-
- list_for_each_entry_safe (l, tmp, &released, client_list) {
- list_del_init (&l->client_list);
-
- pinode = l->pinode;
-
- dom = get_domain (pinode, l->volume);
-
- grant_blocked_entry_locks (this, pinode, dom);
-
- pthread_mutex_lock (&pinode->mutex);
- {
- __pl_entrylk_unref (l);
- }
- pthread_mutex_unlock (&pinode->mutex);
- inode_unref (pinode->inode);
- }
+ pl_common_entrylk (frame, this, volume, fd->inode, basename, cmd, type, NULL, fd);
return 0;
}
-int32_t
+static int32_t
__get_entrylk_count (xlator_t *this, pl_inode_t *pl_inode)
{
int32_t count = 0;
@@ -869,10 +750,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 9860e9f9079..0017e3ed23b 100644
--- a/xlators/features/locks/src/inodelk.c
+++ b/xlators/features/locks/src/inodelk.c
@@ -1,12 +1,22 @@
/*
- Copyright (c) 2006-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) 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
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that 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"
@@ -23,40 +33,30 @@
#include "locks.h"
#include "common.h"
-inline void
+void
__delete_inode_lock (pl_inode_lock_t *lock)
{
- list_del_init (&lock->list);
-}
-
-static inline void
-__pl_inodelk_ref (pl_inode_lock_t *lock)
-{
- lock->ref++;
+ list_del (&lock->list);
}
-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->connection_id);
- GF_FREE (lock);
- }
+ 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)
- return 1;
+ if (l2->fl_type == F_WRLCK || l1->fl_type == F_WRLCK)
+ return 1;
- return 0;
+ return 0;
}
void
-pl_print_inodelk (char *str, int size, int cmd, struct gf_flock *flock, const char *domain)
+pl_print_inodelk (char *str, int size, int cmd, struct flock *flock, const char *domain)
{
char *cmd_str = NULL;
char *type_str = NULL;
@@ -115,43 +115,46 @@ pl_print_inodelk (char *str, int size, int cmd, struct gf_flock *flock, const ch
static int
inodelk_overlap (pl_inode_lock_t *l1, pl_inode_lock_t *l2)
{
- return ((l1->fl_end >= l2->fl_start) &&
- (l2->fl_end >= l1->fl_start));
+ return ((l1->fl_end >= l2->fl_start) &&
+ (l2->fl_end >= l1->fl_start));
}
/* 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) &&
- (l1->client == l2->client));
+ return ((l1->owner == l2->owner) &&
+ (l1->transport == l2->transport));
}
/* Returns true if the 2 inodelks conflict with each other */
static int
inodelk_conflict (pl_inode_lock_t *l1, pl_inode_lock_t *l2)
{
- return (inodelk_overlap (l1, l2) &&
- inodelk_type_conflict (l1, l2));
+ if (same_inodelk_owner (l1, l2))
+ return 0;
+
+ if (!inodelk_overlap (l1, l2))
+ return 0;
+
+ return (inodelk_type_conflict(l1, l2));
}
/* Determine if lock is grantable or not */
static pl_inode_lock_t *
__inodelk_grantable (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->inodelk_list))
- goto out;
- list_for_each_entry (l, &dom->inodelk_list, list){
- if (inodelk_conflict (lock, l) &&
- !same_inodelk_owner (lock, l)) {
- ret = l;
- goto out;
- }
- }
+ pl_inode_lock_t *l = NULL;
+ pl_inode_lock_t *ret = NULL;
+ if (list_empty (&dom->inodelk_list))
+ goto out;
+ list_for_each_entry (l, &dom->inodelk_list, list){
+ if (inodelk_conflict (lock, l)) {
+ ret = l;
+ goto out;
+ }
+ }
out:
- return ret;
+ return ret;
}
static pl_inode_lock_t *
@@ -160,18 +163,18 @@ __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))
- return NULL;
+ if (list_empty (&dom->blocked_entrylks))
+ return NULL;
- list_for_each_entry (l, &dom->blocked_inodelks, blocked_locks) {
- if (inodelk_conflict (lock, l)) {
- ret = l;
- goto out;
+ list_for_each_entry (l, &dom->blocked_inodelks, blocked_locks) {
+ if (inodelk_conflict (lock, l)) {
+ ret = l;
+ goto out;
}
- }
+ }
out:
- return ret;
+ return ret;
}
static int
@@ -179,17 +182,17 @@ __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) {
- if (same_inodelk_owner (lock, newlock))
- return 1;
- }
+ 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) {
- if (same_inodelk_owner (lock, newlock))
- return 1;
- }
+ list_for_each_entry (lock, &dom->blocked_entrylks, blocked_locks) {
+ if (same_inodelk_owner (lock, newlock))
+ return 1;
+ }
- return 0;
+ return 0;
}
@@ -198,97 +201,80 @@ __owner_has_lock (pl_dom_list_t *dom, pl_inode_lock_t *newlock)
*/
static int
__lock_inodelk (xlator_t *this, pl_inode_t *pl_inode, pl_inode_lock_t *lock,
- int can_block, pl_dom_list_t *dom)
+ int can_block, pl_dom_list_t *dom)
{
- pl_inode_lock_t *conf = NULL;
- int ret = -EINVAL;
+ pl_inode_lock_t *conf = NULL;
+ int ret = -EINVAL;
- conf = __inodelk_grantable (dom, lock);
- if (conf) {
- ret = -EAGAIN;
- if (can_block == 0)
- goto out;
+ conf = __inodelk_grantable (dom, lock);
+ if (conf){
+ ret = -EAGAIN;
+ if (can_block == 0)
+ goto out;
- gettimeofday (&lock->blkd_time, NULL);
- list_add_tail (&lock->blocked_locks, &dom->blocked_inodelks);
+ 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);
- goto out;
- }
+ goto out;
+ }
- /* To prevent blocked locks starvation, check if there are any blocked
- * locks thay may conflict with this lock. If there is then don't grant
- * the lock. BUT grant the lock if the owner already has lock to allow
- * nested locks.
- * Example:
- * SHD from Machine1 takes (gfid, 0-infinity) and is granted.
- * SHD from machine2 takes (gfid, 0-infinity) and is blocked.
- * When SHD from Machine1 takes (gfid, 0-128KB) it
- * needs to be granted, without which the earlier lock on 0-infinity
- * will not be unlocked by SHD from Machine1.
- * TODO: Find why 'owner_has_lock' is checked even for blocked locks.
- */
if (__blocked_lock_conflict (dom, lock) && !(__owner_has_lock (dom, lock))) {
ret = -EAGAIN;
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_DEBUG,
- "Lock is grantable, but blocking to prevent starvation");
gf_log (this->name, GF_LOG_TRACE,
- "%s (pid=%d) (lk-owner=%s) %"PRId64" - %"PRId64" => Blocked",
+ "Lock is grantable, but blocking to prevent starvation");
+ gf_log (this->name, GF_LOG_TRACE,
+ "%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;
+ goto out;
}
- __pl_inodelk_ref (lock);
- gettimeofday (&lock->granted_time, NULL);
- list_add (&lock->list, &dom->inodelk_list);
+ list_add (&lock->list, &dom->inodelk_list);
- ret = 0;
+ ret = 0;
out:
- return ret;
+ return ret;
}
/* Return true if the two inodelks have exactly same lock boundaries */
static int
inodelks_equal (pl_inode_lock_t *l1, pl_inode_lock_t *l2)
{
- if ((l1->fl_start == l2->fl_start) &&
- (l1->fl_end == l2->fl_end))
- return 1;
+ if ((l1->fl_start == l2->fl_start) &&
+ (l1->fl_end == l2->fl_end))
+ return 1;
- return 0;
+ return 0;
}
static pl_inode_lock_t *
find_matching_inodelk (pl_inode_lock_t *lock, pl_dom_list_t *dom)
{
- pl_inode_lock_t *l = NULL;
- list_for_each_entry (l, &dom->inodelk_list, list) {
- if (inodelks_equal (l, lock) &&
- same_inodelk_owner (l, lock))
- return l;
- }
- return NULL;
+ pl_inode_lock_t *l = NULL;
+ list_for_each_entry (l, &dom->inodelk_list, list) {
+ if (inodelks_equal (l, lock))
+ return l;
+ }
+ return NULL;
}
/* Set F_UNLCK removes a lock which has the exact same lock boundaries
@@ -298,496 +284,354 @@ static pl_inode_lock_t *
__inode_unlock_lock (xlator_t *this, pl_inode_lock_t *lock, pl_dom_list_t *dom)
{
- pl_inode_lock_t *conf = NULL;
+ pl_inode_lock_t *conf = NULL;
- 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->client);
- goto out;
+ conf = find_matching_inodelk (lock, dom);
+ if (!conf) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ " Matching lock not found for unlock");
+ goto out;
}
- __delete_inode_lock (conf);
+ __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->client);
+ " Matching lock found for unlock");
+ __destroy_inode_lock (lock);
+
out:
- return conf;
-}
+ return conf;
+}
static void
-__grant_blocked_inode_locks (xlator_t *this, pl_inode_t *pl_inode,
- struct list_head *granted, pl_dom_list_t *dom)
+__grant_blocked_inode_locks (xlator_t *this, pl_inode_t *pl_inode,
+ struct list_head *granted, pl_dom_list_t *dom)
{
- int bl_ret = 0;
- pl_inode_lock_t *bl = NULL;
- pl_inode_lock_t *tmp = NULL;
+ int bl_ret = 0;
+ pl_inode_lock_t *bl = NULL;
+ pl_inode_lock_t *tmp = NULL;
struct list_head blocked_list;
INIT_LIST_HEAD (&blocked_list);
list_splice_init (&dom->blocked_inodelks, &blocked_list);
- list_for_each_entry_safe (bl, tmp, &blocked_list, blocked_locks) {
+ list_for_each_entry_safe (bl, tmp, &blocked_list, blocked_locks) {
- list_del_init (&bl->blocked_locks);
+ list_del_init (&bl->blocked_locks);
- bl_ret = __lock_inodelk (this, pl_inode, bl, 1, dom);
+ bl_ret = __lock_inodelk (this, pl_inode, bl, 1, dom);
- if (bl_ret == 0) {
- list_add (&bl->blocked_locks, granted);
+ if (bl_ret == 0) {
+ list_add (&bl->blocked_locks, granted);
}
}
- return;
+ return;
}
/* Grant all inodelks blocked on a lock */
void
-grant_blocked_inode_locks (xlator_t *this, pl_inode_t *pl_inode,
- pl_dom_list_t *dom)
+grant_blocked_inode_locks (xlator_t *this, pl_inode_t *pl_inode, pl_dom_list_t *dom)
{
- struct list_head granted;
- pl_inode_lock_t *lock;
- pl_inode_lock_t *tmp;
+ struct list_head granted;
+ pl_inode_lock_t *lock;
+ pl_inode_lock_t *tmp;
- INIT_LIST_HEAD (&granted);
-
- pthread_mutex_lock (&pl_inode->mutex);
- {
- __grant_blocked_inode_locks (this, pl_inode, &granted, dom);
- }
- pthread_mutex_unlock (&pl_inode->mutex);
+ INIT_LIST_HEAD (&granted);
- list_for_each_entry_safe (lock, tmp, &granted, blocked_locks) {
+ if (list_empty (&dom->blocked_inodelks)) {
gf_log (this->name, GF_LOG_TRACE,
- "%s (pid=%d) (lk-owner=%s) %"PRId64" - %"PRId64" => Granted",
- lock->fl_type == F_UNLCK ? "Unlock" : "Lock",
- lock->client_pid,
- lkowner_utoa (&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);
- lock->frame = NULL;
+ "No blocked locks to be granted for domain: %s", dom->domain);
}
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);
- }
- }
+ {
+ __grant_blocked_inode_locks (this, pl_inode, &granted, dom);
+ }
pthread_mutex_unlock (&pl_inode->mutex);
-}
+ list_for_each_entry_safe (lock, tmp, &granted, blocked_locks) {
+ gf_log (this->name, GF_LOG_TRACE,
+ "%s (pid=%d) (lk-owner=%"PRIu64") %"PRId64" - %"PRId64" => Granted",
+ lock->fl_type == F_UNLCK ? "Unlock" : "Lock",
+ lock->client_pid,
+ lock->owner,
+ lock->user_flock.l_start,
+ lock->user_flock.l_len);
-static void
-pl_inodelk_log_cleanup (pl_inode_lock_t *lock)
-{
- pl_inode_t *pl_inode = NULL;
+ pl_trace_out (this, lock->frame, NULL, NULL, F_SETLKW,
+ &lock->user_flock, 0, 0, lock->volume);
- pl_inode = lock->pl_inode;
+ STACK_UNWIND_STRICT (inodelk, lock->frame, 0, 0);
+ }
- gf_log (THIS->name, GF_LOG_WARNING, "releasing lock on %s held by "
- "{client=%p, pid=%"PRId64" lk-owner=%s}",
- uuid_utoa (pl_inode->gfid), lock->client,
- (uint64_t) lock->client_pid, lkowner_utoa (&lock->owner));
}
-
-/* Release all inodelks from this client */
-int
-pl_inodelk_client_cleanup (xlator_t *this, pl_ctx_t *ctx)
+/* Release all inodelks from this transport */
+static int
+release_inode_locks_of_transport (xlator_t *this, pl_dom_list_t *dom,
+ inode_t *inode, transport_t *trans)
{
- pl_inode_lock_t *tmp = NULL;
- pl_inode_lock_t *l = NULL;
- pl_dom_list_t *dom = NULL;
- pl_inode_t *pl_inode = NULL;
+ pl_inode_lock_t *tmp = NULL;
+ pl_inode_lock_t *l = NULL;
+
+ pl_inode_t * pinode = NULL;
+ struct list_head granted;
struct list_head released;
- struct list_head unwind;
+ char *path = NULL;
+
+ INIT_LIST_HEAD (&granted);
INIT_LIST_HEAD (&released);
- INIT_LIST_HEAD (&unwind);
- pthread_mutex_lock (&ctx->lock);
+ pinode = pl_inode_get (this, inode);
+
+ pthread_mutex_lock (&pinode->mutex);
{
- list_for_each_entry_safe (l, tmp, &ctx->inodelk_lockers,
- client_list) {
- list_del_init (&l->client_list);
-
- pl_inodelk_log_cleanup (l);
-
- pl_inode = l->pl_inode;
-
- pthread_mutex_lock (&pl_inode->mutex);
- {
- /* If the inodelk object is part of granted list but not
- * blocked list, then perform the following actions:
- * i. delete the object from granted list;
- * ii. grant other locks (from other clients) that may
- * have been blocked on this inodelk; and
- * iii. unref the object.
- *
- * If the inodelk object (L1) is part of both granted
- * and blocked lists, then this means that a parallel
- * unlock on another inodelk (L2 say) may have 'granted'
- * L1 and added it to 'granted' list in
- * __grant_blocked_node_locks() (although using the
- * 'blocked_locks' member). In that case, the cleanup
- * codepath must try and grant other overlapping
- * blocked inodelks from other clients, now that L1 is
- * out of their way and then unref L1 in the end, and
- * leave it to the other thread (the one executing
- * unlock codepath) to unwind L1's frame, delete it from
- * blocked_locks list, and perform the last unref on L1.
- *
- * If the inodelk object (L1) is part of blocked list
- * only, the cleanup code path must:
- * i. delete it from the blocked_locks list inside
- * this critical section,
- * ii. unwind its frame with EAGAIN,
- * iii. try and grant blocked inode locks from other
- * clients that were otherwise grantable, but just
- * got blocked to avoid leaving L1 to starve
- * forever.
- * iv. unref the object.
- */
- if (!list_empty (&l->list)) {
- __delete_inode_lock (l);
- list_add_tail (&l->client_list,
- &released);
- } else {
- list_del_init(&l->blocked_locks);
- list_add_tail (&l->client_list,
- &unwind);
- }
+
+ list_for_each_entry_safe (l, tmp, &dom->blocked_inodelks, blocked_locks) {
+ if (l->transport != trans)
+ continue;
+
+ list_del_init (&l->blocked_locks);
+
+ if (inode_path (inode, NULL, &path) < 0) {
+ gf_log (this->name, GF_LOG_TRACE,
+ "inode_path failed");
+ goto unlock;
}
- pthread_mutex_unlock (&pl_inode->mutex);
+
+ 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);
+
}
- }
- pthread_mutex_unlock (&ctx->lock);
- list_for_each_entry_safe (l, tmp, &unwind, client_list) {
- list_del_init (&l->client_list);
+ list_for_each_entry_safe (l, tmp, &dom->inodelk_list, list) {
+ if (l->transport != trans)
+ continue;
- if (l->frame)
- STACK_UNWIND_STRICT (inodelk, l->frame, -1, EAGAIN,
- NULL);
- list_add_tail (&l->client_list, &released);
+ __delete_inode_lock (l);
+ __destroy_inode_lock (l);
- }
- list_for_each_entry_safe (l, tmp, &released, client_list) {
- list_del_init (&l->client_list);
+ 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_TRACE,
+ "releasing lock on %s held by "
+ "{transport=%p, pid=%"PRId64" lk-owner=%"PRIu64"}",
+ path, trans,
+ (uint64_t) l->client_pid,
+ l->owner);
- pl_inode = l->pl_inode;
- dom = get_domain (pl_inode, l->volume);
+ }
+ }
+unlock:
+ if (path)
+ FREE (path);
- grant_blocked_inode_locks (this, pl_inode, dom);
+ pthread_mutex_unlock (&pinode->mutex);
- pthread_mutex_lock (&pl_inode->mutex);
- {
- __pl_inodelk_unref (l);
- }
- pthread_mutex_unlock (&pl_inode->mutex);
- inode_unref (pl_inode->inode);
+ list_for_each_entry_safe (l, tmp, &released, blocked_locks) {
+ list_del_init (&l->blocked_locks);
+
+ STACK_UNWIND_STRICT (inodelk, l->frame, -1, EAGAIN);
+ FREE (l);
}
- return 0;
+ grant_blocked_inode_locks (this, pinode, dom);
+ return 0;
}
static int
-pl_inode_setlk (xlator_t *this, pl_ctx_t *ctx, pl_inode_t *pl_inode,
- pl_inode_lock_t *lock, int can_block, pl_dom_list_t *dom,
- inode_t *inode)
+pl_inode_setlk (xlator_t *this, pl_inode_t *pl_inode, pl_inode_lock_t *lock,
+ int can_block, pl_dom_list_t *dom)
{
- int ret = -EINVAL;
- pl_inode_lock_t *retlock = NULL;
- gf_boolean_t unref = _gf_true;
- gf_boolean_t need_inode_unref = _gf_false;
- short fl_type;
-
- lock->pl_inode = pl_inode;
- fl_type = lock->fl_type;
-
- /* Ideally, AFTER a successful lock (both blocking and non-blocking) or
- * an unsuccessful blocking lock operation, the inode needs to be ref'd.
- *
- * But doing so might give room to a race where the lock-requesting
- * client could send a DISCONNECT just before this thread refs the inode
- * after the locking is done, and the epoll thread could unref the inode
- * in cleanup which means the inode's refcount would come down to 0, and
- * the call to pl_forget() at this point destroys @pl_inode. Now when
- * the io-thread executing this function tries to access pl_inode,
- * it could crash on account of illegal memory access.
- *
- * To get around this problem, the inode is ref'd once even before
- * adding the lock into client_list as a precautionary measure.
- * This way even if there are DISCONNECTs, there will always be 1 extra
- * ref on the inode, so @pl_inode is still alive until after the
- * current stack unwinds.
- */
- pl_inode->inode = inode_ref (inode);
-
- if (ctx)
- pthread_mutex_lock (&ctx->lock);
- 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) {
- lock->frame = NULL;
- gf_log (this->name, GF_LOG_TRACE,
- "%s (pid=%d) (lk-owner=%s) %"PRId64" - %"PRId64" => OK",
+ int ret = -EINVAL;
+ pl_inode_lock_t *retlock = NULL;
+
+ 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)
+ gf_log (this->name, GF_LOG_TRACE,
+ "%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) {
- gf_log (this->name, GF_LOG_TRACE,
- "%s (pid=%d) (lk-owner=%s) %"PRId64" - %"PRId64" => NOK",
- lock->fl_type == F_UNLCK ? "Unlock" : "Lock",
- lock->client_pid,
- lkowner_utoa (&lock->owner),
- lock->user_flock.l_start,
- lock->user_flock.l_len);
- if (can_block)
- unref = _gf_false;
- /* For all but the case where a non-blocking
- * lock attempt fails, the extra ref taken at
- * the start of this function must be negated.
- */
- else
- need_inode_unref = _gf_true;
- }
- if (ctx && (!ret || can_block))
- list_add_tail (&lock->client_list,
- &ctx->inodelk_lockers);
- } else {
- /* Irrespective of whether unlock succeeds or not,
- * the extra inode ref that was done at the start of
- * this function must be negated. Towards this,
- * @need_inode_unref flag is set unconditionally here.
- */
- need_inode_unref = _gf_true;
- 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;
- }
- list_del_init (&retlock->client_list);
- __pl_inodelk_unref (retlock);
+ if (ret == -EAGAIN)
+ gf_log (this->name, GF_LOG_TRACE,
+ "%s (pid=%d) (lk-owner=%"PRIu64") %"PRId64" - %"PRId64" => NOK",
+ lock->fl_type == F_UNLCK ? "Unlock" : "Lock",
+ lock->client_pid,
+ lock->owner,
+ lock->user_flock.l_start,
+ lock->user_flock.l_len);
+
+ goto out;
+ }
- ret = 0;
+
+ 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;
}
-out:
- if (unref)
- __pl_inodelk_unref (lock);
- }
- pthread_mutex_unlock (&pl_inode->mutex);
- if (ctx)
- pthread_mutex_unlock (&ctx->lock);
-
- if (need_inode_unref)
- inode_unref (pl_inode->inode);
-
- /* The following (extra) unref corresponds to the ref that
- * was done at the time the lock was granted.
- */
- if ((fl_type == F_UNLCK) && (ret == 0)) {
- inode_unref (pl_inode->inode);
- grant_blocked_inode_locks (this, pl_inode, dom);
- }
+ __destroy_inode_lock (retlock);
+
+ ret = 0;
+
+ }
+out:
+ pthread_mutex_unlock (&pl_inode->mutex);
+ grant_blocked_inode_locks (this, pl_inode, dom);
return ret;
}
/* Create a new inode_lock_t */
pl_inode_lock_t *
-new_inode_lock (struct gf_flock *flock, client_t *client, pid_t client_pid,
- call_frame_t *frame, xlator_t *this, const char *volume,
- char *conn_id)
+new_inode_lock (struct flock *flock, transport_t *transport, pid_t client_pid,
+ uint64_t owner, const char *volume)
{
- pl_inode_lock_t *lock = NULL;
-
- lock = GF_CALLOC (1, sizeof (*lock),
- gf_locks_mt_pl_inode_lock_t);
- if (!lock) {
- return NULL;
- }
-
- lock->fl_start = flock->l_start;
- lock->fl_type = flock->l_type;
-
- if (flock->l_len == 0)
- lock->fl_end = LLONG_MAX;
- else
- lock->fl_end = flock->l_start + flock->l_len - 1;
-
- lock->client = client;
- lock->client_pid = client_pid;
- lock->volume = volume;
- lock->owner = frame->root->lk_owner;
- lock->frame = frame;
- lock->this = this;
+ pl_inode_lock_t *lock = NULL;
- if (conn_id) {
- lock->connection_id = gf_strdup (conn_id);
- }
+ lock = CALLOC (1, sizeof (*lock));
+ if (!lock) {
+ return NULL;
+ }
- INIT_LIST_HEAD (&lock->list);
- INIT_LIST_HEAD (&lock->blocked_locks);
- INIT_LIST_HEAD (&lock->client_list);
- __pl_inodelk_ref (lock);
+ lock->fl_start = flock->l_start;
+ lock->fl_type = flock->l_type;
- return lock;
-}
+ if (flock->l_len == 0)
+ lock->fl_end = LLONG_MAX;
+ else
+ lock->fl_end = flock->l_start + flock->l_len - 1;
-int32_t
-_pl_convert_volume (const char *volume, char **res)
-{
- char *mdata_vol = NULL;
- int ret = 0;
+ lock->transport = transport;
+ lock->client_pid = client_pid;
+ lock->owner = owner;
+ lock->volume = volume;
- mdata_vol = strrchr (volume, ':');
- //if the volume already ends with :metadata don't bother
- if (mdata_vol && (strcmp (mdata_vol, ":metadata") == 0))
- return 0;
+ INIT_LIST_HEAD (&lock->list);
+ INIT_LIST_HEAD (&lock->blocked_locks);
- ret = gf_asprintf (res, "%s:metadata", volume);
- if (ret <= 0)
- return ENOMEM;
- return 0;
-}
-
-int32_t
-_pl_convert_volume_for_special_range (struct gf_flock *flock,
- const char *volume, char **res)
-{
- int32_t ret = 0;
-
- if ((flock->l_start == LLONG_MAX -1) &&
- (flock->l_len == 0)) {
- ret = _pl_convert_volume (volume, res);
- }
-
- return ret;
+ return lock;
}
/* Common inodelk code called from pl_inodelk and pl_finodelk */
int
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, dict_t *xdata)
+ struct flock *flock, loc_t *loc, fd_t *fd)
{
- int32_t op_ret = -1;
- int32_t op_errno = 0;
- int ret = -1;
- GF_UNUSED int dict_ret = -1;
- int can_block = 0;
- pl_inode_t * pinode = NULL;
- pl_inode_lock_t * reqlock = NULL;
- pl_dom_list_t * dom = NULL;
- char *res = NULL;
- char *res1 = NULL;
- char *conn_id = NULL;
- pl_ctx_t *ctx = NULL;
-
- if (xdata)
- dict_ret = dict_get_str (xdata, "connection-id", &conn_id);
-
- VALIDATE_OR_GOTO (frame, out);
- VALIDATE_OR_GOTO (inode, unwind);
- VALIDATE_OR_GOTO (flock, unwind);
-
- if ((flock->l_start < 0) || (flock->l_len < 0)) {
- op_errno = EINVAL;
- goto unwind;
- }
-
- op_errno = _pl_convert_volume_for_special_range (flock, volume, &res);
- if (op_errno)
- goto unwind;
- if (res)
- volume = res;
+ int32_t op_ret = -1;
+ int32_t op_errno = 0;
+ int ret = -1;
+ int can_block = 0;
+ transport_t * 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);
+ VALIDATE_OR_GOTO (flock, unwind);
+
+ if ((flock->l_start < 0) || (flock->l_len < 0)) {
+ op_errno = EINVAL;
+ goto unwind;
+ }
pl_trace_in (this, frame, fd, loc, cmd, flock, volume);
- if (frame->root->client) {
- ctx = pl_ctx_get (frame->root->client, this);
- if (!ctx) {
- op_errno = ENOMEM;
- gf_log (this->name, GF_LOG_INFO, "pl_ctx_get() failed");
- goto unwind;
- }
+ transport = frame->root->trans;
+ client_pid = frame->root->pid;
+ owner = frame->root->lk_owner;
+
+ pinode = pl_inode_get (this, inode);
+ if (!pinode) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory.");
+ op_errno = ENOMEM;
+ goto unwind;
}
- pinode = pl_inode_get (this, inode);
- if (!pinode) {
- op_errno = ENOMEM;
- goto unwind;
- }
+ dom = get_domain (pinode, volume);
- dom = get_domain (pinode, volume);
- if (!dom) {
- op_errno = ENOMEM;
- goto unwind;
- }
+ if (client_pid == 0) {
+ /*
+ special case: this means release all locks
+ from this transport
+ */
+ gf_log (this->name, GF_LOG_TRACE,
+ "Releasing all locks from transport %p", transport);
- reqlock = new_inode_lock (flock, frame->root->client, frame->root->pid,
- frame, this, dom->domain, conn_id);
+ release_inode_locks_of_transport (this, dom, inode, transport);
+ goto unwind;
+ }
- if (!reqlock) {
- op_ret = -1;
- op_errno = ENOMEM;
- goto unwind;
- }
+ reqlock = new_inode_lock (flock, transport, client_pid, owner, volume);
+ if (!reqlock) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory.");
+ op_ret = -1;
+ op_errno = ENOMEM;
+ goto unwind;
+ }
- switch (cmd) {
- case F_SETLKW:
- can_block = 1;
+ switch (cmd) {
+ case F_SETLKW:
+ can_block = 1;
+ reqlock->frame = frame;
+ reqlock->this = this;
- /* fall through */
+ /* fall through */
- case F_SETLK:
- memcpy (&reqlock->user_flock, flock, sizeof (struct gf_flock));
- ret = pl_inode_setlk (this, ctx, pinode, reqlock, can_block,
- dom, inode);
+ case F_SETLK:
+ memcpy (&reqlock->user_flock, flock, sizeof (struct flock));
+ ret = pl_inode_setlk (this, pinode, reqlock,
+ can_block, dom);
- if (ret < 0) {
- if ((can_block) && (F_UNLCK != flock->l_type)) {
+ if (ret < 0) {
+ if (can_block) {
pl_trace_block (this, frame, fd, loc,
cmd, flock, volume);
- goto out;
+ goto out;
}
- gf_log (this->name, GF_LOG_TRACE, "returning EAGAIN");
- op_errno = -ret;
- goto unwind;
- }
- break;
+ gf_log (this->name, GF_LOG_TRACE, "returning EAGAIN");
+ op_errno = -ret;
+ __destroy_inode_lock (reqlock);
+ goto unwind;
+ }
+ break;
- default:
- op_errno = ENOTSUP;
- gf_log (this->name, GF_LOG_DEBUG,
+ default:
+ op_errno = ENOTSUP;
+ gf_log (this->name, GF_LOG_DEBUG,
"Lock command F_GETLK not supported for [f]inodelk "
"(cmd=%d)",
cmd);
@@ -797,84 +641,85 @@ pl_common_inodelk (call_frame_t *frame, xlator_t *this,
op_ret = 0;
unwind:
- if (flock != NULL)
- pl_trace_out (this, frame, fd, loc, cmd, flock, op_ret,
- op_errno, volume);
+ if ((inode != NULL) && (flock !=NULL)) {
+ pl_update_refkeeper (this, inode);
+ 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:
- GF_FREE (res);
- GF_FREE (res1);
return 0;
}
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 flock *flock)
{
- pl_common_inodelk (frame, this, volume, loc->inode, cmd, flock,
- loc, NULL, xdata);
+
+ pl_common_inodelk (frame, this, volume, loc->inode, cmd, flock, loc, NULL);
return 0;
}
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 flock *flock)
{
- pl_common_inodelk (frame, this, volume, fd->inode, cmd, flock,
- NULL, fd, xdata);
+
+ pl_common_inodelk (frame, this, volume, fd->inode, cmd, flock, NULL, fd);
return 0;
}
-static inline int32_t
-__get_inodelk_dom_count (pl_dom_list_t *dom)
-{
- pl_inode_lock_t *lock = NULL;
- int32_t count = 0;
-
- list_for_each_entry (lock, &dom->inodelk_list, list) {
- count++;
- }
- list_for_each_entry (lock, &dom->blocked_inodelks, blocked_locks) {
- count++;
- }
- return count;
-}
-/* Returns the no. of locks (blocked/granted) held on a given domain name
- * If @domname is NULL, returns the no. of locks in all the domains present.
- * If @domname is non-NULL and non-existent, returns 0 */
-int32_t
-__get_inodelk_count (xlator_t *this, pl_inode_t *pl_inode, char *domname)
+static int32_t
+__get_inodelk_count (xlator_t *this, pl_inode_t *pl_inode)
{
int32_t count = 0;
+ pl_inode_lock_t *lock = NULL;
pl_dom_list_t *dom = NULL;
list_for_each_entry (dom, &pl_inode->dom_list, inode_list) {
- if (domname) {
- if (strcmp (domname, dom->domain) == 0) {
- count = __get_inodelk_dom_count (dom);
- goto out;
- }
+ 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) {
- } else {
- /* Counting locks from all domains */
- count += __get_inodelk_dom_count (dom);
+ 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++;
}
+
}
-out:
return count;
}
int32_t
-get_inodelk_count (xlator_t *this, inode_t *inode, char *domname)
+get_inodelk_count (xlator_t *this, inode_t *inode)
{
pl_inode_t *pl_inode = NULL;
uint64_t tmp_pl_inode = 0;
@@ -890,7 +735,7 @@ get_inodelk_count (xlator_t *this, inode_t *inode, char *domname)
pthread_mutex_lock (&pl_inode->mutex);
{
- count = __get_inodelk_count (this, pl_inode, domname);
+ count = __get_inodelk_count (this, pl_inode);
}
pthread_mutex_unlock (&pl_inode->mutex);
diff --git a/xlators/features/locks/src/locks-mem-types.h b/xlators/features/locks/src/locks-mem-types.h
deleted file mode 100644
index 08aeb0a7925..00000000000
--- a/xlators/features/locks/src/locks-mem-types.h
+++ /dev/null
@@ -1,29 +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 __LOCKS_MEM_TYPES_H__
-#define __LOCKS_MEM_TYPES_H__
-
-#include "mem-types.h"
-
-enum gf_locks_mem_types_ {
- gf_locks_mt_pl_dom_list_t = gf_common_mt_end + 1,
- gf_locks_mt_pl_inode_t,
- gf_locks_mt_posix_lock_t,
- gf_locks_mt_pl_entry_lock_t,
- gf_locks_mt_pl_inode_lock_t,
- gf_locks_mt_truncate_ops,
- gf_locks_mt_pl_rw_req_t,
- gf_locks_mt_posix_locks_private_t,
- gf_locks_mt_pl_fdctx_t,
- gf_locks_mt_end
-};
-#endif
-
diff --git a/xlators/features/locks/src/locks.h b/xlators/features/locks/src/locks.h
index f761b3d4a00..1bbbee119c8 100644
--- a/xlators/features/locks/src/locks.h
+++ b/xlators/features/locks/src/locks.h
@@ -1,12 +1,22 @@
/*
- Copyright (c) 2006-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) 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
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that 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_LOCKS_H__
#define __POSIX_LOCKS_H__
@@ -16,12 +26,9 @@
#endif
#include "compat-errno.h"
+#include "transport.h"
#include "stack.h"
#include "call-stub.h"
-#include "locks-mem-types.h"
-#include "client_t.h"
-
-#include "lkowner.h"
struct __pl_fd;
@@ -33,29 +40,25 @@ struct __posix_lock {
off_t fl_end;
short blocked; /* waiting to acquire */
- struct gf_flock user_flock; /* the flock supplied by the user */
+ struct flock user_flock; /* the flock supplied by the user */
xlator_t *this; /* required for blocked locks */
unsigned long fd_num;
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 *client; /* to identify client node */
- gf_lkowner_t owner;
+ transport_t *transport; /* to identify client node */
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;
@@ -63,25 +66,18 @@ struct __pl_inode_lock {
const char *volume;
- struct gf_flock user_flock; /* the flock supplied by the user */
+ struct flock user_flock; /* the flock supplied by the user */
xlator_t *this; /* required for blocked locks */
- struct __pl_inode *pl_inode;
+ 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 *client; /* to identify client node */
- gf_lkowner_t owner;
+ transport_t *transport; /* to identify client node */
pid_t client_pid; /* pid of client process */
-
- char *connection_id; /* stores the client connection id */
-
- struct list_head client_list; /* list of all locks from a client */
+ uint64_t owner;
};
typedef struct __pl_inode_lock pl_inode_lock_t;
@@ -105,27 +101,18 @@ typedef struct __pl_dom_list_t pl_dom_list_t;
struct __entry_lock {
struct list_head domain_list; /* list_head back to pl_dom_list_t */
struct list_head blocked_locks; /* list_head back to blocked_entrylks */
- int ref;
call_frame_t *frame;
xlator_t *this;
- struct __pl_inode *pinode;
const char *volume;
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 *client;
- gf_lkowner_t owner;
- pid_t client_pid; /* pid of client process */
-
- char *connection_id; /* stores the client connection id */
-
- struct list_head client_list; /* list of all locks from a client */
+ transport_t *trans;
+ pid_t client_pid; /* pid of client process */
+ uint64_t owner;
};
typedef struct __entry_lock pl_entry_lock_t;
@@ -139,70 +126,29 @@ struct __pl_inode {
struct list_head dom_list; /* list of domains */
struct list_head ext_list; /* list of fcntl locks */
struct list_head rw_list; /* list of waiting r/w requests */
- struct list_head reservelk_list; /* list of reservelks */
- struct list_head blocked_reservelks; /* list of blocked reservelks */
- struct list_head blocked_calls; /* List of blocked lock calls while a reserve is held*/
int mandatory; /* if mandatory locking is enabled */
inode_t *refkeeper; /* hold refs on an inode while locks are
held to prevent pruning */
- uuid_t gfid; /* placeholder for gfid of the inode */
- inode_t *inode; /* pointer to be used for ref and unref
- of inode_t as long as there are
- locks on it */
};
typedef struct __pl_inode pl_inode_t;
+struct __pl_fd {
+ gf_boolean_t nonblocking; /* whether O_NONBLOCK has been set */
+};
+typedef struct __pl_fd pl_fd_t;
+
+
typedef struct {
gf_boolean_t mandatory; /* if mandatory locking is enabled */
gf_boolean_t trace; /* trace lock requests in and out */
- char *brickname;
} posix_locks_private_t;
-
typedef struct {
gf_boolean_t entrylk_count_req;
gf_boolean_t inodelk_count_req;
- gf_boolean_t inodelk_dom_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 {
- struct list_head locks_list;
-} pl_fdctx_t;
-
-
-struct _locker {
- struct list_head lockers;
- char *volume;
- inode_t *inode;
- gf_lkowner_t owner;
-};
-
-typedef struct _locks_ctx {
- pthread_mutex_t lock;
- struct list_head inodelk_lockers;
- struct list_head entrylk_lockers;
-} pl_ctx_t;
-
-
-pl_ctx_t *
-pl_ctx_get (client_t *client, xlator_t *xlator);
-
-int
-pl_inodelk_client_cleanup (xlator_t *this, pl_ctx_t *ctx);
-
-int
-pl_entrylk_client_cleanup (xlator_t *this, pl_ctx_t *ctx);
-
#endif /* __POSIX_LOCKS_H__ */
diff --git a/xlators/features/locks/src/posix.c b/xlators/features/locks/src/posix.c
index af25a10aaa3..5b3f7d5303a 100644
--- a/xlators/features/locks/src/posix.c
+++ b/xlators/features/locks/src/posix.c
@@ -1,12 +1,22 @@
/*
- Copyright (c) 2006-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) 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
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that 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>
@@ -27,9 +37,6 @@
#include "locks.h"
#include "common.h"
#include "statedump.h"
-#include "clear.h"
-#include "defaults.h"
-#include "syncop.h"
#ifndef LLONG_MAX
#define LLONG_MAX LONG_LONG_MAX /* compat with old gcc */
@@ -40,87 +47,37 @@
void do_blocked_rw (pl_inode_t *);
static int __rw_allowable (pl_inode_t *, posix_lock_t *, glusterfs_fop_t);
-static int format_brickname(char *);
-int pl_lockinfo_get_brickname (xlator_t *, inode_t *, int32_t *);
-static int fetch_pathinfo(xlator_t *, inode_t *, int32_t *, char **);
-
-static pl_fdctx_t *
-pl_new_fdctx ()
-{
- pl_fdctx_t *fdctx = NULL;
-
- fdctx = GF_CALLOC (1, sizeof (*fdctx),
- gf_locks_mt_pl_fdctx_t);
- GF_VALIDATE_OR_GOTO ("posix-locks", fdctx, out);
-
- INIT_LIST_HEAD (&fdctx->locks_list);
-
-out:
- return fdctx;
-}
-
-static pl_fdctx_t *
-pl_check_n_create_fdctx (xlator_t *this, fd_t *fd)
-{
- int ret = 0;
- uint64_t tmp = 0;
- pl_fdctx_t *fdctx = NULL;
- GF_VALIDATE_OR_GOTO ("posix-locks", this, out);
- GF_VALIDATE_OR_GOTO (this->name, fd, out);
-
- LOCK (&fd->lock);
- {
- ret = __fd_ctx_get (fd, this, &tmp);
- if ((ret != 0) || (tmp == 0)) {
- fdctx = pl_new_fdctx ();
- if (fdctx == NULL) {
- goto unlock;
- }
- }
-
- ret = __fd_ctx_set (fd, this, (uint64_t)(long)fdctx);
- if (ret != 0) {
- GF_FREE (fdctx);
- fdctx = NULL;
- gf_log (this->name, GF_LOG_DEBUG,
- "failed to set fd ctx");
- }
- }
-unlock:
- UNLOCK (&fd->lock);
+struct _truncate_ops {
+ loc_t loc;
+ fd_t *fd;
+ off_t offset;
+ enum {TRUNCATE, FTRUNCATE} op;
+};
-out:
- return fdctx;
-}
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)
+ int32_t op_ret, int32_t op_errno, struct stat *prebuf,
+ struct stat *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;
}
static int
truncate_allowed (pl_inode_t *pl_inode,
- client_t *client, pid_t client_pid,
- gf_lkowner_t *owner, off_t offset)
+ transport_t *transport, pid_t client_pid,
+ uint64_t owner, off_t offset)
{
posix_lock_t *l = NULL;
posix_lock_t region = {.list = {0, }, };
@@ -128,9 +85,9 @@ truncate_allowed (pl_inode_t *pl_inode,
region.fl_start = offset;
region.fl_end = LLONG_MAX;
- region.client = client;
+ region.transport = transport;
region.client_pid = client_pid;
- region.owner = *owner;
+ region.owner = owner;
pthread_mutex_lock (&pl_inode->mutex);
{
@@ -139,8 +96,6 @@ truncate_allowed (pl_inode_t *pl_inode,
&& locks_overlap (&region, l)
&& !same_owner (&region, l)) {
ret = 0;
- gf_log ("posix-locks", GF_LOG_TRACE, "Truncate "
- "allowed");
break;
}
}
@@ -153,11 +108,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 stat *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;
@@ -179,6 +133,8 @@ truncate_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
pl_inode = pl_inode_get (this, inode);
if (!pl_inode) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory.");
op_ret = -1;
op_errno = ENOMEM;
goto unwind;
@@ -186,8 +142,8 @@ truncate_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
if (priv->mandatory
&& pl_inode->mandatory
- && !truncate_allowed (pl_inode, frame->root->client,
- frame->root->pid, &frame->root->lk_owner,
+ && !truncate_allowed (pl_inode, frame->root->trans,
+ frame->root->pid, frame->root->lk_owner,
local->offset)) {
op_ret = -1;
op_errno = EAGAIN;
@@ -198,58 +154,52 @@ 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;
}
return 0;
unwind:
- gf_log (this->name, GF_LOG_ERROR, "truncate failed with ret: %d, "
- "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);
- GF_VALIDATE_OR_GOTO (this->name, local, unwind);
+ local = CALLOC (1, sizeof (struct _truncate_ops));
+ if (!local) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory.");
+ goto 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;
}
@@ -257,54 +207,33 @@ 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);
- GF_VALIDATE_OR_GOTO (this->name, local, unwind);
+ local = CALLOC (1, sizeof (struct _truncate_ops));
+ if (!local) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory.");
+ goto 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)
{
@@ -319,7 +248,7 @@ delete_locks_of_fd (xlator_t *this, pl_inode_t *pl_inode, fd_t *fd)
{
list_for_each_entry_safe (l, tmp, &pl_inode->ext_list, list) {
- if (l->fd_num == fd_to_fdnum(fd)) {
+ if ((l->fd_num == fd_to_fdnum(fd))) {
if (l->blocked) {
list_move_tail (&l->list, &blocked_list);
continue;
@@ -334,8 +263,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);
}
@@ -347,7 +275,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,
- client_t *client, gf_lkowner_t *owner)
+ transport_t *transport, uint64_t owner)
{
posix_lock_t *tmp = NULL;
posix_lock_t *l = NULL;
@@ -355,18 +283,16 @@ __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->client == client) &&
- is_same_lkowner (&l->owner, owner)) {
- gf_log ("posix-locks", GF_LOG_TRACE,
+ 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",
- l->fl_type == F_UNLCK ? "Unlock" : "Lock",
- l->client_pid,
- lkowner_utoa (&l->owner),
- l->user_flock.l_start,
- l->user_flock.l_len,
+ "%s (pid=%d) (lk-owner=%"PRIu64") %"PRId64" - %"PRId64" state: %s",
+ l->fl_type == F_UNLCK ? "Unlock" : "Lock",
+ l->client_pid,
+ l->owner,
+ l->user_flock.l_start,
+ l->user_flock.l_len,
l->blocked == 1 ? "Blocked" : "Active");
__delete_lock (pl_inode, l);
@@ -377,580 +303,52 @@ __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)
-{
- int32_t 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,};
- char *brickname = NULL;
-
- 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;
- }
-
- op_ret = fetch_pathinfo (this, loc->inode, &op_errno, &brickname);
- if (op_ret) {
- gf_log (this->name, GF_LOG_WARNING,
- "Couldn't get brickname");
- } else {
- op_ret = format_brickname(brickname);
- if (op_ret) {
- gf_log (this->name, GF_LOG_WARNING,
- "Couldn't format brickname");
- GF_FREE(brickname);
- brickname = NULL;
- }
- }
-
- if (!gcount && !bcount) {
- if (gf_asprintf (&lk_summary, "No locks cleared.") == -1) {
- op_ret = -1;
- op_errno = ENOMEM;
- goto out;
- }
- } else if (gf_asprintf (&lk_summary, "%s: %s blocked locks=%d "
- "granted locks=%d",
- (brickname == NULL)? this->name : brickname,
- (args.type == CLRLK_INODE)? "inode":
- (args.type == CLRLK_ENTRY)? "entry":
- (args.type == CLRLK_POSIX)? "posix": " ",
- bcount, gcount) == -1) {
- op_ret = -1;
- op_errno = ENOMEM;
- goto out;
- }
-
- strncpy (key, name, strlen (name));
- if (dict_set_dynstr (dict, key, lk_summary)) {
- op_ret = -1;
- op_errno = ENOMEM;
- goto out;
- }
-
- op_ret = 0;
-out:
- GF_FREE(brickname);
- 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;
-}
-
-static int
-format_brickname(char *brickname)
-{
- int ret = -1;
- char *hostname = NULL;
- char *volume = NULL;
- char *saveptr = NULL;
-
- if (!brickname)
- goto out;
-
- strtok_r(brickname, ":", &saveptr);
- hostname = gf_strdup(strtok_r(NULL, ":", &saveptr));
- if (hostname == NULL)
- goto out;
- volume = gf_strdup(strtok_r(NULL, ".", &saveptr));
- if (volume == NULL)
- goto out;
-
- sprintf(brickname, "%s:%s", hostname, volume);
-
- ret = 0;
-out:
- GF_FREE(hostname);
- GF_FREE(volume);
- return ret;
-}
-
-static int
-fetch_pathinfo (xlator_t *this, inode_t *inode, int32_t *op_errno,
- char **brickname)
-{
- int ret = -1;
- loc_t loc = {0, };
- dict_t *dict = NULL;
-
- if (!brickname)
- goto out;
-
- if (!op_errno)
- goto out;
-
- uuid_copy (loc.gfid, inode->gfid);
- loc.inode = inode_ref (inode);
-
- ret = syncop_getxattr (FIRST_CHILD(this), &loc, &dict,
- GF_XATTR_PATHINFO_KEY);
- if (ret < 0) {
- *op_errno = -ret;
- ret = -1;
- goto out;
- }
-
- ret = dict_get_str (dict, GF_XATTR_PATHINFO_KEY, brickname);
- if (ret)
- goto out;
-
- *brickname = gf_strdup(*brickname);
- if (*brickname == NULL) {
- ret = -1;
- goto out;
- }
-
- ret = 0;
-out:
- if (dict != NULL) {
- dict_unref (dict);
- }
- loc_wipe(&loc);
-
- return ret;
-}
-
-
-int
-pl_lockinfo_get_brickname (xlator_t *this, inode_t *inode, int32_t *op_errno)
-{
- int ret = -1;
- posix_locks_private_t *priv = NULL;
- char *brickname = NULL;
- char *end = NULL;
- char *tmp = NULL;
-
- priv = this->private;
-
- ret = fetch_pathinfo (this, inode, op_errno, &brickname);
- if (ret)
- goto out;
-
- end = strrchr (brickname, ':');
- if (!end) {
- GF_FREE(brickname);
- ret = -1;
- goto out;
- }
-
- tmp = brickname;
- brickname = gf_strndup (brickname, (end - brickname));
- if (brickname == NULL) {
- ret = -1;
- goto out;
- }
-
- priv->brickname = brickname;
- ret = 0;
-out:
- GF_FREE(tmp);
- return ret;
-}
-
-char *
-pl_lockinfo_key (xlator_t *this, inode_t *inode, int32_t *op_errno)
-{
- posix_locks_private_t *priv = NULL;
- char *key = NULL;
- int ret = 0;
-
- priv = this->private;
-
- if (priv->brickname == NULL) {
- ret = pl_lockinfo_get_brickname (this, inode, op_errno);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_WARNING,
- "cannot get brickname");
- goto out;
- }
- }
-
- key = priv->brickname;
-out:
- return key;
-}
-
-int32_t
-pl_fgetxattr_handle_lockinfo (xlator_t *this, fd_t *fd,
- dict_t *dict, int32_t *op_errno)
-{
- pl_inode_t *pl_inode = NULL;
- char *key = NULL, *buf = NULL;
- int32_t op_ret = 0;
- unsigned long fdnum = 0;
- int32_t len = 0;
- dict_t *tmp = NULL;
-
- pl_inode = pl_inode_get (this, fd->inode);
-
- if (!pl_inode) {
- gf_log (this->name, GF_LOG_DEBUG, "Could not get inode.");
- *op_errno = EBADFD;
- op_ret = -1;
- goto out;
- }
-
- if (!pl_locks_by_fd (pl_inode, fd)) {
- op_ret = 0;
- goto out;
- }
-
- fdnum = fd_to_fdnum (fd);
-
- key = pl_lockinfo_key (this, fd->inode, op_errno);
- if (key == NULL) {
- op_ret = -1;
- goto out;
- }
-
- tmp = dict_new ();
- if (tmp == NULL) {
- op_ret = -1;
- *op_errno = ENOMEM;
- goto out;
- }
-
- op_ret = dict_set_uint64 (tmp, key, fdnum);
- if (op_ret < 0) {
- *op_errno = -op_ret;
- op_ret = -1;
- gf_log (this->name, GF_LOG_WARNING, "setting lockinfo value "
- "(%lu) for fd (ptr:%p inode-gfid:%s) failed (%s)",
- fdnum, fd, uuid_utoa (fd->inode->gfid),
- strerror (*op_errno));
- goto out;
- }
-
- len = dict_serialized_length (tmp);
- if (len < 0) {
- *op_errno = -op_ret;
- op_ret = -1;
- gf_log (this->name, GF_LOG_WARNING,
- "dict_serialized_length failed (%s) while handling "
- "lockinfo for fd (ptr:%p inode-gfid:%s)",
- strerror (*op_errno), fd, uuid_utoa (fd->inode->gfid));
- goto out;
- }
-
- buf = GF_CALLOC (1, len, gf_common_mt_char);
- if (buf == NULL) {
- op_ret = -1;
- *op_errno = ENOMEM;
- goto out;
- }
-
- op_ret = dict_serialize (tmp, buf);
- if (op_ret < 0) {
- *op_errno = -op_ret;
- op_ret = -1;
- gf_log (this->name, GF_LOG_WARNING,
- "dict_serialize failed (%s) while handling lockinfo "
- "for fd (ptr: %p inode-gfid:%s)", strerror (*op_errno),
- fd, uuid_utoa (fd->inode->gfid));
- goto out;
- }
-
- op_ret = dict_set_dynptr (dict, GF_XATTR_LOCKINFO_KEY, buf, len);
- if (op_ret < 0) {
- *op_errno = -op_ret;
- op_ret = -1;
- gf_log (this->name, GF_LOG_WARNING, "setting lockinfo value "
- "(%lu) for fd (ptr:%p inode-gfid:%s) failed (%s)",
- fdnum, fd, uuid_utoa (fd->inode->gfid),
- strerror (*op_errno));
- goto out;
- }
-
- buf = NULL;
-out:
- if (tmp != NULL) {
- dict_unref (tmp);
- }
-
- if (buf != NULL) {
- GF_FREE (buf);
- }
-
- return op_ret;
-}
-
-
-int32_t
-pl_fgetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
- const char *name, dict_t *xdata)
-{
- int32_t op_ret = 0, op_errno = 0;
- dict_t *dict = NULL;
-
- if (!name) {
- goto usual;
- }
-
- if (strcmp (name, GF_XATTR_LOCKINFO_KEY) == 0) {
- dict = dict_new ();
- if (dict == NULL) {
- op_ret = -1;
- op_errno = ENOMEM;
- goto unwind;
- }
-
- op_ret = pl_fgetxattr_handle_lockinfo (this, fd, dict,
- &op_errno);
- if (op_ret < 0) {
- gf_log (this->name, GF_LOG_WARNING,
- "getting lockinfo on fd (ptr:%p inode-gfid:%s) "
- "failed (%s)", fd, uuid_utoa (fd->inode->gfid),
- strerror (op_errno));
- }
-
- goto unwind;
- } else {
- goto usual;
- }
-
-unwind:
- STACK_UNWIND_STRICT (fgetxattr, frame, op_ret, op_errno, dict, NULL);
- if (dict != NULL) {
- dict_unref (dict);
- }
-
- return 0;
-
-usual:
- STACK_WIND (frame, default_fgetxattr_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fgetxattr, fd, name, xdata);
- return 0;
-}
-
-int32_t
-pl_migrate_locks (call_frame_t *frame, fd_t *newfd, uint64_t oldfd_num,
- int32_t *op_errno)
-{
- pl_inode_t *pl_inode = NULL;
- uint64_t newfd_num = 0;
- posix_lock_t *l = NULL;
- int32_t op_ret = 0;
-
- newfd_num = fd_to_fdnum (newfd);
-
- pl_inode = pl_inode_get (frame->this, newfd->inode);
- if (pl_inode == NULL) {
- op_ret = -1;
- *op_errno = EBADFD;
- goto out;
- }
-
- pthread_mutex_lock (&pl_inode->mutex);
- {
- list_for_each_entry (l, &pl_inode->ext_list, list) {
- if (l->fd_num == oldfd_num) {
- l->fd_num = newfd_num;
- l->client = frame->root->client;
- }
- }
- }
- pthread_mutex_unlock (&pl_inode->mutex);
-
- op_ret = 0;
-out:
- return op_ret;
-}
-
-int32_t
-pl_fsetxattr_handle_lockinfo (call_frame_t *frame, fd_t *fd, char *lockinfo_buf,
- int len, int32_t *op_errno)
-{
- int32_t op_ret = -1;
- dict_t *lockinfo = NULL;
- uint64_t oldfd_num = 0;
- char *key = NULL;
-
- lockinfo = dict_new ();
- if (lockinfo == NULL) {
- op_ret = -1;
- *op_errno = ENOMEM;
- goto out;
- }
-
- op_ret = dict_unserialize (lockinfo_buf, len, &lockinfo);
- if (op_ret < 0) {
- *op_errno = -op_ret;
- op_ret = -1;
- goto out;
- }
-
- key = pl_lockinfo_key (frame->this, fd->inode, op_errno);
- if (key == NULL) {
- op_ret = -1;
- goto out;
- }
-
- op_ret = dict_get_uint64 (lockinfo, key, &oldfd_num);
-
- if (oldfd_num == 0) {
- op_ret = 0;
- goto out;
- }
-
- op_ret = pl_migrate_locks (frame, fd, oldfd_num, op_errno);
- if (op_ret < 0) {
- gf_log (frame->this->name, GF_LOG_WARNING,
- "migration of locks from oldfd (ptr:%p) to newfd "
- "(ptr:%p) (inode-gfid:%s)", (void *)oldfd_num, fd,
- uuid_utoa (fd->inode->gfid));
- goto out;
- }
-
-out:
- dict_unref (lockinfo);
-
- return op_ret;
-}
-
-int32_t
-pl_fsetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *dict,
- int32_t flags, dict_t *xdata)
-{
- int32_t op_ret = 0, op_errno = 0;
- void *lockinfo_buf = NULL;
- int len = 0;
-
- op_ret = dict_get_ptr_and_len (dict, GF_XATTR_LOCKINFO_KEY,
- &lockinfo_buf, &len);
- if (lockinfo_buf == NULL) {
- goto usual;
- }
-
- op_ret = pl_fsetxattr_handle_lockinfo (frame, fd, lockinfo_buf, len,
- &op_errno);
- if (op_ret < 0) {
- goto unwind;
- }
-
-usual:
- STACK_WIND (frame, default_fsetxattr_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fsetxattr, fd, dict, flags, xdata);
- return 0;
-
-unwind:
- STACK_UNWIND_STRICT (fsetxattr, frame, op_ret, op_errno, NULL);
- 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;
+ int dummy = 1;
+ int ret = -1;
if (op_ret < 0)
goto unwind;
- fdctx = pl_check_n_create_fdctx (this, fd);
- if (!fdctx) {
- op_errno = ENOMEM;
- op_ret = -1;
- goto unwind;
- }
+ ret = fd_ctx_set (fd, this, dummy);
+ if (ret != 0)
+ gf_log (this->name, GF_LOG_ERROR,
+ "setting context for fd=%p in locks failed.", fd);
unwind:
- STACK_UNWIND_STRICT (opendir,
+ STACK_UNWIND_STRICT (opendir,
frame,
op_ret,
op_errno,
- fd, xdata);
- return 0;
+ fd);
+ return 0;
}
-int32_t
+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);
- return 0;
+ STACK_WIND (frame,
+ pl_opendir_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->opendir,
+ 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;
}
@@ -958,35 +356,40 @@ 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;
+ posix_locks_private_t *priv = NULL;
+ pl_inode_t *pl_inode = NULL;
+ uint64_t owner = -1;
+
+ priv = this->private;
+ 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.
*/
gf_log (this->name, GF_LOG_TRACE,
- "Releasing all locks with fd %p", fd);
+ "Releasing all locks with fd %p", fd);
delete_locks_of_fd (this, pl_inode, fd);
goto wind;
}
pthread_mutex_lock (&pl_inode->mutex);
{
- __delete_locks_of_owner (pl_inode, frame->root->client,
- &frame->root->lk_owner);
+ __delete_locks_of_owner (pl_inode, frame->root->trans,
+ owner);
}
pthread_mutex_unlock (&pl_inode->mutex);
@@ -996,29 +399,28 @@ 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;
+ int dummy = 1;
+ int ret = -1;
if (op_ret < 0)
goto unwind;
- fdctx = pl_check_n_create_fdctx (this, fd);
- if (!fdctx) {
- op_errno = ENOMEM;
- op_ret = -1;
- goto unwind;
- }
+ ret = fd_ctx_set (fd, this, dummy);
+ if (ret != 0)
+ gf_log (this->name, GF_LOG_ERROR,
+ "setting context for fd=%p in locks failed.", fd);
unwind:
- STACK_UNWIND_STRICT (open, frame, op_ret, op_errno, fd, xdata);
+ STACK_UNWIND_STRICT (open, frame, op_ret, op_errno, fd);
return 0;
}
@@ -1026,11 +428,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;
}
@@ -1039,24 +442,23 @@ pl_open (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
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)
+ fd_t *fd, inode_t *inode, struct stat *buf,
+ struct stat *preparent, struct stat *postparent)
{
- pl_fdctx_t *fdctx = NULL;
+ int dummy = 1;
+ int ret = -1;
if (op_ret < 0)
goto unwind;
- fdctx = pl_check_n_create_fdctx (this, fd);
- if (!fdctx) {
- op_errno = ENOMEM;
- op_ret = -1;
- goto unwind;
- }
+ ret = fd_ctx_set (fd, this, dummy);
+ if (ret != 0)
+ gf_log (this->name, GF_LOG_ERROR,
+ "setting context for fd=%p in locks failed.", fd);
unwind:
STACK_UNWIND_STRICT (create, frame, op_ret, op_errno, fd, inode, buf,
- preparent, postparent, xdata);
+ preparent, postparent);
return 0;
}
@@ -1064,12 +466,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)
{
STACK_WIND (frame, pl_create_cbk,
FIRST_CHILD (this), FIRST_CHILD (this)->fops->create,
- loc, flags, mode, umask, fd, xdata);
+ loc, flags, mode, fd);
return 0;
}
@@ -1077,22 +478,21 @@ pl_create (call_frame_t *frame, xlator_t *this,
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 iovec *vector, int32_t count, struct stat *stbuf,
+ struct iobref *iobref)
{
STACK_UNWIND_STRICT (readv, frame, op_ret, op_errno,
- vector, count, stbuf, iobref, xdata);
+ vector, count, stbuf, iobref);
return 0;
}
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)
+ int32_t op_ret, int32_t op_errno, struct stat *prebuf,
+ struct stat *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;
}
@@ -1122,7 +522,7 @@ do_blocked_rw (pl_inode_t *pl_inode)
list_for_each_entry_safe (rw, tmp, &wind_list, list) {
list_del_init (&rw->list);
call_resume (rw->stub);
- GF_FREE (rw);
+ free (rw);
}
return;
@@ -1150,12 +550,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;
}
@@ -1163,7 +563,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;
@@ -1180,7 +580,7 @@ pl_readv (call_frame_t *frame, xlator_t *this,
if (priv->mandatory && pl_inode->mandatory) {
region.fl_start = offset;
region.fl_end = offset + size - 1;
- region.client = frame->root->client;
+ region.transport = frame->root->trans;
region.fd_num = fd_to_fdnum(fd);
region.client_pid = frame->root->pid;
region.owner = frame->root->lk_owner;
@@ -1201,21 +601,23 @@ pl_readv (call_frame_t *frame, xlator_t *this,
goto unlock;
}
- rw = GF_CALLOC (1, sizeof (*rw),
- gf_locks_mt_pl_rw_req_t);
+ rw = CALLOC (1, sizeof (*rw));
if (!rw) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory.");
op_errno = ENOMEM;
op_ret = -1;
goto unlock;
}
rw->stub = fop_readv_stub (frame, pl_readv_cont,
- fd, size, offset, flags,
- xdata);
+ fd, size, offset);
if (!rw->stub) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory.");
op_errno = ENOMEM;
op_ret = -1;
- GF_FREE (rw);
+ free (rw);
goto unlock;
}
@@ -1231,12 +633,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;
}
@@ -1245,11 +647,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;
}
@@ -1258,7 +660,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;
@@ -1268,13 +670,14 @@ 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);
if (priv->mandatory && pl_inode->mandatory) {
region.fl_start = offset;
region.fl_end = offset + iov_length (vector, count) - 1;
- region.client = frame->root->client;
+ region.transport = frame->root->trans;
region.fd_num = fd_to_fdnum(fd);
region.client_pid = frame->root->pid;
region.owner = frame->root->lk_owner;
@@ -1295,9 +698,10 @@ pl_writev (call_frame_t *frame, xlator_t *this, fd_t *fd,
goto unlock;
}
- rw = GF_CALLOC (1, sizeof (*rw),
- gf_locks_mt_pl_rw_req_t);
+ rw = CALLOC (1, sizeof (*rw));
if (!rw) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory.");
op_errno = ENOMEM;
op_ret = -1;
goto unlock;
@@ -1305,11 +709,13 @@ 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) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory.");
op_errno = ENOMEM;
op_ret = -1;
- GF_FREE (rw);
+ free (rw);
goto unlock;
}
@@ -1325,221 +731,57 @@ 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;
}
-static int
-__fd_has_locks (pl_inode_t *pl_inode, fd_t *fd)
-{
- int found = 0;
- posix_lock_t *l = NULL;
-
- list_for_each_entry (l, &pl_inode->ext_list, list) {
- if (l->fd_num == fd_to_fdnum(fd)) {
- found = 1;
- break;
- }
- }
-
- return found;
-}
-
-static posix_lock_t *
-lock_dup (posix_lock_t *lock)
-{
- posix_lock_t *new_lock = NULL;
-
- new_lock = new_posix_lock (&lock->user_flock, lock->client,
- lock->client_pid, &lock->owner,
- (fd_t *)lock->fd_num);
- return new_lock;
-}
-
-static int
-__dup_locks_to_fdctx (pl_inode_t *pl_inode, fd_t *fd,
- pl_fdctx_t *fdctx)
-{
- posix_lock_t *l = NULL;
- posix_lock_t *duplock = NULL;
- int ret = 0;
-
- list_for_each_entry (l, &pl_inode->ext_list, list) {
- if (l->fd_num == fd_to_fdnum(fd)) {
- duplock = lock_dup (l);
- if (!duplock) {
- ret = -1;
- break;
- }
-
- list_add_tail (&duplock->list, &fdctx->locks_list);
- }
- }
-
- return ret;
-}
-
-static int
-__copy_locks_to_fdctx (pl_inode_t *pl_inode, fd_t *fd,
- pl_fdctx_t *fdctx)
-{
- int ret = 0;
-
- ret = __dup_locks_to_fdctx (pl_inode, fd, fdctx);
- if (ret)
- goto out;
-
-out:
- return ret;
-
-}
-
-static void
-pl_mark_eol_lock (posix_lock_t *lock)
-{
- lock->user_flock.l_type = GF_LK_EOL;
- return;
-}
-
-static posix_lock_t *
-__get_next_fdctx_lock (pl_fdctx_t *fdctx)
-{
- posix_lock_t *lock = NULL;
-
- GF_ASSERT (fdctx);
-
- if (list_empty (&fdctx->locks_list)) {
- gf_log (THIS->name, GF_LOG_DEBUG,
- "fdctx lock list empty");
- goto out;
- }
-
- lock = list_entry (fdctx->locks_list.next, typeof (*lock),
- list);
-
- GF_ASSERT (lock);
-
- list_del_init (&lock->list);
-
-out:
- return lock;
-}
-
-static int
-__set_next_lock_fd (pl_fdctx_t *fdctx, posix_lock_t *reqlock)
-{
- posix_lock_t *lock = NULL;
- int ret = 0;
-
- GF_ASSERT (fdctx);
-
- lock = __get_next_fdctx_lock (fdctx);
- if (!lock) {
- gf_log (THIS->name, GF_LOG_DEBUG,
- "marking EOL in reqlock");
- pl_mark_eol_lock (reqlock);
- goto out;
- }
-
- reqlock->user_flock = lock->user_flock;
- reqlock->fl_start = lock->fl_start;
- reqlock->fl_type = lock->fl_type;
- reqlock->fl_end = lock->fl_end;
- reqlock->owner = lock->owner;
-
-out:
- if (lock)
- __destroy_lock (lock);
-
- return ret;
-}
-
-static int
-pl_getlk_fd (xlator_t *this, pl_inode_t *pl_inode,
- fd_t *fd, posix_lock_t *reqlock)
-{
- uint64_t tmp = 0;
- pl_fdctx_t *fdctx = NULL;
- int ret = 0;
-
- pthread_mutex_lock (&pl_inode->mutex);
- {
- if (!__fd_has_locks (pl_inode, fd)) {
- gf_log (this->name, GF_LOG_DEBUG,
- "fd=%p has no active locks", fd);
- ret = 0;
- goto unlock;
- }
-
- gf_log (this->name, GF_LOG_DEBUG,
- "There are active locks on fd");
-
- ret = fd_ctx_get (fd, this, &tmp);
- fdctx = (pl_fdctx_t *)(long) tmp;
-
- if (list_empty (&fdctx->locks_list)) {
- gf_log (this->name, GF_LOG_TRACE,
- "no fdctx -> copying all locks on fd");
-
- ret = __copy_locks_to_fdctx (pl_inode, fd, fdctx);
- if (ret) {
- goto unlock;
- }
-
- ret = __set_next_lock_fd (fdctx, reqlock);
-
- } else {
- gf_log (this->name, GF_LOG_TRACE,
- "fdctx present -> returning the next lock");
- ret = __set_next_lock_fd (fdctx, reqlock);
- if (ret) {
- gf_log (this->name, GF_LOG_DEBUG,
- "could not get next lock of fd");
- goto unlock;
- }
- }
- }
-
-unlock:
- pthread_mutex_unlock (&pl_inode->mutex);
- return ret;
-
-}
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 flock *flock)
{
- 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;
-
- if ((flock->l_start < 0) || (flock->l_len < 0)) {
+ transport_t *transport = NULL;
+ pid_t client_pid = 0;
+ uint64_t owner = 0;
+ posix_locks_private_t *priv = NULL;
+ 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;
+ priv = this->private;
+
+ if ((flock->l_start < 0) || (flock->l_len < 0)) {
op_ret = -1;
- op_errno = EINVAL;
- goto unwind;
- }
+ op_errno = EINVAL;
+ goto unwind;
+ }
pl_inode = pl_inode_get (this, fd->inode);
if (!pl_inode) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory.");
op_ret = -1;
op_errno = ENOMEM;
goto unwind;
}
- reqlock = new_posix_lock (flock, frame->root->client, frame->root->pid,
- &frame->root->lk_owner, fd);
+ reqlock = new_posix_lock (flock, transport, client_pid,
+ owner, fd);
if (!reqlock) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory.");
op_ret = -1;
op_errno = ENOMEM;
goto unwind;
@@ -1549,68 +791,6 @@ pl_lk (call_frame_t *frame, xlator_t *this,
switch (cmd) {
- case F_RESLK_LCKW:
- can_block = 1;
-
- /* fall through */
- case F_RESLK_LCK:
- memcpy (&reqlock->user_flock, flock, sizeof (struct gf_flock));
- reqlock->frame = frame;
- reqlock->this = this;
-
- ret = pl_reserve_setlk (this, pl_inode, reqlock,
- can_block);
- if (ret < 0) {
- if (can_block)
- goto out;
-
- op_ret = -1;
- op_errno = -ret;
- __destroy_lock (reqlock);
- goto unwind;
- }
- /* Finally a getlk and return the call */
- conf = pl_getlk (pl_inode, reqlock);
- if (conf)
- posix_lock_to_flock (conf, flock);
- break;
-
- case F_RESLK_UNLCK:
- reqlock->frame = frame;
- reqlock->this = this;
- ret = pl_reserve_unlock (this, pl_inode, reqlock);
- if (ret < 0) {
- op_ret = -1;
- op_errno = -ret;
- }
- __destroy_lock (reqlock);
- goto unwind;
-
- break;
-
- case F_GETLK_FD:
- reqlock->frame = frame;
- reqlock->this = this;
- ret = pl_verify_reservelk (this, pl_inode, reqlock, can_block);
- GF_ASSERT (ret >= 0);
-
- ret = pl_getlk_fd (this, pl_inode, fd, reqlock);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_DEBUG,
- "getting locks on fd failed");
- op_ret = -1;
- op_errno = ENOLCK;
- goto unwind;
- }
-
- gf_log (this->name, GF_LOG_TRACE,
- "Replying with a lock on fd for healing");
-
- posix_lock_to_flock (reqlock, flock);
- __destroy_lock (reqlock);
-
- break;
-
#if F_GETLK != F_GETLK64
case F_GETLK64:
#endif
@@ -1635,18 +815,12 @@ pl_lk (call_frame_t *frame, xlator_t *this,
case F_SETLK64:
#endif
case F_SETLK:
- memcpy (&reqlock->user_flock, flock, sizeof (struct gf_flock));
- ret = pl_verify_reservelk (this, pl_inode, reqlock, can_block);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_TRACE,
- "Lock blocked due to conflicting reserve lock");
- goto out;
- }
+ memcpy (&reqlock->user_flock, flock, sizeof (struct flock));
ret = pl_setlk (this, pl_inode, reqlock,
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;
}
@@ -1654,22 +828,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;
}
@@ -1684,123 +849,122 @@ pl_forget (xlator_t *this,
posix_lock_t *ext_tmp = NULL;
posix_lock_t *ext_l = NULL;
- struct list_head posixlks_released;
+ struct list_head posixlks_released;
pl_inode_lock_t *ino_tmp = NULL;
pl_inode_lock_t *ino_l = NULL;
- struct list_head inodelks_released;
+ struct list_head inodelks_released;
pl_rw_req_t *rw_tmp = NULL;
pl_rw_req_t *rw_req = NULL;
pl_entry_lock_t *entry_tmp = NULL;
pl_entry_lock_t *entry_l = NULL;
- struct list_head entrylks_released;
+ struct list_head entrylks_released;
pl_dom_list_t *dom = NULL;
pl_dom_list_t *dom_tmp = NULL;
- INIT_LIST_HEAD (&posixlks_released);
- INIT_LIST_HEAD (&inodelks_released);
- INIT_LIST_HEAD (&entrylks_released);
+ INIT_LIST_HEAD (&posixlks_released);
+ INIT_LIST_HEAD (&inodelks_released);
+ INIT_LIST_HEAD (&entrylks_released);
pl_inode = pl_inode_get (this, inode);
- pthread_mutex_lock (&pl_inode->mutex);
- {
-
- if (!list_empty (&pl_inode->rw_list)) {
- gf_log (this->name, GF_LOG_WARNING,
- "Pending R/W requests found, releasing.");
+ pthread_mutex_lock (&pl_inode->mutex);
+ {
- list_for_each_entry_safe (rw_req, rw_tmp, &pl_inode->rw_list,
- list) {
+ if (!list_empty (&pl_inode->rw_list)) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "Pending R/W requests found, releasing.");
- list_del (&rw_req->list);
- GF_FREE (rw_req);
- }
- }
+ list_for_each_entry_safe (rw_req, rw_tmp, &pl_inode->rw_list,
+ list) {
- if (!list_empty (&pl_inode->ext_list)) {
- gf_log (this->name, GF_LOG_WARNING,
- "Pending fcntl locks found, releasing.");
+ list_del (&rw_req->list);
+ FREE (rw_req);
+ }
+ }
- list_for_each_entry_safe (ext_l, ext_tmp, &pl_inode->ext_list,
- list) {
+ if (!list_empty (&pl_inode->ext_list)) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "Pending fcntl locks found, releasing.");
- __delete_lock (pl_inode, ext_l);
- if (ext_l->blocked) {
- list_add_tail (&ext_l->list, &posixlks_released);
- continue;
- }
- __destroy_lock (ext_l);
- }
- }
+ list_for_each_entry_safe (ext_l, ext_tmp, &pl_inode->ext_list,
+ list) {
+ __delete_lock (pl_inode, ext_l);
+ if (ext_l->blocked) {
+ list_add_tail (&ext_l->list, &posixlks_released);
+ continue;
+ }
+ __destroy_lock (ext_l);
+ }
+ }
- list_for_each_entry_safe (dom, dom_tmp, &pl_inode->dom_list, inode_list) {
- if (!list_empty (&dom->inodelk_list)) {
- gf_log (this->name, GF_LOG_WARNING,
- "Pending inode locks found, releasing.");
+ list_for_each_entry_safe (dom, dom_tmp, &pl_inode->dom_list, inode_list) {
- list_for_each_entry_safe (ino_l, ino_tmp, &dom->inodelk_list, list) {
- __delete_inode_lock (ino_l);
- __pl_inodelk_unref (ino_l);
- }
+ if (!list_empty (&dom->inodelk_list)) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "Pending inode locks found, releasing.");
- list_splice_init (&dom->blocked_inodelks, &inodelks_released);
+ list_for_each_entry_safe (ino_l, ino_tmp, &dom->inodelk_list, list) {
+ __delete_inode_lock (ino_l);
+ __destroy_inode_lock (ino_l);
+ }
+ list_splice_init (&dom->blocked_inodelks, &inodelks_released);
+
- }
- if (!list_empty (&dom->entrylk_list)) {
- gf_log (this->name, GF_LOG_WARNING,
- "Pending entry locks found, releasing.");
+ }
+ if (!list_empty (&dom->entrylk_list)) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "Pending entry locks found, releasing.");
- list_for_each_entry_safe (entry_l, entry_tmp, &dom->entrylk_list, domain_list) {
- list_del_init (&entry_l->domain_list);
+ 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);
- GF_FREE (entry_l->connection_id);
- GF_FREE (entry_l);
- }
+ if (entry_l->basename)
+ FREE (entry_l->basename);
+ FREE (entry_l);
+ }
- list_splice_init (&dom->blocked_entrylks, &entrylks_released);
- }
+ list_splice_init (&dom->blocked_entrylks, &entrylks_released);
+ }
- list_del (&dom->inode_list);
- gf_log ("posix-locks", GF_LOG_TRACE,
- " Cleaning up domain: %s", dom->domain);
- GF_FREE ((char *)(dom->domain));
- GF_FREE (dom);
- }
+ list_del (&dom->inode_list);
+ gf_log ("posix-locks", GF_LOG_TRACE,
+ " Cleaning up domain: %s", dom->domain);
+ FREE (dom->domain);
+ FREE (dom);
+ }
- }
- pthread_mutex_unlock (&pl_inode->mutex);
+ }
+ pthread_mutex_unlock (&pl_inode->mutex);
- list_for_each_entry_safe (ext_l, ext_tmp, &posixlks_released, list) {
+ 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);
- __destroy_lock (ext_l);
- }
+ 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) {
+ 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) {
+ 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);
- GF_FREE (entry_l->connection_id);
- GF_FREE (entry_l);
+ STACK_UNWIND_STRICT (entrylk, entry_l->frame, -1, 0);
+ if (entry_l->basename)
+ FREE (entry_l->basename);
+ FREE (entry_l);
- }
+ }
- GF_FREE (pl_inode);
+ FREE (pl_inode);
return 0;
}
@@ -1811,14 +975,8 @@ pl_release (xlator_t *this, fd_t *fd)
pl_inode_t *pl_inode = NULL;
uint64_t tmp_pl_inode = 0;
int ret = -1;
- uint64_t tmp = 0;
- pl_fdctx_t *fdctx = NULL;
- if (fd == NULL) {
- goto out;
- }
-
- ret = inode_ctx_get (fd->inode, this, &tmp_pl_inode);
+ ret = inode_ctx_get (fd->inode, this, &tmp_pl_inode);
if (ret != 0)
goto out;
@@ -1830,48 +988,11 @@ 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) {
- gf_log (this->name, GF_LOG_DEBUG,
- "Could not get fdctx");
- goto out;
- }
-
- fdctx = (pl_fdctx_t *)(long)tmp;
-
- GF_FREE (fdctx);
-out:
- return ret;
-}
-
-int
-pl_releasedir (xlator_t *this, fd_t *fd)
-{
- int ret = -1;
- uint64_t tmp = 0;
- pl_fdctx_t *fdctx = NULL;
- if (fd == NULL) {
- goto out;
- }
-
- ret = fd_ctx_del (fd, this, &tmp);
- if (ret) {
- gf_log (this->name, GF_LOG_DEBUG,
- "Could not get fdctx");
- goto out;
- }
-
- fdctx = (pl_fdctx_t *)(long)tmp;
-
- GF_FREE (fdctx);
out:
return ret;
}
-
-int32_t
+static int32_t
__get_posixlk_count (xlator_t *this, pl_inode_t *pl_inode)
{
posix_lock_t *lock = NULL;
@@ -1879,6 +1000,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++;
}
@@ -1911,24 +1042,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)
{
@@ -1945,34 +1058,19 @@ pl_entrylk_xattr_fill (xlator_t *this, inode_t *inode,
}
void
-pl_inodelk_xattr_fill (xlator_t *this, inode_t *inode, dict_t *dict,
- gf_boolean_t per_dom)
+pl_inodelk_xattr_fill (xlator_t *this, inode_t *inode,
+ dict_t *dict)
{
int32_t count = 0;
int ret = -1;
- char *domname = NULL;
-
-
- if (per_dom){
- ret = dict_get_str (dict, GLUSTERFS_INODELK_DOM_COUNT,
- &domname);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to get "
- "value for key %s",GLUSTERFS_INODELK_DOM_COUNT);
- goto out;
- }
- }
-
- count = get_inodelk_count (this, inode, domname);
+ count = get_inodelk_count (this, inode);
ret = dict_set_int32 (dict, GLUSTERFS_INODELK_COUNT, count);
if (ret < 0) {
- gf_log (this->name, GF_LOG_DEBUG, "Failed to set count for "
- "key %s", GLUSTERFS_INODELK_COUNT);
+ gf_log (this->name, GF_LOG_DEBUG,
+ " dict_set failed on key %s", GLUSTERFS_INODELK_COUNT);
}
-out:
- return;
}
void
@@ -1993,63 +1091,56 @@ pl_posixlk_xattr_fill (xlator_t *this, inode_t *inode,
int32_t
pl_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)
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ inode_t *inode,
+ struct stat *buf,
+ dict_t *dict,
+ struct stat *postparent)
{
pl_local_t *local = NULL;
- GF_VALIDATE_OR_GOTO (this->name, frame->local, out);
+ if (!frame->local) {
+ goto 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, _gf_false);
- if (local->inodelk_dom_count_req)
- pl_inodelk_xattr_fill (this, inode, xdata, _gf_true);
+ 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)
+ FREE (local);
- STACK_UNWIND_STRICT (
- lookup,
- frame,
- op_ret,
- op_errno,
- inode,
- buf,
- xdata,
- postparent);
- return 0;
+out:
+ STACK_UNWIND (frame,
+ 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;
@@ -2058,121 +1149,42 @@ pl_lookup (call_frame_t *frame,
VALIDATE_OR_GOTO (this, out);
VALIDATE_OR_GOTO (loc, out);
- local = mem_get0 (this->local_pool);
- GF_VALIDATE_OR_GOTO (this->name, local, out);
-
- if (xdata) {
- if (dict_get (xdata, GLUSTERFS_ENTRYLK_COUNT))
- local->entrylk_count_req = 1;
- if (dict_get (xdata, GLUSTERFS_INODELK_COUNT))
- local->inodelk_count_req = 1;
- if (dict_get (xdata, GLUSTERFS_INODELK_DOM_COUNT))
- local->inodelk_dom_count_req = 1;
- if (dict_get (xdata, GLUSTERFS_POSIXLK_COUNT))
- local->posixlk_count_req = 1;
- if (dict_get (xdata, GLUSTERFS_PARENT_ENTRYLK))
- local->parent_entrylk_req = 1;
+ local = CALLOC (1, sizeof (*local));
+ if (!local) {
+ ret = -1;
+ gf_log (this->name, GF_LOG_ERROR,
+ " Out of memory");
+ goto out;
}
+ if (dict_get (xattr_req, GLUSTERFS_ENTRYLK_COUNT))
+ local->entrylk_count_req = 1;
+ if (dict_get (xattr_req, GLUSTERFS_INODELK_COUNT))
+ local->inodelk_count_req = 1;
+ if (dict_get (xattr_req, GLUSTERFS_POSIXLK_COUNT))
+ local->posixlk_count_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);
+ STACK_WIND (frame,
+ pl_lookup_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->lookup,
+ loc,
+ xattr_req);
ret = 0;
out:
if (ret == -1)
- 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,
- _gf_false);
- if (local->inodelk_dom_count_req)
- pl_inodelk_xattr_fill (this, entry->inode, entry->dict,
- _gf_true);
- if (local->posixlk_count_req)
- pl_posixlk_xattr_fill (this, entry->inode, entry->dict);
- }
+ STACK_UNWIND_STRICT (lookup, frame, -1, 0, NULL, NULL, NULL, NULL);
-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_INODELK_DOM_COUNT))
- local->inodelk_dom_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;
+ return 0;
}
-
void
-pl_dump_lock (char *str, int size, struct gf_flock *flock,
- gf_lkowner_t *owner, void *trans, char *conn_id,
- time_t *granted_time, time_t *blkd_time, gf_boolean_t active)
+pl_dump_lock (char *str, int size, struct flock *flock, uint64_t owner)
{
- char *type_str = NULL;
- char granted[256] = {0,};
- char blocked[256] = {0,};
-
- if (granted_time)
- gf_time_fmt (granted, sizeof (granted), *granted_time,
- gf_timefmt_FT);
- if (blkd_time)
- gf_time_fmt (blocked, sizeof (blocked), *blkd_time,
- gf_timefmt_FT);
+ char *type_str = NULL;
+
switch (flock->l_type) {
case F_RDLCK:
type_str = "READ";
@@ -2188,32 +1200,12 @@ 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, conn_id,
- 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, conn_id,
- blocked, 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, conn_id, blocked);
- }
+ snprintf (str, size, "type=%s, start=%llu, len=%llu, pid=%llu, lk-owner=%llu",
+ type_str, (unsigned long long) flock->l_start,
+ (unsigned long long) flock->l_len,
+ (unsigned long long) flock->l_pid,
+ (unsigned long long) owner);
+
}
@@ -2222,74 +1214,42 @@ __dump_entrylks (pl_inode_t *pl_inode)
{
pl_dom_list_t *dom = NULL;
pl_entry_lock_t *lock = NULL;
- char blocked[256] = {0,};
- char granted[256] = {0,};
- int count = 0;
- char key[GF_DUMP_MAX_BUF_LEN] = {0,};
- char *k = "xlator.feature.locks.lock-dump.domain.entrylk";
+ int count = 0;
+ char key[GF_DUMP_MAX_BUF_LEN];
- char tmp[4098];
+ char tmp[256];
list_for_each_entry (dom, &pl_inode->dom_list, inode_list) {
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->entrylk_list, domain_list) {
- gf_time_fmt (granted, sizeof (granted),
- lock->granted_time.tv_sec, gf_timefmt_FT);
- gf_proc_dump_build_key(key, k,
- "entrylk[%d](ACTIVE)", count );
- if (lock->blkd_time.tv_sec == 0) {
- snprintf (tmp, sizeof (tmp), ENTRY_GRNTD_FMT,
- lock->type == ENTRYLK_RDLCK ?
- "ENTRYLK_RDLCK" : "ENTRYLK_WRLCK",
- lock->basename,
- (unsigned long long) lock->client_pid,
- lkowner_utoa (&lock->owner),
- lock->client,
- lock->connection_id, granted);
- } else {
- gf_time_fmt (blocked, sizeof (blocked),
- lock->blkd_time.tv_sec,
- gf_timefmt_FT);
- snprintf (tmp, sizeof (tmp),
- 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->client,
- lock->connection_id,
- blocked, granted);
- }
+ gf_proc_dump_build_key(key,
+ "xlator.feature.locks.lock-dump.domain.entrylk",
+ "entrylk[%d](ACTIVE)",count );
+ snprintf (tmp, 256," %s on %s",
+ lock->type == ENTRYLK_RDLCK ? "ENTRYLK_RDLCK" :
+ "ENTRYLK_WRLCK", lock->basename);
gf_proc_dump_write(key, tmp);
count++;
}
- list_for_each_entry (lock, &dom->blocked_entrylks,
- blocked_locks) {
-
- gf_time_fmt (blocked, sizeof (blocked),
- lock->blkd_time.tv_sec, gf_timefmt_FT);
+ list_for_each_entry (lock, &dom->blocked_entrylks, blocked_locks) {
- gf_proc_dump_build_key(key, k,
- "entrylk[%d](BLOCKED)", count );
- snprintf (tmp, sizeof (tmp), ENTRY_BLKD_FMT,
- lock->type == ENTRYLK_RDLCK ?
- "ENTRYLK_RDLCK" : "ENTRYLK_WRLCK",
- lock->basename,
- (unsigned long long) lock->client_pid,
- lkowner_utoa (&lock->owner), lock->client,
- lock->connection_id, blocked);
+ gf_proc_dump_build_key(key,
+ "xlator.feature.locks.lock-dump.domain.entrylk",
+ "entrylk[%d](BLOCKED)",count );
+ snprintf (tmp, 256," %s on %s state = Blocked",
+ lock->type == ENTRYLK_RDLCK ? "ENTRYLK_RDLCK" :
+ "ENTRYLK_WRLCK", lock->basename);
gf_proc_dump_write(key, tmp);
@@ -2297,6 +1257,7 @@ __dump_entrylks (pl_inode_t *pl_inode)
}
}
+
}
void
@@ -2318,30 +1279,24 @@ __dump_inodelks (pl_inode_t *pl_inode)
int count = 0;
char key[GF_DUMP_MAX_BUF_LEN];
- char tmp[4098];
+ char tmp[256];
list_for_each_entry (dom, &pl_inode->dom_list, inode_list) {
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, sizeof (tmp), &lock->user_flock,
- &lock->owner,
- lock->client, lock->connection_id,
- &lock->granted_time.tv_sec,
- &lock->blkd_time.tv_sec,
- _gf_true);
+ pl_dump_lock (tmp, 256, &lock->user_flock, lock->owner);
gf_proc_dump_write(key, tmp);
count++;
@@ -2350,14 +1305,9 @@ __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, sizeof (tmp), &lock->user_flock,
- &lock->owner,
- lock->client, lock->connection_id,
- 0, &lock->blkd_time.tv_sec,
- _gf_false);
+ pl_dump_lock (tmp, 256, &lock->user_flock, lock->owner);
gf_proc_dump_write(key, tmp);
count++;
@@ -2385,24 +1335,23 @@ __dump_posixlks (pl_inode_t *pl_inode)
int count = 0;
char key[GF_DUMP_MAX_BUF_LEN];
- char tmp[4098];
+ char tmp[256];
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, sizeof (tmp), &lock->user_flock,
- &lock->owner, lock->client, NULL,
- &lock->granted_time.tv_sec, &lock->blkd_time.tv_sec,
- (lock->blocked)? _gf_false: _gf_true);
+ pl_dump_lock (tmp, 256, &lock->user_flock, lock->owner);
gf_proc_dump_write(key, tmp);
count++;
}
+
+
+
}
void
@@ -2423,189 +1372,91 @@ 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;
- }
-
- 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)
- 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;
-
- /*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);
-
- 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);
- }
-
- count = __get_inodelk_count (this, pl_inode, NULL);
- if (count) {
- gf_proc_dump_write("inodelk-count", "%d", count);
- __dump_inodelks (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;
-}
+ if (!inode)
+ return -1;
-int32_t
-mem_acct_init (xlator_t *this)
-{
- int ret = -1;
+ ret = inode_ctx_get (inode, this, &tmp_pl_inode);
- if (!this)
+ if (ret != 0)
return ret;
- ret = xlator_mem_acct_init (this, gf_locks_mt_end + 1);
+ pl_inode = (pl_inode_t *)(long)tmp_pl_inode;
- if (ret != 0) {
- gf_log (this->name, GF_LOG_ERROR, "Memory accounting init"
- "failed");
- return ret;
- }
+ if (!pl_inode)
+ return -1;
- return ret;
-}
+ gf_proc_dump_build_key(key,
+ "xlator.feature.locks.inode",
+ "%ld.mandatory",inode->ino);
+ gf_proc_dump_write(key, "%d", pl_inode->mandatory);
-pl_ctx_t*
-pl_ctx_get (client_t *client, xlator_t *xlator)
-{
- void *tmp = NULL;
- pl_ctx_t *ctx = NULL;
+ 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);
- client_ctx_get (client, xlator, &tmp);
+ dump_entrylks(pl_inode);
- ctx = tmp;
+ 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);
- if (ctx != NULL)
- goto out;
+ dump_inodelks(pl_inode);
- ctx = GF_CALLOC (1, sizeof (pl_ctx_t), gf_locks_mt_posix_lock_t);
+ 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);
- if (ctx == NULL)
- goto out;
+ dump_posixlks(pl_inode);
- pthread_mutex_init (&ctx->lock, NULL);
- INIT_LIST_HEAD (&ctx->inodelk_lockers);
- INIT_LIST_HEAD (&ctx->entrylk_lockers);
- if (client_ctx_set (client, xlator, ctx) != 0) {
- pthread_mutex_destroy (&ctx->lock);
- GF_FREE (ctx);
- ctx = NULL;
- }
-out:
- return ctx;
+ return 0;
}
-static int
-pl_client_disconnect_cbk (xlator_t *this, client_t *client)
-{
- pl_ctx_t *pl_ctx = NULL;
-
- pl_ctx = pl_ctx_get (client, this);
-
- pl_inodelk_client_cleanup (this, pl_ctx);
-
- pl_entrylk_client_cleanup (this, pl_ctx);
-
- return 0;
-}
-
-static int
-pl_client_destroy_cbk (xlator_t *this, client_t *client)
+/*
+ * pl_dump_inode - inode dump function for posix locks
+ *
+ */
+int
+pl_dump_inode (xlator_t *this)
{
- void *tmp = NULL;
- pl_ctx_t *pl_ctx = NULL;
-
- pl_client_disconnect_cbk (this, client);
-
- client_ctx_del (client, this, &tmp);
- if (tmp == NULL)
- return 0;
-
- pl_ctx = tmp;
-
- GF_ASSERT (list_empty(&pl_ctx->inodelk_lockers));
- GF_ASSERT (list_empty(&pl_ctx->entrylk_lockers));
+ assert(this);
- pthread_mutex_destroy (&pl_ctx->lock);
- GF_FREE (pl_ctx);
+ if (this->itable) {
+ inode_table_dump(this->itable,
+ "xlator.features.locks.inode_table");
+ }
return 0;
}
+
int
init (xlator_t *this)
{
posix_locks_private_t *priv = NULL;
xlator_list_t *trav = NULL;
data_t *mandatory = NULL;
- data_t *trace = NULL;
- int ret = -1;
+ data_t *trace = NULL;
if (!this->children || this->children->next) {
gf_log (this->name, GF_LOG_CRITICAL,
"FATAL: posix-locks should have exactly one child");
- goto out;
+ return -1;
}
if (!this->parents) {
@@ -2621,43 +1472,28 @@ init (xlator_t *this)
gf_log (this->name, GF_LOG_CRITICAL,
"'locks' translator is not loaded over a storage "
"translator");
- goto out;
+ return -1;
}
- priv = GF_CALLOC (1, sizeof (*priv),
- gf_locks_mt_posix_locks_private_t);
+ priv = CALLOC (1, sizeof (*priv));
mandatory = dict_get (this->options, "mandatory-locks");
if (mandatory)
gf_log (this->name, GF_LOG_WARNING,
"mandatory locks not supported in this minor release.");
- trace = dict_get (this->options, "trace");
- if (trace) {
- if (gf_string2boolean (trace->data,
- &priv->trace) == -1) {
- gf_log (this->name, GF_LOG_ERROR,
- "'trace' takes on only boolean values.");
- goto out;
- }
- }
-
- 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;
- }
+ trace = dict_get (this->options, "trace");
+ if (trace) {
+ if (gf_string2boolean (trace->data,
+ &priv->trace) == -1) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "'trace' takes on only boolean values.");
+ return -1;
+ }
+ }
this->private = priv;
- ret = 0;
-
-out:
- if (ret) {
- GF_FREE (priv);
- }
- return ret;
+ return 0;
}
@@ -2667,11 +1503,7 @@ fini (xlator_t *this)
posix_locks_private_t *priv = NULL;
priv = this->private;
- if (!priv)
- return 0;
- this->private = NULL;
- GF_FREE (priv->brickname);
- GF_FREE (priv);
+ free (priv);
return 0;
}
@@ -2679,23 +1511,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 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 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,
@@ -2712,10 +1542,10 @@ struct xlator_fops fops = {
.fentrylk = pl_fentrylk,
.flush = pl_flush,
.opendir = pl_opendir,
- .readdirp = pl_readdirp,
- .getxattr = pl_getxattr,
- .fgetxattr = pl_fgetxattr,
- .fsetxattr = pl_fsetxattr,
+};
+
+
+struct xlator_mops mops = {
};
struct xlator_dumpops dumpops = {
@@ -2723,11 +1553,8 @@ struct xlator_dumpops dumpops = {
};
struct xlator_cbks cbks = {
- .forget = pl_forget,
- .release = pl_release,
- .releasedir = pl_releasedir,
- .client_destroy = pl_client_destroy_cbk,
- .client_disconnect = pl_client_disconnect_cbk,
+ .forget = pl_forget,
+ .release = pl_release,
};
@@ -2735,8 +1562,8 @@ struct volume_options options[] = {
{ .key = { "mandatory-locks", "mandatory" },
.type = GF_OPTION_TYPE_BOOL
},
- { .key = { "trace" },
- .type = GF_OPTION_TYPE_BOOL
- },
+ { .key = { "trace" },
+ .type = GF_OPTION_TYPE_BOOL
+ },
{ .key = {NULL} },
};
diff --git a/xlators/features/locks/src/reservelk.c b/xlators/features/locks/src/reservelk.c
deleted file mode 100644
index 11abd26d85f..00000000000
--- a/xlators/features/locks/src/reservelk.c
+++ /dev/null
@@ -1,443 +0,0 @@
-/*
- Copyright (c) 2006-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 "compat.h"
-#include "xlator.h"
-#include "inode.h"
-#include "logging.h"
-#include "common-utils.h"
-#include "list.h"
-
-#include "locks.h"
-#include "common.h"
-
-void
-__delete_reserve_lock (posix_lock_t *lock)
-{
- list_del (&lock->list);
-}
-
-void
-__destroy_reserve_lock (posix_lock_t *lock)
-{
- GF_FREE (lock);
-}
-
-/* Return true if the two reservelks have exactly same lock boundaries */
-int
-reservelks_equal (posix_lock_t *l1, posix_lock_t *l2)
-{
- if ((l1->fl_start == l2->fl_start) &&
- (l1->fl_end == l2->fl_end))
- return 1;
-
- return 0;
-}
-
-/* Determine if lock is grantable or not */
-static posix_lock_t *
-__reservelk_grantable (pl_inode_t *pl_inode, posix_lock_t *lock)
-{
- xlator_t *this = NULL;
- posix_lock_t *l = NULL;
- posix_lock_t *ret_lock = NULL;
-
- this = THIS;
-
- if (list_empty (&pl_inode->reservelk_list)) {
- gf_log (this->name, GF_LOG_TRACE,
- "No reservelks in list");
- goto out;
- }
- list_for_each_entry (l, &pl_inode->reservelk_list, list){
- if (reservelks_equal (lock, l)) {
- ret_lock = l;
- break;
- }
- }
-out:
- return ret_lock;
-}
-
-static inline int
-__same_owner_reservelk (posix_lock_t *l1, posix_lock_t *l2)
-{
- return (is_same_lkowner (&l1->owner, &l2->owner));
-
-}
-
-static posix_lock_t *
-__matching_reservelk (pl_inode_t *pl_inode, posix_lock_t *lock)
-{
- posix_lock_t *l = NULL;
-
- if (list_empty (&pl_inode->reservelk_list)) {
- gf_log ("posix-locks", GF_LOG_TRACE,
- "reservelk list empty");
- return NULL;
- }
-
- list_for_each_entry (l, &pl_inode->reservelk_list, list) {
- if (reservelks_equal (l, lock)) {
- gf_log ("posix-locks", GF_LOG_TRACE,
- "equal reservelk found");
- break;
- }
- }
-
- return l;
-}
-
-static int
-__reservelk_conflict (xlator_t *this, pl_inode_t *pl_inode,
- posix_lock_t *lock)
-{
- posix_lock_t *conf = NULL;
- int ret = 0;
-
- conf = __matching_reservelk (pl_inode, lock);
- if (conf) {
- gf_log (this->name, GF_LOG_TRACE,
- "Matching reservelk found");
- if (__same_owner_reservelk (lock, conf)) {
- list_del_init (&conf->list);
- gf_log (this->name, GF_LOG_TRACE,
- "Removing the matching reservelk for setlk to progress");
- GF_FREE (conf);
- ret = 0;
- } else {
- gf_log (this->name, GF_LOG_TRACE,
- "Conflicting reservelk found");
- ret = 1;
- }
-
- }
- return ret;
-
-}
-
-int
-pl_verify_reservelk (xlator_t *this, pl_inode_t *pl_inode,
- posix_lock_t *lock, int can_block)
-{
- int ret = 0;
-
- pthread_mutex_lock (&pl_inode->mutex);
- {
- if (__reservelk_conflict (this, pl_inode, lock)) {
- gf_log (this->name, GF_LOG_TRACE,
- "Found conflicting reservelk. Blocking until reservelk is unlocked.");
- lock->blocked = can_block;
- list_add_tail (&lock->list, &pl_inode->blocked_calls);
- ret = -1;
- goto unlock;
- }
-
- gf_log (this->name, GF_LOG_TRACE,
- "no conflicting reservelk found. Call continuing");
- ret = 0;
-
- }
-unlock:
- pthread_mutex_unlock (&pl_inode->mutex);
-
- return ret;
-
-}
-
-
-/* Determines if lock can be granted and adds the lock. If the lock
- * is blocking, adds it to the blocked_reservelks.
- */
-static int
-__lock_reservelk (xlator_t *this, pl_inode_t *pl_inode, posix_lock_t *lock,
- int can_block)
-{
- posix_lock_t *conf = NULL;
- int ret = -EINVAL;
-
- conf = __reservelk_grantable (pl_inode, lock);
- if (conf){
- ret = -EAGAIN;
- if (can_block == 0)
- goto out;
-
- 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",
- lock->fl_type == F_UNLCK ? "Unlock" : "Lock",
- lock->client_pid,
- lkowner_utoa (&lock->owner),
- lock->user_flock.l_start,
- lock->user_flock.l_len);
-
-
- goto out;
- }
-
- list_add (&lock->list, &pl_inode->reservelk_list);
-
- ret = 0;
-
-out:
- return ret;
-}
-
-static posix_lock_t *
-find_matching_reservelk (posix_lock_t *lock, pl_inode_t *pl_inode)
-{
- posix_lock_t *l = NULL;
- list_for_each_entry (l, &pl_inode->reservelk_list, list) {
- if (reservelks_equal (l, lock))
- return l;
- }
- return NULL;
-}
-
-/* Set F_UNLCK removes a lock which has the exact same lock boundaries
- * as the UNLCK lock specifies. If such a lock is not found, returns invalid
- */
-static posix_lock_t *
-__reserve_unlock_lock (xlator_t *this, posix_lock_t *lock, pl_inode_t *pl_inode)
-{
-
- posix_lock_t *conf = NULL;
-
- conf = find_matching_reservelk (lock, pl_inode);
- if (!conf) {
- gf_log (this->name, GF_LOG_DEBUG,
- " Matching lock not found for unlock");
- goto out;
- }
- __delete_reserve_lock (conf);
- gf_log (this->name, GF_LOG_DEBUG,
- " Matching lock found for unlock");
-
-out:
- return conf;
-
-
-}
-
-static void
-__grant_blocked_reserve_locks (xlator_t *this, pl_inode_t *pl_inode,
- struct list_head *granted)
-{
- int bl_ret = 0;
- posix_lock_t *bl = NULL;
- posix_lock_t *tmp = NULL;
-
- struct list_head blocked_list;
-
- INIT_LIST_HEAD (&blocked_list);
- list_splice_init (&pl_inode->blocked_reservelks, &blocked_list);
-
- list_for_each_entry_safe (bl, tmp, &blocked_list, list) {
-
- list_del_init (&bl->list);
-
- bl_ret = __lock_reservelk (this, pl_inode, bl, 1);
-
- if (bl_ret == 0) {
- list_add (&bl->list, granted);
- }
- }
- return;
-}
-
-/* Grant all reservelks blocked on lock(s) */
-void
-grant_blocked_reserve_locks (xlator_t *this, pl_inode_t *pl_inode)
-{
- struct list_head granted;
- posix_lock_t *lock = NULL;
- posix_lock_t *tmp = NULL;
-
- INIT_LIST_HEAD (&granted);
-
- if (list_empty (&pl_inode->blocked_reservelks)) {
- gf_log (this->name, GF_LOG_TRACE,
- "No blocked locks to be granted");
- return;
- }
-
- pthread_mutex_lock (&pl_inode->mutex);
- {
- __grant_blocked_reserve_locks (this, pl_inode, &granted);
- }
- pthread_mutex_unlock (&pl_inode->mutex);
-
- 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",
- lock->fl_type == F_UNLCK ? "Unlock" : "Lock",
- lock->client_pid,
- lkowner_utoa (&lock->owner),
- lock->user_flock.l_start,
- lock->user_flock.l_len);
-
- STACK_UNWIND_STRICT (lk, lock->frame, 0, 0, &lock->user_flock,
- NULL);
- }
-
-}
-
-static void
-__grant_blocked_lock_calls (xlator_t *this, pl_inode_t *pl_inode,
- struct list_head *granted)
-{
- int bl_ret = 0;
- posix_lock_t *bl = NULL;
- posix_lock_t *tmp = NULL;
-
- struct list_head blocked_list;
-
- INIT_LIST_HEAD (&blocked_list);
- list_splice_init (&pl_inode->blocked_reservelks, &blocked_list);
-
- list_for_each_entry_safe (bl, tmp, &blocked_list, list) {
-
- list_del_init (&bl->list);
-
- bl_ret = pl_verify_reservelk (this, pl_inode, bl, bl->blocked);
-
- if (bl_ret == 0) {
- list_add_tail (&bl->list, granted);
- }
- }
- return;
-}
-
-void
-grant_blocked_lock_calls (xlator_t *this, pl_inode_t *pl_inode)
-{
- struct list_head granted;
- posix_lock_t *lock = NULL;
- posix_lock_t *tmp = NULL;
- fd_t *fd = NULL;
-
- int can_block = 0;
- int32_t cmd = 0;
- int ret = 0;
-
- if (list_empty (&pl_inode->blocked_calls)) {
- gf_log (this->name, GF_LOG_TRACE,
- "No blocked lock calls to be granted");
- return;
- }
-
- pthread_mutex_lock (&pl_inode->mutex);
- {
- __grant_blocked_lock_calls (this, pl_inode, &granted);
- }
- pthread_mutex_unlock (&pl_inode->mutex);
-
- list_for_each_entry_safe (lock, tmp, &granted, list) {
- fd = fd_from_fdnum (lock);
-
- if (lock->blocked) {
- can_block = 1;
- cmd = F_SETLKW;
- }
- else
- cmd = F_SETLK;
-
- lock->blocked = 0;
- ret = pl_setlk (this, pl_inode, lock, can_block);
- if (ret == -1) {
- if (can_block) {
- pl_trace_block (this, lock->frame, fd, NULL,
- cmd, &lock->user_flock, NULL);
- continue;
- } else {
- gf_log (this->name, GF_LOG_DEBUG, "returning EAGAIN");
- 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);
- __destroy_lock (lock);
- }
- }
-
- }
-
-}
-
-
-int
-pl_reserve_unlock (xlator_t *this, pl_inode_t *pl_inode, posix_lock_t *lock)
-{
- posix_lock_t *retlock = NULL;
- int ret = -1;
-
- pthread_mutex_lock (&pl_inode->mutex);
- {
- retlock = __reserve_unlock_lock (this, lock, pl_inode);
- if (!retlock) {
- gf_log (this->name, GF_LOG_DEBUG,
- "Bad Unlock issued on Inode lock");
- ret = -EINVAL;
- goto out;
- }
-
- gf_log (this->name, GF_LOG_TRACE,
- "Reservelk Unlock successful");
- __destroy_reserve_lock (retlock);
- ret = 0;
- }
-out:
- pthread_mutex_unlock (&pl_inode->mutex);
-
- grant_blocked_reserve_locks (this, pl_inode);
- grant_blocked_lock_calls (this, pl_inode);
-
- return ret;
-
-}
-
-int
-pl_reserve_setlk (xlator_t *this, pl_inode_t *pl_inode, posix_lock_t *lock,
- int can_block)
-{
- int ret = -EINVAL;
-
- pthread_mutex_lock (&pl_inode->mutex);
- {
-
- 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",
- lock->fl_type == F_UNLCK ? "Unlock" : "Lock",
- lock->client_pid,
- lkowner_utoa (&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",
- lock->fl_type == F_UNLCK ? "Unlock" : "Lock",
- lock->client_pid,
- lkowner_utoa (&lock->owner),
- lock->fl_start,
- lock->fl_end);
-
- }
- pthread_mutex_unlock (&pl_inode->mutex);
- return ret;
-}
diff --git a/xlators/features/locks/tests/unit-test.c b/xlators/features/locks/tests/unit-test.c
index d2cca32dec3..fc69ce8a9bd 100644
--- a/xlators/features/locks/tests/unit-test.c
+++ b/xlators/features/locks/tests/unit-test.c
@@ -1,12 +1,22 @@
/*
- Copyright (c) 2006-2012 Red Hat, Inc. <http://www.redhat.com>
- This file is part of GlusterFS.
+ Copyright (c) 2006-2009 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 General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that 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"
diff --git a/xlators/features/mac-compat/Makefile.am b/xlators/features/mac-compat/Makefile.am
deleted file mode 100644
index d471a3f9243..00000000000
--- a/xlators/features/mac-compat/Makefile.am
+++ /dev/null
@@ -1,3 +0,0 @@
-SUBDIRS = src
-
-CLEANFILES =
diff --git a/xlators/features/mac-compat/src/Makefile.am b/xlators/features/mac-compat/src/Makefile.am
deleted file mode 100644
index 42ed350e93e..00000000000
--- a/xlators/features/mac-compat/src/Makefile.am
+++ /dev/null
@@ -1,15 +0,0 @@
-xlator_LTLIBRARIES = mac-compat.la
-xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/features
-
-mac_compat_la_LDFLAGS = -module -avoid-version
-
-mac_compat_la_SOURCES = mac-compat.c
-mac_compat_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la
-
-noinst_HEADERS = mac-compat.h
-
-AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src
-
-AM_CFLAGS = -Wall $(GF_CFLAGS)
-
-CLEANFILES =
diff --git a/xlators/features/mac-compat/src/mac-compat.c b/xlators/features/mac-compat/src/mac-compat.c
deleted file mode 100644
index 0eaf563e889..00000000000
--- a/xlators/features/mac-compat/src/mac-compat.c
+++ /dev/null
@@ -1,349 +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 "xlator.h"
-#include "defaults.h"
-#include "compat-errno.h"
-#include "syscall.h"
-#include "mem-pool.h"
-#include "mac-compat.h"
-
-static int
-dict_key_remove_namespace(dict_t *dict, char *key, data_t *value, void *data)
-{
- /*
- char buffer[3*value->len+1];
- int index = 0;
- for (index = 0; index < value->len; index++)
- sprintf(buffer+3*index, " %02x", value->data[index]);
- */
- xlator_t *this = (xlator_t *) data;
- if (strncmp(key, "user.", 5) == 0) {
- dict_set (dict, key + 5, value);
- gf_log (this->name, GF_LOG_DEBUG,
- "remove_namespace_dict: %s -> %s ", key, key + 5);
- dict_del (dict, key);
- }
- return 0;
-}
-
-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)
-{
- intptr_t ax = (intptr_t)this->private;
- int i = 0;
-
- gf_log (this->name, GF_LOG_DEBUG,
- "getxattr_cbk: dict %p private: %p xdata %p ", dict,
- this->private, xdata);
-
- if (dict) {
- dict_foreach(dict, dict_key_remove_namespace, this);
- }
- else {
- // TODO: we expect dict to exist here, don't know why this
- // this is needed
- dict = dict_new();
- }
- gf_log (this->name, GF_LOG_DEBUG,
- "getxattr_cbk: dict %p ax: %ld op_ret %d op_err %d ", dict, ax,
- op_ret, op_errno);
- if ((ax == GF_XATTR_ALL && op_ret >= 0) || ax != GF_XATTR_NONE) {
- op_ret = op_errno = 0;
- for (i = 0; i < GF_XATTR_ALL; i++) {
- if (dict_get (dict, apple_xattr_name[i]))
- continue;
- /* set dummy data */
- gf_log (this->name, GF_LOG_DEBUG,
- "getxattr_cbk: setting dummy data %p, %s", dict,
- apple_xattr_name[i]);
- if (dict_set (dict, apple_xattr_name[i],
- bin_to_data ((void *)apple_xattr_value[i],
- apple_xattr_len[i])) == -1) {
- op_ret = -1;
- op_errno = ENOATTR;
-
- break;
- }
- }
- }
- STACK_UNWIND_STRICT (getxattr, frame, op_ret, op_errno, dict, xdata);
- return 0;
-}
-
-
-static
-int prepend_xattr_user_namespace(dict_t *dict, char *key, data_t *value, void *obj)
-{
- xlator_t *this = (xlator_t *) obj;
- dict_t *newdict = (dict_t *) this->private;
- char *newkey = NULL;
- gf_add_prefix(XATTR_USER_PREFIX, key, &newkey);
- key = newkey;
- dict_set(newdict, (char *)key, value);
- if (newkey)
- GF_FREE(newkey);
- return 0;
-}
-
-intptr_t
-check_name(const char *name, char **newkey)
-{
- intptr_t ax = GF_XATTR_NONE;
- if (name) {
- int i = 0;
- for (i = 0; i < GF_XATTR_ALL; i++) {
- if (strcmp (apple_xattr_name[i], name) == 0) {
- ax = i;
- break;
- }
- }
- gf_add_prefix("user.", name, newkey);
- } else
- ax = GF_XATTR_ALL;
- return ax;
-}
-
-int32_t
-maccomp_getxattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
- const char *name, dict_t *xdata)
-{
- char *newkey = NULL;
- this->private = (void *) check_name(name, &newkey);
-
- gf_log (this->name, GF_LOG_DEBUG,
- "getxattr: name %s private: %p xdata %p ", name,
- this->private, xdata);
- STACK_WIND (frame, maccomp_getxattr_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->getxattr,
- loc, newkey, xdata);
- return 0;
-}
-
-
-int32_t
-maccomp_fgetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
- const char *name, dict_t *xdata)
-{
- char *newkey = NULL;
- this->private = (void *) check_name(name, &newkey);
-
- STACK_WIND (frame, maccomp_getxattr_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fgetxattr,
- fd, newkey, xdata);
- GF_FREE(newkey);
- 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)
-{
- intptr_t ax = (intptr_t)this->private;
-
- if (op_ret == -1 && ax != GF_XATTR_NONE)
- op_ret = op_errno = 0;
- gf_log (this->name, GF_LOG_DEBUG,
- "setxattr_cbk op_ret %d op_errno %d private: %p xdata %p ",
- op_ret, op_errno, this->private, xdata);
- STACK_UNWIND_STRICT (setxattr, frame, op_ret, op_errno, xdata);
- return 0;
-}
-
-int32_t
-maccomp_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct iatt *iatt1,
- struct iatt *iattr2, dict_t *xdata)
-{
- gf_log (this->name, GF_LOG_DEBUG,
- "setattr_cbk op_ret %d op_errno %d private: %p xdata %p ",
- op_ret, op_errno, this->private, xdata);
- STACK_UNWIND_STRICT (setattr, frame, op_ret, op_errno,
- iatt1, iattr2, xdata);
- return 0;
-}
-
-int map_flags(int flags)
-{
- /* DARWIN has different defines on XATTR_ flags.
- There do not seem to be a POSIX standard
- Parse any other flags over.
- NOFOLLOW is always true on Linux and Darwin
- */
- int linux_flags = flags & ~(GF_XATTR_CREATE | GF_XATTR_REPLACE | XATTR_REPLACE);
- if (XATTR_CREATE & flags)
- linux_flags |= GF_XATTR_CREATE;
- if (XATTR_REPLACE & flags)
- linux_flags |= GF_XATTR_REPLACE;
- return linux_flags;
-}
-
-int32_t
-maccomp_fremovexattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
- const char *name, dict_t *xdata)
-{
- char *newkey = NULL;
-
- this->private = (void *) check_name(name, &newkey);
-
- STACK_WIND (frame, default_fremovexattr_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fremovexattr,
- fd, newkey, xdata);
- GF_FREE(newkey);
- return 0;
-}
-
-int32_t
-maccomp_setxattr (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *dict,
- int32_t flags, dict_t *xdata)
-{
- intptr_t ax = GF_XATTR_NONE;
- int i = 0;
-
- for (i = 0; i < GF_XATTR_ALL; i++) {
- if (dict_get (dict, apple_xattr_name[i])) {
- ax = i;
-
- break;
- }
- }
- dict_t *newdict = dict_new();
- this->private = (void *) newdict;
- dict_foreach(dict, prepend_xattr_user_namespace, this);
-
- this->private = (void *)ax;
- int linux_flags = map_flags(flags);
- gf_log (this->name, GF_LOG_DEBUG,
- "setxattr flags: %d -> %d dict %p private: %p xdata %p ",
- flags, linux_flags, dict, this->private, xdata);
- STACK_WIND (frame, maccomp_setxattr_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->setxattr,
- loc, newdict, linux_flags, xdata);
- dict_unref(newdict);
- return 0;
-}
-
-int32_t
-maccomp_setattr (call_frame_t *frame, xlator_t *this, loc_t *loc, struct iatt *iattr,
- int32_t flags, dict_t *xdata)
-{
- gf_log (this->name, GF_LOG_DEBUG,
- "setattr iattr %p private: %p xdata %p ",
- iattr, this->private, xdata);
- STACK_WIND (frame, maccomp_setattr_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->setattr,
- loc, iattr, flags, xdata);
- return 0;
-}
-
-int32_t
-maccomp_removexattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
- const char *name, dict_t *xdata)
-{
- char *newkey = NULL;
- this->private = (void *) check_name(name, &newkey);
-
- STACK_WIND (frame, default_removexattr_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->removexattr,
- loc, newkey, xdata);
-
- gf_log (this->name, GF_LOG_TRACE,
- "removeattr name %p private: %p xdata %p ",
- name, this->private, xdata);
- GF_FREE(newkey);
- 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)
-{
- intptr_t ax = GF_XATTR_NONE;
- int i = 0;
-
- for (i = 0; i < GF_XATTR_ALL; i++) {
- if (dict_get (dict, apple_xattr_name[i])) {
- ax = i;
-
- break;
- }
- }
-
- dict_t *newdict = dict_new();
- this->private = (void *) newdict;
- dict_foreach(dict, prepend_xattr_user_namespace, this);
-
- this->private = (void *)ax;
- int linux_flags = map_flags(flags);
- gf_log (this->name, GF_LOG_DEBUG,
- "fsetxattr flags: %d -> %d dict %p private: %p xdata %p ",
- flags, linux_flags, dict, this->private, xdata);
- STACK_WIND (frame, maccomp_setxattr_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fsetxattr,
- fd, newdict, linux_flags, xdata);
- dict_unref(newdict);
- 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 = {
- .getxattr = maccomp_getxattr,
- .fgetxattr = maccomp_fgetxattr,
- .setxattr = maccomp_setxattr,
- .setattr = maccomp_setattr,
- .fsetxattr = maccomp_fsetxattr,
- .removexattr = maccomp_removexattr,
- .fremovexattr = maccomp_fremovexattr,
-};
-
-struct xlator_cbks cbks;
-
-struct volume_options options[] = {
- { .key = {NULL} },
-};
diff --git a/xlators/features/mac-compat/src/mac-compat.h b/xlators/features/mac-compat/src/mac-compat.h
deleted file mode 100644
index b033ca0e4d8..00000000000
--- a/xlators/features/mac-compat/src/mac-compat.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- Copyright (c) 2014 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 __MAC_COMPAT_H__
-#define __MAC_COMPAT_H__
-
-enum apple_xattr {
- GF_FINDER_INFO_XATTR,
- GF_RESOURCE_FORK_XATTR,
- GF_XATTR_ALL,
- GF_XATTR_NONE
-};
-
-static char *apple_xattr_name[] = {
- [GF_FINDER_INFO_XATTR] = "com.apple.FinderInfo",
- [GF_RESOURCE_FORK_XATTR] = "com.apple.ResourceFork"
-};
-
-static const char *apple_xattr_value[] = {
- [GF_FINDER_INFO_XATTR] =
- /* 1 2 3 4 5 6 7 8 */
- "\0\0\0\0\0\0\0\0"
- "\0\0\0\0\0\0\0\0"
- "\0\0\0\0\0\0\0\0"
- "\0\0\0\0\0\0\0\0",
- [GF_RESOURCE_FORK_XATTR] = ""
-};
-
-static int32_t apple_xattr_len[] = {
- [GF_FINDER_INFO_XATTR] = 32,
- [GF_RESOURCE_FORK_XATTR] = 1
-};
-
-#endif /* __MAC_COMPAT_H__ */
diff --git a/xlators/features/marker/Makefile.am b/xlators/features/marker/Makefile.am
deleted file mode 100644
index a985f42a877..00000000000
--- a/xlators/features/marker/Makefile.am
+++ /dev/null
@@ -1,3 +0,0 @@
-SUBDIRS = src
-
-CLEANFILES =
diff --git a/xlators/features/marker/src/Makefile.am b/xlators/features/marker/src/Makefile.am
deleted file mode 100644
index a7c67647218..00000000000
--- a/xlators/features/marker/src/Makefile.am
+++ /dev/null
@@ -1,17 +0,0 @@
-xlator_LTLIBRARIES = marker.la
-xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/features
-
-marker_la_LDFLAGS = -module -avoid-version
-
-marker_la_SOURCES = marker.c marker-quota.c marker-quota-helper.c marker-common.c
-marker_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la
-
-noinst_HEADERS = marker-mem-types.h marker.h marker-quota.h marker-quota-helper.h marker-common.h $(top_builddir)/xlators/lib/src/libxlator.h
-
-AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \
- -I$(top_srcdir)/xlators/lib/src
-
-AM_CFLAGS = -Wall -fno-strict-aliasing $(GF_CFLAGS)
-
-CLEANFILES =
-
diff --git a/xlators/features/marker/src/marker-common.c b/xlators/features/marker/src/marker-common.c
deleted file mode 100644
index 84a718add97..00000000000
--- a/xlators/features/marker/src/marker-common.c
+++ /dev/null
@@ -1,69 +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 <fnmatch.h>
-#include "marker-common.h"
-
-marker_inode_ctx_t *
-marker_inode_ctx_new ()
-{
- marker_inode_ctx_t *ctx = NULL;
-
- ctx = GF_CALLOC (1, sizeof (marker_inode_ctx_t),
- gf_marker_mt_marker_inode_ctx_t);
- if (ctx == NULL)
- goto out;
-
- ctx->quota_ctx = NULL;
-out:
- return ctx;
-}
-
-int32_t
-marker_force_inode_ctx_get (inode_t *inode, xlator_t *this,
- marker_inode_ctx_t **ctx)
-{
- int32_t ret = -1;
- uint64_t ctx_int = 0;
-
- LOCK (&inode->lock);
- {
- ret = __inode_ctx_get (inode, this, &ctx_int);
- if (ret == 0)
- *ctx = (marker_inode_ctx_t *) (unsigned long)ctx_int;
- else {
- *ctx = marker_inode_ctx_new ();
- if (*ctx == NULL)
- goto unlock;
-
- ret = __inode_ctx_put (inode, this,
- (uint64_t )(unsigned long) *ctx);
- if (ret == -1) {
- GF_FREE (*ctx);
- goto unlock;
- }
- ret = 0;
- }
- }
-unlock: UNLOCK (&inode->lock);
-
- return ret;
-}
-
-int
-marker_filter_quota_xattr (dict_t *dict, char *key,
- data_t *value, void *data)
-{
- dict_del (dict, key);
- return 0;
-}
diff --git a/xlators/features/marker/src/marker-common.h b/xlators/features/marker/src/marker-common.h
deleted file mode 100644
index 23dd846cb0a..00000000000
--- a/xlators/features/marker/src/marker-common.h
+++ /dev/null
@@ -1,27 +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 _MARKER_COMMON_H
-#define _MARKER_COMMON_H
-
-#ifndef _CONFIG_H
-#define _CONFIG_H
-#include "config.h"
-#endif
-
-#include "inode.h"
-#include "xlator.h"
-#include "marker.h"
-
-int32_t
-marker_force_inode_ctx_get (inode_t *, xlator_t *, marker_inode_ctx_t **);
-
-int
-marker_filter_quota_xattr (dict_t *, char *, data_t *, void *);
-#endif
diff --git a/xlators/features/marker/src/marker-mem-types.h b/xlators/features/marker/src/marker-mem-types.h
deleted file mode 100644
index 1f74d504897..00000000000
--- a/xlators/features/marker/src/marker-mem-types.h
+++ /dev/null
@@ -1,25 +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 __MARKER_MEM_TYPES_H__
-#define __MARKER_MEM_TYPES_H__
-
-#include "mem-types.h"
-
-enum gf_marker_mem_types_ {
- gf_marker_mt_marker_conf_t = gf_common_mt_end + 1,
- 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_inode_contribution_t,
- gf_marker_mt_end
-};
-#endif
diff --git a/xlators/features/marker/src/marker-quota-helper.c b/xlators/features/marker/src/marker-quota-helper.c
deleted file mode 100644
index 0ad9bf00409..00000000000
--- a/xlators/features/marker/src/marker-quota-helper.c
+++ /dev/null
@@ -1,429 +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 "locking.h"
-#include "marker-quota.h"
-#include "marker-common.h"
-#include "marker-quota-helper.h"
-#include "marker-mem-types.h"
-
-int
-mq_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 (inode) {
- loc->inode = inode_ref (inode);
- }
-
- if (parent)
- loc->parent = inode_ref (parent);
-
- 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)
- loc_wipe (loc);
-out:
- return ret;
-}
-
-
-int32_t
-mq_inode_loc_fill (const char *parent_gfid, inode_t *inode, loc_t *loc)
-{
- char *resolvedpath = NULL;
- inode_t *parent = NULL;
- int ret = -1;
-
- if ((!inode) || (!loc))
- return ret;
-
- if ((inode) && __is_root_gfid (inode->gfid)) {
- loc->parent = NULL;
- goto ignore_parent;
- }
-
- if (parent_gfid == NULL)
- parent = inode_parent (inode, 0, NULL);
- else
- parent = inode_find (inode->table,
- (unsigned char *) parent_gfid);
-
- if (parent == NULL) {
- gf_log ("marker", GF_LOG_ERROR, "parent is NULL for %s",
- uuid_utoa(inode->gfid));
- goto err;
- }
-
-ignore_parent:
- ret = inode_path (inode, NULL, &resolvedpath);
- if (ret < 0) {
- gf_log ("marker", GF_LOG_ERROR, "failed to resolve path for %s",
- uuid_utoa(inode->gfid));
- goto err;
- }
-
- ret = mq_loc_fill (loc, inode, parent, resolvedpath);
- if (ret < 0)
- goto err;
-
-err:
- if (parent)
- inode_unref (parent);
-
- GF_FREE (resolvedpath);
-
- return ret;
-}
-
-
-quota_inode_ctx_t *
-mq_alloc_inode_ctx ()
-{
- int32_t ret = -1;
- quota_inode_ctx_t *ctx = NULL;
-
- QUOTA_ALLOC (ctx, quota_inode_ctx_t, ret);
- if (ret == -1)
- goto out;
-
- ctx->size = 0;
- ctx->dirty = 0;
- ctx->updation_status = _gf_false;
- LOCK_INIT (&ctx->lock);
- INIT_LIST_HEAD (&ctx->contribution_head);
-out:
- return ctx;
-}
-
-inode_contribution_t *
-mq_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;
-
- list_for_each_entry (temp, &ctx->contribution_head, contri_list) {
- if (uuid_compare (temp->gfid, inode->gfid) == 0) {
- contri = temp;
- goto out;
- }
- }
-out:
- return contri;
-}
-
-
-int32_t
-mq_delete_contribution_node (dict_t *dict, char *key,
- inode_contribution_t *contribution)
-{
- if (dict_get (dict, key) != NULL)
- goto out;
-
- QUOTA_FREE_CONTRIBUTION_NODE (contribution);
-out:
- return 0;
-}
-
-
-inode_contribution_t *
-__mq_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) {
- if (!uuid_is_null (loc->pargfid))
- loc->parent = inode_find (loc->inode->table,
- loc->pargfid);
-
- if (!loc->parent)
- loc->parent = inode_parent (loc->inode, loc->pargfid,
- loc->name);
- 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) {
- goto out;
- }
- }
-
- QUOTA_ALLOC (contribution, inode_contribution_t, ret);
- if (ret == -1)
- goto out;
-
- contribution->contribution = 0;
-
- 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:
- return contribution;
-}
-
-
-inode_contribution_t *
-mq_add_new_contribution_node (xlator_t *this, quota_inode_ctx_t *ctx,
- loc_t *loc)
-{
- inode_contribution_t *contribution = NULL;
-
- if ((ctx == NULL) || (loc == NULL))
- return NULL;
-
- if (((loc->path) && (strcmp (loc->path, "/") == 0))
- || (!loc->path && uuid_is_null (loc->pargfid)))
- return NULL;
-
- LOCK (&ctx->lock);
- {
- contribution = __mq_add_new_contribution_node (this, ctx, loc);
- }
- UNLOCK (&ctx->lock);
-
- return contribution;
-}
-
-
-int32_t
-mq_dict_set_contribution (xlator_t *this, dict_t *dict,
- loc_t *loc)
-{
- int32_t ret = -1;
- char contri_key [512] = {0, };
-
- GF_VALIDATE_OR_GOTO ("marker", this, out);
- GF_VALIDATE_OR_GOTO ("marker", dict, out);
- GF_VALIDATE_OR_GOTO ("marker", loc, out);
-
- if (loc->parent) {
- GET_CONTRI_KEY (contri_key, loc->parent->gfid, ret);
- if (ret < 0) {
- ret = -1;
- goto out;
- }
- } else {
- /* nameless lookup, fetch contributions to all parents */
- GET_CONTRI_KEY (contri_key, NULL, ret);
- }
-
- ret = dict_set_int64 (dict, contri_key, 0);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_WARNING,
- "unable to set dict value on %s.",
- loc->path);
- goto out;
- }
-
- ret = 0;
-out:
- return ret;
-}
-
-
-int32_t
-mq_inode_ctx_get (inode_t *inode, xlator_t *this,
- quota_inode_ctx_t **ctx)
-{
- int32_t ret = -1;
- uint64_t ctx_int = 0;
- marker_inode_ctx_t *mark_ctx = NULL;
-
- GF_VALIDATE_OR_GOTO ("marker", inode, out);
- GF_VALIDATE_OR_GOTO ("marker", this, out);
- GF_VALIDATE_OR_GOTO ("marker", ctx, out);
-
- ret = inode_ctx_get (inode, this, &ctx_int);
- if (ret < 0) {
- ret = -1;
- *ctx = NULL;
- goto out;
- }
-
- mark_ctx = (marker_inode_ctx_t *) (unsigned long)ctx_int;
- if (mark_ctx->quota_ctx == NULL) {
- ret = -1;
- goto out;
- }
-
- *ctx = mark_ctx->quota_ctx;
-
- ret = 0;
-
-out:
- return ret;
-}
-
-
-quota_inode_ctx_t *
-__mq_inode_ctx_new (inode_t *inode, xlator_t *this)
-{
- int32_t ret = -1;
- quota_inode_ctx_t *quota_ctx = NULL;
- marker_inode_ctx_t *mark_ctx = NULL;
-
- ret = marker_force_inode_ctx_get (inode, this, &mark_ctx);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "marker_force_inode_ctx_get() failed");
- goto out;
- }
-
- LOCK (&inode->lock);
- {
- if (mark_ctx->quota_ctx == NULL) {
- quota_ctx = mq_alloc_inode_ctx ();
- if (quota_ctx == NULL) {
- ret = -1;
- goto unlock;
- }
- mark_ctx->quota_ctx = quota_ctx;
- } else {
- quota_ctx = mark_ctx->quota_ctx;
- }
-
- ret = 0;
- }
-unlock:
- UNLOCK (&inode->lock);
-out:
- return quota_ctx;
-}
-
-
-quota_inode_ctx_t *
-mq_inode_ctx_new (inode_t * inode, xlator_t *this)
-{
- return __mq_inode_ctx_new (inode, this);
-}
-
-quota_local_t *
-mq_local_new ()
-{
- quota_local_t *local = NULL;
-
- local = mem_get0 (THIS->local_pool);
- if (!local)
- goto out;
-
- local->ref = 1;
- LOCK_INIT (&local->lock);
-
- local->ctx = NULL;
- local->contri = NULL;
-
-out:
- return local;
-}
-
-quota_local_t *
-mq_local_ref (quota_local_t *local)
-{
- LOCK (&local->lock);
- {
- local->ref ++;
- }
- UNLOCK (&local->lock);
-
- return local;
-}
-
-
-int32_t
-mq_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);
-
- if (ref != 0)
- goto out;
-
- if (local->fd != NULL)
- fd_unref (local->fd);
-
- loc_wipe (&local->loc);
-
- 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
deleted file mode 100644
index b200413b0ad..00000000000
--- a/xlators/features/marker/src/marker-quota-helper.h
+++ /dev/null
@@ -1,76 +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 _MARKER_QUOTA_HELPER_H
-#define _MARKER_QUOTA_HELPER_H
-
-#ifndef _CONFIG_H
-#define _CONFIG_H
-#include "config.h"
-#endif
-
-#include "marker.h"
-
-#define QUOTA_FREE_CONTRIBUTION_NODE(_contribution) \
- do { \
- list_del (&_contribution->contri_list); \
- GF_FREE (_contribution); \
- } while (0)
-
-#define QUOTA_SAFE_INCREMENT(lock, var) \
- do { \
- LOCK (lock); \
- var ++; \
- UNLOCK (lock); \
- } while (0)
-
-#define QUOTA_SAFE_DECREMENT(lock, var, value) \
- do { \
- LOCK (lock); \
- { \
- value = --var; \
- } \
- UNLOCK (lock); \
- } while (0)
-
-inode_contribution_t *
-mq_add_new_contribution_node (xlator_t *, quota_inode_ctx_t *, loc_t *);
-
-int32_t
-mq_dict_set_contribution (xlator_t *, dict_t *, loc_t *);
-
-quota_inode_ctx_t *
-mq_inode_ctx_new (inode_t *, xlator_t *);
-
-int32_t
-mq_inode_ctx_get (inode_t *, xlator_t *, quota_inode_ctx_t **);
-
-int32_t
-mq_delete_contribution_node (dict_t *, char *, inode_contribution_t *);
-
-int32_t
-mq_inode_loc_fill (const char *, inode_t *, loc_t *);
-
-quota_local_t *
-mq_local_new ();
-
-quota_local_t *
-mq_local_ref (quota_local_t *);
-
-int32_t
-mq_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);
-
-#endif
diff --git a/xlators/features/marker/src/marker-quota.c b/xlators/features/marker/src/marker-quota.c
deleted file mode 100644
index b8d7a774377..00000000000
--- a/xlators/features/marker/src/marker-quota.c
+++ /dev/null
@@ -1,2716 +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 "dict.h"
-#include "xlator.h"
-#include "defaults.h"
-#include "libxlator.h"
-#include "common-utils.h"
-#include "byte-order.h"
-#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->parent == NULL) && (uuid_is_null (src->pargfid))
- && !__is_root_gfid (src->inode->gfid))) {
- 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;
-
- conf = this->private;
-
- LOCK (&conf->lock);
- {
- if (++conf->quota_lk_owner == 0) {
- ++conf->quota_lk_owner;
- }
-
- lk_owner = conf->quota_lk_owner;
- }
- UNLOCK (&conf->lock);
-
- set_lk_owner_from_uint64 (&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)
-{
- int32_t ret = -1;
- int32_t len = 0;
- char *path = NULL;
-
- GF_VALIDATE_OR_GOTO ("marker", this, out);
- GF_VALIDATE_OR_GOTO ("marker", newloc, out);
- GF_VALIDATE_OR_GOTO ("marker", oldloc, out);
- GF_VALIDATE_OR_GOTO ("marker", name, out);
-
- newloc->inode = inode_new (oldloc->inode->table);
-
- if (!newloc->inode) {
- ret = -1;
- goto out;
- }
-
- newloc->parent = inode_ref (oldloc->inode);
- uuid_copy (newloc->pargfid, oldloc->inode->gfid);
-
- if (!oldloc->path) {
- ret = loc_path (oldloc, NULL);
- if (ret == -1)
- goto out;
- }
-
- len = strlen (oldloc->path);
-
- if (oldloc->path [len - 1] == '/')
- ret = gf_asprintf ((char **) &path, "%s%s",
- oldloc->path, name);
- else
- ret = gf_asprintf ((char **) &path, "%s/%s",
- oldloc->path, name);
-
- if (ret < 0)
- goto out;
-
- newloc->path = path;
-
- newloc->name = strrchr (newloc->path, '/');
-
- if (newloc->name)
- newloc->name++;
-
- gf_log (this->name, GF_LOG_DEBUG, "path = %s name =%s",
- newloc->path, newloc->name);
-out:
- return ret;
-}
-
-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)
-{
- 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)
-{
- struct gf_flock lock = {0, };
- 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);
-
- return 0;
- }
-
- if (op_ret == 0)
- local->ctx->dirty = 0;
-
- lock.l_type = F_UNLCK;
- lock.l_whence = SEEK_SET;
- lock.l_start = 0;
- 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,
- 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);
-
- 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)
-{
- int32_t ret = -1;
- int64_t *size = NULL;
- dict_t *newdict = NULL;
- quota_local_t *local = NULL;
-
- local = (quota_local_t *) frame->local;
-
- if (op_ret == -1)
- goto err;
-
- if (!dict)
- goto wind;
-
- ret = dict_get_bin (dict, QUOTA_SIZE_KEY, (void **) &size);
- if (ret)
- goto wind;
-
- LOCK (&local->ctx->lock);
- {
- local->ctx->size = ntoh64 (*size);
- }
- UNLOCK (&local->ctx->lock);
-
-wind:
- newdict = dict_new ();
- if (!newdict)
- goto err;
-
- ret = dict_set_int8 (newdict, QUOTA_DIRTY_KEY, 0);
- 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,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->setxattr,
- &local->loc, newdict, 0, NULL);
- 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 (newdict)
- dict_unref (newdict);
-
- return 0;
-}
-
-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)
-{
- int32_t ret = -1;
- dict_t *new_dict = NULL;
- int64_t *size = NULL;
- int64_t *delta = NULL;
- quota_local_t *local = NULL;
-
- local = frame->local;
-
- if (op_ret == -1)
- goto err;
-
- if (dict == NULL) {
- gf_log (this->name, GF_LOG_WARNING,
- "Dict is null while updating the size xattr %s",
- local->loc.path?local->loc.path:"");
- goto err;
- }
-
- ret = dict_get_bin (dict, QUOTA_SIZE_KEY, (void **) &size);
- if (!size) {
- gf_log (this->name, GF_LOG_WARNING,
- "failed to get the size, %s",
- local->loc.path?local->loc.path:"");
- goto err;
- }
-
- QUOTA_ALLOC_OR_GOTO (delta, int64_t, ret, err);
-
- *delta = hton64 (local->sum - ntoh64 (*size));
-
- gf_log (this->name, GF_LOG_DEBUG, "calculated size = %"PRId64", "
- "original size = %"PRIu64
- " path = %s diff = %"PRIu64, local->sum, ntoh64 (*size),
- local->loc.path, ntoh64 (*delta));
-
- new_dict = dict_new ();
- if (!new_dict) {
- errno = ENOMEM;
- goto err;
- }
-
- ret = dict_set_bin (new_dict, QUOTA_SIZE_KEY, delta, 8);
- 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),
- FIRST_CHILD(this)->fops->xattrop, &local->loc,
- GF_XATTROP_ADD_ARRAY64, new_dict, NULL);
-
- 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 (new_dict)
- dict_unref (new_dict);
-
- return 0;
-}
-
-int32_t
-mq_test_and_set_local_err(quota_local_t *local,
- int32_t *val)
-{
- 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;
-
- local = (quota_local_t *) frame->local;
-
- dict = dict_new ();
- if (!dict) {
- ret = -1;
- goto err;
- }
-
- ret = dict_set_int64 (dict, QUOTA_SIZE_KEY, 0);
- 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),
- FIRST_CHILD(this)->fops->lookup, &local->loc, dict);
- ret =0;
-
-err:
- if (ret) {
- local->err = -1;
-
- mq_release_lock_on_dirty_inode (frame, NULL, this, 0, 0, NULL);
- }
-
- 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)
-{
- 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;
-
- frame->local = NULL;
-
- 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);
-
- goto exit;
- }
-
- ret = mq_get_local_err (local, &val);
- if (!ret && val == -2)
- goto exit;
-
- GET_CONTRI_KEY (contri_key, local->loc.inode->gfid, ret);
- if (ret < 0)
- goto out;
-
- if (!dict)
- goto out;
-
- if (dict_get_bin (dict, contri_key, (void **) &contri) == 0)
- local->sum += ntoh64 (*contri);
-
-out:
- LOCK (&local->lock);
- {
- val = --local->dentry_child_count;
- }
- UNLOCK (&local->lock);
-
- if (val == 0) {
- mq_dirty_inode_readdir (local->frame, NULL, this,
- 0, 0, NULL, 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)
-{
- 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);
-
- if (op_ret == -1) {
- gf_log (this->name, GF_LOG_TRACE,
- "readdir failed %s", strerror (op_errno));
- local->err = -1;
-
- mq_release_lock_on_dirty_inode (frame, NULL, this, 0, 0, NULL);
-
- goto end;
- } else if (op_ret == 0) {
- mq_get_dirty_inode_size (frame, this);
-
- goto end;
- }
-
- 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;
-
- }
-
- local->frame = frame;
-
- LOCK (&local->lock);
- {
- local->dentry_child_count = count;
- local->d_off = offset;
- }
- UNLOCK (&local->lock);
-
-
- 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;
- }
-
- ret = mq_loc_fill_from_name (this, &loc, &local->loc,
- entry->d_ino, entry->d_name);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_WARNING, "Couldn't build "
- "loc for %s/%s, returning from updation of "
- "quota attributes",
- uuid_utoa (local->loc.inode->gfid),
- entry->d_name);
- 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)
- goto out;
-
- newframe->local = mq_local_ref (local);
-
- dict = dict_new ();
- if (!dict) {
- ret = -1;
- goto out;
- }
-
- GET_CONTRI_KEY (contri_key, local->loc.inode->gfid, ret);
- if (ret < 0)
- goto out;
-
- ret = dict_set_int64 (dict, contri_key, 0);
- if (ret)
- goto out;
-
- STACK_WIND (newframe,
- mq_get_child_contribution,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->lookup,
- &loc, dict);
-
- offset = entry->d_off;
-
- loc_wipe (&loc);
-
- newframe = NULL;
-
- out:
- if (dict) {
- dict_unref (dict);
- dict = NULL;
- }
-
- if (ret) {
- val = -2;
- mq_test_and_set_local_err (local, &val);
-
- if (newframe) {
- newframe->local = NULL;
- mq_local_unref(this, local);
- QUOTA_STACK_DESTROY (newframe, this);
- }
-
- break;
- }
- }
-
- if (ret && val != -2) {
- mq_release_lock_on_dirty_inode (frame, NULL, this, 0, 0, NULL);
- }
-end:
- mq_local_unref (this, local);
-
- 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_local_t *local = NULL;
-
- local = frame->local;
-
- if (op_ret == -1) {
- local->err = -1;
- mq_release_lock_on_dirty_inode (frame, NULL, this, 0, 0, NULL);
- return 0;
- }
-
- if (local->fd == NULL)
- local->fd = fd_ref (fd);
-
- STACK_WIND (frame,
- mq_readdir_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->readdir,
- local->fd, READDIR_BUF, local->d_off, xdata);
-
- 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)
-{
- int8_t dirty = -1;
- int32_t ret = -1;
- fd_t *fd = NULL;
- quota_local_t *local = NULL;
-
- local = frame->local;
-
- if (op_ret == -1) {
- gf_log (this->name, GF_LOG_ERROR, "failed to get "
- "the dirty xattr for %s", local->loc.path);
- goto err;
- }
-
- if (!dict) {
- ret = -1;
- goto err;
- }
-
- ret = dict_get_int8 (dict, QUOTA_DIRTY_KEY, &dirty);
- if (ret)
- goto err;
-
- //the inode is not dirty anymore
- if (dirty == 0) {
- mq_release_lock_on_dirty_inode (frame, NULL, this, 0, 0, NULL);
-
- return 0;
- }
-
- fd = fd_create (local->loc.inode, frame->root->pid);
-
- 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,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->opendir,
- &local->loc, fd, NULL);
-
- 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);
- }
-
- 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)
-{
- int32_t ret = -1;
- dict_t *xattr_req = NULL;
- quota_local_t *local = NULL;
-
- if (op_ret == -1) {
- mq_dirty_inode_updation_done (frame, NULL, this, 0, 0, NULL);
- return 0;
- }
-
- local = frame->local;
-
- xattr_req = dict_new ();
- if (xattr_req == NULL) {
- ret = -1;
- goto err;
- }
-
- ret = dict_set_int8 (xattr_req, QUOTA_DIRTY_KEY, 0);
- 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,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->lookup,
- &local->loc,
- xattr_req);
- ret = 0;
-
-err:
- if (ret) {
- local->err = -1;
- mq_release_lock_on_dirty_inode(frame, NULL, this, 0, 0, NULL);
- }
-
- if (xattr_req)
- dict_unref (xattr_req);
-
- 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)
-{
- 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;
- goto out;
- }
-
- mq_assign_lk_owner (this, frame);
-
- local = mq_local_new ();
- if (local == NULL)
- goto fr_destroy;
-
- frame->local = local;
- ret = mq_loc_copy (&local->loc, loc);
- if (ret < 0)
- goto fr_destroy;
-
- local->ctx = ctx;
-
- local->contri = contribution;
-
- lock.l_type = F_WRLCK;
- lock.l_whence = SEEK_SET;
- 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,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->inodelk,
- this->name, &local->loc, F_SETLKW, &lock, NULL);
- return 1;
-
-fr_destroy:
- QUOTA_STACK_DESTROY (frame, this);
-out:
-
- return 0;
-}
-
-
-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_local_t *local = NULL;
-
- if (frame == NULL)
- return 0;
-
- 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)
-{
- int32_t ret = -1;
- dict_t *newdict = NULL;
- quota_local_t *local = NULL;
-
- if (op_ret < 0) {
- goto err;
- }
-
- local = frame->local;
-
- if (local->loc.inode->ia_type == IA_IFDIR) {
- newdict = dict_new ();
- if (!newdict) {
- goto err;
- }
-
- ret = dict_set_int8 (newdict, QUOTA_DIRTY_KEY, 0);
- 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,
- 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);
- }
-
- ret = 0;
-
-err:
- if (ret < 0) {
- mq_xattr_creation_release_lock (frame, NULL, this, 0, 0, NULL);
- }
-
- if (newdict != NULL)
- dict_unref (newdict);
-
- return 0;
-}
-
-
-int32_t
-mq_create_xattr (xlator_t *this, call_frame_t *frame)
-{
- int32_t ret = 0;
- int64_t *value = NULL;
- int64_t *size = NULL;
- dict_t *dict = NULL;
- char key[512] = {0, };
- quota_local_t *local = NULL;
- quota_inode_ctx_t *ctx = NULL;
- inode_contribution_t *contri = NULL;
-
- if (frame == NULL || this == NULL)
- return 0;
-
- local = frame->local;
-
- ret = mq_inode_ctx_get (local->loc.inode, this, &ctx);
- if (ret < 0) {
- ctx = mq_inode_ctx_new (local->loc.inode, this);
- if (ctx == NULL) {
- gf_log (this->name, GF_LOG_WARNING,
- "mq_inode_ctx_new failed");
- ret = -1;
- goto out;
- }
- }
-
- dict = dict_new ();
- if (!dict)
- goto out;
-
- if (local->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 ((local->loc.path && strcmp (local->loc.path, "/") != 0)
- || (local->loc.inode && !uuid_is_null (local->loc.inode->gfid) &&
- !__is_root_gfid (local->loc.inode->gfid))
- || (!uuid_is_null (local->loc.gfid)
- && !__is_root_gfid (local->loc.gfid))) {
- 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 ((local->loc.path && strcmp (local->loc.path, "/") != 0)
- || (!uuid_is_null (local->loc.gfid)
- && !__is_root_gfid (local->loc.gfid))
- || (local->loc.inode
- && !uuid_is_null (local->loc.inode->gfid)
- && !__is_root_gfid (local->loc.inode->gfid))) {
- 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;
- }
-
- ret = mq_req_xattr (this, &local->loc, xattr_req);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_WARNING, "cannot request xattr");
- 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_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;
-
- frame = create_frame (this, this->ctx->pool);
- if (!frame) {
- ret = -1;
- goto err;
- }
-
- local = mq_local_new ();
- if (local == NULL) {
- goto err;
- }
-
- frame->local = local;
-
- ret = loc_copy (&local->loc, loc);
- if (ret < 0) {
- goto err;
- }
-
- frame->local = local;
-
- lock.l_len = 0;
- lock.l_start = 0;
- lock.l_type = F_WRLCK;
- lock.l_whence = SEEK_SET;
-
- STACK_WIND (frame,
- mq_get_xattr,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->inodelk,
- this->name, &local->loc, F_SETLKW, &lock, NULL);
-
- return 0;
-
-err:
- QUOTA_STACK_DESTROY (frame, this);
-
- return 0;
-}
-
-
-int32_t
-mq_get_parent_inode_local (xlator_t *this, quota_local_t *local)
-{
- 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", 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_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;
- }
-
- 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;
- }
-
- local->ctx = ctx;
-
- if (list_empty (&ctx->contribution_head)) {
- gf_log_callingfn (this->name, GF_LOG_ERROR,
- "contribution node list is empty");
- ret = -1;
- goto out;
- }
-
- /* Earlier we used to get the next entry in the list maintained
- by the context. In a good situation it works. i.e the next
- parent in the directory hierarchy for this path is obtained.
-
- But consider the below situation:
- mount-point: /mnt/point
- quota enabled directories within mount point: /a, /b, /c
-
- Now when some file (file1) in the directory /c is written some data,
- then to update the directories, marker has to get the contribution
- object for the parent inode, i.e /c.
- Beefore, it was being done by
- local->contri = (inode_contribution_t *) ctx->contribution_head.next;
- It works in the normal situations. But suppose /c is moved to /b.
- Now /b's contribution object is added to the end of the list of
- parents that the file file1 within /b/c is maintaining. Now if
- the file /b/c/file1 is copied to /b/c/new, to update the parent in
- the order c, b and / we cannot go to the next element in the list,
- as in this case the next contribution object would be / and /b's
- contribution will be at the end of the list. So get the proper
- parent's contribution, by searching the entire list.
- */
- contribution = mq_get_contribution_node (local->loc.parent, ctx);
- GF_ASSERT (contribution != NULL);
- local->contri = contribution;
-
- ret = 0;
-out:
- return ret;
-}
-
-
-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)
-{
- QUOTA_STACK_DESTROY (frame, this);
- return 0;
-}
-
-
-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)
-{
- int32_t ret = 0;
- gf_boolean_t status = _gf_false;
- 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);
-
- return 0;
- }
-
- 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);
- } else {
- ret = mq_get_parent_inode_local (this, local);
- if (ret < 0) {
- mq_xattr_updation_done (frame, NULL, this, 0, 0, NULL,
- 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);
- }
- }
-out:
- return 0;
-}
-
-
-//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)
-{
- int32_t ret = 0;
- 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);
- if (ret < 0)
- goto wind;
-
- LOCK (&ctx->lock);
- {
- ctx->dirty = 0;
- }
- 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;
- lock.l_start = 0;
- lock.l_len = 0;
- lock.l_pid = 0;
-
- STACK_WIND (frame,
- mq_inodelk_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->inodelk,
- this->name, &local->parent_loc,
- F_SETLKW, &lock, NULL);
-
- 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)
-{
- int32_t ret = -1;
- int64_t *size = NULL;
- dict_t *newdict = NULL;
- quota_local_t *local = NULL;
- quota_inode_ctx_t *ctx = NULL;
-
- local = frame->local;
-
- if (op_ret == -1) {
- gf_log (this->name, GF_LOG_WARNING, "%s occurred while"
- " updating the size of %s", strerror (op_errno),
- local->parent_loc.path);
-
- goto err;
- }
-
- //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;
- goto err;
- }
-
- ret = dict_get_bin (dict, QUOTA_SIZE_KEY, (void **) &size);
- if (ret < 0) {
- op_errno = EINVAL;
- goto err;
- }
-
- LOCK (&ctx->lock);
- {
- if (size)
- ctx->size = ntoh64 (*size);
- gf_log (this->name, GF_LOG_DEBUG, "%s %"PRId64,
- local->parent_loc.path, ctx->size);
- }
- UNLOCK (&ctx->lock);
- }
-
- newdict = dict_new ();
- if (!newdict) {
- op_errno = ENOMEM;
- goto err;
- }
-
- ret = dict_set_int8 (newdict, QUOTA_DIRTY_KEY, 0);
-
- if (ret == -1) {
- op_errno = -ret;
- 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,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->setxattr,
- &local->parent_loc, newdict, 0, NULL);
-
- ret = 0;
-err:
- if (op_ret == -1 || ret == -1) {
- local->err = op_errno;
-
- mq_release_parent_lock (frame, NULL, this, 0, 0, NULL);
- }
-
- if (newdict)
- dict_unref (newdict);
-
- return 0;
-}
-
-
-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)
-{
- int64_t *size = NULL;
- int32_t ret = -1;
- dict_t *newdict = NULL;
- quota_local_t *local = 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),
- "xattrop call failed: %s", strerror (op_errno));
-
- goto err;
- }
-
- LOCK (&local->contri->lock);
- {
- local->contri->contribution += local->delta;
- }
- UNLOCK (&local->contri->lock);
-
- gf_log_callingfn (this->name, GF_LOG_DEBUG, "path: %s size: %"PRId64
- " contribution:%"PRId64,
- local->loc.path, local->ctx->size,
- local->contri->contribution);
-
- if (dict == NULL) {
- op_errno = EINVAL;
- goto err;
- }
-
- ret = mq_inode_ctx_get (local->parent_loc.inode, this, &ctx);
- if (ret < 0) {
- op_errno = EINVAL;
- goto err;
- }
-
- newdict = dict_new ();
- if (!newdict) {
- op_errno = ENOMEM;
- ret = -1;
- goto err;
- }
-
- QUOTA_ALLOC_OR_GOTO (size, int64_t, ret, err);
-
- *size = hton64 (local->delta);
-
- ret = dict_set_bin (newdict, QUOTA_SIZE_KEY, size, 8);
- if (ret < 0) {
- op_errno = -ret;
- 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,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->xattrop,
- &local->parent_loc,
- GF_XATTROP_ADD_ARRAY64,
- newdict, NULL);
- ret = 0;
-err:
- if (op_ret == -1 || ret < 0) {
- local->err = op_errno;
- mq_release_parent_lock (frame, NULL, this, 0, 0, NULL);
- }
-
- if (newdict)
- dict_unref (newdict);
-
- return 0;
-}
-
-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)
-{
- int32_t ret = -1;
- int64_t *size = NULL, size_int = 0, contri_int = 0;
- 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;
-
- 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));
- goto err;
- }
-
- 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;
- 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;
- 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);
- {
- if (ret < 0)
- contribution->contribution = 0;
- else
- contribution->contribution = ntoh64 (*contri);
-
- contri_int = contribution->contribution;
- }
- 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;
-
- if (local->delta == 0) {
- mq_mark_undirty (frame, NULL, this, 0, 0, NULL, NULL);
- return 0;
- }
-
- newdict = dict_new ();
- if (newdict == NULL) {
- op_errno = ENOMEM;
- ret = -1;
- goto err;
- }
-
- 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,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->xattrop,
- &local->loc,
- GF_XATTROP_ADD_ARRAY64,
- newdict, NULL);
- ret = 0;
-
-err:
- if (op_ret == -1 || ret < 0) {
- local->err = op_errno;
-
- mq_release_parent_lock (frame, NULL, this, 0, 0, NULL);
- }
-
- if (newdict)
- dict_unref (newdict);
-
- return 0;
-}
-
-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)
-{
- int32_t ret = -1;
- char contri_key [512] = {0, };
- dict_t *newdict = NULL;
- quota_local_t *local = 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));
- goto err;
- }
-
- VALIDATE_OR_GOTO (local->ctx, err);
- VALIDATE_OR_GOTO (local->contri, err);
-
- gf_log (this->name, GF_LOG_DEBUG, "%s marked dirty",
- local->parent_loc.path);
-
- //update parent ctx
- ret = mq_inode_ctx_get (local->parent_loc.inode, this, &ctx);
- if (ret == -1) {
- op_errno = EINVAL;
- goto err;
- }
-
- LOCK (&ctx->lock);
- {
- ctx->dirty = 1;
- }
- UNLOCK (&ctx->lock);
-
- newdict = dict_new ();
- if (newdict == NULL) {
- op_errno = ENOMEM;
- 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;
- 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),
- 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);
-
- mq_release_parent_lock (frame, NULL, this, 0, 0, NULL);
- }
-
- if (newdict)
- dict_unref (newdict);
-
- return 0;
-}
-
-int32_t
-mq_markdirty (call_frame_t *frame, void *cookie,
- xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata)
-{
- int32_t ret = -1;
- dict_t *dict = NULL;
- quota_local_t *local = 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)",
- local->parent_loc.path, strerror (op_errno));
-
- local->err = op_errno;
-
- mq_set_ctx_updation_status (local->ctx, _gf_false);
-
- mq_inodelk_cbk (frame, NULL, this, 0, 0, NULL);
-
- return 0;
- }
-
- gf_log (this->name, GF_LOG_TRACE,
- "inodelk succeeded on %s", local->parent_loc.path);
-
- dict = dict_new ();
- if (!dict) {
- ret = -1;
- goto err;
- }
-
- ret = dict_set_int8 (dict, QUOTA_DIRTY_KEY, 1);
- 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,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->setxattr,
- &local->parent_loc, dict, 0, NULL);
-
- 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);
- }
-
- if (dict)
- dict_unref (dict);
-
- return 0;
-}
-
-
-int32_t
-mq_get_lock_on_parent (call_frame_t *frame, xlator_t *this)
-{
- struct gf_flock lock = {0, };
- quota_local_t *local = NULL;
-
- GF_VALIDATE_OR_GOTO ("marker", frame, fr_destroy);
-
- local = frame->local;
- 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,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->inodelk,
- this->name, &local->parent_loc, F_SETLKW, &lock, NULL);
-
- return 0;
-
-fr_destroy:
- QUOTA_STACK_DESTROY (frame, this);
-
- return -1;
-}
-
-int
-mq_prepare_txn_frame (xlator_t *this, loc_t *loc,
- quota_inode_ctx_t *ctx,
- inode_contribution_t *contri,
- call_frame_t **new_frame)
-{
- call_frame_t *frame = NULL;
- int ret = -1;
- quota_local_t *local = NULL;
-
- if (!this || !loc || !new_frame)
- goto err;
-
- frame = create_frame (this, this->ctx->pool);
- if (frame == NULL)
- goto err;
-
- mq_assign_lk_owner (this, frame);
-
- local = mq_local_new ();
- if (local == NULL)
- goto fr_destroy;
-
- frame->local = local;
-
- ret = mq_loc_copy (&local->loc, loc);
- if (ret < 0)
- goto fr_destroy;
-
- ret = mq_inode_loc_fill (NULL, local->loc.parent,
- &local->parent_loc);
- if (ret < 0)
- goto fr_destroy;
-
- local->ctx = ctx;
- local->contri = contri;
-
- ret = 0;
- *new_frame = frame;
-
- return ret;
-
-fr_destroy:
- QUOTA_STACK_DESTROY (frame, this);
-err:
- return ret;
-}
-
-int
-mq_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;
-
- ret = mq_prepare_txn_frame (this, loc, ctx,
- contri, &frame);
- if (ret)
- goto err;
-
- ret = mq_get_lock_on_parent (frame, this);
- if (ret == -1)
- goto err;
-
- return 0;
-
-err:
- mq_set_ctx_updation_status (ctx, _gf_false);
-
- return -1;
-}
-
-
-int
-mq_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;
- 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);
-
- ret = mq_inode_ctx_get (loc->inode, this, &ctx);
- if (ret == -1) {
- gf_log (this->name, GF_LOG_WARNING,
- "inode ctx get failed, aborting quota txn");
- ret = -1;
- goto out;
- }
-
- /* Create the contribution node if its absent. Is it right to
- assume that if the contribution node is not there, then
- create one and proceed instead of returning?
- Reason for this assumption is for hard links. Suppose
- hard link for a file f1 present in a directory d1 is
- created in the directory d2 (as f2). Now, since d2's
- contribution is not there in f1's inode ctx, d2's
- contribution xattr wont be created and will create problems
- for quota operations.
- */
- contribution = mq_get_contribution_node (loc->parent, ctx);
- if (!contribution) {
- if ((loc->path && strcmp (loc->path, "/"))
- || (!uuid_is_null (loc->gfid)
- && !__is_root_gfid (loc->gfid))
- || (loc->inode && !uuid_is_null (loc->inode->gfid)
- && !__is_root_gfid (loc->inode->gfid)))
- gf_log_callingfn (this->name, GF_LOG_TRACE,
- "contribution node for the "
- "path (%s) with parent (%s) "
- "not found", loc->path,
- loc->parent?
- uuid_utoa (loc->parent->gfid):
- NULL);
-
- contribution = mq_add_new_contribution_node (this, ctx, loc);
- if (!contribution) {
- if(loc->path && strcmp (loc->path, "/"))
- gf_log_callingfn (this->name, GF_LOG_WARNING,
- "could not allocate "
- " contribution node for (%s) "
- "parent: (%s)", loc->path,
- loc->parent?
- uuid_utoa (loc->parent->gfid):
- NULL);
- goto out;
- }
- }
-
- /* To improve performance, do not 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;
-out:
- return ret;
-}
-
-
-
-
-
-int32_t
-mq_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);
- if (ret < 0) {
- ctx = mq_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 (!loc->path || (loc->path && strcmp (loc->path, "/") != 0)) {
- contribution = mq_add_new_contribution_node (this, ctx, loc);
- if (contribution == NULL) {
- if (!uuid_is_null (loc->inode->gfid))
- gf_log (this->name, GF_LOG_DEBUG,
- "cannot add a new contribution node "
- "(%s)", uuid_utoa (loc->inode->gfid));
- ret = -1;
- goto err;
- }
- }
-
- ret = dict_get_bin (dict, QUOTA_SIZE_KEY, (void **) &size);
- if (ret < 0)
- goto out;
-
- ret = dict_get_int8 (dict, QUOTA_DIRTY_KEY, &dirty);
- if (ret < 0)
- goto out;
-
- if ((loc->path && strcmp (loc->path, "/") != 0)
- || (!uuid_is_null (loc->gfid) && !__is_root_gfid (loc->gfid))
- || (loc->inode && !uuid_is_null (loc->inode->gfid) &&
- !__is_root_gfid (loc->inode->gfid))) {
- not_root = _gf_true;
-
- GET_CONTRI_KEY (contri_key, contribution->gfid, ret);
- if (ret < 0)
- goto out;
-
- ret = dict_get_bin (dict, contri_key, (void **) &contri);
- if (ret < 0)
- goto out;
-
- LOCK (&contribution->lock);
- {
- contribution->contribution = ntoh64 (*contri);
- contri_int = contribution->contribution;
- }
- UNLOCK (&contribution->lock);
- }
-
- LOCK (&ctx->lock);
- {
- ctx->size = ntoh64 (*size);
- ctx->dirty = dirty;
- size_int = ctx->size;
- }
- UNLOCK (&ctx->lock);
-
- gf_log (this->name, GF_LOG_DEBUG, "size=%"PRId64
- " contri=%"PRId64, size_int, contri_int);
-
- 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);
- }
-
- ret = 0;
-out:
- if (ret)
- mq_set_inode_xattr (this, loc);
-err:
- return ret;
-}
-
-int32_t
-mq_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;
- char contri_key [512] = {0, };
- quota_inode_ctx_t *ctx = NULL;
- inode_contribution_t *contribution = NULL;
-
- ret = mq_inode_ctx_get (loc->inode, this, &ctx);
- if (ret < 0) {
- ctx = mq_inode_ctx_new (loc->inode, this);
- if (ctx == NULL) {
- gf_log (this->name, GF_LOG_WARNING,
- "mq_inode_ctx_new failed");
- ret = -1;
- goto out;
- }
- }
-
- contribution = mq_add_new_contribution_node (this, ctx, loc);
- if (contribution == NULL) {
- gf_log_callingfn (this->name, GF_LOG_DEBUG, "cannot allocate "
- "contribution node (path:%s)", loc->path);
- 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) {
- GET_CONTRI_KEY (contri_key, contribution->gfid, ret);
- if (ret < 0)
- continue;
-
- ret = dict_get_bin (dict, contri_key, (void **) &contri_int);
- 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);
-
- gf_log (this->name, GF_LOG_DEBUG,
- "size=%"PRId64 " contri=%"PRId64, size, contri_int);
-
- if (size != contri_int) {
- mq_initiate_quota_txn (this, loc);
- }
- } else {
- if (size)
- mq_initiate_quota_txn (this, loc);
- else
- mq_set_inode_xattr (this, loc);
- }
- }
-
-out:
- return ret;
-}
-
-int32_t
-mq_xattr_state (xlator_t *this,
- loc_t *loc,
- dict_t *dict,
- struct iatt buf)
-{
- if (((buf.ia_type == IA_IFREG) && !dht_is_linkfile (&buf, dict))
- || (buf.ia_type == IA_IFLNK)) {
- mq_inspect_file_xattr (this, loc, dict, buf);
- } else if (buf.ia_type == IA_IFDIR)
- mq_inspect_directory_xattr (this, loc, dict, buf);
-
- return 0;
-}
-
-int32_t
-mq_req_xattr (xlator_t *this,
- loc_t *loc,
- dict_t *dict)
-{
- int32_t ret = -1;
-
- GF_VALIDATE_OR_GOTO ("marker", this, out);
- GF_VALIDATE_OR_GOTO ("marker", dict, out);
-
- if (!loc)
- goto set_size;
-
- //if not "/" then request contribution
- if (loc->path && strcmp (loc->path, "/") == 0)
- goto set_size;
-
- ret = mq_dict_set_contribution (this, dict, loc);
- if (ret == -1)
- goto out;
-
-set_size:
- ret = dict_set_uint64 (dict, QUOTA_SIZE_KEY, 0);
- if (ret < 0) {
- ret = -1;
- goto out;
- }
-
- ret = dict_set_int8 (dict, QUOTA_DIRTY_KEY, 0);
- if (ret < 0) {
- ret = -1;
- goto out;
- }
-
- ret = 0;
-
-out:
- return ret;
-}
-
-
-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_STACK_DESTROY (frame, this);
-
- 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 *xdata)
-{
- int32_t ret = 0;
- char contri_key [512] = {0, };
- quota_local_t *local = NULL;
- inode_t *inode = NULL;
- dentry_t *tmp = NULL;
- gf_boolean_t last_dentry = _gf_true;
- loc_t loc = {0, };
- dentry_t *other_dentry = NULL;
- gf_boolean_t remove = _gf_false;
-
- local = (quota_local_t *) frame->local;
-
- if (op_ret == -1 || local->err == -1) {
- mq_removexattr_cbk (frame, NULL, this, -1, 0, NULL);
- return 0;
- }
-
- frame->local = NULL;
-
- GET_CONTRI_KEY (contri_key, local->contri->gfid, ret);
-
- if (!local->loc.inode)
- inode = inode_grep (local->loc.parent->table, local->loc.parent,
- local->loc.name);
- else
- inode = inode_ref (local->loc.inode);
-
- /* Suppose there are 2 directories dir1 and dir2. Quota limit is set on
- both the directories. There is a file (f1) in dir1. A hark link is
- created for that file inside the directory dir2 (say f2). Now one
- more xattr is set in the inode as a new hard link is created in a
- separate directory.
- i.e trusted.glusterfs.quota.<gfid of dir2>.contri=<contribution>
-
- Now when the hardlink f2 is removed, then the new xattr added (i.e
- the xattr indicating its contribution to ITS parent directory) should
- be removed (IFF there is not another hardlink for that file in the
- same directory).
-
- To do that upon getting unlink first check whether any other hard
- links for the same inode exists in the same directory. If so do not
- do anything and proceed for quota transaction.
- Otherwise, if the removed entry was the only link for that inode
- within that directory, then get another dentry for the inode
- (by traversing the list of dentries for the inode) and using the
- the dentry's parent and name, send removexattr so that the xattr
- is removed.
-
- If it is not done, then if the volume is restarted or the brick
- process is restarted, then wrong quota usage will be shown for the
- directory dir2.
- */
- if (inode) {
- tmp = NULL;
- list_for_each_entry (tmp, &inode->dentry_list, inode_list) {
- if (local->loc.parent == tmp->parent) {
- if (strcmp (local->loc.name, local->loc.name)) {
- last_dentry = _gf_false;
- break;
- }
- }
- }
- remove = last_dentry;
- }
-
- if (remove) {
- if (!other_dentry) {
- list_for_each_entry (tmp, &inode->dentry_list,
- inode_list) {
- if (local->loc.parent != tmp->parent) {
- other_dentry = tmp;
- break;
- }
- }
- }
-
- if (!other_dentry)
- mq_removexattr_cbk (frame, NULL, this, 0, 0, NULL);
- else {
- loc.parent = inode_ref (other_dentry->parent);
- loc.name = gf_strdup (other_dentry->name);
- uuid_copy (loc.pargfid , other_dentry->parent->gfid);
- loc.inode = inode_ref (inode);
- uuid_copy (loc.gfid, inode->gfid);
- inode_path (other_dentry->parent, other_dentry->name,
- (char **)&loc.path);
-
- STACK_WIND (frame, mq_removexattr_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->removexattr,
- &loc, contri_key, NULL);
- }
- } else
- mq_removexattr_cbk (frame, NULL, this, 0, 0, NULL);
-
- ret = 0;
-
- if (strcmp (local->parent_loc.path, "/") != 0) {
- ret = mq_get_parent_inode_local (this, local);
- if (ret < 0)
- goto out;
-
- mq_start_quota_txn (this, &local->loc, local->ctx, local->contri);
- }
-out:
- mq_local_unref (this, local);
-
- loc_wipe (&loc);
- inode_unref (inode);
- 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 ret = -1;
- struct gf_flock lock = {0, };
- quota_inode_ctx_t *ctx = NULL;
- quota_local_t *local = NULL;
- int64_t contribution = 0;
-
- 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);
-
- LOCK (&local->contri->lock);
- {
- local->contri->contribution = 0;
- }
- UNLOCK (&local->contri->lock);
- }
- }
-
- 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_remove_done,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->inodelk,
- this->name, &local->parent_loc,
- F_SETLKW, &lock, NULL);
- 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)
-{
- int32_t ret = -1;
- int64_t *size = NULL;
- dict_t *dict = NULL;
- quota_local_t *local = NULL;
-
- local = frame->local;
- if (op_ret == -1) {
- gf_log (this->name, GF_LOG_WARNING,
- "inodelk set failed on %s", local->parent_loc.path);
- QUOTA_STACK_DESTROY (frame, this);
- return 0;
- }
-
- VALIDATE_OR_GOTO (local->contri, err);
-
- dict = dict_new ();
- if (dict == NULL) {
- ret = -1;
- goto err;
- }
-
- QUOTA_ALLOC_OR_GOTO (size, int64_t, ret, err);
-
- *size = hton64 (-local->size);
-
- 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);
- dict_unref (dict);
- return 0;
-
-err:
- local->err = 1;
- mq_inode_remove_done (frame, NULL, this, -1, 0, NULL, NULL);
- if (dict)
- dict_unref (dict);
- return 0;
-}
-
-int32_t
-mq_reduce_parent_size (xlator_t *this, loc_t *loc, int64_t contri)
-{
- int32_t ret = -1;
- struct gf_flock lock = {0,};
- call_frame_t *frame = NULL;
- quota_local_t *local = NULL;
- 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);
-
- ret = mq_inode_ctx_get (loc->inode, this, &ctx);
- if (ret < 0)
- goto out;
-
- contribution = mq_get_contribution_node (loc->parent, ctx);
- if (contribution == NULL) {
- gf_log_callingfn (this->name, GF_LOG_WARNING, "contribution for"
- " the node %s is NULL", loc->path);
- goto out;
- }
-
- local = mq_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) {
- gf_log_callingfn (this->name, GF_LOG_TRACE,
- "local->size is 0 " "path: (%s)", loc->path);
- ret = 0;
- goto out;
- }
-
- ret = mq_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);
- if (ret < 0) {
- gf_log_callingfn (this->name, GF_LOG_INFO, "building parent loc"
- " failed. (gfid: %s)",
- uuid_utoa (loc->parent->gfid));
- goto out;
- }
-
- frame = create_frame (this, this->ctx->pool);
- if (!frame) {
- ret = -1;
- goto out;
- }
-
- mq_assign_lk_owner (this, frame);
-
- frame->local = local;
-
- lock.l_len = 0;
- lock.l_start = 0;
- 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;
- ret = 0;
-
-out:
- if (local != NULL)
- mq_local_unref (this, local);
-
- return ret;
-}
-
-
-int32_t
-init_quota_priv (xlator_t *this)
-{
- return 0;
-}
-
-
-int32_t
-mq_rename_update_newpath (xlator_t *this, loc_t *loc)
-{
- 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);
-
- ret = mq_inode_ctx_get (loc->inode, this, &ctx);
- if (ret < 0)
- goto out;
-
- contribution = mq_add_new_contribution_node (this, ctx, loc);
- if (contribution == NULL) {
- ret = -1;
- goto out;
- }
-
- mq_initiate_quota_txn (this, loc);
-out:
- return ret;
-}
-
-int32_t
-mq_forget (xlator_t *this, quota_inode_ctx_t *ctx)
-{
- inode_contribution_t *contri = NULL;
- inode_contribution_t *next = NULL;
-
- GF_VALIDATE_OR_GOTO ("marker", this, out);
- GF_VALIDATE_OR_GOTO ("marker", ctx, out);
-
- list_for_each_entry_safe (contri, next, &ctx->contribution_head,
- contri_list) {
- list_del (&contri->contri_list);
- GF_FREE (contri);
- }
-
- LOCK_DESTROY (&ctx->lock);
- GF_FREE (ctx);
-out:
- return 0;
-}
diff --git a/xlators/features/marker/src/marker-quota.h b/xlators/features/marker/src/marker-quota.h
deleted file mode 100644
index 42def9d22dc..00000000000
--- a/xlators/features/marker/src/marker-quota.h
+++ /dev/null
@@ -1,135 +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 _MARKER_QUOTA_H
-#define _MARKER_QUOTA_H
-
-#ifndef _CONFIG_H
-#define _CONFIG_H
-#include "config.h"
-#endif
-
-#include "xlator.h"
-#include "marker-mem-types.h"
-
-#define QUOTA_XATTR_PREFIX "trusted.glusterfs"
-#define QUOTA_DIRTY_KEY "trusted.glusterfs.quota.dirty"
-
-#define CONTRIBUTION "contri"
-#define CONTRI_KEY_MAX 512
-#define READDIR_BUF 4096
-
-
-#define QUOTA_STACK_DESTROY(_frame, _this) \
- do { \
- quota_local_t *_local = NULL; \
- _local = _frame->local; \
- _frame->local = NULL; \
- STACK_DESTROY (_frame->root); \
- mq_local_unref (_this, _local); \
- } while (0)
-
-
-#define QUOTA_ALLOC(var, type, ret) \
- do { \
- ret = 0; \
- var = GF_CALLOC (sizeof (type), 1, \
- gf_marker_mt_##type); \
- if (!var) { \
- ret = -1; \
- } \
- } while (0);
-
-#define QUOTA_ALLOC_OR_GOTO(var, type, ret, label) \
- do { \
- var = GF_CALLOC (sizeof (type), 1, \
- gf_marker_mt_##type); \
- if (!var) { \
- gf_log ("", GF_LOG_ERROR, \
- "out of memory"); \
- ret = -1; \
- goto label; \
- } \
- ret = 0; \
- } while (0);
-
-#define GET_CONTRI_KEY(var, _gfid, _ret) \
- do { \
- if (_gfid != NULL) { \
- char _gfid_unparsed[40]; \
- uuid_unparse (_gfid, _gfid_unparsed); \
- _ret = snprintf (var, CONTRI_KEY_MAX, \
- QUOTA_XATTR_PREFIX \
- ".%s.%s." CONTRIBUTION, "quota", \
- _gfid_unparsed); \
- } else { \
- _ret = snprintf (var, CONTRI_KEY_MAX, \
- QUOTA_XATTR_PREFIX \
- ".%s.." CONTRIBUTION, "quota"); \
- } \
- } while (0);
-
-#define QUOTA_SAFE_INCREMENT(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;
-};
-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;
-};
-typedef struct inode_contribution inode_contribution_t;
-
-int32_t
-mq_get_lock_on_parent (call_frame_t *, xlator_t *);
-
-int32_t
-mq_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);
-
-int32_t
-mq_set_inode_xattr (xlator_t *, loc_t *);
-
-int
-mq_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 *);
-
-int32_t
-mq_reduce_parent_size (xlator_t *, loc_t *, int64_t);
-
-int32_t
-mq_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);
-
-int32_t
-mq_forget (xlator_t *, quota_inode_ctx_t *);
-#endif
diff --git a/xlators/features/marker/src/marker.c b/xlators/features/marker/src/marker.c
deleted file mode 100644
index 1814cdc8f8e..00000000000
--- a/xlators/features/marker/src/marker.c
+++ /dev/null
@@ -1,3197 +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 "xlator.h"
-#include "defaults.h"
-#include "libxlator.h"
-#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"
-#include "syncop.h"
-
-#include <fnmatch.h>
-
-#define _GF_UID_GID_CHANGED 1
-
-static char *quota_external_xattrs[] = {
- QUOTA_SIZE_KEY,
- QUOTA_LIMIT_KEY,
- NULL,
-};
-
-void
-fini (xlator_t *this);
-
-int32_t
-marker_start_setxattr (call_frame_t *, xlator_t *);
-
-marker_local_t *
-marker_local_ref (marker_local_t *local)
-{
- GF_VALIDATE_OR_GOTO ("marker", local, err);
-
- LOCK (&local->lock);
- {
- local->ref++;
- }
- UNLOCK (&local->lock);
-
- return local;
-err:
- return NULL;
-}
-
-int
-marker_loc_fill (loc_t *loc, inode_t *inode, inode_t *parent, char *path)
-{
- int ret = -1;
-
- if (!loc)
- return ret;
-
- if (inode) {
- loc->inode = inode_ref (inode);
- if (uuid_is_null (loc->gfid)) {
- uuid_copy (loc->gfid, loc->inode->gfid);
- }
- }
-
- 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++;
- }
-
- ret = 0;
-loc_wipe:
- if (ret < 0)
- loc_wipe (loc);
-
- return ret;
-}
-
-int
-marker_inode_loc_fill (inode_t *inode, char *name, loc_t *loc)
-{
- char *resolvedpath = NULL;
- int ret = -1;
- inode_t *parent = NULL;
-
- if ((!inode) || (!loc))
- return ret;
-
- parent = inode_parent (inode, NULL, NULL);
-
- ret = inode_path (inode, name, &resolvedpath);
- if (ret < 0)
- goto err;
-
- ret = marker_loc_fill (loc, inode, parent, resolvedpath);
- if (ret < 0)
- goto err;
-
-err:
- if (parent)
- inode_unref (parent);
-
- GF_FREE (resolvedpath);
-
- return ret;
-}
-
-int32_t
-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, NULL, &loc);
-
- if (ret < 0) {
- ret = -1;
- goto out;
- }
-
- loc_wipe (&local->loc);
-
- local->loc = loc;
-out:
- if (need_unref)
- inode_unref (parent);
-
- return ret;
-}
-
-int32_t
-marker_error_handler (xlator_t *this, marker_local_t *local, int32_t op_errno)
-{
- marker_conf_t *priv = NULL;
- const char *path = NULL;
-
- priv = (marker_conf_t *) this->private;
- path = local
- ? (local->loc.path
- ? local->loc.path : uuid_utoa(local->loc.gfid))
- : "<nul>";
-
- gf_log (this->name, GF_LOG_CRITICAL,
- "Indexing gone corrupt at %s (reason: %s)."
- " Geo-replication slave content needs to be revalidated",
- path, strerror (op_errno));
- unlink (priv->timestamp_file);
-
- return 0;
-}
-
-int32_t
-marker_local_unref (marker_local_t *local)
-{
- int32_t var = 0;
-
- if (local == NULL)
- return -1;
-
- LOCK (&local->lock);
- {
- var = --local->ref;
- }
- UNLOCK (&local->lock);
-
- if (var != 0)
- goto out;
-
- loc_wipe (&local->loc);
- loc_wipe (&local->parent_loc);
- if (local->xdata)
- dict_unref (local->xdata);
-
- if (local->oplocal) {
- marker_local_unref (local->oplocal);
- local->oplocal = NULL;
- }
- mem_put (local);
-out:
- return 0;
-}
-
-int32_t
-stat_stampfile (xlator_t *this, marker_conf_t *priv,
- struct volume_mark **status)
-{
- struct stat buf = {0, };
- struct volume_mark *vol_mark = NULL;
-
- vol_mark = GF_CALLOC (sizeof (struct volume_mark), 1,
- gf_marker_mt_volume_mark);
-
- vol_mark->major = 1;
- vol_mark->minor = 0;
-
- GF_ASSERT (sizeof (priv->volume_uuid_bin) == 16);
- memcpy (vol_mark->uuid, priv->volume_uuid_bin, 16);
-
- if (stat (priv->timestamp_file, &buf) != -1) {
- vol_mark->retval = 0;
- vol_mark->sec = htonl (buf.st_mtime);
- vol_mark->usec = htonl (ST_MTIM_NSEC (&buf)/1000);
- } else
- vol_mark->retval = 1;
-
- *status = vol_mark;
-
- return 0;
-}
-
-int32_t
-marker_getxattr_stampfile_cbk (call_frame_t *frame, xlator_t *this,
- const char *name, struct volume_mark *vol_mark,
- dict_t *xdata)
-{
- int32_t ret = -1;
- dict_t *dict = NULL;
-
- if (vol_mark == NULL){
- STACK_UNWIND_STRICT (getxattr, frame, -1, ENOMEM, NULL, NULL);
-
- goto out;
- }
-
- 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);
-
- STACK_UNWIND_STRICT (getxattr, frame, 0, 0, dict, xdata);
-
- dict_unref (dict);
-out:
- return 0;
-}
-
-gf_boolean_t
-call_from_special_client (call_frame_t *frame, xlator_t *this, const char *name)
-{
- struct volume_mark *vol_mark = NULL;
- marker_conf_t *priv = NULL;
- gf_boolean_t is_true = _gf_true;
-
- priv = (marker_conf_t *)this->private;
-
- if (frame->root->pid != GF_CLIENT_PID_GSYNCD || name == NULL ||
- strcmp (name, MARKER_XATTR_PREFIX "." VOLUME_MARK) != 0) {
- is_true = _gf_false;
- goto out;
- }
-
- stat_stampfile (this, priv, &vol_mark);
-
- marker_getxattr_stampfile_cbk (frame, this, name, vol_mark, NULL);
-out:
- return is_true;
-}
-
-static gf_boolean_t
-_is_quota_internal_xattr (dict_t *d, char *k, data_t *v, void *data)
-{
- int i = 0;
- char **external_xattrs = data;
-
- for (i = 0; external_xattrs && external_xattrs[i]; i++) {
- if (strcmp (k, external_xattrs[i]) == 0)
- return _gf_false;
- }
-
- if (fnmatch ("trusted.glusterfs.quota*", k, 0) == 0)
- return _gf_true;
-
- /* It would be nice if posix filters pgfid xattrs. But since marker
- * also takes up responsibility to clean these up, adding the filtering
- * here (Check 'quota_xattr_cleaner')
- */
- if (fnmatch (PGFID_XATTR_KEY_PREFIX"*", k, 0) == 0)
- return _gf_true;
-
- return _gf_false;
-}
-
-static void
-marker_filter_internal_xattrs (xlator_t *this, dict_t *xattrs)
-{
- marker_conf_t *priv = NULL;
- char **ext = NULL;
-
- priv = this->private;
- if (priv->feature_enabled & GF_QUOTA)
- ext = quota_external_xattrs;
-
- dict_foreach_match (xattrs, _is_quota_internal_xattr, ext,
- dict_remove_foreach_fn, NULL);
- return;
-}
-
-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)
-{
- marker_local_t *local = NULL;
- local = frame->local;
-
-
- if (cookie) {
- gf_log (this->name, GF_LOG_DEBUG,
- "Filtering the quota extended attributes");
-
- /* If the getxattr is from a non special client, then do not
- copy the quota related xattrs (except the quota limit key
- i.e trusted.glusterfs.quota.limit-set which has been set by
- glusterd on the directory on which quota limit is set.) for
- directories. Let the healing of xattrs happen upon lookup.
- NOTE: setting of trusted.glusterfs.quota.limit-set as of now
- happens from glusterd. It should be moved to quotad. Also
- trusted.glusterfs.quota.limit-set is set on directory which
- is permanent till quota is removed on that directory or limit
- is changed. So let that xattr be healed by other xlators
- properly whenever directory healing is done.
- */
- /*
- * Except limit-set xattr, rest of the xattrs are maintained
- * by quota xlator. Don't expose them to other xlators.
- * This filter makes sure quota xattrs are not healed as part of
- * metadata self-heal
- */
- marker_filter_internal_xattrs (frame->this, dict);
- }
-
- frame->local = NULL;
- STACK_UNWIND_STRICT (getxattr, frame, op_ret, op_errno, dict, xdata);
- marker_local_unref (local);
- return 0;
-}
-
-int32_t
-marker_getxattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
- const char *name, dict_t *xdata)
-{
- gf_boolean_t is_true = _gf_false;
- marker_conf_t *priv = NULL;
- unsigned long cookie = 0;
- marker_local_t *local = NULL;
-
- priv = this->private;
-
- frame->local = mem_get0 (this->local_pool);
- local = frame->local;
- if (local == NULL)
- goto out;
-
- MARKER_INIT_LOCAL (frame, local);
-
- if ((loc_copy (&local->loc, loc)) < 0)
- goto out;
-
- gf_log (this->name, GF_LOG_DEBUG, "USER:PID = %d", frame->root->pid);
-
- if (priv && priv->feature_enabled & GF_XTIME)
- is_true = call_from_special_client (frame, this, name);
-
- if (is_true == _gf_false) {
- 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;
- }
- STACK_WIND_COOKIE (frame, marker_getxattr_cbk,
- (void *)cookie,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->getxattr,
- loc, name, xdata);
- }
-
- return 0;
-out:
- frame->local = NULL;
- STACK_UNWIND_STRICT (getxattr, frame, -1, ENOMEM, NULL, NULL);
- marker_local_unref (local);
- return 0;
-}
-
-
-int32_t
-marker_setxattr_done (call_frame_t *frame)
-{
- marker_local_t *local = NULL;
-
- local = (marker_local_t *) frame->local;
-
- frame->local = NULL;
-
- STACK_DESTROY (frame->root);
-
- marker_local_unref (local);
-
- return 0;
-}
-
-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 ret = 0;
- int32_t done = 0;
- marker_local_t *local = NULL;
-
- local = (marker_local_t*) frame->local;
-
- if (op_ret == -1 && op_errno == ENOSPC) {
- marker_error_handler (this, local, op_errno);
- done = 1;
- 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;
- }
- }
-
- ret = marker_trav_parent (local);
-
- if (ret == -1) {
- gf_log (this->name, GF_LOG_DEBUG, "Error occurred "
- "while traversing to the parent, stopping marker");
-
- done = 1;
-
- goto out;
- }
-
- marker_start_setxattr (frame, this);
-
-out:
- if (done) {
- marker_setxattr_done (frame);
- }
-
- return 0;
-}
-
-int32_t
-marker_start_setxattr (call_frame_t *frame, xlator_t *this)
-{
- int32_t ret = -1;
- dict_t *dict = NULL;
- marker_local_t *local = NULL;
- marker_conf_t *priv = NULL;
-
- priv = this->private;
-
- 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;
- }
-
- STACK_WIND (frame, marker_specific_setxattr_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->setxattr, &local->loc, dict, 0,
- NULL);
-
- ret = 0;
-out:
- if (dict)
- dict_unref (dict);
-
- return ret;
-}
-
-void
-marker_gettimeofday (marker_local_t *local)
-{
- struct timeval tv = {0, };
-
- gettimeofday (&tv, NULL);
-
- local->timebuf [0] = htonl (tv.tv_sec);
- local->timebuf [1] = htonl (tv.tv_usec);
-
- return;
-}
-
-int32_t
-marker_create_frame (xlator_t *this, marker_local_t *local)
-{
- call_frame_t *frame = NULL;
-
- frame = create_frame (this, this->ctx->pool);
-
- frame->local = (void *) local;
-
- marker_start_setxattr (frame, this);
-
- return 0;
-}
-
-int32_t
-marker_xtime_update_marks (xlator_t *this, marker_local_t *local)
-{
- marker_conf_t *priv = NULL;
-
- GF_VALIDATE_OR_GOTO ("marker", this, out);
- GF_VALIDATE_OR_GOTO (this->name, local, out);
-
- priv = this->private;
-
- if ((local->pid == GF_CLIENT_PID_GSYNCD
- && !(priv->feature_enabled & GF_XTIME_GSYNC_FORCE))
- || (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)
-{
- marker_conf_t *priv = NULL;
- marker_local_t *local = NULL;
-
- if (op_ret == -1) {
- gf_log (this->name, GF_LOG_TRACE, "error occurred "
- "while creating directory %s", strerror (op_errno));
- }
-
- local = (marker_local_t *) frame->local;
-
- frame->local = NULL;
-
- STACK_UNWIND_STRICT (mkdir, frame, op_ret, op_errno, inode,
- buf, preparent, postparent, xdata);
-
- 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);
-
- if (priv->feature_enabled & GF_XTIME)
- marker_xtime_update_marks (this, local);
-
-out:
- marker_local_unref (local);
-
- return 0;
-}
-
-int
-marker_mkdir (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
- mode_t umask, dict_t *xdata)
-{
- int32_t ret = 0;
- marker_local_t *local = NULL;
- marker_conf_t *priv = NULL;
-
- priv = this->private;
-
- if (priv->feature_enabled == 0)
- goto wind;
-
- local = mem_get0 (this->local_pool);
-
- MARKER_INIT_LOCAL (frame, local);
-
- ret = loc_copy (&local->loc, loc);
-
- if (ret == -1)
- goto err;
-wind:
- STACK_WIND (frame, marker_mkdir_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->mkdir, loc, mode, umask, xdata);
-
- return 0;
-err:
- STACK_UNWIND_STRICT (mkdir, frame, -1, ENOMEM, 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)
-{
- marker_local_t *local = NULL;
- marker_conf_t *priv = NULL;
-
- if (op_ret == -1) {
- gf_log (this->name, GF_LOG_TRACE, "error occurred "
- "while creating file %s", strerror (op_errno));
- }
-
- local = (marker_local_t *) frame->local;
-
- frame->local = NULL;
-
- STACK_UNWIND_STRICT (create, frame, op_ret, op_errno, fd, inode, buf,
- preparent, postparent, xdata);
-
- 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);
-
- if (priv->feature_enabled & GF_XTIME)
- marker_xtime_update_marks (this, local);
-
-out:
- marker_local_unref (local);
-
- return 0;
-}
-
-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)
-{
- int32_t ret = 0;
- marker_local_t *local = NULL;
- marker_conf_t *priv = NULL;
-
- priv = this->private;
-
- if (priv->feature_enabled == 0)
- goto wind;
-
- local = mem_get0 (this->local_pool);
-
- MARKER_INIT_LOCAL (frame, local);
-
- ret = loc_copy (&local->loc, loc);
-
- if (ret == -1)
- goto err;
-wind:
- STACK_WIND (frame, marker_create_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->create, loc, flags, mode, umask,
- fd, xdata);
- return 0;
-err:
- STACK_UNWIND_STRICT (create, frame, -1, ENOMEM, NULL, NULL, NULL, NULL,
- NULL, NULL);
-
- return 0;
-}
-
-
-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)
-{
- marker_conf_t *priv = NULL;
- marker_local_t *local = NULL;
-
- if (op_ret == -1) {
- gf_log (this->name, GF_LOG_TRACE, "error occurred "
- "while write, %s", strerror (op_errno));
- }
-
- local = (marker_local_t *) frame->local;
-
- frame->local = NULL;
-
- STACK_UNWIND_STRICT (writev, frame, op_ret, op_errno, prebuf, postbuf,
- xdata);
-
- if (op_ret == -1 || local == NULL)
- goto out;
-
- priv = this->private;
-
- if (priv->feature_enabled & GF_QUOTA)
- mq_initiate_quota_txn (this, &local->loc);
-
- if (priv->feature_enabled & GF_XTIME)
- marker_xtime_update_marks (this, local);
-
-out:
- marker_local_unref (local);
-
- return 0;
-}
-
-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)
-{
- int32_t ret = 0;
- marker_local_t *local = NULL;
- marker_conf_t *priv = NULL;
-
- priv = this->private;
-
- if (priv->feature_enabled == 0)
- goto wind;
-
- local = mem_get0 (this->local_pool);
-
- MARKER_INIT_LOCAL (frame, local);
-
- ret = marker_inode_loc_fill (fd->inode, NULL, &local->loc);
-
- if (ret == -1)
- goto err;
-wind:
- STACK_WIND (frame, marker_writev_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->writev, fd, vector, count, offset,
- flags, iobref, xdata);
- return 0;
-err:
- STACK_UNWIND_STRICT (writev, frame, -1, ENOMEM, NULL, NULL, NULL);
-
- return 0;
-}
-
-
-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)
-{
- marker_conf_t *priv = NULL;
- marker_local_t *local = NULL;
-
- if (op_ret == -1) {
- gf_log (this->name, GF_LOG_TRACE, "error occurred "
- "rmdir %s", strerror (op_errno));
- }
-
- local = (marker_local_t *) frame->local;
-
- frame->local = NULL;
-
- STACK_UNWIND_STRICT (rmdir, frame, op_ret, op_errno, preparent,
- postparent, xdata);
-
- if (op_ret == -1 || local == NULL)
- goto out;
-
- priv = this->private;
-
- if (priv->feature_enabled & GF_QUOTA)
- mq_reduce_parent_size (this, &local->loc, -1);
-
- if (priv->feature_enabled & GF_XTIME)
- marker_xtime_update_marks (this, local);
-out:
- marker_local_unref (local);
-
- return 0;
-}
-
-int32_t
-marker_rmdir (call_frame_t *frame, xlator_t *this, loc_t *loc, int flags,
- dict_t *xdata)
-{
- int32_t ret = 0;
- marker_local_t *local = NULL;
- marker_conf_t *priv = NULL;
-
- priv = this->private;
-
- if (priv->feature_enabled == 0)
- goto wind;
-
- local = mem_get0 (this->local_pool);
-
- MARKER_INIT_LOCAL (frame, local);
-
- ret = loc_copy (&local->loc, loc);
-
- if (ret == -1)
- goto err;
-wind:
- STACK_WIND (frame, marker_rmdir_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->rmdir, loc, flags, xdata);
- return 0;
-err:
- STACK_UNWIND_STRICT (rmdir, frame, -1, ENOMEM, NULL, NULL, NULL);
-
- return 0;
-}
-
-
-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)
-{
- marker_conf_t *priv = NULL;
- marker_local_t *local = NULL;
-
- if (op_ret == -1) {
- gf_log (this->name, GF_LOG_TRACE,
- "%s occurred in unlink", strerror (op_errno));
- }
-
- local = (marker_local_t *) frame->local;
-
- frame->local = NULL;
-
- STACK_UNWIND_STRICT (unlink, frame, op_ret, op_errno, preparent,
- postparent, xdata);
-
- if (op_ret == -1 || local == NULL)
- goto out;
-
- priv = this->private;
-
- if (priv->feature_enabled & GF_QUOTA) {
- if (!local->skip_txn)
- mq_reduce_parent_size (this, &local->loc, -1);
- }
-
- if (priv->feature_enabled & GF_XTIME)
- marker_xtime_update_marks (this, local);
-out:
- marker_local_unref (local);
-
- return 0;
-}
-
-
-int32_t
-marker_unlink (call_frame_t *frame, xlator_t *this, loc_t *loc, int xflag,
- dict_t *xdata)
-{
- int32_t ret = 0;
- marker_local_t *local = NULL;
- marker_conf_t *priv = NULL;
-
- priv = this->private;
-
- if (priv->feature_enabled == 0)
- goto unlink_wind;
-
- local = mem_get0 (this->local_pool);
- local->xflag = xflag;
- if (xdata)
- local->xdata = dict_ref (xdata);
- MARKER_INIT_LOCAL (frame, local);
-
- ret = loc_copy (&local->loc, loc);
-
- if (ret == -1)
- goto err;
-
- if (xdata && dict_get (xdata, GLUSTERFS_MARKER_DONT_ACCOUNT_KEY)) {
- local->skip_txn = 1;
- goto unlink_wind;
- }
-
-unlink_wind:
- STACK_WIND (frame, marker_unlink_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->unlink, loc, xflag, xdata);
- return 0;
-err:
- frame->local = NULL;
- STACK_UNWIND_STRICT (unlink, frame, -1, ENOMEM, NULL, NULL, NULL);
- marker_local_unref (local);
- 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)
-{
- marker_local_t *local = NULL;
- marker_conf_t *priv = NULL;
-
- if (op_ret == -1) {
- gf_log (this->name, GF_LOG_TRACE, "%s occurred while "
- "linking a file ", strerror (op_errno));
- }
-
- local = (marker_local_t *) frame->local;
-
- frame->local = NULL;
-
- STACK_UNWIND_STRICT (link, frame, op_ret, op_errno, inode, buf,
- preparent, postparent, xdata);
-
- if (op_ret == -1 || local == NULL)
- goto out;
-
- priv = this->private;
-
- if (priv->feature_enabled & GF_QUOTA) {
- if (!local->skip_txn)
- mq_set_inode_xattr (this, &local->loc);
- }
-
-
- if (priv->feature_enabled & GF_XTIME)
- marker_xtime_update_marks (this, local);
-out:
- marker_local_unref (local);
-
- return 0;
-}
-
-int32_t
-marker_link (call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc,
- dict_t *xdata)
-{
- int32_t ret = 0;
- marker_local_t *local = NULL;
- marker_conf_t *priv = NULL;
-
- priv = this->private;
-
- if (priv->feature_enabled == 0)
- goto wind;
-
- local = mem_get0 (this->local_pool);
-
- MARKER_INIT_LOCAL (frame, local);
-
- ret = loc_copy (&local->loc, newloc);
-
- if (ret == -1)
- goto err;
-
- if (xdata && dict_get (xdata, GLUSTERFS_MARKER_DONT_ACCOUNT_KEY))
- local->skip_txn = 1;
-wind:
- STACK_WIND (frame, marker_link_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->link, oldloc, newloc, xdata);
- return 0;
-err:
- STACK_UNWIND_STRICT (link, frame, -1, ENOMEM, NULL, 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_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 ? op_errno : EINVAL;
- }
-
- 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);
- } else {
- gf_log (this->name, GF_LOG_CRITICAL,
- "continuation stub to unwind the call is absent, hence "
- "call will be hung (call-stack id = %"PRIu64")",
- frame->root->unique);
- }
-
- 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_set_inode_xattr (this, &newloc);
-
- loc_wipe (&newloc);
-
- 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);
- }
-
- 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;
-
- if (op_ret < 0) {
- if (local->err == 0) {
- local->err = op_errno ? op_errno : EINVAL;
- }
-
- 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));
- }
-
- if (local->next_lock_on == NULL) {
- marker_rename_done (frame, NULL, this, 0, 0, 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) && (op_errno != ENODATA)) {
- 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;
- }
-
- 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;
- }
-
- local->stub = stub;
-
- GET_CONTRI_KEY (contri_key, oplocal->loc.parent->gfid, ret);
- if (ret < 0) {
- local->err = ENOMEM;
- goto quota_err;
- }
-
- /* 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.parent = inode_ref (local->loc.parent);
- uuid_copy (newloc.gfid, oplocal->loc.inode->gfid);
-
- STACK_WIND_COOKIE (frame, marker_rename_release_oldp_lock,
- frame->cookie, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->removexattr,
- &newloc, contri_key, NULL);
-
- 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) && (op_errno != ENODATA)) {
- local->err = op_errno ? op_errno : EINVAL;
- 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 ? errno : ENOMEM;
- goto err;
- }
-
- if (dict_get_bin (dict, contri_key,
- (void **) &contribution) == 0) {
- local->contribution = ntoh64 (*contribution);
- }
- }
-
- 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);
- 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_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) && (op_errno != ENODATA)) {
- local->err = op_errno ? op_errno : EINVAL;
- 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 ? errno : ENOMEM;
- 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 ? errno : ENOMEM;
- 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);
- }
-
- 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 ? op_errno : EINVAL;
- 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 ? errno : ENOMEM;
- 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);
- }
-
- 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 ? op_errno : EINVAL;
- 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;
- }
-
- 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);
- }
-
- 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)
-{
- 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;
-
- priv = this->private;
-
- if (priv->feature_enabled == 0)
- goto rename_wind;
-
- local = mem_get0 (this->local_pool);
-
- MARKER_INIT_LOCAL (frame, local);
-
- oplocal = mem_get0 (this->local_pool);
-
- MARKER_INIT_LOCAL (frame, oplocal);
-
- frame->local = local;
-
- local->oplocal = marker_local_ref (oplocal);
-
- ret = loc_copy (&local->loc, newloc);
- if (ret < 0)
- 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)
- 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);
-
- return 0;
-
-rename_wind:
- STACK_WIND (frame, marker_rename_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->rename, oldloc, newloc, xdata);
-
- return 0;
-err:
- STACK_UNWIND_STRICT (rename, frame, -1, ENOMEM, NULL,
- NULL, NULL, NULL, NULL, NULL);
-
- return 0;
-}
-
-
-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)
-{
- marker_local_t *local = NULL;
- marker_conf_t *priv = NULL;
-
- if (op_ret == -1) {
- gf_log (this->name, GF_LOG_TRACE, "%s occurred while "
- "truncating a file ", strerror (op_errno));
- }
-
- local = (marker_local_t *) frame->local;
-
- frame->local = NULL;
-
- STACK_UNWIND_STRICT (truncate, frame, op_ret, op_errno, prebuf,
- postbuf, xdata);
-
- if (op_ret == -1 || local == NULL)
- goto out;
-
- priv = this->private;
-
- if (priv->feature_enabled & GF_QUOTA)
- mq_initiate_quota_txn (this, &local->loc);
-
- if (priv->feature_enabled & GF_XTIME)
- marker_xtime_update_marks (this, local);
-
-out:
- marker_local_unref (local);
-
- return 0;
-}
-
-int32_t
-marker_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset,
- dict_t *xdata)
-{
- int32_t ret = 0;
- marker_local_t *local = NULL;
- marker_conf_t *priv = NULL;
-
- priv = this->private;
-
- if (priv->feature_enabled == 0)
- goto wind;
-
- local = mem_get0 (this->local_pool);
-
- MARKER_INIT_LOCAL (frame, local);
-
- ret = loc_copy (&local->loc, loc);
-
- if (ret == -1)
- goto err;
-wind:
- STACK_WIND (frame, marker_truncate_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->truncate, loc, offset, xdata);
- return 0;
-err:
- STACK_UNWIND_STRICT (truncate, frame, -1, ENOMEM, NULL, NULL, NULL);
-
- return 0;
-}
-
-
-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)
-{
- marker_local_t *local = NULL;
- marker_conf_t *priv = NULL;
-
- if (op_ret == -1) {
- gf_log (this->name, GF_LOG_TRACE, "%s occurred while "
- "truncating a file ", strerror (op_errno));
- }
-
- local = (marker_local_t *) frame->local;
-
- frame->local = NULL;
-
- STACK_UNWIND_STRICT (ftruncate, frame, op_ret, op_errno, prebuf,
- postbuf, xdata);
-
- if (op_ret == -1 || local == NULL)
- goto out;
-
- priv = this->private;
-
- if (priv->feature_enabled & GF_QUOTA)
- mq_initiate_quota_txn (this, &local->loc);
-
- if (priv->feature_enabled & GF_XTIME)
- marker_xtime_update_marks (this, local);
-out:
- marker_local_unref (local);
-
- return 0;
-}
-
-int32_t
-marker_ftruncate (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
- dict_t *xdata)
-{
- int32_t ret = 0;
- marker_local_t *local = NULL;
- marker_conf_t *priv = NULL;
-
- priv = this->private;
-
- if (priv->feature_enabled == 0)
- goto wind;
-
- local = mem_get0 (this->local_pool);
-
- MARKER_INIT_LOCAL (frame, local);
-
- ret = marker_inode_loc_fill (fd->inode, NULL, &local->loc);
-
- if (ret == -1)
- goto err;
-wind:
- STACK_WIND (frame, marker_ftruncate_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->ftruncate, fd, offset, xdata);
- return 0;
-err:
- STACK_UNWIND_STRICT (ftruncate, frame, -1, ENOMEM, NULL, NULL, NULL);
-
- return 0;
-}
-
-
-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)
-{
- marker_conf_t *priv = NULL;
- marker_local_t *local = NULL;
-
- if (op_ret == -1) {
- gf_log (this->name, GF_LOG_TRACE, "%s occurred while "
- "creating symlinks ", strerror (op_errno));
- }
-
- local = (marker_local_t *) frame->local;
-
- frame->local = NULL;
-
- STACK_UNWIND_STRICT (symlink, frame, op_ret, op_errno, inode, buf,
- preparent, postparent, xdata);
-
- 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);
-
- if (priv->feature_enabled & GF_XTIME)
- marker_xtime_update_marks (this, local);
-out:
- marker_local_unref (local);
-
- return 0;
-}
-
-int
-marker_symlink (call_frame_t *frame, xlator_t *this, const char *linkpath,
- loc_t *loc, mode_t umask, dict_t *xdata)
-{
- int32_t ret = 0;
- marker_local_t *local = NULL;
- marker_conf_t *priv = NULL;
-
- priv = this->private;
-
- if (priv->feature_enabled == 0)
- goto wind;
-
- local = mem_get0 (this->local_pool);
-
- MARKER_INIT_LOCAL (frame, local);
-
- ret = loc_copy (&local->loc, loc);
-
- if (ret == -1)
- goto err;
-wind:
- STACK_WIND (frame, marker_symlink_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->symlink, linkpath, loc, umask,
- xdata);
- return 0;
-err:
- STACK_UNWIND_STRICT (symlink, frame, -1, ENOMEM, 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)
-{
- marker_local_t *local = NULL;
- marker_conf_t *priv = NULL;
-
- if (op_ret == -1) {
- gf_log (this->name, GF_LOG_TRACE, "%s occurred with "
- "mknod ", strerror (op_errno));
- }
-
- local = (marker_local_t *) frame->local;
-
- frame->local = NULL;
-
- STACK_UNWIND_STRICT (mknod, frame, op_ret, op_errno, inode,
- buf, preparent, postparent, xdata);
-
- 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);
- }
-
- if (priv->feature_enabled & GF_XTIME)
- marker_xtime_update_marks (this, local);
-out:
- marker_local_unref (local);
-
- return 0;
-}
-
-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)
-{
- int32_t ret = 0;
- marker_local_t *local = NULL;
- marker_conf_t *priv = NULL;
-
- priv = this->private;
-
- if (priv->feature_enabled == 0)
- goto wind;
-
- local = mem_get0 (this->local_pool);
-
- MARKER_INIT_LOCAL (frame, local);
-
- ret = loc_copy (&local->loc, loc);
-
- local->mode = mode;
-
- if (ret == -1)
- goto err;
-wind:
- STACK_WIND (frame, marker_mknod_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->mknod, loc, mode, rdev, umask,
- xdata);
- return 0;
-err:
- STACK_UNWIND_STRICT (mknod, frame, -1, ENOMEM, NULL,
- NULL, NULL, NULL, NULL);
- return 0;
-}
-
-
-int32_t
-marker_fallocate_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)
-{
- marker_local_t *local = NULL;
- marker_conf_t *priv = NULL;
-
- if (op_ret == -1) {
- gf_log (this->name, GF_LOG_TRACE, "%s occurred while "
- "fallocating a file ", strerror (op_errno));
- }
-
- local = (marker_local_t *) frame->local;
-
- frame->local = NULL;
-
- STACK_UNWIND_STRICT (fallocate, frame, op_ret, op_errno, prebuf,
- postbuf, xdata);
-
- if (op_ret == -1 || local == NULL)
- goto out;
-
- priv = this->private;
-
- if (priv->feature_enabled & GF_QUOTA)
- mq_initiate_quota_txn (this, &local->loc);
-
- if (priv->feature_enabled & GF_XTIME)
- marker_xtime_update_marks (this, local);
-out:
- marker_local_unref (local);
-
- return 0;
-}
-
-int32_t
-marker_fallocate(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t mode,
- off_t offset, size_t len, dict_t *xdata)
-{
- int32_t ret = 0;
- marker_local_t *local = NULL;
- marker_conf_t *priv = NULL;
-
- priv = this->private;
-
- if (priv->feature_enabled == 0)
- goto wind;
-
- local = mem_get0 (this->local_pool);
-
- MARKER_INIT_LOCAL (frame, local);
-
- ret = marker_inode_loc_fill (fd->inode, NULL, &local->loc);
-
- if (ret == -1)
- goto err;
-wind:
- STACK_WIND (frame, marker_fallocate_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fallocate, fd, mode, offset, len,
- xdata);
- return 0;
-err:
- STACK_UNWIND_STRICT (fallocate, frame, -1, ENOMEM, NULL, NULL, NULL);
-
- return 0;
-}
-
-
-int32_t
-marker_discard_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)
-{
- marker_local_t *local = NULL;
- marker_conf_t *priv = NULL;
-
- if (op_ret == -1) {
- gf_log (this->name, GF_LOG_TRACE, "%s occurred during discard",
- strerror (op_errno));
- }
-
- local = (marker_local_t *) frame->local;
-
- frame->local = NULL;
-
- STACK_UNWIND_STRICT (discard, frame, op_ret, op_errno, prebuf,
- postbuf, xdata);
-
- if (op_ret == -1 || local == NULL)
- goto out;
-
- priv = this->private;
-
- if (priv->feature_enabled & GF_QUOTA)
- mq_initiate_quota_txn (this, &local->loc);
-
- if (priv->feature_enabled & GF_XTIME)
- marker_xtime_update_marks (this, local);
-out:
- marker_local_unref (local);
-
- return 0;
-}
-
-int32_t
-marker_discard(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
- size_t len, dict_t *xdata)
-{
- int32_t ret = 0;
- marker_local_t *local = NULL;
- marker_conf_t *priv = NULL;
-
- priv = this->private;
-
- if (priv->feature_enabled == 0)
- goto wind;
-
- local = mem_get0 (this->local_pool);
-
- MARKER_INIT_LOCAL (frame, local);
-
- ret = marker_inode_loc_fill (fd->inode, NULL, &local->loc);
-
- if (ret == -1)
- goto err;
-wind:
- STACK_WIND (frame, marker_discard_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->discard, fd, offset, len, xdata);
- return 0;
-err:
- STACK_UNWIND_STRICT (discard, frame, -1, ENOMEM, NULL, NULL, NULL);
-
- return 0;
-}
-
-int32_t
-marker_zerofill_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)
-{
- marker_local_t *local = NULL;
- marker_conf_t *priv = NULL;
-
- if (op_ret == -1) {
- gf_log (this->name, GF_LOG_TRACE, "%s occurred during zerofill",
- strerror (op_errno));
- }
-
- local = (marker_local_t *) frame->local;
-
- frame->local = NULL;
-
- STACK_UNWIND_STRICT (zerofill, frame, op_ret, op_errno, prebuf,
- postbuf, xdata);
-
- if (op_ret == -1 || local == NULL)
- goto out;
-
- priv = this->private;
-
- if (priv->feature_enabled & GF_QUOTA)
- mq_initiate_quota_txn (this, &local->loc);
-
- if (priv->feature_enabled & GF_XTIME)
- marker_xtime_update_marks (this, local);
-out:
- marker_local_unref (local);
-
- return 0;
-}
-
-int32_t
-marker_zerofill(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
- off_t len, dict_t *xdata)
-{
- int32_t ret = 0;
- marker_local_t *local = NULL;
- marker_conf_t *priv = NULL;
-
- priv = this->private;
-
- if (priv->feature_enabled == 0)
- goto wind;
-
- local = mem_get0 (this->local_pool);
-
- MARKER_INIT_LOCAL (frame, local);
-
- ret = marker_inode_loc_fill (fd->inode, NULL, &local->loc);
-
- if (ret == -1)
- goto err;
-wind:
- STACK_WIND (frame, marker_zerofill_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->zerofill, fd, offset, len, xdata);
- return 0;
-err:
- STACK_UNWIND_STRICT (zerofill, frame, -1, ENOMEM, NULL, NULL, NULL);
-
- return 0;
-}
-
-
-/* when a call from the special client is received on
- * key trusted.glusterfs.volume-mark with value "RESET"
- * or if the value is 0length, update the change the
- * access time and modification time via touching the
- * timestamp file.
- */
-int32_t
-call_from_sp_client_to_reset_tmfile (call_frame_t *frame,
- xlator_t *this,
- dict_t *dict)
-{
- int32_t fd = 0;
- int32_t op_ret = 0;
- int32_t op_errno = 0;
- data_t *data = NULL;
- marker_conf_t *priv = NULL;
-
- if (frame == NULL || this == NULL || dict == NULL)
- return -1;
-
- priv = this->private;
-
- data = dict_get (dict, "trusted.glusterfs.volume-mark");
- if (data == NULL)
- return -1;
-
- if (frame->root->pid != GF_CLIENT_PID_GSYNCD) {
- op_ret = -1;
- op_errno = EPERM;
-
- goto out;
- }
-
- if (data->len == 0 || (data->len == 5 &&
- 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
- * timestamps on a zero length file on all machies.
- */
- close (fd);
- }
-
- if (fd != -1 || errno == ENOENT) {
- op_ret = 0;
- op_errno = 0;
- } else {
- op_ret = -1;
- op_errno = errno;
- }
- } else {
- op_ret = -1;
- op_errno = EINVAL;
- }
-out:
- STACK_UNWIND_STRICT (setxattr, frame, op_ret, op_errno, NULL);
-
- return 0;
-}
-
-
-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)
-{
- 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));
- }
-
- local = (marker_local_t *) frame->local;
-
- frame->local = NULL;
-
- STACK_UNWIND_STRICT (setxattr, frame, op_ret, op_errno, xdata);
-
- if (op_ret == -1 || local == NULL)
- goto out;
-
- priv = this->private;
-
- if (priv->feature_enabled & GF_XTIME)
- marker_xtime_update_marks (this, local);
-out:
- marker_local_unref (local);
-
- return 0;
-}
-
-int
-remove_quota_keys (dict_t *dict, char *k, data_t *v, void *data)
-{
- call_frame_t *frame = data;
- marker_local_t *local = frame->local;
- xlator_t *this = frame->this;
- int ret = -1;
-
- ret = syncop_removexattr (FIRST_CHILD (this), &local->loc, k, 0);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "%s: Failed to remove "
- "extended attribute: %s", local->loc.path, k);
- return -1;
- }
- return 0;
-}
-
-int
-quota_xattr_cleaner_cbk (int ret, call_frame_t *frame, void *args)
-{
- dict_t *xdata = args;
- int op_ret = -1;
- int op_errno = 0;
- marker_local_t *local = NULL;
-
- local = frame->local;
- frame->local = NULL;
-
- op_ret = (ret < 0)? -1: 0;
- op_errno = -ret;
-
- STACK_UNWIND_STRICT (setxattr, frame, op_ret, op_errno, xdata);
- marker_local_unref (local);
- return ret;
-}
-
-int
-quota_xattr_cleaner (void *args)
-{
- struct synctask *task = NULL;
- call_frame_t *frame = NULL;
- xlator_t *this = NULL;
- marker_local_t *local = NULL;
- dict_t *xdata = NULL;
- int ret = -1;
-
- task = synctask_get ();
- if (!task)
- goto out;
-
- frame = task->frame;
- this = frame->this;
- local = frame->local;
-
- ret = syncop_listxattr (FIRST_CHILD(this), &local->loc, &xdata);
- if (ret == -1) {
- ret = -errno;
- goto out;
- }
-
- ret = dict_foreach_fnmatch (xdata, "trusted.glusterfs.quota.*",
- remove_quota_keys, frame);
- if (ret == -1) {
- ret = -errno;
- goto out;
- }
- ret = dict_foreach_fnmatch (xdata, PGFID_XATTR_KEY_PREFIX"*",
- remove_quota_keys, frame);
- if (ret == -1) {
- ret = -errno;
- goto out;
- }
-
- ret = 0;
-out:
- if (xdata)
- dict_unref (xdata);
-
- return ret;
-}
-
-int
-marker_do_xattr_cleanup (call_frame_t *frame, xlator_t *this, dict_t *xdata,
- loc_t *loc)
-{
- int ret = -1;
- marker_local_t *local = NULL;
-
- local = mem_get0 (this->local_pool);
- if (!local)
- goto out;
-
- MARKER_INIT_LOCAL (frame, local);
-
- loc_copy (&local->loc, loc);
- ret = synctask_new (this->ctx->env, quota_xattr_cleaner,
- quota_xattr_cleaner_cbk, frame, xdata);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to create synctask "
- "for cleaning up quota extended attributes");
- goto out;
- }
-
- ret = 0;
-out:
- if (ret) {
- frame->local = NULL;
- STACK_UNWIND_STRICT (setxattr, frame, -1, ENOMEM, xdata);
- marker_local_unref (local);
- }
- return ret;
-}
-
-static inline gf_boolean_t
-marker_xattr_cleanup_cmd (dict_t *dict)
-{
- return (dict_get (dict, VIRTUAL_QUOTA_XATTR_CLEANUP_KEY) != NULL);
-}
-
-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 ret = 0;
- marker_local_t *local = NULL;
- marker_conf_t *priv = NULL;
- int op_errno = ENOMEM;
-
- priv = this->private;
-
- if (marker_xattr_cleanup_cmd (dict)) {
- if (frame->root->uid != 0 || frame->root->gid != 0) {
- op_errno = EPERM;
- ret = -1;
- goto err;
- }
-
- /* The following function does the cleanup and then unwinds the
- * corresponding call*/
- loc_path (loc, NULL);
- marker_do_xattr_cleanup (frame, this, xdata, loc);
- return 0;
- }
-
- if (priv->feature_enabled == 0)
- goto wind;
-
- ret = call_from_sp_client_to_reset_tmfile (frame, this, dict);
- if (ret == 0)
- return 0;
-
- local = mem_get0 (this->local_pool);
-
- MARKER_INIT_LOCAL (frame, local);
-
- ret = loc_copy (&local->loc, loc);
-
- if (ret == -1)
- goto err;
-wind:
- STACK_WIND (frame, marker_setxattr_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->setxattr, loc, dict, flags, xdata);
- return 0;
-err:
- STACK_UNWIND_STRICT (setxattr, frame, -1, op_errno, NULL);
-
- return 0;
-}
-
-
-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)
-{
- marker_local_t *local = NULL;
- marker_conf_t *priv = NULL;
-
- if (op_ret == -1) {
- gf_log (this->name, GF_LOG_TRACE, "%s occurred in "
- "fsetxattr", strerror (op_errno));
- }
-
- local = (marker_local_t *) frame->local;
-
- frame->local = NULL;
-
- STACK_UNWIND_STRICT (fsetxattr, frame, op_ret, op_errno, xdata);
-
- if (op_ret == -1 || local == NULL)
- goto out;
-
- priv = this->private;
-
- if (priv->feature_enabled & GF_XTIME)
- marker_xtime_update_marks (this, local);
-out:
- marker_local_unref (local);
-
- return 0;
-}
-
-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 ret = 0;
- marker_local_t *local = NULL;
- marker_conf_t *priv = NULL;
-
- priv = this->private;
-
- if (priv->feature_enabled == 0)
- goto wind;
-
- ret = call_from_sp_client_to_reset_tmfile (frame, this, dict);
- if (ret == 0)
- return 0;
-
- local = mem_get0 (this->local_pool);
-
- MARKER_INIT_LOCAL (frame, local);
-
- ret = marker_inode_loc_fill (fd->inode, NULL, &local->loc);
-
- if (ret == -1)
- goto err;
-wind:
- STACK_WIND (frame, marker_fsetxattr_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fsetxattr, fd, dict, flags, xdata);
- return 0;
-err:
- STACK_UNWIND_STRICT (fsetxattr, frame, -1, ENOMEM, NULL);
-
- return 0;
-}
-
-
-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)
-{
- marker_local_t *local = NULL;
- marker_conf_t *priv = NULL;
-
- if (op_ret == -1) {
- gf_log (this->name, GF_LOG_TRACE, "%s occurred in "
- "fsetattr ", strerror (op_errno));
- }
-
- local = (marker_local_t *) frame->local;
-
- frame->local = NULL;
-
- STACK_UNWIND_STRICT (fsetattr, frame, op_ret, op_errno, statpre,
- statpost, xdata);
-
- if (op_ret == -1 || local == NULL)
- goto out;
-
- priv = this->private;
-
- if (priv->feature_enabled & GF_XTIME)
- marker_xtime_update_marks (this, local);
-out:
- marker_local_unref (local);
-
- return 0;
-}
-
-
-int32_t
-marker_fsetattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
- struct iatt *stbuf, int32_t valid, dict_t *xdata)
-{
- int32_t ret = 0;
- marker_local_t *local = NULL;
- marker_conf_t *priv = NULL;
-
- priv = this->private;
-
- if (priv->feature_enabled == 0)
- goto wind;
-
- local = mem_get0 (this->local_pool);
-
- MARKER_INIT_LOCAL (frame, local);
-
- ret = marker_inode_loc_fill (fd->inode, NULL, &local->loc);
-
- if (ret == -1)
- goto err;
-wind:
- STACK_WIND (frame, marker_fsetattr_cbk, FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->fsetattr, fd, stbuf, valid, xdata);
- return 0;
-err:
- STACK_UNWIND_STRICT (fsetattr, frame, -1, ENOMEM, NULL, NULL, NULL);
-
- return 0;
-}
-
-
-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)
-{
- marker_local_t *local = NULL;
- marker_conf_t *priv = NULL;
-
- local = (marker_local_t *) frame->local;
-
- frame->local = NULL;
-
- if (op_ret == -1) {
- gf_log (this->name, GF_LOG_TRACE,
- "%s occurred during setattr of %s",
- strerror (op_errno),
- (local ? local->loc.path : "<nul>"));
- }
-
- STACK_UNWIND_STRICT (setattr, frame, op_ret, op_errno, statpre,
- statpost, xdata);
-
- if (op_ret == -1 || local == NULL)
- goto out;
-
- priv = this->private;
-
- if (priv->feature_enabled & GF_XTIME)
- marker_xtime_update_marks (this, local);
-out:
- marker_local_unref (local);
-
- return 0;
-}
-
-int32_t
-marker_setattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
- struct iatt *stbuf, int32_t valid, dict_t *xdata)
-{
- int32_t ret = 0;
- marker_local_t *local = NULL;
- marker_conf_t *priv = NULL;
-
- priv = this->private;
-
- if (priv->feature_enabled == 0)
- goto wind;
-
- local = mem_get0 (this->local_pool);
-
- MARKER_INIT_LOCAL (frame, local);
-
- ret = loc_copy (&local->loc, loc);
-
- if (ret == -1)
- goto err;
-wind:
- STACK_WIND (frame, marker_setattr_cbk, FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->setattr, loc, stbuf, valid, xdata);
- return 0;
-err:
- STACK_UNWIND_STRICT (setattr, frame, -1, ENOMEM, NULL, NULL, NULL);
-
- return 0;
-}
-
-
-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)
-{
- marker_local_t *local = NULL;
- marker_conf_t *priv = NULL;
-
- if (op_ret == -1) {
- gf_log (this->name, GF_LOG_TRACE,
- "%s occurred while "
- "removing extended attribute",
- strerror (op_errno));
- }
-
- local = (marker_local_t *) frame->local;
-
- frame->local = NULL;
-
- STACK_UNWIND_STRICT (removexattr, frame, op_ret, op_errno, xdata);
-
- if (op_ret == -1 || local == NULL)
- goto out;
-
- priv = this->private;
-
- if (priv->feature_enabled & GF_XTIME)
- marker_xtime_update_marks (this, local);
-out:
- marker_local_unref (local);
-
- return 0;
-}
-
-int32_t
-marker_removexattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
- const char *name, dict_t *xdata)
-{
- int32_t ret = 0;
- marker_local_t *local = NULL;
- marker_conf_t *priv = NULL;
-
- priv = this->private;
-
- if (priv->feature_enabled == 0)
- goto wind;
-
- local = mem_get0 (this->local_pool);
-
- MARKER_INIT_LOCAL (frame, local);
-
- ret = loc_copy (&local->loc, loc);
-
- if (ret == -1)
- goto err;
-wind:
- STACK_WIND (frame, marker_removexattr_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->removexattr, loc, name, xdata);
- return 0;
-err:
- STACK_UNWIND_STRICT (removexattr, frame, -1, ENOMEM, NULL);
-
- return 0;
-}
-
-static gf_boolean_t
-__has_quota_xattrs (dict_t *xattrs)
-{
- if (dict_foreach_match (xattrs, _is_quota_internal_xattr, NULL,
- dict_null_foreach_fn, NULL) > 0)
- return _gf_true;
-
- return _gf_false;
-}
-
-int32_t
-marker_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)
-{
- marker_conf_t *priv = NULL;
- marker_local_t *local = NULL;
- dict_t *xattrs = NULL;
- priv = this->private;
-
- if (op_ret == -1) {
- gf_log (this->name, GF_LOG_TRACE, "lookup failed with %s",
- strerror (op_errno));
- }
-
- if (dict && __has_quota_xattrs (dict)) {
- xattrs = dict_copy_with_ref (dict, NULL);
- if (!xattrs) {
- op_ret = -1;
- op_errno = ENOMEM;
- } else {
- marker_filter_internal_xattrs (this, xattrs);
- }
- } else if (dict) {
- xattrs = dict_ref (dict);
- }
-
- local = (marker_local_t *) frame->local;
-
- frame->local = NULL;
-
- STACK_UNWIND_STRICT (lookup, frame, op_ret, op_errno, inode, buf,
- xattrs, postparent);
-
- 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);
-
-
- if (priv->feature_enabled & GF_QUOTA) {
- mq_xattr_state (this, &local->loc, dict, *buf);
- }
-
-out:
- marker_local_unref (local);
- if (xattrs)
- dict_unref (xattrs);
-
- return 0;
-}
-
-int32_t
-marker_lookup (call_frame_t *frame, xlator_t *this,
- loc_t *loc, dict_t *xattr_req)
-{
- int32_t ret = 0;
- marker_local_t *local = NULL;
- marker_conf_t *priv = NULL;
-
- priv = this->private;
-
- if (priv->feature_enabled == 0)
- goto wind;
-
- local = mem_get0 (this->local_pool);
- if (local == NULL)
- goto err;
-
- MARKER_INIT_LOCAL (frame, local);
-
- ret = loc_copy (&local->loc, loc);
- if (ret == -1)
- goto err;
-
- if ((priv->feature_enabled & GF_QUOTA) && xattr_req)
- mq_req_xattr (this, loc, xattr_req);
-wind:
- STACK_WIND (frame, marker_lookup_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->lookup, loc, xattr_req);
- return 0;
-err:
- STACK_UNWIND_STRICT (lookup, frame, -1, ENOMEM, NULL, NULL, NULL, NULL);
-
- return 0;
-}
-
-
-int
-marker_build_ancestry_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;
- loc_t loc = {0, };
- inode_t *parent = NULL;
- int ret = -1;
-
- if ((op_ret <= 0) || (entries == NULL)) {
- goto out;
- }
-
-
- list_for_each_entry (entry, &entries->list, list) {
- if (entry->inode == entry->inode->table->root) {
- inode_unref (parent);
- parent = NULL;
- }
-
- if (parent) {
- ret = marker_inode_loc_fill (parent,
- entry->d_name, &loc);
- } else {
- ret = marker_inode_loc_fill (entry->inode, NULL, &loc);
- }
-
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING, "Couldn't build "
- "loc for %s/%s",
- parent? uuid_utoa (parent->gfid): NULL,
- entry->d_name);
- continue;
- }
-
- mq_xattr_state (this, &loc, entry->dict, entry->d_stat);
-
- inode_unref (parent);
- parent = inode_ref (entry->inode);
- loc_wipe (&loc);
- }
-
- if (parent)
- inode_unref (parent);
-
-out:
- STACK_UNWIND_STRICT (readdirp, frame, op_ret, op_errno, entries, xdata);
- 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;
- marker_conf_t *priv = NULL;
- marker_local_t *local = NULL;
- loc_t loc = {0, };
- int ret = -1;
- char *resolvedpath = NULL;
-
- if (op_ret <= 0)
- goto unwind;
-
- priv = this->private;
- local = frame->local;
-
- if (!(priv->feature_enabled & GF_QUOTA) || (local == NULL)) {
- goto unwind;
- }
-
- list_for_each_entry (entry, &entries->list, list) {
- if ((strcmp (entry->d_name, ".") == 0) ||
- (strcmp (entry->d_name, "..") == 0) ||
- entry->inode == NULL)
- continue;
-
- loc.parent = inode_ref (local->loc.inode);
- loc.inode = inode_ref (entry->inode);
- ret = inode_path (loc.parent, entry->d_name, &resolvedpath);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR, "failed to get the "
- "path for the entry %s", entry->d_name);
- loc_wipe (&loc);
- continue;
- }
-
- loc.path = gf_strdup (resolvedpath);
- if (!loc.path) {
- gf_log (this->name, GF_LOG_ERROR, "strdup of path "
- "failed for the entry %s (path: %s)",
- entry->d_name, resolvedpath);
- loc_wipe (&loc);
- continue;
- }
-
- mq_xattr_state (this, &loc, entry->dict, entry->d_stat);
-
- loc_wipe (&loc);
- GF_FREE (resolvedpath);
- resolvedpath = NULL;
- }
-
-unwind:
- local = frame->local;
- frame->local = NULL;
-
- STACK_UNWIND_STRICT (readdirp, frame, op_ret, op_errno, entries, xdata);
- marker_local_unref (local);
-
- 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;
- loc_t loc = {0, };
- marker_local_t *local = NULL;
-
- priv = this->private;
-
- if ((dict != NULL) && dict_get (dict, GET_ANCESTRY_DENTRY_KEY)) {
- STACK_WIND (frame, marker_build_ancestry_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->readdirp,
- fd, size, offset, dict);
- } else {
- if (priv->feature_enabled & GF_QUOTA) {
- local = mem_get0 (this->local_pool);
-
- MARKER_INIT_LOCAL (frame, local);
-
- loc.parent = local->loc.inode = inode_ref (fd->inode);
-
- if (dict == NULL)
- dict = dict_new ();
-
- mq_req_xattr (this, &loc, dict);
- }
-
- 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)
-{
- int ret = -1;
-
- if (!this)
- return ret;
-
- ret = xlator_mem_acct_init (this, gf_marker_mt_end + 1);
-
- if (ret != 0) {
- gf_log(this->name, GF_LOG_ERROR, "Memory accounting init"
- " failed");
- return ret;
- }
-
- return ret;
-}
-
-
-int32_t
-init_xtime_priv (xlator_t *this, dict_t *options)
-{
- data_t *data = NULL;
- int32_t ret = -1;
- marker_conf_t *priv = NULL;
-
- GF_VALIDATE_OR_GOTO ("marker", this, out);
- GF_VALIDATE_OR_GOTO (this->name, options, out);
- GF_VALIDATE_OR_GOTO (this->name, this->private, out);
-
- priv = this->private;
-
- if((data = dict_get (options, VOLUME_UUID)) != NULL) {
- priv->volume_uuid = data->data;
-
- 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);
- goto out;
- }
-
- ret = gf_asprintf (& (priv->marker_xattr), "%s.%s.%s",
- MARKER_XATTR_PREFIX, priv->volume_uuid,
- XTIME);
-
- if (ret == -1){
- priv->marker_xattr = NULL;
- goto out;
- }
-
- gf_log (this->name, GF_LOG_DEBUG,
- "volume-uuid = %s", priv->volume_uuid);
- } else {
- priv->volume_uuid = NULL;
-
- gf_log (this->name, GF_LOG_ERROR,
- "please specify the volume-uuid"
- "in the translator options");
-
- return -1;
- }
-
- if ((data = dict_get (options, TIMESTAMP_FILE)) != NULL) {
- priv->timestamp_file = data->data;
-
- gf_log (this->name, GF_LOG_DEBUG,
- "the timestamp-file is = %s",
- priv->timestamp_file);
-
- } else {
- priv->timestamp_file = NULL;
-
- gf_log (this->name, GF_LOG_ERROR,
- "please specify the timestamp-file"
- "in the translator options");
-
- goto out;
- }
-
- ret = 0;
-out:
- return ret;
-}
-
-void
-marker_xtime_priv_cleanup (xlator_t *this)
-{
- marker_conf_t *priv = NULL;
-
- GF_VALIDATE_OR_GOTO ("marker", this, out);
-
- priv = (marker_conf_t *) this->private;
-
- GF_VALIDATE_OR_GOTO (this->name, priv, out);
-
- GF_FREE (priv->volume_uuid);
-
- GF_FREE (priv->timestamp_file);
-
- GF_FREE (priv->marker_xattr);
-out:
- return;
-}
-
-void
-marker_priv_cleanup (xlator_t *this)
-{
- marker_conf_t *priv = NULL;
-
- GF_VALIDATE_OR_GOTO ("marker", this, out);
-
- priv = (marker_conf_t *) this->private;
-
- GF_VALIDATE_OR_GOTO (this->name, priv, out);
-
- marker_xtime_priv_cleanup (this);
-
- LOCK_DESTROY (&priv->lock);
-
- GF_FREE (priv);
-out:
- return;
-}
-
-int32_t
-reconfigure (xlator_t *this, dict_t *options)
-{
- int32_t ret = 0;
- data_t *data = NULL;
- gf_boolean_t flag = _gf_false;
- marker_conf_t *priv = NULL;
-
- GF_ASSERT (this);
- GF_ASSERT (this->private);
-
- priv = this->private;
-
- priv->feature_enabled = 0;
-
- GF_VALIDATE_OR_GOTO (this->name, options, out);
-
- data = dict_get (options, "quota");
- if (data) {
- ret = gf_string2boolean (data->data, &flag);
- if (ret == 0 && flag == _gf_true) {
- ret = init_quota_priv (this);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_WARNING,
- "failed to initialize quota private");
- } else {
- priv->feature_enabled |= GF_QUOTA;
- }
- }
- }
-
- data = dict_get (options, "xtime");
- if (data) {
- ret = gf_string2boolean (data->data, &flag);
- if (ret == 0 && flag == _gf_true) {
- marker_xtime_priv_cleanup (this);
-
- ret = init_xtime_priv (this, options);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_WARNING,
- "failed to initialize xtime private, "
- "xtime updation will fail");
- } else {
- priv->feature_enabled |= GF_XTIME;
- data = dict_get (options, "gsync-force-xtime");
- if (!data)
- goto out;
- ret = gf_string2boolean (data->data, &flag);
- if (ret == 0 && flag)
- priv->feature_enabled |= GF_XTIME_GSYNC_FORCE;
- }
- }
- }
-out:
- return ret;
-}
-
-
-int32_t
-init (xlator_t *this)
-{
- dict_t *options = NULL;
- data_t *data = NULL;
- int32_t ret = 0;
- gf_boolean_t flag = _gf_false;
- marker_conf_t *priv = NULL;
-
- if (!this->children) {
- gf_log (this->name, GF_LOG_ERROR,
- "marker translator needs subvolume defined.");
- return -1;
- }
-
- if (!this->parents) {
- gf_log (this->name, GF_LOG_WARNING,
- "Volume is dangling.");
- return -1;
- }
-
- options = this->options;
-
- ALLOCATE_OR_GOTO (this->private, marker_conf_t, err);
-
- priv = this->private;
-
- priv->feature_enabled = 0;
-
- LOCK_INIT (&priv->lock);
-
- data = dict_get (options, "quota");
- if (data) {
- ret = gf_string2boolean (data->data, &flag);
- if (ret == 0 && flag == _gf_true) {
- ret = init_quota_priv (this);
- if (ret < 0)
- goto err;
-
- priv->feature_enabled |= GF_QUOTA;
- }
- }
-
- data = dict_get (options, "xtime");
- if (data) {
- ret = gf_string2boolean (data->data, &flag);
- if (ret == 0 && flag == _gf_true) {
- ret = init_xtime_priv (this, options);
- if (ret < 0)
- goto err;
-
- priv->feature_enabled |= GF_XTIME;
- data = dict_get (options, "gsync-force-xtime");
- if (!data)
- goto cont;
- ret = gf_string2boolean (data->data, &flag);
- if (ret == 0 && flag)
- priv->feature_enabled |= GF_XTIME_GSYNC_FORCE;
- }
- }
-
- cont:
- 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);
-
- return -1;
-}
-
-int32_t
-marker_forget (xlator_t *this, inode_t *inode)
-{
- marker_inode_ctx_t *ctx = NULL;
- uint64_t value = 0;
-
- if (inode_ctx_del (inode, this, &value) != 0)
- goto out;
-
- ctx = (marker_inode_ctx_t *)(unsigned long)value;
- if (ctx == NULL) {
- goto out;
- }
-
- mq_forget (this, ctx->quota_ctx);
-
- GF_FREE (ctx);
-out:
- return 0;
-}
-
-void
-fini (xlator_t *this)
-{
- marker_priv_cleanup (this);
-}
-
-struct xlator_fops fops = {
- .lookup = marker_lookup,
- .create = marker_create,
- .mkdir = marker_mkdir,
- .writev = marker_writev,
- .truncate = marker_truncate,
- .ftruncate = marker_ftruncate,
- .symlink = marker_symlink,
- .link = marker_link,
- .unlink = marker_unlink,
- .rmdir = marker_rmdir,
- .rename = marker_rename,
- .mknod = marker_mknod,
- .setxattr = marker_setxattr,
- .fsetxattr = marker_fsetxattr,
- .setattr = marker_setattr,
- .fsetattr = marker_fsetattr,
- .removexattr = marker_removexattr,
- .getxattr = marker_getxattr,
- .readdirp = marker_readdirp,
- .fallocate = marker_fallocate,
- .discard = marker_discard,
- .zerofill = marker_zerofill,
-};
-
-struct xlator_cbks cbks = {
- .forget = marker_forget
-};
-
-struct volume_options options[] = {
- {.key = {"volume-uuid"}},
- {.key = {"timestamp-file"}},
- {.key = {"quota"}},
- {.key = {"xtime"}},
- {.key = {"gsync-force-xtime"}},
- {.key = {NULL}}
-};
diff --git a/xlators/features/marker/src/marker.h b/xlators/features/marker/src/marker.h
deleted file mode 100644
index 23d1580f0e5..00000000000
--- a/xlators/features/marker/src/marker.h
+++ /dev/null
@@ -1,139 +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 _MARKER_H
-#define _MARKER_H
-
-#ifndef _CONFIG_H
-#define _CONFIG_H
-#include "config.h"
-#endif
-
-#include "marker-quota.h"
-#include "xlator.h"
-#include "defaults.h"
-#include "uuid.h"
-#include "call-stub.h"
-
-#define MARKER_XATTR_PREFIX "trusted.glusterfs"
-#define XTIME "xtime"
-#define VOLUME_MARK "volume-mark"
-#define VOLUME_UUID "volume-uuid"
-#define TIMESTAMP_FILE "timestamp-file"
-
-enum {
- GF_QUOTA = 1,
- GF_XTIME = 2,
- GF_XTIME_GSYNC_FORCE = 4,
-};
-
-/*initialize the local variable*/
-#define MARKER_INIT_LOCAL(_frame,_local) do { \
- _frame->local = _local; \
- _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)
-
-/* try alloc and if it fails, goto label */
-#define ALLOCATE_OR_GOTO(var, type, label) do { \
- var = GF_CALLOC (sizeof (type), 1, \
- gf_marker_mt_##type); \
- if (!var) { \
- gf_log (this->name, GF_LOG_ERROR, \
- "out of memory :("); \
- goto label; \
- } \
- } 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;
- dict_t *xdata;
- gf_boolean_t skip_txn;
-};
-typedef struct marker_local marker_local_t;
-
-#define quota_local_t marker_local_t
-
-struct marker_inode_ctx {
- struct quota_inode_ctx *quota_ctx;
-};
-typedef struct marker_inode_ctx marker_inode_ctx_t;
-
-struct marker_conf{
- char feature_enabled;
- char *size_key;
- char *dirty_key;
- char *volume_uuid;
- uuid_t volume_uuid_bin;
- char *timestamp_file;
- char *marker_xattr;
- uint64_t quota_lk_owner;
- gf_lock_t lock;
-};
-typedef struct marker_conf marker_conf_t;
-
-#endif
diff --git a/xlators/features/path-convertor/src/Makefile.am b/xlators/features/path-convertor/src/Makefile.am
index 393a7bd089c..58cfed0f983 100644
--- a/xlators/features/path-convertor/src/Makefile.am
+++ b/xlators/features/path-convertor/src/Makefile.am
@@ -2,14 +2,13 @@
xlator_LTLIBRARIES = path-converter.la
xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/testing/features
-path_converter_la_LDFLAGS = -module -avoid-version
+path_converter_la_LDFLAGS = -module -avoidversion
path_converter_la_SOURCES = path.c
path_converter_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la
-AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src
-
-AM_CFLAGS = -Wall $(GF_CFLAGS)
+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/features/path-convertor/src/path-mem-types.h b/xlators/features/path-convertor/src/path-mem-types.h
deleted file mode 100644
index 77ada8d537a..00000000000
--- a/xlators/features/path-convertor/src/path-mem-types.h
+++ /dev/null
@@ -1,22 +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 __PATH_MEM_TYPES_H__
-#define __PATH_MEM_TYPES_H__
-
-#include "mem-types.h"
-
-enum gf_path_mem_types_ {
- gf_path_mt_path_private_t = gf_common_mt_end + 1,
- gf_path_mt_char,
- gf_path_mt_regex_t,
- gf_path_mt_end
-};
-#endif
-
diff --git a/xlators/features/path-convertor/src/path.c b/xlators/features/path-convertor/src/path.c
index 5c52e0a8d53..d58f0f3cb59 100644
--- a/xlators/features/path-convertor/src/path.c
+++ b/xlators/features/path-convertor/src/path.c
@@ -1,12 +1,22 @@
/*
- 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-2009 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/>.
*/
+
/* TODO: add gf_log to all the cases returning errors */
#ifndef _CONFIG_H
@@ -25,7 +35,6 @@
#include <errno.h>
#include "glusterfs.h"
#include "xlator.h"
-#include "path-mem-types.h"
typedef struct path_private
{
@@ -42,7 +51,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;
@@ -54,9 +63,7 @@ name_this_to_that (xlator_t *xl, const char *path, const char *name)
if (priv->end_off && (total_len > priv->end_off)) {
j = priv->start_off;
- tmp_name = GF_CALLOC (1, (total_len +
- ZR_FILE_CONTENT_STRLEN),
- gf_path_mt_char);
+ tmp_name = CALLOC (1, (total_len + ZR_FILE_CONTENT_STRLEN));
ERR_ABORT (tmp_name);
/* Get the complete path for the file first */
@@ -97,7 +104,7 @@ path_this_to_that (xlator_t *xl, const char *path)
int32_t i = 0, j = 0;
if (priv->end_off && (path_len > priv->start_off)) {
- priv_path = GF_CALLOC (1, path_len, gf_path_mt_char);
+ priv_path = CALLOC (1, path_len);
ERR_ABORT (priv_path);
if (priv->start_off && (path_len > priv->start_off))
@@ -127,9 +134,9 @@ path_create_cbk (call_frame_t *frame,
int32_t op_errno,
fd_t *fd,
inode_t *inode,
- struct iatt *buf,
- struct iatt *preparent,
- struct iatt *postparent)
+ struct stat *buf,
+ struct stat *preparent,
+ struct stat *postparent)
{
STACK_UNWIND (frame, op_ret, op_errno, fd, inode, buf);
return 0;
@@ -180,7 +187,7 @@ path_readlink_cbk (call_frame_t *frame,
int32_t op_ret,
int32_t op_errno,
const char *buf,
- struct iatt *sbuf)
+ struct stat *sbuf)
{
STACK_UNWIND (frame, op_ret, op_errno, buf, sbuf);
return 0;
@@ -193,9 +200,9 @@ path_lookup_cbk (call_frame_t *frame,
int32_t op_ret,
int32_t op_errno,
inode_t *inode,
- struct iatt *buf,
+ struct stat *buf,
dict_t *xattr,
- struct iatt *postparent)
+ struct stat *postparent)
{
STACK_UNWIND (frame, op_ret, op_errno, inode, buf, xattr);
return 0;
@@ -209,9 +216,9 @@ path_symlink_cbk (call_frame_t *frame,
int32_t op_ret,
int32_t op_errno,
inode_t *inode,
- struct iatt *buf,
- struct iatt *preparent,
- struct iatt *postparent)
+ struct stat *buf,
+ struct stat *preparent,
+ struct stat *postparent)
{
STACK_UNWIND (frame, op_ret, op_errno, inode, buf);
return 0;
@@ -224,9 +231,9 @@ path_mknod_cbk (call_frame_t *frame,
int32_t op_ret,
int32_t op_errno,
inode_t *inode,
- struct iatt *buf,
- struct iatt *preparent,
- struct iatt *postparent)
+ struct stat *buf,
+ struct stat *preparent,
+ struct stat *postparent)
{
STACK_UNWIND (frame, op_ret, op_errno, inode, buf);
return 0;
@@ -240,9 +247,9 @@ path_mkdir_cbk (call_frame_t *frame,
int32_t op_ret,
int32_t op_errno,
inode_t *inode,
- struct iatt *buf,
- struct iatt *preparent,
- struct iatt *postparent)
+ struct stat *buf,
+ struct stat *preparent,
+ struct stat *postparent)
{
STACK_UNWIND (frame, op_ret, op_errno, inode, buf);
return 0;
@@ -255,9 +262,9 @@ path_link_cbk (call_frame_t *frame,
int32_t op_ret,
int32_t op_errno,
inode_t *inode,
- struct iatt *buf,
- struct iatt *preparent,
- struct iatt *postparent)
+ struct stat *buf,
+ struct stat *preparent,
+ struct stat *postparent)
{
STACK_UNWIND (frame, op_ret, op_errno, inode, buf);
return 0;
@@ -282,11 +289,11 @@ path_rename_buf_cbk (call_frame_t *frame,
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)
+ struct stat *buf,
+ struct stat *preoldparent,
+ struct stat *postoldparent,
+ struct stat *prenewparent,
+ struct stat *postnewparent)
{
STACK_UNWIND (frame, op_ret, op_errno, buf);
return 0;
@@ -300,7 +307,7 @@ path_common_buf_cbk (call_frame_t *frame,
xlator_t *this,
int32_t op_ret,
int32_t op_errno,
- struct iatt *buf)
+ struct stat *buf)
{
STACK_UNWIND (frame, op_ret, op_errno, buf);
return 0;
@@ -320,8 +327,8 @@ path_common_dict_cbk (call_frame_t *frame,
int32_t
path_common_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)
+ int32_t op_ret, int32_t op_errno,struct stat *preparent,
+ struct stat *postparent)
{
STACK_UNWIND (frame, op_ret, op_errno);
return 0;
@@ -329,8 +336,8 @@ path_common_remove_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t
path_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 op_ret, int32_t op_errno,struct stat *prebuf,
+ struct stat *postbuf)
{
STACK_UNWIND (frame, op_ret, op_errno, prebuf, postbuf);
return 0;
@@ -371,7 +378,7 @@ path_lookup (call_frame_t *frame,
loc->path = loc_path;
if (tmp_path != loc_path)
- GF_FREE (tmp_path);
+ FREE (tmp_path);
return 0;
}
@@ -398,7 +405,7 @@ path_stat (call_frame_t *frame,
loc->path = loc_path;
if (tmp_path != loc_path)
- GF_FREE (tmp_path);
+ FREE (tmp_path);
return 0;
}
@@ -427,7 +434,7 @@ path_readlink (call_frame_t *frame,
loc->path = loc_path;
if (tmp_path != loc_path)
- GF_FREE (tmp_path);
+ FREE (tmp_path);
return 0;
}
@@ -458,7 +465,7 @@ path_mknod (call_frame_t *frame,
loc->path = loc_path;
if (tmp_path != loc_path)
- GF_FREE (tmp_path);
+ FREE (tmp_path);
return 0;
}
@@ -487,7 +494,7 @@ path_mkdir (call_frame_t *frame,
loc->path = loc_path;
if (tmp_path != loc_path)
- GF_FREE (tmp_path);
+ FREE (tmp_path);
return 0;
}
@@ -514,7 +521,7 @@ path_unlink (call_frame_t *frame,
loc->path = loc_path;
if (tmp_path != loc_path)
- GF_FREE (tmp_path);
+ FREE (tmp_path);
return 0;
}
@@ -541,7 +548,7 @@ path_rmdir (call_frame_t *frame,
loc->path = loc_path;
if (tmp_path != loc_path)
- GF_FREE (tmp_path);
+ FREE (tmp_path);
return 0;
}
@@ -570,7 +577,7 @@ path_symlink (call_frame_t *frame,
loc->path = loc_path;
if (tmp_path != loc_path)
- GF_FREE (tmp_path);
+ FREE (tmp_path);
return 0;
}
@@ -608,11 +615,11 @@ path_rename (call_frame_t *frame,
oldloc->path = oldloc_path;
if (tmp_oldloc_path != oldloc_path)
- GF_FREE (tmp_oldloc_path);
+ FREE (tmp_oldloc_path);
newloc->path = newloc_path;
if (tmp_newloc_path != newloc_path)
- GF_FREE (tmp_newloc_path);
+ FREE (tmp_newloc_path);
return 0;
}
@@ -650,11 +657,11 @@ path_link (call_frame_t *frame,
oldloc->path = oldloc_path;
if (tmp_oldloc_path != oldloc_path)
- GF_FREE (tmp_oldloc_path);
+ FREE (tmp_oldloc_path);
newloc->path = newloc_path;
if (tmp_newloc_path != newloc_path)
- GF_FREE (tmp_newloc_path);
+ FREE (tmp_newloc_path);
return 0;
}
@@ -665,8 +672,8 @@ path_setattr_cbk (call_frame_t *frame,
xlator_t *this,
int32_t op_ret,
int32_t op_errno,
- struct iatt *preop,
- struct iatt *postop)
+ struct stat *preop,
+ struct stat *postop)
{
STACK_UNWIND (frame, op_ret, op_errno, preop, postop);
return 0;
@@ -676,7 +683,7 @@ int32_t
path_setattr (call_frame_t *frame,
xlator_t *this,
loc_t *loc,
- struct iatt *stbuf,
+ struct stat *stbuf,
int32_t valid)
{
char *loc_path = (char *)loc->path;
@@ -697,7 +704,7 @@ path_setattr (call_frame_t *frame,
loc->path = loc_path;
if (tmp_path != loc_path)
- GF_FREE (tmp_path);
+ FREE (tmp_path);
return 0;
}
@@ -727,7 +734,7 @@ path_truncate (call_frame_t *frame,
loc->path = loc_path;
if (tmp_path != loc_path)
- GF_FREE (tmp_path);
+ FREE (tmp_path);
return 0;
}
@@ -761,7 +768,7 @@ path_open (call_frame_t *frame,
loc->path = loc_path;
if (tmp_path != loc_path)
- GF_FREE (tmp_path);
+ FREE (tmp_path);
return 0;
}
@@ -794,7 +801,7 @@ path_create (call_frame_t *frame,
loc->path = loc_path;
if (tmp_path != loc_path)
- GF_FREE (tmp_path);
+ FREE (tmp_path);
return 0;
}
@@ -836,9 +843,10 @@ path_setxattr (call_frame_t *frame,
loc->path = loc_path;
if (tmp_path != loc_path)
- GF_FREE (tmp_path);
+ FREE (tmp_path);
- GF_FREE (tmp_name);
+ if (tmp_name)
+ FREE (tmp_name);
return 0;
}
@@ -872,10 +880,10 @@ path_getxattr (call_frame_t *frame,
loc->path = loc_path;
if (tmp_path != loc_path)
- GF_FREE (tmp_path);
+ FREE (tmp_path);
if (tmp_name != name)
- GF_FREE (tmp_name);
+ FREE (tmp_name);
return 0;
}
@@ -909,10 +917,10 @@ path_removexattr (call_frame_t *frame,
loc->path = loc_path;
if (tmp_path != loc_path)
- GF_FREE (tmp_path);
+ FREE (tmp_path);
if (tmp_name != name)
- GF_FREE (tmp_name);
+ FREE (tmp_name);
return 0;
}
@@ -941,7 +949,7 @@ path_opendir (call_frame_t *frame,
loc->path = loc_path;
if (tmp_path != loc_path)
- GF_FREE (tmp_path);
+ FREE (tmp_path);
return 0;
}
@@ -970,7 +978,7 @@ path_access (call_frame_t *frame,
loc->path = loc_path;
if (tmp_path != loc_path)
- GF_FREE (tmp_path);
+ FREE (tmp_path);
return 0;
}
@@ -1012,7 +1020,7 @@ path_checksum (call_frame_t *frame,
loc->path = loc_path;
if (tmp_path != loc_path)
- GF_FREE (tmp_path);
+ FREE (tmp_path);
return 0;
}
@@ -1039,14 +1047,14 @@ path_entrylk (call_frame_t *frame, xlator_t *this,
loc->path = loc_path;
if (tmp_path != loc_path)
- GF_FREE (tmp_path);
+ FREE (tmp_path);
return 0;
}
int32_t
path_inodelk (call_frame_t *frame, xlator_t *this,
- const char *volume, loc_t *loc, int32_t cmd, struct gf_flock *lock)
+ const char *volume, loc_t *loc, int32_t cmd, struct flock *lock)
{
char *loc_path = (char *)loc->path;
char *tmp_path = NULL;
@@ -1065,7 +1073,7 @@ path_inodelk (call_frame_t *frame, xlator_t *this,
loc->path = loc_path;
if (tmp_path != loc_path)
- GF_FREE (tmp_path);
+ FREE (tmp_path);
return 0;
}
@@ -1097,29 +1105,11 @@ path_xattrop (call_frame_t *frame,
loc->path = loc_path;
if (tmp_path != loc_path)
- GF_FREE (tmp_path);
+ FREE (tmp_path);
return 0;
}
-int32_t
-mem_acct_init (xlator_t *this)
-{
- int ret = -1;
-
- if (!this)
- return ret;
-
- ret = xlator_mem_acct_init (this, gf_path_mt_end + 1);
-
- if (ret != 0) {
- gf_log (this->name, GF_LOG_ERROR, "Memory accounting init"
- "failed");
- return ret;
- }
-
- return ret;
-}
int32_t
init (xlator_t *this)
@@ -1138,7 +1128,7 @@ init (xlator_t *this)
"dangling volume. check volfile ");
}
- priv = GF_CALLOC (1, sizeof (*priv), gf_path_mt_path_private_t);
+ priv = CALLOC (1, sizeof (*priv));
ERR_ABORT (priv);
if (dict_get (options, "start-offset")) {
priv->start_off = data_to_int32 (dict_get (options,
@@ -1151,8 +1141,7 @@ init (xlator_t *this)
if (dict_get (options, "regex")) {
int32_t ret = 0;
- priv->preg = GF_CALLOC (1, sizeof (regex_t),
- gf_path_mt_regex_t);
+ priv->preg = CALLOC (1, sizeof (regex_t));
ERR_ABORT (priv->preg);
ret = regcomp (priv->preg,
data_to_str (dict_get (options, "regex")),
@@ -1160,7 +1149,7 @@ init (xlator_t *this)
if (ret) {
gf_log (this->name, GF_LOG_ERROR,
"Failed to compile the 'option regex'");
- GF_FREE (priv);
+ FREE (priv);
return -1;
}
if (dict_get (options, "replace-with")) {
@@ -1207,6 +1196,11 @@ struct xlator_fops fops = {
.setattr = path_setattr,
};
+
+struct xlator_mops mops = {
+};
+
+
struct xlator_cbks cbks = {
};
diff --git a/xlators/features/protect/Makefile.am b/xlators/features/protect/Makefile.am
deleted file mode 100644
index d471a3f9243..00000000000
--- a/xlators/features/protect/Makefile.am
+++ /dev/null
@@ -1,3 +0,0 @@
-SUBDIRS = src
-
-CLEANFILES =
diff --git a/xlators/features/protect/src/Makefile.am b/xlators/features/protect/src/Makefile.am
deleted file mode 100644
index fdfed4b219e..00000000000
--- a/xlators/features/protect/src/Makefile.am
+++ /dev/null
@@ -1,21 +0,0 @@
-xlator_LTLIBRARIES = prot_dht.la prot_client.la prot_server.la
-
-xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/features
-
-prot_dht_la_LDFLAGS = -module -avoid-version
-prot_dht_la_SOURCES = prot_dht.c
-prot_dht_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la
-
-prot_client_la_LDFLAGS = -module -avoid-version
-prot_client_la_SOURCES = prot_client.c
-prot_client_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la
-
-prot_server_la_LDFLAGS = -module -avoid-version
-prot_server_la_SOURCES = prot_server.c
-prot_server_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la
-
-AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \
- -I$(CONTRIBDIR)/libexecinfo
-AM_CFLAGS = -Wall $(GF_CFLAGS)
-
-CLEANFILES =
diff --git a/xlators/features/protect/src/prot_client.c b/xlators/features/protect/src/prot_client.c
deleted file mode 100644
index 500c772bedd..00000000000
--- a/xlators/features/protect/src/prot_client.c
+++ /dev/null
@@ -1,219 +0,0 @@
-/*
- Copyright (c) 2013 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 "xlator.h"
-#include "defaults.h"
-
-#ifdef HAVE_BACKTRACE
-#include <execinfo.h>
-#else
-#include "execinfo_compat.h"
-#endif
-
-#define NUM_FRAMES 20
-
-static char PROTECT_KEY[] = "trusted.glusterfs.protect";
-
-enum {
- PROT_ACT_NONE = 0,
- PROT_ACT_LOG,
- PROT_ACT_REJECT,
-};
-
-void
-pcli_print_trace (char *name, call_frame_t *frame)
-{
- void *frames[NUM_FRAMES];
- char **symbols;
- int size;
- int i;
-
- gf_log (name, GF_LOG_INFO, "Translator stack:");
- while (frame) {
- gf_log (name, GF_LOG_INFO, "%s (%s)",
- frame->wind_from, frame->this->name);
- frame = frame->next;
- }
-
- size = backtrace (frames, NUM_FRAMES);
- if (size <= 0) {
- return;
- }
- symbols = backtrace_symbols (frames, size);
- if (!symbols) {
- return;
- }
-
- gf_log (name, GF_LOG_INFO, "Processor stack:");
- for (i = 0; i < size; ++i) {
- gf_log (name, GF_LOG_INFO, "%s", symbols[i]);
- }
- free (symbols);
-}
-
-int32_t
-pcli_rename (call_frame_t *frame, xlator_t *this, loc_t *oldloc,
- loc_t *newloc, dict_t *xdata)
-{
- uint64_t value;
-
- if (newloc->parent == oldloc->parent) {
- gf_log (this->name, GF_LOG_DEBUG, "rename in same directory");
- goto simple_unwind;
- }
- if (!oldloc->parent) {
- goto simple_unwind;
- }
- if (inode_ctx_get (oldloc->parent, this, &value) != 0) {
- goto simple_unwind;
- }
-
- if (value != PROT_ACT_NONE) {
- gf_log (this->name, GF_LOG_WARNING,
- "got rename for protected %s", oldloc->path);
- pcli_print_trace (this->name, frame->next);
- if (value == PROT_ACT_REJECT) {
- STACK_UNWIND_STRICT (rename, frame, -1, EPERM,
- NULL, NULL, NULL, NULL, NULL,
- xdata);
- return 0;
- }
- }
-
-simple_unwind:
- STACK_WIND_TAIL (frame, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->rename, oldloc, newloc,
- xdata);
- return 0;
-}
-
-int32_t
-pcli_setxattr (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *dict,
- int32_t flags, dict_t *xdata)
-{
- data_t *data;
- uint64_t value;
-
- /*
- * We can't use dict_get_str and strcmp here, because the value comes
- * directly from the user and might not be NUL-terminated (it would
- * be if we had set it ourselves.
- */
-
- data = dict_get(dict,PROTECT_KEY);
- if (!data) {
- goto simple_wind;
- }
-
- if (dict->count > 1) {
- gf_log (this->name, GF_LOG_WARNING,
- "attempted to mix %s with other keys", PROTECT_KEY);
- goto simple_wind;
- }
-
- gf_log (this->name, GF_LOG_DEBUG, "got %s request", PROTECT_KEY);
- if (!strncmp(data->data,"log",data->len)) {
- gf_log (this->name, GF_LOG_DEBUG,
- "logging removals on %s", loc->path);
- value = PROT_ACT_LOG;
- }
- else if (!strncmp(data->data,"reject",data->len)) {
- gf_log (this->name, GF_LOG_DEBUG,
- "rejecting removals on %s", loc->path);
- value = PROT_ACT_REJECT;
- }
- else {
- gf_log (this->name, GF_LOG_DEBUG,
- "removing protection on %s", loc->path);
- value = PROT_ACT_NONE;
- }
- /* Right now the value doesn't matter - just the presence. */
- if (inode_ctx_set(loc->inode,this,&value) != 0) {
- gf_log (this->name, GF_LOG_WARNING,
- "failed to set protection status for %s", loc->path);
- }
- STACK_UNWIND_STRICT (setxattr, frame, 0, 0, NULL);
- return 0;
-
-simple_wind:
- STACK_WIND_TAIL (frame,
- FIRST_CHILD(this), FIRST_CHILD(this)->fops->setxattr,
- loc, dict, flags, xdata);
- return 0;
-}
-
-int32_t
-pcli_unlink (call_frame_t *frame, xlator_t *this, loc_t *loc, int xflag,
- dict_t *xdata)
-{
- uint64_t value;
-
- if (!loc->parent || (inode_ctx_get(loc->parent,this,&value) != 0)) {
- goto simple_unwind;
- }
-
- if (value != PROT_ACT_NONE) {
- gf_log (this->name, GF_LOG_WARNING,
- "got unlink for protected %s", loc->path);
- pcli_print_trace(this->name,frame->next);
- if (value == PROT_ACT_REJECT) {
- STACK_UNWIND_STRICT (unlink, frame, -1, EPERM,
- NULL, NULL, NULL);
- return 0;
- }
- }
-
-simple_unwind:
- STACK_WIND_TAIL (frame, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->unlink, loc, xflag, 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 = {
- .rename = pcli_rename,
- .setxattr = pcli_setxattr,
- .unlink = pcli_unlink,
-};
-
-struct xlator_cbks cbks = {
-};
-
-struct volume_options options[] = {
- { .key = {NULL} },
-};
diff --git a/xlators/features/protect/src/prot_dht.c b/xlators/features/protect/src/prot_dht.c
deleted file mode 100644
index feec6ffd69c..00000000000
--- a/xlators/features/protect/src/prot_dht.c
+++ /dev/null
@@ -1,168 +0,0 @@
-/*
- Copyright (c) 2013 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 "xlator.h"
-#include "defaults.h"
-
-enum gf_pdht_mem_types_ {
- gf_pdht_mt_coord_t = gf_common_mt_end + 1,
- gf_pdht_mt_end
-};
-
-typedef struct {
- pthread_mutex_t lock;
- uint16_t refs;
- int32_t op_ret;
- int32_t op_errno;
- dict_t *xdata;
-} pdht_coord_t;
-
-static char PROTECT_KEY[] = "trusted.glusterfs.protect";
-
-void
-pdht_unref_and_unlock (call_frame_t *frame, xlator_t *this,
- pdht_coord_t *coord)
-{
- gf_boolean_t should_unwind;
-
- should_unwind = (--(coord->refs) == 0);
- pthread_mutex_unlock(&coord->lock);
-
- if (should_unwind) {
- STACK_UNWIND_STRICT (setxattr, frame,
- coord->op_ret, coord->op_errno,
- coord->xdata);
- if (coord->xdata) {
- dict_unref(coord->xdata);
- }
- GF_FREE(coord);
- }
-}
-
-int32_t
-pdht_recurse_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
-{
- pdht_coord_t *coord = cookie;
-
- pthread_mutex_lock(&coord->lock);
- if (op_ret) {
- coord->op_ret = op_ret;
- coord->op_errno = op_errno;
- }
- if (xdata) {
- if (coord->xdata) {
- dict_unref(coord->xdata);
- }
- coord->xdata = dict_ref(xdata);
- }
- pdht_unref_and_unlock(frame,this,coord);
-
- return 0;
-}
-
-void
-pdht_recurse (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *dict,
- int32_t flags, dict_t *xdata, xlator_t *xl, pdht_coord_t *coord)
-{
- xlator_list_t *iter;
-
- if (!strcmp(xl->type,"features/prot_client")) {
- pthread_mutex_lock(&coord->lock);
- ++(coord->refs);
- pthread_mutex_unlock(&coord->lock);
- STACK_WIND_COOKIE (frame, pdht_recurse_cbk, coord, xl,
- xl->fops->setxattr, loc, dict, flags, xdata);
- }
-
- else for (iter = xl->children; iter; iter = iter->next) {
- pdht_recurse (frame, this, loc, dict, flags, xdata,
- iter->xlator, coord);
- }
-}
-
-int32_t
-pdht_setxattr (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *dict,
- int32_t flags, dict_t *xdata)
-{
- pdht_coord_t *coord;
-
- if (!dict_get(dict,PROTECT_KEY)) {
- goto simple_wind;
- }
-
- if (dict->count > 1) {
- gf_log (this->name, GF_LOG_WARNING,
- "attempted to mix %s with other keys", PROTECT_KEY);
- goto simple_wind;
- }
-
- coord = GF_CALLOC(1,sizeof(*coord),gf_pdht_mt_coord_t);
- if (!coord) {
- gf_log (this->name, GF_LOG_WARNING, "allocation failed");
- goto simple_wind;
- }
-
- pthread_mutex_init(&coord->lock,NULL);
- coord->refs = 1;
- coord->op_ret = 0;
- coord->xdata = NULL;
-
- pdht_recurse(frame,this,loc,dict,flags,xdata,this,coord);
- pthread_mutex_lock(&coord->lock);
- pdht_unref_and_unlock(frame,this,coord);
-
- return 0;
-
-simple_wind:
- STACK_WIND_TAIL (frame,
- FIRST_CHILD(this), FIRST_CHILD(this)->fops->setxattr,
- loc, dict, flags, 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 = {
- .setxattr = pdht_setxattr,
-};
-
-struct xlator_cbks cbks = {
-};
-
-struct volume_options options[] = {
- { .key = {NULL} },
-};
diff --git a/xlators/features/protect/src/prot_server.c b/xlators/features/protect/src/prot_server.c
deleted file mode 100644
index beaee0889b7..00000000000
--- a/xlators/features/protect/src/prot_server.c
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- Copyright (c) 2013 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 "xlator.h"
-#include "defaults.h"
-
-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 = {
-};
-
-struct xlator_cbks cbks = {
-};
-
-struct volume_options options[] = {
- { .key = {NULL} },
-};
diff --git a/xlators/features/qemu-block/src/Makefile.am b/xlators/features/qemu-block/src/Makefile.am
deleted file mode 100644
index de14a971e2a..00000000000
--- a/xlators/features/qemu-block/src/Makefile.am
+++ /dev/null
@@ -1,155 +0,0 @@
-if ENABLE_QEMU_BLOCK
-xlator_LTLIBRARIES = qemu-block.la
-xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/features
-
-qemu_block_la_LDFLAGS = -module -avoid-version
-qemu_block_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la $(GLIB_LIBS) $(ZLIB_LIBS) -lrt
-
-qemu_block_la_SOURCES_qemu = \
- $(CONTRIBDIR)/qemu/qemu-coroutine.c \
- $(CONTRIBDIR)/qemu/qemu-coroutine-lock.c \
- $(CONTRIBDIR)/qemu/qemu-coroutine-sleep.c \
- $(CONTRIBDIR)/qemu/coroutine-ucontext.c \
- $(CONTRIBDIR)/qemu/block.c \
- $(CONTRIBDIR)/qemu/nop-symbols.c
-
-qemu_block_la_SOURCES_qemu_util = \
- $(CONTRIBDIR)/qemu/util/aes.c \
- $(CONTRIBDIR)/qemu/util/bitmap.c \
- $(CONTRIBDIR)/qemu/util/bitops.c \
- $(CONTRIBDIR)/qemu/util/cutils.c \
- $(CONTRIBDIR)/qemu/util/error.c \
- $(CONTRIBDIR)/qemu/util/hbitmap.c \
- $(CONTRIBDIR)/qemu/util/iov.c \
- $(CONTRIBDIR)/qemu/util/module.c \
- $(CONTRIBDIR)/qemu/util/oslib-posix.c \
- $(CONTRIBDIR)/qemu/util/qemu-option.c \
- $(CONTRIBDIR)/qemu/util/qemu-error.c \
- $(CONTRIBDIR)/qemu/util/qemu-thread-posix.c \
- $(CONTRIBDIR)/qemu/util/unicode.c \
- $(CONTRIBDIR)/qemu/util/hexdump.c
-
-qemu_block_la_SOURCES_qemu_block = \
- $(CONTRIBDIR)/qemu/block/snapshot.c \
- $(CONTRIBDIR)/qemu/block/qcow2-cache.c \
- $(CONTRIBDIR)/qemu/block/qcow2-cluster.c \
- $(CONTRIBDIR)/qemu/block/qcow2-refcount.c \
- $(CONTRIBDIR)/qemu/block/qcow2-snapshot.c \
- $(CONTRIBDIR)/qemu/block/qcow2.c \
- $(CONTRIBDIR)/qemu/block/qed-check.c \
- $(CONTRIBDIR)/qemu/block/qed-cluster.c \
- $(CONTRIBDIR)/qemu/block/qed-gencb.c \
- $(CONTRIBDIR)/qemu/block/qed-l2-cache.c \
- $(CONTRIBDIR)/qemu/block/qed-table.c \
- $(CONTRIBDIR)/qemu/block/qed.c
-
-qemu_block_la_SOURCES_qemu_qobject = \
- $(CONTRIBDIR)/qemu/qobject/json-lexer.c \
- $(CONTRIBDIR)/qemu/qobject/json-parser.c \
- $(CONTRIBDIR)/qemu/qobject/json-streamer.c \
- $(CONTRIBDIR)/qemu/qobject/qbool.c \
- $(CONTRIBDIR)/qemu/qobject/qdict.c \
- $(CONTRIBDIR)/qemu/qobject/qerror.c \
- $(CONTRIBDIR)/qemu/qobject/qfloat.c \
- $(CONTRIBDIR)/qemu/qobject/qint.c \
- $(CONTRIBDIR)/qemu/qobject/qjson.c \
- $(CONTRIBDIR)/qemu/qobject/qlist.c \
- $(CONTRIBDIR)/qemu/qobject/qstring.c
-
-qemu_block_la_SOURCES = \
- $(qemu_block_la_SOURCES_qemu) \
- $(qemu_block_la_SOURCES_qemu_util) \
- $(qemu_block_la_SOURCES_qemu_block) \
- $(qemu_block_la_SOURCES_qemu_qobject) \
- bdrv-xlator.c \
- coroutine-synctask.c \
- bh-syncop.c \
- monitor-logging.c \
- clock-timer.c \
- qemu-block.c \
- qb-coroutines.c
-
-noinst_HEADERS_qemu = \
- $(CONTRIBDIR)/qemu/config-host.h \
- $(CONTRIBDIR)/qemu/qapi-types.h \
- $(CONTRIBDIR)/qemu/qmp-commands.h \
- $(CONTRIBDIR)/qemu/trace/generated-tracers.h \
- $(CONTRIBDIR)/qemu/include/config.h \
- $(CONTRIBDIR)/qemu/include/glib-compat.h \
- $(CONTRIBDIR)/qemu/include/qemu-common.h \
- $(CONTRIBDIR)/qemu/include/trace.h \
- $(CONTRIBDIR)/qemu/include/block/coroutine.h \
- $(CONTRIBDIR)/qemu/include/block/aio.h \
- $(CONTRIBDIR)/qemu/include/block/block.h \
- $(CONTRIBDIR)/qemu/include/block/block_int.h \
- $(CONTRIBDIR)/qemu/include/block/blockjob.h \
- $(CONTRIBDIR)/qemu/include/block/coroutine.h \
- $(CONTRIBDIR)/qemu/include/block/coroutine_int.h \
- $(CONTRIBDIR)/qemu/include/block/snapshot.h \
- $(CONTRIBDIR)/qemu/include/exec/cpu-common.h \
- $(CONTRIBDIR)/qemu/include/exec/hwaddr.h \
- $(CONTRIBDIR)/qemu/include/exec/poison.h \
- $(CONTRIBDIR)/qemu/include/fpu/softfloat.h \
- $(CONTRIBDIR)/qemu/include/migration/migration.h \
- $(CONTRIBDIR)/qemu/include/migration/qemu-file.h \
- $(CONTRIBDIR)/qemu/include/migration/vmstate.h \
- $(CONTRIBDIR)/qemu/include/monitor/monitor.h \
- $(CONTRIBDIR)/qemu/include/monitor/readline.h \
- $(CONTRIBDIR)/qemu/include/qapi/error.h \
- $(CONTRIBDIR)/qemu/include/qapi/qmp/json-lexer.h \
- $(CONTRIBDIR)/qemu/include/qapi/qmp/json-parser.h \
- $(CONTRIBDIR)/qemu/include/qapi/qmp/json-streamer.h \
- $(CONTRIBDIR)/qemu/include/qapi/qmp/qbool.h \
- $(CONTRIBDIR)/qemu/include/qapi/qmp/qdict.h \
- $(CONTRIBDIR)/qemu/include/qapi/qmp/qerror.h \
- $(CONTRIBDIR)/qemu/include/qapi/qmp/qfloat.h \
- $(CONTRIBDIR)/qemu/include/qapi/qmp/qint.h \
- $(CONTRIBDIR)/qemu/include/qapi/qmp/qjson.h \
- $(CONTRIBDIR)/qemu/include/qapi/qmp/qlist.h \
- $(CONTRIBDIR)/qemu/include/qapi/qmp/qobject.h \
- $(CONTRIBDIR)/qemu/include/qapi/qmp/qstring.h \
- $(CONTRIBDIR)/qemu/include/qapi/qmp/types.h \
- $(CONTRIBDIR)/qemu/include/qemu/aes.h \
- $(CONTRIBDIR)/qemu/include/qemu/atomic.h \
- $(CONTRIBDIR)/qemu/include/qemu/bitmap.h \
- $(CONTRIBDIR)/qemu/include/qemu/bitops.h \
- $(CONTRIBDIR)/qemu/include/qemu/bswap.h \
- $(CONTRIBDIR)/qemu/include/qemu/compiler.h \
- $(CONTRIBDIR)/qemu/include/qemu/error-report.h \
- $(CONTRIBDIR)/qemu/include/qemu/event_notifier.h \
- $(CONTRIBDIR)/qemu/include/qemu/hbitmap.h \
- $(CONTRIBDIR)/qemu/include/qemu/host-utils.h \
- $(CONTRIBDIR)/qemu/include/qemu/iov.h \
- $(CONTRIBDIR)/qemu/include/qemu/main-loop.h \
- $(CONTRIBDIR)/qemu/include/qemu/module.h \
- $(CONTRIBDIR)/qemu/include/qemu/notify.h \
- $(CONTRIBDIR)/qemu/include/qemu/option.h \
- $(CONTRIBDIR)/qemu/include/qemu/option_int.h \
- $(CONTRIBDIR)/qemu/include/qemu/osdep.h \
- $(CONTRIBDIR)/qemu/include/qemu/queue.h \
- $(CONTRIBDIR)/qemu/include/qemu/sockets.h \
- $(CONTRIBDIR)/qemu/include/qemu/thread-posix.h \
- $(CONTRIBDIR)/qemu/include/qemu/thread.h \
- $(CONTRIBDIR)/qemu/include/qemu/timer.h \
- $(CONTRIBDIR)/qemu/include/qemu/typedefs.h \
- $(CONTRIBDIR)/qemu/include/sysemu/sysemu.h \
- $(CONTRIBDIR)/qemu/include/sysemu/os-posix.h \
- $(CONTRIBDIR)/qemu/block/qcow2.h \
- $(CONTRIBDIR)/qemu/block/qed.h
-
-noinst_HEADERS = \
- $(noinst_HEADERS_qemu) \
- qemu-block.h \
- qemu-block-memory-types.h \
- qb-coroutines.h
-
-AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \
- -I$(CONTRIBDIR)/qemu \
- -I$(CONTRIBDIR)/qemu/include \
- -DGLUSTER_XLATOR
-
-AM_CFLAGS = -fno-strict-aliasing -Wall $(GF_CFLAGS) $(GLIB_CFLAGS)
-
-CLEANFILES =
-
-endif
diff --git a/xlators/features/qemu-block/src/bdrv-xlator.c b/xlators/features/qemu-block/src/bdrv-xlator.c
deleted file mode 100644
index 1e55b5fb70b..00000000000
--- a/xlators/features/qemu-block/src/bdrv-xlator.c
+++ /dev/null
@@ -1,389 +0,0 @@
-/*
- Copyright (c) 2013 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 "inode.h"
-#include "syncop.h"
-#include "qemu-block.h"
-#include "block/block_int.h"
-
-typedef struct BDRVGlusterState {
- inode_t *inode;
-} BDRVGlusterState;
-
-static QemuOptsList runtime_opts = {
- .name = "gluster",
- .head = QTAILQ_HEAD_INITIALIZER(runtime_opts.head),
- .desc = {
- {
- .name = "filename",
- .type = QEMU_OPT_STRING,
- .help = "GFID of file",
- },
- { /* end of list */ }
- },
-};
-
-inode_t *
-qb_inode_from_filename (const char *filename)
-{
- const char *iptr = NULL;
- inode_t *inode = NULL;
-
- iptr = filename + 17;
- sscanf (iptr, "%p", &inode);
-
- return inode;
-}
-
-
-int
-qb_inode_to_filename (inode_t *inode, char *filename, int size)
-{
- return snprintf (filename, size, "gluster://inodep:%p", inode);
-}
-
-
-static fd_t *
-fd_from_bs (BlockDriverState *bs)
-{
- BDRVGlusterState *s = bs->opaque;
-
- return fd_anonymous (s->inode);
-}
-
-
-static int
-qemu_gluster_open (BlockDriverState *bs, QDict *options, int bdrv_flags)
-{
- inode_t *inode = NULL;
- BDRVGlusterState *s = bs->opaque;
- QemuOpts *opts = NULL;
- Error *local_err = NULL;
- const char *filename = NULL;
- char gfid_str[128];
- int ret;
- qb_conf_t *conf = THIS->private;
-
- opts = qemu_opts_create_nofail(&runtime_opts);
- qemu_opts_absorb_qdict(opts, options, &local_err);
- if (error_is_set(&local_err)) {
- qerror_report_err(local_err);
- error_free(local_err);
- return -EINVAL;
- }
-
- filename = qemu_opt_get(opts, "filename");
-
- /*
- * gfid:<gfid> format means we're opening a backing image.
- */
- ret = sscanf(filename, "gluster://gfid:%s", gfid_str);
- if (ret) {
- loc_t loc = {0,};
- struct iatt buf = {0,};
- uuid_t gfid;
-
- uuid_parse(gfid_str, gfid);
-
- loc.inode = inode_find(conf->root_inode->table, gfid);
- if (!loc.inode) {
- loc.inode = inode_new(conf->root_inode->table);
- uuid_copy(loc.inode->gfid, gfid);
- }
-
- uuid_copy(loc.gfid, loc.inode->gfid);
- ret = syncop_lookup(FIRST_CHILD(THIS), &loc, NULL, &buf, NULL,
- NULL);
- if (ret) {
- loc_wipe(&loc);
- return ret;
- }
-
- s->inode = inode_ref(loc.inode);
- loc_wipe(&loc);
- } else {
- inode = qb_inode_from_filename (filename);
- if (!inode)
- return -EINVAL;
-
- s->inode = inode_ref(inode);
- }
-
- return 0;
-}
-
-
-static int
-qemu_gluster_create (const char *filename, QEMUOptionParameter *options)
-{
- uint64_t total_size = 0;
- inode_t *inode = NULL;
- fd_t *fd = NULL;
- struct iatt stat = {0, };
- int ret = 0;
-
- inode = qb_inode_from_filename (filename);
- if (!inode)
- return -EINVAL;
-
- while (options && options->name) {
- if (!strcmp(options->name, BLOCK_OPT_SIZE)) {
- total_size = options->value.n / BDRV_SECTOR_SIZE;
- }
- options++;
- }
-
- fd = fd_anonymous (inode);
- if (!fd)
- return -ENOMEM;
-
- ret = syncop_fstat (FIRST_CHILD(THIS), fd, &stat);
- if (ret) {
- fd_unref (fd);
- return ret;
- }
-
- if (stat.ia_size) {
- /* format ONLY if the filesize is 0 bytes */
- fd_unref (fd);
- return -EFBIG;
- }
-
- if (total_size) {
- ret = syncop_ftruncate (FIRST_CHILD(THIS), fd, total_size);
- if (ret) {
- fd_unref (fd);
- return ret;
- }
- }
-
- fd_unref (fd);
- return 0;
-}
-
-
-static int
-qemu_gluster_co_readv (BlockDriverState *bs, int64_t sector_num, int nb_sectors,
- QEMUIOVector *qiov)
-{
- fd_t *fd = NULL;
- off_t offset = 0;
- size_t size = 0;
- struct iovec *iov = NULL;
- int count = 0;
- struct iobref *iobref = NULL;
- int ret = 0;
-
- fd = fd_from_bs (bs);
- if (!fd)
- return -EIO;
-
- offset = sector_num * BDRV_SECTOR_SIZE;
- size = nb_sectors * BDRV_SECTOR_SIZE;
-
- ret = syncop_readv (FIRST_CHILD(THIS), fd, size, offset, 0,
- &iov, &count, &iobref);
- if (ret < 0)
- goto out;
-
- iov_copy (qiov->iov, qiov->niov, iov, count); /* *choke!* */
-
-out:
- GF_FREE (iov);
- if (iobref)
- iobref_unref (iobref);
- fd_unref (fd);
- return ret;
-}
-
-
-static int
-qemu_gluster_co_writev (BlockDriverState *bs, int64_t sector_num, int nb_sectors,
- QEMUIOVector *qiov)
-{
- fd_t *fd = NULL;
- off_t offset = 0;
- size_t size = 0;
- struct iobref *iobref = NULL;
- struct iobuf *iobuf = NULL;
- struct iovec iov = {0, };
- int ret = -ENOMEM;
-
- fd = fd_from_bs (bs);
- if (!fd)
- return -EIO;
-
- offset = sector_num * BDRV_SECTOR_SIZE;
- size = nb_sectors * BDRV_SECTOR_SIZE;
-
- iobuf = iobuf_get2 (THIS->ctx->iobuf_pool, size);
- if (!iobuf)
- goto out;
-
- iobref = iobref_new ();
- if (!iobref) {
- goto out;
- }
-
- iobref_add (iobref, iobuf);
-
- iov_unload (iobuf_ptr (iobuf), qiov->iov, qiov->niov); /* *choke!* */
-
- iov.iov_base = iobuf_ptr (iobuf);
- iov.iov_len = size;
-
- ret = syncop_writev (FIRST_CHILD(THIS), fd, &iov, 1, offset, iobref, 0);
-
-out:
- if (iobuf)
- iobuf_unref (iobuf);
- if (iobref)
- iobref_unref (iobref);
- fd_unref (fd);
- return ret;
-}
-
-
-static int
-qemu_gluster_co_flush (BlockDriverState *bs)
-{
- fd_t *fd = NULL;
- int ret = 0;
-
- fd = fd_from_bs (bs);
-
- ret = syncop_flush (FIRST_CHILD(THIS), fd);
-
- fd_unref (fd);
-
- return ret;
-}
-
-
-static int
-qemu_gluster_co_fsync (BlockDriverState *bs)
-{
- fd_t *fd = NULL;
- int ret = 0;
-
- fd = fd_from_bs (bs);
-
- ret = syncop_fsync (FIRST_CHILD(THIS), fd, 0);
-
- fd_unref (fd);
-
- return ret;
-}
-
-
-static int
-qemu_gluster_truncate (BlockDriverState *bs, int64_t offset)
-{
- fd_t *fd = NULL;
- int ret = 0;
-
- fd = fd_from_bs (bs);
-
- ret = syncop_ftruncate (FIRST_CHILD(THIS), fd, offset);
-
- fd_unref (fd);
-
- return ret;
-}
-
-
-static int64_t
-qemu_gluster_getlength (BlockDriverState *bs)
-{
- fd_t *fd = NULL;
- int ret = 0;
- struct iatt iatt = {0, };
-
- fd = fd_from_bs (bs);
-
- ret = syncop_fstat (FIRST_CHILD(THIS), fd, &iatt);
- if (ret < 0)
- return -1;
-
- return iatt.ia_size;
-}
-
-
-static int64_t
-qemu_gluster_allocated_file_size (BlockDriverState *bs)
-{
- fd_t *fd = NULL;
- int ret = 0;
- struct iatt iatt = {0, };
-
- fd = fd_from_bs (bs);
-
- ret = syncop_fstat (FIRST_CHILD(THIS), fd, &iatt);
- if (ret < 0)
- return -1;
-
- return iatt.ia_blocks * 512;
-}
-
-
-static void
-qemu_gluster_close (BlockDriverState *bs)
-{
- BDRVGlusterState *s = NULL;
-
- s = bs->opaque;
-
- inode_unref (s->inode);
-
- return;
-}
-
-
-static QEMUOptionParameter qemu_gluster_create_options[] = {
- {
- .name = BLOCK_OPT_SIZE,
- .type = OPT_SIZE,
- .help = "Virtual disk size"
- },
- { NULL }
-};
-
-
-static BlockDriver bdrv_gluster = {
- .format_name = "gluster",
- .protocol_name = "gluster",
- .instance_size = sizeof(BDRVGlusterState),
- .bdrv_file_open = qemu_gluster_open,
- .bdrv_close = qemu_gluster_close,
- .bdrv_create = qemu_gluster_create,
- .bdrv_getlength = qemu_gluster_getlength,
- .bdrv_get_allocated_file_size = qemu_gluster_allocated_file_size,
- .bdrv_co_readv = qemu_gluster_co_readv,
- .bdrv_co_writev = qemu_gluster_co_writev,
- .bdrv_co_flush_to_os = qemu_gluster_co_flush,
- .bdrv_co_flush_to_disk = qemu_gluster_co_fsync,
- .bdrv_truncate = qemu_gluster_truncate,
- .create_options = qemu_gluster_create_options,
-};
-
-
-static void bdrv_gluster_init(void)
-{
- bdrv_register(&bdrv_gluster);
-}
-
-
-block_init(bdrv_gluster_init);
diff --git a/xlators/features/qemu-block/src/bh-syncop.c b/xlators/features/qemu-block/src/bh-syncop.c
deleted file mode 100644
index e8686f6d4ba..00000000000
--- a/xlators/features/qemu-block/src/bh-syncop.c
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- Copyright (c) 2013 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 "syncop.h"
-#include "qemu-block-memory-types.h"
-
-#include "block/aio.h"
-
-void
-qemu_bh_schedule (QEMUBH *bh)
-{
- return;
-}
-
-void
-qemu_bh_cancel (QEMUBH *bh)
-{
- return;
-}
-
-void
-qemu_bh_delete (QEMUBH *bh)
-{
-
-}
-
-QEMUBH *
-qemu_bh_new (QEMUBHFunc *cb, void *opaque)
-{
- return NULL;
-}
diff --git a/xlators/features/qemu-block/src/clock-timer.c b/xlators/features/qemu-block/src/clock-timer.c
deleted file mode 100644
index fcbec6ad1cd..00000000000
--- a/xlators/features/qemu-block/src/clock-timer.c
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- Copyright (c) 2013 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 "syncop.h"
-#include "qemu-block-memory-types.h"
-
-#include "qemu/timer.h"
-
-QEMUClock *vm_clock;
-int use_rt_clock = 0;
-
-QEMUTimer *qemu_new_timer (QEMUClock *clock, int scale,
- QEMUTimerCB *cb, void *opaque)
-{
- return NULL;
-}
-
-int64_t qemu_get_clock_ns (QEMUClock *clock)
-{
- return 0;
-}
-
-void qemu_mod_timer (QEMUTimer *ts, int64_t expire_time)
-{
- return;
-}
-
-void qemu_free_timer (QEMUTimer *ts)
-{
-
-}
-
-void qemu_del_timer (QEMUTimer *ts)
-{
-
-}
-
-bool qemu_aio_wait()
-{
- synctask_wake (synctask_get());
- synctask_yield (synctask_get());
- return 0;
-}
diff --git a/xlators/features/qemu-block/src/coroutine-synctask.c b/xlators/features/qemu-block/src/coroutine-synctask.c
deleted file mode 100644
index e43988a953f..00000000000
--- a/xlators/features/qemu-block/src/coroutine-synctask.c
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- Copyright (c) 2013 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 "syncop.h"
-#include "qemu-block-memory-types.h"
-
-#include "qemu-block.h"
-
-/*
- * This code serves as the bridge from the main glusterfs context to the qemu
- * coroutine context via synctask. We create a single threaded syncenv with a
- * single synctask responsible for processing a queue of coroutines. The qemu
- * code invoked from within the synctask function handlers uses the ucontext
- * coroutine implementation and scheduling logic internal to qemu. This
- * effectively donates a thread of execution to qemu and its internal coroutine
- * management.
- *
- * NOTE: The existence of concurrent synctasks has proven quite racy with regard
- * to qemu coroutine management, particularly related to the lifecycle
- * differences with top-level synctasks and internally created coroutines and
- * interactions with qemu-internal queues (and locks, in turn). We explicitly
- * disallow this scenario, via the queue, until it is more well supported.
- */
-
-static struct {
- struct list_head queue;
- gf_lock_t lock;
- struct synctask *task;
-} qb_co;
-
-static void
-init_qbco()
-{
- INIT_LIST_HEAD(&qb_co.queue);
- LOCK_INIT(&qb_co.lock);
-}
-
-static int
-synctask_nop_cbk (int ret, call_frame_t *frame, void *opaque)
-{
- return 0;
-}
-
-static int
-qb_synctask_wrap (void *opaque)
-{
- qb_local_t *qb_local, *tmp;
-
- LOCK(&qb_co.lock);
-
- while (!list_empty(&qb_co.queue)) {
- list_for_each_entry_safe(qb_local, tmp, &qb_co.queue, list) {
- list_del_init(&qb_local->list);
- break;
- }
-
- UNLOCK(&qb_co.lock);
-
- qb_local->synctask_fn(qb_local);
- /* qb_local is now unwound and gone! */
-
- LOCK(&qb_co.lock);
- }
-
- qb_co.task = NULL;
-
- UNLOCK(&qb_co.lock);
-
- return 0;
-}
-
-int
-qb_coroutine (call_frame_t *frame, synctask_fn_t fn)
-{
- qb_local_t *qb_local = NULL;
- qb_conf_t *qb_conf = NULL;
- static int init = 0;
-
- qb_local = frame->local;
- qb_local->synctask_fn = fn;
- qb_conf = frame->this->private;
-
- if (!init) {
- init = 1;
- init_qbco();
- }
-
- LOCK(&qb_co.lock);
-
- if (!qb_co.task)
- qb_co.task = synctask_create(qb_conf->env, qb_synctask_wrap,
- synctask_nop_cbk, frame, NULL);
-
- list_add_tail(&qb_local->list, &qb_co.queue);
-
- UNLOCK(&qb_co.lock);
-
- return 0;
-}
diff --git a/xlators/features/qemu-block/src/monitor-logging.c b/xlators/features/qemu-block/src/monitor-logging.c
deleted file mode 100644
index d37c37f0f29..00000000000
--- a/xlators/features/qemu-block/src/monitor-logging.c
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- Copyright (c) 2013 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 "qemu-block-memory-types.h"
-
-#include "block/block_int.h"
-
-Monitor *cur_mon;
-
-int
-monitor_cur_is_qmp()
-{
- /* No QMP support here */
- return 0;
-}
-
-void
-monitor_set_error (Monitor *mon, QError *qerror)
-{
- /* NOP here */
- return;
-}
-
-
-void
-monitor_vprintf(Monitor *mon, const char *fmt, va_list ap)
-{
- char buf[4096];
-
- vsnprintf(buf, sizeof(buf), fmt, ap);
-
- gf_log (THIS->name, GF_LOG_ERROR, "%s", buf);
-}
diff --git a/xlators/features/qemu-block/src/qb-coroutines.c b/xlators/features/qemu-block/src/qb-coroutines.c
deleted file mode 100644
index 974312f1268..00000000000
--- a/xlators/features/qemu-block/src/qb-coroutines.c
+++ /dev/null
@@ -1,667 +0,0 @@
-/*
- Copyright (c) 2013 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 "inode.h"
-#include "call-stub.h"
-#include "defaults.h"
-#include "qemu-block-memory-types.h"
-#include "qemu-block.h"
-#include "qb-coroutines.h"
-
-
-int
-qb_format_and_resume (void *opaque)
-{
- qb_local_t *local = NULL;
- call_frame_t *frame = NULL;
- call_stub_t *stub = NULL;
- inode_t *inode = NULL;
- char filename[64];
- char base_filename[128];
- int use_base = 0;
- qb_inode_t *qb_inode = NULL;
- Error *local_err = NULL;
- fd_t *fd = NULL;
- dict_t *xattr = NULL;
- qb_conf_t *qb_conf = NULL;
- int ret = -1;
-
- local = opaque;
- frame = local->frame;
- stub = local->stub;
- inode = local->inode;
- qb_conf = frame->this->private;
-
- qb_inode_to_filename (inode, filename, 64);
-
- qb_inode = qb_inode_ctx_get (frame->this, inode);
-
- /*
- * See if the caller specified a backing image.
- */
- if (!uuid_is_null(qb_inode->backing_gfid) || qb_inode->backing_fname) {
- loc_t loc = {0,};
- char gfid_str[64];
- struct iatt buf;
-
- if (!uuid_is_null(qb_inode->backing_gfid)) {
- loc.inode = inode_find(qb_conf->root_inode->table,
- qb_inode->backing_gfid);
- if (!loc.inode) {
- loc.inode = inode_new(qb_conf->root_inode->table);
- uuid_copy(loc.inode->gfid,
- qb_inode->backing_gfid);
- }
- uuid_copy(loc.gfid, loc.inode->gfid);
- } else if (qb_inode->backing_fname) {
- loc.inode = inode_new(qb_conf->root_inode->table);
- loc.name = qb_inode->backing_fname;
- loc.parent = inode_parent(inode, NULL, NULL);
- loc_path(&loc, loc.name);
- }
-
- /*
- * Lookup the backing image. Verify existence and/or get the
- * gfid if we don't already have it.
- */
- ret = syncop_lookup(FIRST_CHILD(frame->this), &loc, NULL, &buf,
- NULL, NULL);
- GF_FREE(qb_inode->backing_fname);
- if (ret) {
- loc_wipe(&loc);
- ret = -ret;
- goto err;
- }
-
- uuid_copy(qb_inode->backing_gfid, buf.ia_gfid);
- loc_wipe(&loc);
-
- /*
- * We pass the filename of the backing image into the qemu block
- * subsystem as the associated gfid. This is embedded into the
- * clone image and passed along to the gluster bdrv backend when
- * the block subsystem needs to operate on the backing image on
- * behalf of the clone.
- */
- uuid_unparse(qb_inode->backing_gfid, gfid_str);
- snprintf(base_filename, sizeof(base_filename),
- "gluster://gfid:%s", gfid_str);
- use_base = 1;
- }
-
- bdrv_img_create (filename, qb_inode->fmt,
- use_base ? base_filename : NULL, 0, 0, qb_inode->size,
- 0, &local_err, true);
-
- if (error_is_set (&local_err)) {
- gf_log (frame->this->name, GF_LOG_ERROR, "%s",
- error_get_pretty (local_err));
- error_free (local_err);
- QB_STUB_UNWIND (stub, -1, EIO);
- return 0;
- }
-
- fd = fd_anonymous (inode);
- if (!fd) {
- gf_log (frame->this->name, GF_LOG_ERROR,
- "could not create anonymous fd for %s",
- uuid_utoa (inode->gfid));
- QB_STUB_UNWIND (stub, -1, ENOMEM);
- return 0;
- }
-
- xattr = dict_new ();
- if (!xattr) {
- gf_log (frame->this->name, GF_LOG_ERROR,
- "could not allocate xattr dict for %s",
- uuid_utoa (inode->gfid));
- QB_STUB_UNWIND (stub, -1, ENOMEM);
- fd_unref (fd);
- return 0;
- }
-
- ret = dict_set_str (xattr, qb_conf->qb_xattr_key, local->fmt);
- if (ret) {
- gf_log (frame->this->name, GF_LOG_ERROR,
- "could not dict_set for %s",
- uuid_utoa (inode->gfid));
- QB_STUB_UNWIND (stub, -1, ENOMEM);
- fd_unref (fd);
- dict_unref (xattr);
- return 0;
- }
-
- ret = syncop_fsetxattr (FIRST_CHILD(THIS), fd, xattr, 0);
- if (ret) {
- gf_log (frame->this->name, GF_LOG_ERROR,
- "failed to setxattr for %s",
- uuid_utoa (inode->gfid));
- QB_STUB_UNWIND (stub, -1, -ret);
- fd_unref (fd);
- dict_unref (xattr);
- return 0;
- }
-
- fd_unref (fd);
- dict_unref (xattr);
-
- QB_STUB_UNWIND (stub, 0, 0);
-
- return 0;
-
-err:
- QB_STUB_UNWIND(stub, -1, ret);
- return 0;
-}
-
-
-static BlockDriverState *
-qb_bs_create (inode_t *inode, const char *fmt)
-{
- char filename[64];
- BlockDriverState *bs = NULL;
- BlockDriver *drv = NULL;
- int op_errno = 0;
- int ret = 0;
-
- bs = bdrv_new (uuid_utoa (inode->gfid));
- if (!bs) {
- op_errno = ENOMEM;
- gf_log (THIS->name, GF_LOG_ERROR,
- "could not allocate @bdrv for gfid:%s",
- uuid_utoa (inode->gfid));
- goto err;
- }
-
- drv = bdrv_find_format (fmt);
- if (!drv) {
- op_errno = EINVAL;
- gf_log (THIS->name, GF_LOG_ERROR,
- "Unknown file format: %s for gfid:%s",
- fmt, uuid_utoa (inode->gfid));
- goto err;
- }
-
- qb_inode_to_filename (inode, filename, 64);
-
- ret = bdrv_open (bs, filename, NULL, BDRV_O_RDWR, drv);
- if (ret < 0) {
- op_errno = -ret;
- gf_log (THIS->name, GF_LOG_ERROR,
- "Unable to bdrv_open() gfid:%s (%s)",
- uuid_utoa (inode->gfid), strerror (op_errno));
- goto err;
- }
-
- return bs;
-err:
- errno = op_errno;
- return NULL;
-}
-
-
-int
-qb_co_open (void *opaque)
-{
- qb_local_t *local = NULL;
- call_frame_t *frame = NULL;
- call_stub_t *stub = NULL;
- inode_t *inode = NULL;
- qb_inode_t *qb_inode = NULL;
-
- local = opaque;
- frame = local->frame;
- stub = local->stub;
- inode = local->inode;
-
- qb_inode = qb_inode_ctx_get (frame->this, inode);
- if (!qb_inode->bs) {
- /* FIXME: we need locks around this when
- enabling multithreaded syncop/coroutine
- for qemu-block
- */
-
- qb_inode->bs = qb_bs_create (inode, qb_inode->fmt);
- if (!qb_inode->bs) {
- QB_STUB_UNWIND (stub, -1, errno);
- return 0;
- }
- }
- qb_inode->refcnt++;
-
- QB_STUB_RESUME (stub);
-
- return 0;
-}
-
-
-int
-qb_co_writev (void *opaque)
-{
- qb_local_t *local = NULL;
- call_frame_t *frame = NULL;
- call_stub_t *stub = NULL;
- inode_t *inode = NULL;
- qb_inode_t *qb_inode = NULL;
- QEMUIOVector qiov = {0, };
- int ret = 0;
-
- local = opaque;
- frame = local->frame;
- stub = local->stub;
- inode = local->inode;
-
- qb_inode = qb_inode_ctx_get (frame->this, inode);
- if (!qb_inode->bs) {
- /* FIXME: we need locks around this when
- enabling multithreaded syncop/coroutine
- for qemu-block
- */
-
- qb_inode->bs = qb_bs_create (inode, qb_inode->fmt);
- if (!qb_inode->bs) {
- QB_STUB_UNWIND (stub, -1, errno);
- return 0;
- }
- }
-
- qemu_iovec_init_external (&qiov, stub->args.vector, stub->args.count);
-
- ret = bdrv_pwritev (qb_inode->bs, stub->args.offset, &qiov);
-
- if (ret < 0) {
- QB_STUB_UNWIND (stub, -1, -ret);
- } else {
- QB_STUB_UNWIND (stub, ret, 0);
- }
-
- return 0;
-}
-
-
-int
-qb_co_readv (void *opaque)
-{
- qb_local_t *local = NULL;
- call_frame_t *frame = NULL;
- call_stub_t *stub = NULL;
- inode_t *inode = NULL;
- qb_inode_t *qb_inode = NULL;
- struct iobuf *iobuf = NULL;
- struct iobref *iobref = NULL;
- struct iovec iov = {0, };
- int ret = 0;
-
- local = opaque;
- frame = local->frame;
- stub = local->stub;
- inode = local->inode;
-
- qb_inode = qb_inode_ctx_get (frame->this, inode);
- if (!qb_inode->bs) {
- /* FIXME: we need locks around this when
- enabling multithreaded syncop/coroutine
- for qemu-block
- */
-
- qb_inode->bs = qb_bs_create (inode, qb_inode->fmt);
- if (!qb_inode->bs) {
- QB_STUB_UNWIND (stub, -1, errno);
- return 0;
- }
- }
-
- if (stub->args.offset >= qb_inode->size) {
- QB_STUB_UNWIND (stub, 0, 0);
- return 0;
- }
-
- iobuf = iobuf_get2 (frame->this->ctx->iobuf_pool, stub->args.size);
- if (!iobuf) {
- QB_STUB_UNWIND (stub, -1, ENOMEM);
- return 0;
- }
-
- iobref = iobref_new ();
- if (!iobref) {
- QB_STUB_UNWIND (stub, -1, ENOMEM);
- iobuf_unref (iobuf);
- return 0;
- }
-
- if (iobref_add (iobref, iobuf) < 0) {
- iobuf_unref (iobuf);
- iobref_unref (iobref);
- QB_STUB_UNWIND (stub, -1, ENOMEM);
- return 0;
- }
-
- ret = bdrv_pread (qb_inode->bs, stub->args.offset, iobuf_ptr (iobuf),
- stub->args.size);
-
- if (ret < 0) {
- QB_STUB_UNWIND (stub, -1, -ret);
- iobref_unref (iobref);
- return 0;
- }
-
- iov.iov_base = iobuf_ptr (iobuf);
- iov.iov_len = ret;
-
- stub->args_cbk.vector = iov_dup (&iov, 1);
- stub->args_cbk.count = 1;
- stub->args_cbk.iobref = iobref;
-
- QB_STUB_UNWIND (stub, ret, 0);
-
- return 0;
-}
-
-
-int
-qb_co_fsync (void *opaque)
-{
- qb_local_t *local = NULL;
- call_frame_t *frame = NULL;
- call_stub_t *stub = NULL;
- inode_t *inode = NULL;
- qb_inode_t *qb_inode = NULL;
- int ret = 0;
-
- local = opaque;
- frame = local->frame;
- stub = local->stub;
- inode = local->inode;
-
- qb_inode = qb_inode_ctx_get (frame->this, inode);
- if (!qb_inode->bs) {
- /* FIXME: we need locks around this when
- enabling multithreaded syncop/coroutine
- for qemu-block
- */
-
- qb_inode->bs = qb_bs_create (inode, qb_inode->fmt);
- if (!qb_inode->bs) {
- QB_STUB_UNWIND (stub, -1, errno);
- return 0;
- }
- }
-
- ret = bdrv_flush (qb_inode->bs);
-
- if (ret < 0) {
- QB_STUB_UNWIND (stub, -1, -ret);
- } else {
- QB_STUB_UNWIND (stub, ret, 0);
- }
-
- return 0;
-}
-
-
-static void
-qb_update_size_xattr (xlator_t *this, fd_t *fd, const char *fmt, off_t offset)
-{
- char val[QB_XATTR_VAL_MAX];
- qb_conf_t *qb_conf = NULL;
- dict_t *xattr = NULL;
-
- qb_conf = this->private;
-
- snprintf (val, QB_XATTR_VAL_MAX, "%s:%llu",
- fmt, (long long unsigned) offset);
-
- xattr = dict_new ();
- if (!xattr)
- return;
-
- if (dict_set_str (xattr, qb_conf->qb_xattr_key, val) != 0) {
- dict_unref (xattr);
- return;
- }
-
- syncop_fsetxattr (FIRST_CHILD(this), fd, xattr, 0);
- dict_unref (xattr);
-}
-
-
-int
-qb_co_truncate (void *opaque)
-{
- qb_local_t *local = NULL;
- call_frame_t *frame = NULL;
- call_stub_t *stub = NULL;
- inode_t *inode = NULL;
- qb_inode_t *qb_inode = NULL;
- int ret = 0;
- off_t offset = 0;
- xlator_t *this = NULL;
-
- this = THIS;
-
- local = opaque;
- frame = local->frame;
- stub = local->stub;
- inode = local->inode;
-
- qb_inode = qb_inode_ctx_get (frame->this, inode);
- if (!qb_inode->bs) {
- /* FIXME: we need locks around this when
- enabling multithreaded syncop/coroutine
- for qemu-block
- */
-
- qb_inode->bs = qb_bs_create (inode, qb_inode->fmt);
- if (!qb_inode->bs) {
- QB_STUB_UNWIND (stub, -1, errno);
- return 0;
- }
- }
-
- ret = syncop_fstat (FIRST_CHILD(this), local->fd,
- &stub->args_cbk.prestat);
- if (ret < 0)
- goto out;
- stub->args_cbk.prestat.ia_size = qb_inode->size;
-
- ret = bdrv_truncate (qb_inode->bs, stub->args.offset);
- if (ret < 0)
- goto out;
-
- offset = bdrv_getlength (qb_inode->bs);
-
- qb_inode->size = offset;
-
- ret = syncop_fstat (FIRST_CHILD(this), local->fd,
- &stub->args_cbk.poststat);
- if (ret < 0)
- goto out;
- stub->args_cbk.poststat.ia_size = qb_inode->size;
-
- qb_update_size_xattr (this, local->fd, qb_inode->fmt, qb_inode->size);
-
-out:
- if (ret < 0) {
- QB_STUB_UNWIND (stub, -1, -ret);
- } else {
- QB_STUB_UNWIND (stub, ret, 0);
- }
-
- return 0;
-}
-
-
-int
-qb_co_close (void *opaque)
-{
- qb_local_t *local = NULL;
- call_frame_t *frame = NULL;
- inode_t *inode = NULL;
- qb_inode_t *qb_inode = NULL;
- BlockDriverState *bs = NULL;
-
- local = opaque;
- inode = local->inode;
-
- qb_inode = qb_inode_ctx_get (THIS, inode);
-
- if (!--qb_inode->refcnt) {
- bs = qb_inode->bs;
- qb_inode->bs = NULL;
- bdrv_delete (bs);
- }
-
- frame = local->frame;
- frame->local = NULL;
- qb_local_free (THIS, local);
- STACK_DESTROY (frame->root);
-
- return 0;
-}
-
-
-int
-qb_snapshot_create (void *opaque)
-{
- qb_local_t *local = NULL;
- call_frame_t *frame = NULL;
- call_stub_t *stub = NULL;
- inode_t *inode = NULL;
- qb_inode_t *qb_inode = NULL;
- QEMUSnapshotInfo sn;
- struct timeval tv = {0, };
- int ret = 0;
-
- local = opaque;
- frame = local->frame;
- stub = local->stub;
- inode = local->inode;
-
- qb_inode = qb_inode_ctx_get (frame->this, inode);
- if (!qb_inode->bs) {
- /* FIXME: we need locks around this when
- enabling multithreaded syncop/coroutine
- for qemu-block
- */
-
- qb_inode->bs = qb_bs_create (inode, qb_inode->fmt);
- if (!qb_inode->bs) {
- QB_STUB_UNWIND (stub, -1, errno);
- return 0;
- }
- }
-
- memset (&sn, 0, sizeof (sn));
- pstrcpy (sn.name, sizeof(sn.name), local->name);
- gettimeofday (&tv, NULL);
- sn.date_sec = tv.tv_sec;
- sn.date_nsec = tv.tv_usec * 1000;
-
- ret = bdrv_snapshot_create (qb_inode->bs, &sn);
- if (ret < 0) {
- QB_STUB_UNWIND (stub, -1, -ret);
- } else {
- QB_STUB_UNWIND (stub, ret, 0);
- }
-
- return 0;
-}
-
-
-int
-qb_snapshot_delete (void *opaque)
-{
- qb_local_t *local = NULL;
- call_frame_t *frame = NULL;
- call_stub_t *stub = NULL;
- inode_t *inode = NULL;
- qb_inode_t *qb_inode = NULL;
- int ret = 0;
-
- local = opaque;
- frame = local->frame;
- stub = local->stub;
- inode = local->inode;
-
- qb_inode = qb_inode_ctx_get (frame->this, inode);
- if (!qb_inode->bs) {
- /* FIXME: we need locks around this when
- enabling multithreaded syncop/coroutine
- for qemu-block
- */
-
- qb_inode->bs = qb_bs_create (inode, qb_inode->fmt);
- if (!qb_inode->bs) {
- QB_STUB_UNWIND (stub, -1, errno);
- return 0;
- }
- }
-
- ret = bdrv_snapshot_delete (qb_inode->bs, local->name);
-
- if (ret < 0) {
- QB_STUB_UNWIND (stub, -1, -ret);
- } else {
- QB_STUB_UNWIND (stub, ret, 0);
- }
-
- return 0;
-}
-
-
-int
-qb_snapshot_goto (void *opaque)
-{
- qb_local_t *local = NULL;
- call_frame_t *frame = NULL;
- call_stub_t *stub = NULL;
- inode_t *inode = NULL;
- qb_inode_t *qb_inode = NULL;
- int ret = 0;
-
- local = opaque;
- frame = local->frame;
- stub = local->stub;
- inode = local->inode;
-
- qb_inode = qb_inode_ctx_get (frame->this, inode);
- if (!qb_inode->bs) {
- /* FIXME: we need locks around this when
- enabling multithreaded syncop/coroutine
- for qemu-block
- */
-
- qb_inode->bs = qb_bs_create (inode, qb_inode->fmt);
- if (!qb_inode->bs) {
- QB_STUB_UNWIND (stub, -1, errno);
- return 0;
- }
- }
-
- ret = bdrv_snapshot_goto (qb_inode->bs, local->name);
-
- if (ret < 0) {
- QB_STUB_UNWIND (stub, -1, -ret);
- } else {
- QB_STUB_UNWIND (stub, ret, 0);
- }
-
- return 0;
-}
diff --git a/xlators/features/qemu-block/src/qb-coroutines.h b/xlators/features/qemu-block/src/qb-coroutines.h
deleted file mode 100644
index 583319f3b06..00000000000
--- a/xlators/features/qemu-block/src/qb-coroutines.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- Copyright (c) 2013 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 __QB_COROUTINES_H
-#define __QB_COROUTINES_H
-
-#include "syncop.h"
-#include "call-stub.h"
-#include "block/block_int.h"
-#include "monitor/monitor.h"
-
-int qb_format_and_resume (void *opaque);
-int qb_snapshot_create (void *opaque);
-int qb_snapshot_delete (void *opaque);
-int qb_snapshot_goto (void *opaque);
-int qb_co_open (void *opaque);
-int qb_co_close (void *opaque);
-int qb_co_writev (void *opaque);
-int qb_co_readv (void *opaque);
-int qb_co_fsync (void *opaque);
-int qb_co_truncate (void *opaque);
-
-#endif /* __QB_COROUTINES_H */
diff --git a/xlators/features/qemu-block/src/qemu-block-memory-types.h b/xlators/features/qemu-block/src/qemu-block-memory-types.h
deleted file mode 100644
index 267b3893fed..00000000000
--- a/xlators/features/qemu-block/src/qemu-block-memory-types.h
+++ /dev/null
@@ -1,25 +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 __QB_MEM_TYPES_H__
-#define __QB_MEM_TYPES_H__
-
-#include "mem-types.h"
-
-enum gf_qb_mem_types_ {
- gf_qb_mt_qb_conf_t = gf_common_mt_end + 1,
- gf_qb_mt_qb_inode_t,
- gf_qb_mt_qb_local_t,
- gf_qb_mt_coroutinesynctask_t,
- gf_qb_mt_end
-};
-#endif
-
diff --git a/xlators/features/qemu-block/src/qemu-block.c b/xlators/features/qemu-block/src/qemu-block.c
deleted file mode 100644
index 768866f6429..00000000000
--- a/xlators/features/qemu-block/src/qemu-block.c
+++ /dev/null
@@ -1,1140 +0,0 @@
-/*
- Copyright (c) 2013 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 "inode.h"
-#include "call-stub.h"
-#include "defaults.h"
-#include "qemu-block-memory-types.h"
-#include "qemu-block.h"
-#include "qb-coroutines.h"
-
-
-qb_inode_t *
-__qb_inode_ctx_get (xlator_t *this, inode_t *inode)
-{
- uint64_t value = 0;
- qb_inode_t *qb_inode = NULL;
-
- __inode_ctx_get (inode, this, &value);
- qb_inode = (qb_inode_t *)(unsigned long) value;
-
- return qb_inode;
-}
-
-
-qb_inode_t *
-qb_inode_ctx_get (xlator_t *this, inode_t *inode)
-{
- qb_inode_t *qb_inode = NULL;
-
- LOCK (&inode->lock);
- {
- qb_inode = __qb_inode_ctx_get (this, inode);
- }
- UNLOCK (&inode->lock);
-
- return qb_inode;
-}
-
-
-qb_inode_t *
-qb_inode_ctx_del (xlator_t *this, inode_t *inode)
-{
- uint64_t value = 0;
- qb_inode_t *qb_inode = NULL;
-
- inode_ctx_del (inode, this, &value);
- qb_inode = (qb_inode_t *)(unsigned long) value;
-
- return qb_inode;
-}
-
-
-int
-qb_inode_cleanup (xlator_t *this, inode_t *inode, int warn)
-{
- qb_inode_t *qb_inode = NULL;
-
- qb_inode = qb_inode_ctx_del (this, inode);
-
- if (!qb_inode)
- return 0;
-
- if (warn)
- gf_log (this->name, GF_LOG_WARNING,
- "inode %s no longer block formatted",
- uuid_utoa (inode->gfid));
-
- /* free (qb_inode->bs); */
-
- GF_FREE (qb_inode);
-
- return 0;
-}
-
-
-int
-qb_iatt_fixup (xlator_t *this, inode_t *inode, struct iatt *iatt)
-{
- qb_inode_t *qb_inode = NULL;
-
- qb_inode = qb_inode_ctx_get (this, inode);
- if (!qb_inode)
- return 0;
-
- iatt->ia_size = qb_inode->size;
-
- return 0;
-}
-
-
-int
-qb_format_extract (xlator_t *this, char *format, inode_t *inode)
-{
- char *s, *save;
- uint64_t size = 0;
- char fmt[QB_XATTR_VAL_MAX+1] = {0, };
- qb_inode_t *qb_inode = NULL;
- char *formatstr = NULL;
- uuid_t gfid = {0,};
- char gfid_str[64] = {0,};
- int ret;
-
- strncpy(fmt, format, QB_XATTR_VAL_MAX);
-
- s = strtok_r(fmt, ":", &save);
- if (!s)
- goto invalid;
- formatstr = gf_strdup(s);
-
- s = strtok_r(NULL, ":", &save);
- if (!s)
- goto invalid;
- if (gf_string2bytesize (s, &size))
- goto invalid;
- if (!size)
- goto invalid;
-
- s = strtok_r(NULL, "\0", &save);
- if (s && !strncmp(s, "<gfid:", strlen("<gfid:"))) {
- /*
- * Check for valid gfid backing image specifier.
- */
- if (strlen(s) + 1 > sizeof(gfid_str))
- goto invalid;
- ret = sscanf(s, "<gfid:%[^>]s", gfid_str);
- if (ret == 1) {
- ret = uuid_parse(gfid_str, gfid);
- if (ret < 0)
- goto invalid;
- }
- }
-
- qb_inode = qb_inode_ctx_get (this, inode);
- if (!qb_inode)
- qb_inode = GF_CALLOC (1, sizeof (*qb_inode),
- gf_qb_mt_qb_inode_t);
- if (!qb_inode) {
- GF_FREE(formatstr);
- return ENOMEM;
- }
-
- strncpy(qb_inode->fmt, formatstr, QB_XATTR_VAL_MAX);
- qb_inode->size = size;
-
- /*
- * If a backing gfid was not specified, interpret any remaining bytes
- * associated with a backing image as a filename local to the parent
- * directory. The format processing will validate further.
- */
- if (!uuid_is_null(gfid))
- uuid_copy(qb_inode->backing_gfid, gfid);
- else if (s)
- qb_inode->backing_fname = gf_strdup(s);
-
- inode_ctx_set (inode, this, (void *)&qb_inode);
-
- GF_FREE(formatstr);
-
- return 0;
-
-invalid:
- GF_FREE(formatstr);
-
- gf_log (this->name, GF_LOG_WARNING,
- "invalid format '%s' in inode %s", format,
- uuid_utoa (inode->gfid));
- return EINVAL;
-}
-
-
-void
-qb_local_free (xlator_t *this, qb_local_t *local)
-{
- if (local->inode)
- inode_unref (local->inode);
- if (local->fd)
- fd_unref (local->fd);
- GF_FREE (local);
-}
-
-
-int
-qb_local_init (call_frame_t *frame)
-{
- qb_local_t *qb_local = NULL;
-
- qb_local = GF_CALLOC (1, sizeof (*qb_local), gf_qb_mt_qb_local_t);
- if (!qb_local)
- return -1;
- INIT_LIST_HEAD(&qb_local->list);
-
- qb_local->frame = frame;
- frame->local = qb_local;
-
- return 0;
-}
-
-
-int
-qb_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, struct iatt *postparent)
-{
- char *format = NULL;
- qb_conf_t *conf = NULL;
-
- conf = this->private;
-
- if (op_ret == -1)
- goto out;
-
- /*
- * Cache the root inode for dealing with backing images. The format
- * coroutine and the gluster qemu backend driver both use the root inode
- * table to verify and/or redirect I/O to the backing image via
- * anonymous fd's.
- */
- if (!conf->root_inode && __is_root_gfid(inode->gfid))
- conf->root_inode = inode_ref(inode);
-
- if (!xdata)
- goto out;
-
- if (dict_get_str (xdata, conf->qb_xattr_key, &format))
- goto out;
-
- if (!format) {
- qb_inode_cleanup (this, inode, 1);
- goto out;
- }
-
- op_errno = qb_format_extract (this, format, inode);
- if (op_errno)
- op_ret = -1;
-
- qb_iatt_fixup (this, inode, buf);
-out:
- QB_STACK_UNWIND (lookup, frame, op_ret, op_errno, inode, buf,
- xdata, postparent);
- return 0;
-}
-
-
-int
-qb_lookup (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
-{
- qb_conf_t *conf = NULL;
-
- conf = this->private;
-
- xdata = xdata ? dict_ref (xdata) : dict_new ();
-
- if (!xdata)
- goto enomem;
-
- if (dict_set_int32 (xdata, conf->qb_xattr_key, 0))
- goto enomem;
-
- STACK_WIND (frame, qb_lookup_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->lookup, loc, xdata);
- dict_unref (xdata);
- return 0;
-enomem:
- QB_STACK_UNWIND (lookup, frame, -1, ENOMEM, 0, 0, 0, 0);
- if (xdata)
- dict_unref (xdata);
- return 0;
-}
-
-
-int
-qb_setxattr_format (call_frame_t *frame, xlator_t *this, call_stub_t *stub,
- dict_t *xattr, inode_t *inode)
-{
- char *format = NULL;
- int op_errno = 0;
- qb_local_t *qb_local = NULL;
- data_t *data = NULL;
- qb_inode_t *qb_inode;
-
- if (!(data = dict_get (xattr, "trusted.glusterfs.block-format"))) {
- QB_STUB_RESUME (stub);
- return 0;
- }
-
- format = alloca (data->len + 1);
- memcpy (format, data->data, data->len);
- format[data->len] = 0;
-
- op_errno = qb_format_extract (this, format, inode);
- if (op_errno) {
- QB_STUB_UNWIND (stub, -1, op_errno);
- return 0;
- }
- qb_inode = qb_inode_ctx_get(this, inode);
-
- qb_local = frame->local;
-
- qb_local->stub = stub;
- qb_local->inode = inode_ref (inode);
-
- snprintf(qb_local->fmt, QB_XATTR_VAL_MAX, "%s:%" PRId64, qb_inode->fmt,
- qb_inode->size);
-
- qb_coroutine (frame, qb_format_and_resume);
-
- return 0;
-}
-
-
-int
-qb_setxattr_snapshot_create (call_frame_t *frame, xlator_t *this,
- call_stub_t *stub, dict_t *xattr, inode_t *inode)
-{
- qb_local_t *qb_local = NULL;
- char *name = NULL;
- data_t *data = NULL;
-
- if (!(data = dict_get (xattr, "trusted.glusterfs.block-snapshot-create"))) {
- QB_STUB_RESUME (stub);
- return 0;
- }
-
- name = alloca (data->len + 1);
- memcpy (name, data->data, data->len);
- name[data->len] = 0;
-
- qb_local = frame->local;
-
- qb_local->stub = stub;
- qb_local->inode = inode_ref (inode);
- strncpy (qb_local->name, name, 128);
-
- qb_coroutine (frame, qb_snapshot_create);
-
- return 0;
-}
-
-
-int
-qb_setxattr_snapshot_delete (call_frame_t *frame, xlator_t *this,
- call_stub_t *stub, dict_t *xattr, inode_t *inode)
-{
- qb_local_t *qb_local = NULL;
- char *name = NULL;
- data_t *data = NULL;
-
- if (!(data = dict_get (xattr, "trusted.glusterfs.block-snapshot-delete"))) {
- QB_STUB_RESUME (stub);
- return 0;
- }
-
- name = alloca (data->len + 1);
- memcpy (name, data->data, data->len);
- name[data->len] = 0;
-
- qb_local = frame->local;
-
- qb_local->stub = stub;
- qb_local->inode = inode_ref (inode);
- strncpy (qb_local->name, name, 128);
-
- qb_coroutine (frame, qb_snapshot_delete);
-
- return 0;
-}
-
-int
-qb_setxattr_snapshot_goto (call_frame_t *frame, xlator_t *this,
- call_stub_t *stub, dict_t *xattr, inode_t *inode)
-{
- qb_local_t *qb_local = NULL;
- char *name = NULL;
- data_t *data = NULL;
-
- if (!(data = dict_get (xattr, "trusted.glusterfs.block-snapshot-goto"))) {
- QB_STUB_RESUME (stub);
- return 0;
- }
-
- name = alloca (data->len + 1);
- memcpy (name, data->data, data->len);
- name[data->len] = 0;
-
- qb_local = frame->local;
-
- qb_local->stub = stub;
- qb_local->inode = inode_ref (inode);
- strncpy (qb_local->name, name, 128);
-
- qb_coroutine (frame, qb_snapshot_goto);
-
- return 0;
-}
-
-
-int
-qb_setxattr_common (call_frame_t *frame, xlator_t *this, call_stub_t *stub,
- dict_t *xattr, inode_t *inode)
-{
- data_t *data = NULL;
-
- if ((data = dict_get (xattr, "trusted.glusterfs.block-format"))) {
- qb_setxattr_format (frame, this, stub, xattr, inode);
- return 0;
- }
-
- if ((data = dict_get (xattr, "trusted.glusterfs.block-snapshot-create"))) {
- qb_setxattr_snapshot_create (frame, this, stub, xattr, inode);
- return 0;
- }
-
- if ((data = dict_get (xattr, "trusted.glusterfs.block-snapshot-delete"))) {
- qb_setxattr_snapshot_delete (frame, this, stub, xattr, inode);
- return 0;
- }
-
- if ((data = dict_get (xattr, "trusted.glusterfs.block-snapshot-goto"))) {
- qb_setxattr_snapshot_goto (frame, this, stub, xattr, inode);
- return 0;
- }
-
- QB_STUB_RESUME (stub);
-
- return 0;
-}
-
-
-int
-qb_setxattr (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xattr,
- int flags, dict_t *xdata)
-{
- call_stub_t *stub = NULL;
-
- if (qb_local_init (frame) != 0)
- goto enomem;
-
- stub = fop_setxattr_stub (frame, default_setxattr_resume, loc, xattr,
- flags, xdata);
- if (!stub)
- goto enomem;
-
- qb_setxattr_common (frame, this, stub, xattr, loc->inode);
-
- return 0;
-enomem:
- QB_STACK_UNWIND (setxattr, frame, -1, ENOMEM, 0);
- return 0;
-}
-
-
-int
-qb_fsetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xattr,
- int flags, dict_t *xdata)
-{
- call_stub_t *stub = NULL;
-
- if (qb_local_init (frame) != 0)
- goto enomem;
-
- stub = fop_fsetxattr_stub (frame, default_fsetxattr_resume, fd, xattr,
- flags, xdata);
- if (!stub)
- goto enomem;
-
- qb_setxattr_common (frame, this, stub, xattr, fd->inode);
-
- return 0;
-enomem:
- QB_STACK_UNWIND (fsetxattr, frame, -1, ENOMEM, 0);
- return 0;
-}
-
-
-int
-qb_open_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int op_ret, int op_errno, fd_t *fd, dict_t *xdata)
-{
- call_stub_t *stub = NULL;
- qb_local_t *qb_local = NULL;
-
- qb_local = frame->local;
-
- if (op_ret < 0)
- goto unwind;
-
- if (!qb_inode_ctx_get (this, qb_local->inode))
- goto unwind;
-
- stub = fop_open_cbk_stub (frame, NULL, op_ret, op_errno, fd, xdata);
- if (!stub) {
- op_ret = -1;
- op_errno = ENOMEM;
- goto unwind;
- }
-
- qb_local->stub = stub;
-
- qb_coroutine (frame, qb_co_open);
-
- return 0;
-unwind:
- QB_STACK_UNWIND (open, frame, op_ret, op_errno, fd, xdata);
- return 0;
-}
-
-
-int
-qb_open (call_frame_t *frame, xlator_t *this, loc_t *loc, int flags,
- fd_t *fd, dict_t *xdata)
-{
- qb_local_t *qb_local = NULL;
- qb_inode_t *qb_inode = NULL;
-
- qb_inode = qb_inode_ctx_get (this, loc->inode);
- if (!qb_inode) {
- STACK_WIND (frame, default_open_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->open, loc, flags, fd,
- xdata);
- return 0;
- }
-
- if (qb_local_init (frame) != 0)
- goto enomem;
-
- qb_local = frame->local;
-
- qb_local->inode = inode_ref (loc->inode);
- qb_local->fd = fd_ref (fd);
-
- STACK_WIND (frame, qb_open_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->open, loc, flags, fd, xdata);
- return 0;
-enomem:
- QB_STACK_UNWIND (open, frame, -1, ENOMEM, 0, 0);
- return 0;
-}
-
-
-int
-qb_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)
-{
- qb_local_t *qb_local = NULL;
- qb_inode_t *qb_inode = NULL;
-
- qb_inode = qb_inode_ctx_get (this, fd->inode);
- if (!qb_inode) {
- STACK_WIND (frame, default_writev_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->writev, fd, vector, count,
- offset, flags, iobref, xdata);
- return 0;
- }
-
- if (qb_local_init (frame) != 0)
- goto enomem;
-
- qb_local = frame->local;
-
- qb_local->inode = inode_ref (fd->inode);
- qb_local->fd = fd_ref (fd);
-
- qb_local->stub = fop_writev_stub (frame, NULL, fd, vector, count,
- offset, flags, iobref, xdata);
- if (!qb_local->stub)
- goto enomem;
-
- qb_coroutine (frame, qb_co_writev);
-
- return 0;
-enomem:
- QB_STACK_UNWIND (writev, frame, -1, ENOMEM, 0, 0, 0);
- return 0;
-}
-
-
-int
-qb_readv (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
- off_t offset, uint32_t flags, dict_t *xdata)
-{
- qb_local_t *qb_local = NULL;
- qb_inode_t *qb_inode = NULL;
-
- qb_inode = qb_inode_ctx_get (this, fd->inode);
- if (!qb_inode) {
- STACK_WIND (frame, default_readv_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->readv, fd, size, offset,
- flags, xdata);
- return 0;
- }
-
- if (qb_local_init (frame) != 0)
- goto enomem;
-
- qb_local = frame->local;
-
- qb_local->inode = inode_ref (fd->inode);
- qb_local->fd = fd_ref (fd);
-
- qb_local->stub = fop_readv_stub (frame, NULL, fd, size, offset,
- flags, xdata);
- if (!qb_local->stub)
- goto enomem;
-
- qb_coroutine (frame, qb_co_readv);
-
- return 0;
-enomem:
- QB_STACK_UNWIND (readv, frame, -1, ENOMEM, 0, 0, 0, 0, 0);
- return 0;
-}
-
-
-int
-qb_fsync (call_frame_t *frame, xlator_t *this, fd_t *fd, int dsync,
- dict_t *xdata)
-{
- qb_local_t *qb_local = NULL;
- qb_inode_t *qb_inode = NULL;
-
- qb_inode = qb_inode_ctx_get (this, fd->inode);
- if (!qb_inode) {
- STACK_WIND (frame, default_fsync_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fsync, fd, dsync, xdata);
- return 0;
- }
-
- if (qb_local_init (frame) != 0)
- goto enomem;
-
- qb_local = frame->local;
-
- qb_local->inode = inode_ref (fd->inode);
- qb_local->fd = fd_ref (fd);
-
- qb_local->stub = fop_fsync_stub (frame, NULL, fd, dsync, xdata);
-
- if (!qb_local->stub)
- goto enomem;
-
- qb_coroutine (frame, qb_co_fsync);
-
- return 0;
-enomem:
- QB_STACK_UNWIND (fsync, frame, -1, ENOMEM, 0, 0, 0);
- return 0;
-}
-
-
-int
-qb_flush (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
-{
- qb_local_t *qb_local = NULL;
- qb_inode_t *qb_inode = NULL;
-
- qb_inode = qb_inode_ctx_get (this, fd->inode);
- if (!qb_inode) {
- STACK_WIND (frame, default_flush_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->flush, fd, xdata);
- return 0;
- }
-
- if (qb_local_init (frame) != 0)
- goto enomem;
-
- qb_local = frame->local;
-
- qb_local->inode = inode_ref (fd->inode);
- qb_local->fd = fd_ref (fd);
-
- qb_local->stub = fop_flush_stub (frame, NULL, fd, xdata);
-
- if (!qb_local->stub)
- goto enomem;
-
- qb_coroutine (frame, qb_co_fsync);
-
- return 0;
-enomem:
- QB_STACK_UNWIND (flush, frame, -1, ENOMEM, 0);
- return 0;
-}
-
-static int32_t
-qb_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)
-{
- qb_conf_t *conf = this->private;
- gf_dirent_t *entry;
- char *format;
-
- list_for_each_entry(entry, &entries->list, list) {
- if (!entry->inode || !entry->dict)
- continue;
-
- format = NULL;
- if (dict_get_str(entry->dict, conf->qb_xattr_key, &format))
- continue;
-
- if (!format) {
- qb_inode_cleanup(this, entry->inode, 1);
- continue;
- }
-
- if (qb_format_extract(this, format, entry->inode))
- continue;
-
- qb_iatt_fixup(this, entry->inode, &entry->d_stat);
- }
-
- STACK_UNWIND_STRICT(readdirp, frame, op_ret, op_errno, entries, xdata);
- return 0;
-}
-
-static int32_t
-qb_readdirp(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
- off_t off, dict_t *xdata)
-{
- qb_conf_t *conf = this->private;
-
- xdata = xdata ? dict_ref(xdata) : dict_new();
- if (!xdata)
- goto enomem;
-
- if (dict_set_int32 (xdata, conf->qb_xattr_key, 0))
- goto enomem;
-
- STACK_WIND(frame, qb_readdirp_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->readdirp, fd, size, off, xdata);
-
- dict_unref(xdata);
- return 0;
-
-enomem:
- QB_STACK_UNWIND(readdirp, frame, -1, ENOMEM, NULL, NULL);
- if (xdata)
- dict_unref(xdata);
- return 0;
-}
-
-int
-qb_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset,
- dict_t *xdata)
-{
- qb_local_t *qb_local = NULL;
- qb_inode_t *qb_inode = NULL;
-
- qb_inode = qb_inode_ctx_get (this, loc->inode);
- if (!qb_inode) {
- STACK_WIND (frame, default_truncate_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->truncate, loc, offset,
- xdata);
- return 0;
- }
-
- if (qb_local_init (frame) != 0)
- goto enomem;
-
- qb_local = frame->local;
-
- qb_local->inode = inode_ref (loc->inode);
- qb_local->fd = fd_anonymous (loc->inode);
-
- qb_local->stub = fop_truncate_stub (frame, NULL, loc, offset, xdata);
-
- if (!qb_local->stub)
- goto enomem;
-
- qb_coroutine (frame, qb_co_truncate);
-
- return 0;
-enomem:
- QB_STACK_UNWIND (truncate, frame, -1, ENOMEM, 0, 0, 0);
- return 0;
-}
-
-
-int
-qb_ftruncate (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
- dict_t *xdata)
-{
- qb_local_t *qb_local = NULL;
- qb_inode_t *qb_inode = NULL;
-
- qb_inode = qb_inode_ctx_get (this, fd->inode);
- if (!qb_inode) {
- STACK_WIND (frame, default_ftruncate_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->ftruncate, fd, offset,
- xdata);
- return 0;
- }
-
- if (qb_local_init (frame) != 0)
- goto enomem;
-
- qb_local = frame->local;
-
- qb_local->inode = inode_ref (fd->inode);
- qb_local->fd = fd_ref (fd);
-
- qb_local->stub = fop_ftruncate_stub (frame, NULL, fd, offset, xdata);
-
- if (!qb_local->stub)
- goto enomem;
-
- qb_coroutine (frame, qb_co_truncate);
-
- return 0;
-enomem:
- QB_STACK_UNWIND (ftruncate, frame, -1, ENOMEM, 0, 0, 0);
- return 0;
-}
-
-
-int
-qb_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int op_ret, int op_errno, struct iatt *iatt, dict_t *xdata)
-{
- inode_t *inode = NULL;
-
- inode = frame->local;
- frame->local = NULL;
-
- if (inode) {
- qb_iatt_fixup (this, inode, iatt);
- inode_unref (inode);
- }
-
- QB_STACK_UNWIND (stat, frame, op_ret, op_errno, iatt, xdata);
-
- return 0;
-}
-
-int
-qb_stat (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
-{
- if (qb_inode_ctx_get (this, loc->inode))
- frame->local = inode_ref (loc->inode);
-
- STACK_WIND (frame, qb_stat_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->stat, loc, xdata);
- return 0;
-}
-
-
-int
-qb_fstat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int op_ret, int op_errno, struct iatt *iatt, dict_t *xdata)
-{
- inode_t *inode = NULL;
-
- inode = frame->local;
- frame->local = NULL;
-
- if (inode) {
- qb_iatt_fixup (this, inode, iatt);
- inode_unref (inode);
- }
-
- QB_STACK_UNWIND (fstat, frame, op_ret, op_errno, iatt, xdata);
-
- return 0;
-}
-
-
-int
-qb_fstat (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
-{
- if (qb_inode_ctx_get (this, fd->inode))
- frame->local = inode_ref (fd->inode);
-
- STACK_WIND (frame, qb_fstat_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fstat, fd, xdata);
- return 0;
-}
-
-
-int
-qb_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int op_ret, int op_errno, struct iatt *pre, struct iatt *post,
- dict_t *xdata)
-{
- inode_t *inode = NULL;
-
- inode = frame->local;
- frame->local = NULL;
-
- if (inode) {
- qb_iatt_fixup (this, inode, pre);
- qb_iatt_fixup (this, inode, post);
- inode_unref (inode);
- }
-
- QB_STACK_UNWIND (setattr, frame, op_ret, op_errno, pre, post, xdata);
-
- return 0;
-}
-
-
-int
-qb_setattr (call_frame_t *frame, xlator_t *this, loc_t *loc, struct iatt *buf,
- int valid, dict_t *xdata)
-{
- if (qb_inode_ctx_get (this, loc->inode))
- frame->local = inode_ref (loc->inode);
-
- STACK_WIND (frame, qb_setattr_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->setattr, loc, buf, valid, xdata);
- return 0;
-}
-
-
-int
-qb_fsetattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int op_ret, int op_errno, struct iatt *pre, struct iatt *post,
- dict_t *xdata)
-{
- inode_t *inode = NULL;
-
- inode = frame->local;
- frame->local = NULL;
-
- if (inode) {
- qb_iatt_fixup (this, inode, pre);
- qb_iatt_fixup (this, inode, post);
- inode_unref (inode);
- }
-
- QB_STACK_UNWIND (fsetattr, frame, op_ret, op_errno, pre, post, xdata);
-
- return 0;
-}
-
-
-int
-qb_fsetattr (call_frame_t *frame, xlator_t *this, fd_t *fd, struct iatt *buf,
- int valid, dict_t *xdata)
-{
- if (qb_inode_ctx_get (this, fd->inode))
- frame->local = inode_ref (fd->inode);
-
- STACK_WIND (frame, qb_setattr_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fsetattr, fd, buf, valid, xdata);
- return 0;
-}
-
-
-int
-qb_forget (xlator_t *this, inode_t *inode)
-{
- return qb_inode_cleanup (this, inode, 0);
-}
-
-
-int
-qb_release (xlator_t *this, fd_t *fd)
-{
- call_frame_t *frame = NULL;
-
- frame = create_frame (this, this->ctx->pool);
- if (!frame) {
- gf_log (this->name, GF_LOG_ERROR,
- "Could not allocate frame. "
- "Leaking QEMU BlockDriverState");
- return -1;
- }
-
- if (qb_local_init (frame) != 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "Could not allocate local. "
- "Leaking QEMU BlockDriverState");
- STACK_DESTROY (frame->root);
- return -1;
- }
-
- if (qb_coroutine (frame, qb_co_close) != 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "Could not allocate coroutine. "
- "Leaking QEMU BlockDriverState");
- qb_local_free (this, frame->local);
- frame->local = NULL;
- STACK_DESTROY (frame->root);
- }
-
- return 0;
-}
-
-int
-mem_acct_init (xlator_t *this)
-{
- int ret = -1;
-
- ret = xlator_mem_acct_init (this, gf_qb_mt_end + 1);
-
- if (ret)
- gf_log (this->name, GF_LOG_ERROR, "Memory accounting init "
- "failed");
- return ret;
-}
-
-
-int
-reconfigure (xlator_t *this, dict_t *options)
-{
- return 0;
-}
-
-
-int
-init (xlator_t *this)
-{
- qb_conf_t *conf = NULL;
- int32_t ret = -1;
- static int bdrv_inited = 0;
-
- if (!this->children || this->children->next) {
- gf_log (this->name, GF_LOG_ERROR,
- "FATAL: qemu-block (%s) not configured with exactly "
- "one child", this->name);
- goto out;
- }
-
- conf = GF_CALLOC (1, sizeof (*conf), gf_qb_mt_qb_conf_t);
- if (!conf)
- goto out;
-
- /* configure 'option window-size <size>' */
- GF_OPTION_INIT ("default-password", conf->default_password, str, out);
-
- /* qemu coroutines use "co_mutex" for synchronizing among themselves.
- However "co_mutex" itself is not threadsafe if the coroutine framework
- is multithreaded (which usually is not). However synctasks are
- fundamentally multithreaded, so for now create a syncenv which has
- scaling limits set to max 1 thread so that the qemu coroutines can
- execute "safely".
-
- Future work: provide an implementation of "co_mutex" which is
- threadsafe and use the global multithreaded ctx->env syncenv.
- */
- conf->env = syncenv_new (0, 1, 1);
-
- this->private = conf;
-
- ret = 0;
-
- snprintf (conf->qb_xattr_key, QB_XATTR_KEY_MAX, QB_XATTR_KEY_FMT,
- this->name);
-
- cur_mon = (void *) 1;
-
- if (!bdrv_inited) {
- bdrv_init ();
- bdrv_inited = 1;
- }
-
-out:
- if (ret)
- GF_FREE (conf);
-
- return ret;
-}
-
-
-void
-fini (xlator_t *this)
-{
- qb_conf_t *conf = NULL;
-
- conf = this->private;
-
- this->private = NULL;
-
- if (conf->root_inode)
- inode_unref(conf->root_inode);
- GF_FREE (conf);
-
- return;
-}
-
-
-struct xlator_fops fops = {
- .lookup = qb_lookup,
- .fsetxattr = qb_fsetxattr,
- .setxattr = qb_setxattr,
- .open = qb_open,
- .writev = qb_writev,
- .readv = qb_readv,
- .fsync = qb_fsync,
- .truncate = qb_truncate,
- .ftruncate = qb_ftruncate,
- .stat = qb_stat,
- .fstat = qb_fstat,
- .setattr = qb_setattr,
- .fsetattr = qb_fsetattr,
- .flush = qb_flush,
-/*
- .getxattr = qb_getxattr,
- .fgetxattr = qb_fgetxattr
-*/
- .readdirp = qb_readdirp,
-};
-
-
-struct xlator_cbks cbks = {
- .forget = qb_forget,
- .release = qb_release,
-};
-
-
-struct xlator_dumpops dumpops = {
-};
-
-
-struct volume_options options[] = {
- { .key = {"default-password"},
- .type = GF_OPTION_TYPE_STR,
- .default_value = "",
- .description = "Default password for the AES encrypted block images."
- },
- { .key = {NULL} },
-};
diff --git a/xlators/features/qemu-block/src/qemu-block.h b/xlators/features/qemu-block/src/qemu-block.h
deleted file mode 100644
index 21cdcec2613..00000000000
--- a/xlators/features/qemu-block/src/qemu-block.h
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- Copyright (c) 2013 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 __QEMU_BLOCK_H
-#define __QEMU_BLOCK_H
-
-#include "syncop.h"
-#include "call-stub.h"
-#include "block/block_int.h"
-#include "monitor/monitor.h"
-
-/* QB_XATTR_KEY_FMT is the on-disk xattr stored in the inode which
- indicates that the file must be "interpreted" by the block format
- logic. The value of the key is of the pattern:
-
- "format:virtual_size"
-
- e.g
-
- "qcow2:20GB" or "qed:100GB"
-
- The format and virtual size are colon separated. The format is
- a case sensitive string which qemu recognizes. virtual_size is
- specified as a size which glusterfs recognizes as size (i.e.,
- value accepted by gf_string2bytesize())
-*/
-#define QB_XATTR_KEY_FMT "trusted.glusterfs.%s.format"
-
-#define QB_XATTR_KEY_MAX 64
-
-#define QB_XATTR_VAL_MAX 64
-
-
-typedef struct qb_inode {
- char fmt[QB_XATTR_VAL_MAX]; /* this is only the format, not "format:size" */
- uint64_t size; /* virtual size in bytes */
- BlockDriverState *bs;
- int refcnt;
- uuid_t backing_gfid;
- char *backing_fname;
-} qb_inode_t;
-
-
-typedef struct qb_conf {
- Monitor *mon;
- struct syncenv *env;
- char qb_xattr_key[QB_XATTR_KEY_MAX];
- char *default_password;
- inode_t *root_inode;
-} qb_conf_t;
-
-
-typedef struct qb_local {
- call_frame_t *frame; /* backpointer */
- call_stub_t *stub;
- inode_t *inode;
- fd_t *fd;
- char fmt[QB_XATTR_VAL_MAX+1];
- char name[256];
- synctask_fn_t synctask_fn;
- struct list_head list;
-} qb_local_t;
-
-void qb_local_free (xlator_t *this, qb_local_t *local);
-int qb_coroutine (call_frame_t *frame, synctask_fn_t fn);
-inode_t *qb_inode_from_filename (const char *filename);
-int qb_inode_to_filename (inode_t *inode, char *filename, int size);
-int qb_format_extract (xlator_t *this, char *format, inode_t *inode);
-
-qb_inode_t *qb_inode_ctx_get (xlator_t *this, inode_t *inode);
-
-#define QB_STACK_UNWIND(typ, frame, args ...) do { \
- qb_local_t *__local = frame->local; \
- xlator_t *__this = frame->this; \
- \
- frame->local = NULL; \
- STACK_UNWIND_STRICT (typ, frame, args); \
- if (__local) \
- qb_local_free (__this, __local); \
- } while (0)
-
-#define QB_STUB_UNWIND(stub, op_ret, op_errno) do { \
- qb_local_t *__local = stub->frame->local; \
- xlator_t *__this = stub->frame->this; \
- \
- stub->frame->local = NULL; \
- call_unwind_error (stub, op_ret, op_errno); \
- if (__local) \
- qb_local_free (__this, __local); \
- } while (0)
-
-#define QB_STUB_RESUME(stub_errno) do { \
- qb_local_t *__local = stub->frame->local; \
- xlator_t *__this = stub->frame->this; \
- \
- stub->frame->local = NULL; \
- call_resume (stub); \
- if (__local) \
- qb_local_free (__this, __local); \
- } while (0)
-
-#endif /* !__QEMU_BLOCK_H */
diff --git a/xlators/features/quiesce/Makefile.am b/xlators/features/quiesce/Makefile.am
deleted file mode 100644
index a985f42a877..00000000000
--- a/xlators/features/quiesce/Makefile.am
+++ /dev/null
@@ -1,3 +0,0 @@
-SUBDIRS = src
-
-CLEANFILES =
diff --git a/xlators/features/quiesce/src/Makefile.am b/xlators/features/quiesce/src/Makefile.am
deleted file mode 100644
index 15e46629e78..00000000000
--- a/xlators/features/quiesce/src/Makefile.am
+++ /dev/null
@@ -1,15 +0,0 @@
-xlator_LTLIBRARIES = quiesce.la
-xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/features
-
-quiesce_la_LDFLAGS = -module -avoid-version
-
-quiesce_la_SOURCES = quiesce.c
-quiesce_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la
-
-noinst_HEADERS = quiesce.h quiesce-mem-types.h
-
-AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src
-
-AM_CFLAGS = -Wall $(GF_CFLAGS)
-
-CLEANFILES =
diff --git a/xlators/features/quiesce/src/quiesce-mem-types.h b/xlators/features/quiesce/src/quiesce-mem-types.h
deleted file mode 100644
index 6e582f424ea..00000000000
--- a/xlators/features/quiesce/src/quiesce-mem-types.h
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- Copyright (c) 2010-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 __QUIESCE_MEM_TYPES_H__
-#define __QUIESCE_MEM_TYPES_H__
-
-#include "mem-types.h"
-
-enum gf_quiesce_mem_types_ {
- gf_quiesce_mt_priv_t = gf_common_mt_end + 1,
- gf_quiesce_mt_end
-};
-#endif
diff --git a/xlators/features/quiesce/src/quiesce.c b/xlators/features/quiesce/src/quiesce.c
deleted file mode 100644
index 24c7dc6ed31..00000000000
--- a/xlators/features/quiesce/src/quiesce.c
+++ /dev/null
@@ -1,2610 +0,0 @@
-/*
- Copyright (c) 2010-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 "quiesce.h"
-#include "defaults.h"
-#include "call-stub.h"
-
-/* TODO: */
-/* Think about 'writev/_*_lk/setattr/xattrop/' fops to do re-transmittion */
-
-
-/* Quiesce Specific Functions */
-void
-gf_quiesce_local_wipe (xlator_t *this, quiesce_local_t *local)
-{
- if (!local || !this || !this->private)
- return;
-
- 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->dict)
- dict_unref (local->dict);
- if (local->iobref)
- iobref_unref (local->iobref);
- GF_FREE (local->vector);
-
- mem_put (local);
-}
-
-call_stub_t *
-gf_quiesce_dequeue (xlator_t *this)
-{
- call_stub_t *stub = NULL;
- quiesce_priv_t *priv = NULL;
-
- priv = this->private;
-
- if (!priv || list_empty (&priv->req))
- return NULL;
-
- LOCK (&priv->lock);
- {
- stub = list_entry (priv->req.next, call_stub_t, list);
- list_del_init (&stub->list);
- priv->queue_size--;
- }
- UNLOCK (&priv->lock);
-
- return stub;
-}
-
-void *
-gf_quiesce_dequeue_start (void *data)
-{
- xlator_t *this = NULL;
- quiesce_priv_t *priv = NULL;
- call_stub_t *stub = NULL;
-
- this = data;
- priv = this->private;
- THIS = this;
-
- while (!list_empty (&priv->req)) {
- stub = gf_quiesce_dequeue (this);
- if (stub) {
- call_resume (stub);
- }
- }
-
- return 0;
-}
-
-
-void
-gf_quiesce_timeout (void *data)
-{
- xlator_t *this = NULL;
- quiesce_priv_t *priv = NULL;
-
- this = data;
- priv = this->private;
- THIS = this;
-
- LOCK (&priv->lock);
- {
- priv->pass_through = _gf_true;
- }
- UNLOCK (&priv->lock);
-
- gf_quiesce_dequeue_start (this);
-
- return;
-}
-
-void
-gf_quiesce_enqueue (xlator_t *this, call_stub_t *stub)
-{
- quiesce_priv_t *priv = NULL;
- struct timespec timeout = {0,};
-
- priv = this->private;
- if (!priv) {
- gf_log_callingfn (this->name, GF_LOG_ERROR,
- "this->private == NULL");
- return;
- }
-
- LOCK (&priv->lock);
- {
- list_add_tail (&stub->list, &priv->req);
- priv->queue_size++;
- }
- UNLOCK (&priv->lock);
-
- if (!priv->timer) {
- timeout.tv_sec = 20;
- timeout.tv_nsec = 0;
-
- priv->timer = gf_timer_call_after (this->ctx,
- timeout,
- gf_quiesce_timeout,
- (void *) this);
- }
-
- return;
-}
-
-
-
-/* _CBK function section */
-
-int32_t
-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)
-{
- call_stub_t *stub = NULL;
- quiesce_local_t *local = NULL;
-
- local = frame->local;
- frame->local = NULL;
- if ((op_ret == -1) && (op_errno == ENOTCONN)) {
- /* Re-transmit (by putting in the queue) */
- stub = fop_lookup_stub (frame, default_lookup_resume,
- &local->loc, local->dict);
- if (!stub) {
- STACK_UNWIND_STRICT (lookup, frame, -1, ENOMEM,
- NULL, NULL, NULL, NULL);
- goto out;
- }
-
- gf_quiesce_enqueue (this, stub);
- goto out;
- }
-
- STACK_UNWIND_STRICT (lookup, frame, op_ret, op_errno, inode, buf,
- dict, postparent);
-out:
- gf_quiesce_local_wipe (this, local);
-
- return 0;
-}
-
-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)
-{
- call_stub_t *stub = NULL;
- quiesce_local_t *local = NULL;
-
- 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);
- if (!stub) {
- STACK_UNWIND_STRICT (stat, frame, -1, ENOMEM,
- NULL, NULL);
- goto out;
- }
-
- gf_quiesce_enqueue (this, stub);
- goto out;
- }
-
- STACK_UNWIND_STRICT (stat, frame, op_ret, op_errno, buf, xdata);
-out:
- gf_quiesce_local_wipe (this, local);
-
- return 0;
-}
-
-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)
-{
- call_stub_t *stub = NULL;
- quiesce_local_t *local = NULL;
-
- 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);
- if (!stub) {
- STACK_UNWIND_STRICT (access, frame, -1, ENOMEM, NULL);
- goto out;
- }
-
- gf_quiesce_enqueue (this, stub);
- goto out;
- }
-
- STACK_UNWIND_STRICT (access, frame, op_ret, op_errno, xdata);
-out:
- gf_quiesce_local_wipe (this, local);
-
- return 0;
-}
-
-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)
-{
- call_stub_t *stub = NULL;
- quiesce_local_t *local = NULL;
-
- 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);
- if (!stub) {
- STACK_UNWIND_STRICT (readlink, frame, -1, ENOMEM,
- NULL, NULL, NULL);
- goto out;
- }
-
- gf_quiesce_enqueue (this, stub);
- goto out;
- }
-
- STACK_UNWIND_STRICT (readlink, frame, op_ret, op_errno, path, buf, xdata);
-out:
- gf_quiesce_local_wipe (this, local);
-
- return 0;
-}
-
-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)
-{
- call_stub_t *stub = NULL;
- quiesce_local_t *local = NULL;
-
- 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);
- if (!stub) {
- STACK_UNWIND_STRICT (open, frame, -1, ENOMEM,
- NULL, NULL);
- goto out;
- }
-
- gf_quiesce_enqueue (this, stub);
- goto out;
- }
-
- STACK_UNWIND_STRICT (open, frame, op_ret, op_errno, fd, xdata);
-out:
- gf_quiesce_local_wipe (this, local);
-
- return 0;
-}
-
-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)
-{
- call_stub_t *stub = NULL;
- quiesce_local_t *local = NULL;
-
- 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);
- if (!stub) {
- STACK_UNWIND_STRICT (readv, frame, -1, ENOMEM,
- NULL, 0, NULL, NULL, NULL);
- goto out;
- }
-
- gf_quiesce_enqueue (this, stub);
- goto out;
- }
-
- STACK_UNWIND_STRICT (readv, frame, op_ret, op_errno, vector, count,
- stbuf, iobref, xdata);
-out:
- gf_quiesce_local_wipe (this, local);
-
- return 0;
-}
-
-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)
-{
- call_stub_t *stub = NULL;
- quiesce_local_t *local = NULL;
-
- 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);
- if (!stub) {
- STACK_UNWIND_STRICT (flush, frame, -1, ENOMEM, NULL);
- goto out;
- }
-
- gf_quiesce_enqueue (this, stub);
- goto out;
- }
-
- STACK_UNWIND_STRICT (flush, frame, op_ret, op_errno, xdata);
-out:
- gf_quiesce_local_wipe (this, local);
-
- return 0;
-}
-
-
-
-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)
-{
- call_stub_t *stub = NULL;
- quiesce_local_t *local = NULL;
-
- 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);
- if (!stub) {
- STACK_UNWIND_STRICT (fsync, frame, -1, ENOMEM,
- NULL, NULL, NULL);
- goto out;
- }
-
- gf_quiesce_enqueue (this, stub);
- goto out;
- }
-
- STACK_UNWIND_STRICT (fsync, frame, op_ret, op_errno, prebuf, postbuf, xdata);
-out:
- gf_quiesce_local_wipe (this, local);
-
- return 0;
-}
-
-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)
-{
- call_stub_t *stub = NULL;
- quiesce_local_t *local = NULL;
-
- 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);
- if (!stub) {
- STACK_UNWIND_STRICT (fstat, frame, -1, ENOMEM,
- NULL, NULL);
- goto out;
- }
-
- gf_quiesce_enqueue (this, stub);
- goto out;
- }
-
- STACK_UNWIND_STRICT (fstat, frame, op_ret, op_errno, buf, xdata);
-out:
- gf_quiesce_local_wipe (this, local);
-
- return 0;
-}
-
-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)
-{
- call_stub_t *stub = NULL;
- quiesce_local_t *local = NULL;
-
- 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);
- if (!stub) {
- STACK_UNWIND_STRICT (opendir, frame, -1, ENOMEM,
- NULL, NULL);
- goto out;
- }
-
- gf_quiesce_enqueue (this, stub);
- goto out;
- }
-
- STACK_UNWIND_STRICT (opendir, frame, op_ret, op_errno, fd, xdata);
-out:
- gf_quiesce_local_wipe (this, local);
-
- return 0;
-}
-
-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)
-{
- call_stub_t *stub = NULL;
- quiesce_local_t *local = NULL;
-
- 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);
- if (!stub) {
- STACK_UNWIND_STRICT (fsyncdir, frame, -1, ENOMEM, NULL);
- goto out;
- }
-
- gf_quiesce_enqueue (this, stub);
- goto out;
- }
-
- STACK_UNWIND_STRICT (fsyncdir, frame, op_ret, op_errno, xdata);
-out:
- gf_quiesce_local_wipe (this, local);
-
- return 0;
-}
-
-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)
-{
- call_stub_t *stub = NULL;
- quiesce_local_t *local = NULL;
-
- 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);
- if (!stub) {
- STACK_UNWIND_STRICT (statfs, frame, -1, ENOMEM,
- NULL, NULL);
- goto out;
- }
-
- gf_quiesce_enqueue (this, stub);
- goto out;
- }
-
- STACK_UNWIND_STRICT (statfs, frame, op_ret, op_errno, buf, xdata);
-out:
- gf_quiesce_local_wipe (this, local);
-
- return 0;
-}
-
-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)
-{
- call_stub_t *stub = NULL;
- quiesce_local_t *local = NULL;
-
- 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);
- if (!stub) {
- STACK_UNWIND_STRICT (fgetxattr, frame, -1, ENOMEM,
- NULL, NULL);
- goto out;
- }
-
- gf_quiesce_enqueue (this, stub);
- goto out;
- }
-
- STACK_UNWIND_STRICT (fgetxattr, frame, op_ret, op_errno, dict, xdata);
-out:
- gf_quiesce_local_wipe (this, local);
-
- return 0;
-}
-
-
-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)
-{
- call_stub_t *stub = NULL;
- quiesce_local_t *local = NULL;
-
- 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);
- if (!stub) {
- STACK_UNWIND_STRICT (getxattr, frame, -1, ENOMEM,
- NULL, NULL);
- goto out;
- }
-
- gf_quiesce_enqueue (this, stub);
- goto out;
- }
-
- STACK_UNWIND_STRICT (getxattr, frame, op_ret, op_errno, dict, xdata);
-out:
- gf_quiesce_local_wipe (this, local);
-
- return 0;
-}
-
-
-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)
-{
- call_stub_t *stub = NULL;
- quiesce_local_t *local = NULL;
-
- 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);
- if (!stub) {
- STACK_UNWIND_STRICT (rchecksum, frame, -1, ENOMEM,
- 0, NULL, NULL);
- goto out;
- }
-
- gf_quiesce_enqueue (this, stub);
- goto out;
- }
-
- STACK_UNWIND_STRICT (rchecksum, frame, op_ret, op_errno, weak_checksum,
- strong_checksum, xdata);
-out:
- gf_quiesce_local_wipe (this, local);
-
- return 0;
-}
-
-
-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)
-{
- call_stub_t *stub = NULL;
- quiesce_local_t *local = NULL;
-
- 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);
- if (!stub) {
- STACK_UNWIND_STRICT (readdir, frame, -1, ENOMEM,
- NULL, NULL);
- goto out;
- }
-
- gf_quiesce_enqueue (this, stub);
- goto out;
- }
-
- STACK_UNWIND_STRICT (readdir, frame, op_ret, op_errno, entries, xdata);
-out:
- gf_quiesce_local_wipe (this, local);
-
- return 0;
-}
-
-
-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)
-{
- call_stub_t *stub = NULL;
- quiesce_local_t *local = NULL;
-
- 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);
- if (!stub) {
- STACK_UNWIND_STRICT (readdirp, frame, -1, ENOMEM,
- NULL, NULL);
- goto out;
- }
-
- gf_quiesce_enqueue (this, stub);
- goto out;
- }
-
- STACK_UNWIND_STRICT (readdirp, frame, op_ret, op_errno, entries, xdata);
-out:
- gf_quiesce_local_wipe (this, local);
-
- return 0;
-}
-
-
-#if 0
-
-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)
-{
- 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_writev_stub (frame, default_writev_resume,
- local->fd, local->vector, local->flag,
- local->offset, local->io_flags,
- local->iobref, xdata);
- if (!stub) {
- STACK_UNWIND_STRICT (writev, frame, -1, ENOMEM,
- NULL, NULL, NULL);
- goto out;
- }
-
- gf_quiesce_enqueue (this, stub);
- goto out;
- }
-
- STACK_UNWIND_STRICT (writev, frame, op_ret, op_errno, prebuf, postbuf, xdata);
-out:
- gf_quiesce_local_wipe (this, local);
-
- return 0;
-}
-
-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)
-{
- 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_xattrop_stub (frame, default_xattrop_resume,
- &local->loc, local->xattrop_flags,
- local->dict, xdata);
- if (!stub) {
- STACK_UNWIND_STRICT (xattrop, frame, -1, ENOMEM,
- NULL, NULL);
- goto out;
- }
-
- gf_quiesce_enqueue (this, stub);
- goto out;
- }
-
- STACK_UNWIND_STRICT (xattrop, frame, op_ret, op_errno, dict, xdata);
-out:
- gf_quiesce_local_wipe (this, local);
-
- return 0;
-}
-
-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)
-{
- 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_fxattrop_stub (frame, default_fxattrop_resume,
- local->fd, local->xattrop_flags,
- local->dict, xdata);
- if (!stub) {
- STACK_UNWIND_STRICT (fxattrop, frame, -1, ENOMEM,
- NULL, NULL);
- goto out;
- }
-
- gf_quiesce_enqueue (this, stub);
- goto out;
- }
-
- STACK_UNWIND_STRICT (fxattrop, frame, op_ret, op_errno, dict, xdata);
-out:
- gf_quiesce_local_wipe (this, local);
-
- return 0;
-}
-
-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)
-{
- 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_lk_stub (frame, default_lk_resume,
- local->fd, local->flag, &local->flock, xdata);
- if (!stub) {
- STACK_UNWIND_STRICT (lk, frame, -1, ENOMEM,
- NULL, NULL);
- goto out;
- }
-
- gf_quiesce_enqueue (this, stub);
- goto out;
- }
-
- STACK_UNWIND_STRICT (lk, frame, op_ret, op_errno, lock, xdata);
-out:
- gf_quiesce_local_wipe (this, local);
-
- return 0;
-}
-
-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)
-{
- 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_inodelk_stub (frame, default_inodelk_resume,
- local->volname, &local->loc,
- local->flag, &local->flock, xdata);
- if (!stub) {
- STACK_UNWIND_STRICT (inodelk, frame, -1, ENOMEM, NULL);
- goto out;
- }
-
- gf_quiesce_enqueue (this, stub);
- goto out;
- }
-
- STACK_UNWIND_STRICT (inodelk, frame, op_ret, op_errno, xdata);
-out:
- gf_quiesce_local_wipe (this, local);
-
- return 0;
-}
-
-
-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)
-{
- 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_finodelk_stub (frame, default_finodelk_resume,
- local->volname, local->fd,
- local->flag, &local->flock, xdata);
- if (!stub) {
- STACK_UNWIND_STRICT (finodelk, frame, -1, ENOMEM, NULL);
- goto out;
- }
-
- gf_quiesce_enqueue (this, stub);
- goto out;
- }
-
- STACK_UNWIND_STRICT (finodelk, frame, op_ret, op_errno, xdata);
-out:
- gf_quiesce_local_wipe (this, local);
-
- return 0;
-}
-
-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)
-{
- 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_entrylk_stub (frame, default_entrylk_resume,
- local->volname, &local->loc,
- local->name, local->cmd, local->type, xdata);
- if (!stub) {
- STACK_UNWIND_STRICT (entrylk, frame, -1, ENOMEM, NULL);
- goto out;
- }
-
- gf_quiesce_enqueue (this, stub);
- goto out;
- }
-
- STACK_UNWIND_STRICT (entrylk, frame, op_ret, op_errno, xdata);
-out:
- gf_quiesce_local_wipe (this, local);
-
- return 0;
-}
-
-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)
-{
- 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_fentrylk_stub (frame, default_fentrylk_resume,
- local->volname, local->fd,
- local->name, local->cmd, local->type, xdata);
- if (!stub) {
- STACK_UNWIND_STRICT (fentrylk, frame, -1, ENOMEM, NULL);
- goto out;
- }
-
- gf_quiesce_enqueue (this, stub);
- goto out;
- }
-
- STACK_UNWIND_STRICT (fentrylk, frame, op_ret, op_errno, xdata);
-out:
- gf_quiesce_local_wipe (this, local);
-
- return 0;
-}
-
-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)
-{
- 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_setattr_stub (frame, default_setattr_resume,
- &local->loc, &local->stbuf, local->flag, xdata);
- if (!stub) {
- STACK_UNWIND_STRICT (setattr, frame, -1, ENOMEM,
- NULL, NULL, NULL);
- goto out;
- }
-
- gf_quiesce_enqueue (this, stub);
- goto out;
- }
-
- STACK_UNWIND_STRICT (setattr, frame, op_ret, op_errno, statpre,
- statpost, xdata);
-out:
- gf_quiesce_local_wipe (this, local);
-
- return 0;
-}
-
-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)
-{
- 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_fsetattr_stub (frame, default_fsetattr_resume,
- local->fd, &local->stbuf, local->flag, xdata);
- if (!stub) {
- STACK_UNWIND_STRICT (fsetattr, frame, -1, ENOMEM,
- NULL, NULL, NULL);
- goto out;
- }
-
- gf_quiesce_enqueue (this, stub);
- goto out;
- }
-
- STACK_UNWIND_STRICT (fsetattr, frame, op_ret, op_errno, statpre,
- statpost, xdata);
-out:
- gf_quiesce_local_wipe (this, local);
-
- return 0;
-}
-
-#endif /* if 0 */
-
-
-/* FOP */
-
-/* No retransmittion */
-
-int32_t
-quiesce_removexattr (call_frame_t *frame,
- xlator_t *this,
- loc_t *loc,
- const char *name, dict_t *xdata)
-{
- quiesce_priv_t *priv = NULL;
- call_stub_t *stub = NULL;
-
- priv = this->private;
-
- if (priv->pass_through) {
- STACK_WIND (frame,
- default_removexattr_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->removexattr,
- loc,
- name, xdata);
- return 0;
- }
-
- stub = fop_removexattr_stub (frame, default_removexattr_resume,
- loc, name, xdata);
- if (!stub) {
- STACK_UNWIND_STRICT (removexattr, frame, -1, ENOMEM, NULL);
- return 0;
- }
-
- gf_quiesce_enqueue (this, stub);
-
- return 0;
-}
-
-int32_t
-quiesce_truncate (call_frame_t *frame,
- xlator_t *this,
- loc_t *loc,
- off_t offset, dict_t *xdata)
-{
- quiesce_priv_t *priv = NULL;
- call_stub_t *stub = NULL;
-
- priv = this->private;
-
- if (priv->pass_through) {
- STACK_WIND (frame,
- default_truncate_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->truncate,
- loc,
- offset, xdata);
- return 0;
- }
-
- stub = fop_truncate_stub (frame, default_truncate_resume, loc, offset, xdata);
- if (!stub) {
- STACK_UNWIND_STRICT (truncate, frame, -1, ENOMEM, NULL, NULL, NULL);
- return 0;
- }
-
- gf_quiesce_enqueue (this, stub);
-
- return 0;
-}
-
-int32_t
-quiesce_fsetxattr (call_frame_t *frame,
- xlator_t *this,
- fd_t *fd,
- dict_t *dict,
- int32_t flags, dict_t *xdata)
-{
- quiesce_priv_t *priv = NULL;
- call_stub_t *stub = NULL;
-
- priv = this->private;
-
- if (priv->pass_through) {
- STACK_WIND (frame,
- default_fsetxattr_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fsetxattr,
- fd,
- dict,
- flags, xdata);
- return 0;
- }
-
- stub = fop_fsetxattr_stub (frame, default_fsetxattr_resume,
- fd, dict, flags, xdata);
- if (!stub) {
- STACK_UNWIND_STRICT (fsetxattr, frame, -1, ENOMEM, NULL);
- return 0;
- }
-
- gf_quiesce_enqueue (this, stub);
-
- return 0;
-}
-
-int32_t
-quiesce_setxattr (call_frame_t *frame,
- xlator_t *this,
- loc_t *loc,
- dict_t *dict,
- int32_t flags, dict_t *xdata)
-{
- quiesce_priv_t *priv = NULL;
- call_stub_t *stub = NULL;
-
- priv = this->private;
-
- if (priv->pass_through) {
- STACK_WIND (frame,
- default_setxattr_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->setxattr,
- loc,
- dict,
- flags, xdata);
- return 0;
- }
-
- stub = fop_setxattr_stub (frame, default_setxattr_resume,
- loc, dict, flags, xdata);
- if (!stub) {
- STACK_UNWIND_STRICT (setxattr, frame, -1, ENOMEM, NULL);
- return 0;
- }
-
- gf_quiesce_enqueue (this, stub);
-
- return 0;
-}
-
-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)
-{
- quiesce_priv_t *priv = NULL;
- call_stub_t *stub = NULL;
-
- priv = this->private;
-
- if (priv->pass_through) {
- /* Don't send O_APPEND below, as write() re-transmittions can
- fail with O_APPEND */
- STACK_WIND (frame, default_create_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->create,
- loc, (flags & ~O_APPEND), mode, umask, fd, xdata);
- return 0;
- }
-
- stub = fop_create_stub (frame, default_create_resume,
- loc, (flags & ~O_APPEND), mode, umask, fd, xdata);
- if (!stub) {
- STACK_UNWIND_STRICT (create, frame, -1, ENOMEM,
- NULL, NULL, NULL, NULL, NULL, NULL);
- return 0;
- }
-
- gf_quiesce_enqueue (this, stub);
-
- return 0;
-}
-
-int32_t
-quiesce_link (call_frame_t *frame,
- xlator_t *this,
- loc_t *oldloc,
- loc_t *newloc, dict_t *xdata)
-{
- quiesce_priv_t *priv = NULL;
- call_stub_t *stub = NULL;
-
- priv = this->private;
-
- if (priv->pass_through) {
- STACK_WIND (frame,
- default_link_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->link,
- oldloc, newloc, xdata);
- return 0;
- }
-
- stub = fop_link_stub (frame, default_link_resume, oldloc, newloc, xdata);
- if (!stub) {
- STACK_UNWIND_STRICT (link, frame, -1, ENOMEM,
- NULL, NULL, NULL, NULL, NULL);
- return 0;
- }
-
- gf_quiesce_enqueue (this, stub);
-
- return 0;
-}
-
-int32_t
-quiesce_rename (call_frame_t *frame,
- xlator_t *this,
- loc_t *oldloc,
- loc_t *newloc, dict_t *xdata)
-{
- quiesce_priv_t *priv = NULL;
- call_stub_t *stub = NULL;
-
- priv = this->private;
-
- if (priv->pass_through) {
- STACK_WIND (frame,
- default_rename_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->rename,
- oldloc, newloc, xdata);
- return 0;
- }
-
- stub = fop_rename_stub (frame, default_rename_resume, oldloc, newloc, xdata);
- if (!stub) {
- STACK_UNWIND_STRICT (rename, frame, -1, ENOMEM,
- NULL, NULL, NULL, NULL, NULL, NULL);
- return 0;
- }
-
- gf_quiesce_enqueue (this, stub);
-
- return 0;
-}
-
-
-int
-quiesce_symlink (call_frame_t *frame, xlator_t *this,
- const char *linkpath, loc_t *loc, mode_t umask, dict_t *xdata)
-{
- quiesce_priv_t *priv = NULL;
- call_stub_t *stub = NULL;
-
- priv = this->private;
-
- if (priv->pass_through) {
- STACK_WIND (frame, default_symlink_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->symlink,
- linkpath, loc, umask, xdata);
- return 0;
- }
-
- stub = fop_symlink_stub (frame, default_symlink_resume,
- linkpath, loc, umask, xdata);
- if (!stub) {
- STACK_UNWIND_STRICT (symlink, frame, -1, ENOMEM,
- NULL, NULL, NULL, NULL, NULL);
- return 0;
- }
-
- gf_quiesce_enqueue (this, stub);
-
- return 0;
-}
-
-
-int
-quiesce_rmdir (call_frame_t *frame, xlator_t *this, loc_t *loc, int flags, dict_t *xdata)
-{
- quiesce_priv_t *priv = NULL;
- call_stub_t *stub = NULL;
-
- priv = this->private;
-
- if (priv->pass_through) {
- STACK_WIND (frame, default_rmdir_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->rmdir,
- loc, flags, xdata);
- return 0;
- }
-
- stub = fop_rmdir_stub (frame, default_rmdir_resume, loc, flags, xdata);
- if (!stub) {
- STACK_UNWIND_STRICT (rmdir, frame, -1, ENOMEM, NULL, NULL, NULL);
- return 0;
- }
-
- gf_quiesce_enqueue (this, stub);
-
- return 0;
-}
-
-int32_t
-quiesce_unlink (call_frame_t *frame,
- xlator_t *this,
- loc_t *loc, int xflag, dict_t *xdata)
-{
- quiesce_priv_t *priv = NULL;
- call_stub_t *stub = NULL;
-
- priv = this->private;
-
- if (priv->pass_through) {
- STACK_WIND (frame,
- default_unlink_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->unlink,
- loc, xflag, xdata);
- return 0;
- }
-
- stub = fop_unlink_stub (frame, default_unlink_resume, loc, xflag, xdata);
- if (!stub) {
- STACK_UNWIND_STRICT (unlink, frame, -1, ENOMEM, NULL, NULL, NULL);
- return 0;
- }
-
- gf_quiesce_enqueue (this, stub);
-
- return 0;
-}
-
-int
-quiesce_mkdir (call_frame_t *frame, xlator_t *this,
- loc_t *loc, mode_t mode, mode_t umask, dict_t *xdata)
-{
- quiesce_priv_t *priv = NULL;
- call_stub_t *stub = NULL;
-
- priv = this->private;
-
- if (priv->pass_through) {
- STACK_WIND (frame, default_mkdir_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->mkdir,
- loc, mode, umask, xdata);
- return 0;
- }
-
- stub = fop_mkdir_stub (frame, default_mkdir_resume,
- loc, mode, umask, xdata);
- if (!stub) {
- STACK_UNWIND_STRICT (mkdir, frame, -1, ENOMEM,
- NULL, NULL, NULL, NULL, NULL);
- return 0;
- }
-
- gf_quiesce_enqueue (this, stub);
-
- return 0;
-}
-
-
-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)
-{
- quiesce_priv_t *priv = NULL;
- call_stub_t *stub = NULL;
-
- priv = this->private;
-
- if (priv->pass_through) {
- STACK_WIND (frame, default_mknod_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->mknod,
- loc, mode, rdev, umask, xdata);
- return 0;
- }
-
- stub = fop_mknod_stub (frame, default_mknod_resume,
- loc, mode, rdev, umask, xdata);
- if (!stub) {
- STACK_UNWIND_STRICT (mknod, frame, -1, ENOMEM,
- NULL, NULL, NULL, NULL, NULL);
- return 0;
- }
-
- gf_quiesce_enqueue (this, stub);
-
- return 0;
-}
-
-int32_t
-quiesce_ftruncate (call_frame_t *frame,
- xlator_t *this,
- fd_t *fd,
- off_t offset, dict_t *xdata)
-{
- quiesce_priv_t *priv = NULL;
- call_stub_t *stub = NULL;
-
- priv = this->private;
-
- if (priv->pass_through) {
- STACK_WIND (frame,
- default_ftruncate_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->ftruncate,
- fd,
- offset, xdata);
- return 0;
- }
-
- stub = fop_ftruncate_stub (frame, default_ftruncate_resume, fd, offset, xdata);
- if (!stub) {
- STACK_UNWIND_STRICT (ftruncate, frame, -1, ENOMEM, NULL, NULL, NULL);
- return 0;
- }
-
- gf_quiesce_enqueue (this, stub);
-
- return 0;
-}
-
-/* Re-transmittion */
-
-int32_t
-quiesce_readlink (call_frame_t *frame,
- xlator_t *this,
- loc_t *loc,
- size_t size, dict_t *xdata)
-{
- quiesce_priv_t *priv = NULL;
- call_stub_t *stub = NULL;
- quiesce_local_t *local = NULL;
-
- priv = this->private;
-
- if (priv && priv->pass_through) {
- local = mem_get0 (priv->local_pool);
- loc_dup (loc, &local->loc);
- local->size = size;
- frame->local = local;
-
- STACK_WIND (frame,
- quiesce_readlink_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->readlink,
- loc,
- size, xdata);
- return 0;
- }
-
- stub = fop_readlink_stub (frame, default_readlink_resume, loc, size, xdata);
- if (!stub) {
- STACK_UNWIND_STRICT (readlink, frame, -1, ENOMEM, NULL, NULL, NULL);
- return 0;
- }
-
- gf_quiesce_enqueue (this, stub);
-
- return 0;
-}
-
-
-int32_t
-quiesce_access (call_frame_t *frame,
- xlator_t *this,
- loc_t *loc,
- int32_t mask, dict_t *xdata)
-{
- quiesce_priv_t *priv = NULL;
- call_stub_t *stub = NULL;
- quiesce_local_t *local = NULL;
-
- priv = this->private;
-
- if (priv && priv->pass_through) {
- local = mem_get0 (priv->local_pool);
- loc_dup (loc, &local->loc);
- local->flag = mask;
- frame->local = local;
-
- STACK_WIND (frame,
- quiesce_access_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->access,
- loc,
- mask, xdata);
- return 0;
- }
-
- stub = fop_access_stub (frame, default_access_resume, loc, mask, xdata);
- if (!stub) {
- STACK_UNWIND_STRICT (access, frame, -1, ENOMEM, NULL);
- return 0;
- }
-
- gf_quiesce_enqueue (this, stub);
-
- return 0;
-}
-
-int32_t
-quiesce_fgetxattr (call_frame_t *frame,
- xlator_t *this,
- fd_t *fd,
- const char *name, dict_t *xdata)
-{
- quiesce_priv_t *priv = NULL;
- call_stub_t *stub = NULL;
- quiesce_local_t *local = NULL;
-
- priv = this->private;
-
- if (priv && priv->pass_through) {
- local = mem_get0 (priv->local_pool);
- local->fd = fd_ref (fd);
- if (name)
- local->name = gf_strdup (name);
-
- frame->local = local;
-
- STACK_WIND (frame,
- quiesce_fgetxattr_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fgetxattr,
- fd,
- name, xdata);
- return 0;
- }
-
- stub = fop_fgetxattr_stub (frame, default_fgetxattr_resume, fd, name, xdata);
- if (!stub) {
- STACK_UNWIND_STRICT (fgetxattr, frame, -1, ENOMEM, NULL, NULL);
- return 0;
- }
-
- gf_quiesce_enqueue (this, stub);
-
- return 0;
-}
-
-int32_t
-quiesce_statfs (call_frame_t *frame,
- xlator_t *this,
- loc_t *loc, dict_t *xdata)
-{
- quiesce_priv_t *priv = NULL;
- call_stub_t *stub = NULL;
- quiesce_local_t *local = NULL;
-
- priv = this->private;
-
- if (priv && priv->pass_through) {
- local = mem_get0 (priv->local_pool);
- loc_dup (loc, &local->loc);
- frame->local = local;
-
- STACK_WIND (frame,
- quiesce_statfs_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->statfs,
- loc, xdata);
- return 0;
- }
-
- stub = fop_statfs_stub (frame, default_statfs_resume, loc, xdata);
- if (!stub) {
- STACK_UNWIND_STRICT (statfs, frame, -1, ENOMEM, NULL, NULL);
- return 0;
- }
-
- gf_quiesce_enqueue (this, stub);
-
- return 0;
-}
-
-int32_t
-quiesce_fsyncdir (call_frame_t *frame,
- xlator_t *this,
- fd_t *fd,
- int32_t flags, dict_t *xdata)
-{
- quiesce_priv_t *priv = NULL;
- call_stub_t *stub = NULL;
- quiesce_local_t *local = NULL;
-
- priv = this->private;
-
- if (priv && priv->pass_through) {
- local = mem_get0 (priv->local_pool);
- local->fd = fd_ref (fd);
- local->flag = flags;
- frame->local = local;
-
- STACK_WIND (frame,
- quiesce_fsyncdir_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fsyncdir,
- fd,
- flags, xdata);
- return 0;
- }
-
- stub = fop_fsyncdir_stub (frame, default_fsyncdir_resume, fd, flags, xdata);
- if (!stub) {
- STACK_UNWIND_STRICT (fsyncdir, frame, -1, ENOMEM, NULL);
- return 0;
- }
-
- gf_quiesce_enqueue (this, stub);
-
- return 0;
-}
-
-int32_t
-quiesce_opendir (call_frame_t *frame,
- xlator_t *this,
- loc_t *loc, fd_t *fd, dict_t *xdata)
-{
- quiesce_priv_t *priv = NULL;
- call_stub_t *stub = NULL;
- quiesce_local_t *local = NULL;
-
- priv = this->private;
-
- if (priv && priv->pass_through) {
- local = mem_get0 (priv->local_pool);
- loc_dup (loc, &local->loc);
- local->fd = fd_ref (fd);
- frame->local = local;
-
- STACK_WIND (frame,
- quiesce_opendir_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->opendir,
- loc, fd, xdata);
- return 0;
- }
-
- stub = fop_opendir_stub (frame, default_opendir_resume, loc, fd, xdata);
- if (!stub) {
- STACK_UNWIND_STRICT (opendir, frame, -1, ENOMEM, NULL, NULL);
- return 0;
- }
-
- gf_quiesce_enqueue (this, stub);
-
- return 0;
-}
-
-int32_t
-quiesce_fstat (call_frame_t *frame,
- xlator_t *this,
- fd_t *fd, dict_t *xdata)
-{
- quiesce_priv_t *priv = NULL;
- call_stub_t *stub = NULL;
- quiesce_local_t *local = NULL;
-
- priv = this->private;
-
- if (priv && priv->pass_through) {
- local = mem_get0 (priv->local_pool);
- local->fd = fd_ref (fd);
- frame->local = local;
-
- STACK_WIND (frame,
- quiesce_fstat_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fstat,
- fd, xdata);
- return 0;
- }
-
- stub = fop_fstat_stub (frame, default_fstat_resume, fd, xdata);
- if (!stub) {
- STACK_UNWIND_STRICT (fstat, frame, -1, ENOMEM, NULL, NULL);
- return 0;
- }
-
- gf_quiesce_enqueue (this, stub);
-
- return 0;
-}
-
-int32_t
-quiesce_fsync (call_frame_t *frame,
- xlator_t *this,
- fd_t *fd,
- int32_t flags, dict_t *xdata)
-{
- quiesce_priv_t *priv = NULL;
- call_stub_t *stub = NULL;
- quiesce_local_t *local = NULL;
-
- priv = this->private;
-
- if (priv && priv->pass_through) {
- local = mem_get0 (priv->local_pool);
- local->fd = fd_ref (fd);
- local->flag = flags;
- frame->local = local;
-
- STACK_WIND (frame,
- quiesce_fsync_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fsync,
- fd,
- flags, xdata);
- return 0;
- }
-
- stub = fop_fsync_stub (frame, default_fsync_resume, fd, flags, xdata);
- if (!stub) {
- STACK_UNWIND_STRICT (fsync, frame, -1, ENOMEM, NULL, NULL, NULL);
- return 0;
- }
-
- gf_quiesce_enqueue (this, stub);
-
- return 0;
-}
-
-int32_t
-quiesce_flush (call_frame_t *frame,
- xlator_t *this,
- fd_t *fd, dict_t *xdata)
-{
- quiesce_priv_t *priv = NULL;
- call_stub_t *stub = NULL;
- quiesce_local_t *local = NULL;
-
- priv = this->private;
-
- if (priv && priv->pass_through) {
- local = mem_get0 (priv->local_pool);
- local->fd = fd_ref (fd);
- frame->local = local;
-
- STACK_WIND (frame,
- quiesce_flush_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->flush,
- fd, xdata);
- return 0;
- }
-
- stub = fop_flush_stub (frame, default_flush_resume, fd, xdata);
- if (!stub) {
- STACK_UNWIND_STRICT (flush, frame, -1, ENOMEM, NULL);
- return 0;
- }
-
- gf_quiesce_enqueue (this, stub);
-
- return 0;
-}
-
-int32_t
-quiesce_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)
-{
- quiesce_priv_t *priv = NULL;
- call_stub_t *stub = NULL;
-
- priv = this->private;
-
- if (priv && priv->pass_through) {
- STACK_WIND (frame,
- default_writev_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->writev,
- fd,
- vector,
- count,
- off, flags,
- iobref, xdata);
- return 0;
- }
-
- stub = fop_writev_stub (frame, default_writev_resume,
- fd, vector, count, off, flags, iobref, xdata);
- if (!stub) {
- STACK_UNWIND_STRICT (writev, frame, -1, ENOMEM, NULL, NULL, NULL);
- return 0;
- }
-
- gf_quiesce_enqueue (this, stub);
-
- return 0;
-}
-
-int32_t
-quiesce_readv (call_frame_t *frame,
- xlator_t *this,
- fd_t *fd,
- size_t size,
- off_t offset, uint32_t flags, dict_t *xdata)
-{
- quiesce_priv_t *priv = NULL;
- call_stub_t *stub = NULL;
- quiesce_local_t *local = NULL;
-
- priv = this->private;
-
- if (priv && priv->pass_through) {
- local = mem_get0 (priv->local_pool);
- local->fd = fd_ref (fd);
- local->size = size;
- local->offset = offset;
- local->io_flag = flags;
- frame->local = local;
-
- STACK_WIND (frame,
- quiesce_readv_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->readv,
- fd,
- size,
- offset, flags, xdata);
- return 0;
- }
-
- stub = fop_readv_stub (frame, default_readv_resume, fd, size, offset,
- flags, xdata);
- if (!stub) {
- STACK_UNWIND_STRICT (readv, frame, -1, ENOMEM,
- NULL, 0, NULL, NULL, NULL);
- return 0;
- }
-
- gf_quiesce_enqueue (this, stub);
-
- return 0;
-}
-
-
-int32_t
-quiesce_open (call_frame_t *frame,
- xlator_t *this,
- loc_t *loc,
- int32_t flags, fd_t *fd,
- dict_t *xdata)
-{
- quiesce_priv_t *priv = NULL;
- call_stub_t *stub = NULL;
- quiesce_local_t *local = NULL;
-
- priv = this->private;
-
- if (priv && priv->pass_through) {
- local = mem_get0 (priv->local_pool);
- loc_dup (loc, &local->loc);
- local->fd = fd_ref (fd);
-
- /* Don't send O_APPEND below, as write() re-transmittions can
- fail with O_APPEND */
- local->flag = (flags & ~O_APPEND);
- 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;
- }
-
- stub = fop_open_stub (frame, default_open_resume, loc,
- (flags & ~O_APPEND), fd, xdata);
- if (!stub) {
- STACK_UNWIND_STRICT (open, frame, -1, ENOMEM, NULL, NULL);
- return 0;
- }
-
- gf_quiesce_enqueue (this, stub);
-
- return 0;
-}
-
-int32_t
-quiesce_getxattr (call_frame_t *frame,
- xlator_t *this,
- loc_t *loc,
- const char *name, dict_t *xdata)
-{
- quiesce_priv_t *priv = NULL;
- call_stub_t *stub = NULL;
- quiesce_local_t *local = NULL;
-
- priv = this->private;
-
- if (priv && priv->pass_through) {
- local = mem_get0 (priv->local_pool);
- loc_dup (loc, &local->loc);
- if (name)
- local->name = gf_strdup (name);
-
- frame->local = local;
-
- STACK_WIND (frame,
- quiesce_getxattr_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->getxattr,
- loc,
- name, xdata);
- return 0;
- }
-
- stub = fop_getxattr_stub (frame, default_getxattr_resume, loc, name, xdata);
- if (!stub) {
- STACK_UNWIND_STRICT (getxattr, frame, -1, ENOMEM, NULL, NULL);
- return 0;
- }
-
- gf_quiesce_enqueue (this, stub);
-
- return 0;
-}
-
-
-int32_t
-quiesce_xattrop (call_frame_t *frame,
- xlator_t *this,
- loc_t *loc,
- gf_xattrop_flags_t flags,
- dict_t *dict, dict_t *xdata)
-{
- quiesce_priv_t *priv = NULL;
- call_stub_t *stub = NULL;
-
- priv = this->private;
-
- if (priv && priv->pass_through) {
- STACK_WIND (frame,
- default_xattrop_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->xattrop,
- loc,
- flags,
- dict, xdata);
- return 0;
- }
-
- stub = fop_xattrop_stub (frame, default_xattrop_resume,
- loc, flags, dict, xdata);
- if (!stub) {
- STACK_UNWIND_STRICT (xattrop, frame, -1, ENOMEM, NULL, NULL);
- return 0;
- }
-
- gf_quiesce_enqueue (this, stub);
-
- return 0;
-}
-
-int32_t
-quiesce_fxattrop (call_frame_t *frame,
- xlator_t *this,
- fd_t *fd,
- gf_xattrop_flags_t flags,
- dict_t *dict, dict_t *xdata)
-{
- quiesce_priv_t *priv = NULL;
- call_stub_t *stub = NULL;
-
- priv = this->private;
-
- if (priv && priv->pass_through) {
- STACK_WIND (frame,
- default_fxattrop_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fxattrop,
- fd,
- flags,
- dict, xdata);
- return 0;
- }
-
- stub = fop_fxattrop_stub (frame, default_fxattrop_resume,
- fd, flags, dict, xdata);
- if (!stub) {
- STACK_UNWIND_STRICT (fxattrop, frame, -1, ENOMEM, NULL, NULL);
- return 0;
- }
-
- gf_quiesce_enqueue (this, stub);
-
- return 0;
-}
-
-int32_t
-quiesce_lk (call_frame_t *frame,
- xlator_t *this,
- fd_t *fd,
- int32_t cmd,
- struct gf_flock *lock, dict_t *xdata)
-{
- quiesce_priv_t *priv = NULL;
- call_stub_t *stub = NULL;
-
- priv = this->private;
-
- if (priv && priv->pass_through) {
- STACK_WIND (frame,
- default_lk_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->lk,
- fd,
- cmd,
- lock, xdata);
- return 0;
- }
-
- stub = fop_lk_stub (frame, default_lk_resume, fd, cmd, lock, xdata);
- if (!stub) {
- STACK_UNWIND_STRICT (lk, frame, -1, ENOMEM, NULL, NULL);
- return 0;
- }
-
- gf_quiesce_enqueue (this, stub);
-
- return 0;
-}
-
-
-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)
-{
- quiesce_priv_t *priv = NULL;
- call_stub_t *stub = NULL;
-
- priv = this->private;
-
- if (priv && priv->pass_through) {
- STACK_WIND (frame,
- default_inodelk_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->inodelk,
- volume, loc, cmd, lock, xdata);
- return 0;
- }
-
- stub = fop_inodelk_stub (frame, default_inodelk_resume,
- volume, loc, cmd, lock, xdata);
- if (!stub) {
- STACK_UNWIND_STRICT (inodelk, frame, -1, ENOMEM, NULL);
- return 0;
- }
-
- gf_quiesce_enqueue (this, stub);
-
- return 0;
-}
-
-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)
-{
- quiesce_priv_t *priv = NULL;
- call_stub_t *stub = NULL;
-
- priv = this->private;
-
- if (priv && priv->pass_through) {
- STACK_WIND (frame,
- default_finodelk_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->finodelk,
- volume, fd, cmd, lock, xdata);
- return 0;
- }
-
- stub = fop_finodelk_stub (frame, default_finodelk_resume,
- volume, fd, cmd, lock, xdata);
- if (!stub) {
- STACK_UNWIND_STRICT (finodelk, frame, -1, ENOMEM, NULL);
- return 0;
- }
-
- gf_quiesce_enqueue (this, stub);
-
- return 0;
-}
-
-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)
-{
- quiesce_priv_t *priv = NULL;
- call_stub_t *stub = NULL;
-
- priv = this->private;
-
- if (priv && priv->pass_through) {
- STACK_WIND (frame, default_entrylk_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->entrylk,
- volume, loc, basename, cmd, type, xdata);
- return 0;
- }
-
- stub = fop_entrylk_stub (frame, default_entrylk_resume,
- volume, loc, basename, cmd, type, xdata);
- if (!stub) {
- STACK_UNWIND_STRICT (entrylk, frame, -1, ENOMEM, NULL);
- return 0;
- }
-
- gf_quiesce_enqueue (this, stub);
-
- return 0;
-}
-
-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)
-{
- quiesce_priv_t *priv = NULL;
- call_stub_t *stub = NULL;
-
- priv = this->private;
-
- if (priv && priv->pass_through) {
- STACK_WIND (frame, default_fentrylk_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fentrylk,
- volume, fd, basename, cmd, type, xdata);
- return 0;
- }
-
- stub = fop_fentrylk_stub (frame, default_fentrylk_resume,
- volume, fd, basename, cmd, type, xdata);
- if (!stub) {
- STACK_UNWIND_STRICT (fentrylk, frame, -1, ENOMEM, NULL);
- return 0;
- }
-
- gf_quiesce_enqueue (this, stub);
-
- return 0;
-}
-
-int32_t
-quiesce_rchecksum (call_frame_t *frame,
- xlator_t *this,
- fd_t *fd, off_t offset,
- int32_t len, dict_t *xdata)
-{
- quiesce_priv_t *priv = NULL;
- call_stub_t *stub = NULL;
- quiesce_local_t *local = NULL;
-
- priv = this->private;
-
- if (priv && priv->pass_through) {
- local = mem_get0 (priv->local_pool);
- local->fd = fd_ref (fd);
- local->offset = offset;
- local->flag = len;
- frame->local = local;
-
- STACK_WIND (frame,
- quiesce_rchecksum_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->rchecksum,
- fd, offset, len, xdata);
- return 0;
- }
-
- stub = fop_rchecksum_stub (frame, default_rchecksum_resume,
- fd, offset, len, xdata);
- if (!stub) {
- STACK_UNWIND_STRICT (rchecksum, frame, -1, ENOMEM, 0, NULL, NULL);
- return 0;
- }
-
- gf_quiesce_enqueue (this, stub);
-
- return 0;
-}
-
-
-int32_t
-quiesce_readdir (call_frame_t *frame,
- xlator_t *this,
- fd_t *fd,
- size_t size,
- off_t off, dict_t *xdata)
-{
- quiesce_priv_t *priv = NULL;
- call_stub_t *stub = NULL;
- quiesce_local_t *local = NULL;
-
- priv = this->private;
-
- if (priv && priv->pass_through) {
- local = mem_get0 (priv->local_pool);
- local->fd = fd_ref (fd);
- local->size = size;
- local->offset = off;
- frame->local = local;
-
- STACK_WIND (frame,
- quiesce_readdir_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->readdir,
- fd, size, off, xdata);
- return 0;
- }
-
- stub = fop_readdir_stub (frame, default_readdir_resume, fd, size, off, xdata);
- if (!stub) {
- STACK_UNWIND_STRICT (readdir, frame, -1, ENOMEM, NULL, NULL);
- return 0;
- }
-
- gf_quiesce_enqueue (this, stub);
-
- return 0;
-}
-
-
-int32_t
-quiesce_readdirp (call_frame_t *frame,
- xlator_t *this,
- fd_t *fd,
- size_t size,
- off_t off, dict_t *dict)
-{
- quiesce_priv_t *priv = NULL;
- call_stub_t *stub = NULL;
- quiesce_local_t *local = NULL;
-
- priv = this->private;
-
- if (priv && priv->pass_through) {
- local = mem_get0 (priv->local_pool);
- 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;
- }
-
- stub = fop_readdirp_stub (frame, default_readdirp_resume, fd, size,
- off, dict);
- if (!stub) {
- STACK_UNWIND_STRICT (readdirp, frame, -1, ENOMEM, NULL, NULL);
- return 0;
- }
-
- gf_quiesce_enqueue (this, stub);
-
- return 0;
-}
-
-int32_t
-quiesce_setattr (call_frame_t *frame,
- xlator_t *this,
- loc_t *loc,
- struct iatt *stbuf,
- int32_t valid, dict_t *xdata)
-{
- quiesce_priv_t *priv = NULL;
- call_stub_t *stub = NULL;
-
- priv = this->private;
-
- if (priv && priv->pass_through) {
- STACK_WIND (frame,
- default_setattr_cbk,
- FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->setattr,
- loc, stbuf, valid, xdata);
- return 0;
- }
-
- stub = fop_setattr_stub (frame, default_setattr_resume,
- loc, stbuf, valid, xdata);
- if (!stub) {
- STACK_UNWIND_STRICT (setattr, frame, -1, ENOMEM, NULL, NULL, NULL);
- return 0;
- }
-
- gf_quiesce_enqueue (this, stub);
-
- return 0;
-}
-
-
-int32_t
-quiesce_stat (call_frame_t *frame,
- xlator_t *this,
- loc_t *loc, dict_t *xdata)
-{
- quiesce_priv_t *priv = NULL;
- call_stub_t *stub = NULL;
- quiesce_local_t *local = NULL;
-
- priv = this->private;
-
- if (priv && priv->pass_through) {
- local = mem_get0 (priv->local_pool);
- loc_dup (loc, &local->loc);
- frame->local = local;
-
- STACK_WIND (frame,
- quiesce_stat_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->stat,
- loc, xdata);
- return 0;
- }
-
- stub = fop_stat_stub (frame, default_stat_resume, loc, xdata);
- if (!stub) {
- STACK_UNWIND_STRICT (stat, frame, -1, ENOMEM, NULL, NULL);
- return 0;
- }
-
- gf_quiesce_enqueue (this, stub);
-
- return 0;
-}
-
-int32_t
-quiesce_lookup (call_frame_t *frame,
- xlator_t *this,
- loc_t *loc,
- dict_t *xattr_req)
-{
- quiesce_priv_t *priv = NULL;
- call_stub_t *stub = NULL;
- quiesce_local_t *local = NULL;
-
- priv = this->private;
-
- if (priv && priv->pass_through) {
- local = mem_get0 (priv->local_pool);
- loc_dup (loc, &local->loc);
- local->dict = dict_ref (xattr_req);
- frame->local = local;
-
- STACK_WIND (frame,
- quiesce_lookup_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->lookup,
- loc, xattr_req);
- return 0;
- }
-
- stub = fop_lookup_stub (frame, default_lookup_resume, loc, xattr_req);
- if (!stub) {
- STACK_UNWIND_STRICT (lookup, frame, -1, ENOMEM,
- NULL, NULL, NULL, NULL);
- return 0;
- }
-
- gf_quiesce_enqueue (this, stub);
-
- return 0;
-}
-
-int32_t
-quiesce_fsetattr (call_frame_t *frame,
- xlator_t *this,
- fd_t *fd,
- struct iatt *stbuf,
- int32_t valid, dict_t *xdata)
-{
- quiesce_priv_t *priv = NULL;
- call_stub_t *stub = NULL;
-
- priv = this->private;
-
- if (priv && priv->pass_through) {
- STACK_WIND (frame,
- default_fsetattr_cbk,
- FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->fsetattr,
- fd, stbuf, valid, xdata);
- return 0;
- }
-
- stub = fop_fsetattr_stub (frame, default_fsetattr_resume,
- fd, stbuf, valid, xdata);
- if (!stub) {
- STACK_UNWIND_STRICT (fsetattr, frame, -1, ENOMEM, NULL, NULL, NULL);
- return 0;
- }
-
- gf_quiesce_enqueue (this, stub);
-
- return 0;
-}
-
-int32_t
-mem_acct_init (xlator_t *this)
-{
- int ret = -1;
-
- ret = xlator_mem_acct_init (this, gf_quiesce_mt_end + 1);
-
- return ret;
-}
-
-int
-init (xlator_t *this)
-{
- int ret = -1;
- quiesce_priv_t *priv = NULL;
-
- if (!this->children || this->children->next) {
- gf_log (this->name, GF_LOG_ERROR,
- "'quiesce' 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_quiesce_mt_priv_t);
- if (!priv)
- goto out;
-
- priv->local_pool = mem_pool_new (quiesce_local_t,
- GF_FOPS_EXPECTED_IN_PARALLEL);
-
- LOCK_INIT (&priv->lock);
- priv->pass_through = _gf_false;
-
- INIT_LIST_HEAD (&priv->req);
-
- this->private = priv;
- ret = 0;
-out:
- return ret;
-}
-
-void
-fini (xlator_t *this)
-{
- quiesce_priv_t *priv = NULL;
-
- priv = this->private;
- if (!priv)
- goto out;
- this->private = NULL;
-
- mem_pool_destroy (priv->local_pool);
- LOCK_DESTROY (&priv->lock);
- GF_FREE (priv);
-out:
- return;
-}
-
-int
-notify (xlator_t *this, int event, void *data, ...)
-{
- int ret = 0;
- quiesce_priv_t *priv = NULL;
- struct timespec timeout = {0,};
-
- priv = this->private;
- if (!priv)
- goto out;
-
- switch (event) {
- case GF_EVENT_CHILD_UP:
- {
- ret = pthread_create (&priv->thr, NULL, gf_quiesce_dequeue_start,
- this);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "failed to create the quiesce-dequeue thread");
- }
-
- LOCK (&priv->lock);
- {
- priv->pass_through = _gf_true;
- }
- UNLOCK (&priv->lock);
- break;
- }
- case GF_EVENT_CHILD_DOWN:
- LOCK (&priv->lock);
- {
- priv->pass_through = _gf_false;
- }
- UNLOCK (&priv->lock);
-
- if (priv->timer)
- break;
- timeout.tv_sec = 20;
- timeout.tv_nsec = 0;
-
- priv->timer = gf_timer_call_after (this->ctx,
- timeout,
- gf_quiesce_timeout,
- (void *) this);
-
- if (priv->timer == NULL) {
- gf_log (this->name, GF_LOG_ERROR,
- "Cannot create timer");
- }
-
- break;
- default:
- break;
- }
-
- ret = default_notify (this, event, data);
-out:
- return ret;
-}
-
-
-struct xlator_fops fops = {
- /* write/modifying fops */
- .mknod = quiesce_mknod,
- .create = quiesce_create,
- .truncate = quiesce_truncate,
- .ftruncate = quiesce_ftruncate,
- .setxattr = quiesce_setxattr,
- .removexattr = quiesce_removexattr,
- .symlink = quiesce_symlink,
- .unlink = quiesce_unlink,
- .link = quiesce_link,
- .mkdir = quiesce_mkdir,
- .rmdir = quiesce_rmdir,
- .rename = quiesce_rename,
-
- /* The below calls are known to change state, hence
- re-transmittion is not advised */
- .lk = quiesce_lk,
- .inodelk = quiesce_inodelk,
- .finodelk = quiesce_finodelk,
- .entrylk = quiesce_entrylk,
- .fentrylk = quiesce_fentrylk,
- .xattrop = quiesce_xattrop,
- .fxattrop = quiesce_fxattrop,
- .setattr = quiesce_setattr,
- .fsetattr = quiesce_fsetattr,
-
- /* Special case, re-transmittion is not harmful *
- * as offset is properly sent from above layers */
- /* TODO: not re-transmitted as of now */
- .writev = quiesce_writev,
-
- /* re-transmittable fops */
- .lookup = quiesce_lookup,
- .stat = quiesce_stat,
- .fstat = quiesce_fstat,
- .access = quiesce_access,
- .readlink = quiesce_readlink,
- .getxattr = quiesce_getxattr,
- .open = quiesce_open,
- .readv = quiesce_readv,
- .flush = quiesce_flush,
- .fsync = quiesce_fsync,
- .statfs = quiesce_statfs,
- .opendir = quiesce_opendir,
- .readdir = quiesce_readdir,
- .readdirp = quiesce_readdirp,
- .fsyncdir = quiesce_fsyncdir,
-
-};
-
-struct xlator_dumpops dumpops;
-
-
-struct xlator_cbks cbks;
-
-
-struct volume_options options[] = {
- { .key = {NULL} },
-};
diff --git a/xlators/features/quiesce/src/quiesce.h b/xlators/features/quiesce/src/quiesce.h
deleted file mode 100644
index 878ed77e928..00000000000
--- a/xlators/features/quiesce/src/quiesce.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- Copyright (c) 2010-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 __QUIESCE_H__
-#define __QUIESCE_H__
-
-#include "quiesce-mem-types.h"
-#include "xlator.h"
-#include "timer.h"
-
-#define GF_FOPS_EXPECTED_IN_PARALLEL 512
-
-typedef struct {
- gf_timer_t *timer;
- gf_boolean_t pass_through;
- gf_lock_t lock;
- struct list_head req;
- int queue_size;
- pthread_t thr;
- struct mem_pool *local_pool;
-} quiesce_priv_t;
-
-typedef struct {
- fd_t *fd;
- char *name;
- char *volname;
- loc_t loc;
- off_t size;
- off_t offset;
- mode_t mode;
- int32_t flag;
- struct iatt stbuf;
- struct iovec *vector;
- struct iobref *iobref;
- dict_t *dict;
- struct gf_flock flock;
- entrylk_cmd cmd;
- 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/Makefile.am b/xlators/features/quota/src/Makefile.am
index 7165adc59ef..886d839643c 100644
--- a/xlators/features/quota/src/Makefile.am
+++ b/xlators/features/quota/src/Makefile.am
@@ -1,22 +1,13 @@
-xlator_LTLIBRARIES = quota.la quotad.la
+xlator_LTLIBRARIES = quota.la
xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/features
-quota_la_LDFLAGS = -module -avoid-version
-quotad_la_LDFLAGS = -module -avoid-version
+quota_la_LDFLAGS = -module -avoidversion
-quota_la_SOURCES = quota.c quota-enforcer-client.c
-quota_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la
+quota_la_SOURCES = quota.c
+quota_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la
-quotad_la_SOURCES = quotad.c quotad-helpers.c quotad-aggregator.c
-quotad_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)
-noinst_HEADERS = quota-mem-types.h quota.h quotad-aggregator.h quotad-helpers.h
-
-AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \
- -I$(top_srcdir)/xlators/cluster/dht/src -I$(top_srcdir)/rpc/xdr/src/ \
- -I$(top_srcdir)/rpc/rpc-lib/src
-
-AM_CFLAGS = -Wall $(GF_CFLAGS)
-
-CLEANFILES =
+CLEANFILES =
diff --git a/xlators/features/quota/src/quota-enforcer-client.c b/xlators/features/quota/src/quota-enforcer-client.c
deleted file mode 100644
index a52180936e3..00000000000
--- a/xlators/features/quota/src/quota-enforcer-client.c
+++ /dev/null
@@ -1,405 +0,0 @@
-/*
- Copyright (c) 2010-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 <stdio.h>
-#include <string.h>
-#include <netinet/in.h>
-#include <sys/socket.h>
-#include <sys/types.h>
-#include <sys/resource.h>
-#include <sys/file.h>
-#include <netdb.h>
-#include <signal.h>
-#include <libgen.h>
-
-#include <sys/utsname.h>
-
-#include <stdint.h>
-#include <pthread.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <time.h>
-#include <semaphore.h>
-#include <errno.h>
-
-#ifndef _CONFIG_H
-#define _CONFIG_H
-#include "config.h"
-#endif
-
-#ifdef HAVE_MALLOC_H
-#include <malloc.h>
-#endif
-
-#ifdef HAVE_MALLOC_STATS
-#ifdef DEBUG
-#include <mcheck.h>
-#endif
-#endif
-
-#include "quota.h"
-
-extern struct rpc_clnt_program quota_enforcer_clnt;
-
-int32_t
-quota_validate_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);
-
-int
-quota_enforcer_submit_request (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)
-{
- int ret = -1;
- int count = 0;
- struct iovec iov = {0, };
- struct iobuf *iobuf = NULL;
- char new_iobref = 0;
- ssize_t xdr_size = 0;
- quota_priv_t *priv = NULL;
-
- GF_ASSERT (this);
-
- priv = this->private;
-
- if (req) {
- xdr_size = xdr_sizeof (xdrproc, req);
- iobuf = iobuf_get2 (this->ctx->iobuf_pool, xdr_size);
- if (!iobuf) {
- goto out;
- }
-
- if (!iobref) {
- iobref = iobref_new ();
- if (!iobref) {
- goto out;
- }
-
- new_iobref = 1;
- }
-
- iobref_add (iobref, iobuf);
-
- 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) {
- goto out;
- }
- iov.iov_len = ret;
- count = 1;
- }
-
- /* Send the msg */
- ret = rpc_clnt_submit (priv->rpc_clnt, prog, procnum, cbkfn,
- &iov, count,
- NULL, 0, iobref, frame, NULL, 0, NULL, 0, NULL);
- ret = 0;
-
-out:
- if (new_iobref)
- iobref_unref (iobref);
- if (iobuf)
- iobuf_unref (iobuf);
-
- return ret;
-}
-
-int
-quota_enforcer_lookup_cbk (struct rpc_req *req, struct iovec *iov,
- int count, void *myframe)
-{
- quota_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->validate_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->validate_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->validate_loc.path,
- loc_gfid_utoa (&local->validate_loc));
- else
- gf_log (this->name, GF_LOG_TRACE,
- "not found on remote node");
-
- }
-
- local->validate_cbk (frame, NULL, this, rsp.op_ret, rsp.op_errno, inode,
- &stbuf, xdata, &postparent);
-
- if (xdata)
- dict_unref (xdata);
-
- free (rsp.xdata.xdata_val);
-
- return 0;
-}
-
-int
-quota_enforcer_lookup (call_frame_t *frame, xlator_t *this, loc_t *loc,
- dict_t *xdata, fop_lookup_cbk_t validate_cbk)
-{
- quota_local_t *local = NULL;
- gfs3_lookup_req req = {{0,},};
- int ret = 0;
- int op_errno = ESTALE;
- quota_priv_t *priv = NULL;
-
- if (!frame || !this || !loc)
- goto unwind;
-
- local = frame->local;
- local->validate_cbk = validate_cbk;
-
- priv = this->private;
-
- if (!(loc && loc->inode))
- goto unwind;
-
- if (!uuid_is_null (loc->inode->gfid))
- memcpy (req.gfid, loc->inode->gfid, 16);
- else
- memcpy (req.gfid, loc->gfid, 16);
-
- if (xdata) {
- GF_PROTOCOL_DICT_SERIALIZE (this, xdata,
- (&req.xdata.xdata_val),
- req.xdata.xdata_len,
- op_errno, unwind);
- }
-
- if (loc->name)
- req.bname = (char *)loc->name;
- else
- req.bname = "";
-
- ret = quota_enforcer_submit_request (&req, frame,
- priv->quota_enforcer,
- GF_AGGREGATOR_LOOKUP,
- NULL, this,
- quota_enforcer_lookup_cbk,
- (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);
-
- return 0;
-
-unwind:
- validate_cbk (frame, NULL, this, -1, op_errno, NULL, NULL, NULL, NULL);
-
- GF_FREE (req.xdata.xdata_val);
-
- return 0;
-}
-
-int
-quota_enforcer_notify (struct rpc_clnt *rpc, void *mydata,
- rpc_clnt_event_t event, void *data)
-{
- xlator_t *this = NULL;
- int ret = 0;
-
- this = mydata;
-
- switch (event) {
- case RPC_CLNT_CONNECT:
- {
- gf_log (this->name, GF_LOG_TRACE, "got RPC_CLNT_CONNECT");
- break;
- }
-
- case RPC_CLNT_DISCONNECT:
- {
- gf_log (this->name, GF_LOG_TRACE, "got RPC_CLNT_DISCONNECT");
- break;
- }
-
- default:
- gf_log (this->name, GF_LOG_TRACE,
- "got some other RPC event %d", event);
- ret = 0;
- break;
- }
-
- return ret;
-}
-
-int
-quota_enforcer_blocking_connect (rpc_clnt_t *rpc)
-{
- dict_t *options = NULL;
- int ret = -1;
-
- options = dict_new ();
- if (options == NULL)
- goto out;
-
- ret = dict_set_str (options, "non-blocking-io", "no");
- if (ret)
- goto out;
-
- rpc->conn.trans->reconfigure (rpc->conn.trans, options);
-
- rpc_clnt_start (rpc);
-
- ret = dict_set_str (options, "non-blocking-io", "yes");
- if (ret)
- goto out;
-
- rpc->conn.trans->reconfigure (rpc->conn.trans, options);
-
- ret = 0;
-out:
- dict_unref (options);
-
- return ret;
-}
-
-//Returns a started rpc_clnt. Creates a new rpc_clnt if quota_priv doesn't have
-//one already
-struct rpc_clnt *
-quota_enforcer_init (xlator_t *this, dict_t *options)
-{
- struct rpc_clnt *rpc = NULL;
- quota_priv_t *priv = NULL;
- int ret = -1;
-
- priv = this->private;
-
- LOCK (&priv->lock);
- {
- if (priv->rpc_clnt) {
- ret = 0;
- rpc = priv->rpc_clnt;
- }
- }
- UNLOCK (&priv->lock);
-
- if (rpc)
- goto out;
-
- priv->quota_enforcer = &quota_enforcer_clnt;
-
- ret = dict_set_str (options, "transport.address-family", "unix");
- if (ret)
- goto out;
-
- ret = dict_set_str (options, "transport-type", "socket");
- if (ret)
- goto out;
-
- ret = dict_set_str (options, "transport.socket.connect-path",
- "/tmp/quotad.socket");
- if (ret)
- goto out;
-
- rpc = rpc_clnt_new (options, this->ctx, this->name, 16);
- if (!rpc) {
- ret = -1;
- goto out;
- }
-
- ret = rpc_clnt_register_notify (rpc, quota_enforcer_notify, this);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "failed to register notify");
- goto out;
- }
-
- ret = quota_enforcer_blocking_connect (rpc);
- if (ret)
- goto out;
-
- ret = 0;
-out:
- if (ret) {
- if (rpc)
- rpc_clnt_unref (rpc);
- rpc = NULL;
- }
-
- return rpc;
-}
-
-struct rpc_clnt_procedure quota_enforcer_actors[GF_AGGREGATOR_MAXVALUE] = {
- [GF_AGGREGATOR_NULL] = {"NULL", NULL},
- [GF_AGGREGATOR_LOOKUP] = {"LOOKUP", NULL},
-};
-
-struct rpc_clnt_program quota_enforcer_clnt = {
- .progname = "Quota enforcer",
- .prognum = GLUSTER_AGGREGATOR_PROGRAM,
- .progver = GLUSTER_AGGREGATOR_VERSION,
- .numproc = GF_AGGREGATOR_MAXVALUE,
- .proctable = quota_enforcer_actors,
-};
diff --git a/xlators/features/quota/src/quota-mem-types.h b/xlators/features/quota/src/quota-mem-types.h
deleted file mode 100644
index 97d9165681f..00000000000
--- a/xlators/features/quota/src/quota-mem-types.h
+++ /dev/null
@@ -1,30 +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 __QUOTA_MEM_TYPES_H__
-#define __QUOTA_MEM_TYPES_H__
-
-#include "mem-types.h"
-
-enum gf_quota_mem_types_ {
- gf_quota_mt_quota_priv_t = gf_common_mt_end + 1,
- gf_quota_mt_quota_inode_ctx_t,
- gf_quota_mt_loc_t,
- gf_quota_mt_char,
- gf_quota_mt_int64_t,
- gf_quota_mt_int32_t,
- gf_quota_mt_limits_t,
- gf_quota_mt_quota_dentry_t,
- gf_quota_mt_quota_limits_level_t,
- gf_quota_mt_qd_vols_conf_t,
- gf_quota_mt_aggregator_state_t,
- gf_quota_mt_end
-};
-#endif
-
diff --git a/xlators/features/quota/src/quota.c b/xlators/features/quota/src/quota.c
index dd3e8e2b624..a5c3188ac15 100644
--- a/xlators/features/quota/src/quota.c
+++ b/xlators/features/quota/src/quota.c
@@ -1,4627 +1,1080 @@
/*
- 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-2009 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 <fnmatch.h>
-
-#include "quota.h"
-#include "common-utils.h"
-#include "defaults.h"
-#include "statedump.h"
-
-void
-quota_get_limit_dir (call_frame_t *frame, inode_t *cur_inode, xlator_t *this);
-
-int32_t
-quota_check_limit (call_frame_t *frame, inode_t *inode, xlator_t *this,
- char *name, uuid_t par);
-
-int
-quota_fill_inodectx (xlator_t *this, inode_t *inode, dict_t *dict,
- loc_t *loc, struct iatt *buf, int32_t *op_errno);
-
-struct volume_options options[];
-
-static int32_t
-__quota_init_inode_ctx (inode_t *inode, xlator_t *this,
- quota_inode_ctx_t **context)
-{
- int32_t ret = -1;
- quota_inode_ctx_t *ctx = NULL;
-
- if (inode == NULL) {
- goto out;
- }
-
- QUOTA_ALLOC_OR_GOTO (ctx, quota_inode_ctx_t, out);
-
- LOCK_INIT(&ctx->lock);
-
- if (context != NULL) {
- *context = ctx;
- }
- INIT_LIST_HEAD (&ctx->parents);
+#ifndef _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
- 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));
- }
-out:
- return ret;
-}
-
-
-static int32_t
-quota_inode_ctx_get (inode_t *inode, xlator_t *this,
- quota_inode_ctx_t **ctx, char create_if_absent)
-{
- int32_t ret = 0;
- uint64_t ctx_int;
+#include <sys/time.h>
- LOCK (&inode->lock);
- {
- ret = __inode_ctx_get (inode, this, &ctx_int);
-
- if ((ret == 0) && (ctx != NULL)) {
- *ctx = (quota_inode_ctx_t *) (unsigned long)ctx_int;
- } else if (create_if_absent) {
- ret = __quota_init_inode_ctx (inode, this, ctx);
- }
- }
- UNLOCK (&inode->lock);
-
- return ret;
-}
-
-int
-quota_loc_fill (loc_t *loc, inode_t *inode, inode_t *parent, char *path)
-{
- int ret = -1;
-
- if (!loc || (inode == NULL))
- return ret;
-
- if (inode) {
- loc->inode = inode_ref (inode);
- uuid_copy (loc->gfid, inode->gfid);
- }
+#include "xlator.h"
+#include "defaults.h"
+#include "common-utils.h"
- if (parent) {
- loc->parent = inode_ref (parent);
- }
+#ifndef MAX_IOVEC
+#define MAX_IOVEC 16
+#endif
+
+#define GF_DISK_USAGE_STATBUF(blocks) (blocks * 512)
+#define GF_DISK_FILE_USAGE(preblocks,postblocks) ((postblocks - preblocks) * 512)
+#define GF_DISK_DIRECTORY_USAGE(preblocks,postblocks) ((postblocks - preblocks) * 512)
+
+struct quota_local {
+ struct stat stbuf;
+ inode_t *inode;
+ char *path;
+ fd_t *fd;
+ off_t offset;
+ int32_t count;
+ struct iovec vector[MAX_IOVEC];
+ struct iobref *iobref;
+ loc_t loc;
+};
- if (path != NULL) {
- loc->path = gf_strdup (path);
- loc->name = strrchr (loc->path, '/');
- if (loc->name) {
- loc->name++;
- }
- }
+struct quota_priv {
+ char only_first_time; /* Used to make sure a call is done only one time */
+ gf_lock_t lock; /* Used while updating variables */
- ret = 0;
+ uint64_t disk_usage_limit; /* Used for Disk usage quota */
+ uint64_t current_disk_usage; /* Keep the current usage value */
- if (ret < 0) {
- loc_wipe (loc);
- }
+ uint32_t min_free_disk_limit; /* user specified limit, in %*/
+ uint32_t current_free_disk; /* current free disk space available, in % */
+ uint32_t refresh_interval; /* interval in seconds */
+ uint32_t min_disk_last_updated_time; /* used for interval calculation */
- return ret;
-}
+ loc_t root_loc; /* Store '/' loc_t to make xattr calls */
+};
int
-quota_inode_loc_fill (inode_t *inode, loc_t *loc)
-{
- char *resolvedpath = NULL;
- inode_t *parent = NULL;
- int ret = -1;
- xlator_t *this = NULL;
-
- if ((!inode) || (!loc)) {
- return ret;
- }
-
- this = THIS;
-
- if ((inode) && __is_root_gfid (inode->gfid)) {
- 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)",
- uuid_utoa (inode->gfid));
- }
-
-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)",
- uuid_utoa (inode->gfid));
- }
-
- ret = quota_loc_fill (loc, inode, parent, resolvedpath);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_WARNING, "cannot fill loc");
- goto err;
- }
-
-err:
- if (parent) {
- inode_unref (parent);
- }
-
- GF_FREE (resolvedpath);
-
- return ret;
-}
-
-
-int32_t
-quota_local_cleanup (xlator_t *this, quota_local_t *local)
-{
- if (local == NULL) {
- goto out;
- }
-
- loc_wipe (&local->loc);
- loc_wipe (&local->newloc);
- loc_wipe (&local->oldloc);
- loc_wipe (&local->validate_loc);
-
- inode_unref (local->inode);
-
- if (local->xdata)
- dict_unref (local->xdata);
-
- LOCK_DESTROY (&local->lock);
-
- mem_put (local);
-out:
- return 0;
-}
-
-
-static inline quota_local_t *
-quota_local_new ()
-{
- quota_local_t *local = NULL;
- local = mem_get0 (THIS->local_pool);
- if (local == NULL)
- goto out;
-
- LOCK_INIT (&local->lock);
- local->space_available = -1;
-
-out:
- return local;
-}
-
-
-quota_dentry_t *
-__quota_dentry_new (quota_inode_ctx_t *ctx, char *name, uuid_t par)
-{
- quota_dentry_t *dentry = NULL;
- GF_UNUSED int32_t ret = 0;
-
- QUOTA_ALLOC_OR_GOTO (dentry, quota_dentry_t, err);
-
- INIT_LIST_HEAD (&dentry->next);
-
- dentry->name = gf_strdup (name);
- if (dentry->name == NULL) {
- GF_FREE (dentry);
- dentry = NULL;
- goto err;
- }
-
- uuid_copy (dentry->par, par);
-
- if (ctx != NULL)
- list_add_tail (&dentry->next, &ctx->parents);
+quota_statvfs_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct statvfs *stbuf)
+{
+ struct quota_priv *priv = this->private;
+
+ if (op_ret >= 0) {
+ priv->current_free_disk =
+ (stbuf->f_bavail * 100) / stbuf->f_blocks;
+ }
-err:
- return dentry;
+ STACK_DESTROY (frame->root);
+ return 0;
}
void
-__quota_dentry_free (quota_dentry_t *dentry)
+gf_quota_usage_subtract (xlator_t *this, size_t size)
{
- if (dentry == NULL) {
- goto out;
- }
+ struct quota_priv *priv = NULL;
- list_del_init (&dentry->next);
+ priv = this->private;
- GF_FREE (dentry->name);
- GF_FREE (dentry);
-out:
- return;
+ LOCK (&priv->lock);
+ {
+ if (priv->current_disk_usage < size)
+ priv->current_disk_usage = 0;
+ else
+ priv->current_disk_usage -= size;
+ }
+ UNLOCK (&priv->lock);
}
-void
-check_ancestory_2_cbk (struct list_head *parents, inode_t *inode,
- int32_t op_ret, int32_t op_errno, void *data)
-{
- inode_t *this_inode = NULL;
- quota_inode_ctx_t *ctx = NULL;
-
- this_inode = data;
-
- if (op_ret < 0)
- goto out;
-
- if (parents == NULL || list_empty (parents)) {
- gf_log (THIS->name, GF_LOG_WARNING,
- "Couldn't build ancestry for inode (gfid:%s). "
- "Without knowing ancestors till root, quota "
- "cannot be enforced.",
- uuid_utoa (this_inode->gfid));
- goto out;
- }
-
- quota_inode_ctx_get (this_inode, THIS, &ctx, 0);
- if (ctx)
- ctx->ancestry_built = _gf_true;
-
-out:
- inode_unref (this_inode);
-}
void
-check_ancestory_2 (xlator_t *this, quota_local_t *local, inode_t *inode)
+gf_quota_usage_add (xlator_t *this, size_t size)
{
- inode_t *cur_inode = NULL;
- inode_t *parent = NULL;
- quota_inode_ctx_t *ctx = NULL;
- char *name = NULL;
- uuid_t pgfid = {0};
-
- name = (char *) local->loc.name;
- if (local->loc.parent) {
- uuid_copy (pgfid, local->loc.parent->gfid);
- parent = local->loc.parent;
- }
+ struct quota_priv *priv = this->private;
- cur_inode = inode_ref (inode);
- while (cur_inode && !__is_root_gfid (cur_inode->gfid)) {
- quota_inode_ctx_get (cur_inode, this, &ctx, 0);
- /* build ancestry is required only on the first lookup,
- * so stop crawling when the inode_ctx is set for an inode
- */
- if (ctx && ctx->ancestry_built)
- goto setctx;
-
- parent = inode_parent (cur_inode, pgfid, name);
- if (!parent) {
- quota_build_ancestry (cur_inode, check_ancestory_2_cbk,
- inode_ref (inode));
- goto out;
- }
-
- if (name != NULL) {
- name = NULL;
- uuid_clear (pgfid);
- }
-
- inode_unref (cur_inode);
- cur_inode = parent;
- }
-
-setctx:
- if (cur_inode && cur_inode != inode) {
- quota_inode_ctx_get (inode, this, &ctx, 0);
- if (ctx)
- ctx->ancestry_built = _gf_true;
- }
-out:
- if (cur_inode)
- inode_unref (cur_inode);
-}
-
-static inline void
-quota_link_count_decrement (quota_local_t *local)
-{
- call_stub_t *stub = NULL;
- int link_count = -1;
-
- if (local == NULL)
- goto out;
-
- LOCK (&local->lock);
- {
- link_count = --local->link_count;
- if (link_count == 0) {
- stub = local->stub;
- local->stub = NULL;
- }
- }
- UNLOCK (&local->lock);
-
- if (stub != NULL) {
- call_resume (stub);
- }
-out:
- return;
-}
-
-static inline void
-quota_handle_validate_error (quota_local_t *local, int32_t op_ret,
- int32_t op_errno)
-{
- if (local == NULL)
- goto out;
-
- LOCK (&local->lock);
- {
- if (op_ret < 0) {
- local->op_ret = op_ret;
- local->op_errno = op_errno;
- }
- }
- UNLOCK (&local->lock);
-
- /* we abort checking limits on this path to root */
- quota_link_count_decrement (local);
-out:
- return;
-}
-
-int32_t
-quota_validate_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)
-{
- quota_local_t *local = NULL;
- int32_t ret = 0;
- quota_inode_ctx_t *ctx = NULL;
- int64_t *size = 0;
- uint64_t value = 0;
-
- local = frame->local;
-
- if (op_ret < 0) {
- goto unwind;
- }
-
- GF_ASSERT (local);
- GF_ASSERT (frame);
- GF_VALIDATE_OR_GOTO_WITH_ERROR ("quota", this, unwind, op_errno,
- EINVAL);
- GF_VALIDATE_OR_GOTO_WITH_ERROR (this->name, xdata, unwind, op_errno,
- EINVAL);
-
- ret = inode_ctx_get (local->validate_loc.inode, this, &value);
-
- 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)",
- uuid_utoa (local->validate_loc.inode->gfid));
- op_errno = EINVAL;
- goto unwind;
- }
-
- ret = dict_get_bin (xdata, QUOTA_SIZE_KEY, (void **) &size);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_WARNING,
- "size key not present in dict");
- op_errno = EINVAL;
- goto unwind;
- }
-
- local->just_validated = 1; /* so that we don't go into infinite
- * loop of validation and checking
- * limit when timeout is zero.
- */
- LOCK (&ctx->lock);
- {
- ctx->size = ntoh64 (*size);
- gettimeofday (&ctx->tv, NULL);
- }
- UNLOCK (&ctx->lock);
-
- quota_check_limit (frame, local->validate_loc.inode, this, NULL, NULL);
- return 0;
-
-unwind:
- quota_handle_validate_error (local, op_ret, op_errno);
- return 0;
-}
-
-
-static inline uint64_t
-quota_time_elapsed (struct timeval *now, struct timeval *then)
-{
- return (now->tv_sec - then->tv_sec);
+ LOCK (&priv->lock);
+ {
+ priv->current_disk_usage += size;
+ }
+ UNLOCK (&priv->lock);
}
-int32_t
-quota_timeout (struct timeval *tv, int32_t timeout)
-{
- struct timeval now = {0,};
- int32_t timed_out = 0;
-
- gettimeofday (&now, NULL);
-
- if (quota_time_elapsed (&now, tv) >= timeout) {
- timed_out = 1;
- }
-
- return timed_out;
-}
-
-static inline void
-quota_add_parent (quota_dentry_t *dentry, struct list_head *list)
+void
+gf_quota_update_current_free_disk (xlator_t *this)
{
- quota_dentry_t *entry = NULL;
- gf_boolean_t found = _gf_false;
+ call_frame_t *frame = NULL;
+ call_pool_t *pool = NULL;
- if ((dentry == NULL) || (list == NULL)) {
- goto out;
- }
+ struct quota_priv *priv = NULL;
- list_for_each_entry (entry, list, next) {
- if (uuid_compare (dentry->par, entry->par) == 0) {
- found = _gf_true;
- goto out;
- }
- }
+ pool = this->ctx->pool;
+ frame = create_frame (this, pool);
+
+ priv = this->private;
- list_add_tail (&dentry->next, list);
+ STACK_WIND (frame, quota_statvfs_cbk,
+ this->children->xlator,
+ this->children->xlator->fops->statfs, &(priv->root_loc));
-out:
- return;
+ return ;
}
-int32_t
-quota_build_ancestry_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)
-{
- inode_t *parent = NULL, *tmp_parent = NULL;
- gf_dirent_t *entry = NULL;
- loc_t loc = {0, };
- quota_dentry_t *dentry = NULL, *tmp = NULL;
- quota_inode_ctx_t *ctx = NULL;
- struct list_head parents = {0, };
- quota_local_t *local = NULL;
-
- INIT_LIST_HEAD (&parents);
-
- local = frame->local;
- frame->local = NULL;
-
- if (op_ret < 0)
- goto err;
-
- parent = inode_parent (local->loc.inode, 0, NULL);
- if (parent == NULL) {
- gf_log (this->name, GF_LOG_WARNING, "parent is NULL");
- op_errno = EINVAL;
- goto err;
- }
-
- if ((op_ret > 0) && (entries != NULL)) {
- list_for_each_entry (entry, &entries->list, list) {
- if (__is_root_gfid (entry->inode->gfid)) {
- /* The list contains a sub-list for each
- * possible path to the target inode. Each
- * sub-list starts with the root entry of the
- * tree and is followed by the child entries
- * for a particular path to the target entry.
- * The root entry is an implied sub-list
- * delimiter, as it denotes we have started
- * processing a new path. Reset the parent
- * pointer and continue
- */
-
- tmp_parent = NULL;
- }
-
- uuid_copy (loc.gfid, entry->d_stat.ia_gfid);
-
- loc.inode = inode_ref (entry->inode);
- loc.parent = inode_ref (tmp_parent);
- loc.name = entry->d_name;
-
- quota_fill_inodectx (this, entry->inode, entry->dict,
- &loc, &entry->d_stat, &op_errno);
-
- tmp_parent = entry->inode;
-
- loc_wipe (&loc);
- }
- }
-
- quota_inode_ctx_get (local->loc.inode, this, &ctx, 0);
-
- if (ctx != NULL) {
- LOCK (&ctx->lock);
- {
- list_for_each_entry (dentry, &ctx->parents, next) {
- /* we built ancestry for a non-directory */
- tmp = __quota_dentry_new (NULL, dentry->name,
- dentry->par);
- quota_add_parent (tmp, &parents);
-
- if (list_empty (&tmp->next)) {
- __quota_dentry_free (tmp);
- tmp = NULL;
- }
- }
- }
- UNLOCK (&ctx->lock);
- }
-
- if (list_empty (&parents)) {
- /* we built ancestry for a directory */
- list_for_each_entry (entry, &entries->list, list) {
- if (entry->inode == local->loc.inode)
- break;
- }
-
- GF_ASSERT (&entry->list != &entries->list);
- tmp = __quota_dentry_new (NULL, entry->d_name, parent->gfid);
- quota_add_parent (tmp, &parents);
- }
-
- local->ancestry_cbk (&parents, local->loc.inode, 0, 0,
- local->ancestry_data);
- goto cleanup;
-
-err:
- local->ancestry_cbk (NULL, NULL, -1, op_errno, local->ancestry_data);
-
-cleanup:
- STACK_DESTROY (frame->root);
- quota_local_cleanup (this, local);
-
- if (parent != NULL) {
- inode_unref (parent);
- parent = NULL;
- }
-
- list_for_each_entry_safe (dentry, tmp, &parents, next) {
- __quota_dentry_free (dentry);
- }
+int
+gf_quota_check_free_disk (xlator_t *this)
+{
+ struct quota_priv * priv = NULL;
+ struct timeval tv = {0, 0};
+
+ priv = this->private;
+ if (priv->min_free_disk_limit) {
+ gettimeofday (&tv, NULL);
+ if (tv.tv_sec > (priv->refresh_interval +
+ priv->min_disk_last_updated_time)) {
+ priv->min_disk_last_updated_time = tv.tv_sec;
+ gf_quota_update_current_free_disk (this);
+ }
+ if (priv->current_free_disk <= priv->min_free_disk_limit)
+ return -1;
+ }
- return 0;
+ return 0;
}
-int32_t
-quota_build_ancestry_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)
-{
- dict_t *xdata_req = NULL;
- quota_local_t *local = NULL;
-
- if (op_ret < 0) {
- goto err;
- }
-
- xdata_req = dict_new ();
- if (xdata_req == NULL) {
- op_ret = -ENOMEM;
- goto err;
- }
-
- op_ret = dict_set_int8 (xdata_req, QUOTA_LIMIT_KEY, 1);
- if (op_ret < 0) {
- op_errno = -op_ret;
- goto err;
- }
-
- op_ret = dict_set_int8 (xdata_req, GET_ANCESTRY_DENTRY_KEY, 1);
- if (op_ret < 0) {
- op_errno = -op_ret;
- goto err;
- }
-
- /* This would ask posix layer to construct dentry chain till root */
- STACK_WIND (frame, quota_build_ancestry_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->readdirp, fd, 0, 0, xdata_req);
-
- op_ret = 0;
-
-err:
- fd_unref (fd);
-
- dict_unref (xdata_req);
-
- if (op_ret < 0) {
- local = frame->local;
- frame->local = NULL;
-
- local->ancestry_cbk (NULL, NULL, -1, op_errno,
- local->ancestry_data);
- quota_local_cleanup (this, local);
- STACK_DESTROY (frame->root);
- }
-
- return 0;
-}
int
-quota_build_ancestry (inode_t *inode, quota_ancestry_built_t ancestry_cbk,
- void *data)
+quota_truncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct stat *prebuf,
+ struct stat *postbuf)
{
- loc_t loc = {0, };
- fd_t *fd = NULL;
- quota_local_t *local = NULL;
- call_frame_t *new_frame = NULL;
- int op_errno = EINVAL;
- xlator_t *this = NULL;
-
- this = THIS;
-
- loc.inode = inode_ref (inode);
- uuid_copy (loc.gfid, inode->gfid);
-
- fd = fd_create (inode, 0);
-
- new_frame = create_frame (this, this->ctx->pool);
- if (new_frame == NULL) {
- op_errno = ENOMEM;
- goto err;
- }
-
- new_frame->root->uid = new_frame->root->gid = 0;
-
- local = quota_local_new ();
- if (local == NULL) {
- op_errno = ENOMEM;
- goto err;
- }
+ struct quota_priv *priv = this->private;
- new_frame->local = local;
- local->ancestry_cbk = ancestry_cbk;
- local->ancestry_data = data;
- local->loc.inode = inode_ref (inode);
-
- if (IA_ISDIR (inode->ia_type)) {
- STACK_WIND (new_frame, quota_build_ancestry_open_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->opendir, &loc, fd,
- NULL);
- } else {
- STACK_WIND (new_frame, quota_build_ancestry_open_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->open, &loc, 0, fd,
- NULL);
- }
-
- loc_wipe (&loc);
- return 0;
-
-err:
- ancestry_cbk (NULL, NULL, -1, op_errno, data);
-
- fd_unref (fd);
-
- local = new_frame->local;
- new_frame->local = NULL;
+ int space_freed = 0;
- if (local != NULL) {
- quota_local_cleanup (this, local);
- }
-
- if (new_frame != NULL) {
- STACK_DESTROY (new_frame->root);
- }
+ if ((op_ret >= 0) && priv->disk_usage_limit) {
+ space_freed = GF_DISK_FILE_USAGE (prebuf->st_blocks, postbuf->st_blocks);
+ gf_quota_usage_subtract (this, space_freed);
+ }
- loc_wipe (&loc);
- return 0;
+ STACK_UNWIND_STRICT (truncate, frame, op_ret, op_errno,
+ prebuf, postbuf);
+ return 0;
}
int
-quota_validate (call_frame_t *frame, inode_t *inode, xlator_t *this,
- fop_lookup_cbk_t cbk_fn)
+quota_truncate (call_frame_t *frame, xlator_t *this,
+ loc_t *loc, off_t offset)
{
- quota_local_t *local = NULL;
- int ret = 0;
- dict_t *xdata = NULL;
- quota_priv_t *priv = NULL;
-
- local = frame->local;
- priv = this->private;
-
- LOCK (&local->lock);
- {
- loc_wipe (&local->validate_loc);
-
- 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",
- uuid_utoa (inode->gfid));
- }
- }
- UNLOCK (&local->lock);
-
- if (ret < 0) {
- ret = -ENOMEM;
- goto err;
- }
-
- xdata = dict_new ();
- if (xdata == NULL) {
- ret = -ENOMEM;
- goto err;
- }
-
- ret = dict_set_int8 (xdata, QUOTA_SIZE_KEY, 1);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_WARNING, "dict set failed");
- ret = -ENOMEM;
- goto err;
- }
-
- ret = dict_set_str (xdata, "volume-uuid", priv->volume_uuid);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_WARNING, "dict set failed");
- ret = -ENOMEM;
- goto err;
- }
- ret = quota_enforcer_lookup (frame, this, &local->validate_loc, xdata,
- cbk_fn);
- if (ret < 0) {
- ret = -ENOTCONN;
- goto err;
- }
-
- ret = 0;
-err:
- if (xdata)
- dict_unref (xdata);
-
- return ret;
+ STACK_WIND (frame, quota_truncate_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->truncate,
+ loc, offset);
+ return 0;
}
-void
-quota_check_limit_continuation (struct list_head *parents, inode_t *inode,
- int32_t op_ret, int32_t op_errno, void *data)
-{
- call_frame_t *frame = NULL;
- xlator_t *this = NULL;
- quota_local_t *local = NULL;
- quota_dentry_t *entry = NULL;
- inode_t *parent = NULL;
- int parent_count = 0;
-
- frame = data;
- local = frame->local;
- this = THIS;
-
- if ((op_ret < 0) || list_empty (parents)) {
- if (op_ret >= 0) {
- gf_log (this->name, GF_LOG_WARNING,
- "Couldn't build ancestry for inode (gfid:%s). "
- "Without knowing ancestors till root, quota "
- "cannot be enforced. "
- "Hence, failing fop with EIO",
- uuid_utoa (inode->gfid));
- op_errno = EIO;
- }
-
- quota_handle_validate_error (local, -1, op_errno);
- goto out;
- }
-
- list_for_each_entry (entry, parents, next) {
- parent_count++;
- }
-
- LOCK (&local->lock);
- {
- local->link_count += (parent_count - 1);
- }
- UNLOCK (&local->lock);
-
- list_for_each_entry (entry, parents, next) {
- parent = inode_find (inode->table, entry->par);
- quota_check_limit (frame, parent, this, NULL, NULL);
- inode_unref (parent);
- }
-
-out:
- return;
-}
-
-int32_t
-quota_check_limit (call_frame_t *frame, inode_t *inode, xlator_t *this,
- char *name, uuid_t par)
-{
- int32_t ret = -1, op_errno = EINVAL;
- inode_t *_inode = NULL, *parent = NULL;
- quota_inode_ctx_t *ctx = NULL;
- quota_priv_t *priv = NULL;
- quota_local_t *local = NULL;
- char need_validate = 0;
- gf_boolean_t hard_limit_exceeded = 0;
- int64_t delta = 0, wouldbe_size = 0;
- int64_t space_available = 0;
- uint64_t value = 0;
- char just_validated = 0;
- uuid_t trav_uuid = {0,};
- uint32_t timeout = 0;
-
- GF_VALIDATE_OR_GOTO ("quota", this, err);
- GF_VALIDATE_OR_GOTO (this->name, frame, err);
- GF_VALIDATE_OR_GOTO (this->name, inode, err);
-
- local = frame->local;
- GF_VALIDATE_OR_GOTO (this->name, local, err);
-
- delta = local->delta;
-
- GF_VALIDATE_OR_GOTO (this->name, local->stub, err);
- /* Allow all the trusted clients
- * Don't block the gluster internal processes like rebalance, gsyncd,
- * self heal etc from the disk quotas.
- *
- * Method: Allow all the clients with PID negative. This is by the
- * assumption that any kernel assigned pid doesn't have the negative
- * number.
- */
- if (0 > frame->root->pid) {
- ret = 0;
- quota_link_count_decrement (local);
- goto done;
- }
-
- priv = this->private;
-
- inode_ctx_get (inode, this, &value);
- ctx = (quota_inode_ctx_t *)(unsigned long)value;
-
- _inode = inode_ref (inode);
-
- LOCK (&local->lock);
- {
- just_validated = local->just_validated;
- local->just_validated = 0;
- }
- UNLOCK (&local->lock);
-
- if ( par != NULL ) {
- uuid_copy (trav_uuid, par);
- }
-
- do {
- if (ctx != NULL && (ctx->hard_lim > 0 || ctx->soft_lim > 0)) {
- wouldbe_size = ctx->size + delta;
-
- LOCK (&ctx->lock);
- {
- timeout = priv->soft_timeout;
-
- if ((ctx->soft_lim >= 0)
- && (wouldbe_size > ctx->soft_lim)) {
- timeout = priv->hard_timeout;
- }
-
- if (!just_validated
- && quota_timeout (&ctx->tv, timeout)) {
- need_validate = 1;
- } else if (wouldbe_size >= ctx->hard_lim) {
- hard_limit_exceeded = 1;
- }
- }
- UNLOCK (&ctx->lock);
-
- if (need_validate) {
- ret = quota_validate (frame, _inode, this,
- quota_validate_cbk);
- if (ret < 0) {
- op_errno = -ret;
- goto err;
- }
-
- break;
- }
-
- if (hard_limit_exceeded) {
- local->op_ret = -1;
- local->op_errno = EDQUOT;
-
- space_available = ctx->hard_lim - ctx->size;
-
- if (space_available < 0)
- space_available = 0;
-
- if ((local->space_available < 0)
- || (local->space_available
- > space_available)){
- local->space_available
- = space_available;
-
- }
-
- if (space_available == 0) {
- op_errno = EDQUOT;
- goto err;
- }
- }
-
- /* We log usage only if quota limit is configured on
- that inode. */
- quota_log_usage (this, ctx, _inode, delta);
- }
-
- if (__is_root_gfid (_inode->gfid)) {
- quota_link_count_decrement (local);
- break;
- }
-
- parent = inode_parent (_inode, trav_uuid, name);
-
- if (name != NULL) {
- name = NULL;
- uuid_clear (trav_uuid);
- }
-
- if (parent == NULL) {
- ret = quota_build_ancestry (_inode,
- quota_check_limit_continuation,
- frame);
- if (ret < 0) {
- op_errno = -ret;
- goto err;
- }
-
- break;
- }
-
- inode_unref (_inode);
- _inode = parent;
- just_validated = 0;
-
- if (_inode == NULL) {
- break;
- }
-
- value = 0;
- inode_ctx_get (_inode, this, &value);
- ctx = (quota_inode_ctx_t *)(unsigned long)value;
- } while (1);
-
- if (_inode != NULL) {
- inode_unref (_inode);
- _inode = NULL;
- }
-
-done:
- return 0;
-
-err:
- quota_handle_validate_error (local, -1, op_errno);
-
- inode_unref (_inode);
- return 0;
-}
-
-static inline int
-quota_get_limits (xlator_t *this, dict_t *dict, int64_t *hard_lim,
- int64_t *soft_lim)
-{
- quota_limit_t *limit = NULL;
- quota_priv_t *priv = NULL;
- int64_t soft_lim_percent = 0, *ptr = NULL;
- int ret = 0;
-
- if ((this == NULL) || (dict == NULL) || (hard_lim == NULL)
- || (soft_lim == NULL))
- goto out;
-
- priv = this->private;
-
- ret = dict_get_bin (dict, QUOTA_LIMIT_KEY, (void **) &ptr);
- limit = (quota_limit_t *)ptr;
-
- if (limit) {
- *hard_lim = ntoh64 (limit->hard_lim);
- soft_lim_percent = ntoh64 (limit->soft_lim_percent);
- }
-
- if (soft_lim_percent < 0) {
- soft_lim_percent = priv->default_soft_lim;
- }
-
- if ((*hard_lim > 0) && (soft_lim_percent > 0)) {
- *soft_lim = (soft_lim_percent * (*hard_lim))/100;
- }
-
-out:
- return 0;
-}
int
-quota_fill_inodectx (xlator_t *this, inode_t *inode, dict_t *dict,
- loc_t *loc, struct iatt *buf, int32_t *op_errno)
-{
- int32_t ret = -1;
- char found = 0;
- quota_inode_ctx_t *ctx = NULL;
- quota_dentry_t *dentry = NULL;
- uint64_t value = 0;
- int64_t hard_lim = -1, soft_lim = -1;
-
- quota_get_limits (this, dict, &hard_lim, &soft_lim);
-
- inode_ctx_get (inode, this, &value);
- ctx = (quota_inode_ctx_t *)(unsigned long)value;
-
- if ((((ctx == NULL) || (ctx->hard_lim == hard_lim))
- && (hard_lim < 0) && !QUOTA_REG_OR_LNK_FILE (buf->ia_type))) {
- ret = 0;
- goto out;
- }
-
- ret = quota_inode_ctx_get (inode, this, &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));
- ret = -1;
- *op_errno = ENOMEM;
- goto out;
- }
-
- LOCK (&ctx->lock);
- {
- ctx->hard_lim = hard_lim;
- ctx->soft_lim = soft_lim;
-
- ctx->buf = *buf;
-
- if (!QUOTA_REG_OR_LNK_FILE (buf->ia_type)) {
- goto unlock;
- }
-
- /* do nothing if it is a nameless lookup */
- if (loc->name == NULL || !loc->parent)
- goto unlock;
-
- list_for_each_entry (dentry, &ctx->parents, next) {
- if ((strcmp (dentry->name, loc->name) == 0) &&
- (uuid_compare (loc->parent->gfid,
- dentry->par) == 0)) {
- found = 1;
- break;
- }
- }
-
- if (!found) {
- dentry = __quota_dentry_new (ctx,
- (char *)loc->name,
- loc->parent->gfid);
- 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)",
- uuid_utoa (local->loc.inode->gfid));
- */
- ret = -1;
- *op_errno = ENOMEM;
- goto unlock;
- }
- }
- }
-unlock:
- UNLOCK (&ctx->lock);
-
-out:
- return ret;
-}
-
-int32_t
-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)
+quota_ftruncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct stat *prebuf,
+ struct stat *postbuf)
{
- quota_local_t *local = NULL;
- int32_t ret = 0;
- inode_t *this_inode = NULL;
-
- local = frame->local;
- frame->local = NULL;
-
- if (op_ret >= 0 && inode) {
- this_inode = inode_ref (inode);
-
- op_ret = quota_fill_inodectx (this, inode, dict, &local->loc,
- buf, &op_errno);
- if (op_ret < 0)
- op_errno = ENOMEM;
- }
-
- QUOTA_STACK_UNWIND (lookup, frame, op_ret, op_errno, inode, buf,
- dict, postparent);
-
- if (op_ret < 0 || this_inode == NULL || uuid_is_null(this_inode->gfid))
- goto out;
-
- check_ancestory_2 (this, local, this_inode);
+ struct quota_priv *priv = NULL;
+ int space_freed = 0;
-out:
- if (this_inode)
- inode_unref (this_inode);
+ priv = this->private;
- quota_local_cleanup (this, local);
+ if ((op_ret >= 0) && priv->disk_usage_limit) {
+ space_freed = GF_DISK_FILE_USAGE (prebuf->st_blocks, postbuf->st_blocks);
+ gf_quota_usage_subtract (this, space_freed);
+ }
- return 0;
+ STACK_UNWIND_STRICT (ftruncate, frame, op_ret, op_errno,
+ prebuf, postbuf);
+ return 0;
}
-int32_t
-quota_lookup (call_frame_t *frame, xlator_t *this, loc_t *loc,
- dict_t *xattr_req)
-{
- quota_priv_t *priv = NULL;
- int32_t ret = -1;
- quota_local_t *local = NULL;
-
- priv = this->private;
-
- WIND_IF_QUOTAOFF (priv->is_quota_on, off);
-
- xattr_req = xattr_req ? dict_ref(xattr_req) : dict_new();
- if (!xattr_req)
- goto err;
-
- local = quota_local_new ();
- if (local == NULL) {
- goto err;
- }
-
- frame->local = local;
- loc_copy (&local->loc, loc);
- ret = dict_set_int8 (xattr_req, QUOTA_LIMIT_KEY, 1);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_WARNING,
- "dict set of key for hard-limit failed");
- goto err;
- }
-
- STACK_WIND (frame, quota_lookup_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->lookup, loc, xattr_req);
-
- ret = 0;
-
-err:
- if (xattr_req)
- dict_unref (xattr_req);
-
- if (ret < 0) {
- QUOTA_STACK_UNWIND (lookup, frame, -1, ENOMEM,
- NULL, NULL, NULL, NULL);
- }
-
- return 0;
-
-off:
- STACK_WIND_TAIL (frame, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->lookup, loc, xattr_req);
- return 0;
-}
-
-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)
+int
+quota_ftruncate (call_frame_t *frame, xlator_t *this,
+ fd_t *fd, off_t offset)
{
- int32_t ret = 0;
- uint64_t ctx_int = 0;
- quota_inode_ctx_t *ctx = NULL;
- quota_local_t *local = NULL;
-
- local = frame->local;
-
- if ((op_ret < 0) || (local == NULL)) {
- goto out;
- }
-
- 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));
- goto out;
- }
-
- LOCK (&ctx->lock);
- {
- ctx->buf = *postbuf;
- }
- UNLOCK (&ctx->lock);
-
-out:
- QUOTA_STACK_UNWIND (writev, frame, op_ret, op_errno, prebuf, postbuf,
- xdata);
-
- return 0;
+ STACK_WIND (frame, quota_ftruncate_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->ftruncate,
+ fd, offset);
+ return 0;
}
-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)
+int
+quota_mknod_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno,
+ inode_t *inode, struct stat *buf, struct stat *preparent,
+ struct stat *postparent)
{
- quota_local_t *local = NULL;
- int32_t op_errno = EINVAL;
- quota_priv_t *priv = NULL;
- struct iovec *new_vector = NULL;
- int32_t new_count = 0;
-
- priv = this->private;
-
- local = frame->local;
- if (local == NULL) {
- gf_log (this->name, GF_LOG_WARNING, "local is NULL");
- goto unwind;
- }
+ struct quota_priv *priv = NULL;
+ int space_used = 0;
- if (local->op_ret == -1) {
- op_errno = local->op_errno;
-
- if ((op_errno == EDQUOT) && (local->space_available > 0)) {
- new_count = iov_subset (vector, count, 0,
- local->space_available, NULL);
-
- new_vector = GF_CALLOC (new_count,
- sizeof (struct iovec),
- gf_common_mt_iovec);
- if (new_vector == NULL) {
- local->op_ret = -1;
- local->op_errno = ENOMEM;
- goto unwind;
- }
-
- new_count = iov_subset (vector, count, 0,
- local->space_available,
- new_vector);
-
- vector = new_vector;
- count = new_count;
- } else {
- goto unwind;
- }
- }
-
- STACK_WIND (frame, quota_writev_cbk,
- FIRST_CHILD(this), FIRST_CHILD(this)->fops->writev, fd,
- vector, count, off, flags, iobref, xdata);
-
- if (new_vector != NULL)
- GF_FREE (new_vector);
+ priv = this->private;
- return 0;
+ if ((op_ret >= 0) && priv->disk_usage_limit) {
+ space_used = GF_DISK_USAGE_STATBUF (buf->st_blocks) +
+ GF_DISK_DIRECTORY_USAGE (preparent->st_blocks,
+ postparent->st_blocks);
+ gf_quota_usage_add (this, space_used);
+ }
-unwind:
- QUOTA_STACK_UNWIND (writev, frame, -1, op_errno, NULL, NULL, NULL);
- return 0;
+ STACK_UNWIND_STRICT (mknod, frame, op_ret, op_errno, inode, buf,
+ preparent, postparent);
+ return 0;
}
-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)
+int
+quota_mknod (call_frame_t *frame, xlator_t *this,
+ loc_t *loc, mode_t mode, dev_t rdev)
{
- quota_priv_t *priv = NULL;
- int32_t ret = -1, op_errno = EINVAL;
- int32_t parents = 0;
- uint64_t size = 0;
- quota_local_t *local = NULL;
- quota_inode_ctx_t *ctx = NULL;
- quota_dentry_t *dentry = NULL, *tmp = NULL;
- call_stub_t *stub = NULL;
- struct list_head head = {0, };
-
- priv = this->private;
+ struct quota_priv *priv = NULL;
- WIND_IF_QUOTAOFF (priv->is_quota_on, off);
+ priv = this->private;
- INIT_LIST_HEAD (&head);
-
- GF_ASSERT (frame);
- GF_VALIDATE_OR_GOTO ("quota", this, unwind);
- GF_VALIDATE_OR_GOTO (this->name, fd, unwind);
-
- local = quota_local_new ();
- if (local == NULL) {
- goto unwind;
- }
-
- frame->local = local;
- local->loc.inode = inode_ref (fd->inode);
-
- ret = quota_inode_ctx_get (fd->inode, this, &ctx, 0);
- if (ctx == NULL) {
- gf_log (this->name, GF_LOG_DEBUG, "quota context is NULL on "
- "inode (%s). "
- "If quota is not enabled recently and crawler has "
- "finished crawling, its an error",
- uuid_utoa (fd->inode->gfid));
- }
-
- stub = fop_writev_stub (frame, quota_writev_helper, fd, vector, count,
- off, flags, iobref, xdata);
- if (stub == NULL) {
- op_errno = ENOMEM;
- goto unwind;
- }
-
- priv = this->private;
- GF_VALIDATE_OR_GOTO (this->name, priv, unwind);
-
- size = iov_length (vector, count);
- if (ctx != NULL) {
- LOCK (&ctx->lock);
- {
- list_for_each_entry (dentry, &ctx->parents, next) {
- tmp = __quota_dentry_new (NULL, dentry->name,
- dentry->par);
- list_add_tail (&tmp->next, &head);
- parents++;
- }
- }
- UNLOCK (&ctx->lock);
- }
+ if (gf_quota_check_free_disk (this) == -1) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "min-free-disk limit (%u) crossed, current available is %u",
+ priv->min_free_disk_limit, priv->current_free_disk);
+ STACK_UNWIND_STRICT (mknod, frame, -1, ENOSPC, NULL, NULL,
+ NULL, NULL);
+ return 0;
+ }
- LOCK (&local->lock);
- {
- local->delta = size;
- local->link_count = (parents != 0) ? parents : 1;
- local->stub = stub;
+ if (priv->current_disk_usage > priv->disk_usage_limit) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Disk usage limit (%"PRIu64") crossed, current usage is %"PRIu64"",
+ priv->disk_usage_limit, priv->current_disk_usage);
+ STACK_UNWIND_STRICT (mknod, frame, -1, ENOSPC, NULL, NULL,
+ NULL, NULL);
+ return 0;
}
- UNLOCK (&local->lock);
-
- if (parents == 0) {
- /* nameless lookup on this inode, allow quota to reconstruct
- * ancestry as part of check_limit.
- */
- quota_check_limit (frame, fd->inode, this, NULL, NULL);
- } else {
- list_for_each_entry_safe (dentry, tmp, &head, next) {
- quota_check_limit (frame, fd->inode, this, dentry->name,
- dentry->par);
- __quota_dentry_free (dentry);
- }
- }
-
- return 0;
-unwind:
- QUOTA_STACK_UNWIND (writev, frame, -1, op_errno, NULL, NULL, NULL);
- return 0;
-
-off:
- STACK_WIND_TAIL (frame, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->writev, fd,
- vector, count, off, flags, iobref, xdata);
- return 0;
+ STACK_WIND (frame, quota_mknod_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->mknod,
+ loc, mode, rdev);
+ return 0;
}
-int32_t
+int
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)
+ int32_t op_ret, int32_t op_errno, inode_t *inode,
+ struct stat *buf, struct stat *preparent,
+ struct stat *postparent)
{
- QUOTA_STACK_UNWIND (mkdir, frame, op_ret, op_errno, inode,
- buf, preparent, postparent, xdata);
- return 0;
-}
+ struct quota_priv *priv = NULL;
+ int space_used = 0;
+ priv = this->private;
-int32_t
-quota_mkdir_helper (call_frame_t *frame, xlator_t *this, loc_t *loc,
- mode_t mode, 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;
- }
-
- op_errno = local->op_errno;
-
- if (local->op_ret == -1) {
- goto unwind;
- }
-
- STACK_WIND (frame, quota_mkdir_cbk,
- FIRST_CHILD(this), FIRST_CHILD(this)->fops->mkdir, loc,
- mode, umask, xdata);
-
- return 0;
-
-unwind:
- QUOTA_STACK_UNWIND (mkdir, frame, -1, op_errno, 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)
-{
- quota_priv_t *priv = NULL;
- int32_t ret = 0, op_errno = 0;
- quota_local_t *local = NULL;
- call_stub_t *stub = NULL;
-
- priv = this->private;
-
- WIND_IF_QUOTAOFF (priv->is_quota_on, off);
-
- local = quota_local_new ();
- if (local == NULL) {
- op_errno = ENOMEM;
- goto err;
- }
-
- frame->local = local;
-
- ret = loc_copy (&local->loc, loc);
- if (ret) {
- op_errno = ENOMEM;
- gf_log (this->name, GF_LOG_WARNING, "loc_copy failed");
- goto err;
- }
-
- stub = fop_mkdir_stub (frame, quota_mkdir_helper, loc, mode, umask,
- xdata);
- if (stub == NULL) {
- op_errno = ENOMEM;
- goto err;
- }
-
- LOCK (&local->lock);
- {
- local->stub = stub;
- local->delta = 0;
- local->link_count = 1;
- }
- UNLOCK (&local->lock);
-
- quota_check_limit (frame, loc->parent, this, NULL, NULL);
- return 0;
-
-err:
- QUOTA_STACK_UNWIND (mkdir, frame, -1, op_errno, NULL, NULL, NULL,
- NULL, NULL);
+ if ((op_ret >= 0) && priv->disk_usage_limit) {
- return 0;
-
-off:
- STACK_WIND_TAIL (frame, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->mkdir,
- loc, mode, umask, xdata);
-
- return 0;
-}
-
-
-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)
-{
- 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, this, &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 (create, frame, op_ret, op_errno, fd, inode, buf,
- preparent, postparent, xdata);
- 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)
-{
- quota_local_t *local = NULL;
- int32_t op_errno = EINVAL;
- quota_priv_t *priv = NULL;
-
- local = frame->local;
-
- priv = this->private;
-
- 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_create_cbk,
- FIRST_CHILD (this), FIRST_CHILD (this)->fops->create, loc,
- flags, mode, umask, fd, xdata);
- return 0;
+ space_used = GF_DISK_USAGE_STATBUF (buf->st_blocks) +
+ GF_DISK_DIRECTORY_USAGE (preparent->st_blocks,
+ postparent->st_blocks);
+ gf_quota_usage_add (this, space_used);
+ }
-unwind:
- QUOTA_STACK_UNWIND (create, frame, -1, op_errno, NULL, NULL,
- NULL, NULL, NULL, NULL);
- return 0;
+ STACK_UNWIND_STRICT (mkdir, frame, op_ret, op_errno, inode, buf,
+ preparent, postparent);
+ 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)
+int
+quota_mkdir (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode)
{
- quota_priv_t *priv = NULL;
- int32_t ret = -1;
- quota_local_t *local = NULL;
- int32_t op_errno = 0;
- call_stub_t *stub = NULL;
-
- priv = this->private;
-
- WIND_IF_QUOTAOFF (priv->is_quota_on, off);
-
- local = quota_local_new ();
- if (local == NULL) {
- op_errno = ENOMEM;
- goto err;
- }
+ struct quota_priv *priv = NULL;
- frame->local = local;
+ priv = this->private;
- ret = loc_copy (&local->loc, loc);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING, "loc_copy failed");
- op_errno = ENOMEM;
- goto err;
- }
-
- stub = fop_create_stub (frame, quota_create_helper, loc, flags, mode,
- umask, fd, xdata);
- if (stub == NULL) {
- goto err;
- }
+ if (gf_quota_check_free_disk (this) == -1) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "min-free-disk limit (%u) crossed, current available is %u",
+ priv->min_free_disk_limit, priv->current_free_disk);
+ STACK_UNWIND_STRICT (mkdir, frame, -1, ENOSPC, NULL, NULL,
+ NULL, NULL);
+ return 0;
+
+ }
- LOCK (&local->lock);
- {
- local->link_count = 1;
- local->stub = stub;
- local->delta = 0;
+ if (priv->current_disk_usage > priv->disk_usage_limit) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Disk usage limit (%"PRIu64") crossed, current usage is %"PRIu64"",
+ priv->disk_usage_limit, priv->current_disk_usage);
+ STACK_UNWIND_STRICT (mkdir, frame, -1, ENOSPC, NULL, NULL,
+ NULL, NULL);
+ return 0;
}
- UNLOCK (&local->lock);
-
- quota_check_limit (frame, loc->parent, this, NULL, NULL);
- return 0;
-err:
- QUOTA_STACK_UNWIND (create, frame, -1, op_errno, NULL, NULL, NULL,
- NULL, NULL, NULL);
- return 0;
+ STACK_WIND (frame, quota_mkdir_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->mkdir,
+ loc, mode);
-off:
- STACK_WIND_TAIL (frame, FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->create, loc,
- flags, mode, umask, fd, xdata);
- return 0;
+ return 0;
}
-int32_t
+int
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)
-{
- quota_local_t *local = NULL;
- quota_inode_ctx_t *ctx = NULL;
- uint64_t value = 0;
- quota_dentry_t *dentry = NULL;
- quota_dentry_t *old_dentry = NULL;
-
- if (op_ret < 0) {
- goto out;
- }
-
- local = (quota_local_t *) frame->local;
-
- inode_ctx_get (local->loc.inode, this, &value);
- ctx = (quota_inode_ctx_t *)(unsigned long)value;
-
- if (ctx == NULL) {
- gf_log (this->name, GF_LOG_WARNING,
- "quota context not set in inode (gfid:%s)",
- uuid_utoa (local->loc.inode->gfid));
- goto out;
- }
-
- 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)) {
- old_dentry = dentry;
- break;
- }
- }
- if (old_dentry)
- __quota_dentry_free (old_dentry);
- }
- UNLOCK (&ctx->lock);
-
-out:
- QUOTA_STACK_UNWIND (unlink, frame, op_ret, op_errno, preparent,
- postparent, xdata);
- return 0;
-}
-
-
-int32_t
-quota_unlink (call_frame_t *frame, xlator_t *this, loc_t *loc, int xflag,
- dict_t *xdata)
-{
- quota_priv_t *priv = NULL;
- int32_t ret = -1;
- quota_local_t *local = NULL;
-
- priv = this->private;
-
- WIND_IF_QUOTAOFF (priv->is_quota_on, off);
-
- local = quota_local_new ();
- if (local == NULL) {
- goto err;
- }
-
- frame->local = local;
-
- if (xdata && dict_get (xdata, GLUSTERFS_INTERNAL_FOP_KEY)) {
- local->skip_check = _gf_true;
- }
-
- ret = loc_copy (&local->loc, loc);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING, "loc_copy failed");
- goto err;
- }
-
- STACK_WIND (frame, quota_unlink_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->unlink, loc, xflag, xdata);
-
- ret = 0;
-
-err:
- if (ret == -1) {
- QUOTA_STACK_UNWIND (unlink, frame, -1, 0, NULL, NULL, NULL);
- }
-
- return 0;
-
-off:
- STACK_WIND_TAIL (frame, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->unlink, loc, xflag, xdata);
- return 0;
-}
-
-
-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)
-{
- int32_t ret = -1;
- quota_local_t *local = NULL;
- quota_inode_ctx_t *ctx = NULL;
- quota_dentry_t *dentry = NULL;
- char found = 0;
-
- if (op_ret < 0) {
- goto out;
- }
-
- local = (quota_local_t *) frame->local;
-
- if (local->skip_check)
- goto out;
-
- ret = quota_inode_ctx_get (inode, this, &ctx, 0);
- if ((ret == -1) || (ctx == NULL)) {
- gf_log (this->name, GF_LOG_DEBUG, "quota context is NULL on "
- "inode (%s). "
- "If quota is not enabled recently and crawler has "
- "finished crawling, its an error",
- uuid_utoa (inode->gfid));
- goto out;
- }
-
- 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)) {
- 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,
- uuid_utoa (local->loc.inode->gfid));
- break;
- }
- }
-
- if (!found) {
- 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;
- }
- }
-
- ctx->buf = *buf;
- }
-unlock:
- UNLOCK (&ctx->lock);
-
-out:
- QUOTA_STACK_UNWIND (link, frame, op_ret, op_errno, inode, buf,
- preparent, postparent, xdata);
+ int32_t op_ret, int32_t op_errno, struct stat *preparent,
+ struct stat *postparent)
+{
+ struct quota_local *local = NULL;
+ int space_freed = 0;
+
+ local = frame->local;
+
+ if (local) {
+ if (op_ret >= 0) {
+ space_freed = GF_DISK_USAGE_STATBUF (local->stbuf.st_blocks) +
+ GF_DISK_DIRECTORY_USAGE (preparent->st_blocks,
+ postparent->st_blocks);
+ gf_quota_usage_subtract (this, space_freed);
+ }
+ loc_wipe (&local->loc);
+ }
- return 0;
+ STACK_UNWIND_STRICT (unlink, frame, op_ret, op_errno, preparent, postparent);
+ return 0;
}
-int32_t
-quota_link_helper (call_frame_t *frame, xlator_t *this, loc_t *oldloc,
- loc_t *newloc, dict_t *xdata)
+int
+quota_unlink_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct stat *buf)
{
- quota_local_t *local = NULL;
- int32_t op_errno = EINVAL;
- quota_priv_t *priv = NULL;
+ struct quota_local *local = NULL;
- priv = this->private;
+ local = frame->local;
- local = frame->local;
- if (local == NULL) {
- gf_log (this->name, GF_LOG_WARNING, "local is NULL");
- goto unwind;
- }
-
- op_errno = local->op_errno;
-
- if (local->op_ret == -1) {
- goto unwind;
- }
+ if (op_ret >= 0) {
+ if (buf->st_nlink == 1) {
+ local->stbuf = *buf;
+ }
+ }
- STACK_WIND (frame, quota_link_cbk,
- FIRST_CHILD(this), FIRST_CHILD(this)->fops->link, oldloc,
- newloc, xdata);
- return 0;
+ STACK_WIND (frame, quota_unlink_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->unlink,
+ &local->loc);
-unwind:
- QUOTA_STACK_UNWIND (link, frame, -1, op_errno, NULL, NULL,
- NULL, NULL, NULL);
- return 0;
+ return 0;
}
-int32_t
-quota_link (call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc,
- dict_t *xdata)
+int
+quota_unlink (call_frame_t *frame, xlator_t *this, loc_t *loc)
{
- quota_priv_t *priv = NULL;
- int32_t ret = -1, op_errno = ENOMEM;
- quota_local_t *local = NULL;
- quota_inode_ctx_t *ctx = NULL;
- call_stub_t *stub = NULL;
+ struct quota_local *local = NULL;
+ struct quota_priv *priv = NULL;
- priv = this->private;
+ priv = this->private;
- WIND_IF_QUOTAOFF (priv->is_quota_on, off);
+ if (priv->disk_usage_limit) {
+ local = CALLOC (1, sizeof (struct quota_local));
+ frame->local = local;
- if (xdata && dict_get (xdata, GLUSTERFS_INTERNAL_FOP_KEY)) {
- goto off;
- }
+ loc_copy (&local->loc, loc);
- quota_inode_ctx_get (oldloc->inode, this, &ctx, 0);
- if (ctx == NULL) {
- gf_log (this->name, GF_LOG_DEBUG, "quota context is NULL on "
- "inode (%s). "
- "If quota is not enabled recently and crawler has "
- "finished crawling, its an error",
- uuid_utoa (oldloc->inode->gfid));
- }
-
- local = quota_local_new ();
- if (local == NULL) {
- goto err;
- }
-
- frame->local = (void *) local;
-
-
- ret = loc_copy (&local->loc, newloc);
- if (ret == -1) {
- gf_log (this->name, GF_LOG_WARNING, "loc_copy failed");
- goto err;
- }
-
- stub = fop_link_stub (frame, quota_link_helper, oldloc, newloc, xdata);
- if (stub == NULL) {
- goto err;
- }
-
- LOCK (&local->lock);
- {
- local->link_count = 1;
- local->stub = stub;
- local->delta = (ctx != NULL) ? ctx->buf.ia_blocks * 512 : 0;
- }
- UNLOCK (&local->lock);
-
- quota_check_limit (frame, newloc->parent, this, NULL, NULL);
- return 0;
-
-err:
- QUOTA_STACK_UNWIND (link, frame, -1, op_errno, NULL, NULL,
- NULL, NULL, NULL);
- return 0;
+ STACK_WIND (frame,
+ quota_unlink_stat_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->stat,
+ loc);
+ return 0;
+ }
-off:
- STACK_WIND_TAIL (frame, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->link, oldloc,
- newloc, xdata);
- return 0;
+ STACK_WIND (frame, quota_unlink_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->unlink,
+ loc);
+ return 0;
}
-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)
-{
- int32_t ret = -1;
- int64_t size = 0;
- quota_local_t *local = NULL;
- quota_inode_ctx_t *ctx = NULL;
- quota_dentry_t *old_dentry = NULL, *dentry = NULL;
- char new_dentry_found = 0;
-
- if (op_ret < 0) {
- goto out;
- }
-
- local = frame->local;
- if (local == NULL) {
- op_ret = -1;
- op_errno = EINVAL;
- gf_log (this->name, GF_LOG_WARNING, "local is NULL");
- goto out;
- }
-
- if (QUOTA_REG_OR_LNK_FILE (local->oldloc.inode->ia_type)) {
- size = buf->ia_blocks * 512;
- }
-
- if (!QUOTA_REG_OR_LNK_FILE (local->oldloc.inode->ia_type)) {
- goto out;
- }
-
- ret = quota_inode_ctx_get (local->oldloc.inode, this, &ctx, 0);
- if ((ret == -1) || (ctx == NULL)) {
- gf_log (this->name, GF_LOG_DEBUG, "quota context is NULL on "
- "inode (%s). "
- "If quota is not enabled recently and crawler has "
- "finished crawling, its an error",
- uuid_utoa (local->oldloc.inode->gfid));
-
- goto out;
- }
-
- LOCK (&ctx->lock);
- {
- 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)) {
- old_dentry = dentry;
- } else if ((strcmp (dentry->name,
- local->newloc.name) == 0) &&
- (uuid_compare (local->newloc.parent->gfid,
- dentry->par) == 0)) {
- 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,
- uuid_utoa (local->oldloc.inode->gfid));
- }
-
- if (old_dentry && new_dentry_found)
- break;
- }
-
- if (old_dentry != NULL) {
- __quota_dentry_free (old_dentry);
- } else {
- gf_log (this->name, GF_LOG_WARNING,
- "dentry corresponding to the path just renamed "
- "(name:%s) is not present", local->oldloc.name);
- }
-
- if (!new_dentry_found) {
- dentry = __quota_dentry_new (ctx,
- (char *)local->newloc.name,
- local->newloc.parent->gfid);
- if (dentry == NULL) {
- gf_log (this->name, GF_LOG_WARNING,
- "cannot create a new dentry (name:%s) "
- "for inode(gfid:%s)",
- local->newloc.name,
- uuid_utoa (local->oldloc.inode->gfid));
- op_ret = -1;
- op_errno = ENOMEM;
- goto unlock;
- }
- }
-
- ctx->buf = *buf;
- }
-unlock:
- UNLOCK (&ctx->lock);
-
-out:
- QUOTA_STACK_UNWIND (rename, frame, op_ret, op_errno, buf, preoldparent,
- postoldparent, prenewparent, postnewparent, xdata);
+int
+quota_rmdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct stat *preparent,
+ struct stat *postparent)
+{
+ struct quota_local *local = NULL;
+ int space_freed = 0;
+
+ local = frame->local;
+
+ if (local) {
+ if (op_ret >= 0) {
+ space_freed = GF_DISK_USAGE_STATBUF (local->stbuf.st_blocks) +
+ GF_DISK_DIRECTORY_USAGE (preparent->st_blocks,
+ postparent->st_blocks);
+ gf_quota_usage_subtract (this, space_freed);
+ }
+ loc_wipe (&local->loc);
+ }
- return 0;
+ STACK_UNWIND_STRICT (rmdir, frame, op_ret, op_errno, preparent, postparent);
+ return 0;
}
-int32_t
-quota_rename_helper (call_frame_t *frame, xlator_t *this, loc_t *oldloc,
- loc_t *newloc, dict_t *xdata)
+int
+quota_rmdir_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct stat *buf)
{
- quota_local_t *local = NULL;
- int32_t op_errno = EINVAL;
- quota_priv_t *priv = NULL;
-
- priv = this->private;
-
- local = frame->local;
- if (local == NULL) {
- gf_log (this->name, GF_LOG_WARNING, "local is NULL");
- goto unwind;
- }
+ struct quota_local *local = NULL;
- op_errno = local->op_errno;
+ local = frame->local;
- if (local->op_ret == -1) {
- goto unwind;
- }
-
- STACK_WIND (frame, quota_rename_cbk,
- FIRST_CHILD(this), FIRST_CHILD(this)->fops->rename, oldloc,
- newloc, xdata);
+ if (op_ret >= 0) {
+ local->stbuf = *buf;
+ }
- return 0;
+ STACK_WIND (frame, quota_rmdir_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->rmdir,
+ &local->loc);
-unwind:
- QUOTA_STACK_UNWIND (rename, frame, -1, op_errno, NULL, NULL,
- NULL, NULL, NULL, NULL);
- return 0;
+ return 0;
}
-static int32_t
-quota_rename_get_size_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)
-{
- quota_local_t *local = NULL;
- int32_t ret = 0;
- int64_t *size = 0;
-
- GF_ASSERT (frame);
- GF_VALIDATE_OR_GOTO_WITH_ERROR ("quota", this, out, op_errno,
- EINVAL);
- GF_VALIDATE_OR_GOTO_WITH_ERROR (this->name, xdata, out, op_errno,
- EINVAL);
- local = frame->local;
- GF_ASSERT (local);
- local->link_count = 1;
-
- if (op_ret < 0)
- goto out;
-
-
- ret = dict_get_bin (xdata, QUOTA_SIZE_KEY, (void **) &size);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_WARNING,
- "size key not present in dict");
- op_errno = EINVAL;
- goto out;
- }
- local->delta = ntoh64 (*size);
- quota_check_limit (frame, local->newloc.parent, this,
- NULL, NULL);
- return 0;
-
-out:
- quota_handle_validate_error (local, -1, op_errno);
- return 0;
-}
-
-int32_t
-quota_rename (call_frame_t *frame, xlator_t *this, loc_t *oldloc,
- loc_t *newloc, dict_t *xdata)
+int
+quota_rmdir (call_frame_t *frame, xlator_t *this, loc_t *loc)
{
- quota_priv_t *priv = NULL;
- int32_t ret = -1, op_errno = ENOMEM;
- quota_local_t *local = NULL;
- quota_inode_ctx_t *ctx = NULL;
- call_stub_t *stub = NULL;
+ struct quota_local *local = NULL;
+ struct quota_priv *priv = NULL;
- priv = this->private;
+ priv = this->private;
- WIND_IF_QUOTAOFF (priv->is_quota_on, off);
+ if (priv->disk_usage_limit) {
+ local = CALLOC (1, sizeof (struct quota_local));
+ frame->local = local;
- local = quota_local_new ();
- if (local == NULL) {
- goto err;
- }
-
- frame->local = local;
-
- ret = loc_copy (&local->oldloc, oldloc);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_WARNING, "loc_copy failed");
- goto err;
- }
+ loc_copy (&local->loc, loc);
- ret = loc_copy (&local->newloc, newloc);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_WARNING, "loc_copy failed");
- goto err;
- }
-
- stub = fop_rename_stub (frame, quota_rename_helper, oldloc, newloc,
- xdata);
- if (stub == NULL) {
- goto err;
- }
-
- LOCK (&local->lock);
- {
- local->link_count = 1;
- local->stub = stub;
- }
- UNLOCK (&local->lock);
-
- if (QUOTA_REG_OR_LNK_FILE (oldloc->inode->ia_type)) {
- ret = quota_inode_ctx_get (oldloc->inode, this, &ctx, 0);
- if (ctx == NULL) {
- gf_log (this->name, GF_LOG_WARNING,
- "quota context not set in inode (gfid:%s), "
- "considering file size as zero while enforcing "
- "quota on new ancestry",
- oldloc->inode ? uuid_utoa (oldloc->inode->gfid)
- : "0");
- local->delta = 0;
-
- } else {
-
- /* FIXME: We need to account for the size occupied by this
- * inode on the target directory. To avoid double
- * accounting, we need to modify enforcer to perform
- * quota_check_limit only uptil the least common ancestor
- * directory inode*/
-
- /* FIXME: The following code assumes that regular files and
- *linkfiles are present, in their entirety, in a single
- brick. This *assumption is invalid in the case of
- stripe.*/
-
- local->delta = ctx->buf.ia_blocks * 512;
- }
-
- } else if (IA_ISDIR (oldloc->inode->ia_type)) {
- ret = quota_validate (frame, oldloc->inode, this,
- quota_rename_get_size_cbk);
- if (ret){
- op_errno = -ret;
- goto err;
- }
-
- return 0;
- }
-
- quota_check_limit (frame, newloc->parent, this, NULL, NULL);
- return 0;
-
-err:
- QUOTA_STACK_UNWIND (rename, frame, -1, op_errno, NULL,
- NULL, NULL, NULL, NULL, NULL);
- return 0;
-
-off:
- STACK_WIND_TAIL (frame, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->rename, oldloc,
- newloc, xdata);
+ STACK_WIND (frame, quota_rmdir_stat_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->stat, loc);
+ return 0;
+ }
- return 0;
+ STACK_WIND (frame, quota_rmdir_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->rmdir,
+ loc);
+ return 0;
}
-int32_t
+int
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)
+ int32_t op_ret, int32_t op_errno, inode_t *inode,
+ struct stat *buf, struct stat *preparent,
+ struct stat *postparent)
{
- quota_local_t *local = NULL;
- quota_inode_ctx_t *ctx = NULL;
- quota_dentry_t *dentry = NULL;
+ struct quota_priv *priv = NULL;
+ int space_used = 0;
- if (op_ret < 0) {
- goto out;
- }
-
- local = frame->local;
+ priv = this->private;
- quota_inode_ctx_get (local->loc.inode, this, &ctx, 1);
- if (ctx == NULL) {
- gf_log (this->name, GF_LOG_DEBUG, "quota context is NULL on "
- "inode (%s). "
- "If quota is not enabled recently and crawler has "
- "finished crawling, its an error",
- uuid_utoa (local->loc.inode->gfid));
-
- goto out;
- }
-
- 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;
- }
- }
- UNLOCK (&ctx->lock);
-
-out:
- QUOTA_STACK_UNWIND (symlink, frame, op_ret, op_errno, inode, buf,
- preparent, postparent, xdata);
+ if ((op_ret >= 0) && priv->disk_usage_limit) {
+ space_used = GF_DISK_USAGE_STATBUF (buf->st_blocks) +
+ GF_DISK_DIRECTORY_USAGE (preparent->st_blocks,
+ postparent->st_blocks);
+ gf_quota_usage_add (this, space_used);
+ }
- return 0;
+ STACK_UNWIND_STRICT (symlink, frame, op_ret, op_errno, inode, buf,
+ preparent, postparent);
+ return 0;
}
int
-quota_symlink_helper (call_frame_t *frame, xlator_t *this, const char *linkpath,
- loc_t *loc, mode_t umask, dict_t *xdata)
+quota_symlink (call_frame_t *frame, xlator_t *this,
+ const char *linkpath, loc_t *loc)
{
- quota_local_t *local = NULL;
- int32_t op_errno = EINVAL;
- quota_priv_t *priv = NULL;
-
- local = frame->local;
- if (local == NULL) {
- gf_log (this->name, GF_LOG_WARNING, "local is NULL");
- goto unwind;
- }
+ struct quota_priv *priv = NULL;
- priv = this->private;
+ priv = this->private;
- if (local->op_ret == -1) {
- op_errno = local->op_errno;
- goto unwind;
+ if (gf_quota_check_free_disk (this) == -1) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "min-free-disk limit (%u) crossed, current available is %u",
+ priv->min_free_disk_limit, priv->current_free_disk);
+ STACK_UNWIND_STRICT (symlink, frame, -1, ENOSPC, NULL, NULL,
+ NULL, NULL);
+ return 0;
+
+ }
+ if (priv->current_disk_usage > priv->disk_usage_limit) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Disk usage limit (%"PRIu64") crossed, current usage is %"PRIu64"",
+ priv->disk_usage_limit, priv->current_disk_usage);
+ STACK_UNWIND_STRICT (symlink, frame, -1, ENOSPC, NULL, NULL,
+ NULL, NULL);
+ return 0;
}
- STACK_WIND (frame, quota_symlink_cbk,
- FIRST_CHILD(this), FIRST_CHILD(this)->fops->symlink,
- linkpath, loc, umask, xdata);
- return 0;
-
-unwind:
- QUOTA_STACK_UNWIND (symlink, frame, -1, op_errno, NULL, NULL,
- NULL, NULL, NULL);
- return 0;
+ STACK_WIND (frame, quota_symlink_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->symlink,
+ linkpath, loc);
+ return 0;
}
int
-quota_symlink (call_frame_t *frame, xlator_t *this, const char *linkpath,
- loc_t *loc, mode_t umask, dict_t *xdata)
-{
- quota_priv_t *priv = NULL;
- int32_t ret = -1;
- int32_t op_errno = ENOMEM;
- quota_local_t *local = NULL;
- call_stub_t *stub = NULL;
-
- priv = this->private;
-
- WIND_IF_QUOTAOFF (priv->is_quota_on, off);
-
- local = quota_local_new ();
- if (local == NULL) {
- goto err;
- }
-
- frame->local = local;
-
- ret = loc_copy (&local->loc, loc);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_WARNING, "loc_copy failed");
- goto err;
- }
-
- stub = fop_symlink_stub (frame, quota_symlink_helper, linkpath, loc,
- umask, xdata);
- if (stub == NULL) {
- goto err;
- }
-
- LOCK (&local->lock);
- {
- local->stub = stub;
- local->delta = strlen (linkpath);
- local->link_count = 1;
- }
- UNLOCK (&local->lock);
-
- quota_check_limit (frame, loc->parent, this, NULL, NULL);
- return 0;
-
-err:
- QUOTA_STACK_UNWIND (symlink, frame, -1, op_errno, NULL, NULL, NULL,
- NULL, NULL);
-
- return 0;
-
-off:
- STACK_WIND_TAIL (frame, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->symlink,
- linkpath, loc, umask, xdata);
- return 0;
-}
-
-
-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)
-{
- quota_local_t *local = NULL;
- quota_inode_ctx_t *ctx = NULL;
-
- if (op_ret < 0) {
- goto out;
- }
-
- local = frame->local;
- if (local == NULL) {
- gf_log (this->name, GF_LOG_WARNING, "local is NULL");
- goto out;
- }
-
- quota_inode_ctx_get (local->loc.inode, this, &ctx, 0);
- if (ctx == NULL) {
- gf_log (this->name, GF_LOG_DEBUG, "quota context is NULL on "
- "inode (%s). "
- "If quota is not enabled recently and crawler has "
- "finished crawling, its an error",
- uuid_utoa (local->loc.inode->gfid));
- goto out;
- }
-
- LOCK (&ctx->lock);
- {
- ctx->buf = *postbuf;
- }
- UNLOCK (&ctx->lock);
-
-out:
- QUOTA_STACK_UNWIND (truncate, frame, op_ret, op_errno, prebuf,
- postbuf, xdata);
- return 0;
-}
-
-
-int32_t
-quota_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset,
- dict_t *xdata)
-{
- quota_priv_t *priv = NULL;
- int32_t ret = -1;
- quota_local_t *local = NULL;
-
- priv = this->private;
-
- WIND_IF_QUOTAOFF (priv->is_quota_on, off);
-
- local = quota_local_new ();
- if (local == NULL) {
- goto err;
- }
-
- frame->local = local;
-
- ret = loc_copy (&local->loc, loc);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_WARNING, "loc_copy failed");
- goto err;
- }
-
- STACK_WIND (frame, quota_truncate_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->truncate, loc, offset, xdata);
-
- return 0;
-
-err:
- QUOTA_STACK_UNWIND (truncate, frame, -1, ENOMEM, NULL, NULL, NULL);
-
- return 0;
-off:
- STACK_WIND_TAIL (frame, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->truncate, loc, offset, xdata);
- return 0;
-}
-
-
-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)
-{
- quota_local_t *local = NULL;
- quota_inode_ctx_t *ctx = NULL;
-
- if (op_ret < 0) {
- goto out;
- }
-
- local = frame->local;
- if (local == NULL) {
- gf_log (this->name, GF_LOG_WARNING, "local is NULL");
- goto out;
- }
-
- quota_inode_ctx_get (local->loc.inode, this, &ctx, 0);
- if (ctx == NULL) {
- gf_log (this->name, GF_LOG_DEBUG, "quota context is NULL on "
- "inode (%s). "
- "If quota is not enabled recently and crawler has "
- "finished crawling, its an error",
- uuid_utoa (local->loc.inode->gfid));
- goto out;
- }
-
- LOCK (&ctx->lock);
- {
- ctx->buf = *postbuf;
- }
- UNLOCK (&ctx->lock);
-
-out:
- QUOTA_STACK_UNWIND (ftruncate, frame, op_ret, op_errno, prebuf,
- postbuf, xdata);
- return 0;
-}
-
-
-int32_t
-quota_ftruncate (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
- dict_t *xdata)
-{
- quota_priv_t *priv = NULL;
- quota_local_t *local = NULL;
-
- priv = this->private;
-
- WIND_IF_QUOTAOFF (priv->is_quota_on, off);
-
- local = quota_local_new ();
- if (local == NULL)
- goto err;
-
- frame->local = local;
-
- local->loc.inode = inode_ref (fd->inode);
-
- STACK_WIND (frame, quota_ftruncate_cbk,
- FIRST_CHILD(this), FIRST_CHILD(this)->fops->ftruncate, fd,
- offset, xdata);
-
- return 0;
-err:
- QUOTA_STACK_UNWIND (ftruncate, frame, -1, ENOMEM, NULL, NULL, NULL);
-
- return 0;
-
-off:
- STACK_WIND_TAIL (frame, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->ftruncate, fd,
- offset, xdata);
- return 0;
-}
-
-
-int32_t
-quota_send_dir_limit_to_cli (call_frame_t *frame, xlator_t *this,
- inode_t *inode, const char *name)
-{
- int32_t ret = 0;
- char dir_limit [1024] = {0, };
- dict_t *dict = NULL;
- quota_inode_ctx_t *ctx = NULL;
- uint64_t value = 0;
- quota_priv_t *priv = NULL;
-
- priv = this->private;
- if (!priv->is_quota_on) {
- snprintf (dir_limit, 1024, "Quota is disabled please turn on");
- goto dict_set;
- }
-
- ret = inode_ctx_get (inode, this, &value);
- if (ret < 0)
- goto out;
-
- ctx = (quota_inode_ctx_t *)(unsigned long)value;
- snprintf (dir_limit, 1024, "%"PRId64",%"PRId64, ctx->size,
- ctx->hard_lim);
-
-dict_set:
- dict = dict_new ();
- if (dict == NULL) {
- ret = -1;
- goto out;
- }
-
- ret = dict_set_str (dict, (char *) name, dir_limit);
- if (ret < 0)
- goto out;
-
- gf_log (this->name, GF_LOG_DEBUG, "str = %s", dir_limit);
-
- QUOTA_STACK_UNWIND (getxattr, frame, 0, 0, dict, NULL);
-
- ret = 0;
-
-out:
- return ret;
-}
-
-
-int32_t
-quota_fgetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
- const char *name, dict_t *xdata)
-{
- int32_t ret = 0;
-
- if (name && strcasecmp (name, "trusted.limit.list") == 0) {
- ret = quota_send_dir_limit_to_cli (frame, this, fd->inode,
- name);
- if (ret == 0) {
- return 0;
- }
- }
-
- STACK_WIND (frame, default_fgetxattr_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fgetxattr, fd, name, xdata);
- return 0;
-}
-
-
-int32_t
-quota_getxattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
- const char *name, dict_t *xdata)
-{
- int32_t ret = 0;
-
- if ((name != NULL) && strcasecmp (name, "trusted.limit.list") == 0) {
- ret = quota_send_dir_limit_to_cli (frame, this, loc->inode,
- name);
- if (ret == 0)
- return 0;
- }
-
- STACK_WIND (frame, default_getxattr_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->getxattr, loc, name, xdata);
- 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)
-{
- quota_local_t *local = NULL;
- quota_inode_ctx_t *ctx = NULL;
-
- if (op_ret < 0) {
- goto out;
- }
-
- local = frame->local;
- if (local == NULL) {
- gf_log (this->name, GF_LOG_WARNING, "local is NULL");
- goto out;
- }
-
- quota_inode_ctx_get (local->loc.inode, this, &ctx, 0);
- if (ctx == NULL) {
- if (!IA_ISDIR (buf->ia_type)) {
- gf_log (this->name, GF_LOG_DEBUG,
- "quota context is NULL on "
- "inode (%s). "
- "If quota is not enabled recently and crawler "
- "has finished crawling, its an error",
- uuid_utoa (local->loc.inode->gfid));
- }
-
- goto out;
- }
-
- LOCK (&ctx->lock);
- {
- if (buf)
- ctx->buf = *buf;
- }
- UNLOCK (&ctx->lock);
-
-out:
- QUOTA_STACK_UNWIND (stat, frame, op_ret, op_errno, buf, xdata);
- return 0;
-}
-
-
-int32_t
-quota_stat (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
-{
- quota_priv_t *priv = NULL;
- quota_local_t *local = NULL;
- int32_t ret = -1;
-
- priv = this->private;
-
- WIND_IF_QUOTAOFF (priv->is_quota_on, off);
-
- local = quota_local_new ();
- if (local == NULL) {
- goto unwind;
- }
-
- frame->local = local;
- ret = loc_copy (&local->loc, loc);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_WARNING, "loc_copy failed");
- goto unwind;
- }
-
- STACK_WIND (frame, quota_stat_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->stat, loc,
- xdata);
- return 0;
-
-unwind:
- QUOTA_STACK_UNWIND (stat, frame, -1, ENOMEM, NULL, NULL);
- return 0;
-
-off:
- STACK_WIND_TAIL (frame, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->stat, loc,
- xdata);
- 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)
-{
- quota_local_t *local = NULL;
- quota_inode_ctx_t *ctx = NULL;
-
- if (op_ret < 0) {
- goto out;
- }
-
- local = frame->local;
- if (local == NULL) {
- gf_log (this->name, GF_LOG_WARNING, "local is NULL");
- goto out;
- }
-
- quota_inode_ctx_get (local->loc.inode, this, &ctx, 0);
- if (ctx == NULL) {
- if (!IA_ISDIR (buf->ia_type)) {
- gf_log (this->name, GF_LOG_DEBUG,
- "quota context is NULL on "
- "inode (%s). "
- "If quota is not enabled recently and crawler "
- "has finished crawling, its an error",
- uuid_utoa (local->loc.inode->gfid));
- }
-
- goto out;
- }
-
- LOCK (&ctx->lock);
- {
- if (buf)
- ctx->buf = *buf;
- }
- UNLOCK (&ctx->lock);
-
-out:
- QUOTA_STACK_UNWIND (fstat, frame, op_ret, op_errno, buf, xdata);
- return 0;
-}
-
-
-int32_t
-quota_fstat (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
-{
- quota_priv_t *priv = NULL;
- quota_local_t *local = NULL;
-
- priv = this->private;
-
- WIND_IF_QUOTAOFF (priv->is_quota_on, off);
-
- local = quota_local_new ();
- if (local == NULL) {
- goto unwind;
- }
-
- frame->local = local;
-
- local->loc.inode = inode_ref (fd->inode);
-
- STACK_WIND (frame, quota_fstat_cbk,
- FIRST_CHILD(this), FIRST_CHILD(this)->fops->fstat, fd,
- xdata);
- return 0;
-
-unwind:
- QUOTA_STACK_UNWIND (fstat, frame, -1, ENOMEM, NULL, NULL);
- return 0;
-
-off:
- STACK_WIND_TAIL (frame, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fstat, fd,
- xdata);
- return 0;
-}
-
-
-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)
-{
- quota_local_t *local = NULL;
- quota_inode_ctx_t *ctx = NULL;
-
- if (op_ret < 0) {
- goto out;
- }
-
- local = frame->local;
- if (local == NULL) {
- gf_log (this->name, GF_LOG_WARNING, "local is NULL");
- goto out;
- }
-
- quota_inode_ctx_get (local->loc.inode, this, &ctx, 0);
- if (ctx == NULL) {
- gf_log (this->name, GF_LOG_DEBUG, "quota context is NULL on "
- "inode (%s). "
- "If quota is not enabled recently and crawler has "
- "finished crawling, its an error",
- uuid_utoa (local->loc.inode->gfid));
- goto out;
- }
-
- LOCK (&ctx->lock);
- {
- ctx->buf = *buf;
- }
- UNLOCK (&ctx->lock);
-
-out:
- QUOTA_STACK_UNWIND (readlink, frame, op_ret, op_errno, path, buf,
- xdata);
- return 0;
-}
-
-
-int32_t
-quota_readlink (call_frame_t *frame, xlator_t *this, loc_t *loc, size_t size,
- dict_t *xdata)
-{
- quota_priv_t *priv = NULL;
- quota_local_t *local = NULL;
- int32_t ret = -1;
-
- priv = this->private;
-
- WIND_IF_QUOTAOFF (priv->is_quota_on, off);
-
- local = quota_local_new ();
- if (local == NULL) {
- goto unwind;
- }
-
- frame->local = local;
-
- ret = loc_copy (&local->loc, loc);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_WARNING, "loc_copy failed");
- goto unwind;
- }
-
- STACK_WIND (frame, quota_readlink_cbk,
- FIRST_CHILD(this), FIRST_CHILD(this)->fops->readlink, loc,
- size, xdata);
- return 0;
-
-unwind:
- QUOTA_STACK_UNWIND (readlink, frame, -1, ENOMEM, NULL, NULL, NULL);
- return 0;
-
-off:
- STACK_WIND_TAIL (frame, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->readlink, loc,
- size, xdata);
- return 0;
-}
-
-
-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)
-{
- quota_local_t *local = NULL;
- quota_inode_ctx_t *ctx = NULL;
-
- if (op_ret < 0) {
- goto out;
- }
-
- local = frame->local;
- if (local == NULL) {
- gf_log (this->name, GF_LOG_WARNING, "local is NULL");
- goto out;
- }
-
- quota_inode_ctx_get (local->loc.inode, this, &ctx, 0);
- if (ctx == NULL) {
- gf_log (this->name, GF_LOG_DEBUG, "quota context is NULL on "
- "inode (%s). "
- "If quota is not enabled recently and crawler has "
- "finished crawling, its an error",
- uuid_utoa (local->loc.inode->gfid));
- goto out;
- }
-
- LOCK (&ctx->lock);
- {
- ctx->buf = *buf;
- }
- UNLOCK (&ctx->lock);
-
-out:
- QUOTA_STACK_UNWIND (readv, frame, op_ret, op_errno, vector, count,
- buf, iobref, xdata);
- 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)
-{
- quota_priv_t *priv = NULL;
- quota_local_t *local = NULL;
-
- priv = this->private;
-
- WIND_IF_QUOTAOFF (priv->is_quota_on, off);
-
- local = quota_local_new ();
- if (local == NULL) {
- goto unwind;
- }
-
- frame->local = local;
-
- 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);
- return 0;
-
-unwind:
- QUOTA_STACK_UNWIND (readv, frame, -1, ENOMEM, NULL, -1, NULL, NULL,
- NULL);
- return 0;
-
-off:
- STACK_WIND_TAIL (frame, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->readv, fd,
- size, offset, flags, xdata);
- return 0;
-}
-
-
-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)
-{
- quota_local_t *local = NULL;
- quota_inode_ctx_t *ctx = NULL;
-
- if (op_ret < 0) {
- goto out;
- }
-
- local = frame->local;
- if (local == NULL) {
- gf_log (this->name, GF_LOG_WARNING, "local is NULL");
- goto out;
- }
-
- quota_inode_ctx_get (local->loc.inode, this, &ctx, 0);
- if (ctx == NULL) {
- gf_log (this->name, GF_LOG_DEBUG, "quota context is NULL on "
- "inode (%s). "
- "If quota is not enabled recently and crawler has "
- "finished crawling, its an error",
- uuid_utoa (local->loc.inode->gfid));
- goto out;
- }
-
- LOCK (&ctx->lock);
- {
- ctx->buf = *postbuf;
- }
- UNLOCK (&ctx->lock);
-
-out:
- QUOTA_STACK_UNWIND (fsync, frame, op_ret, op_errno, prebuf, postbuf,
- xdata);
- return 0;
-}
-
-
-int32_t
-quota_fsync (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags,
- dict_t *xdata)
-{
- quota_priv_t *priv = NULL;
- quota_local_t *local = NULL;
-
- priv = this->private;
-
- WIND_IF_QUOTAOFF (priv->is_quota_on, off);
-
- local = quota_local_new ();
- if (local == NULL) {
- goto unwind;
- }
-
- local->loc.inode = inode_ref (fd->inode);
-
- frame->local = local;
-
- STACK_WIND (frame, quota_fsync_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fsync, fd,
- flags, xdata);
- return 0;
-
-unwind:
- QUOTA_STACK_UNWIND (fsync, frame, -1, ENOMEM, NULL, NULL, NULL);
- return 0;
-
-off:
- STACK_WIND_TAIL (frame, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fsync, fd,
- flags, xdata);
- return 0;
-}
-
-
-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)
-{
- quota_local_t *local = NULL;
- quota_inode_ctx_t *ctx = NULL;
-
- if (op_ret < 0) {
- goto out;
- }
-
- local = frame->local;
- if (local == NULL) {
- gf_log (this->name, GF_LOG_WARNING, "local is NULL");
- goto out;
- }
-
- quota_inode_ctx_get (local->loc.inode, this, &ctx, 0);
- if (ctx == NULL) {
- if (!IA_ISDIR (statpost->ia_type)) {
- gf_log (this->name, GF_LOG_DEBUG, "quota context is "
- "NULL on inode (%s). "
- "If quota is not enabled recently and crawler "
- "has finished crawling, its an error",
- uuid_utoa (local->loc.inode->gfid));
- }
-
- goto out;
- }
-
- LOCK (&ctx->lock);
- {
- if (statpost)
- ctx->buf = *statpost;
- }
- UNLOCK (&ctx->lock);
-
-out:
- QUOTA_STACK_UNWIND (setattr, frame, op_ret, op_errno, statpre,
- statpost, xdata);
- 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)
+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 stat *buf,
+ struct stat *preparent, struct stat *postparent)
{
- quota_priv_t *priv = NULL;
- quota_local_t *local = NULL;
- int32_t ret = -1;
+ struct quota_priv *priv = this->private;
+ int ret = 0;
- priv = this->private;
+ int space_used = 0;
- WIND_IF_QUOTAOFF (priv->is_quota_on, off);
+ if ((op_ret >= 0) && priv->current_disk_usage) {
+ space_used = GF_DISK_USAGE_STATBUF (buf->st_blocks) +
+ GF_DISK_DIRECTORY_USAGE (preparent->st_blocks,
+ postparent->st_blocks);
+ gf_quota_usage_add (this, space_used);
- local = quota_local_new ();
- if (local == NULL) {
- goto unwind;
- }
-
- frame->local = local;
-
- ret = loc_copy (&local->loc, loc);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_WARNING, "loc_copy failed");
- goto unwind;
- }
-
- STACK_WIND (frame, quota_setattr_cbk, FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->setattr, loc,
- stbuf, valid, xdata);
- return 0;
+ ret = fd_ctx_set (fd, this, 1);
+ }
-unwind:
- QUOTA_STACK_UNWIND (setattr, frame, -1, ENOMEM, NULL, NULL, NULL);
- return 0;
-
-off:
- STACK_WIND_TAIL (frame, FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->setattr, loc,
- stbuf, valid, xdata);
- return 0;
+ STACK_UNWIND_STRICT (create, frame, op_ret, op_errno, fd, inode, buf,
+ preparent, postparent);
+ return 0;
}
-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)
+int
+quota_create (call_frame_t *frame, xlator_t *this,
+ loc_t *loc, int32_t flags, mode_t mode, fd_t *fd)
{
- quota_local_t *local = NULL;
- quota_inode_ctx_t *ctx = NULL;
+ struct quota_priv *priv = NULL;
- if (op_ret < 0) {
- goto out;
- }
+ priv = this->private;
- local = frame->local;
- if (local == NULL) {
- gf_log (this->name, GF_LOG_WARNING, "local is NULL");
- goto out;
- }
-
- quota_inode_ctx_get (local->loc.inode, this, &ctx, 0);
- if (ctx == NULL) {
- if (!IA_ISDIR (statpost->ia_type)) {
- gf_log (this->name, GF_LOG_DEBUG, "quota context is "
- "NULL on inode (%s). "
- "If quota is not enabled recently and crawler "
- "has finished crawling, its an error",
- uuid_utoa (local->loc.inode->gfid));
- }
-
- goto out;
- }
-
- LOCK (&ctx->lock);
- {
- ctx->buf = *statpost;
+ if (gf_quota_check_free_disk (this) == -1) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "min-free-disk limit (%u) crossed, current available is %u",
+ priv->min_free_disk_limit, priv->current_free_disk);
+ STACK_UNWIND_STRICT (create, frame, -1, ENOSPC, NULL, NULL, NULL,
+ NULL, NULL);
+ return 0;
+
+ }
+ if (priv->current_disk_usage > priv->disk_usage_limit) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Disk usage limit (%"PRIu64") crossed, current usage is %"PRIu64"",
+ priv->disk_usage_limit, priv->current_disk_usage);
+ STACK_UNWIND_STRICT (create, frame, -1, ENOSPC, NULL, NULL, NULL,
+ NULL, NULL);
+ return 0;
}
- UNLOCK (&ctx->lock);
-out:
- QUOTA_STACK_UNWIND (fsetattr, frame, op_ret, op_errno, statpre,
- statpost, xdata);
- return 0;
+ STACK_WIND (frame, quota_create_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->create,
+ loc, flags, mode, fd);
+ 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)
+int
+quota_open_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, fd_t *fd)
{
- quota_priv_t *priv = NULL;
- quota_local_t *local = NULL;
+ int ret = 0;
- priv = this->private;
+ if (op_ret >= 0)
+ ret = fd_ctx_set (fd, this, 1);
- WIND_IF_QUOTAOFF (priv->is_quota_on, off);
-
- local = quota_local_new ();
- if (local == NULL) {
- goto unwind;
- }
-
- frame->local = local;
-
- 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);
- return 0;
-
-unwind:
- QUOTA_STACK_UNWIND (fsetattr, frame, -1, ENOMEM, NULL, NULL, NULL);
- return 0;
-
-off:
- STACK_WIND_TAIL (frame, FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->fsetattr, fd,
- stbuf, valid, xdata);
- 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, this, &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;
+ STACK_UNWIND_STRICT (open, frame, op_ret, op_errno, fd);
+ 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_open (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
+ fd_t *fd, int32_t wbflags)
{
- quota_local_t *local = NULL;
- int32_t op_errno = EINVAL;
- quota_priv_t *priv = NULL;
-
- local = frame->local;
- if (local == NULL) {
- gf_log (this->name, GF_LOG_WARNING, "local is NULL");
- goto unwind;
- }
-
- priv = this->private;
-
- 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;
+ STACK_WIND (frame, quota_open_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->open,
+ loc, flags, fd, wbflags);
+ 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)
+quota_writev_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct stat *prebuf,
+ struct stat *postbuf)
{
- quota_priv_t *priv = NULL;
- int32_t ret = -1;
- quota_local_t *local = NULL;
- call_stub_t *stub = NULL;
-
- priv = this->private;
-
- WIND_IF_QUOTAOFF (priv->is_quota_on, off);
-
- 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;
- }
+ struct quota_priv *priv = NULL;
+ struct quota_local *local = NULL;
- stub = fop_mknod_stub (frame, quota_mknod_helper, loc, mode, rdev,
- umask, xdata);
- if (stub == NULL) {
- goto err;
- }
-
- LOCK (&local->lock);
- {
- local->link_count = 1;
- local->stub = stub;
- local->delta = 0;
- }
- UNLOCK (&local->lock);
- quota_check_limit (frame, loc->parent, this, NULL, NULL);
- return 0;
+ priv = this->private;
+ local = frame->local;
-err:
- QUOTA_STACK_UNWIND (mknod, frame, -1, ENOMEM, NULL, NULL, NULL, NULL,
- NULL);
- return 0;
+ if (priv->disk_usage_limit) {
+ if (op_ret >= 0) {
+ gf_quota_usage_add (this, (postbuf->st_blocks -
+ prebuf->st_blocks) * 512);
+ }
+ fd_unref (local->fd);
+ iobref_unref (local->iobref);
+ }
-off:
- STACK_WIND_TAIL (frame, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->mknod, loc,
- mode, rdev, umask, xdata);
- return 0;
+ STACK_UNWIND_STRICT (writev, frame, op_ret, op_errno, prebuf, postbuf);
+ 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_local_t *local = NULL;
- quota_inode_ctx_t *ctx = NULL;
- int ret = 0;
-
- local = frame->local;
- if (!local)
- goto out;
-
- ret = quota_inode_ctx_get (local->loc.inode, this, &ctx, 1);
- if ((ret < 0) || (ctx == NULL)) {
- op_errno = ENOMEM;
- goto out;
- }
-
- LOCK (&ctx->lock);
- {
- ctx->hard_lim = local->limit.hard_lim;
- ctx->soft_lim = local->limit.soft_lim_percent;
- }
- UNLOCK (&ctx->lock);
-
-out:
- 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)
-{
- quota_priv_t *priv = NULL;
- int op_errno = EINVAL;
- int op_ret = -1;
- int64_t hard_lim = -1, soft_lim = -1;
- quota_local_t *local = NULL;
-
- priv = this->private;
-
- WIND_IF_QUOTAOFF (priv->is_quota_on, off);
-
- VALIDATE_OR_GOTO (frame, err);
- VALIDATE_OR_GOTO (this, err);
- VALIDATE_OR_GOTO (loc, err);
-
- if (frame->root->pid >= 0) {
- GF_IF_INTERNAL_XATTR_GOTO ("trusted.glusterfs.quota*", dict,
- op_errno, err);
- GF_IF_INTERNAL_XATTR_GOTO ("trusted.pgfid*", dict, op_errno,
- err);
- }
-
- quota_get_limits (this, dict, &hard_lim, &soft_lim);
-
- if (hard_lim > 0) {
- local = quota_local_new ();
- if (local == NULL) {
- op_errno = ENOMEM;
- goto err;
- }
-
- frame->local = local;
- loc_copy (&local->loc, loc);
-
- local->limit.hard_lim = hard_lim;
- local->limit.soft_lim_percent = soft_lim;
- }
+quota_writev_fstat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct stat *buf)
+{
+ struct quota_local *local = NULL;
+ struct quota_priv *priv = NULL;
+ int iovlen = 0;
+
+
+ local = frame->local;
+ priv = this->private;
+
+ if (op_ret >= 0) {
+ if (priv->current_disk_usage > priv->disk_usage_limit) {
+ iovlen = iov_length (local->vector, local->count);
+
+ if (iovlen > (buf->st_blksize - (buf->st_size % buf->st_blksize))) {
+ fd_unref (local->fd);
+ iobref_unref (local->iobref);
+ STACK_UNWIND_STRICT (writev, frame, -1, ENOSPC,
+ NULL, NULL);
+ return 0;
+ }
+ }
+ local->stbuf = *buf;
+ }
+
+ STACK_WIND (frame, quota_writev_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->writev,
+ local->fd, local->vector, local->count, local->offset,
+ local->iobref);
- 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;
-
-off:
- STACK_WIND_TAIL (frame, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->setxattr, loc,
- dict, flags, xdata);
- return 0;
+ 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_inode_ctx_t *ctx = NULL;
- quota_local_t *local = NULL;
-
- local = frame->local;
- if (!local)
- goto out;
-
- op_ret = quota_inode_ctx_get (local->loc.inode, this, &ctx, 1);
- if ((op_ret < 0) || (ctx == NULL)) {
- op_errno = ENOMEM;
- goto out;
- }
-
- LOCK (&ctx->lock);
- {
- ctx->hard_lim = local->limit.hard_lim;
- ctx->soft_lim = local->limit.soft_lim_percent;
- }
- UNLOCK (&ctx->lock);
-
-out:
- 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)
-{
- quota_priv_t *priv = NULL;
- int32_t op_ret = -1;
- int32_t op_errno = EINVAL;
- quota_local_t *local = NULL;
- int64_t hard_lim = -1, soft_lim = -1;
-
- priv = this->private;
-
- WIND_IF_QUOTAOFF (priv->is_quota_on, off);
-
- VALIDATE_OR_GOTO (frame, err);
- VALIDATE_OR_GOTO (this, err);
- VALIDATE_OR_GOTO (fd, err);
-
- if (0 <= frame->root->pid) {
- GF_IF_INTERNAL_XATTR_GOTO ("trusted.glusterfs.quota*",
- dict, op_errno, err);
- GF_IF_INTERNAL_XATTR_GOTO ("trusted.pgfid*", dict,
- op_errno, err);
- }
-
- quota_get_limits (this, dict, &hard_lim, &soft_lim);
+quota_writev (call_frame_t *frame, xlator_t *this, fd_t *fd,
+ struct iovec *vector, int32_t count, off_t off,
+ struct iobref *iobref)
+{
+ struct quota_local *local = NULL;
+ struct quota_priv *priv = NULL;
+ int i = 0;
+
+ priv = this->private;
+
+ if (gf_quota_check_free_disk (this) == -1) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "min-free-disk limit (%u) crossed, current available is %u",
+ priv->min_free_disk_limit, priv->current_free_disk);
+ STACK_UNWIND_STRICT (writev, frame, -1, ENOSPC,
+ NULL, NULL);
+ return 0;
+ }
- if (hard_lim > 0) {
- local = quota_local_new ();
- if (local == NULL) {
- op_errno = ENOMEM;
- goto err;
+ if (priv->disk_usage_limit) {
+ local = CALLOC (1, sizeof (struct quota_local));
+ local->fd = fd_ref (fd);
+ local->iobref = iobref_ref (iobref);
+ for (i = 0; i < count; i++) {
+ local->vector[i].iov_base = vector[i].iov_base;
+ local->vector[i].iov_len = vector[i].iov_len;
}
- frame->local = local;
- local->loc.inode = inode_ref (fd->inode);
- local->limit.hard_lim = hard_lim;
- local->limit.soft_lim_percent = soft_lim;
- }
+ local->count = count;
+ local->offset = off;
+ frame->local = local;
- 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;
-
-off:
- STACK_WIND_TAIL (frame, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fsetxattr, fd,
- dict, flags, xdata);
- return 0;
+ STACK_WIND (frame, quota_writev_fstat_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->fstat, fd);
+ return 0;
+ }
+
+ STACK_WIND (frame, quota_writev_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->writev,
+ fd, vector, count, off, iobref);
+ 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)
+ int32_t op_ret, int32_t op_errno)
{
- QUOTA_STACK_UNWIND (removexattr, frame, op_ret, op_errno, xdata);
- return 0;
+ if (op_ret == -1) {
+ gf_log (this->name, GF_LOG_CRITICAL,
+ "failed to remove the disk-usage value: %s",
+ strerror (op_errno));
+ }
+
+ STACK_DESTROY (frame->root);
+ return 0;
}
+
int
-quota_removexattr (call_frame_t *frame, xlator_t *this,
- loc_t *loc, const char *name, dict_t *xdata)
+quota_setxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno)
{
- quota_priv_t *priv = NULL;
- int32_t op_errno = EINVAL;
-
- priv = this->private;
-
- WIND_IF_QUOTAOFF (priv->is_quota_on, off);
+ dict_t *dict = NULL;
- VALIDATE_OR_GOTO (this, err);
+ if (op_ret == -1) {
+ gf_log (this->name, GF_LOG_CRITICAL,
+ "failed to set the disk-usage value: %s",
+ strerror (op_errno));
+ }
- /* all quota xattrs can be cleaned up by doing setxattr on special key.
- * Hence its ok that we don't allow removexattr on quota keys here.
- */
- if (frame->root->pid >= 0) {
- GF_IF_NATIVE_XATTR_GOTO ("trusted.glusterfs.quota*",
- name, op_errno, err);
- GF_IF_NATIVE_XATTR_GOTO ("trusted.pgfid*", name,
- op_errno, err);
+ if (cookie) {
+ dict = (dict_t *) cookie;
+ dict_unref (dict);
}
- 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;
-
-off:
- STACK_WIND_TAIL (frame, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->removexattr,
- loc, name, xdata);
- return 0;
+ STACK_DESTROY (frame->root);
+ 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)
+quota_statfs_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct statvfs *statvfs)
{
- quota_priv_t *priv = NULL;
- int32_t op_ret = -1;
- int32_t op_errno = EINVAL;
+ struct quota_priv *priv = NULL;
+ uint64_t f_blocks = 0;
+ int64_t f_bfree = 0;
+ uint64_t f_bused = 0;
- priv = this->private;
- WIND_IF_QUOTAOFF (priv->is_quota_on, off);
+ priv = this->private;
- VALIDATE_OR_GOTO (frame, err);
- VALIDATE_OR_GOTO (this, err);
- VALIDATE_OR_GOTO (fd, err);
-
- if (frame->root->pid >= 0) {
- GF_IF_NATIVE_XATTR_GOTO ("trusted.glusterfs.quota*",
- name, op_errno, err);
- GF_IF_NATIVE_XATTR_GOTO ("trusted.pgfid*", 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;
-
-off:
- STACK_WIND_TAIL (frame, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fremovexattr,
- fd, name, xdata);
- 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 *inode = NULL;
- uint64_t value = 0;
- int64_t usage = -1;
- int64_t avail = -1;
- int64_t blocks = 0;
- quota_inode_ctx_t *ctx = NULL;
- int ret = 0;
- gf_boolean_t dict_created = _gf_false;
- quota_local_t *local = frame->local;
-
- 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 (!inode) {
- gf_log(this->name,GF_LOG_WARNING,
- "null inode, cannot adjust for quota");
+ if (op_ret != 0)
goto unwind;
- }
- inode_ctx_get (inode, this, &value);
- ctx = (quota_inode_ctx_t *)(unsigned long)value;
- if (!ctx || ctx->hard_lim <= 0)
- goto unwind;
-
- { /* statfs is adjusted in this code block */
- usage = (ctx->size) / buf->f_bsize;
-
- blocks = ctx->hard_lim / buf->f_bsize;
- buf->f_blocks = blocks;
-
- avail = buf->f_blocks - usage;
- avail = max (avail, 0);
-
- 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;
- }
+ f_blocks = priv->disk_usage_limit / statvfs->f_frsize;
+ f_bused = priv->current_disk_usage / statvfs->f_frsize;
- if (!xdata) {
- xdata = dict_new ();
- if (!xdata)
- goto unwind;
- dict_created = _gf_true;
- }
-
- ret = dict_set_int8 (xdata, "quota-deem-statfs", 1);
- if (-1 == ret)
- gf_log (this->name, GF_LOG_ERROR, "Dict set failed, "
- "deem-statfs option may have no effect");
+ if (f_blocks && (f_blocks < statvfs->f_blocks))
+ statvfs->f_blocks = f_blocks;
-unwind:
- QUOTA_STACK_UNWIND (statfs, frame, op_ret, op_errno, buf, xdata);
+ f_bfree = (statvfs->f_blocks - f_bused);
- if (dict_created)
- dict_unref (xdata);
+ if (f_bfree >= 0)
+ statvfs->f_bfree = statvfs->f_bavail = f_bfree;
+ else
+ statvfs->f_bfree = statvfs->f_bavail = 0;
- return 0;
+unwind:
+ STACK_UNWIND_STRICT (statfs, frame, op_ret, op_errno, statvfs);
+ return 0;
}
-int32_t
-quota_statfs_helper (call_frame_t *frame, xlator_t *this, loc_t *loc,
- dict_t *xdata)
+int
+quota_statfs (call_frame_t *frame, xlator_t *this, loc_t *loc)
{
- quota_local_t *local = frame->local;
- int op_errno = EINVAL;
-
- GF_VALIDATE_OR_GOTO ("quota", local, err);
-
- if (-1 == local->op_ret) {
- op_errno = local->op_errno;
- goto err;
- }
+ STACK_WIND (frame, quota_statfs_cbk,
+ FIRST_CHILD (this), FIRST_CHILD (this)->fops->statfs, loc);
- STACK_WIND_COOKIE (frame, quota_statfs_cbk, local->inode,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->statfs, loc, xdata);
- return 0;
-err:
- QUOTA_STACK_UNWIND (statfs, frame, -1, op_errno, NULL, NULL);
-
- return 0;
+ return 0;
}
-int32_t
-quota_statfs_validate_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)
-{
- quota_local_t *local = NULL;
- int32_t ret = 0;
- quota_inode_ctx_t *ctx = NULL;
- int64_t *size = 0;
- uint64_t value = 0;
-
- local = frame->local;
-
- if (op_ret < 0)
- goto resume;
-
- GF_ASSERT (local);
- GF_ASSERT (frame);
- GF_VALIDATE_OR_GOTO_WITH_ERROR ("quota", this, resume, op_errno,
- EINVAL);
- GF_VALIDATE_OR_GOTO_WITH_ERROR (this->name, xdata, resume, op_errno,
- EINVAL);
-
- ret = inode_ctx_get (local->validate_loc.inode, this, &value);
-
- 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)",
- uuid_utoa (local->validate_loc.inode->gfid));
- op_errno = EINVAL;
- goto resume;
- }
-
- ret = dict_get_bin (xdata, QUOTA_SIZE_KEY, (void **) &size);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_WARNING,
- "size key not present in dict");
- op_errno = EINVAL;
- goto resume;
- }
-
- LOCK (&ctx->lock);
- {
- ctx->size = ntoh64 (*size);
- gettimeofday (&ctx->tv, NULL);
- }
- UNLOCK (&ctx->lock);
-
-resume:
- quota_link_count_decrement (local);
- return 0;
-}
-void
-quota_get_limit_dir_continuation (struct list_head *parents, inode_t *inode,
- int32_t op_ret, int32_t op_errno, void *data)
+int
+quota_getxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *value)
{
- call_frame_t *frame = NULL;
- xlator_t *this = NULL;
- quota_local_t *local = NULL;
- quota_dentry_t *entry = NULL;
- inode_t *parent = NULL;
-
- frame = data;
- local = frame->local;
- this = THIS;
-
- if ((op_ret < 0) || list_empty (parents)) {
- if (op_ret >= 0) {
- gf_log (this->name, GF_LOG_WARNING,
- "Couldn't build ancestry for inode (gfid:%s). "
- "Without knowing ancestors till root, quota "
- "cannot be enforced. "
- "Hence, failing fop with EIO",
- uuid_utoa (inode->gfid));
- op_errno = EIO;
- }
-
- quota_handle_validate_error (local, -1, op_errno);
- goto out;
- }
+ data_t *data = NULL;
+ struct quota_priv *priv = this->private;
+
+ if (op_ret >= 0) {
+ data = dict_get (value, "trusted.glusterfs-quota-du");
+ if (data) {
+ LOCK (&priv->lock);
+ {
+ priv->current_disk_usage = data_to_uint64 (data);
+ }
+ UNLOCK (&priv->lock);
- entry = list_entry (parents, quota_dentry_t, next);
- parent = inode_find (inode->table, entry->par);
+ return 0;
+ }
+ }
- quota_get_limit_dir (frame, parent, this);
+ STACK_DESTROY (frame->root);
- inode_unref (parent);
-out:
- return;
+ return 0;
}
-void
-quota_statfs_continue (call_frame_t *frame, xlator_t *this, inode_t *inode)
-{
- call_stub_t *stub = NULL;
- quota_local_t *local = frame->local;
- int ret = -1;
-
- stub = fop_statfs_stub (frame, quota_statfs_helper,
- &local->loc, local->xdata);
- if (!stub)
- goto err;
-
- LOCK (&local->lock);
- {
- local->inode = inode_ref (inode);
- local->link_count = 1;
- local->stub = stub;
- }
- UNLOCK (&local->lock);
-
- ret = quota_validate (frame, local->inode, this,
- quota_statfs_validate_cbk);
- if (0 > ret)
- quota_handle_validate_error (local, -1, -ret);
- return;
-
-err:
- QUOTA_STACK_UNWIND (statfs, frame, -1, ENOMEM, NULL, NULL);
-
- return;
-}
void
-quota_get_limit_dir (call_frame_t *frame, inode_t *cur_inode, xlator_t *this)
+gf_quota_get_disk_usage (xlator_t *this)
{
- inode_t *inode = NULL;
- inode_t *parent = NULL;
- uint64_t value = 0;
- quota_inode_ctx_t *ctx = NULL;
- int ret = -1;
- quota_local_t *local = frame->local;
-
- if (!cur_inode)
- goto out;
-
- inode = inode_ref (cur_inode);
- while (inode) {
- value = 0;
- inode_ctx_get (inode, this, &value);
-
- if (value) {
- ctx = (quota_inode_ctx_t *)(unsigned long)value;
- if (ctx->hard_lim > 0)
- break;
- }
-
- if (__is_root_gfid (inode->gfid))
- goto off;
-
- parent = inode_parent (inode, 0, NULL);
- if (!parent) {
- ret = quota_build_ancestry
- (inode, quota_get_limit_dir_continuation,
- (void *)frame);
- goto out;
- }
-
- inode_unref (inode);
- inode = parent;
- }
-
- quota_statfs_continue (frame, this, inode);
- inode_unref (inode);
- return;
+ call_frame_t *frame = NULL;
+ call_pool_t *pool = NULL;
-off:
- gf_log (this->name, GF_LOG_DEBUG,
- "No limit set on the inode or it's parents.");
+ struct quota_priv *priv = NULL;
- QUOTA_STACK_WIND_TAIL (frame, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->statfs,
- &local->loc, local->xdata);
-out:
- inode_unref (inode);
+ pool = this->ctx->pool;
+ frame = create_frame (this, pool);
+ priv = this->private;
- return;
+ STACK_WIND (frame, quota_getxattr_cbk,
+ this->children->xlator,
+ this->children->xlator->fops->getxattr,
+ &(priv->root_loc),
+ "trusted.glusterfs-quota-du");
+ return ;
}
-int32_t
-quota_statfs (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
-{
- int op_errno = 0;
- int ret = -1;
- int8_t ignore_deem_statfs = 0;
- quota_priv_t *priv = NULL;
- quota_local_t *local = NULL;
-
- priv = this->private;
- GF_ASSERT (loc);
-
- WIND_IF_QUOTAOFF (priv->is_quota_on, off);
-
- ret = dict_get_int8 (xdata, GF_INTERNAL_IGNORE_DEEM_STATFS,
- &ignore_deem_statfs);
- ret = 0;
- if (ignore_deem_statfs)
- goto off;
-
- if (priv->consider_statfs && loc->inode) {
- local = quota_local_new ();
- if (!local) {
- op_errno = ENOMEM;
- goto err;
- }
-
- ret = loc_copy (&local->loc, loc);
- if (-1 == ret) {
- op_errno = ENOMEM;
- goto err;
- }
-
- if (xdata)
- local->xdata = dict_ref (xdata);
-
- local->link_count = 1;
-
- frame->local = local;
-
- quota_get_limit_dir (frame, loc->inode, this);
-
- return 0;
- }
-
- /*
- * 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.
- *
- * Also if the option deem-statfs is not set to "on" don't
- * bother calculating quota limit on / in statfs_cbk.
- */
- if (priv->consider_statfs)
- gf_log (this->name, GF_LOG_ERROR,
- "Missing inode, can't adjust for quota");
-
-
-off:
- STACK_WIND_TAIL (frame, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->statfs, loc, xdata);
- return 0;
-
-err:
- QUOTA_STACK_UNWIND (statfs, frame, -1, op_errno, NULL, NULL);
-
- 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;
- quota_local_t *local = NULL;
- loc_t loc = {0, };
-
- if (op_ret <= 0)
- goto unwind;
-
- local = frame->local;
-
- list_for_each_entry (entry, &entries->list, list) {
- if ((strcmp (entry->d_name, ".") == 0) ||
- (strcmp (entry->d_name, "..") == 0) ||
- entry->inode == NULL)
- continue;
-
- uuid_copy (loc.gfid, entry->d_stat.ia_gfid);
- loc.inode = inode_ref (entry->inode);
- loc.parent = inode_ref (local->loc.inode);
- uuid_copy (loc.pargfid, loc.parent->gfid);
- loc.name = entry->d_name;
-
- quota_fill_inodectx (this, entry->inode, entry->dict,
- &loc, &entry->d_stat, &op_errno);
-
- loc_wipe (&loc);
- }
-
-unwind:
- QUOTA_STACK_UNWIND (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)
+void
+gf_quota_cache_sync (xlator_t *this)
{
- quota_priv_t *priv = NULL;
- int ret = 0;
- gf_boolean_t new_dict = _gf_false;
- quota_local_t *local = NULL;
-
- priv = this->private;
-
- WIND_IF_QUOTAOFF (priv->is_quota_on, off);
-
- local = quota_local_new ();
-
- if (local == NULL) {
- goto err;
- }
-
- frame->local = local;
-
- local->loc.inode = inode_ref (fd->inode);
-
- if (dict == NULL) {
- dict = dict_new ();
- new_dict = _gf_true;
- }
-
- if (dict) {
- ret = dict_set_int8 (dict, QUOTA_LIMIT_KEY, 1);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_WARNING,
- "dict set of key for hard-limit failed");
- goto err;
- }
- }
+ struct quota_priv *priv = NULL;
+ call_frame_t *frame = NULL;
+ dict_t *dict = get_new_dict ();
- STACK_WIND (frame, quota_readdirp_cbk,
- FIRST_CHILD(this), FIRST_CHILD(this)->fops->readdirp, fd,
- size, offset, dict);
- if (new_dict) {
- dict_unref (dict);
- }
- return 0;
-err:
- STACK_UNWIND_STRICT (readdirp, frame, -1, EINVAL, NULL, NULL);
+ priv = this->private;
- if (new_dict) {
- dict_unref (dict);
- }
+ frame = create_frame (this, this->ctx->pool);
+ dict_set (dict, "trusted.glusterfs-quota-du",
+ data_from_uint64 (priv->current_disk_usage));
- return 0;
+ dict_ref (dict);
-off:
- STACK_WIND_TAIL (frame, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->readdirp, fd,
- size, offset, dict);
- return 0;
+ STACK_WIND_COOKIE (frame, quota_setxattr_cbk,
+ (void *) (dict_t *) dict,
+ this->children->xlator,
+ this->children->xlator->fops->setxattr,
+ &(priv->root_loc), dict, 0);
}
-int32_t
-quota_fallocate_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 ret = 0;
- uint64_t ctx_int = 0;
- quota_inode_ctx_t *ctx = NULL;
- quota_local_t *local = NULL;
-
- local = frame->local;
-
- if ((op_ret < 0) || (local == NULL)) {
- goto out;
- }
-
- 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));
- goto out;
- }
-
- LOCK (&ctx->lock);
- {
- ctx->buf = *postbuf;
- }
- UNLOCK (&ctx->lock);
-
-out:
- QUOTA_STACK_UNWIND (fallocate, frame, op_ret, op_errno, prebuf, postbuf,
- xdata);
-
- return 0;
-}
-
-int32_t
-quota_fallocate_helper (call_frame_t *frame, xlator_t *this, fd_t *fd,
- int32_t mode, off_t offset, size_t len, dict_t *xdata)
+int
+quota_release (xlator_t *this, fd_t *fd)
{
- quota_local_t *local = NULL;
- int32_t op_errno = EINVAL;
- quota_priv_t *priv = NULL;
-
- local = frame->local;
- if (local == NULL) {
- gf_log (this->name, GF_LOG_WARNING, "local is NULL");
- goto unwind;
- }
-
- priv = this->private;
+ gf_quota_cache_sync (this);
- if (local->op_ret == -1) {
- op_errno = local->op_errno;
- goto unwind;
- }
-
- STACK_WIND (frame, quota_fallocate_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fallocate, fd, mode, offset, len,
- xdata);
- return 0;
-
-unwind:
- QUOTA_STACK_UNWIND (fallocate, frame, -1, op_errno, NULL, NULL, NULL);
- return 0;
+ return 0;
}
+/* notify */
int32_t
-quota_fallocate(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t mode,
- off_t offset, size_t len, dict_t *xdata)
-{
- int32_t ret = -1, op_errno = EINVAL;
- int32_t parents = 0;
- quota_local_t *local = NULL;
- quota_inode_ctx_t *ctx = NULL;
- quota_priv_t *priv = NULL;
- quota_dentry_t *dentry = NULL;
- call_stub_t *stub = NULL;
-
- priv = this->private;
- GF_VALIDATE_OR_GOTO (this->name, priv, unwind);
-
- WIND_IF_QUOTAOFF (priv->is_quota_on, off);
-
- GF_ASSERT (frame);
- GF_VALIDATE_OR_GOTO ("quota", this, unwind);
- GF_VALIDATE_OR_GOTO (this->name, fd, unwind);
-
- local = quota_local_new ();
- if (local == NULL) {
- goto unwind;
- }
-
- frame->local = local;
- local->loc.inode = inode_ref (fd->inode);
-
- ret = quota_inode_ctx_get (fd->inode, this, &ctx, 0);
- if (ctx == NULL) {
- gf_log (this->name, GF_LOG_DEBUG, "quota context is "
- "NULL on inode (%s). "
- "If quota is not enabled recently and crawler "
- "has finished crawling, its an error",
- uuid_utoa (local->loc.inode->gfid));
- }
-
- stub = fop_fallocate_stub(frame, quota_fallocate_helper, fd, mode,
- offset, len, xdata);
- if (stub == NULL) {
- op_errno = ENOMEM;
- goto unwind;
- }
-
- priv = this->private;
- GF_VALIDATE_OR_GOTO (this->name, priv, unwind);
-
- if (ctx != NULL) {
- LOCK (&ctx->lock);
- {
- list_for_each_entry (dentry, &ctx->parents, next) {
- parents++;
- }
- }
- UNLOCK (&ctx->lock);
- }
-
- /*
- * Note that by using len as the delta we're assuming the range from
- * offset to offset+len has not already been allocated. This can result
- * in ENOSPC errors attempting to allocate an already allocated range.
- */
- local->delta = len;
- local->stub = stub;
- local->link_count = parents;
-
- if (parents == 0) {
- local->link_count = 1;
- quota_check_limit (frame, fd->inode, this, NULL, NULL);
- } else {
- list_for_each_entry (dentry, &ctx->parents, next) {
- quota_check_limit (frame, fd->inode, this, dentry->name,
- dentry->par);
- }
- }
-
- return 0;
-
-unwind:
- QUOTA_STACK_UNWIND (fallocate, frame, -1, op_errno, NULL, NULL, NULL);
- return 0;
-
-off:
- STACK_WIND_TAIL (frame, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fallocate, fd, mode, offset,
- len, xdata);
- return 0;
-}
-
-void
-quota_log_helper (char **usage_str, int64_t cur_size, inode_t *inode,
- char **path, struct timeval *cur_time)
-{
- xlator_t *this = THIS;
-
- if (!usage_str || !inode || !path || !cur_time) {
- gf_log (this->name, GF_LOG_ERROR, "Received null argument");
- return;
- }
-
- *usage_str = gf_uint64_2human_readable (cur_size);
- if (!(*usage_str))
- gf_log (this->name, GF_LOG_ERROR, "integer to string "
- "conversion failed Reason:\"Cannot allocate memory\"");
-
- inode_path (inode, NULL, path);
- if (!(*path))
- *path = uuid_utoa (inode->gfid);
-
- gettimeofday (cur_time, NULL);
-}
-
-/* Logs if
-* i. Usage crossed soft limit
-* ii. Usage above soft limit and alert-time elapsed
-*/
-void
-quota_log_usage (xlator_t *this, quota_inode_ctx_t *ctx, inode_t *inode,
- int64_t delta)
+notify (xlator_t *this,
+ int32_t event,
+ void *data,
+ ...)
{
- struct timeval cur_time = {0,};
- char *usage_str = NULL;
- char *path = NULL;
- int64_t cur_size = 0;
- quota_priv_t *priv = NULL;
-
- priv = this->private;
- cur_size = ctx->size + delta;
-
- if ((ctx->soft_lim <= 0) || cur_size < ctx->soft_lim)
- return;
-
- /* Usage crossed/reached soft limit */
- if (DID_REACH_LIMIT (ctx->soft_lim, ctx->size, cur_size)) {
-
- quota_log_helper (&usage_str, cur_size, inode,
- &path, &cur_time);
-
- gf_log (this->name, GF_LOG_ALERT, "Usage crossed "
- "soft limit: %s used by %s", usage_str, path);
- ctx->prev_log = cur_time;
- }
- /* Usage is above soft limit */
- else if (cur_size > ctx->soft_lim &&
- quota_timeout (&ctx->prev_log, priv->log_timeout)) {
-
- quota_log_helper (&usage_str, cur_size, inode,
- &path, &cur_time);
-
- gf_log (this->name, GF_LOG_ALERT, "Usage is above "
- "soft limit: %s used by %s", usage_str, path);
- ctx->prev_log = cur_time;
- }
-
- if (usage_str)
- GF_FREE (usage_str);
+ default_notify (this, event, data);
+ return 0;
}
int32_t
-mem_acct_init (xlator_t *this)
-{
- int ret = -1;
-
- if (!this)
- return ret;
-
- ret = xlator_mem_acct_init (this, gf_quota_mt_end + 1);
-
- if (ret != 0) {
- gf_log (this->name, GF_LOG_WARNING, "Memory accounting"
- "init failed");
- return ret;
- }
-
- return ret;
+quota_lookup_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ inode_t *inode,
+ struct stat *buf,
+ dict_t *dict,
+ struct stat *postparent)
+{
+ STACK_UNWIND (frame,
+ op_ret,
+ op_errno,
+ inode,
+ buf,
+ dict,
+ postparent);
+ return 0;
}
int32_t
-quota_forget (xlator_t *this, inode_t *inode)
-{
- int32_t ret = 0;
- uint64_t ctx_int = 0;
- quota_inode_ctx_t *ctx = NULL;
- quota_dentry_t *dentry = NULL, *tmp;
-
- ret = inode_ctx_del (inode, this, &ctx_int);
-
- if (ret < 0) {
- return 0;
- }
-
- ctx = (quota_inode_ctx_t *) (long)ctx_int;
-
- LOCK (&ctx->lock);
- {
- list_for_each_entry_safe (dentry, tmp, &ctx->parents, next) {
- __quota_dentry_free (dentry);
- }
- }
- UNLOCK (&ctx->lock);
-
- LOCK_DESTROY (&ctx->lock);
+quota_lookup (call_frame_t *frame,
+ xlator_t *this,
+ loc_t *loc,
+ dict_t *xattr_req)
+{
+ struct quota_priv *priv = NULL;
+
+ priv = this->private;
+
+ if (priv->only_first_time) {
+ if (strcmp (loc->path, "/") == 0) {
+ loc_copy(&(priv->root_loc), loc);
+ priv->only_first_time = 0;
+ if (priv->disk_usage_limit)
+ gf_quota_get_disk_usage (this);
+ }
+ }
- GF_FREE (ctx);
+ STACK_WIND (frame,
+ quota_lookup_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->lookup,
+ loc,
+ xattr_req);
+ return 0;
+ }
- return 0;
-}
-
-int32_t
+int32_t
init (xlator_t *this)
{
- int32_t ret = -1;
- quota_priv_t *priv = NULL;
- rpc_clnt_t *rpc = NULL;
-
- if ((this->children == NULL)
- || this->children->next) {
- gf_log (this->name, GF_LOG_ERROR,
- "FATAL: quota (%s) not configured with "
- "exactly one child", this->name);
- return -1;
- }
-
- if (this->parents == NULL) {
- gf_log (this->name, GF_LOG_WARNING,
- "dangling volume. check volfile");
- }
-
- QUOTA_ALLOC_OR_GOTO (priv, quota_priv_t, err);
-
- LOCK_INIT (&priv->lock);
-
- this->private = priv;
-
- GF_OPTION_INIT ("deem-statfs", priv->consider_statfs, bool, err);
- GF_OPTION_INIT ("server-quota", priv->is_quota_on, bool, err);
- GF_OPTION_INIT ("default-soft-limit", priv->default_soft_lim, percent,
- err);
- GF_OPTION_INIT ("soft-timeout", priv->soft_timeout, time, err);
- GF_OPTION_INIT ("hard-timeout", priv->hard_timeout, time, err);
- GF_OPTION_INIT ("alert-time", priv->log_timeout, time, err);
- GF_OPTION_INIT ("volume-uuid", priv->volume_uuid, str, err);
+ int ret = 0;
+ data_t *data = NULL;
+ struct quota_priv *_private = NULL;
- 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;
- }
-
- if (priv->is_quota_on) {
- rpc = quota_enforcer_init (this, this->options);
- if (rpc == NULL) {
- ret = -1;
- gf_log (this->name, GF_LOG_WARNING,
- "quota enforcer rpc init failed");
- goto err;
- }
+ if (!this->children || this->children->next) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "FATAL: quota should have exactly one child");
+ return -1;
+ }
+
+ if (!this->parents) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "dangling volume. check volfile ");
+ }
- LOCK (&priv->lock);
- {
- priv->rpc_clnt = rpc;
+ _private = CALLOC (1, sizeof (struct quota_priv));
+ _private->disk_usage_limit = 0;
+ data = dict_get (this->options, "disk-usage-limit");
+ if (data) {
+ if (gf_string2bytesize (data->data, &_private->disk_usage_limit) != 0) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "invalid number '%s' for disk-usage limit", data->data);
+ ret = -1;
+ goto out;
}
- UNLOCK (&priv->lock);
- }
-
- ret = 0;
-err:
- return ret;
-}
-int
-reconfigure (xlator_t *this, dict_t *options)
-{
- int32_t ret = -1;
- quota_priv_t *priv = NULL;
- gf_boolean_t quota_on = _gf_false;
- rpc_clnt_t *rpc = NULL;
-
- priv = this->private;
-
- GF_OPTION_RECONF ("deem-statfs", priv->consider_statfs, options, bool,
- out);
- GF_OPTION_RECONF ("server-quota", quota_on, options, bool,
- out);
- GF_OPTION_RECONF ("default-soft-limit", priv->default_soft_lim,
- options, percent, out);
- GF_OPTION_RECONF ("alert-time", priv->log_timeout, options,
- time, out);
- GF_OPTION_RECONF ("soft-timeout", priv->soft_timeout, options,
- time, out);
- GF_OPTION_RECONF ("hard-timeout", priv->hard_timeout, options,
- time, out);
-
- if (quota_on) {
- priv->rpc_clnt = quota_enforcer_init (this,
- this->options);
- if (priv->rpc_clnt == NULL) {
- ret = -1;
- gf_log (this->name, GF_LOG_WARNING,
- "quota enforcer rpc init failed");
- goto out;
- }
-
- } else {
- LOCK (&priv->lock);
- {
- rpc = priv->rpc_clnt;
- priv->rpc_clnt = NULL;
- }
- UNLOCK (&priv->lock);
-
- if (rpc != NULL) {
- // Quotad is shutdown when there is no started volume
- // which has quota enabled. So, we should disable the
- // enforcer client when quota is disabled on a volume,
- // to avoid spurious reconnect attempts to a service
- // (quotad), that is known to be down.
- rpc_clnt_unref (rpc);
+ LOCK_INIT (&_private->lock);
+ _private->current_disk_usage = 0;
+ }
+
+ _private->min_free_disk_limit = 0;
+ data = dict_get (this->options, "min-free-disk-limit");
+ if (data) {
+ if (gf_string2percent (data->data, &_private->min_free_disk_limit) != 0) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "invalid percent '%s' for min-free-disk limit", data->data);
+ ret = -1;
+ goto out;
}
- }
-
- priv->is_quota_on = quota_on;
-
- ret = 0;
-out:
- return ret;
-}
-
-int32_t
-quota_priv_dump (xlator_t *this)
-{
- quota_priv_t *priv = NULL;
- int32_t ret = -1;
-
-
- GF_ASSERT (this);
-
- priv = this->private;
-
- gf_proc_dump_add_section ("xlators.features.quota.priv", this->name);
-
- ret = TRY_LOCK (&priv->lock);
- if (ret)
- goto out;
- else {
- gf_proc_dump_write("soft-timeout", "%d", priv->soft_timeout);
- gf_proc_dump_write("hard-timeout", "%d", priv->hard_timeout);
- gf_proc_dump_write("alert-time", "%d", priv->log_timeout);
- gf_proc_dump_write("quota-on", "%d", priv->is_quota_on);
- gf_proc_dump_write("statfs", "%d", priv->consider_statfs);
- gf_proc_dump_write("volume-uuid", "%s", priv->volume_uuid);
- gf_proc_dump_write("validation-count", "%ld",
- priv->validation_count);
- }
- UNLOCK (&priv->lock);
-
-out:
- return 0;
-}
-
-void
+ _private->refresh_interval = 20; /* 20seconds is default */
+ data = dict_get (this->options, "refresh-interval");
+ if (data) {
+ if (gf_string2time (data->data,
+ &_private->refresh_interval)!= 0) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "invalid time '%s' for refresh "
+ "interval", data->data);
+ ret = -1;
+ goto out;
+ }
+ }
+ }
+
+ _private->only_first_time = 1;
+ this->private = (void *)_private;
+ ret = 0;
+ out:
+ return ret;
+}
+
+void
fini (xlator_t *this)
{
- return;
-}
+ struct quota_priv *_private = this->private;
+ if (_private) {
+ gf_quota_cache_sync (this);
+ this->private = NULL;
+ }
+
+ return ;
+}
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,
- .fallocate = quota_fallocate,
+ .create = quota_create,
+ .open = quota_open,
+ .lookup = quota_lookup,
+ .truncate = quota_truncate,
+ .ftruncate = quota_ftruncate,
+ .writev = quota_writev,
+ .unlink = quota_unlink,
+ .rmdir = quota_rmdir,
+ .mknod = quota_mknod,
+ .mkdir = quota_mkdir,
+ .symlink = quota_symlink,
+ .statfs = quota_statfs,
};
-struct xlator_cbks cbks = {
- .forget = quota_forget
+struct xlator_mops mops = {
};
-struct xlator_dumpops dumpops = {
- .priv = quota_priv_dump,
+struct xlator_cbks cbks = {
+ .release = quota_release
};
+
struct volume_options options[] = {
- {.key = {"limit-set"}},
- {.key = {"deem-statfs"},
- .type = GF_OPTION_TYPE_BOOL,
- .default_value = "off",
- .description = "If set to on, it takes quota limits into"
- "consideration while estimating fs size. (df command)"
- " (Default is off)."
- },
- {.key = {"server-quota"},
- .type = GF_OPTION_TYPE_BOOL,
- .default_value = "off",
- .description = "Skip the quota enforcement if the feature is"
- " not turned on. This is not a user exposed option."
- },
- {.key = {"default-soft-limit"},
- .type = GF_OPTION_TYPE_PERCENT,
- .default_value = "80%",
- },
- {.key = {"soft-timeout"},
- .type = GF_OPTION_TYPE_TIME,
- .min = 0,
- .max = 1800,
- .default_value = "60",
- .description = "quota caches the directory sizes on client. "
- "soft-timeout indicates the timeout for the validity of"
- " cache before soft-limit has been crossed."
- },
- {.key = {"hard-timeout"},
- .type = GF_OPTION_TYPE_TIME,
- .min = 0,
- .max = 60,
- .default_value = "5",
- .description = "quota caches the directory sizes on client. "
- "hard-timeout indicates the timeout for the validity of"
- " cache after soft-limit has been crossed."
- },
- { .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", "rdma"},
- .type = GF_OPTION_TYPE_STR,
- },
- { .key = {"remote-host"},
- .type = GF_OPTION_TYPE_INTERNET_ADDRESS,
- },
- { .key = {"remote-port"},
- .type = GF_OPTION_TYPE_INT,
- },
- { .key = {"volume-uuid"},
- .type = GF_OPTION_TYPE_STR,
- .description = "uuid of the volume this brick is part of."
- },
- { .key = {"alert-time"},
- .type = GF_OPTION_TYPE_TIME,
- .min = 0,
- .max = 7*86400,
- .default_value = "86400",
- },
- {.key = {NULL}}
+ { .key = {"min-free-disk-limit"},
+ .type = GF_OPTION_TYPE_PERCENT
+ },
+ { .key = {"refresh-interval"},
+ .type = GF_OPTION_TYPE_TIME
+ },
+ { .key = {"disk-usage-limit"},
+ .type = GF_OPTION_TYPE_SIZET
+ },
+ { .key = {NULL} },
};
diff --git a/xlators/features/quota/src/quota.h b/xlators/features/quota/src/quota.h
deleted file mode 100644
index 149582593ff..00000000000
--- a/xlators/features/quota/src/quota.h
+++ /dev/null
@@ -1,245 +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
-
-#ifndef _QUOTA_H
-#define _QUOTA_H
-
-#include "xlator.h"
-#include "call-stub.h"
-#include "defaults.h"
-#include "common-utils.h"
-#include "quota-mem-types.h"
-#include "glusterfs.h"
-#include "compat.h"
-#include "logging.h"
-#include "dict.h"
-#include "stack.h"
-#include "common-utils.h"
-#include "event.h"
-#include "globals.h"
-#include "rpcsvc.h"
-#include "rpc-clnt.h"
-#include "byte-order.h"
-#include "glusterfs3-xdr.h"
-#include "glusterfs3.h"
-#include "xdr-generic.h"
-#include "compat-errno.h"
-#include "protocol-common.h"
-
-#define DIRTY "dirty"
-#define SIZE "size"
-#define CONTRIBUTION "contri"
-#define VAL_LENGTH 8
-#define READDIR_BUF 4096
-
-#ifndef UUID_CANONICAL_FORM_LEN
-#define UUID_CANONICAL_FORM_LEN 36
-#endif
-
-#define WIND_IF_QUOTAOFF(is_quota_on, label) \
- if (!is_quota_on) \
- goto label;
-
-#define DID_REACH_LIMIT(lim, prev_size, cur_size) \
- ((cur_size) >= (lim) && (prev_size) < (lim))
-
-#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)
-
-#define QUOTA_ALLOC_OR_GOTO(var, type, label) \
- do { \
- var = GF_CALLOC (sizeof (type), 1, \
- gf_quota_mt_##type); \
- if (!var) { \
- gf_log ("", GF_LOG_ERROR, \
- "out of memory"); \
- ret = -1; \
- goto label; \
- } \
- } while (0);
-
-#define QUOTA_STACK_WIND_TAIL(frame, params...) \
- do { \
- quota_local_t *_local = NULL; \
- xlator_t *_this = NULL; \
- \
- if (frame) { \
- _local = frame->local; \
- _this = frame->this; \
- frame->local = NULL; \
- } \
- \
- STACK_WIND_TAIL (frame, params); \
- \
- if (_local) \
- quota_local_cleanup (_this, _local); \
- } while (0)
-
-#define QUOTA_STACK_UNWIND(fop, frame, params...) \
- do { \
- quota_local_t *_local = NULL; \
- xlator_t *_this = NULL; \
- if (frame) { \
- _local = frame->local; \
- _this = frame->this; \
- frame->local = NULL; \
- } \
- STACK_UNWIND_STRICT (fop, frame, params); \
- quota_local_cleanup (_this, _local); \
- } while (0)
-
-#define QUOTA_FREE_CONTRIBUTION_NODE(_contribution) \
- do { \
- list_del (&_contribution->contri_list); \
- GF_FREE (_contribution); \
- } while (0)
-
-#define GET_CONTRI_KEY(var, _vol_name, _gfid, _ret) \
- do { \
- char _gfid_unparsed[40]; \
- if (_gfid != NULL) { \
- uuid_unparse (_gfid, _gfid_unparsed); \
- _ret = gf_asprintf (var, QUOTA_XATTR_PREFIX \
- "%s.%s." CONTRIBUTION, \
- _vol_name, _gfid_unparsed); \
- } else { \
- _ret = gf_asprintf (var, QUOTA_XATTR_PREFIX \
- "%s.." CONTRIBUTION, \
- _vol_name); \
- } \
- } while (0)
-
-
-#define GET_CONTRI_KEY_OR_GOTO(var, _vol_name, _gfid, label) \
- do { \
- GET_CONTRI_KEY(var, _vol_name, _gfid, ret); \
- if (ret == -1) \
- goto label; \
- } while (0)
-
-#define GET_DIRTY_KEY_OR_GOTO(var, _vol_name, label) \
- do { \
- ret = gf_asprintf (var, QUOTA_XATTR_PREFIX \
- "%s." DIRTY, _vol_name); \
- if (ret == -1) \
- goto label; \
- } while (0)
-
-#define QUOTA_REG_OR_LNK_FILE(ia_type) \
- (IA_ISREG (ia_type) || IA_ISLNK (ia_type))
-
-
-
-struct quota_dentry {
- char *name;
- uuid_t par;
- struct list_head next;
-};
-typedef struct quota_dentry quota_dentry_t;
-
-struct quota_inode_ctx {
- int64_t size;
- int64_t hard_lim;
- int64_t soft_lim;
- struct iatt buf;
- struct list_head parents;
- struct timeval tv;
- struct timeval prev_log;
- gf_boolean_t ancestry_built;
- gf_lock_t lock;
-};
-typedef struct quota_inode_ctx quota_inode_ctx_t;
-
-struct quota_limit {
- int64_t hard_lim;
- int64_t soft_lim_percent;
-} __attribute__ ((packed));
-typedef struct quota_limit quota_limit_t;
-
-typedef void
-(*quota_ancestry_built_t) (struct list_head *parents, inode_t *inode,
- int32_t op_ret, int32_t op_errno, void *data);
-
-struct quota_local {
- gf_lock_t lock;
- uint32_t validate_count;
- uint32_t link_count;
- loc_t loc;
- loc_t oldloc;
- loc_t newloc;
- loc_t validate_loc;
- int64_t delta;
- int32_t op_ret;
- int32_t op_errno;
- int64_t size;
- gf_boolean_t skip_check;
- char just_validated;
- fop_lookup_cbk_t validate_cbk;
- inode_t *inode;
- call_stub_t *stub;
- struct iobref *iobref;
- quota_limit_t limit;
- int64_t space_available;
- quota_ancestry_built_t ancestry_cbk;
- void *ancestry_data;
- dict_t *xdata;
-};
-typedef struct quota_local quota_local_t;
-
-struct quota_priv {
- uint32_t soft_timeout;
- uint32_t hard_timeout;
- uint32_t log_timeout;
- double default_soft_lim;
- gf_boolean_t is_quota_on;
- gf_boolean_t consider_statfs;
- gf_lock_t lock;
- rpc_clnt_prog_t *quota_enforcer;
- struct rpcsvc_program *quotad_aggregator;
- struct rpc_clnt *rpc_clnt;
- rpcsvc_t *rpcsvc;
- inode_table_t *itable;
- char *volume_uuid;
- uint64_t validation_count;
-};
-typedef struct quota_priv quota_priv_t;
-
-void
-check_ancestory_2 (xlator_t *this, quota_local_t *local, inode_t *inode);
-
-int
-quota_build_ancestry (inode_t *inode, quota_ancestry_built_t ancestry_cbk,
- void *data);
-int
-quota_enforcer_lookup (call_frame_t *frame, xlator_t *this, loc_t *loc,
- dict_t *xdata, fop_lookup_cbk_t cbk);
-struct rpc_clnt *
-quota_enforcer_init (xlator_t *this, dict_t *options);
-
-void
-quota_log_usage (xlator_t *this, quota_inode_ctx_t *ctx, inode_t *inode,
- int64_t delta);
-
-#endif
diff --git a/xlators/features/quota/src/quotad-aggregator.c b/xlators/features/quota/src/quotad-aggregator.c
deleted file mode 100644
index 2c2b8589356..00000000000
--- a/xlators/features/quota/src/quotad-aggregator.c
+++ /dev/null
@@ -1,419 +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 "cli1-xdr.h"
-#include "quota.h"
-#include "quotad-helpers.h"
-#include "quotad-aggregator.h"
-
-struct rpcsvc_program quotad_aggregator_prog;
-
-struct iobuf *
-quotad_serialize_reply (rpcsvc_request_t *req, void *arg, struct iovec *outmsg,
- xdrproc_t xdrproc)
-{
- struct iobuf *iob = NULL;
- ssize_t retlen = 0;
- ssize_t xdr_size = 0;
-
- 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;
- }
- }
- outmsg->iov_len = retlen;
-ret:
- if (retlen == -1) {
- iobuf_unref (iob);
- iob = NULL;
- }
-
- return iob;
-}
-
-int
-quotad_aggregator_submit_reply (call_frame_t *frame, rpcsvc_request_t *req,
- void *arg, struct iovec *payload,
- int payloadcount, struct iobref *iobref,
- xdrproc_t xdrproc)
-{
- struct iobuf *iob = NULL;
- int ret = -1;
- struct iovec rsp = {0,};
- quotad_aggregator_state_t *state = NULL;
- char new_iobref = 0;
-
- GF_VALIDATE_OR_GOTO ("server", req, ret);
-
- if (frame) {
- state = frame->root->state;
- frame->local = NULL;
- }
-
- if (!iobref) {
- iobref = iobref_new ();
- if (!iobref) {
- goto ret;
- }
-
- new_iobref = 1;
- }
-
- iob = quotad_serialize_reply (req, arg, &rsp, xdrproc);
- if (!iob) {
- gf_log ("", GF_LOG_ERROR, "Failed to serialize reply");
- goto ret;
- }
-
- iobref_add (iobref, iob);
-
- ret = rpcsvc_submit_generic (req, &rsp, 1, payload, payloadcount,
- iobref);
-
- iobuf_unref (iob);
-
- ret = 0;
-ret:
- if (state) {
- quotad_aggregator_free_state (state);
- }
-
- if (frame)
- STACK_DESTROY (frame->root);
-
- if (new_iobref) {
- iobref_unref (iobref);
- }
-
- return ret;
-}
-
-int
-quotad_aggregator_getlimit_cbk (xlator_t *this, call_frame_t *frame,
- void *lookup_rsp)
-{
- gfs3_lookup_rsp *rsp = lookup_rsp;
- gf_cli_rsp cli_rsp = {0,};
- dict_t *xdata = NULL;
- int ret = -1;
-
- GF_PROTOCOL_DICT_UNSERIALIZE (frame->this, xdata,
- (rsp->xdata.xdata_val),
- (rsp->xdata.xdata_len), rsp->op_ret,
- rsp->op_errno, out);
-
- ret = 0;
-out:
- rsp->op_ret = ret;
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "failed to unserialize "
- "nameless lookup rsp");
- goto reply;
- }
- cli_rsp.op_ret = rsp->op_ret;
- cli_rsp.op_errno = rsp->op_errno;
- cli_rsp.op_errstr = "";
- if (xdata) {
- GF_PROTOCOL_DICT_SERIALIZE (frame->this, xdata,
- (&cli_rsp.dict.dict_val),
- (cli_rsp.dict.dict_len),
- cli_rsp.op_errno, reply);
- }
-
-reply:
- quotad_aggregator_submit_reply (frame, frame->local, (void*)&cli_rsp, NULL, 0,
- NULL, (xdrproc_t)xdr_gf_cli_rsp);
-
- dict_unref (xdata);
- GF_FREE (cli_rsp.dict.dict_val);
- return 0;
-}
-
-int
-quotad_aggregator_getlimit (rpcsvc_request_t *req)
-{
- call_frame_t *frame = NULL;
- gf_cli_req cli_req = {{0}, };
- gf_cli_rsp cli_rsp = {0};
- gfs3_lookup_req args = {{0,},};
- gfs3_lookup_rsp rsp = {0,};
- quotad_aggregator_state_t *state = NULL;
- xlator_t *this = NULL;
- dict_t *dict = NULL;
- int ret = -1, op_errno = 0;
- char *gfid_str = NULL;
- uuid_t gfid = {0};
-
- GF_VALIDATE_OR_GOTO ("quotad-aggregator", req, err);
-
- this = THIS;
-
- ret = xdr_to_generic (req->msg[0], &cli_req, (xdrproc_t)xdr_gf_cli_req);
- if (ret < 0) {
- //failed to decode msg;
- gf_log ("", GF_LOG_ERROR, "xdr decoding error");
- req->rpc_err = GARBAGE_ARGS;
- goto err;
- }
-
- 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 err;
- }
- }
-
- ret = dict_get_str (dict, "gfid", &gfid_str);
- if (ret) {
- goto err;
- }
-
- uuid_parse ((const char*)gfid_str, gfid);
-
- frame = quotad_aggregator_get_frame_from_req (req);
- if (frame == NULL) {
- rsp.op_errno = ENOMEM;
- goto err;
- }
- state = frame->root->state;
- state->xdata = dict;
- ret = dict_set_int32 (state->xdata, QUOTA_LIMIT_KEY, 42);
- if (ret)
- goto err;
-
- ret = dict_set_int32 (state->xdata, QUOTA_SIZE_KEY, 42);
- if (ret)
- goto err;
-
- ret = dict_set_int32 (state->xdata, GET_ANCESTRY_PATH_KEY, 42);
- if (ret)
- goto err;
-
- memcpy (&args.gfid, &gfid, 16);
-
- args.bname = alloca (req->msg[0].iov_len);
- args.xdata.xdata_val = alloca (req->msg[0].iov_len);
-
- ret = qd_nameless_lookup (this, frame, &args, state->xdata,
- quotad_aggregator_getlimit_cbk);
- if (ret) {
- rsp.op_errno = ret;
- goto err;
- }
-
- return ret;
-
-err:
- cli_rsp.op_ret = -1;
- cli_rsp.op_errno = op_errno;
- cli_rsp.op_errstr = "";
-
- quotad_aggregator_getlimit_cbk (this, frame, &cli_rsp);
- dict_unref (dict);
-
- return ret;
-}
-
-int
-quotad_aggregator_lookup_cbk (xlator_t *this, call_frame_t *frame,
- void *rsp)
-{
- quotad_aggregator_submit_reply (frame, frame->local, rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gfs3_lookup_rsp);
-
- return 0;
-}
-
-
-int
-quotad_aggregator_lookup (rpcsvc_request_t *req)
-{
- call_frame_t *frame = NULL;
- gfs3_lookup_req args = {{0,},};
- int ret = -1, op_errno = 0;
- gfs3_lookup_rsp rsp = {0,};
- quotad_aggregator_state_t *state = NULL;
- xlator_t *this = NULL;
-
- GF_VALIDATE_OR_GOTO ("quotad-aggregator", req, err);
-
- this = THIS;
-
- args.bname = alloca (req->msg[0].iov_len);
- args.xdata.xdata_val = alloca (req->msg[0].iov_len);
-
- ret = xdr_to_generic (req->msg[0], &args,
- (xdrproc_t)xdr_gfs3_lookup_req);
- if (ret < 0) {
- rsp.op_errno = EINVAL;
- goto err;
- }
-
- frame = quotad_aggregator_get_frame_from_req (req);
- if (frame == NULL) {
- rsp.op_errno = ENOMEM;
- goto err;
- }
-
- state = frame->root->state;
-
- GF_PROTOCOL_DICT_UNSERIALIZE (this, state->xdata,
- (args.xdata.xdata_val),
- (args.xdata.xdata_len), ret,
- op_errno, err);
-
-
- ret = qd_nameless_lookup (this, frame, &args, state->xdata,
- quotad_aggregator_lookup_cbk);
- if (ret) {
- rsp.op_errno = ret;
- goto err;
- }
-
- return ret;
-
-err:
- rsp.op_ret = -1;
- rsp.op_errno = op_errno;
-
- quotad_aggregator_lookup_cbk (this, frame, &rsp);
- return ret;
-}
-
-int
-quotad_aggregator_rpc_notify (rpcsvc_t *rpc, void *xl, rpcsvc_event_t event,
- void *data)
-{
- if (!xl || !data) {
- gf_log_callingfn ("server", GF_LOG_WARNING,
- "Calling rpc_notify without initializing");
- goto out;
- }
-
- switch (event) {
- case RPCSVC_EVENT_ACCEPT:
- break;
-
- case RPCSVC_EVENT_DISCONNECT:
- break;
-
- default:
- break;
- }
-
-out:
- return 0;
-}
-
-int
-quotad_aggregator_init (xlator_t *this)
-{
- quota_priv_t *priv = NULL;
- int ret = -1;
-
- priv = this->private;
-
- ret = dict_set_str (this->options, "transport.address-family", "unix");
- if (ret)
- goto out;
-
- ret = dict_set_str (this->options, "transport-type", "socket");
- if (ret)
- goto out;
-
- ret = dict_set_str (this->options, "transport.socket.listen-path",
- "/tmp/quotad.socket");
- if (ret)
- goto out;
-
- /* RPC related */
- priv->rpcsvc = rpcsvc_init (this, this->ctx, this->options, 0);
- if (priv->rpcsvc == NULL) {
- gf_log (this->name, GF_LOG_WARNING,
- "creation of rpcsvc failed");
- ret = -1;
- goto out;
- }
-
- ret = rpcsvc_create_listeners (priv->rpcsvc, this->options,
- this->name);
- if (ret < 1) {
- gf_log (this->name, GF_LOG_WARNING,
- "creation of listener failed");
- ret = -1;
- goto out;
- }
-
- priv->quotad_aggregator = &quotad_aggregator_prog;
- quotad_aggregator_prog.options = this->options;
-
- ret = rpcsvc_program_register (priv->rpcsvc, &quotad_aggregator_prog);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING,
- "registration of program (name:%s, prognum:%d, "
- "progver:%d) failed", quotad_aggregator_prog.progname,
- quotad_aggregator_prog.prognum,
- quotad_aggregator_prog.progver);
- goto out;
- }
-
- ret = 0;
-out:
- return ret;
-}
-
-rpcsvc_actor_t quotad_aggregator_actors[GF_AGGREGATOR_MAXVALUE] = {
- [GF_AGGREGATOR_NULL] = {"NULL", GF_AGGREGATOR_NULL, NULL, NULL, 0,
- DRC_NA},
- [GF_AGGREGATOR_LOOKUP] = {"LOOKUP", GF_AGGREGATOR_NULL,
- quotad_aggregator_lookup, NULL, 0, DRC_NA},
- [GF_AGGREGATOR_GETLIMIT] = {"GETLIMIT", GF_AGGREGATOR_GETLIMIT,
- quotad_aggregator_getlimit, NULL, 0, DRC_NA},
-};
-
-
-struct rpcsvc_program quotad_aggregator_prog = {
- .progname = "GlusterFS 3.3",
- .prognum = GLUSTER_AGGREGATOR_PROGRAM,
- .progver = GLUSTER_AGGREGATOR_VERSION,
- .numactors = GF_AGGREGATOR_MAXVALUE,
- .actors = quotad_aggregator_actors
-};
diff --git a/xlators/features/quota/src/quotad-aggregator.h b/xlators/features/quota/src/quotad-aggregator.h
deleted file mode 100644
index 5ddea5b3c46..00000000000
--- a/xlators/features/quota/src/quotad-aggregator.h
+++ /dev/null
@@ -1,37 +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 _QUOTAD_AGGREGATOR_H
-#define _QUOTAD_AGGREGATOR_H
-
-#include "quota.h"
-#include "stack.h"
-#include "glusterfs3-xdr.h"
-#include "inode.h"
-
-typedef struct {
- void *pool;
- xlator_t *this;
- xlator_t *active_subvol;
- inode_table_t *itable;
- loc_t loc;
- dict_t *xdata;
-} quotad_aggregator_state_t;
-
-typedef int (*quotad_aggregator_lookup_cbk_t) (xlator_t *this,
- call_frame_t *frame,
- void *rsp);
-int
-qd_nameless_lookup (xlator_t *this, call_frame_t *frame, gfs3_lookup_req *req,
- dict_t *xdata, quotad_aggregator_lookup_cbk_t lookup_cbk);
-int
-quotad_aggregator_init (xlator_t *this);
-
-#endif
diff --git a/xlators/features/quota/src/quotad-helpers.c b/xlators/features/quota/src/quotad-helpers.c
deleted file mode 100644
index 9a98ab17a24..00000000000
--- a/xlators/features/quota/src/quotad-helpers.c
+++ /dev/null
@@ -1,107 +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 "quotad-helpers.h"
-
-quotad_aggregator_state_t *
-get_quotad_aggregator_state (xlator_t *this, rpcsvc_request_t *req)
-{
- quotad_aggregator_state_t *state = NULL;
- xlator_t *active_subvol = NULL;
- quota_priv_t *priv = NULL;
-
- state = (void *)GF_CALLOC (1, sizeof (*state),
- gf_quota_mt_aggregator_state_t);
- if (!state)
- return NULL;
-
- state->this = THIS;
- priv = this->private;
-
- LOCK (&priv->lock);
- {
- active_subvol = state->active_subvol = FIRST_CHILD (this);
- }
- UNLOCK (&priv->lock);
-
- if (active_subvol->itable == NULL)
- active_subvol->itable = inode_table_new (4096, active_subvol);
-
- state->itable = active_subvol->itable;
-
- state->pool = this->ctx->pool;
-
- return state;
-}
-
-void
-quotad_aggregator_free_state (quotad_aggregator_state_t *state)
-{
- if (state->xdata)
- dict_unref (state->xdata);
-
- GF_FREE (state);
-}
-
-call_frame_t *
-quotad_aggregator_alloc_frame (rpcsvc_request_t *req)
-{
- call_frame_t *frame = NULL;
- quotad_aggregator_state_t *state = NULL;
- xlator_t *this = NULL;
-
- GF_VALIDATE_OR_GOTO ("server", req, out);
- GF_VALIDATE_OR_GOTO ("server", req->trans, out);
- GF_VALIDATE_OR_GOTO ("server", req->svc, out);
- GF_VALIDATE_OR_GOTO ("server", req->svc->ctx, out);
-
- this = req->svc->mydata;
-
- frame = create_frame (this, req->svc->ctx->pool);
- if (!frame)
- goto out;
-
- state = get_quotad_aggregator_state (this, req);
- if (!state)
- goto out;
-
- frame->root->state = state;
- frame->root->unique = 0;
-
- frame->this = this;
-out:
- return frame;
-}
-
-call_frame_t *
-quotad_aggregator_get_frame_from_req (rpcsvc_request_t *req)
-{
- call_frame_t *frame = NULL;
-
- GF_VALIDATE_OR_GOTO ("server", req, out);
-
- frame = quotad_aggregator_alloc_frame (req);
- if (!frame)
- goto out;
-
- frame->root->op = req->procnum;
-
- frame->root->unique = req->xid;
-
- frame->root->uid = req->uid;
- frame->root->gid = req->gid;
- frame->root->pid = req->pid;
-
- frame->root->lk_owner = req->lk_owner;
-
- frame->local = req;
-out:
- return frame;
-}
diff --git a/xlators/features/quota/src/quotad-helpers.h b/xlators/features/quota/src/quotad-helpers.h
deleted file mode 100644
index a10fb7fa82a..00000000000
--- a/xlators/features/quota/src/quotad-helpers.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 QUOTAD_HELPERS_H
-#define QUOTAD_HELPERS_H
-
-#include "rpcsvc.h"
-#include "quota.h"
-#include "quotad-aggregator.h"
-
-void
-quotad_aggregator_free_state (quotad_aggregator_state_t *state);
-
-call_frame_t *
-quotad_aggregator_get_frame_from_req (rpcsvc_request_t *req);
-
-#endif
diff --git a/xlators/features/quota/src/quotad.c b/xlators/features/quota/src/quotad.c
deleted file mode 100644
index 243b943e986..00000000000
--- a/xlators/features/quota/src/quotad.c
+++ /dev/null
@@ -1,210 +0,0 @@
-/*
- Copyright (c) 2013 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 "quota.h"
-#include "quotad-aggregator.h"
-#include "common-utils.h"
-
-int32_t
-mem_acct_init (xlator_t *this)
-{
- int ret = -1;
-
- if (!this)
- return ret;
-
- ret = xlator_mem_acct_init (this, gf_quota_mt_end + 1);
-
- if (0 != ret) {
- gf_log (this->name, GF_LOG_WARNING, "Memory accounting "
- "init failed");
- return ret;
- }
-
- return ret;
-}
-
-int32_t
-qd_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)
-{
- quotad_aggregator_lookup_cbk_t lookup_cbk = NULL;
- gfs3_lookup_rsp rsp = {0, };
-
- lookup_cbk = cookie;
-
- rsp.op_ret = op_ret;
- rsp.op_errno = op_errno;
-
- gf_stat_from_iatt (&rsp.postparent, postparent);
-
- GF_PROTOCOL_DICT_SERIALIZE (this, xdata, (&rsp.xdata.xdata_val),
- rsp.xdata.xdata_len, rsp.op_errno, out);
-
- gf_stat_from_iatt (&rsp.stat, buf);
-
-out:
- lookup_cbk (this, frame, &rsp);
-
- GF_FREE (rsp.xdata.xdata_val);
-
- inode_unref (inode);
-
- return 0;
-}
-
-xlator_t *
-qd_find_subvol (xlator_t *this, char *volume_uuid)
-{
- xlator_list_t *child = NULL;
- xlator_t *subvol = NULL;
- char key[1024];
- char *optstr = NULL;
-
- if (!this || !volume_uuid)
- goto out;
-
- for (child = this->children; child; child = child->next) {
- snprintf(key, 1024, "%s.volume-id", child->xlator->name);
- if (dict_get_str(this->options, key, &optstr) < 0)
- continue;
-
- if (strcmp (optstr, volume_uuid) == 0) {
- subvol = child->xlator;
- break;
- }
- }
-
-out:
- return subvol;
-}
-
-int
-qd_nameless_lookup (xlator_t *this, call_frame_t *frame, gfs3_lookup_req *req,
- dict_t *xdata, quotad_aggregator_lookup_cbk_t lookup_cbk)
-{
- gfs3_lookup_rsp rsp = {0, };
- int op_errno = 0, ret = -1;
- loc_t loc = {0, };
- quotad_aggregator_state_t *state = NULL;
- quota_priv_t *priv = NULL;
- xlator_t *subvol = NULL;
- char *volume_uuid = NULL;
-
- priv = this->private;
- state = frame->root->state;
-
- frame->root->op = GF_FOP_LOOKUP;
-
- loc.inode = inode_new (state->itable);
- if (loc.inode == NULL) {
- op_errno = ENOMEM;
- goto out;
- }
-
- memcpy (loc.gfid, req->gfid, 16);
-
- ret = dict_get_str (xdata, "volume-uuid", &volume_uuid);
- if (ret < 0) {
- op_errno = EINVAL;
- goto out;
- }
-
- subvol = qd_find_subvol (this, volume_uuid);
- if (subvol == NULL) {
- op_errno = EINVAL;
- goto out;
- }
-
- STACK_WIND_COOKIE (frame, qd_lookup_cbk, lookup_cbk, subvol,
- subvol->fops->lookup, &loc, xdata);
- return 0;
-
-out:
- rsp.op_ret = -1;
- rsp.op_errno = op_errno;
-
- lookup_cbk (this, frame, &rsp);
-
- inode_unref (loc.inode);
- return 0;
-}
-
-int
-qd_reconfigure (xlator_t *this, dict_t *options)
-{
- /* As of now quotad is restarted upon alteration of volfile */
- return 0;
-}
-
-void
-qd_fini (xlator_t *this)
-{
- return;
-}
-
-int32_t
-qd_init (xlator_t *this)
-{
- int32_t ret = -1;
- quota_priv_t *priv = NULL;
-
- if (NULL == this->children) {
- gf_log (this->name, GF_LOG_ERROR,
- "FATAL: quota (%s) not configured for min of 1 child",
- this->name);
- ret = -1;
- goto err;
- }
-
- QUOTA_ALLOC_OR_GOTO (priv, quota_priv_t, err);
- LOCK_INIT (&priv->lock);
-
- this->private = priv;
-
- ret = quotad_aggregator_init (this);
- if (ret < 0)
- goto err;
-
- ret = 0;
-err:
- if (ret) {
- GF_FREE (priv);
- }
- return ret;
-}
-
-class_methods_t class_methods = {
- .init = qd_init,
- .fini = qd_fini,
- .reconfigure = qd_reconfigure,
-};
-
-struct xlator_fops fops = {
-};
-
-struct xlator_cbks cbks = {
-};
-
-struct volume_options options[] = {
- { .key = {"transport-type"},
- .value = {"rpc", "rpc-over-rdma", "tcp", "socket", "ib-verbs",
- "unix", "ib-sdp", "tcp/server", "ib-verbs/server", "rdma",
- "rdma*([ \t]),*([ \t])socket",
- "rdma*([ \t]),*([ \t])tcp",
- "tcp*([ \t]),*([ \t])rdma",
- "socket*([ \t]),*([ \t])rdma"},
- .type = GF_OPTION_TYPE_STR
- },
- { .key = {"transport.*"},
- .type = GF_OPTION_TYPE_ANY,
- },
- {.key = {NULL}}
-};
diff --git a/xlators/features/read-only/Makefile.am b/xlators/features/read-only/Makefile.am
deleted file mode 100644
index d471a3f9243..00000000000
--- a/xlators/features/read-only/Makefile.am
+++ /dev/null
@@ -1,3 +0,0 @@
-SUBDIRS = src
-
-CLEANFILES =
diff --git a/xlators/features/read-only/src/Makefile.am b/xlators/features/read-only/src/Makefile.am
deleted file mode 100644
index 4c146213742..00000000000
--- a/xlators/features/read-only/src/Makefile.am
+++ /dev/null
@@ -1,22 +0,0 @@
-xlator_LTLIBRARIES = read-only.la worm.la
-
-xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/features
-
-noinst_HEADERS = read-only-common.h
-
-read_only_la_LDFLAGS = -module -avoid-version
-
-read_only_la_SOURCES = read-only.c read-only-common.c
-read_only_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la
-
-worm_la_LDFLAGS = -module -avoid-version
-
-worm_la_SOURCES = read-only-common.c worm.c
-worm_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la
-
-AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src
-
-AM_CFLAGS = -Wall $(GF_CFLAGS)
-
-CLEANFILES =
-
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 56a7a7176aa..00000000000
--- a/xlators/features/read-only/src/read-only-common.c
+++ /dev/null
@@ -1,239 +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 "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 5d4c7e260ed..00000000000
--- a/xlators/features/read-only/src/read-only-common.h
+++ /dev/null
@@ -1,115 +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 "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
deleted file mode 100644
index e49e54a1b31..00000000000
--- a/xlators/features/read-only/src/read-only.c
+++ /dev/null
@@ -1,77 +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 "xlator.h"
-#include "defaults.h"
-#include "read-only-common.h"
-
-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 = {
- .mknod = ro_mknod,
- .mkdir = ro_mkdir,
- .unlink = ro_unlink,
- .rmdir = ro_rmdir,
- .symlink = ro_symlink,
- .rename = ro_rename,
- .link = ro_link,
- .truncate = ro_truncate,
- .open = ro_open,
- .writev = ro_writev,
- .setxattr = ro_setxattr,
- .fsetxattr = ro_fsetxattr,
- .removexattr = ro_removexattr,
- .fsyncdir = ro_fsyncdir,
- .ftruncate = ro_ftruncate,
- .create = ro_create,
- .setattr = ro_setattr,
- .fsetattr = ro_fsetattr,
- .xattrop = ro_xattrop,
- .fxattrop = ro_fxattrop,
- .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/read-only/src/worm.c b/xlators/features/read-only/src/worm.c
deleted file mode 100644
index 16c3eb3daed..00000000000
--- a/xlators/features/read-only/src/worm.c
+++ /dev/null
@@ -1,89 +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 "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/snapview-client/Makefile.am b/xlators/features/snapview-client/Makefile.am
deleted file mode 100644
index af437a64d6d..00000000000
--- a/xlators/features/snapview-client/Makefile.am
+++ /dev/null
@@ -1 +0,0 @@
-SUBDIRS = src
diff --git a/xlators/features/snapview-client/src/Makefile.am b/xlators/features/snapview-client/src/Makefile.am
deleted file mode 100644
index 8a3f6fe4ea2..00000000000
--- a/xlators/features/snapview-client/src/Makefile.am
+++ /dev/null
@@ -1,15 +0,0 @@
-xlator_LTLIBRARIES = snapview-client.la
-xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/features
-
-snapview_client_la_LDFLAGS = -module -avoid-version
-
-snapview_client_la_SOURCES = snapview-client.c
-snapview_client_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la
-
-noinst_HEADERS = snapview-client.h snapview-client-mem-types.h
-
-AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src
-
-AM_CFLAGS = -Wall $(GF_CFLAGS)
-
-CLEANFILES =
diff --git a/xlators/features/snapview-client/src/snapview-client-mem-types.h b/xlators/features/snapview-client/src/snapview-client-mem-types.h
deleted file mode 100644
index 1a0158d950e..00000000000
--- a/xlators/features/snapview-client/src/snapview-client-mem-types.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- Copyright (c) 2014 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 _SVC_MEM_TYPES_H
-#define _SVC_MEM_TYPES_H
-
-#include "mem-types.h"
-
-enum svc_mem_types {
- gf_svc_mt_svc_private_t = gf_common_mt_end + 1,
- gf_svc_mt_svc_local_t,
- gf_svc_mt_svc_inode_t,
- gf_svc_mt_svc_fd_t,
- gf_svc_mt_end
-};
-
-#endif
diff --git a/xlators/features/snapview-client/src/snapview-client.c b/xlators/features/snapview-client/src/snapview-client.c
deleted file mode 100644
index 58f566ef520..00000000000
--- a/xlators/features/snapview-client/src/snapview-client.c
+++ /dev/null
@@ -1,2356 +0,0 @@
- /*
- Copyright (c) 2014 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 "snapview-client.h"
-#include "inode.h"
-#include "byte-order.h"
-
-
-void
-svc_local_free (svc_local_t *local)
-{
- if (local) {
- loc_wipe (&local->loc);
- if (local->fd)
- fd_unref (local->fd);
- if (local->xdata)
- dict_unref (local->xdata);
- mem_put (local);
- }
-}
-
-xlator_t *
-svc_get_subvolume (xlator_t *this, int inode_type)
-{
- xlator_t *subvolume = NULL;
-
- GF_VALIDATE_OR_GOTO ("snapview-client", this, out);
-
- if (inode_type == VIRTUAL_INODE)
- subvolume = SECOND_CHILD (this);
- else
- subvolume = FIRST_CHILD (this);
-
-out:
- return subvolume;
-}
-
-int32_t
-__svc_inode_ctx_set (xlator_t *this, inode_t *inode, int inode_type)
-{
- uint64_t value = 0;
- int32_t ret = -1;
-
- GF_VALIDATE_OR_GOTO ("snapview-client", this, out);
- GF_VALIDATE_OR_GOTO (this->name, inode, out);
-
- value = inode_type;
-
- ret = __inode_ctx_set (inode, this, &value);
-
-out:
- return ret;
-}
-
-int
-__svc_inode_ctx_get (xlator_t *this, inode_t *inode, int *inode_type)
-{
- uint64_t value = 0;
- int ret = -1;
-
- GF_VALIDATE_OR_GOTO ("snapview-client", this, out);
- GF_VALIDATE_OR_GOTO (this->name, inode, out);
-
- ret = __inode_ctx_get (inode, this, &value);
- if (ret < 0)
- goto out;
-
- *inode_type = (int)(value);
-
-out:
- return ret;
-}
-
-int
-svc_inode_ctx_get (xlator_t *this, inode_t *inode, int *inode_type)
-{
- int ret = -1;
-
- GF_VALIDATE_OR_GOTO ("snapview-client", this, out);
- GF_VALIDATE_OR_GOTO (this->name, inode, out);
-
- LOCK (&inode->lock);
- {
- ret = __svc_inode_ctx_get (this, inode, inode_type);
- }
- UNLOCK (&inode->lock);
-
-out:
- return ret;
-}
-
-int32_t
-svc_inode_ctx_set (xlator_t *this, inode_t *inode, int inode_type)
-{
- int32_t ret = -1;
-
- GF_VALIDATE_OR_GOTO ("snapview-client", this, out);
- GF_VALIDATE_OR_GOTO (this->name, inode, out);
-
- LOCK (&inode->lock);
- {
- ret = __svc_inode_ctx_set (this, inode, inode_type);
- }
- UNLOCK (&inode->lock);
-
-out:
- return ret;
-}
-
-svc_fd_t *
-svc_fd_new (void)
-{
- svc_fd_t *svc_fd = NULL;
-
- svc_fd = GF_CALLOC (1, sizeof (*svc_fd), gf_svc_mt_svc_fd_t);
-
- return svc_fd;
-}
-
-svc_fd_t *
-__svc_fd_ctx_get (xlator_t *this, fd_t *fd)
-{
- svc_fd_t *svc_fd = NULL;
- uint64_t value = 0;
- int ret = -1;
-
- GF_VALIDATE_OR_GOTO ("snapview-client", this, out);
- GF_VALIDATE_OR_GOTO (this->name, fd, out);
-
- ret = __fd_ctx_get (fd, this, &value);
- if (ret)
- return NULL;
-
- svc_fd = (svc_fd_t *) ((long) value);
-
-out:
- return svc_fd;
-}
-
-svc_fd_t *
-svc_fd_ctx_get (xlator_t *this, fd_t *fd)
-{
- svc_fd_t *svc_fd = NULL;
-
- GF_VALIDATE_OR_GOTO ("snapview-client", this, out);
- GF_VALIDATE_OR_GOTO (this->name, fd, out);
-
- LOCK (&fd->lock);
- {
- svc_fd = __svc_fd_ctx_get (this, fd);
- }
- UNLOCK (&fd->lock);
-
-out:
- return svc_fd;
-}
-
-int
-__svc_fd_ctx_set (xlator_t *this, fd_t *fd, svc_fd_t *svc_fd)
-{
- uint64_t value = 0;
- int ret = -1;
-
- GF_VALIDATE_OR_GOTO ("snapview-client", this, out);
- GF_VALIDATE_OR_GOTO (this->name, fd, out);
- GF_VALIDATE_OR_GOTO (this->name, svc_fd, out);
-
- value = (uint64_t)(long) svc_fd;
-
- ret = __fd_ctx_set (fd, this, value);
-
-out:
- return ret;
-}
-
-int32_t
-svc_fd_ctx_set (xlator_t *this, fd_t *fd, svc_fd_t *svc_fd)
-{
- int32_t ret = -1;
-
- GF_VALIDATE_OR_GOTO ("snapview-client", this, out);
- GF_VALIDATE_OR_GOTO (this->name, fd, out);
- GF_VALIDATE_OR_GOTO (this->name, svc_fd, out);
-
- LOCK (&fd->lock);
- {
- ret = __svc_fd_ctx_set (this, fd, svc_fd);
- }
- UNLOCK (&fd->lock);
-
-out:
- return ret;
-}
-
-svc_fd_t *
-__svc_fd_ctx_get_or_new (xlator_t *this, fd_t *fd)
-{
- svc_fd_t *svc_fd = NULL;
- int ret = -1;
- inode_t *inode = NULL;
-
- GF_VALIDATE_OR_GOTO ("snapview-client", this, out);
- GF_VALIDATE_OR_GOTO (this->name, fd, out);
-
- inode = fd->inode;
- svc_fd = __svc_fd_ctx_get (this, fd);
- if (svc_fd) {
- ret = 0;
- goto out;
- }
-
- svc_fd = svc_fd_new ();
- if (!svc_fd) {
- gf_log (this->name, GF_LOG_ERROR, "failed to allocate new fd "
- "context for gfid %s", uuid_utoa (inode->gfid));
- goto out;
- }
-
- ret = __svc_fd_ctx_set (this, fd, svc_fd);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "failed to set fd context "
- "for gfid %s", uuid_utoa (inode->gfid));
- ret = -1;
- }
-
-out:
- if (ret) {
- GF_FREE (svc_fd);
- svc_fd = NULL;
- }
-
- return svc_fd;
-}
-
-svc_fd_t *
-svc_fd_ctx_get_or_new (xlator_t *this, fd_t *fd)
-{
- svc_fd_t *svc_fd = NULL;
-
- GF_VALIDATE_OR_GOTO ("snapview-client", this, out);
- GF_VALIDATE_OR_GOTO (this->name, fd, out);
-
- LOCK (&fd->lock);
- {
- svc_fd = __svc_fd_ctx_get_or_new (this, fd);
- }
- UNLOCK (&fd->lock);
-
-out:
- return svc_fd;
-}
-
-
-int32_t
-svc_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)
-{
- svc_local_t *local = NULL;
- inode_t *parent = NULL;
- xlator_t *subvolume = NULL;
- gf_boolean_t do_unwind = _gf_true;
- int inode_type = -1;
- int parent_type = -1;
- int ret = -1;
-
- local = frame->local;
- subvolume = local->subvolume;
- if (!subvolume) {
- gf_log_callingfn (this->name, GF_LOG_ERROR, "path: %s, "
- "gfid: %s ", local->loc.path,
- inode?uuid_utoa (inode->gfid):"");
- GF_ASSERT (0);
- }
-
- /* There is a possibility that, the client process just came online
- and does not have the inode on which the lookup came. In that case,
- the fresh inode created from fuse for the lookup fop, wont have
- the inode context set without which svc cannot decide where to
- STACK_WIND to. So by default it decides to send the fop to the
- regular subvolume (i.e first child of the xlator). If lookup fails
- on the regular volume, then there is a possibility that the lookup
- is happening on a virtual inode (i.e history data residing in snaps).
- So if lookup fails with ENOENT and the inode context is not there,
- then send the lookup to the 2nd child of svc.
-
- If there are any changes in volfile/client-restarted then inode-ctx
- is lost. In this case if nameless lookup fails with ESTALE,
- then send the lookup to the 2nd child of svc.
- */
- if (op_ret) {
- if (subvolume == FIRST_CHILD (this)) {
- gf_log (this->name,
- (op_errno == ENOENT || op_errno == ESTALE)
- ? GF_LOG_DEBUG:GF_LOG_ERROR,
- "Lookup failed on normal graph with error %s",
- strerror (op_errno));
- } else {
- gf_log (this->name,
- (op_errno == ENOENT || op_errno == ESTALE)
- ? GF_LOG_DEBUG:GF_LOG_ERROR,
- "Lookup failed on snapview graph with error %s",
- strerror (op_errno));
- }
-
- if ((op_errno == ENOENT || op_errno == ESTALE) &&
- !uuid_is_null (local->loc.gfid)) {
- ret = svc_inode_ctx_get (this, inode, &inode_type);
- if (ret < 0 && subvolume == FIRST_CHILD (this)) {
- gf_log (this->name, GF_LOG_DEBUG,
- "Lookup on normal graph failed. "
- "Sending lookup to snapview-server");
-
- subvolume = SECOND_CHILD (this);
- local->subvolume = subvolume;
- STACK_WIND (frame, svc_lookup_cbk, subvolume,
- subvolume->fops->lookup,
- &local->loc, xdata);
- do_unwind = _gf_false;
- }
- }
-
- goto out;
- }
-
- if (local->loc.parent)
- parent = inode_ref (local->loc.parent);
- else {
- parent = inode_parent (inode, NULL, NULL);
- if (!parent && !uuid_is_null (local->loc.pargfid)) {
- parent = inode_find (inode->table,
- local->loc.pargfid);
- }
- }
-
- if (!__is_root_gfid (buf->ia_gfid) && parent) {
- ret = svc_inode_ctx_get (this, parent, &parent_type);
- if (ret < 0) {
- op_ret = -1;
- op_errno = EINVAL;
- gf_log (this->name, GF_LOG_WARNING,
- "Error fetching parent context");
- goto out;
- }
- }
-
- if (subvolume == FIRST_CHILD (this))
- inode_type = NORMAL_INODE;
- else
- inode_type = VIRTUAL_INODE;
-
- ret = svc_inode_ctx_set (this, inode, inode_type);
- if (ret)
- gf_log (this->name, GF_LOG_ERROR, "failed to set inode type"
- "into the context");
-
-out:
- if (do_unwind) {
- SVC_STACK_UNWIND (lookup, frame, op_ret, op_errno, inode, buf,
- xdata, postparent);
- }
-
- if (parent)
- inode_unref (parent);
-
- return 0;
-}
-
-int32_t
-svc_lookup (call_frame_t *frame, xlator_t *this, loc_t *loc,
- dict_t *xdata)
-{
- int32_t ret = -1;
- svc_local_t *local = NULL;
- xlator_t *subvolume = NULL;
- int op_ret = -1;
- int op_errno = EINVAL;
- inode_t *parent = NULL;
- svc_private_t *priv = NULL;
- dict_t *new_xdata = NULL;
- int inode_type = -1;
- int parent_type = -1;
- gf_boolean_t wind = _gf_false;
-
- GF_VALIDATE_OR_GOTO ("svc", this, out);
- GF_VALIDATE_OR_GOTO (this->name, this->private, out);
- GF_VALIDATE_OR_GOTO (this->name, frame, out);
- GF_VALIDATE_OR_GOTO (this->name, loc, out);
- GF_VALIDATE_OR_GOTO (this->name, loc->inode, out);
-
- priv = this->private;
-
- ret = svc_inode_ctx_get (this, loc->inode, &inode_type);
- if (!__is_root_gfid (loc->gfid)) {
- if (loc->parent) {
- parent = inode_ref (loc->parent);
- ret = svc_inode_ctx_get (this, loc->parent,
- &parent_type);
- } else {
- parent = inode_parent (loc->inode, loc->pargfid, NULL);
- if (parent)
- ret = svc_inode_ctx_get (this, parent,
- &parent_type);
- }
- }
-
- local = mem_get0 (this->local_pool);
- if (!local) {
- gf_log (this->name, GF_LOG_ERROR, "failed to allocate local");
- op_ret = -1;
- op_errno = ENOMEM;
- goto out;
- }
-
- frame->local = local;
- loc_copy (&local->loc, loc);
-
- if (__is_root_gfid (loc->inode->gfid)) {
- subvolume = FIRST_CHILD (this);
- GF_ASSERT (subvolume);
- local->subvolume = subvolume;
- wind = _gf_true;
- goto out;
- }
-
- /* nfs sends nameless lookups directly using the gfid. In that case
- loc->name will be NULL. So check if loc->name is NULL. If so, then
- try to get the subvolume using inode context. But if the inode has
- not been looked up yet, then send the lookup call to the first
- subvolume.
- */
-
- if (!loc->name) {
- if (uuid_is_null (loc->inode->gfid)) {
- subvolume = FIRST_CHILD (this);
- local->subvolume = subvolume;
- wind = _gf_true;
- goto out;
- } else {
- if (inode_type >= 0)
- subvolume = svc_get_subvolume (this,
- inode_type);
- else
- subvolume = FIRST_CHILD (this);
- local->subvolume = subvolume;
- wind = _gf_true;
- goto out;
- }
- }
-
- if (strcmp (loc->name, priv->path)) {
- if (parent_type == NORMAL_INODE) {
- subvolume = FIRST_CHILD (this);
- local->subvolume = subvolume;
- } else {
- subvolume = SECOND_CHILD (this);
- local->subvolume = subvolume;
- }
- } else {
- subvolume = SECOND_CHILD (this);
- local->subvolume = subvolume;
- if (parent_type == NORMAL_INODE) {
- /* Indication of whether the lookup is happening on the
- entry point or not, to the snapview-server.
- */
- SVC_ENTRY_POINT_SET (this, xdata, op_ret, op_errno,
- new_xdata, priv, ret, out);
- }
- }
-
- wind = _gf_true;
-
-out:
- if (wind)
- STACK_WIND (frame, svc_lookup_cbk,
- subvolume, subvolume->fops->lookup, loc, xdata);
- else
- SVC_STACK_UNWIND (lookup, frame, op_ret, op_errno, NULL,
- NULL, NULL, NULL);
- if (new_xdata)
- dict_unref (new_xdata);
-
- if (parent)
- inode_unref (parent);
-
- return 0;
-}
-
-/* should all the fops be handled like lookup is supposed to be
- handled? i.e just based on inode type decide where the call should
- be sent and in the call back update the contexts.
-*/
-int32_t
-svc_stat (call_frame_t *frame, xlator_t *this, loc_t *loc,
- dict_t *xdata)
-{
- int32_t ret = -1;
- int inode_type = -1;
- xlator_t *subvolume = NULL;
- int32_t op_ret = -1;
- int32_t op_errno = EINVAL;
- gf_boolean_t wind = _gf_false;
-
- GF_VALIDATE_OR_GOTO ("svc", this, out);
- GF_VALIDATE_OR_GOTO (this->name, frame, out);
- GF_VALIDATE_OR_GOTO (this->name, loc, out);
- GF_VALIDATE_OR_GOTO (this->name, loc->inode, out);
-
- SVC_GET_SUBVOL_FROM_CTX (this, op_ret, op_errno, inode_type, ret,
- loc->inode, subvolume, out);
-
- STACK_WIND_TAIL (frame,subvolume, subvolume->fops->stat, loc, xdata);
-
- wind = _gf_true;
-
-out:
- if (!wind)
- SVC_STACK_UNWIND (stat, frame, op_ret, op_errno,
- NULL, NULL);
- return 0;
-}
-
-int32_t
-svc_fstat (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
-{
- int32_t ret = -1;
- int inode_type = -1;
- xlator_t *subvolume = NULL;
- int32_t op_ret = -1;
- int32_t op_errno = EINVAL;
- gf_boolean_t wind = _gf_false;
-
- GF_VALIDATE_OR_GOTO ("svc", this, out);
- GF_VALIDATE_OR_GOTO (this->name, frame, out);
- GF_VALIDATE_OR_GOTO (this->name, fd, out);
- GF_VALIDATE_OR_GOTO (this->name, fd->inode, out);
-
- SVC_GET_SUBVOL_FROM_CTX (this, op_ret, op_errno, inode_type, ret,
- fd->inode, subvolume, out);
-
- STACK_WIND_TAIL (frame, subvolume, subvolume->fops->fstat, fd, xdata);
-
- wind = _gf_true;
-
-out:
- if (!wind)
- SVC_STACK_UNWIND (fstat, frame, op_ret, op_errno, NULL, NULL);
-
- return ret;
-}
-
-int32_t
-svc_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)
-{
- svc_fd_t *svc_fd = NULL;
- svc_local_t *local = NULL;
- svc_private_t *priv = NULL;
- gf_boolean_t special_dir = _gf_false;
- char path[PATH_MAX] = {0, };
-
- GF_VALIDATE_OR_GOTO ("snapview-client", this, out);
- GF_VALIDATE_OR_GOTO (this->name, this->private, out);
-
- if (op_ret)
- goto out;
-
- priv = this->private;
- local = frame->local;
-
- if (local->subvolume == FIRST_CHILD (this) && priv->special_dir
- && strcmp (priv->special_dir, "")) {
- if (!__is_root_gfid (fd->inode->gfid))
- snprintf (path, sizeof (path), "%s/.",
- priv->special_dir);
- else
- snprintf (path, sizeof (path), "/.");
-
- if (!strcmp (local->loc.path, priv->special_dir) ||
- !strcmp (local->loc.path, path)) {
- gf_log_callingfn (this->name, GF_LOG_DEBUG,
- "got opendir on special "
- "directory %s (%s)", path,
- uuid_utoa (fd->inode->gfid));
- special_dir = _gf_true;
- }
- }
-
- if (special_dir) {
- svc_fd = svc_fd_ctx_get_or_new (this, fd);
- if (!svc_fd) {
- gf_log (this->name, GF_LOG_ERROR,
- "fd context not found for %s",
- uuid_utoa (fd->inode->gfid));
- goto out;
- }
-
- svc_fd->last_offset = -1;
- svc_fd->special_dir = special_dir;
- }
-
-out:
- STACK_UNWIND_STRICT (opendir, frame, op_ret, op_errno, fd, xdata);
-
- return 0;
-}
-
-
-/* If the inode represents a directory which is actually
- present in a snapshot, then opendir on that directory
- should be sent to the snap-view-server which opens
- the directory in the corresponding graph.
- In fact any opendir call on a virtual directory
- should be sent to svs. Because if it fakes success
- here, then later when readdir on that fd comes, there
- will not be any corresponding fd opened on svs and
- svc has to do things that open-behind is doing.
-*/
-int32_t
-svc_opendir (call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd,
- dict_t *xdata)
-{
- int32_t ret = -1;
- int inode_type = -1;
- xlator_t *subvolume = NULL;
- int op_ret = -1;
- int op_errno = EINVAL;
- gf_boolean_t wind = _gf_false;
- svc_local_t *local = NULL;
-
- GF_VALIDATE_OR_GOTO ("svc", this, out);
- GF_VALIDATE_OR_GOTO (this->name, frame, out);
- GF_VALIDATE_OR_GOTO (this->name, loc, out);
- GF_VALIDATE_OR_GOTO (this->name, loc->inode, out);
- GF_VALIDATE_OR_GOTO (this->name, fd, out);
-
- local = mem_get0 (this->local_pool);
- if (!local) {
- gf_log (this->name, GF_LOG_ERROR, "failed to allocate memory "
- "for local (path: %s, gfid: %s)", loc->path,
- uuid_utoa (fd->inode->gfid));
- op_errno = ENOMEM;
- goto out;
- }
-
- SVC_GET_SUBVOL_FROM_CTX (this, op_ret, op_errno, inode_type, ret,
- loc->inode, subvolume, out);
-
- loc_copy (&local->loc, loc);
- local->subvolume = subvolume;
- frame->local = local;
-
- STACK_WIND (frame, svc_opendir_cbk, subvolume, subvolume->fops->opendir,
- loc, fd, xdata);
-
- wind = _gf_true;
-
-out:
- if (!wind)
- SVC_STACK_UNWIND (opendir, frame, op_ret, op_errno, NULL, NULL);
-
- return 0;
-}
-
-int32_t
-svc_setattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
- struct iatt *stbuf, int32_t valid, dict_t *xdata)
-{
- int32_t ret = -1;
- int inode_type = -1;
- int op_ret = -1;
- int op_errno = EINVAL;
- gf_boolean_t wind = _gf_false;
-
- GF_VALIDATE_OR_GOTO ("svc", this, out);
- GF_VALIDATE_OR_GOTO (this->name, frame, out);
- GF_VALIDATE_OR_GOTO (this->name, loc, out);
- GF_VALIDATE_OR_GOTO (this->name, loc->inode, out);
-
- ret = svc_inode_ctx_get (this, loc->inode, &inode_type);
- if (ret < 0) {
- op_ret = -1;
- op_errno = EINVAL;
- gf_log (this->name, GF_LOG_ERROR, "failed to get the inode "
- "context for %s (gfid: %s)", loc->path,
- uuid_utoa (loc->inode->gfid));
- goto out;
- }
-
- if (inode_type == NORMAL_INODE) {
- STACK_WIND_TAIL (frame, FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->setattr, loc, stbuf,
- valid, xdata);
- } else {
- op_ret = -1;
- op_errno = EROFS;
- goto out;
- }
-
- wind = _gf_true;
-
-out:
- if (!wind)
- SVC_STACK_UNWIND (setattr, frame, op_ret, op_errno,
- NULL, NULL, NULL);
- return 0;
-}
-
-int32_t
-svc_fsetattr (call_frame_t *frame, xlator_t *this, fd_t *fd, struct iatt *stbuf,
- int32_t valid, dict_t *xdata)
-{
- int32_t ret = -1;
- int inode_type = -1;
- int op_ret = -1;
- int op_errno = EINVAL;
- gf_boolean_t wind = _gf_false;
-
- GF_VALIDATE_OR_GOTO ("svc", this, out);
- GF_VALIDATE_OR_GOTO (this->name, frame, out);
- GF_VALIDATE_OR_GOTO (this->name, fd, out);
- GF_VALIDATE_OR_GOTO (this->name, fd->inode, out);
-
- ret = svc_inode_ctx_get (this, fd->inode, &inode_type);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR, "failed to get the inode "
- "context for %s", uuid_utoa (fd->inode->gfid));
- op_ret = -1;
- op_errno = EINVAL;
- goto out;
- }
-
- if (inode_type == NORMAL_INODE) {
- STACK_WIND_TAIL (frame, FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->fsetattr, fd, stbuf,
- valid, xdata);
- } else {
- op_ret = -1;
- op_errno = EROFS;
- goto out;
- }
-
- wind = _gf_true;
-
-out:
- if (!wind)
- SVC_STACK_UNWIND (fsetattr, frame, op_ret, op_errno,
- NULL, NULL, NULL);
- return 0;
-}
-
-int32_t
-svc_getxattr (call_frame_t *frame, xlator_t *this, loc_t *loc, const char *name,
- dict_t *xdata)
-{
- int32_t ret = -1;
- int inode_type = -1;
- xlator_t *subvolume = NULL;
- int op_ret = -1;
- int op_errno = EINVAL;
- gf_boolean_t wind = _gf_false;
- svc_private_t *priv = NULL;
- char attrname[PATH_MAX] = "";
- char attrval[64] = "";
- dict_t *dict = NULL;
-
- GF_VALIDATE_OR_GOTO ("svc", this, out);
- GF_VALIDATE_OR_GOTO (this->name, frame, out);
- GF_VALIDATE_OR_GOTO (this->name, loc, out);
- GF_VALIDATE_OR_GOTO (this->name, loc->inode, out);
- priv = this->private;
- GF_VALIDATE_OR_GOTO (this->name, priv, out);
-
- /*
- * Samba sends this special key for case insensitive
- * filename check. This request comes with a parent
- * path and with a special key GF_XATTR_GET_REAL_FILENAME_KEY.
- * e.g. "glusterfs.get_real_filename:.snaps".
- * If the name variable matches this key then we have
- * to send back .snaps as the real filename.
- */
- if (!name)
- goto stack_wind;
-
- sscanf (name, "%[^:]:%[^@]", attrname, attrval);
- strcat (attrname, ":");
-
- if (!strcmp (attrname, GF_XATTR_GET_REAL_FILENAME_KEY)) {
- if (!strcasecmp (attrval, priv->path)) {
- dict = dict_new ();
- if (NULL == dict) {
- op_errno = ENOMEM;
- goto out;
- }
-
- ret = dict_set_dynstr_with_alloc (dict,
- (char *)name,
- priv->path);
-
- if (ret) {
- op_errno = ENOMEM;
- dict_unref (dict);
- goto out;
- }
-
- op_errno = 0;
- op_ret = strlen (priv->path) + 1;
- /* We should return from here */
- goto out;
- }
- }
-stack_wind:
- SVC_GET_SUBVOL_FROM_CTX (this, op_ret, op_errno, inode_type, ret,
- loc->inode, subvolume, out);
-
- STACK_WIND_TAIL (frame, subvolume, subvolume->fops->getxattr, loc, name,
- xdata);
-
- wind = _gf_true;
-
-out:
- if (!wind)
- SVC_STACK_UNWIND (getxattr, frame, op_ret, op_errno,
- dict, NULL);
-
- if (dict)
- dict_unref (dict);
-
- return 0;
-}
-
-int32_t
-svc_fgetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd, const char *name,
- dict_t *xdata)
-{
- int32_t ret = -1;
- int inode_type = -1;
- xlator_t *subvolume = NULL;
- gf_boolean_t wind = _gf_false;
- int op_ret = -1;
- int op_errno = EINVAL;
-
- GF_VALIDATE_OR_GOTO ("svc", this, out);
- GF_VALIDATE_OR_GOTO (this->name, frame, out);
- GF_VALIDATE_OR_GOTO (this->name, fd, out);
- GF_VALIDATE_OR_GOTO (this->name, fd->inode, out);
-
- SVC_GET_SUBVOL_FROM_CTX (this, op_ret, op_errno, inode_type, ret,
- fd->inode, subvolume, out);
-
- STACK_WIND_TAIL (frame, subvolume,
- subvolume->fops->fgetxattr, fd, name, xdata);
-
- wind = _gf_true;
-
-out:
- if (!wind)
- SVC_STACK_UNWIND (fgetxattr, frame, op_ret, op_errno,
- NULL, NULL);
- return 0;
-}
-
-int32_t
-svc_setxattr (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *dict,
- int32_t flags, dict_t *xdata)
-{
- int32_t ret = -1;
- int inode_type = -1;
- int op_ret = -1;
- int op_errno = EINVAL;
- gf_boolean_t wind = _gf_false;
-
- GF_VALIDATE_OR_GOTO ("svc", this, out);
- GF_VALIDATE_OR_GOTO (this->name, frame, out);
- GF_VALIDATE_OR_GOTO (this->name, loc, out);
- GF_VALIDATE_OR_GOTO (this->name, loc->inode, out);
-
- ret = svc_inode_ctx_get (this, loc->inode, &inode_type);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR, "failed to get inode context "
- "for %s (gfid: %s)", loc->name,
- uuid_utoa (loc->inode->gfid));
- op_ret = -1;
- op_errno = EINVAL;
- goto out;
- }
-
- if (inode_type == NORMAL_INODE) {
- STACK_WIND_TAIL (frame, FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->setxattr, loc, dict,
- flags, xdata);
- } else {
- op_ret = -1;
- op_errno = EROFS;
- goto out;
- }
-
- wind = _gf_true;
-
-out:
- if (!wind)
- SVC_STACK_UNWIND (setxattr, frame, op_ret, op_errno,
- NULL);
-
- return 0;
-}
-
-int32_t
-svc_fsetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *dict,
- int32_t flags, dict_t *xdata)
-{
- int32_t ret = -1;
- int inode_type = -1;
- int op_ret = -1;
- int op_errno = EINVAL;
- gf_boolean_t wind = _gf_false;
-
- GF_VALIDATE_OR_GOTO ("svc", this, out);
- GF_VALIDATE_OR_GOTO (this->name, frame, out);
- GF_VALIDATE_OR_GOTO (this->name, fd, out);
- GF_VALIDATE_OR_GOTO (this->name, fd->inode, out);
-
- ret = svc_inode_ctx_get (this, fd->inode, &inode_type);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR, "failed to get inode context "
- "for %s", uuid_utoa (fd->inode->gfid));
- op_ret = -1;
- op_errno = EINVAL;
- goto out;
- }
-
- if (inode_type == NORMAL_INODE) {
- STACK_WIND_TAIL (frame, FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->fsetxattr, fd, dict,
- flags, xdata);
- } else {
- op_ret = -1;
- op_errno = EROFS;
- goto out;
- }
-
- wind = _gf_true;
-
-out:
- if (!wind)
- STACK_UNWIND_STRICT (fsetxattr, frame, op_ret, op_errno,
- NULL);
-
- return 0;
-}
-
-int32_t
-svc_rmdir (call_frame_t *frame, xlator_t *this, loc_t *loc, int flags,
- dict_t *xdata)
-{
- int inode_type = -1;
- int ret = -1;
- int op_ret = -1;
- int op_errno = EINVAL;
- gf_boolean_t wind = _gf_false;
-
- GF_VALIDATE_OR_GOTO ("svc", this, out);
- GF_VALIDATE_OR_GOTO (this->name, frame, out);
- GF_VALIDATE_OR_GOTO (this->name, loc, out);
- GF_VALIDATE_OR_GOTO (this->name, loc->inode, out);
-
- ret = svc_inode_ctx_get (this, loc->inode, &inode_type);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR, "failed to get the inode "
- "context for %s (gfid: %s)", loc->name,
- uuid_utoa (loc->inode->gfid));
- op_ret = -1;
- op_errno = EINVAL;
- goto out;
- }
-
- if (inode_type == NORMAL_INODE) {
- STACK_WIND_TAIL (frame, FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->rmdir, loc, flags,
- xdata);
- } else {
- op_ret = -1;
- op_errno = EROFS;
- goto out;
- }
-
- wind = _gf_true;
-
-out:
- if (!wind)
- SVC_STACK_UNWIND (rmdir, frame, op_ret, op_errno,
- NULL, NULL, NULL);
- return 0;
-}
-
-int32_t
-svc_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)
-{
- int inode_type = -1;
- int ret = -1;
-
- if (op_ret < 0)
- goto out;
-
- inode_type = NORMAL_INODE;
- ret = svc_inode_ctx_set (this, inode, inode_type);
- if (ret)
- gf_log (this->name, GF_LOG_ERROR, "failed to set inode "
- "context");
-
-
-out:
- SVC_STACK_UNWIND (mkdir, frame, op_ret, op_errno, inode,
- buf, preparent, postparent, xdata);
- return 0;
-}
-
-int32_t
-svc_mkdir (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
- mode_t umask, dict_t *xdata)
-{
- int parent_type = -1;
- int ret = -1;
- int op_ret = -1;
- int op_errno = EINVAL;
- svc_private_t *priv = NULL;
- gf_boolean_t wind = _gf_false;
-
- GF_VALIDATE_OR_GOTO ("svc", this, out);
- GF_VALIDATE_OR_GOTO (this->name, this->private, out);
- GF_VALIDATE_OR_GOTO (this->name, frame, out);
- GF_VALIDATE_OR_GOTO (this->name, loc, out);
- GF_VALIDATE_OR_GOTO (this->name, loc->inode, out);
-
- priv = this->private;
-
- ret = svc_inode_ctx_get (this, loc->parent, &parent_type);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR, "failed to get the inode "
- "context for %s", uuid_utoa (loc->parent->gfid));
- op_ret = -1;
- op_errno = EINVAL;
- goto out;
- }
-
- if (strcmp (loc->name, priv->path) && parent_type == NORMAL_INODE) {
- STACK_WIND (frame, svc_mkdir_cbk, FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->mkdir, loc, mode,
- umask, xdata);
- } else {
- op_ret = -1;
- op_errno = EROFS;
- goto out;
- }
-
- wind = _gf_true;
-
-out:
- if (!wind)
- SVC_STACK_UNWIND (mkdir, frame, op_ret, op_errno, NULL, NULL,
- NULL, NULL, NULL);
- return 0;
-}
-
-int32_t
-svc_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)
-{
- int inode_type = -1;
- int ret = -1;
-
- if (op_ret < 0)
- goto out;
-
- inode_type = NORMAL_INODE;
- ret = svc_inode_ctx_set (this, inode, inode_type);
- if (ret)
- gf_log (this->name, GF_LOG_ERROR, "failed to set inode "
- "context");
-
-out:
- SVC_STACK_UNWIND (mknod, frame, op_ret, op_errno, inode,
- buf, preparent, postparent, xdata);
- return 0;
-}
-
-int32_t
-svc_mknod (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
- dev_t rdev, mode_t umask, dict_t *xdata)
-{
- int parent_type = -1;
- int ret = -1;
- int op_ret = -1;
- int op_errno = EINVAL;
- svc_private_t *priv = NULL;
- gf_boolean_t wind = _gf_false;
-
- GF_VALIDATE_OR_GOTO ("svc", this, out);
- GF_VALIDATE_OR_GOTO (this->name, this->private, out);
- GF_VALIDATE_OR_GOTO (this->name, frame, out);
- GF_VALIDATE_OR_GOTO (this->name, loc, out);
- GF_VALIDATE_OR_GOTO (this->name, loc->inode, out);
-
- priv = this->private;
-
- ret = svc_inode_ctx_get (this, loc->parent, &parent_type);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR, "failed to get the inode "
- "context for %s", uuid_utoa (loc->parent->gfid));
- op_ret = -1;
- op_errno = EINVAL;
- goto out;
- }
-
- if (strcmp (loc->name, priv->path) && parent_type == NORMAL_INODE) {
- STACK_WIND (frame, svc_mknod_cbk, FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->mknod, loc, mode,
- rdev, umask, xdata);
- } else {
- op_ret = -1;
- op_errno = EROFS;
- goto out;
- }
-
- wind = _gf_true;
-
-out:
- if (!wind)
- SVC_STACK_UNWIND (mknod, frame, op_ret, op_errno, NULL, NULL,
- NULL, NULL, NULL);
- return 0;
-}
-
-/* If the flags of the open call contain O_WRONLY or O_RDWR and the inode is
- a virtual inode, then unwind the call back with EROFS. Otherwise simply
- STACK_WIND the call to the first child of svc xlator.
-*/
-int32_t
-svc_open (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
- fd_t *fd, dict_t *xdata)
-{
- xlator_t *subvolume = NULL;
- int inode_type = -1;
- int op_ret = -1;
- int op_errno = EINVAL;
- int ret = -1;
- gf_boolean_t wind = _gf_false;
-
- GF_VALIDATE_OR_GOTO ("svc", this, out);
- GF_VALIDATE_OR_GOTO (this->name, frame, out);
- GF_VALIDATE_OR_GOTO (this->name, loc, out);
- GF_VALIDATE_OR_GOTO (this->name, loc->inode, out);
- GF_VALIDATE_OR_GOTO (this->name, fd, out);
-
- /* Another way is to STACK_WIND to normal subvolume, if inode
- type is not there in the context. If the file actually resides
- in snapshots, then ENOENT would be returned. Needs more analysis.
- */
- SVC_GET_SUBVOL_FROM_CTX (this, op_ret, op_errno, inode_type, ret,
- loc->inode, subvolume, out);
-
- if (((flags & O_ACCMODE) == O_WRONLY) ||
- ((flags & O_ACCMODE) == O_RDWR)) {
- if (subvolume != FIRST_CHILD (this)) {
- op_ret = -1;
- op_errno = EINVAL;
- goto out;
- }
- }
-
- STACK_WIND_TAIL (frame, subvolume, subvolume->fops->open, loc,
- flags, fd, xdata);
-
- wind = _gf_true;
-
-out:
- if (!wind)
- SVC_STACK_UNWIND (open, frame, op_ret, op_errno, NULL,
- NULL);
- return 0;
-}
-
-int32_t
-svc_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)
-{
- int inode_type = -1;
- int ret = -1;
-
- if (op_ret < 0)
- goto out;
-
- inode_type = NORMAL_INODE;
- ret = svc_inode_ctx_set (this, inode, inode_type);
- if (ret)
- gf_log (this->name, GF_LOG_ERROR, "failed to set inode "
- "context");
-
-out:
- SVC_STACK_UNWIND (create, frame, op_ret, op_errno, fd,
- inode, stbuf, preparent, postparent, xdata);
-
- return 0;
-}
-
-int32_t
-svc_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)
-{
- int parent_type = -1;
- int ret = -1;
- int op_ret = -1;
- int op_errno = EINVAL;
- svc_private_t *priv = NULL;
- gf_boolean_t wind = _gf_false;
-
- GF_VALIDATE_OR_GOTO ("svc", this, out);
- GF_VALIDATE_OR_GOTO (this->name, this->private, out);
- GF_VALIDATE_OR_GOTO (this->name, frame, out);
- GF_VALIDATE_OR_GOTO (this->name, loc, out);
- GF_VALIDATE_OR_GOTO (this->name, loc->inode, out);
- GF_VALIDATE_OR_GOTO (this->name, fd, out);
-
- priv = this->private;
-
- ret = svc_inode_ctx_get (this, loc->parent, &parent_type);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR, "failed to get the inode "
- "context for %s", uuid_utoa (loc->parent->gfid));
- op_ret = -1;
- op_errno = EINVAL;
- goto out;
- }
-
- if (strcmp (loc->name, priv->path) && parent_type == NORMAL_INODE) {
- STACK_WIND (frame, svc_create_cbk, FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->create, loc, flags,
- mode, umask, fd, xdata);
- } else {
- op_ret = -1;
- op_errno = EROFS;
- goto out;
- }
-
- wind = _gf_true;
-
-out:
- if (!wind)
- SVC_STACK_UNWIND (create, frame, op_ret, op_errno,
- NULL, NULL, NULL, NULL, NULL, NULL);
- return 0;
-}
-
-int32_t
-svc_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)
-{
- int inode_type = -1;
- int ret = -1;
-
- if (op_ret < 0)
- goto out;
-
- inode_type = NORMAL_INODE;
- ret = svc_inode_ctx_set (this, inode, inode_type);
- if (ret)
- gf_log (this->name, GF_LOG_ERROR, "failed to set inode "
- "context");
-
-out:
- SVC_STACK_UNWIND (symlink, frame, op_ret, op_errno, inode,
- buf, preparent, postparent, xdata);
-
- return 0;
-}
-
-int32_t
-svc_symlink (call_frame_t *frame, xlator_t *this, const char *linkpath,
- loc_t *loc, mode_t umask, dict_t *xdata)
-{
- int parent_type = -1;
- int op_ret = -1;
- int op_errno = EINVAL;
- int ret = -1;
- svc_private_t *priv = NULL;
- gf_boolean_t wind = _gf_false;
-
- GF_VALIDATE_OR_GOTO ("svc", this, out);
- GF_VALIDATE_OR_GOTO (this->name, frame, out);
- GF_VALIDATE_OR_GOTO (this->name, this->private, out);
- GF_VALIDATE_OR_GOTO (this->name, loc, out);
- GF_VALIDATE_OR_GOTO (this->name, loc->inode, out);
-
- priv = this->private;
-
- ret = svc_inode_ctx_get (this, loc->parent, &parent_type);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR, "failed to get the inode "
- "context for %s", uuid_utoa (loc->parent->gfid));
- op_ret = -1;
- op_errno = EINVAL;
- goto out;
- }
-
- if (strcmp (loc->name, priv->path) && parent_type == NORMAL_INODE) {
- STACK_WIND (frame, svc_symlink_cbk, FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->symlink, linkpath, loc,
- umask, xdata);
- } else {
- op_ret = -1;
- op_errno = EROFS;
- goto out;
- }
-
- wind = _gf_true;
-
-out:
- if (!wind)
- SVC_STACK_UNWIND (symlink, frame, op_ret, op_errno,
- NULL, NULL, NULL, NULL, NULL);
- return 0;
-}
-
-int32_t
-svc_unlink (call_frame_t *frame, xlator_t *this, loc_t *loc, int flags,
- dict_t *xdata)
-{
- int inode_type = -1;
- int op_ret = -1;
- int op_errno = EINVAL;
- int ret = -1;
- gf_boolean_t wind = _gf_false;
-
- GF_VALIDATE_OR_GOTO ("svc", this, out);
- GF_VALIDATE_OR_GOTO (this->name, frame, out);
- GF_VALIDATE_OR_GOTO (this->name, loc, out);
- GF_VALIDATE_OR_GOTO (this->name, loc->inode, out);
-
- ret = svc_inode_ctx_get (this, loc->inode, &inode_type);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR, "failed to get the inode "
- "context for %s", uuid_utoa (loc->parent->gfid));
- op_ret = -1;
- op_errno = EINVAL;
- goto out;
- }
-
- if (inode_type == NORMAL_INODE) {
- STACK_WIND_TAIL (frame, FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->unlink, loc, flags,
- xdata);
- } else {
- op_ret = -1;
- op_errno = EROFS;
- goto out;
- }
-
- wind = _gf_true;
-
-out:
- if (!wind)
- SVC_STACK_UNWIND (unlink, frame, op_ret, op_errno, NULL, NULL,
- NULL);
- return 0;
-}
-
-int32_t
-svc_readv (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
- off_t offset, uint32_t flags, dict_t *xdata)
-{
- int inode_type = -1;
- xlator_t *subvolume = NULL;
- int ret = -1;
- int op_ret = -1;
- int op_errno = EINVAL;
- gf_boolean_t wind = _gf_false;
-
- GF_VALIDATE_OR_GOTO ("svc", this, out);
- GF_VALIDATE_OR_GOTO (this->name, frame, out);
- GF_VALIDATE_OR_GOTO (this->name, fd, out);
- GF_VALIDATE_OR_GOTO (this->name, fd->inode, out);
-
- SVC_GET_SUBVOL_FROM_CTX (this, op_ret, op_errno, inode_type, ret,
- fd->inode, subvolume, out);
-
- STACK_WIND_TAIL (frame, subvolume, subvolume->fops->readv,
- fd, size, offset, flags, xdata);
-
- wind = _gf_true;
-
-out:
- if (!wind)
- SVC_STACK_UNWIND (readv, frame, op_ret, op_errno, NULL, 0, NULL,
- NULL, NULL);
- return 0;
-}
-
-int32_t
-svc_readlink (call_frame_t *frame, xlator_t *this,
- loc_t *loc, size_t size, dict_t *xdata)
-{
- int inode_type = -1;
- xlator_t *subvolume = NULL;
- int ret = -1;
- int op_ret = -1;
- int op_errno = EINVAL;
- gf_boolean_t wind = _gf_false;
-
- GF_VALIDATE_OR_GOTO ("svc", this, out);
- GF_VALIDATE_OR_GOTO (this->name, frame, out);
- GF_VALIDATE_OR_GOTO (this->name, loc, out);
- GF_VALIDATE_OR_GOTO (this->name, loc->inode, out);
-
- SVC_GET_SUBVOL_FROM_CTX (this, op_ret, op_errno, inode_type, ret,
- loc->inode, subvolume, out);
-
- STACK_WIND_TAIL (frame, subvolume, subvolume->fops->readlink, loc, size,
- xdata);
-
- wind = _gf_true;
-
-out:
- if (!wind)
- STACK_UNWIND_STRICT (readlink, frame, op_ret, op_errno, NULL, NULL,
- NULL);
- return 0;
-}
-
-int32_t
-svc_access (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t mask,
- dict_t *xdata)
-{
- int ret = -1;
- int inode_type = -1;
- xlator_t *subvolume = NULL;
- int op_ret = -1;
- int op_errno = EINVAL;
- gf_boolean_t wind = _gf_false;
-
- GF_VALIDATE_OR_GOTO ("svc", this, out);
- GF_VALIDATE_OR_GOTO (this->name, frame, out);
- GF_VALIDATE_OR_GOTO (this->name, loc, out);
- GF_VALIDATE_OR_GOTO (this->name, loc->inode, out);
-
- SVC_GET_SUBVOL_FROM_CTX (this, op_ret, op_errno, inode_type, ret,
- loc->inode, subvolume, out);
-
- STACK_WIND_TAIL (frame, subvolume, subvolume->fops->access, loc, mask,
- xdata);
-
- wind = _gf_true;
-
-out:
- if (!wind)
- SVC_STACK_UNWIND (access, frame, op_ret, op_errno, NULL);
-
- return 0;
-}
-
-int32_t
-svc_readdir (call_frame_t *frame, xlator_t *this, fd_t *fd,
- size_t size, off_t off,
- dict_t *xdata)
-{
- int inode_type = -1;
- xlator_t *subvolume = NULL;
- int ret = -1;
- int op_ret = -1;
- int op_errno = EINVAL;
- gf_boolean_t wind = _gf_false;
- svc_fd_t *svc_fd = NULL;
- gf_dirent_t entries;
-
- INIT_LIST_HEAD (&entries);
-
- GF_VALIDATE_OR_GOTO ("svc", this, out);
- GF_VALIDATE_OR_GOTO (this->name, frame, out);
- GF_VALIDATE_OR_GOTO (this->name, fd, out);
- GF_VALIDATE_OR_GOTO (this->name, fd->inode, out);
-
- svc_fd = svc_fd_ctx_get_or_new (this, fd);
- if (!svc_fd)
- gf_log (this->name, GF_LOG_ERROR, "failed to get the fd "
- "context for the inode %s",
- uuid_utoa (fd->inode->gfid));
- else {
- if (svc_fd->entry_point_handled && off == svc_fd->last_offset) {
- op_ret = 0;
- op_errno = ENOENT;
- goto out;
- }
- }
-
- SVC_GET_SUBVOL_FROM_CTX (this, op_ret, op_errno, inode_type, ret,
- fd->inode, subvolume, out);
-
- STACK_WIND_TAIL (frame, subvolume, subvolume->fops->readdir, fd, size,
- off, xdata);
-
- wind = _gf_true;
-
-out:
- if (!wind)
- SVC_STACK_UNWIND (readdir, frame, op_ret, op_errno, &entries,
- NULL);
-
- gf_dirent_free (&entries);
-
- return 0;
-}
-
-/*
- * This lookup if mainly for supporting USS for windows.
- * Since the dentry for the entry-point directory is not sent in
- * the readdir response, from windows explorer, there is no way
- * to access the snapshots. If the explicit path of the entry-point
- * directory is mentioned in the address bar, then windows sends
- * readdir on the parent directory and compares if the entry point
- * directory's name is there in readdir response. If it is not there
- * then access to snapshot world is denied. And windows users cannot
- * access snapshots via samba.
- * So, to handle this a new option called special-directory is created,
- * which if set, snapview-client will send the entry-point's dentry
- * in readdirp o/p for the special directory, so that it will be
- * visible from windows explorer.
- * But to send that virtual entry, the following mechanism is used.
- * 1) Check if readdir from posix is over.
- * 2) If so, then send a lookup on entry point directory to snap daemon
- * (this is needed because in readdirp inodes are linked, so we need to
- * maintain 1:1 mapping between inodes (gfids) from snapview server to
- * snapview client).
- * 3) Once successful lookup response received, send a new entry to
- * windows.
- */
-
-int32_t
-svc_readdirp_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)
-{
- gf_dirent_t entries;
- gf_dirent_t *entry = NULL;
- svc_private_t *private = NULL;
- svc_fd_t *svc_fd = NULL;
- svc_local_t *local = NULL;
- int inode_type = -1;
- int ret = -1;
-
- GF_VALIDATE_OR_GOTO ("snapview-client", this, out);
- GF_VALIDATE_OR_GOTO (this->name, this->private, out);
-
- private = this->private;
- INIT_LIST_HEAD (&entries.list);
-
- local = frame->local;
-
- if (op_ret) {
- op_ret = 0;
- op_errno = ENOENT;
- goto out;
- }
-
- svc_fd = svc_fd_ctx_get (this, local->fd);
- if (!svc_fd) {
- gf_log (this->name, GF_LOG_ERROR, "failed to get the fd "
- "context for the inode %s",
- uuid_utoa (local->fd->inode->gfid));
- op_ret = 0;
- op_errno = ENOENT;
- goto out;
- }
-
- entry = gf_dirent_for_name (private->path);
- if (!entry) {
- gf_log (this->name, GF_LOG_ERROR, "failed to allocate memory "
- "for the entry %s", private->path);
- op_ret = 0;
- op_errno = ENOMEM;
- goto out;
- }
-
- entry->inode = inode_ref (inode);
- entry->d_off = svc_fd->last_offset + 22;
- entry->d_ino = buf->ia_ino;
- entry->d_type = DT_DIR;
- entry->d_stat = *buf;
- inode_type = VIRTUAL_INODE;
- ret = svc_inode_ctx_set (this, entry->inode, inode_type);
- if (ret)
- gf_log (this->name, GF_LOG_ERROR, "failed to set the inode "
- "context");
-
- list_add_tail (&entry->list, &entries.list);
- op_ret = 1;
- svc_fd->last_offset = entry->d_off;
- svc_fd->entry_point_handled = _gf_true;
-
-out:
- SVC_STACK_UNWIND (readdirp, frame, op_ret, op_errno, &entries,
- local->xdata);
-
- gf_dirent_free (&entries);
-
- return 0;
-}
-
-gf_boolean_t
-svc_readdir_on_special_dir (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno,
- gf_dirent_t *entries, dict_t *xdata)
-{
- svc_local_t *local = NULL;
- svc_private_t *private = NULL;
- inode_t *inode = NULL;
- fd_t *fd = NULL;
- char *path = NULL;
- loc_t *loc = NULL;
- dict_t *tmp_xdata = NULL;
- int ret = -1;
- gf_boolean_t unwind = _gf_true;
- svc_fd_t *svc_fd = NULL;
-
- GF_VALIDATE_OR_GOTO ("snapview-client", this, out);
- GF_VALIDATE_OR_GOTO (this->name, this->private, out);
-
- private = this->private;
- local = frame->local;
-
- loc = &local->loc;
- fd = local->fd;
- svc_fd = svc_fd_ctx_get (this, fd);
- if (!svc_fd) {
- gf_log (this->name, GF_LOG_ERROR, "failed to get the fd "
- "context for the inode %s",
- uuid_utoa (fd->inode->gfid));
- goto out;
- }
-
- /*
- * check if its end of readdir operation from posix, if special_dir
- * option is set, if readdir is done on special directory and if
- * readdirp is from normal regular graph.
- */
-
- if (!private->show_entry_point)
- goto out;
-
- if (op_ret == 0 && op_errno == ENOENT && private->special_dir &&
- strcmp (private->special_dir, "") && svc_fd->special_dir &&
- local->subvolume == FIRST_CHILD (this)) {
- inode = inode_grep (fd->inode->table, fd->inode,
- private->path);
- if (!inode) {
- inode = inode_new (fd->inode->table);
- if (!inode) {
- gf_log (this->name, GF_LOG_ERROR, "failed to "
- "allocate new inode");
- goto out;
- }
- }
-
- uuid_copy (local->loc.pargfid, fd->inode->gfid);
- uuid_copy (local->loc.gfid, inode->gfid);
- if (uuid_is_null (inode->gfid))
- ret = inode_path (fd->inode, private->path, &path);
- else
- ret = inode_path (inode, NULL, &path);
-
- if (ret < 0)
- goto out;
- loc->path = gf_strdup (path);
- if (loc->path) {
- if (!loc->name ||
- (loc->name && !strcmp (loc->name, ""))) {
- loc->name = strrchr (loc->path, '/');
- if (loc->name)
- loc->name++;
- }
- }
-
- loc->inode = inode;
- loc->parent = inode_ref (fd->inode);
- tmp_xdata = dict_new ();
- if (!tmp_xdata)
- goto out;
- ret = dict_set_str (tmp_xdata, "entry-point", "true");
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "failed to set dict");
- goto out;
- }
-
- local->cookie = cookie;
- local->xdata = dict_ref (xdata);
- STACK_WIND (frame, svc_readdirp_lookup_cbk,
- SECOND_CHILD (this),
- SECOND_CHILD (this)->fops->lookup, loc, tmp_xdata);
- unwind = _gf_false;
- }
-
-out:
- if (tmp_xdata)
- dict_unref (tmp_xdata);
-
- GF_FREE (path);
- return unwind;
-}
-
-int32_t
-svc_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)
-{
- gf_dirent_t *entry = NULL;
- svc_local_t *local = NULL;
- gf_boolean_t real = _gf_true;
- int inode_type = -1;
- int ret = -1;
- svc_fd_t *svc_fd = NULL;
- gf_boolean_t unwind = _gf_true;
-
- GF_VALIDATE_OR_GOTO ("snapview-client", this, out);
-
- if (op_ret < 0)
- goto out;
-
- local = frame->local;
-
- svc_fd = svc_fd_ctx_get (this, local->fd);
- if (!svc_fd) {
- gf_log (this->name, GF_LOG_WARNING, "failed to get the fd "
- "context for the gfid %s",
- uuid_utoa (local->fd->inode->gfid));
- }
-
- if (local->subvolume == FIRST_CHILD (this))
- real = _gf_true;
- else
- real = _gf_false;
-
- list_for_each_entry (entry, &entries->list, list) {
- if (!entry->inode)
- continue;
-
- if (real)
- inode_type = NORMAL_INODE;
- else
- inode_type = VIRTUAL_INODE;
-
- ret = svc_inode_ctx_set (this, entry->inode, inode_type);
- if (ret)
- gf_log (this->name, GF_LOG_ERROR, "failed to set inode "
- "context");
- svc_fd->last_offset = entry->d_off;
- }
-
- unwind = svc_readdir_on_special_dir (frame, cookie, this, op_ret,
- op_errno, entries, xdata);
-
-out:
- if (unwind)
- SVC_STACK_UNWIND (readdirp, frame, op_ret, op_errno, entries,
- xdata);
-
- return 0;
-}
-
-int32_t
-svc_readdirp (call_frame_t *frame, xlator_t *this, fd_t *fd,
- size_t size, off_t off,
- dict_t *xdata)
-{
- int inode_type = -1;
- xlator_t *subvolume = NULL;
- svc_local_t *local = NULL;
- int ret = -1;
- int op_ret = -1;
- int op_errno = EINVAL;
- gf_boolean_t wind = _gf_false;
- svc_fd_t *svc_fd = NULL;
- gf_dirent_t entries;
-
- INIT_LIST_HEAD (&entries.list);
-
- GF_VALIDATE_OR_GOTO ("svc", this, out);
- GF_VALIDATE_OR_GOTO (this->name, frame, out);
- GF_VALIDATE_OR_GOTO (this->name, fd, out);
- GF_VALIDATE_OR_GOTO (this->name, fd->inode, out);
-
- local = mem_get0 (this->local_pool);
- if (!local) {
- gf_log (this->name, GF_LOG_ERROR, "failed to allocate local");
- op_errno = ENOMEM;
- goto out;
- }
-
- /*
- * This is mainly for samba shares (or windows clients). As part of
- * readdirp on the directory used as samba share, the entry point
- * directory would have been added at the end. So when a new readdirp
- * request comes, we have to check if the entry point has been handled
- * or not in readdirp. That information and the offset used for it
- * is remembered in fd context. If it has been handled, then simply
- * unwind indication end of readdir operation.
- */
- svc_fd = svc_fd_ctx_get_or_new (this, fd);
- if (!svc_fd)
- gf_log (this->name, GF_LOG_ERROR, "failed to get the fd "
- "context for the inode %s",
- uuid_utoa (fd->inode->gfid));
- else {
- if (svc_fd->entry_point_handled && off == svc_fd->last_offset) {
- op_ret = 0;
- op_errno = ENOENT;
- goto out;
- }
- }
-
- SVC_GET_SUBVOL_FROM_CTX (this, op_ret, op_errno, inode_type, ret,
- fd->inode, subvolume, out);
-
- local->subvolume = subvolume;
- local->fd = fd_ref (fd);
- frame->local = local;
-
- STACK_WIND (frame, svc_readdirp_cbk, subvolume,
- subvolume->fops->readdirp, fd, size, off, xdata);
-
- wind = _gf_true;
-
-out:
- if (!wind)
- SVC_STACK_UNWIND (readdirp, frame, op_ret, op_errno, &entries,
- NULL);
-
- gf_dirent_free (&entries);
-
- return 0;
-}
-
-/* Renaming the entries from or to snapshots is not allowed as the snapshots
- are read-only.
-*/
-int32_t
-svc_rename (call_frame_t *frame, xlator_t *this, loc_t *oldloc,
- loc_t *newloc, dict_t *xdata)
-{
- int src_inode_type = -1;
- int dst_inode_type = -1;
- int dst_parent_type = -1;
- int32_t op_ret = -1;
- int32_t op_errno = 0;
- int32_t ret = -1;
- gf_boolean_t wind = _gf_false;
-
- GF_VALIDATE_OR_GOTO ("svc", this, out);
- GF_VALIDATE_OR_GOTO (this->name, frame, out);
- GF_VALIDATE_OR_GOTO (this->name, oldloc, out);
- GF_VALIDATE_OR_GOTO (this->name, oldloc->inode, out);
- GF_VALIDATE_OR_GOTO (this->name, newloc, out);
-
- ret = svc_inode_ctx_get (this, oldloc->inode, &src_inode_type);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR, "failed to get the inode "
- "context for the inode %s",
- uuid_utoa (oldloc->inode->gfid));
- op_ret = -1;
- op_errno = EINVAL;
- goto out;
- }
-
- if (src_inode_type == VIRTUAL_INODE) {
- gf_log (this->name, GF_LOG_ERROR, "rename happening on a entry"
- " %s residing in snapshot", oldloc->name);
- op_ret = -1;
- op_errno = EROFS;
- goto out;
- }
-
- if (newloc->inode) {
- ret = svc_inode_ctx_get (this, newloc->inode, &dst_inode_type);
- if (!ret && dst_inode_type == VIRTUAL_INODE) {
- gf_log (this->name, GF_LOG_ERROR, "rename of %s "
- "happening to a entry %s residing in snapshot",
- oldloc->name, newloc->name);
- op_ret = -1;
- op_errno = EROFS;
- goto out;
- }
- }
-
- if (dst_inode_type < 0) {
- ret = svc_inode_ctx_get (this, newloc->parent,
- &dst_parent_type);
- if (!ret && dst_parent_type == VIRTUAL_INODE) {
- gf_log (this->name, GF_LOG_ERROR, "rename of %s "
- "happening to a entry %s residing in snapshot",
- oldloc->name, newloc->name);
- op_ret = -1;
- op_errno = EROFS;
- goto out;
- }
- }
-
- STACK_WIND_TAIL (frame, FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->rename, oldloc, newloc,
- xdata);
-
- wind = _gf_true;
-
-out:
- if (!wind)
- SVC_STACK_UNWIND (rename, frame, op_ret, op_errno, NULL,
- NULL, NULL, NULL, NULL, NULL);
- return 0;
-}
-
-/* Creating hardlinks for the files from the snapshot is not allowed as it
- will be equivalent of creating hardlinks across different filesystems.
- And so is vise versa.
-*/
-int32_t
-svc_link (call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc,
- dict_t *xdata)
-{
- int src_inode_type = -1;
- int dst_parent_type = -1;
- int32_t op_ret = -1;
- int32_t op_errno = 0;
- int32_t ret = -1;
- gf_boolean_t wind = _gf_false;
-
- GF_VALIDATE_OR_GOTO ("svc", this, out);
- GF_VALIDATE_OR_GOTO (this->name, frame, out);
- GF_VALIDATE_OR_GOTO (this->name, oldloc, out);
- GF_VALIDATE_OR_GOTO (this->name, oldloc->inode, out);
- GF_VALIDATE_OR_GOTO (this->name, newloc, out);
-
- ret = svc_inode_ctx_get (this, oldloc->inode, &src_inode_type);
- if (!ret && src_inode_type == VIRTUAL_INODE) {
- gf_log (this->name, GF_LOG_ERROR, "rename happening on a entry"
- " %s residing in snapshot", oldloc->name);
- op_ret = -1;
- op_errno = EROFS;
- goto out;
- }
-
- ret = svc_inode_ctx_get (this, newloc->parent, &dst_parent_type);
- if (!ret && dst_parent_type == VIRTUAL_INODE) {
- gf_log (this->name, GF_LOG_ERROR, "rename of %s "
- "happening to a entry %s residing in snapshot",
- oldloc->name, newloc->name);
- op_ret = -1;
- op_errno = EROFS;
- goto out;
- }
-
- STACK_WIND_TAIL (frame, FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->link, oldloc, newloc, xdata);
-
- wind = _gf_true;
-
-out:
- if (!wind)
- SVC_STACK_UNWIND (link, frame, op_ret, op_errno,
- NULL, NULL, NULL, NULL, NULL);
- return 0;
-}
-
-int32_t
-svc_removexattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
- const char *name, dict_t *xdata)
-{
- int ret = -1;
- int inode_type = -1;
- int op_ret = -1;
- int op_errno = EINVAL;
- gf_boolean_t wind = _gf_false;
-
- GF_VALIDATE_OR_GOTO ("svc", this, out);
- GF_VALIDATE_OR_GOTO (this->name, frame, out);
- GF_VALIDATE_OR_GOTO (this->name, loc, out);
- GF_VALIDATE_OR_GOTO (this->name, loc->inode, out);
-
- ret = svc_inode_ctx_get (this, loc->inode, &inode_type);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR, "failed to get te inode "
- "context for %s (gfid: %s)", loc->path,
- uuid_utoa (loc->inode->gfid));
- op_ret = -1;
- op_errno = EINVAL;
- goto out;
- }
-
- if (inode_type == NORMAL_INODE) {
- STACK_WIND_TAIL (frame, FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->removexattr, loc,
- name, xdata);
- } else {
- op_ret = -1;
- op_errno = EROFS;
- goto out;
- }
-
- wind = _gf_true;
-
-out:
- if (!wind)
- SVC_STACK_UNWIND (removexattr, frame, op_ret, op_errno,
- NULL);
-
- return 0;
-}
-
-int
-svc_fsync (call_frame_t *frame, xlator_t *this, fd_t *fd, int datasync,
- dict_t *xdata)
-{
- int inode_type = -1;
- int ret = -1;
- int op_ret = -1;
- int op_errno = EINVAL;
- gf_boolean_t wind = _gf_false;
-
- GF_VALIDATE_OR_GOTO ("svc", this, out);
- GF_VALIDATE_OR_GOTO (this->name, frame, out);
- GF_VALIDATE_OR_GOTO (this->name, fd, out);
- GF_VALIDATE_OR_GOTO (this->name, fd->inode, out);
-
- ret = svc_inode_ctx_get (this, fd->inode, &inode_type);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR, "failed to get inode context "
- "for %s", uuid_utoa (fd->inode->gfid));
- op_ret = -1;
- op_errno = EINVAL;
- goto out;
- }
-
- if (inode_type == NORMAL_INODE) {
- STACK_WIND_TAIL (frame, FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->fsync, fd, datasync,
- xdata);
- } else {
- op_ret = -1;
- op_errno = EROFS;
- goto out;
- }
-
- wind = _gf_true;
-
-out:
- if (!wind)
- SVC_STACK_UNWIND (fsync, frame, op_ret, op_errno, NULL, NULL,
- NULL);
-
- return 0;
-}
-
-int32_t
-svc_flush (call_frame_t *frame, xlator_t *this,
- fd_t *fd, dict_t *xdata)
-{
- int32_t op_ret = -1;
- int32_t op_errno = 0;
- int ret = -1;
- int inode_type = -1;
- xlator_t *subvolume = NULL;
- gf_boolean_t wind = _gf_false;
-
- GF_VALIDATE_OR_GOTO ("svc", this, out);
- GF_VALIDATE_OR_GOTO (this->name, frame, out);
- GF_VALIDATE_OR_GOTO (this->name, fd, out);
- GF_VALIDATE_OR_GOTO (this->name, fd->inode, out);
-
- SVC_GET_SUBVOL_FROM_CTX (this, op_ret, op_errno, inode_type, ret,
- fd->inode, subvolume, out);
-
- STACK_WIND_TAIL (frame, subvolume, subvolume->fops->flush, fd, xdata);
-
- wind = _gf_true;
-
-out:
- if (!wind)
- SVC_STACK_UNWIND (flush, frame, op_ret, op_errno, NULL);
-
- return 0;
-}
-
-int32_t
-svc_releasedir (xlator_t *this, fd_t *fd)
-{
- svc_fd_t *sfd = NULL;
- uint64_t tmp_pfd = 0;
- int ret = 0;
-
- GF_VALIDATE_OR_GOTO ("snapview-client", this, out);
- GF_VALIDATE_OR_GOTO (this->name, fd, out);
-
- ret = fd_ctx_del (fd, this, &tmp_pfd);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_DEBUG,
- "pfd from fd=%p is NULL", fd);
- goto out;
- }
-
- GF_FREE (sfd);
-
-out:
- return 0;
-}
-
-int32_t
-svc_forget (xlator_t *this, inode_t *inode)
-{
- int ret = -1;
- uint64_t value = 0;
-
- GF_VALIDATE_OR_GOTO ("svc", this, out);
- GF_VALIDATE_OR_GOTO (this->name, inode, out);
-
- ret = inode_ctx_del (inode, this, &value);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "failed to delete inode "
- "context for %s", uuid_utoa (inode->gfid));
- goto out;
- }
-
-out:
- return 0;
-}
-
-int
-reconfigure (xlator_t *this, dict_t *options)
-{
- svc_private_t *priv = NULL;
-
- priv = this->private;
-
- GF_OPTION_RECONF ("snapshot-directory", priv->path, options, str, out);
- GF_OPTION_RECONF ("show-snapshot-directory", priv->show_entry_point,
- options, bool, out);
-
-out:
- return 0;
-}
-
-int32_t
-mem_acct_init (xlator_t *this)
-{
- int32_t ret = -1;
-
- if (!this)
- return ret;
-
- ret = xlator_mem_acct_init (this, gf_svc_mt_end + 1);
-
- if (ret != 0) {
- gf_log (this->name, GF_LOG_WARNING, "Memory accounting"
- " init failed");
- return ret;
- }
-
- return ret;
-}
-
-int32_t
-init (xlator_t *this)
-{
- svc_private_t *private = NULL;
- int ret = -1;
- int children = 0;
- xlator_list_t *xl = NULL;
-
- if (!this->children) {
- gf_log (this->name, GF_LOG_ERROR,
- "configured without any child");
- goto out;
- }
-
- xl = this->children;
- while (xl) {
- children++;
- xl = xl->next;
- }
-
- if (children != 2) {
- gf_log (this->name, GF_LOG_ERROR, "snap-view-client has got "
- "%d subvolumes. It can have only 2 subvolumes.",
- children);
- goto out;
- }
-
- /* This can be the top of graph in certain cases */
- if (!this->parents) {
- gf_log (this->name, GF_LOG_DEBUG,
- "dangling volume. check volfile ");
- }
-
- private = GF_CALLOC (1, sizeof (*private), gf_svc_mt_svc_private_t);
- if (!private)
- goto out;
-
- GF_OPTION_INIT ("snapshot-directory", private->path, str, out);
- GF_OPTION_INIT ("snapdir-entry-path", private->special_dir, str,
- out);
- GF_OPTION_INIT ("show-snapshot-directory", private->show_entry_point,
- bool, out);
-
- if (strstr (private->special_dir, private->path)) {
- gf_log (this->name, GF_LOG_ERROR, "entry point directory "
- "cannot be part of the special directory");
- GF_FREE (private->special_dir);
- private->special_dir = NULL;
- goto out;
- }
-
- this->private = private;
- this->local_pool = mem_pool_new (svc_local_t, 128);
- if (!this->local_pool) {
- gf_log (this->name, GF_LOG_ERROR, "could not get mem pool for "
- "frame->local");
- goto out;
- }
-
- ret = 0;
-
-out:
- if (ret)
- GF_FREE (private);
-
- return ret;
-}
-
-void
-fini (xlator_t *this)
-{
- svc_private_t *priv = NULL;
-
- if (!this)
- return;
-
- priv = this->private;
- if (!priv)
- return;
-
- this->private = NULL;
-
- GF_FREE (priv->path);
- GF_FREE (priv->special_dir);
- GF_FREE (priv);
-
- return;
-}
-
-int
-notify (xlator_t *this, int event, void *data, ...)
-{
- xlator_t *subvol = NULL;
- int ret = 0;
-
- subvol = data;
-
- /* As there are two subvolumes in snapview-client, there is
- * a possibility that the regular subvolume is still down and
- * snapd subvolume come up first. So if we don't handle this situation
- * CHILD_UP event will be propagated upwards to fuse when
- * regular subvolume is still down.
- * This can cause data unavailable for the application.
- * So for now send notifications up only for regular subvolume.
- *
- * TODO: In future if required we may need to handle
- * notifications from virtual subvolume
- */
- if (subvol != SECOND_CHILD (this))
- ret = default_notify (this, event, data);
-
- return ret;
-}
-
-struct xlator_fops fops = {
- .lookup = svc_lookup,
- .opendir = svc_opendir,
- .stat = svc_stat,
- .fstat = svc_fstat,
- .rmdir = svc_rmdir,
- .rename = svc_rename,
- .mkdir = svc_mkdir,
- .open = svc_open,
- .unlink = svc_unlink,
- .setattr = svc_setattr,
- .getxattr = svc_getxattr,
- .setxattr = svc_setxattr,
- .fsetxattr = svc_fsetxattr,
- .readv = svc_readv,
- .readdir = svc_readdir,
- .readdirp = svc_readdirp,
- .create = svc_create,
- .readlink = svc_readlink,
- .mknod = svc_mknod,
- .symlink = svc_symlink,
- .flush = svc_flush,
- .link = svc_link,
- .access = svc_access,
- .removexattr = svc_removexattr,
- .fsync = svc_fsync,
-};
-
-struct xlator_cbks cbks = {
- .forget = svc_forget,
- .releasedir = svc_releasedir,
-};
-
-struct volume_options options[] = {
- { .key = {"snapshot-directory"},
- .type = GF_OPTION_TYPE_STR,
- .default_value = ".snaps",
- },
- { .key = {"snapdir-entry-path"},
- .type = GF_OPTION_TYPE_STR,
- .description = "An option to set the path of a directory on which "
- "when readdir comes, dentry for the snapshot-directory"
- " should be created and added in the readdir response",
- .default_value = "",
- },
- { .key = {"show-snapshot-directory"},
- .type = GF_OPTION_TYPE_BOOL,
- .description = "If this option is set, and the option "
- "\"snapdir-entry-path\" is set (which is set by samba "
- "vfs plugin for glusterfs, then send the entry point "
- "when readdir comes on the snapdir-entry-path",
- .default_value = "off",
- },
- { .key = {NULL} },
-};
diff --git a/xlators/features/snapview-client/src/snapview-client.h b/xlators/features/snapview-client/src/snapview-client.h
deleted file mode 100644
index 9973458884b..00000000000
--- a/xlators/features/snapview-client/src/snapview-client.h
+++ /dev/null
@@ -1,126 +0,0 @@
- /*
- Copyright (c) 2014 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 __SNAP_VIEW_CLIENT_H__
-#define __SNAP_VIEW_CLIENT_H__
-
-#ifndef _CONFIG_H
-#define _CONFIG_H
-#include "config.h"
-#endif
-
-#include "glusterfs.h"
-#include "logging.h"
-#include "dict.h"
-#include "xlator.h"
-#include "defaults.h"
-#include "snapview-client-mem-types.h"
-
-struct __svc_local {
- loc_t loc;
- xlator_t *subvolume;
- fd_t *fd;
- void *cookie;
- dict_t *xdata;
-};
-typedef struct __svc_local svc_local_t;
-
-void
-svc_local_free (svc_local_t *local);
-
-#define SVC_STACK_UNWIND(fop, frame, params ...) do { \
- svc_local_t *__local = NULL; \
- if (frame) { \
- __local = frame->local; \
- frame->local = NULL; \
- } \
- STACK_UNWIND_STRICT (fop, frame, params); \
- svc_local_free (__local); \
- } while (0)
-
-#define SVC_ENTRY_POINT_SET(this, xdata, op_ret, op_errno, new_xdata, \
- priv, ret, label) \
- do { \
- if (!xdata) { \
- xdata = new_xdata = dict_new (); \
- if (!new_xdata) { \
- gf_log (this->name, GF_LOG_ERROR, \
- "failed to allocate new dict"); \
- op_ret = -1; \
- op_errno = ENOMEM; \
- goto label; \
- } \
- } \
- ret = dict_set_str (xdata, "entry-point", "true"); \
- if (ret) { \
- gf_log (this->name, GF_LOG_ERROR, \
- "failed to set dict"); \
- op_ret = -1; \
- op_errno = ENOMEM; \
- goto label; \
- } \
- } while (0);
-
-#define SVC_GET_SUBVOL_FROM_CTX(this, op_ret, op_errno, inode_type, ret, \
- inode, subvolume, label) \
- do { \
- ret = svc_inode_ctx_get (this, inode, &inode_type); \
- if (ret < 0) { \
- gf_log (this->name, GF_LOG_ERROR, \
- "inode context not found for gfid %s", \
- uuid_utoa (inode->gfid)); \
- op_ret = -1; \
- op_errno = EINVAL; \
- goto label; \
- } \
- \
- subvolume = svc_get_subvolume (this, inode_type); \
- } while (0);
-
-struct svc_private {
- char *path;
- char *special_dir; /* needed for samba */
- gf_boolean_t show_entry_point;
-};
-typedef struct svc_private svc_private_t;
-
-struct svc_fd {
- off_t last_offset;
- gf_boolean_t entry_point_handled;
- gf_boolean_t special_dir;
-};
-typedef struct svc_fd svc_fd_t;
-
-typedef enum {
- NORMAL_INODE = 1,
- VIRTUAL_INODE
-} inode_type_t;
-
-void svc_local_free (svc_local_t *local);
-
-xlator_t *
-svc_get_subvolume (xlator_t *this, int inode_type);
-
-int
-__svc_inode_ctx_get (xlator_t *this, inode_t *inode, int *inode_type);
-
-int
-svc_inode_ctx_get (xlator_t *this, inode_t *inode, int *inode_type);
-
-int32_t
-svc_inode_ctx_set (xlator_t *this, inode_t *inode, int inode_type);
-
-void
-svc_local_free (svc_local_t *local);
-
-gf_boolean_t
-svc_readdir_on_special_dir (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno,
- gf_dirent_t *entries, dict_t *xdata);
-#endif /* __SNAP_VIEW_CLIENT_H__ */
diff --git a/xlators/features/snapview-server/Makefile.am b/xlators/features/snapview-server/Makefile.am
deleted file mode 100644
index af437a64d6d..00000000000
--- a/xlators/features/snapview-server/Makefile.am
+++ /dev/null
@@ -1 +0,0 @@
-SUBDIRS = src
diff --git a/xlators/features/snapview-server/src/Makefile.am b/xlators/features/snapview-server/src/Makefile.am
deleted file mode 100644
index df58d7bef71..00000000000
--- a/xlators/features/snapview-server/src/Makefile.am
+++ /dev/null
@@ -1,22 +0,0 @@
-xlator_LTLIBRARIES = snapview-server.la
-xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/features
-
-snapview_server_la_LDFLAGS = -module -avoid-version
-
-snapview_server_la_SOURCES = snapview-server.c snapview-server-mgmt.c snapview-server-helpers.c
-snapview_server_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la\
- $(top_builddir)/api/src/libgfapi.la\
- $(RLLIBS) $(top_builddir)/rpc/xdr/src/libgfxdr.la \
- $(top_builddir)/rpc/rpc-lib/src/libgfrpc.la
-
-noinst_HEADERS = snapview-server.h snapview-server-mem-types.h
-
-AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \
- -I$(top_srcdir)/api/src \
- -I$(top_srcdir)/rpc/rpc-lib/src \
- -I$(top_srcdir)/rpc/xdr/src \
- -DDATADIR=\"$(localstatedir)\"
-
-AM_CFLAGS = -Wall $(GF_CFLAGS)
-
-CLEANFILES =
diff --git a/xlators/features/snapview-server/src/snapview-server-helpers.c b/xlators/features/snapview-server/src/snapview-server-helpers.c
deleted file mode 100644
index 7f03dc47f02..00000000000
--- a/xlators/features/snapview-server/src/snapview-server-helpers.c
+++ /dev/null
@@ -1,594 +0,0 @@
-/*
- Copyright (c) 2014 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 "snapview-server.h"
-#include "snapview-server-mem-types.h"
-
-#include "xlator.h"
-#include "rpc-clnt.h"
-#include "xdr-generic.h"
-#include "protocol-common.h"
-#include <pthread.h>
-
-
-int
-__svs_inode_ctx_set (xlator_t *this, inode_t *inode, svs_inode_t *svs_inode)
-{
- uint64_t value = 0;
- int ret = -1;
-
- GF_VALIDATE_OR_GOTO ("snapview-server", this, out);
- GF_VALIDATE_OR_GOTO (this->name, inode, out);
- GF_VALIDATE_OR_GOTO (this->name, svs_inode, out);
-
- value = (uint64_t)(long) svs_inode;
-
- ret = __inode_ctx_set (inode, this, &value);
-
-out:
- return ret;
-}
-
-svs_inode_t *
-__svs_inode_ctx_get (xlator_t *this, inode_t *inode)
-{
- svs_inode_t *svs_inode = NULL;
- uint64_t value = 0;
- int ret = -1;
-
- GF_VALIDATE_OR_GOTO ("snapview-server", this, out);
- GF_VALIDATE_OR_GOTO (this->name, inode, out);
-
- ret = __inode_ctx_get (inode, this, &value);
- if (ret)
- goto out;
-
- svs_inode = (svs_inode_t *) ((long) value);
-
-out:
- return svs_inode;
-}
-
-svs_inode_t *
-svs_inode_ctx_get (xlator_t *this, inode_t *inode)
-{
- svs_inode_t *svs_inode = NULL;
-
- GF_VALIDATE_OR_GOTO ("snapview-server", this, out);
- GF_VALIDATE_OR_GOTO (this->name, inode, out);
-
- LOCK (&inode->lock);
- {
- svs_inode = __svs_inode_ctx_get (this, inode);
- }
- UNLOCK (&inode->lock);
-
-out:
- return svs_inode;
-}
-
-int32_t
-svs_inode_ctx_set (xlator_t *this, inode_t *inode, svs_inode_t *svs_inode)
-{
- int32_t ret = -1;
-
- GF_VALIDATE_OR_GOTO ("snapview-server", this, out);
- GF_VALIDATE_OR_GOTO (this->name, inode, out);
- GF_VALIDATE_OR_GOTO (this->name, svs_inode, out);
-
- LOCK (&inode->lock);
- {
- ret = __svs_inode_ctx_set (this, inode, svs_inode);
- }
- UNLOCK (&inode->lock);
-
-out:
- return ret;
-}
-
-svs_inode_t *
-svs_inode_new (void)
-{
- svs_inode_t *svs_inode = NULL;
-
- svs_inode = GF_CALLOC (1, sizeof (*svs_inode), gf_svs_mt_svs_inode_t);
-
- return svs_inode;
-}
-
-svs_inode_t *
-svs_inode_ctx_get_or_new (xlator_t *this, inode_t *inode)
-{
- svs_inode_t *svs_inode = NULL;
- int ret = -1;
-
- GF_VALIDATE_OR_GOTO ("snapview-server", this, out);
- GF_VALIDATE_OR_GOTO (this->name, inode, out);
-
- LOCK (&inode->lock);
- {
- svs_inode = __svs_inode_ctx_get (this, inode);
- if (!svs_inode) {
- svs_inode = svs_inode_new ();
- if (svs_inode) {
- ret = __svs_inode_ctx_set (this, inode,
- svs_inode);
- if (ret) {
- GF_FREE (svs_inode);
- svs_inode = NULL;
- }
- }
- }
- }
- UNLOCK (&inode->lock);
-
-out:
- return svs_inode;
-}
-
-svs_fd_t *
-svs_fd_new (void)
-{
- svs_fd_t *svs_fd = NULL;
-
- svs_fd = GF_CALLOC (1, sizeof (*svs_fd), gf_svs_mt_svs_fd_t);
-
- return svs_fd;
-}
-
-int
-__svs_fd_ctx_set (xlator_t *this, fd_t *fd, svs_fd_t *svs_fd)
-{
- uint64_t value = 0;
- int ret = -1;
-
- GF_VALIDATE_OR_GOTO ("snapview-server", this, out);
- GF_VALIDATE_OR_GOTO (this->name, fd, out);
- GF_VALIDATE_OR_GOTO (this->name, svs_fd, out);
-
- value = (uint64_t)(long) svs_fd;
-
- ret = __fd_ctx_set (fd, this, value);
-
-out:
- return ret;
-}
-
-svs_fd_t *
-__svs_fd_ctx_get (xlator_t *this, fd_t *fd)
-{
- svs_fd_t *svs_fd = NULL;
- uint64_t value = 0;
- int ret = -1;
-
- GF_VALIDATE_OR_GOTO ("snapview-server", this, out);
- GF_VALIDATE_OR_GOTO (this->name, fd, out);
-
- ret = __fd_ctx_get (fd, this, &value);
- if (ret)
- return NULL;
-
- svs_fd = (svs_fd_t *) ((long) value);
-
-out:
- return svs_fd;
-}
-
-svs_fd_t *
-svs_fd_ctx_get (xlator_t *this, fd_t *fd)
-{
- svs_fd_t *svs_fd = NULL;
-
- GF_VALIDATE_OR_GOTO ("snapview-server", this, out);
- GF_VALIDATE_OR_GOTO (this->name, fd, out);
-
- LOCK (&fd->lock);
- {
- svs_fd = __svs_fd_ctx_get (this, fd);
- }
- UNLOCK (&fd->lock);
-
-out:
- return svs_fd;
-}
-
-int32_t
-svs_fd_ctx_set (xlator_t *this, fd_t *fd, svs_fd_t *svs_fd)
-{
- int32_t ret = -1;
-
- GF_VALIDATE_OR_GOTO ("snapview-server", this, out);
- GF_VALIDATE_OR_GOTO (this->name, fd, out);
- GF_VALIDATE_OR_GOTO (this->name, svs_fd, out);
-
- LOCK (&fd->lock);
- {
- ret = __svs_fd_ctx_set (this, fd, svs_fd);
- }
- UNLOCK (&fd->lock);
-
-out:
- return ret;
-}
-
-svs_fd_t *
-__svs_fd_ctx_get_or_new (xlator_t *this, fd_t *fd)
-{
- svs_fd_t *svs_fd = NULL;
- int ret = -1;
- glfs_t *fs = NULL;
- glfs_object_t *object = NULL;
- svs_inode_t *inode_ctx = NULL;
- glfs_fd_t *glfd = NULL;
- inode_t *inode = NULL;
-
- GF_VALIDATE_OR_GOTO ("snapview-server", this, out);
- GF_VALIDATE_OR_GOTO (this->name, fd, out);
-
- inode = fd->inode;
- svs_fd = __svs_fd_ctx_get (this, fd);
- if (svs_fd) {
- ret = 0;
- goto out;
- }
-
- svs_fd = svs_fd_new ();
- if (!svs_fd) {
- gf_log (this->name, GF_LOG_ERROR, "failed to allocate new fd "
- "context for gfid %s", uuid_utoa (inode->gfid));
- goto out;
- }
-
- if (fd_is_anonymous (fd)) {
- inode_ctx = svs_inode_ctx_get (this, inode);
- if (!inode_ctx) {
- gf_log (this->name, GF_LOG_ERROR, "failed to get inode "
- "context for %s", uuid_utoa (inode->gfid));
- goto out;
- }
-
- fs = inode_ctx->fs;
- object = inode_ctx->object;
-
- if (inode->ia_type == IA_IFDIR) {
- glfd = glfs_h_opendir (fs, object);
- if (!glfd) {
- gf_log (this->name, GF_LOG_ERROR, "failed to "
- "open the directory %s",
- uuid_utoa (inode->gfid));
- goto out;
- }
- }
-
- if (inode->ia_type == IA_IFREG) {
- glfd = glfs_h_open (fs, object, O_RDONLY|O_LARGEFILE);
- if (!glfd) {
- gf_log (this->name, GF_LOG_ERROR, "failed to "
- "open the file %s",
- uuid_utoa (inode->gfid));
- goto out;
- }
- }
-
- svs_fd->fd = glfd;
- }
-
- ret = __svs_fd_ctx_set (this, fd, svs_fd);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "failed to set fd context "
- "for gfid %s", uuid_utoa (inode->gfid));
- if (svs_fd->fd) {
- if (inode->ia_type == IA_IFDIR) {
- ret = glfs_closedir (svs_fd->fd);
- if (ret)
- gf_log (this->name, GF_LOG_ERROR,
- "failed to close the fd for %s",
- uuid_utoa (inode->gfid));
- }
- if (inode->ia_type == IA_IFREG) {
- ret = glfs_close (svs_fd->fd);
- if (ret)
- gf_log (this->name, GF_LOG_ERROR,
- "failed to close the fd for %s",
- uuid_utoa (inode->gfid));
- }
- }
- ret = -1;
- }
-
-out:
- if (ret) {
- GF_FREE (svs_fd);
- svs_fd = NULL;
- }
-
- return svs_fd;
-}
-
-svs_fd_t *
-svs_fd_ctx_get_or_new (xlator_t *this, fd_t *fd)
-{
- svs_fd_t *svs_fd = NULL;
-
- GF_VALIDATE_OR_GOTO ("snapview-server", this, out);
- GF_VALIDATE_OR_GOTO (this->name, fd, out);
-
- LOCK (&fd->lock);
- {
- svs_fd = __svs_fd_ctx_get_or_new (this, fd);
- }
- UNLOCK (&fd->lock);
-
-out:
- return svs_fd;
-}
-
-void
-svs_fill_ino_from_gfid (struct iatt *buf)
-{
- uint64_t temp_ino = 0;
- int j = 0;
- int i = 0;
- xlator_t *this = NULL;
-
- this = THIS;
-
- GF_VALIDATE_OR_GOTO ("snapview-server", this, out);
- GF_VALIDATE_OR_GOTO (this->name, buf, out);
-
- /* 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;
-}
-
-void
-svs_iatt_fill (uuid_t gfid, struct iatt *buf)
-{
- struct timeval tv = {0, };
- xlator_t *this = NULL;
-
- this = THIS;
-
- GF_VALIDATE_OR_GOTO ("snapview-server", this, out);
- GF_VALIDATE_OR_GOTO (this->name, buf, out);
-
- buf->ia_type = IA_IFDIR;
- buf->ia_uid = 0;
- buf->ia_gid = 0;
- buf->ia_size = 0;
- buf->ia_nlink = 2;
- buf->ia_blocks = 8;
- buf->ia_size = 4096;
-
- uuid_copy (buf->ia_gfid, gfid);
- svs_fill_ino_from_gfid (buf);
-
- buf->ia_prot = ia_prot_from_st_mode (0755);
-
- gettimeofday (&tv, 0);
-
- buf->ia_mtime = buf->ia_atime = buf->ia_ctime = tv.tv_sec;
- buf->ia_mtime_nsec = buf->ia_atime_nsec = buf->ia_ctime_nsec =
- (tv.tv_usec * 1000);
-
-out:
- return;
-}
-
-/* priv->snaplist_lock should be held before calling this function */
-snap_dirent_t *
-__svs_get_snap_dirent (xlator_t *this, const char *name)
-{
- svs_private_t *private = NULL;
- int i = 0;
- snap_dirent_t *dirents = NULL;
- snap_dirent_t *tmp_dirent = NULL;
- snap_dirent_t *dirent = NULL;
-
- private = this->private;
-
- dirents = private->dirents;
- if (!dirents) {
- goto out;
- }
-
- tmp_dirent = dirents;
- for (i = 0; i < private->num_snaps; i++) {
- if (!strcmp (tmp_dirent->name, name)) {
- dirent = tmp_dirent;
- break;
- }
- tmp_dirent++;
- }
-
- out:
- return dirent;
-}
-
-glfs_t *
-__svs_initialise_snapshot_volume (xlator_t *this, const char *name,
- int32_t *op_errno)
-{
- svs_private_t *priv = NULL;
- int32_t ret = -1;
- int32_t local_errno = ESTALE;
- snap_dirent_t *dirent = NULL;
- char volname[PATH_MAX] = {0, };
- glfs_t *fs = NULL;
- int loglevel = GF_LOG_INFO;
- char logfile[PATH_MAX] = {0, };
-
- GF_VALIDATE_OR_GOTO ("snapview-server", this, out);
- GF_VALIDATE_OR_GOTO (this->name, this->private, out);
- GF_VALIDATE_OR_GOTO (this->name, name, out);
-
- priv = this->private;
-
- dirent = __svs_get_snap_dirent (this, name);
- if (!dirent) {
- gf_log (this->name, GF_LOG_DEBUG, "snap entry for "
- "name %s not found", name);
- local_errno = ENOENT;
- goto out;
- }
-
- if (dirent->fs) {
- ret = 0;
- fs = dirent->fs;
- goto out;
- }
-
- snprintf (volname, sizeof (volname), "/snaps/%s/%s",
- dirent->name, dirent->snap_volname);
-
-
- fs = glfs_new (volname);
- if (!fs) {
- gf_log (this->name, GF_LOG_ERROR,
- "glfs instance for snap volume %s "
- "failed", dirent->name);
- local_errno = ENOMEM;
- goto out;
- }
-
- ret = glfs_set_volfile_server (fs, "tcp", "localhost",
- 24007);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "setting the "
- "volfile srever for snap volume %s "
- "failed", dirent->name);
- goto out;
- }
-
- snprintf (logfile, sizeof (logfile),
- DEFAULT_SVD_LOG_FILE_DIRECTORY "/snaps/%s/%s-%s.log",
- priv->volname, name, dirent->uuid);
-
- ret = glfs_set_logging(fs, logfile, loglevel);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "failed to set the "
- "log file path");
- goto out;
- }
-
- ret = glfs_init (fs);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "initing the "
- "fs for %s failed", dirent->name);
- goto out;
- }
-
- ret = 0;
-
-out:
- if (ret) {
- if (op_errno)
- *op_errno = local_errno;
-
- if (fs)
- glfs_fini (fs);
- fs = NULL;
- }
-
- if (fs) {
- dirent->fs = fs;
- }
-
- return fs;
-}
-
-glfs_t *
-svs_initialise_snapshot_volume (xlator_t *this, const char *name,
- int32_t *op_errno)
-{
- glfs_t *fs = NULL;
- svs_private_t *priv = NULL;
-
- GF_VALIDATE_OR_GOTO ("snapview-server", this, out);
- GF_VALIDATE_OR_GOTO (this->name, this->private, out);
- GF_VALIDATE_OR_GOTO (this->name, name, out);
-
- priv = this->private;
-
- LOCK (&priv->snaplist_lock);
- {
- fs = __svs_initialise_snapshot_volume (this, name, op_errno);
- }
- UNLOCK (&priv->snaplist_lock);
-
-
-out:
-
- return fs;
-}
-
-snap_dirent_t *
-svs_get_latest_snap_entry (xlator_t *this)
-{
- svs_private_t *priv = NULL;
- snap_dirent_t *dirents = NULL;
- snap_dirent_t *dirent = NULL;
-
- GF_VALIDATE_OR_GOTO ("svs", this, out);
-
- priv = this->private;
-
- LOCK (&priv->snaplist_lock);
- {
- dirents = priv->dirents;
- if (!dirents) {
- goto unlock;
- }
- if (priv->num_snaps)
- dirent = &dirents[priv->num_snaps - 1];
- }
-unlock:
- UNLOCK (&priv->snaplist_lock);
-
-out:
- return dirent;
-}
-
-glfs_t *
-svs_get_latest_snapshot (xlator_t *this)
-{
- glfs_t *fs = NULL;
- snap_dirent_t *dirent = NULL;
- svs_private_t *priv = NULL;
-
- GF_VALIDATE_OR_GOTO ("svs", this, out);
- priv = this->private;
-
- dirent = svs_get_latest_snap_entry (this);
-
- if (dirent) {
- LOCK (&priv->snaplist_lock);
- {
- fs = dirent->fs;
- }
- UNLOCK (&priv->snaplist_lock);
- }
-
-out:
- return fs;
-}
diff --git a/xlators/features/snapview-server/src/snapview-server-mem-types.h b/xlators/features/snapview-server/src/snapview-server-mem-types.h
deleted file mode 100644
index a8035165000..00000000000
--- a/xlators/features/snapview-server/src/snapview-server-mem-types.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- Copyright (c) 2014 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 __SNAP_VIEW_MEM_TYPES_H
-#define __SNAP_VIEW_MEM_TYPES_H
-
-#include "mem-types.h"
-
-enum snapview_mem_types {
- gf_svs_mt_priv_t = gf_common_mt_end + 1,
- gf_svs_mt_svs_inode_t,
- gf_svs_mt_dirents_t,
- gf_svs_mt_svs_fd_t,
- gf_svs_mt_snaplist_t,
- gf_svs_mt_end
-};
-
-#endif
-
diff --git a/xlators/features/snapview-server/src/snapview-server-mgmt.c b/xlators/features/snapview-server/src/snapview-server-mgmt.c
deleted file mode 100644
index f2a1e7b7893..00000000000
--- a/xlators/features/snapview-server/src/snapview-server-mgmt.c
+++ /dev/null
@@ -1,480 +0,0 @@
-/*
- Copyright (c) 2014 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 "snapview-server.h"
-#include "snapview-server-mem-types.h"
-#include <pthread.h>
-
-int
-mgmt_cbk_snap (struct rpc_clnt *rpc, void *mydata, void *data)
-{
- xlator_t *this = NULL;
-
- this = mydata;
- GF_ASSERT (this);
-
- gf_log ("mgmt", GF_LOG_INFO, "list of snapshots changed");
-
- svs_get_snapshot_list (this);
- return 0;
-}
-
-rpcclnt_cb_actor_t svs_cbk_actors[GF_CBK_MAXVALUE] = {
- [GF_CBK_GET_SNAPS] = {"GETSNAPS", GF_CBK_GET_SNAPS, mgmt_cbk_snap},
-};
-
-struct rpcclnt_cb_program svs_cbk_prog = {
- .progname = "GlusterFS Callback",
- .prognum = GLUSTER_CBK_PROGRAM,
- .progver = GLUSTER_CBK_VERSION,
- .actors = svs_cbk_actors,
- .numactors = GF_CBK_MAXVALUE,
-};
-
-char *clnt_handshake_procs[GF_HNDSK_MAXVALUE] = {
- [GF_HNDSK_NULL] = "NULL",
- [GF_HNDSK_EVENT_NOTIFY] = "EVENTNOTIFY",
-};
-
-rpc_clnt_prog_t svs_clnt_handshake_prog = {
- .progname = "GlusterFS Handshake",
- .prognum = GLUSTER_HNDSK_PROGRAM,
- .progver = GLUSTER_HNDSK_VERSION,
- .procnames = clnt_handshake_procs,
-};
-
-int
-svs_mgmt_init (xlator_t *this)
-{
- int ret = -1;
- svs_private_t *priv = NULL;
- dict_t *options = NULL;
- int port = GF_DEFAULT_BASE_PORT;
- char *host = NULL;
- cmd_args_t *cmd_args = NULL;
- glusterfs_ctx_t *ctx = NULL;
-
- GF_VALIDATE_OR_GOTO ("snapview-server", this, out);
- GF_VALIDATE_OR_GOTO (this->name, this->private, out);
- GF_VALIDATE_OR_GOTO (this->name, this->ctx, out);
-
- priv = this->private;
-
- ctx = this->ctx;
- cmd_args = &ctx->cmd_args;
-
- host = "localhost";
- if (cmd_args->volfile_server)
- host = cmd_args->volfile_server;
-
- ret = rpc_transport_inet_options_build (&options, host, port);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "failed to build the "
- "transport options");
- goto out;
- }
-
- priv->rpc = rpc_clnt_new (options, this->ctx, this->name, 8);
- if (!priv->rpc) {
- gf_log (this->name, GF_LOG_ERROR, "failed to initialize RPC");
- goto out;
- }
-
- ret = rpcclnt_cbk_program_register (priv->rpc, &svs_cbk_prog,
- this);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "failed to register callback program");
- goto out;
- }
-
- ret = rpc_clnt_start (priv->rpc);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "failed to start the rpc "
- "client");
- goto out;
- }
-
- ret = 0;
-
- gf_log (this->name, GF_LOG_DEBUG, "svs mgmt init successful");
-
-out:
- if (ret) {
- rpc_clnt_connection_cleanup (&priv->rpc->conn);
- rpc_clnt_unref (priv->rpc);
- priv->rpc = NULL;
- }
-
- return ret;
-}
-
-int
-svs_mgmt_submit_request (void *req, call_frame_t *frame,
- glusterfs_ctx_t *ctx,
- rpc_clnt_prog_t *prog, int procnum,
- fop_cbk_fn_t cbkfn, xdrproc_t xdrproc)
-{
- int ret = -1;
- int count = 0;
- struct iovec iov = {0, };
- struct iobuf *iobuf = NULL;
- struct iobref *iobref = NULL;
- ssize_t xdr_size = 0;
-
- GF_VALIDATE_OR_GOTO ("snapview-server", frame, out);
- GF_VALIDATE_OR_GOTO ("snapview-server", req, out);
- GF_VALIDATE_OR_GOTO ("snapview-server", ctx, out);
- GF_VALIDATE_OR_GOTO ("snapview-server", prog, out);
-
- GF_ASSERT (frame->this);
-
- iobref = iobref_new ();
- if (!iobref) {
- goto out;
- }
-
- if (req) {
- xdr_size = xdr_sizeof (xdrproc, req);
-
- iobuf = iobuf_get2 (ctx->iobuf_pool, xdr_size);
- if (!iobuf) {
- 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) {
- gf_log (frame->this->name, GF_LOG_WARNING,
- "Failed to create XDR payload");
- goto out;
- }
- iov.iov_len = ret;
- count = 1;
- }
-
- ret = rpc_clnt_submit (ctx->mgmt, prog, procnum, cbkfn,
- &iov, count,
- NULL, 0, iobref, frame, NULL, 0, NULL, 0, NULL);
-
-out:
- if (iobref)
- iobref_unref (iobref);
-
- if (iobuf)
- iobuf_unref (iobuf);
- return ret;
-}
-
-
-int
-mgmt_get_snapinfo_cbk (struct rpc_req *req, struct iovec *iov,
- int count, void *myframe)
-{
- gf_getsnap_name_uuid_rsp rsp = {0,};
- call_frame_t *frame = NULL;
- glusterfs_ctx_t *ctx = NULL;
- int ret = -1;
- dict_t *dict = NULL;
- char key[1024] = {0};
- int snapcount = 0;
- svs_private_t *priv = NULL;
- xlator_t *this = NULL;
- int i = 0;
- int j = 0;
- char *value = NULL;
- snap_dirent_t *dirents = NULL;
- snap_dirent_t *old_dirents = NULL;
- int oldcount = 0;
-
- GF_VALIDATE_OR_GOTO ("snapview-server", req, error_out);
- GF_VALIDATE_OR_GOTO ("snapview-server", myframe, error_out);
- GF_VALIDATE_OR_GOTO ("snapview-server", iov, error_out);
-
- frame = myframe;
- this = frame->this;
- ctx = frame->this->ctx;
- priv = this->private;
- old_dirents = priv->dirents;
-
- if (!ctx) {
- gf_log (frame->this->name, GF_LOG_ERROR, "NULL context");
- errno = EINVAL;
- goto out;
- }
-
- if (-1 == req->rpc_status) {
- gf_log (frame->this->name, GF_LOG_ERROR,
- "RPC call is not successful");
- errno = EINVAL;
- goto out;
- }
-
- ret = xdr_to_generic (*iov, &rsp,
- (xdrproc_t)xdr_gf_getsnap_name_uuid_rsp);
- if (ret < 0) {
- gf_log (frame->this->name, GF_LOG_ERROR,
- "Failed to decode xdr response, rsp.op_ret = %d",
- rsp.op_ret);
- goto out;
- }
-
- if (rsp.op_ret == -1) {
- errno = rsp.op_errno;
- ret = -1;
- goto out;
- }
-
- if (!rsp.dict.dict_len) {
- gf_log (frame->this->name, GF_LOG_ERROR,
- "Response dict is not populated");
- ret = -1;
- errno = EINVAL;
- goto out;
- }
-
- dict = dict_new ();
- if (!dict) {
- ret = -1;
- errno = ENOMEM;
- goto out;
- }
-
- ret = dict_unserialize (rsp.dict.dict_val, rsp.dict.dict_len, &dict);
- if (ret) {
- gf_log (frame->this->name, GF_LOG_ERROR,
- "Failed to unserialize dictionary");
- errno = EINVAL;
- goto out;
- }
-
- ret = dict_get_int32 (dict, "snap-count", (int32_t*)&snapcount);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Error retrieving snapcount");
- errno = EINVAL;
- ret = -1;
- goto out;
- }
-
- if (snapcount > 0) {
- /* first time we are fetching snap list */
- dirents = GF_CALLOC (snapcount, sizeof (snap_dirent_t),
- gf_svs_mt_dirents_t);
- if (!dirents) {
- gf_log (frame->this->name, GF_LOG_ERROR,
- "Unable to allocate memory");
- errno = ENOMEM;
- ret = -1;
- goto out;
- }
- }
-
- for (i = 0; i < snapcount; i++) {
- snprintf (key, sizeof (key), "snap-volname.%d", i+1);
- ret = dict_get_str (dict, key, &value);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Error retrieving snap volname %d",
- i+1);
- errno = EINVAL;
- ret = -1;
- goto out;
- }
-
- strncpy (dirents[i].snap_volname, value,
- sizeof (dirents[i].snap_volname));
-
- snprintf (key, sizeof (key), "snap-id.%d", i+1);
- ret = dict_get_str (dict, key, &value);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Error retrieving snap uuid %d", i+1);
- errno = EINVAL;
- ret = -1;
- goto out;
- }
- strncpy (dirents[i].uuid, value,
- sizeof (dirents[i].uuid));
-
- snprintf (key, sizeof (key), "snapname.%d", i+1);
- ret = dict_get_str (dict, key, &value);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Error retrieving snap name %d", i+1);
- errno = EINVAL;
- ret = -1;
- goto out;
- }
- strncpy (dirents[i].name, value,
- sizeof (dirents[i].name));
- }
-
- /*
- * Got the new snap list populated in dirents
- * The new snap list is either a subset or a superset of
- * the existing snaplist old_dirents which has priv->num_snaps
- * number of entries.
- *
- * If subset, then clean up the fs for entries which are
- * no longer relevant.
- *
- * For other overlapping entries set the fs for new dirents
- * entries which have a fs assigned already in old_dirents
- *
- * We do this as we don't want to do new glfs_init()s repeatedly
- * as the dirents entries for snapshot volumes get repatedly
- * cleaned up and allocated. And if we don't then that will lead
- * to memleaks
- */
-
- LOCK (&priv->snaplist_lock);
- {
- oldcount = priv->num_snaps;
- for (i = 0; i < priv->num_snaps; i++) {
- for (j = 0; j < snapcount; j++) {
- if ((!strcmp (old_dirents[i].name,
- dirents[j].name)) &&
- (!strcmp (old_dirents[i].uuid,
- dirents[j].uuid))) {
- dirents[j].fs = old_dirents[i].fs;
- old_dirents[i].fs = NULL;
- break;
- }
- }
- }
-
- priv->dirents = dirents;
- priv->num_snaps = snapcount;
- }
- UNLOCK (&priv->snaplist_lock);
-
- if (old_dirents) {
- for (i = 0; i < oldcount; i++) {
- if (old_dirents[i].fs)
- glfs_fini (old_dirents[i].fs);
- }
- }
-
- GF_FREE (old_dirents);
-
- ret = 0;
-
-out:
- if (dict) {
- dict_unref (dict);
- }
- free (rsp.dict.dict_val);
- free (rsp.op_errstr);
-
- if (ret && dirents) {
- gf_log (this->name, GF_LOG_WARNING,
- "Could not update dirents with refreshed snap list");
- GF_FREE (dirents);
- }
-
- if (myframe)
- SVS_STACK_DESTROY (myframe);
-
-error_out:
- return ret;
-}
-
-int
-svs_get_snapshot_list (xlator_t *this)
-{
- gf_getsnap_name_uuid_req req = {{0,}};
- int ret = -1;
- dict_t *dict = NULL;
- glusterfs_ctx_t *ctx = NULL;
- call_frame_t *frame = NULL;
- svs_private_t *priv = NULL;
- gf_boolean_t frame_cleanup = _gf_true;
-
- GF_VALIDATE_OR_GOTO ("snapview-server", this, out);
-
- ctx = this->ctx;
- if (!ctx) {
- gf_log (this->name, GF_LOG_ERROR,
- "ctx is NULL");
- goto out;
- }
-
- frame = create_frame (this, ctx->pool);
- if (!frame) {
- gf_log (this->name, GF_LOG_ERROR,
- "Error allocating frame");
- goto out;
- }
-
- priv = this->private;
-
- dict = dict_new ();
- if (!dict) {
- gf_log (this->name, GF_LOG_ERROR,
- "Error allocating dictionary");
- goto out;
- }
-
- ret = dict_set_str (dict, "volname", priv->volname);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Error setting volname in dict");
- goto out;
- }
-
- ret = dict_allocate_and_serialize (dict, &req.dict.dict_val,
- &req.dict.dict_len);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to serialize dictionary");
- ret = -1;
- goto out;
- }
-
- ret = svs_mgmt_submit_request (&req, frame, ctx,
- &svs_clnt_handshake_prog,
- GF_HNDSK_GET_SNAPSHOT_INFO,
- mgmt_get_snapinfo_cbk,
- (xdrproc_t)xdr_gf_getsnap_name_uuid_req);
-
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Error sending snapshot names RPC request");
- }
-
- frame_cleanup = _gf_false;
-
-out:
- if (dict) {
- dict_unref (dict);
- }
- GF_FREE (req.dict.dict_val);
-
- if (frame_cleanup) {
- /*
- * Destroy the frame if we encountered an error
- * Else we need to clean it up in
- * mgmt_get_snapinfo_cbk
- */
- SVS_STACK_DESTROY (frame);
- }
-
- return ret;
-}
diff --git a/xlators/features/snapview-server/src/snapview-server.c b/xlators/features/snapview-server/src/snapview-server.c
deleted file mode 100644
index 4df7864b1bf..00000000000
--- a/xlators/features/snapview-server/src/snapview-server.c
+++ /dev/null
@@ -1,2246 +0,0 @@
-/*
- Copyright (c) 2014 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 "snapview-server.h"
-#include "snapview-server-mem-types.h"
-#include "compat-errno.h"
-
-#include "xlator.h"
-#include "rpc-clnt.h"
-#include "xdr-generic.h"
-#include "protocol-common.h"
-#include "syscall.h"
-#include <pthread.h>
-
-
-int32_t
-svs_lookup_entry_point (xlator_t *this, loc_t *loc, inode_t *parent,
- struct iatt *buf, struct iatt *postparent,
- int32_t *op_errno)
-{
- uuid_t gfid;
- svs_inode_t *inode_ctx = NULL;
- int op_ret = -1;
-
- GF_VALIDATE_OR_GOTO ("snapview-server", this, out);
- GF_VALIDATE_OR_GOTO (this->name, loc, out);
- GF_VALIDATE_OR_GOTO (this->name, loc->inode, out);
- GF_VALIDATE_OR_GOTO (this->name, buf, out);
- GF_VALIDATE_OR_GOTO (this->name, postparent, out);
-
- if (uuid_is_null (loc->inode->gfid)) {
- uuid_generate (gfid);
- svs_iatt_fill (gfid, buf);
-
- /* Here the inode context of the entry point directory
- is filled with just the type of the inode and the gfid
- of the parent from where the entry point was entered.
- The glfs object and the fs instance will be NULL.
- */
- if (parent)
- svs_iatt_fill (parent->gfid, postparent);
- else {
- svs_iatt_fill (buf->ia_gfid, postparent);
- }
-
- inode_ctx = svs_inode_ctx_get_or_new (this, loc->inode);
- if (!inode_ctx) {
- gf_log (this->name, GF_LOG_ERROR, "failed to "
- "allocate inode context for entry point "
- "directory");
- op_ret = -1;
- *op_errno = ENOMEM;
- goto out;
- }
- uuid_copy (inode_ctx->pargfid, loc->pargfid);
- memcpy (&inode_ctx->buf, buf, sizeof (*buf));
- inode_ctx->type = SNAP_VIEW_ENTRY_POINT_INODE;
- } else {
- if (inode_ctx) {
- memcpy (buf, &inode_ctx->buf, sizeof (*buf));
- svs_iatt_fill (inode_ctx->pargfid, postparent);
- } else {
- svs_iatt_fill (loc->inode->gfid, buf);
- if (parent)
- svs_iatt_fill (parent->gfid,
- postparent);
- else {
- svs_iatt_fill (loc->inode->gfid,
- postparent);
- }
- }
- }
-
- op_ret = 0;
-
-out:
- return op_ret;
-}
-
-/* When lookup comes from client and the protocol/server tries to resolve
- the pargfid via just sending the gfid as part of lookup, if the inode
- for the parent gfid is not found. But since that gfid has not yet been
- looked up yet, inode will not be having inode context and parent is not
- there (as it is the parent of the entry that is being resolved). So
- without parent and inode context, svs cannot know which snapshot
- to look into. In such cases, the amguity is handled by looking
- into the latest snapshot. If the directory is there in the latest
- snapshot, lookup is successful, otherwise it is a failure. So for
- any directory created after taking the latest snapshot, entry into
- snapshot world is denied. i.e you have to be part of snapshot world
- to enter it. If the gfid is not found there, then unwind with
- ESTALE
- This gets executed mainly in the situation where the snapshot entry
- point is entered from a non-root directory and that non-root directory's
- inode (or gfid) is not yet looked up. And in each case when a gfid has to
- be looked up (without any inode contex and parent context present), last
- snapshot is referred and a random gfid is not generated.
-*/
-int32_t
-svs_lookup_gfid (xlator_t *this, loc_t *loc, struct iatt *buf,
- struct iatt *postparent, int32_t *op_errno)
-{
- int32_t op_ret = -1;
- unsigned char handle_obj[GFAPI_HANDLE_LENGTH] = {0, };
- glfs_t *fs = NULL;
- glfs_object_t *object = NULL;
- struct stat statbuf = {0, };
- svs_inode_t *inode_ctx = NULL;
-
- GF_VALIDATE_OR_GOTO ("snapview-server", this, out);
- GF_VALIDATE_OR_GOTO (this->name, loc, out);
- GF_VALIDATE_OR_GOTO (this->name, loc->inode, out);
- GF_VALIDATE_OR_GOTO (this->name, buf, out);
- GF_VALIDATE_OR_GOTO (this->name, postparent, out);
-
- if (uuid_is_null (loc->gfid) && uuid_is_null (loc->inode->gfid)) {
- gf_log (this->name, GF_LOG_ERROR, "gfid is NULL");
- goto out;
- }
-
- if (!uuid_is_null (loc->inode->gfid))
- memcpy (handle_obj, loc->inode->gfid,
- GFAPI_HANDLE_LENGTH);
- else
- memcpy (handle_obj, loc->gfid,
- GFAPI_HANDLE_LENGTH);
-
- fs = svs_get_latest_snapshot (this);
- if (!fs) {
- gf_log (this->name, GF_LOG_ERROR, "failed to get the latest "
- "snapshot");
- op_ret = -1;
- *op_errno = EINVAL;
- goto out;
- }
-
-
- object = glfs_h_create_from_handle (fs, handle_obj, GFAPI_HANDLE_LENGTH,
- &statbuf);
- if (!object) {
- gf_log (this->name, GF_LOG_ERROR, "failed to do lookup and get "
- "the handle on the snapshot %s (path: %s, gfid: %s)",
- loc->name, loc->path, uuid_utoa (loc->gfid));
- op_ret = -1;
- *op_errno = ESTALE;
- goto out;
- }
-
- inode_ctx = svs_inode_ctx_get_or_new (this, loc->inode);
- if (!inode_ctx) {
- gf_log (this->name, GF_LOG_ERROR, "failed to allocate inode "
- "context");
- op_ret = -1;
- *op_errno = ENOMEM;
- goto out;
- }
-
- iatt_from_stat (buf, &statbuf);
- if (!uuid_is_null (loc->gfid))
- uuid_copy (buf->ia_gfid, loc->gfid);
- else
- uuid_copy (buf->ia_gfid, loc->inode->gfid);
-
- inode_ctx->type = SNAP_VIEW_VIRTUAL_INODE;
- inode_ctx->fs = fs;
- inode_ctx->object = object;
- memcpy (&inode_ctx->buf, buf, sizeof (*buf));
- svs_iatt_fill (buf->ia_gfid, postparent);
-
- op_ret = 0;
-
-out:
- return op_ret;
-}
-
-/* If the parent is an entry point inode, then create the handle for the
- snapshot on which lookup came. i.e in reality lookup came on
- the directory from which the entry point directory was entered, but
- lookup is into the past. So create the handle for it by doing
- the name-less lookup on the gfid (which can be obtained from
- parent's context
-*/
-int32_t
-svs_lookup_snapshot (xlator_t *this, loc_t *loc, struct iatt *buf,
- struct iatt *postparent, inode_t *parent,
- svs_inode_t *parent_ctx, int32_t *op_errno)
-{
- int32_t op_ret = -1;
- unsigned char handle_obj[GFAPI_HANDLE_LENGTH] = {0, };
- glfs_t *fs = NULL;
- glfs_object_t *object = NULL;
- struct stat statbuf = {0, };
- svs_inode_t *inode_ctx = NULL;
- uuid_t gfid;
-
- GF_VALIDATE_OR_GOTO ("snapview-server", this, out);
- GF_VALIDATE_OR_GOTO (this->name, loc, out);
- GF_VALIDATE_OR_GOTO (this->name, loc->inode, out);
- GF_VALIDATE_OR_GOTO (this->name, buf, out);
- GF_VALIDATE_OR_GOTO (this->name, postparent, out);
- GF_VALIDATE_OR_GOTO (this->name, parent_ctx, out);
- GF_VALIDATE_OR_GOTO (this->name, parent, out);
-
- fs = svs_initialise_snapshot_volume (this, loc->name, op_errno);
- if (!fs) {
- gf_log (this->name, GF_LOG_DEBUG, "failed to "
- "create the fs instance for snap %s",
- loc->name);
- *op_errno = ENOENT;
- op_ret = -1;
- goto out;
- }
-
- memcpy (handle_obj, parent_ctx->pargfid,
- GFAPI_HANDLE_LENGTH);
- object = glfs_h_create_from_handle (fs, handle_obj, GFAPI_HANDLE_LENGTH,
- &statbuf);
- if (!object) {
- gf_log (this->name, GF_LOG_DEBUG, "failed to do lookup and "
- "get the handle on the snapshot %s", loc->name);
- op_ret = -1;
- *op_errno = errno;
- goto out;
- }
-
- inode_ctx = svs_inode_ctx_get_or_new (this, loc->inode);
- if (!inode_ctx) {
- gf_log (this->name, GF_LOG_ERROR, "failed to "
- "allocate inode context");
- op_ret = -1;
- *op_errno = ENOMEM;
- goto out;
- }
-
- if (uuid_is_null (loc->gfid) &&
- uuid_is_null (loc->inode->gfid))
- uuid_generate (gfid);
- else {
- if (!uuid_is_null (loc->inode->gfid))
- uuid_copy (gfid, loc->inode->gfid);
- else
- uuid_copy (gfid, loc->gfid);
- }
- iatt_from_stat (buf, &statbuf);
- uuid_copy (buf->ia_gfid, gfid);
- svs_fill_ino_from_gfid (buf);
- inode_ctx->type = SNAP_VIEW_SNAPSHOT_INODE;
- inode_ctx->fs = fs;
- inode_ctx->object = object;
- memcpy (&inode_ctx->buf, buf, sizeof (*buf));
- svs_iatt_fill (parent->gfid, postparent);
-
- op_ret = 0;
-
-out:
- return op_ret;
-}
-
-/* Both parent and entry are from snapshot world */
-int32_t
-svs_lookup_entry (xlator_t *this, loc_t *loc, struct iatt *buf,
- struct iatt *postparent, inode_t *parent,
- svs_inode_t *parent_ctx, int32_t *op_errno)
-{
- int32_t op_ret = -1;
- glfs_t *fs = NULL;
- glfs_object_t *object = NULL;
- struct stat statbuf = {0, };
- svs_inode_t *inode_ctx = NULL;
- glfs_object_t *parent_object = NULL;
- uuid_t gfid;
-
- GF_VALIDATE_OR_GOTO ("snapview-server", this, out);
- GF_VALIDATE_OR_GOTO (this->name, loc, out);
- GF_VALIDATE_OR_GOTO (this->name, loc->inode, out);
- GF_VALIDATE_OR_GOTO (this->name, buf, out);
- GF_VALIDATE_OR_GOTO (this->name, postparent, out);
- GF_VALIDATE_OR_GOTO (this->name, parent_ctx, out);
- GF_VALIDATE_OR_GOTO (this->name, parent, out);
-
- parent_object = parent_ctx->object;
- fs = parent_ctx->fs;
-
- object = glfs_h_lookupat (fs, parent_object, loc->name,
- &statbuf);
- if (!object) {
- gf_log (this->name, GF_LOG_DEBUG, "failed to do lookup and "
- "get the handle for entry %s (path: %s)", loc->name,
- loc->path);
- op_ret = -1;
- *op_errno = errno;
- goto out;
- }
-
- inode_ctx = svs_inode_ctx_get_or_new (this, loc->inode);
- if (!inode_ctx) {
- gf_log (this->name, GF_LOG_ERROR, "failed to "
- "allocate inode context");
- op_ret = -1;
- *op_errno = ENOMEM;
- goto out;
- }
-
- if (uuid_is_null (loc->gfid) &&
- uuid_is_null (loc->inode->gfid))
- uuid_generate (gfid);
- else {
- if (!uuid_is_null (loc->inode->gfid))
- uuid_copy (gfid, loc->inode->gfid);
- else
- uuid_copy (gfid, loc->gfid);
- }
-
- iatt_from_stat (buf, &statbuf);
- uuid_copy (buf->ia_gfid, gfid);
- svs_fill_ino_from_gfid (buf);
- inode_ctx->type = SNAP_VIEW_VIRTUAL_INODE;
- inode_ctx->fs = fs;
- inode_ctx->object = object;
- memcpy (&inode_ctx->buf, buf, sizeof (*buf));
- svs_iatt_fill (parent->gfid, postparent);
-
- op_ret = 0;
-
-out:
- return op_ret;
-}
-
-/* inode context is there means lookup has come on an object which was
- built either as part of lookup or as part of readdirp. But in readdirp
- we would not have got the handle to access the object in the gfapi
- world.
- So if inode context contains glfs_t instance for the right
- gfapi world and glfs_object_t handle for accessing it in the gfapi
- world, then unwind with success as the snapshots as of now are
- read-only.
- If the above condition is not met, then send lookup call again to
- the gfapi world. It can happen only if both parent context and
- the name of the entry are present.
-
- If parent is an entry point to snapshot world:
- * parent is needed for getting the gfid on which lookup has to be done
- (the gfid present in the inode is a virtual gfid) in the snapshot
- world.
- * name is required to get the right glfs_t instance on which lookup
- has to be done
-
- If parent is a directory from snapshot world:
- * parent context is needed to get the glfs_t instance and to get the
- handle to parent directory in the snapshot world.
- * name is needed to do the lookup on the right entry in the snapshot
- world
-*/
-int32_t
-svs_revalidate (xlator_t *this, loc_t *loc, inode_t *parent,
- svs_inode_t *inode_ctx, svs_inode_t *parent_ctx,
- struct iatt *buf, struct iatt *postparent, int32_t *op_errno)
-{
- int32_t op_ret = -1;
- int ret = -1;
- char tmp_uuid[64] = {0, };
- glfs_t *fs = NULL;
- glfs_object_t *object = NULL;
-
- GF_VALIDATE_OR_GOTO ("snapview-server", this, out);
- GF_VALIDATE_OR_GOTO (this->name, buf, out);
- GF_VALIDATE_OR_GOTO (this->name, postparent, out);
- GF_VALIDATE_OR_GOTO (this->name, inode_ctx, out);
-
- if (inode_ctx->type == SNAP_VIEW_ENTRY_POINT_INODE) {
- svs_iatt_fill (loc->inode->gfid, buf);
- if (parent)
- svs_iatt_fill (parent->gfid,
- postparent);
- else
- svs_iatt_fill (loc->inode->gfid, postparent);
- op_ret = 0;
- goto out;
- } else {
- /* Though fs and object are present in the inode context, its
- * better to check if fs is valid or not before doing anything.
- * Its for the protection from the following operations.
- * 1) Create a file on the glusterfs mount point
- * 2) Create a snapshot (say "snap1")
- * 3) Access the contents of the snapshot
- * 4) Delete the file from the mount point
- * 5) Delete the snapshot "snap1"
- * 6) Create a new snapshot "snap1"
- *
- * Now accessing the new snapshot "snap1" gives problems.
- * Because the inode and dentry created for snap1 would not be
- * deleted upon the deletion of the snapshot (as deletion of
- * snapshot is a gluster cli operation, not a fop). So next time
- * upon creation of a new snap with same name, the previous
- * inode and dentry itself will be used. But the inode context
- * contains old information about the glfs_t instance and the
- * handle in the gfapi world. Thus the glfs_t instance should
- * be checked before accessing. If its wrong, then right
- * instance should be obtained by doing the lookup.
- */
- if (inode_ctx->fs && inode_ctx->object) {
- fs = inode_ctx->fs;
- object = inode_ctx->object;
- SVS_CHECK_VALID_SNAPSHOT_HANDLE(fs, this);
- if (fs) {
- memcpy (buf, &inode_ctx->buf, sizeof (*buf));
- if (parent)
- svs_iatt_fill (parent->gfid,
- postparent);
- else
- svs_iatt_fill (buf->ia_gfid,
- postparent);
- op_ret = 0;
- goto out;
- } else {
- inode_ctx->fs = NULL;
- inode_ctx->object = NULL;
- ret = svs_get_handle (this, loc, inode_ctx,
- op_errno);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "failed to get the handle for "
- "%s (gfid %s)", loc->path,
- uuid_utoa_r (loc->inode->gfid,
- tmp_uuid));
- op_ret = -1;
- goto out;
- }
- }
- }
-
- /* To send the lookup to gfapi world, both the name of the
- entry as well as the parent context is needed.
- */
- if (!loc->name || !parent_ctx) {
- *op_errno = ESTALE;
- gf_log (this->name, GF_LOG_ERROR, "%s is NULL",
- loc->name?"parent context":"loc->name");
- goto out;
- }
-
- if (parent_ctx->type == SNAP_VIEW_ENTRY_POINT_INODE)
- op_ret = svs_lookup_snapshot (this, loc, buf,
- postparent, parent,
- parent_ctx, op_errno);
- else
- op_ret = svs_lookup_entry (this, loc, buf, postparent,
- parent, parent_ctx,
- op_errno);
-
- goto out;
- }
-
-out:
- return op_ret;
-}
-
-int32_t
-svs_lookup (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
-{
- struct iatt buf = {0, };
- int32_t op_ret = -1;
- int32_t op_errno = EINVAL;
- struct iatt postparent = {0,};
- svs_inode_t *inode_ctx = NULL;
- svs_inode_t *parent_ctx = NULL;
- int32_t ret = -1;
- svs_private_t *private = NULL;
- inode_t *parent = NULL;
- glfs_t *fs = NULL;
- snap_dirent_t *dirent = NULL;
- gf_boolean_t entry_point_key = _gf_false;
- gf_boolean_t entry_point = _gf_false;
-
- GF_VALIDATE_OR_GOTO ("svs", this, out);
- GF_VALIDATE_OR_GOTO (this->name, this->private, out);
- GF_VALIDATE_OR_GOTO (this->name, frame, out);
- GF_VALIDATE_OR_GOTO (this->name, loc, out);
- GF_VALIDATE_OR_GOTO (this->name, loc->inode, out);
-
- private = this->private;
-
- /* For lookups sent on inodes (i.e not parent inode + basename, but
- direct inode itself which usually is a nameless lookup or revalidate
- on the inode), loc->name will not be there. Get it from path if
- it is there.
- This is the difference between nameless lookup and revalidate lookup
- on an inode:
- nameless lookup: loc->path contains gfid and strrchr on it fails
- revalidate lookup: loc->path contains the entry name of the inode
- and strrchr gives the name of the entry from path
- */
- if (loc->path) {
- if (!loc->name || (loc->name && !strcmp (loc->name, ""))) {
- loc->name = strrchr (loc->path, '/');
- if (loc->name)
- loc->name++;
- }
- }
-
- if (loc->parent)
- parent = inode_ref (loc->parent);
- else {
- parent = inode_find (loc->inode->table, loc->pargfid);
- if (!parent)
- parent = inode_parent (loc->inode, NULL, NULL);
- }
- if (parent)
- parent_ctx = svs_inode_ctx_get (this, parent);
-
- inode_ctx = svs_inode_ctx_get (this, loc->inode);
-
- /* Initialize latest snapshot, which is used for nameless lookups */
- dirent = svs_get_latest_snap_entry (this);
-
- if (dirent && !dirent->fs) {
- fs = svs_initialise_snapshot_volume (this, dirent->name, NULL);
- }
-
- if (xdata && !inode_ctx) {
- ret = dict_get_str_boolean (xdata, "entry-point", _gf_false);
- if (ret == -1) {
- gf_log (this->name, GF_LOG_DEBUG, "failed to get the "
- "entry point info");
- entry_point_key = _gf_false;
- } else {
- entry_point_key = ret;
- }
-
- if (loc->name && strlen (loc->name)) {
- /* lookup can come with the entry-point set in the dict
- * for the parent directory of the entry-point as well.
- * So consider entry_point only for named lookup
- */
- entry_point = entry_point_key;
- }
- }
-
- if (inode_ctx && inode_ctx->type == SNAP_VIEW_ENTRY_POINT_INODE) {
- /* entry-point may not be set in the dictonary.
- * This can happen if snap-view client is restarted where
- * inode-ctx not available and a nameless lookup has come
- */
- entry_point = _gf_true;
- }
-
- /* lookup is on the entry point to the snapshot world */
- if (entry_point) {
- op_ret = svs_lookup_entry_point (this, loc, parent, &buf,
- &postparent, &op_errno);
- goto out;
- }
-
- /* revalidate */
- if (inode_ctx) {
- op_ret = svs_revalidate (this, loc, parent, inode_ctx,
- parent_ctx, &buf, &postparent,
- &op_errno);
- goto out;
- }
-
- /* This can happen when entry point directory is entered from non-root
- directory. (ex: if /mnt/glusterfs is the mount point, then entry
- point (say .snaps) is entered from /mnt/glusterfs/dir/.snaps). Also
- it can happen when client sends a nameless lookup on just a gfid and
- the server does not have the inode in the inode table.
- */
- if (!inode_ctx && !parent_ctx) {
- if (uuid_is_null (loc->gfid) &&
- uuid_is_null (loc->inode->gfid)) {
- gf_log (this->name, GF_LOG_ERROR, "gfid is NULL");
- op_ret = -1;
- op_errno = ESTALE;
- goto out;
- }
-
- if (!entry_point_key) {
- /* This can happen when there is no inode_ctx available.
- * snapview-server might have restarted or
- * graph change might have happened
- */
- op_ret = -1;
- op_errno = ESTALE;
- goto out;
- }
-
- /* lookup is on the parent directory of entry-point.
- * this would have already looked up by snap-view client
- * so return success
- */
- if (!uuid_is_null (loc->gfid))
- uuid_copy (buf.ia_gfid, loc->gfid);
- else
- uuid_copy (buf.ia_gfid, loc->inode->gfid);
-
- svs_iatt_fill (buf.ia_gfid, &buf);
- svs_iatt_fill (buf.ia_gfid, &postparent);
-
- op_ret = 0;
- goto out;
- }
-
- if (parent_ctx) {
- if (parent_ctx->type == SNAP_VIEW_ENTRY_POINT_INODE)
- op_ret = svs_lookup_snapshot (this, loc, &buf,
- &postparent, parent,
- parent_ctx, &op_errno);
- else
- op_ret = svs_lookup_entry (this, loc, &buf,
- &postparent, parent,
- parent_ctx, &op_errno);
- goto out;
- }
-
-out:
- STACK_UNWIND_STRICT (lookup, frame, op_ret, op_errno,
- loc?loc->inode:NULL, &buf, xdata, &postparent);
-
- if (parent)
- inode_unref (parent);
-
- return 0;
-}
-
-int32_t
-svs_opendir (call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd,
- dict_t *xdata)
-{
- svs_inode_t *inode_ctx = NULL;
- int32_t op_ret = -1;
- int32_t op_errno = EINVAL;
- svs_fd_t *svs_fd = NULL;
- glfs_fd_t *glfd = NULL;
- glfs_t *fs = NULL;
- glfs_object_t *object = NULL;
-
- GF_VALIDATE_OR_GOTO ("snap-view-daemon", this, out);
- GF_VALIDATE_OR_GOTO (this->name, frame, out);
- GF_VALIDATE_OR_GOTO (this->name, fd, out);
- GF_VALIDATE_OR_GOTO (this->name, loc, out);
- GF_VALIDATE_OR_GOTO (this->name, loc->inode, out);
-
- inode_ctx = svs_inode_ctx_get (this, loc->inode);
- if (!inode_ctx) {
- gf_log (this->name, GF_LOG_ERROR, "inode context not found "
- "for the inode %s", uuid_utoa (loc->inode->gfid));
- op_ret = -1;
- op_errno = ESTALE;
- goto out;
- }
-
- /* Fake success is sent if the opendir is on the entry point directory
- or the inode is SNAP_VIEW_ENTRY_POINT_INODE
- */
- if (inode_ctx->type == SNAP_VIEW_ENTRY_POINT_INODE) {
- op_ret = 0;
- op_errno = 0;
- goto out;
- }
- else {
-
- SVS_GET_INODE_CTX_INFO(inode_ctx, fs, object, this, loc, op_ret,
- op_errno, out);
-
- glfd = glfs_h_opendir (fs, object);
- if (!glfd) {
- op_ret = -1;
- op_errno = errno;
- gf_log (this->name, GF_LOG_ERROR, "opendir on %s "
- "failed (gfid: %s)", loc->name,
- uuid_utoa (loc->inode->gfid));
- goto out;
- }
- svs_fd = svs_fd_ctx_get_or_new (this, fd);
- if (!svs_fd) {
- gf_log (this->name, GF_LOG_ERROR, "failed to allocate "
- "fd context %s (gfid: %s)", loc->name,
- uuid_utoa (fd->inode->gfid));
- op_ret = -1;
- op_errno = ENOMEM;
- glfs_closedir (glfd);
- goto out;
- }
- svs_fd->fd = glfd;
-
- op_ret = 0;
- op_errno = 0;
- }
-
-out:
- STACK_UNWIND_STRICT (opendir, frame, op_ret, op_errno, fd, NULL);
-
- return 0;
-}
-
-/*
- * This function adds the xattr keys present in the list (@list) to the dict.
- * But the list contains only the names of the xattrs (and no value, as
- * the gfapi functions for the listxattr operations would return only the
- * names of the xattrs in the buffer provided by the caller, though they had
- * got the values of those xattrs from posix) as described in the man page of
- * listxattr. But before unwinding snapview-server has to put those names
- * back into the dict. But to get the values for those xattrs it has to do the
- * getxattr operation on each xattr which might turn out to be a costly
- * operation. So for each of the xattrs present in the list, a 0 byte value
- * ("") is set into the dict before unwinding. This can be treated as an
- * indicator to other xlators which want to cache the xattrs (as of now,
- * md-cache which caches acl and selinux related xattrs) to not to cache the
- * values of the xattrs present in the dict.
- */
-int32_t
-svs_add_xattrs_to_dict (xlator_t *this, dict_t *dict, char *list, ssize_t size)
-{
- char keybuffer[4096] = {0,};
- size_t remaining_size = 0;
- int32_t list_offset = 0;
- int32_t ret = -1;
-
- GF_VALIDATE_OR_GOTO ("snapview-daemon", this, out);
- GF_VALIDATE_OR_GOTO (this->name, dict, out);
- GF_VALIDATE_OR_GOTO (this->name, list, out);
-
- remaining_size = size;
- list_offset = 0;
- while (remaining_size > 0) {
- strcpy (keybuffer, list + list_offset);
-#ifdef GF_DARWIN_HOST_OS
- /* The protocol expect namespace for now */
- char *newkey = NULL;
- gf_add_prefix (XATTR_USER_PREFIX, keybuffer, &newkey);
- strcpy (keybuffer, newkey);
- GF_FREE (newkey);
-#endif
- ret = dict_set_str (dict, keybuffer, "");
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR, "dict set operation "
- "for the key %s failed.", keybuffer);
- goto out;
- }
-
- remaining_size -= strlen (keybuffer) + 1;
- list_offset += strlen (keybuffer) + 1;
- } /* while (remaining_size > 0) */
-
- ret = 0;
-
-out:
- return ret;
-}
-
-int32_t
-svs_getxattr (call_frame_t *frame, xlator_t *this, loc_t *loc, const char *name,
- dict_t *xdata)
-{
- svs_inode_t *inode_ctx = NULL;
- int32_t op_ret = -1;
- int32_t op_errno = EINVAL;
- glfs_t *fs = NULL;
- glfs_object_t *object = NULL;
- char *value = 0;
- ssize_t size = 0;
- dict_t *dict = NULL;
-
- GF_VALIDATE_OR_GOTO ("snap-view-daemon", this, out);
- GF_VALIDATE_OR_GOTO ("snap-view-daemon", frame, out);
- GF_VALIDATE_OR_GOTO ("snap-view-daemon", loc, out);
- GF_VALIDATE_OR_GOTO ("snap-view-daemon", loc->inode, out);
-
- inode_ctx = svs_inode_ctx_get (this, loc->inode);
- if (!inode_ctx) {
- gf_log (this->name, GF_LOG_ERROR, "inode context not found "
- "for the inode %s", uuid_utoa (loc->inode->gfid));
- op_ret = -1;
- op_errno = ESTALE;
- goto out;
- }
-
- /* ENODATA is sent if the getxattr is on entry point directory
- or the inode is SNAP_VIEW_ENTRY_POINT_INODE. Entry point is
- a virtual directory on which setxattr operations are not
- allowed. If getxattr has to be faked as success, then a value
- for the name of the xattr has to be sent which we dont have.
- */
- if (inode_ctx->type == SNAP_VIEW_ENTRY_POINT_INODE) {
- op_ret = -1;
- op_errno = ENODATA;
- goto out;
- }
- else {
-
- SVS_GET_INODE_CTX_INFO(inode_ctx, fs, object, this, loc, op_ret,
- op_errno, out);
-
- dict = dict_new ();
- if (!dict) {
- gf_log (this->name, GF_LOG_ERROR, "failed to "
- "allocate dict");
- op_ret = -1;
- op_errno = ENOMEM;
- goto out;
- }
-
- size = glfs_h_getxattrs (fs, object, name, NULL, 0);
- if (size == -1) {
- gf_log (this->name, GF_LOG_ERROR, "getxattr "
- "on %s failed (key: %s)", loc->name,
- name);
- op_ret = -1;
- op_errno = errno;
- goto out;
- }
- value = GF_CALLOC (size + 1, sizeof (char),
- gf_common_mt_char);
- if (!value) {
- gf_log (this->name, GF_LOG_ERROR, "failed to "
- "allocate memory for getxattr on %s "
- "(key: %s)", loc->name, name);
- op_ret = -1;
- op_errno = ENOMEM;
- goto out;
- }
-
- size = glfs_h_getxattrs (fs, object, name, value, size);
- if (size == -1) {
- gf_log (this->name, GF_LOG_ERROR, "failed to "
- "get the xattr %s for entry %s", name,
- loc->name);
- op_ret = -1;
- op_errno = errno;
- goto out;
- }
- value[size] = '\0';
-
- if (name) {
- op_ret = dict_set_dynptr (dict, (char *)name, value,
- size);
- if (op_ret < 0) {
- op_errno = -op_ret;
- gf_log (this->name, GF_LOG_ERROR, "dict set "
- "operation for %s for the key %s "
- "failed.", loc->path, name);
- GF_FREE (value);
- value = NULL;
- goto out;
- }
- } else {
- op_ret = svs_add_xattrs_to_dict (this, dict, value,
- size);
- if (op_ret == -1) {
- gf_log (this->name, GF_LOG_ERROR, "failed to "
- "add the xattrs from the list to dict");
- op_errno = ENOMEM;
- goto out;
- }
- GF_FREE (value);
- }
- }
-
-out:
- if (op_ret)
- GF_FREE (value);
-
- STACK_UNWIND_STRICT (getxattr, frame, op_ret, op_errno, dict, NULL);
-
- if (dict)
- dict_unref (dict);
-
- return 0;
-}
-
-int32_t
-svs_fgetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd, const char *name,
- dict_t *xdata)
-{
- svs_inode_t *inode_ctx = NULL;
- int32_t op_ret = -1;
- int32_t op_errno = EINVAL;
- char *value = 0;
- ssize_t size = 0;
- dict_t *dict = NULL;
- svs_fd_t *sfd = NULL;
- glfs_fd_t *glfd = NULL;
-
- GF_VALIDATE_OR_GOTO ("snap-view-daemon", this, out);
- GF_VALIDATE_OR_GOTO ("snap-view-daemon", frame, out);
- GF_VALIDATE_OR_GOTO ("snap-view-daemon", fd, out);
- GF_VALIDATE_OR_GOTO ("snap-view-daemon", fd->inode, out);
-
- inode_ctx = svs_inode_ctx_get (this, fd->inode);
- if (!inode_ctx) {
- gf_log (this->name, GF_LOG_ERROR, "inode context not found "
- "for the inode %s", uuid_utoa (fd->inode->gfid));
- op_ret = -1;
- op_errno = ESTALE;
- goto out;
- }
-
- sfd = svs_fd_ctx_get_or_new (this, fd);
- if (!sfd) {
- gf_log (this->name, GF_LOG_ERROR, "failed to get the fd "
- "context for %s", uuid_utoa (fd->inode->gfid));
- op_ret = -1;
- op_errno = EBADFD;
- goto out;
- }
-
- glfd = sfd->fd;
- /* EINVAL is sent if the getxattr is on entry point directory
- or the inode is SNAP_VIEW_ENTRY_POINT_INODE. Entry point is
- a virtual directory on which setxattr operations are not
- allowed. If getxattr has to be faked as success, then a value
- for the name of the xattr has to be sent which we dont have.
- */
- if (inode_ctx->type == SNAP_VIEW_ENTRY_POINT_INODE) {
- op_ret = -1;
- op_errno = EINVAL;
- goto out;
- }
- else {
- dict = dict_new ();
- if (!dict) {
- gf_log (this->name, GF_LOG_ERROR, "failed to "
- "allocate dict");
- op_ret = -1;
- op_errno = ENOMEM;
- goto out;
- }
-
- if (name) {
- size = glfs_fgetxattr (glfd, name, NULL, 0);
- if (size == -1) {
- gf_log (this->name, GF_LOG_ERROR, "getxattr on "
- "%s failed (key: %s)",
- uuid_utoa (fd->inode->gfid), name);
- op_ret = -1;
- op_errno = errno;
- goto out;
- }
- value = GF_CALLOC (size + 1, sizeof (char),
- gf_common_mt_char);
- if (!value) {
- gf_log (this->name, GF_LOG_ERROR, "failed to "
- "allocate memory for getxattr on %s "
- "(key: %s)",
- uuid_utoa (fd->inode->gfid), name);
- op_ret = -1;
- op_errno = ENOMEM;
- goto out;
- }
-
- size = glfs_fgetxattr (glfd, name, value, size);
- if (size == -1) {
- gf_log (this->name, GF_LOG_ERROR, "failed to "
- "get the xattr %s for inode %s", name,
- uuid_utoa (fd->inode->gfid));
- op_ret = -1;
- op_errno = errno;
- goto out;
- }
- value[size] = '\0';
-
- op_ret = dict_set_dynptr (dict, (char *)name, value,
- size);
- if (op_ret < 0) {
- op_errno = -op_ret;
- gf_log (this->name, GF_LOG_ERROR, "dict set "
- "operation for gfid %s for the key %s "
- "failed.",
- uuid_utoa (fd->inode->gfid), name);
- GF_FREE (value);
- goto out;
- }
- } else {
- size = glfs_flistxattr (glfd, NULL, 0);
- if (size == -1) {
- gf_log (this->name, GF_LOG_ERROR, "listxattr "
- "on %s failed",
- uuid_utoa (fd->inode->gfid));
- goto out;
- }
-
- value = GF_CALLOC (size + 1, sizeof (char),
- gf_common_mt_char);
- if (!value) {
- op_ret = -1;
- op_errno = ENOMEM;
- gf_log (this->name, GF_LOG_ERROR, "failed to "
- "allocate buffer for xattr list (%s)",
- uuid_utoa (fd->inode->gfid));
- goto out;
- }
-
- size = glfs_flistxattr (glfd, value, size);
- if (size == -1) {
- op_ret = -1;
- op_errno = errno;
- gf_log (this->name, GF_LOG_ERROR, "listxattr "
- "on %s failed",
- uuid_utoa (fd->inode->gfid));
- goto out;
- }
-
- op_ret = svs_add_xattrs_to_dict (this, dict, value,
- size);
- if (op_ret == -1) {
- gf_log (this->name, GF_LOG_ERROR, "failed to "
- "add the xattrs from the list to dict");
- op_errno = ENOMEM;
- goto out;
- }
- GF_FREE (value);
- }
-
- op_ret = 0;
- op_errno = 0;
- }
-
-out:
- if (op_ret)
- GF_FREE (value);
-
- STACK_UNWIND_STRICT (fgetxattr, frame, op_ret, op_errno, dict, NULL);
-
- if (dict)
- dict_unref (dict);
-
- return 0;
-}
-
-int32_t
-svs_releasedir (xlator_t *this, fd_t *fd)
-{
- svs_fd_t *sfd = NULL;
- uint64_t tmp_pfd = 0;
- int ret = 0;
-
- GF_VALIDATE_OR_GOTO ("snapview-server", this, out);
- GF_VALIDATE_OR_GOTO (this->name, fd, out);
-
- ret = fd_ctx_del (fd, this, &tmp_pfd);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_DEBUG,
- "pfd from fd=%p is NULL", fd);
- goto out;
- }
-
- sfd = (svs_fd_t *)(long)tmp_pfd;
- if (sfd->fd) {
- ret = glfs_closedir (sfd->fd);
- if (ret)
- gf_log (this->name, GF_LOG_WARNING, "failed to close "
- "the glfd for directory %s",
- uuid_utoa (fd->inode->gfid));
- }
-
- GF_FREE (sfd);
-
-out:
- return 0;
-}
-
-int32_t
-svs_flush (call_frame_t *frame, xlator_t *this,
- fd_t *fd, dict_t *xdata)
-{
- int32_t op_ret = -1;
- int32_t op_errno = 0;
- int ret = -1;
- uint64_t value = 0;
- svs_inode_t *inode_ctx = NULL;
-
- GF_VALIDATE_OR_GOTO ("snapview-server", this, out);
- GF_VALIDATE_OR_GOTO (this->name, frame, out);
- GF_VALIDATE_OR_GOTO (this->name, fd, out);
-
- inode_ctx = svs_inode_ctx_get (this, fd->inode);
- if (!inode_ctx) {
- gf_log (this->name, GF_LOG_ERROR, "inode context not found for"
- " the inode %s", uuid_utoa (fd->inode->gfid));
- op_ret = -1;
- op_errno = EINVAL;
- goto out;
- }
-
- ret = fd_ctx_get (fd, this, &value);
- if (ret < 0 && inode_ctx->type != SNAP_VIEW_ENTRY_POINT_INODE) {
- op_errno = EINVAL;
- gf_log (this->name, GF_LOG_WARNING,
- "pfd is NULL on fd=%p", fd);
- goto out;
- }
-
- op_ret = 0;
-
-out:
- STACK_UNWIND_STRICT (flush, frame, op_ret, op_errno, NULL);
-
- return 0;
-}
-
-int32_t
-svs_release (xlator_t *this, fd_t *fd)
-{
- svs_fd_t *sfd = NULL;
- uint64_t tmp_pfd = 0;
- int ret = 0;
-
- GF_VALIDATE_OR_GOTO ("snapview-server", this, out);
- GF_VALIDATE_OR_GOTO (this->name, fd, out);
-
- ret = fd_ctx_del (fd, this, &tmp_pfd);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_DEBUG,
- "pfd from fd=%p is NULL", fd);
- goto out;
- }
-
- sfd = (svs_fd_t *)(long)tmp_pfd;
- if (sfd->fd) {
- ret = glfs_close (sfd->fd);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "failed to close "
- "the glfd for %s",
- uuid_utoa (fd->inode->gfid));
- }
- }
-
- GF_FREE (sfd);
-out:
- return 0;
-}
-
-int32_t
-svs_forget (xlator_t *this, inode_t *inode)
-{
- int ret = -1;
- uint64_t value = 0;
- svs_inode_t *inode_ctx = NULL;
-
- GF_VALIDATE_OR_GOTO ("snapview-server", this, out);
- GF_VALIDATE_OR_GOTO (this->name, inode, out);
-
- ret = inode_ctx_del (inode, this, &value);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "failed to delte the inode "
- "context of %s", uuid_utoa (inode->gfid));
- goto out;
- }
-
- inode_ctx = (svs_inode_t *)value;
-
- if (inode_ctx->object)
- glfs_h_close (inode_ctx->object);
-
- GF_FREE (inode_ctx);
-
-out:
- return 0;
-}
-
-int
-svs_fill_readdir (xlator_t *this, gf_dirent_t *entries, size_t size, off_t off)
-{
- gf_dirent_t *entry = NULL;
- svs_private_t *priv = NULL;
- int i = 0;
- snap_dirent_t *dirents = NULL;
- int this_size = 0;
- int filled_size = 0;
- int count = 0;
-
- GF_VALIDATE_OR_GOTO ("snap-view-daemon", this, out);
- GF_VALIDATE_OR_GOTO ("snap-view-daemon", entries, out);
-
- priv = this->private;
- GF_ASSERT (priv);
-
- /* create the dir entries */
- LOCK (&priv->snaplist_lock);
- {
- dirents = priv->dirents;
-
- for (i = off; i < priv->num_snaps; ) {
- this_size = sizeof (gf_dirent_t) +
- strlen (dirents[i].name) + 1;
- if (this_size + filled_size > size )
- goto unlock;
-
- entry = gf_dirent_for_name (dirents[i].name);
- if (!entry) {
- gf_log (this->name, GF_LOG_ERROR,
- "failed to allocate dentry for %s",
- dirents[i].name);
- goto unlock;
- }
-
- entry->d_off = i + 1;
- /*
- * readdir on the entry-point directory to the snapshot
- * world, will return elements in the list of the
- * snapshots as the directory entries. Since the entries
- * returned are virtual entries which does not exist
- * physically on the disk, pseudo inode numbers are
- * generated.
- */
- entry->d_ino = i + 2*42;
- entry->d_type = DT_DIR;
- list_add_tail (&entry->list, &entries->list);
- ++i;
- count++;
- filled_size += this_size;
- }
- }
-unlock:
- UNLOCK (&priv->snaplist_lock);
-
-out:
- return count;
-}
-
-int32_t
-svs_glfs_readdir (xlator_t *this, glfs_fd_t *glfd, gf_dirent_t *entries,
- int32_t *op_errno, struct iatt *buf, gf_boolean_t readdirplus,
- size_t size)
-{
- int filled_size = 0;
- int this_size = 0;
- int32_t ret = -1;
- int32_t count = 0;
- gf_dirent_t *entry = NULL;
- struct dirent *dirents = NULL;
- struct dirent de = {0, };
- struct stat statbuf = {0, };
- off_t in_case = -1;
-
- GF_VALIDATE_OR_GOTO ("svs", this, out);
- GF_VALIDATE_OR_GOTO (this->name, glfd, out);
- GF_VALIDATE_OR_GOTO (this->name, entries, out);
- GF_VALIDATE_OR_GOTO (this->name, buf, out);
-
- while (filled_size < size) {
- in_case = glfs_telldir (glfd);
- if (in_case == -1) {
- gf_log (this->name, GF_LOG_ERROR, "telldir failed");
- break;
- }
-
- if (readdirplus)
- ret = glfs_readdirplus_r (glfd, &statbuf, &de,
- &dirents);
- else
- ret = glfs_readdir_r (glfd, &de, &dirents);
-
- if (ret == 0 && dirents != NULL) {
- if (readdirplus)
- this_size = max (sizeof (gf_dirent_t),
- sizeof (gfs3_dirplist))
- + strlen (de.d_name) + 1;
- else
- this_size = sizeof (gf_dirent_t)
- + strlen (de.d_name) + 1;
-
- if (this_size + filled_size > size) {
- glfs_seekdir (glfd, in_case);
- break;
- }
-
- entry = gf_dirent_for_name (de.d_name);
- if (!entry) {
- gf_log (this->name, GF_LOG_ERROR,
- "could not create gf_dirent "
- "for entry %s: (%s)",
- entry->d_name,
- strerror (errno));
- break;
- }
- entry->d_off = glfs_telldir (glfd);
- entry->d_ino = de.d_ino;
- entry->d_type = de.d_type;
- iatt_from_stat (buf, &statbuf);
- if (readdirplus)
- entry->d_stat = *buf;
- list_add_tail (&entry->list, &entries->list);
-
- filled_size += this_size;
- count++;
- } else if (ret == 0 && dirents == NULL) {
- *op_errno = ENOENT;
- break;
- } else if (ret != 0) {
- *op_errno = errno;
- break;
- }
- dirents = NULL;
- ret = -1;
- }
-
-out:
- return count;
-}
-
-/* readdirp can be of 2 types.
- 1) It can come on entry point directory where the list of snapshots
- is sent as dirents. In this case, the iatt structure is filled
- on the fly if the inode is not found for the entry or the inode
- context is NULL. Other wise if inode is found and inode context
- is there the iatt structure saved in the context is used.
- 2) It can be on a directory in one of the snapshots. In this case,
- the readdirp call would have sent us a iatt structure. So the same
- structure is used with the exception that the gfid and the inode
- numbers will be newly generated and filled in.
-*/
-void
-svs_readdirp_fill (xlator_t *this, inode_t *parent, svs_inode_t *parent_ctx,
- gf_dirent_t *entry)
-{
- inode_t *inode = NULL;
- uuid_t random_gfid = {0,};
- struct iatt buf = {0, };
- svs_inode_t *inode_ctx = NULL;
-
- GF_VALIDATE_OR_GOTO ("snapview-server", this, out);
- GF_VALIDATE_OR_GOTO (this->name, parent, out);
- GF_VALIDATE_OR_GOTO (this->name, parent_ctx, out);
- GF_VALIDATE_OR_GOTO (this->name, entry, out);
-
- if (!strcmp (entry->d_name, ".") || !strcmp (entry->d_name, ".."))
- goto out;
-
- inode = inode_grep (parent->table, parent, entry->d_name);
- if (inode) {
- entry->inode = inode;
- inode_ctx = svs_inode_ctx_get (this, inode);
- if (!inode_ctx) {
- uuid_copy (buf.ia_gfid, inode->gfid);
- svs_iatt_fill (inode->gfid, &buf);
- buf.ia_type = inode->ia_type;
- } else {
- buf = inode_ctx->buf;
- }
-
- entry->d_ino = buf.ia_ino;
-
- if (parent_ctx->type == SNAP_VIEW_ENTRY_POINT_INODE)
- entry->d_stat = buf;
- else {
- entry->d_stat.ia_ino = buf.ia_ino;
- uuid_copy (entry->d_stat.ia_gfid, buf.ia_gfid);
- }
- } else {
- inode = inode_new (parent->table);
- entry->inode = inode;
- uuid_generate (random_gfid);
- uuid_copy (buf.ia_gfid, random_gfid);
- svs_fill_ino_from_gfid (&buf);
- entry->d_ino = buf.ia_ino;
-
- /* If inode context allocation fails, then do not send the
- inode for that particular entry as part of readdirp
- response. Fuse and protocol/server will link the inodes
- in readdirp only if the entry contains inode in it.
- */
- inode_ctx = svs_inode_ctx_get_or_new (this, inode);
- if (!inode_ctx) {
- gf_log (this->name, GF_LOG_ERROR, "failed to allocate "
- "inode context for %s", entry->d_name);
- inode_unref (entry->inode);
- entry->inode = NULL;
- goto out;
- }
-
-
- if (parent_ctx->type == SNAP_VIEW_ENTRY_POINT_INODE) {
- buf.ia_type = IA_IFDIR;
- inode_ctx->buf = buf;
- entry->d_stat = buf;
- inode_ctx->type = SNAP_VIEW_SNAPSHOT_INODE;
- } else {
- uuid_copy (entry->d_stat.ia_gfid, buf.ia_gfid);
- entry->d_stat.ia_ino = buf.ia_ino;
- inode_ctx->buf = entry->d_stat;
- inode_ctx->type = SNAP_VIEW_VIRTUAL_INODE;
- }
- }
-
-out:
- return;
-}
-
-/* In readdirp, though new inode is created along with the generation of
- new gfid, the inode context created will not contain the glfs_t instance
- for the filesystem it belongs to and the handle for it in the gfapi
- world. (handle is obtained only by doing the lookup call on the entry
- and doing lookup on each entry received as part of readdir call is a
- costly operation. So the fs and handle is NULL in the inode context
- and is filled in when lookup comes on that object.
-*/
-int32_t
-svs_readdirp (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
- off_t off, dict_t *dict)
-{
- gf_dirent_t entries;
- gf_dirent_t *entry = NULL;
- struct iatt buf = {0, };
- int count = 0;
- int op_ret = -1;
- int op_errno = EINVAL;
- svs_inode_t *parent_ctx = NULL;
- svs_fd_t *svs_fd = NULL;
-
- GF_VALIDATE_OR_GOTO ("snap-view-daemon", this, unwind);
- GF_VALIDATE_OR_GOTO (this->name, frame, unwind);
- GF_VALIDATE_OR_GOTO (this->name, fd, unwind);
- GF_VALIDATE_OR_GOTO (this->name, fd->inode, unwind);
-
- INIT_LIST_HEAD (&entries.list);
-
- parent_ctx = svs_inode_ctx_get (this, fd->inode);
- if (!parent_ctx) {
- gf_log (this->name, GF_LOG_ERROR, "failed to get the inode "
- "context for %s", uuid_utoa (fd->inode->gfid));
- op_ret = -1;
- op_errno = EINVAL;
- goto unwind;
- }
-
- if (parent_ctx->type == SNAP_VIEW_ENTRY_POINT_INODE) {
- LOCK (&fd->lock);
- {
- count = svs_fill_readdir (this, &entries, size, off);
- }
- UNLOCK (&fd->lock);
-
- op_ret = count;
-
- list_for_each_entry (entry, &entries.list, list) {
- svs_readdirp_fill (this, fd->inode, parent_ctx, entry);
- }
-
- goto unwind;
- } else {
- svs_fd = svs_fd_ctx_get_or_new (this, fd);
- if (!svs_fd) {
- gf_log (this->name, GF_LOG_ERROR, "failed to get the "
- "fd context %s", uuid_utoa (fd->inode->gfid));
- op_ret = -1;
- op_errno = EBADFD;
- goto unwind;
- }
-
- glfs_seekdir (svs_fd->fd, off);
-
- LOCK (&fd->lock);
- {
- count = svs_glfs_readdir (this, svs_fd->fd, &entries,
- &op_errno, &buf, _gf_true,
- size);
- }
- UNLOCK (&fd->lock);
-
- op_ret = count;
-
- list_for_each_entry (entry, &entries.list, list) {
- svs_readdirp_fill (this, fd->inode, parent_ctx, entry);
- }
-
- goto unwind;
- }
-
-unwind:
- STACK_UNWIND_STRICT (readdirp, frame, op_ret, op_errno, &entries, dict);
-
- gf_dirent_free (&entries);
-
- return 0;
-}
-
-int32_t
-svs_readdir (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
- off_t off, dict_t *xdata)
-{
- svs_private_t *priv = NULL;
- gf_dirent_t entries = {{{0, }, }, };
- int count = 0;
- svs_inode_t *inode_ctx = NULL;
- int op_errno = EINVAL;
- int op_ret = -1;
- svs_fd_t *svs_fd = NULL;
- glfs_fd_t *glfd = NULL;
-
- INIT_LIST_HEAD (&entries.list);
-
- GF_VALIDATE_OR_GOTO ("snap-view-server", this, unwind);
- GF_VALIDATE_OR_GOTO (this->name, frame, unwind);
- GF_VALIDATE_OR_GOTO (this->name, fd, unwind);
- GF_VALIDATE_OR_GOTO (this->name, fd->inode, unwind);
-
- priv = this->private;
-
- inode_ctx = svs_inode_ctx_get (this, fd->inode);
- if (!inode_ctx) {
- gf_log (this->name, GF_LOG_ERROR, "inode context not found in "
- "the inode %s", uuid_utoa (fd->inode->gfid));
- op_ret = -1;
- op_errno = EINVAL;
- goto unwind;
- }
-
- if (inode_ctx->type == SNAP_VIEW_ENTRY_POINT_INODE) {
- LOCK (&fd->lock);
- {
- count = svs_fill_readdir (this, &entries, size, off);
- }
- UNLOCK (&fd->lock);
- } else {
- svs_fd = svs_fd_ctx_get_or_new (this, fd);
- if (!svs_fd) {
- gf_log (this->name, GF_LOG_ERROR, "failed to get the "
- "fd context %s", uuid_utoa (fd->inode->gfid));
- op_ret = -1;
- op_errno = EBADFD;
- goto unwind;
- }
-
- glfd = svs_fd->fd;
-
- LOCK (&fd->lock);
- {
- count = svs_glfs_readdir (this, glfd, &entries,
- &op_errno, NULL, _gf_false,
- size);
- }
- UNLOCK (&fd->lock);
- }
-
- op_ret = count;
-
-unwind:
- STACK_UNWIND_STRICT (readdir, frame, op_ret, op_errno, &entries, xdata);
-
- gf_dirent_free (&entries);
-
- return 0;
-}
-
-/*
- * This function is mainly helpful for NFS. Till now NFS server was not linking
- * the inodes in readdirp, which caused problems when below operations were
- * performed.
- *
- * 1) ls -l in one of the snaopshots (snapview-server would generate gfids for
- * each entry on the fly and link the inodes associated with those entries)
- * 2) NFS server upon getting readdirp reply would not link the inodes of the
- * entries. But it used to generate filehandles for each entry and associate
- * the gfid of that entry with the filehandle and send it as part of the
- * reply to nfs client.
- * 3) NFS client would send the filehandle of one of those entries when some
- * activity is done on it.
- * 4) NFS server would not be able to find the inode for the gfid present in the
- * filehandle (as the inode was not linked) and would go for hard resolution
- * by sending a lookup on the gfid by creating a new inode.
- * 5) snapview-client will not able to identify whether the inode is a real
- * inode existing in the main volume or a virtual inode existing in the
- * snapshots as there would not be any inode context.
- * 6) Since the gfid upon which lookup is sent is a virtual gfid which is not
- * present in the disk, lookup would fail and the application would get an
- * error.
- *
- * The above problem is fixed by the below commit which makes snapview server
- * more compatible with nfs server (1dea949cb60c3814c9206df6ba8dddec8d471a94).
- * But now because NFS server does inode linking in readdirp has introduced
- * the below issue.
- * In readdirp though snapview-server allocates inode contexts it does not
- * actually perform lookup on each entry it obtained in readdirp (as doing
- * a lookup via gfapi over the network for each entry would be costly).
- *
- * Till now it was not a problem with NFS server, as NFS was sending a lookup on
- * the gfid it got from NFS client, for which it was not able to find the right
- * inode. So snapview-server was able to get the fs instance (glfs_t) of the
- * snapshot volume to which the entry belongs to, and the handle for the entry
- * from the corresponding snapshot volume and fill those informations in the
- * inode context.
- *
- * But now, since NFS server is able to find the inode from the inode table for
- * the gfid it got from the NFS client, it wont send lookup. Rather it directly
- * sends the fop it received from the client. Now this causes problems for
- * snapview-server. Because for each fop snapview-server assumes that lookup has
- * been performed on that entry and the entry's inode context contains the
- * pointers for the fs instance and the handle to the entry in that fs. When NFS
- * server sends the fop and snapview-server finds that the fs instance and the
- * handle within the inode context are NULL it unwinds with EINVAL.
- *
- * So to handle this, if fs instance or handle within the inode context are
- * NULL, then do a lookup based on parent inode context's fs instance. And
- * unwind the results obtained as part of lookup
- */
-
-int32_t
-svs_get_handle (xlator_t *this, loc_t *loc, svs_inode_t *inode_ctx,
- int32_t *op_errno)
-{
- svs_inode_t *parent_ctx = NULL;
- int ret = -1;
- inode_t *parent = NULL;
- struct iatt postparent = {0, };
- struct iatt buf = {0, };
- char uuid1[64];
-
- GF_VALIDATE_OR_GOTO ("snap-view-daemon", this, out);
- GF_VALIDATE_OR_GOTO (this->name, loc, out);
- GF_VALIDATE_OR_GOTO (this->name, loc->inode, out);
-
- if (loc->path) {
- if (!loc->name || (loc->name && !strcmp (loc->name, ""))) {
- loc->name = strrchr (loc->path, '/');
- if (loc->name)
- loc->name++;
- }
- }
-
- if (loc->parent)
- parent = inode_ref (loc->parent);
- else {
- parent = inode_find (loc->inode->table, loc->pargfid);
- if (!parent)
- parent = inode_parent (loc->inode, NULL, NULL);
- }
-
- if (parent)
- parent_ctx = svs_inode_ctx_get (this, parent);
-
- if (!parent_ctx) {
- gf_log (this->name, GF_LOG_WARNING, "failed to get the parent "
- "context for %s (%s)", loc->path,
- uuid_utoa_r (loc->inode->gfid, uuid1));
- *op_errno = EINVAL;
- goto out;
- }
-
- if (parent_ctx) {
- if (parent_ctx->type == SNAP_VIEW_ENTRY_POINT_INODE)
- ret = svs_lookup_snapshot (this, loc, &buf,
- &postparent, parent,
- parent_ctx, op_errno);
- else
- ret = svs_lookup_entry (this, loc, &buf,
- &postparent, parent,
- parent_ctx, op_errno);
- }
-
-out:
- if (parent)
- inode_unref (parent);
-
- return ret;
-}
-
-int32_t
-svs_stat (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
-{
- svs_private_t *priv = NULL;
- struct iatt buf = {0, };
- int32_t op_errno = EINVAL;
- int32_t op_ret = -1;
- svs_inode_t *inode_ctx = NULL;
- glfs_t *fs = NULL;
- glfs_object_t *object = NULL;
- struct stat stat = {0, };
- int ret = -1;
-
- GF_VALIDATE_OR_GOTO ("snap-view-daemon", this, out);
- GF_VALIDATE_OR_GOTO (this->name, frame, out);
- GF_VALIDATE_OR_GOTO (this->name, loc, out);
- GF_VALIDATE_OR_GOTO (this->name, loc->inode, out);
-
- priv = this->private;
-
- /* Instead of doing the check of whether it is a entry point directory
- or not by checking the name of the entry and then deciding what
- to do, just check the inode context and decide what to be done.
- */
-
- inode_ctx = svs_inode_ctx_get (this, loc->inode);
- if (!inode_ctx) {
- gf_log (this->name, GF_LOG_ERROR, "inode context not found for"
- " %s", uuid_utoa (loc->inode->gfid));
- op_ret = -1;
- op_errno = EINVAL;
- goto out;
- }
-
- if (inode_ctx->type == SNAP_VIEW_ENTRY_POINT_INODE) {
- svs_iatt_fill (loc->inode->gfid, &buf);
- op_ret = 0;
- }
- else {
-
- SVS_GET_INODE_CTX_INFO(inode_ctx, fs, object, this, loc, op_ret,
- op_errno, out);
-
- ret = glfs_h_stat (fs, object, &stat);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "glfs_h_stat on %s "
- "(gfid: %s) failed", loc->name,
- uuid_utoa (loc->inode->gfid));
- op_ret = -1;
- op_errno = errno;
- goto out;
- }
-
- iatt_from_stat (&buf, &stat);
- uuid_copy (buf.ia_gfid, loc->inode->gfid);
- svs_fill_ino_from_gfid (&buf);
- op_ret = ret;
- }
-
-out:
- STACK_UNWIND_STRICT (stat, frame, op_ret, op_errno, &buf, xdata);
- return 0;
-}
-
-int32_t
-svs_fstat (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
-{
- svs_private_t *priv = NULL;
- struct iatt buf = {0, };
- int32_t op_errno = EINVAL;
- int32_t op_ret = -1;
- svs_inode_t *inode_ctx = NULL;
- struct stat stat = {0, };
- int ret = -1;
- glfs_fd_t *glfd = NULL;
- svs_fd_t *sfd = NULL;
-
- GF_VALIDATE_OR_GOTO ("snap-view-daemon", this, out);
- GF_VALIDATE_OR_GOTO (this->name, frame, out);
- GF_VALIDATE_OR_GOTO (this->name, fd, out);
- GF_VALIDATE_OR_GOTO (this->name, fd->inode, out);
-
- priv = this->private;
-
- /* Instead of doing the check of whether it is a entry point directory
- or not by checking the name of the entry and then deciding what
- to do, just check the inode context and decide what to be done.
- */
-
- inode_ctx = svs_inode_ctx_get (this, fd->inode);
- if (!inode_ctx) {
- gf_log (this->name, GF_LOG_ERROR, "inode context not found for"
- " the inode %s", uuid_utoa (fd->inode->gfid));
- op_ret = -1;
- op_errno = EINVAL;
- goto out;
- }
-
- if (inode_ctx->type == SNAP_VIEW_ENTRY_POINT_INODE) {
- svs_iatt_fill (fd->inode->gfid, &buf);
- op_ret = 0;
- }
- else {
- sfd = svs_fd_ctx_get_or_new (this, fd);
- if (!sfd) {
- gf_log (this->name, GF_LOG_ERROR, "failed to get the "
- "fd context for %s",
- uuid_utoa (fd->inode->gfid));
- op_ret = -1;
- op_errno = EBADFD;
- goto out;
- }
-
- glfd = sfd->fd;
- ret = glfs_fstat (glfd, &stat);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "glfs_fstat on "
- "gfid: %s failed", uuid_utoa (fd->inode->gfid));
- op_ret = -1;
- op_errno = errno;
- goto out;
- }
-
- iatt_from_stat (&buf, &stat);
- uuid_copy (buf.ia_gfid, fd->inode->gfid);
- svs_fill_ino_from_gfid (&buf);
- op_ret = ret;
- }
-
-out:
- STACK_UNWIND_STRICT (fstat, frame, op_ret, op_errno, &buf, xdata);
- return 0;
-}
-
-int32_t
-svs_open (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
- fd_t *fd, dict_t *xdata)
-{
- svs_inode_t *inode_ctx = NULL;
- svs_fd_t *sfd = NULL;
- int32_t op_ret = -1;
- int32_t op_errno = EINVAL;
- glfs_fd_t *glfd = NULL;
- glfs_t *fs = NULL;
- glfs_object_t *object = NULL;
-
-
- GF_VALIDATE_OR_GOTO ("snap-view-daemon", this, out);
- GF_VALIDATE_OR_GOTO (this->name, frame, out);
- GF_VALIDATE_OR_GOTO (this->name, fd, out);
- GF_VALIDATE_OR_GOTO (this->name, loc, out);
- GF_VALIDATE_OR_GOTO (this->name, loc->inode, out);
-
- inode_ctx = svs_inode_ctx_get (this, loc->inode);
- if (!inode_ctx) {
- gf_log (this->name, GF_LOG_ERROR, "inode context for %s "
- "(gfid: %s) not found", loc->name,
- uuid_utoa (loc->inode->gfid));
- goto out;
- }
-
- if (inode_ctx->type == SNAP_VIEW_ENTRY_POINT_INODE)
- GF_ASSERT (0); // on entry point it should always be opendir
-
- SVS_GET_INODE_CTX_INFO(inode_ctx, fs, object, this, loc, op_ret,
- op_errno, out);
-
- glfd = glfs_h_open (fs, object, flags);
- if (!glfd) {
- gf_log (this->name, GF_LOG_ERROR, "glfs_h_open on %s failed "
- "(gfid: %s)", loc->name, uuid_utoa (loc->inode->gfid));
- op_ret = -1;
- op_errno = errno;
- goto out;
- }
-
- sfd = svs_fd_ctx_get_or_new (this, fd);
- if (!sfd) {
- gf_log (this->name, GF_LOG_ERROR, "failed to allocate fd "
- "context for %s (gfid: %s)", loc->name,
- uuid_utoa (loc->inode->gfid));
- op_ret = -1;
- op_errno = ENOMEM;
- glfs_close (glfd);
- goto out;
- }
- sfd->fd = glfd;
-
- op_ret = 0;
-
-out:
- STACK_UNWIND_STRICT (open, frame, op_ret, op_errno, fd, NULL);
- return 0;
-}
-
-int32_t
-svs_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_ret = -1;
- int32_t op_errno = 0;
- svs_private_t *priv = NULL;
- struct iobuf *iobuf = NULL;
- struct iobref *iobref = NULL;
- struct iovec vec = {0,};
- svs_fd_t *sfd = NULL;
- int ret = -1;
- struct stat fstatbuf = {0, };
- glfs_fd_t *glfd = NULL;
- struct iatt stbuf = {0, };
-
- GF_VALIDATE_OR_GOTO ("snap-view-daemon", this, out);
- GF_VALIDATE_OR_GOTO (this->name, frame, out);
- GF_VALIDATE_OR_GOTO (this->name, fd, out);
- GF_VALIDATE_OR_GOTO (this->name, fd->inode, out);
-
- priv = this->private;
- VALIDATE_OR_GOTO (priv, out);
-
- sfd = svs_fd_ctx_get_or_new (this, fd);
- if (!sfd) {
- gf_log (this->name, GF_LOG_ERROR, "failed to get the fd "
- "context for %s", uuid_utoa (fd->inode->gfid));
- op_ret = -1;
- op_errno = EBADFD;
- goto out;
- }
-
- glfd = sfd->fd;
-
- iobuf = iobuf_get2 (this->ctx->iobuf_pool, size);
- if (!iobuf) {
- op_ret = -1;
- op_errno = ENOMEM;
- goto out;
- }
-
- ret = glfs_pread (glfd, iobuf->ptr, size, offset, 0);
- if (ret < 0) {
- op_ret = -1;
- op_errno = errno;
- gf_log (this->name, GF_LOG_ERROR, "glfs_read failed (%s)",
- strerror (op_errno));
- goto out;
- }
-
- vec.iov_base = iobuf->ptr;
- vec.iov_len = ret;
-
- iobref = iobref_new ();
-
- iobref_add (iobref, iobuf);
-
- ret = glfs_fstat (glfd, &fstatbuf);
- if (ret) {
- op_ret = -1;
- op_errno = errno;
- gf_log (this->name, GF_LOG_ERROR, "glfs_fstat failed after "
- "readv on %s", uuid_utoa (fd->inode->gfid));
- goto out;
- }
-
- iatt_from_stat (&stbuf, &fstatbuf);
- uuid_copy (stbuf.ia_gfid, fd->inode->gfid);
- svs_fill_ino_from_gfid (&stbuf);
-
- /* Hack to notify higher layers of EOF. */
- if (!stbuf.ia_size || (offset + vec.iov_len) >= stbuf.ia_size)
- op_errno = ENOENT;
-
- op_ret = vec.iov_len;
-
-out:
-
- STACK_UNWIND_STRICT (readv, frame, op_ret, op_errno,
- &vec, 1, &stbuf, iobref, NULL);
-
- if (iobref)
- iobref_unref (iobref);
- if (iobuf)
- iobuf_unref (iobuf);
-
- return 0;
-}
-
-int32_t
-svs_readlink (call_frame_t *frame, xlator_t *this,
- loc_t *loc, size_t size, dict_t *xdata)
-{
- svs_inode_t *inode_ctx = NULL;
- glfs_t *fs = NULL;
- glfs_object_t *object = NULL;
- int op_ret = -1;
- int op_errno = EINVAL;
- char *buf = NULL;
- struct iatt stbuf = {0, };
- int ret = -1;
- struct stat stat = {0, };
-
- GF_VALIDATE_OR_GOTO ("snap-view-daemon", this, out);
- GF_VALIDATE_OR_GOTO (this->name, frame, out);
- GF_VALIDATE_OR_GOTO (this->name, loc, out);
- GF_VALIDATE_OR_GOTO (this->name, loc->inode, out);
-
- inode_ctx = svs_inode_ctx_get (this, loc->inode);
- if (!inode_ctx) {
- gf_log (this->name, GF_LOG_ERROR, "failed to get inode context "
- "for %s (gfid: %s)", loc->name,
- uuid_utoa (loc->inode->gfid));
- op_ret = -1;
- op_errno = EINVAL;
- goto out;
- }
-
- SVS_GET_INODE_CTX_INFO(inode_ctx, fs, object, this, loc, op_ret,
- op_errno, out);
-
- ret = glfs_h_stat (fs, object, &stat);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "glfs_h_stat on %s "
- "(gfid: %s) failed", loc->name,
- uuid_utoa (loc->inode->gfid));
- op_ret = -1;
- op_errno = errno;
- goto out;
- }
-
- iatt_from_stat (&stbuf, &stat);
- uuid_copy (stbuf.ia_gfid, loc->inode->gfid);
- svs_fill_ino_from_gfid (&stbuf);
-
- buf = alloca (size + 1);
- op_ret = glfs_h_readlink (fs, object, buf, size);
- if (op_ret == -1) {
- gf_log (this->name, GF_LOG_ERROR, "readlink on %s failed "
- "(gfid: %s)", loc->name, uuid_utoa (loc->inode->gfid));
- op_errno = errno;
- goto out;
- }
-
- buf[op_ret] = 0;
-
-out:
- STACK_UNWIND_STRICT (readlink, frame, op_ret, op_errno, buf, &stbuf,
- NULL);
-
- return 0;
-}
-
-int32_t
-svs_access (call_frame_t *frame, xlator_t *this, loc_t *loc, int mask,
- dict_t *xdata)
-{
- int ret = -1;
- int32_t op_ret = -1;
- int32_t op_errno = EINVAL;
- svs_private_t *priv = NULL;
- glfs_t *fs = NULL;
- glfs_object_t *object = NULL;
- svs_inode_t *inode_ctx = NULL;
- gf_boolean_t is_fuse_call = 0;
- int mode = 0;
-
- GF_VALIDATE_OR_GOTO ("svs", this, out);
- GF_VALIDATE_OR_GOTO (this->name, this->private, out);
- GF_VALIDATE_OR_GOTO (this->name, loc, out);
- GF_VALIDATE_OR_GOTO (this->name, loc->inode, out);
-
- priv = this->private;
-
- inode_ctx = svs_inode_ctx_get (this, loc->inode);
- if (!inode_ctx) {
- gf_log (this->name, GF_LOG_ERROR, "inode context not found for"
- " %s", uuid_utoa (loc->inode->gfid));
- op_ret = -1;
- op_errno = EINVAL;
- goto out;
- }
-
- is_fuse_call = __is_fuse_call (frame);
-
- /*
- * For entry-point directory, set read and execute bits. But not write
- * permissions.
- */
- if (inode_ctx->type == SNAP_VIEW_ENTRY_POINT_INODE) {
- if (is_fuse_call) {
- op_ret = 0;
- op_errno = 0;
- } else {
- op_ret = 0;
- mode |= POSIX_ACL_READ;
- mode |= POSIX_ACL_EXECUTE;
- op_errno = mode;
- }
- goto out;
- }
-
-
- SVS_GET_INODE_CTX_INFO(inode_ctx, fs, object, this, loc, op_ret,
- op_errno, out);
-
- /* The actual posix_acl xlator does acl checks differently for
- fuse and nfs. So set frame->root->pid as fspid of the syncop
- if the call came from nfs
- */
- if (!is_fuse_call) {
- syncopctx_setfspid (&frame->root->pid);
- syncopctx_setfsuid (&frame->root->uid);
- syncopctx_setfsgid (&frame->root->gid);
- syncopctx_setfsgroups (frame->root->ngrps,
- frame->root->groups);
- }
-
- ret = glfs_h_access (fs, object, mask);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR, "failed to access %s "
- "(gfid: %s)", loc->path, uuid_utoa (loc->inode->gfid));
- op_ret = -1;
- op_errno = errno;
- goto out;
- }
-
- op_ret = 0;
- op_errno = ret;
-
-out:
-
- STACK_UNWIND_STRICT (access, frame, op_ret, op_errno, NULL);
- return 0;
-}
-
-
-int32_t
-mem_acct_init (xlator_t *this)
-{
- int ret = -1;
-
- if (!this)
- return ret;
-
- ret = xlator_mem_acct_init (this, gf_svs_mt_end + 1);
-
- if (ret != 0) {
- gf_log (this->name, GF_LOG_WARNING, "Memory accounting"
- " init failed");
- return ret;
- }
-
- return ret;
-}
-
-int32_t
-init (xlator_t *this)
-{
- svs_private_t *priv = NULL;
- int ret = -1;
- pthread_t snap_thread;
-
- /* This can be the top of graph in certain cases */
- if (!this->parents) {
- gf_log (this->name, GF_LOG_DEBUG,
- "dangling volume. check volfile ");
- }
-
- priv = GF_CALLOC (1, sizeof (*priv), gf_svs_mt_priv_t);
- if (!priv)
- goto out;
-
- this->private = priv;
-
- GF_OPTION_INIT ("volname", priv->volname, str, out);
- LOCK_INIT (&priv->snaplist_lock);
-
- LOCK (&priv->snaplist_lock);
- {
- priv->num_snaps = 0;
- }
- UNLOCK (&priv->snaplist_lock);
-
- /* What to do here upon failure? should init be failed or succeed? */
- /* If succeeded, then dynamic management of snapshots will not */
- /* happen.*/
- ret = svs_mgmt_init (this);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING, "failed to initiate the "
- "mgmt rpc callback for svs. Dymamic management of the"
- "snapshots will not happen");
- goto out;
- }
-
- /* get the list of snaps first to return to client xlator */
- ret = svs_get_snapshot_list (this);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Error initializing snaplist infrastructure");
- ret = -1;
- goto out;
- }
-
- ret = 0;
-
-out:
- if (ret && priv) {
- LOCK_DESTROY (&priv->snaplist_lock);
- GF_FREE (priv->dirents);
- GF_FREE (priv);
- }
-
- return ret;
-}
-
-void
-fini (xlator_t *this)
-{
- svs_private_t *priv = NULL;
- glusterfs_ctx_t *ctx = NULL;
- int ret = 0;
-
- GF_ASSERT (this);
- priv = this->private;
- this->private = NULL;
- ctx = this->ctx;
- if (!ctx)
- gf_log (this->name, GF_LOG_ERROR,
- "Invalid ctx found");
-
- if (priv) {
- ret = LOCK_DESTROY (&priv->snaplist_lock);
- if (ret != 0) {
- gf_log (this->name, GF_LOG_WARNING,
- "Could not destroy mutex snaplist_lock");
- }
-
- if (priv->dirents) {
- GF_FREE (priv->dirents);
- }
-
- if (priv->rpc) {
- /* cleanup the saved-frames before last unref */
- rpc_clnt_connection_cleanup (&priv->rpc->conn);
- rpc_clnt_unref (priv->rpc);
- }
-
- GF_FREE (priv);
- }
-
- return;
-}
-
-struct xlator_fops fops = {
- .lookup = svs_lookup,
- .stat = svs_stat,
- .opendir = svs_opendir,
- .readdirp = svs_readdirp,
- .readdir = svs_readdir,
- .open = svs_open,
- .readv = svs_readv,
- .flush = svs_flush,
- .fstat = svs_fstat,
- .getxattr = svs_getxattr,
- .access = svs_access,
- .readlink = svs_readlink,
- /* entry fops */
-};
-
-struct xlator_cbks cbks = {
- .release = svs_release,
- .releasedir = svs_releasedir,
- .forget = svs_forget,
-};
-
-struct volume_options options[] = {
- { .key = {"volname"},
- .type = GF_OPTION_TYPE_STR,
- },
- { .key = {NULL} },
-};
diff --git a/xlators/features/snapview-server/src/snapview-server.h b/xlators/features/snapview-server/src/snapview-server.h
deleted file mode 100644
index c80d3456c30..00000000000
--- a/xlators/features/snapview-server/src/snapview-server.h
+++ /dev/null
@@ -1,226 +0,0 @@
-/*
- Copyright (c) 2014 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 __SNAP_VIEW_H__
-#define __SNAP_VIEW_H__
-
-#ifndef _CONFIG_H
-#define _CONFIG_H
-#include "config.h"
-#endif
-
-#include "dict.h"
-#include "defaults.h"
-#include "mem-types.h"
-#include "call-stub.h"
-#include "inode.h"
-#include "byte-order.h"
-#include "iatt.h"
-#include <ctype.h>
-#include <sys/uio.h>
-#include "glusterfs.h"
-#include "xlator.h"
-#include "logging.h"
-#include "glfs.h"
-#include "common-utils.h"
-#include "glfs-handles.h"
-#include "glfs-internal.h"
-#include "glusterfs3-xdr.h"
-#include "glusterfs-acl.h"
-#include "syncop.h"
-#include "list.h"
-#include "timer.h"
-#include "rpc-clnt.h"
-#include "protocol-common.h"
-#include "xdr-generic.h"
-
-
-#define DEFAULT_SVD_LOG_FILE_DIRECTORY DATADIR "/log/glusterfs"
-
-#define SNAP_VIEW_MAX_GLFS_T 256
-#define SNAP_VIEW_MAX_GLFS_FDS 1024
-#define SNAP_VIEW_MAX_GLFS_OBJ_HANDLES 1024
-
-#define SVS_STACK_DESTROY(_frame) \
- do { \
- ((call_frame_t *)_frame)->local = NULL; \
- STACK_DESTROY (((call_frame_t *)_frame)->root); \
- } while (0)
-
-#define SVS_CHECK_VALID_SNAPSHOT_HANDLE(fs, this) \
- do { \
- svs_private_t *_private = NULL; \
- _private = this->private; \
- int i = 0; \
- gf_boolean_t found = _gf_false; \
- LOCK (&_private->snaplist_lock); \
- { \
- for (i = 0; i < _private->num_snaps; i++) { \
- if (_private->dirents->fs && fs && \
- _private->dirents->fs == fs) { \
- found = _gf_true; \
- break; \
- } \
- } \
- } \
- UNLOCK (&_private->snaplist_lock); \
- \
- if (!found) \
- fs = NULL; \
- } while (0)
-
-#define SVS_GET_INODE_CTX_INFO(inode_ctx, fs, object, this, loc, ret, \
- op_errno, label) \
- do { \
- fs = inode_ctx->fs; \
- object = inode_ctx->object; \
- SVS_CHECK_VALID_SNAPSHOT_HANDLE (fs, this); \
- if (!fs) \
- object = NULL; \
- \
- if (!fs || !object) { \
- int32_t tmp = -1; \
- char tmp_uuid[64]; \
- \
- tmp = svs_get_handle (this, loc, inode_ctx, \
- &op_errno); \
- if (tmp) { \
- gf_log (this->name, GF_LOG_ERROR, \
- "failed to get the handle for %s " \
- "(gfid: %s)", loc->path, \
- uuid_utoa_r (loc->inode->gfid, \
- tmp_uuid)); \
- ret = -1; \
- goto label; \
- } \
- \
- fs = inode_ctx->fs; \
- object = inode_ctx->object; \
- } \
- } while(0);
-
-int
-svs_mgmt_submit_request (void *req, call_frame_t *frame,
- glusterfs_ctx_t *ctx,
- rpc_clnt_prog_t *prog, int procnum,
- fop_cbk_fn_t cbkfn, xdrproc_t xdrproc);
-
-int
-svs_get_snapshot_list (xlator_t *this);
-
-int
-mgmt_get_snapinfo_cbk (struct rpc_req *req, struct iovec *iov,
- int count, void *myframe);
-
-typedef enum {
- SNAP_VIEW_ENTRY_POINT_INODE = 0,
- SNAP_VIEW_SNAPSHOT_INODE,
- SNAP_VIEW_VIRTUAL_INODE
-} inode_type_t;
-
-struct svs_inode {
- glfs_t *fs;
- glfs_object_t *object;
- inode_type_t type;
-
- /* used only for entry point directory where gfid of the directory
- from where the entry point was entered is saved.
- */
- uuid_t pargfid;
- struct iatt buf;
-};
-typedef struct svs_inode svs_inode_t;
-
-struct svs_fd {
- glfs_fd_t *fd;
-};
-typedef struct svs_fd svs_fd_t;
-
-struct snap_dirent {
- char name[NAME_MAX];
- char uuid[UUID_CANONICAL_FORM_LEN + 1];
- char snap_volname[NAME_MAX];
- glfs_t *fs;
-};
-typedef struct snap_dirent snap_dirent_t;
-
-struct svs_private {
- snap_dirent_t *dirents;
- int num_snaps;
- char *volname;
- struct list_head snaplist;
- gf_lock_t snaplist_lock;
- struct rpc_clnt *rpc;
-};
-typedef struct svs_private svs_private_t;
-
-int
-__svs_inode_ctx_set (xlator_t *this, inode_t *inode, svs_inode_t *svs_inode);
-
-svs_inode_t *
-__svs_inode_ctx_get (xlator_t *this, inode_t *inode);
-
-svs_inode_t *
-svs_inode_ctx_get (xlator_t *this, inode_t *inode);
-
-int32_t
-svs_inode_ctx_set (xlator_t *this, inode_t *inode, svs_inode_t *svs_inode);
-
-svs_inode_t *
-svs_inode_ctx_get_or_new (xlator_t *this, inode_t *inode);
-
-int
-__svs_fd_ctx_set (xlator_t *this, fd_t *fd, svs_fd_t *svs_fd);
-
-svs_fd_t *
-__svs_fd_ctx_get (xlator_t *this, fd_t *fd);
-
-svs_fd_t *
-svs_fd_ctx_get (xlator_t *this, fd_t *fd);
-
-int32_t
-svs_fd_ctx_set (xlator_t *this, fd_t *fd, svs_fd_t *svs_fd);
-
-svs_fd_t *
-__svs_fd_ctx_get_or_new (xlator_t *this, fd_t *fd);
-
-svs_fd_t *
-svs_fd_ctx_get_or_new (xlator_t *this, fd_t *fd);
-
-void
-svs_fill_ino_from_gfid (struct iatt *buf);
-
-void
-svs_iatt_fill (uuid_t gfid, struct iatt *buf);
-
-snap_dirent_t *
-svs_get_latest_snap_entry (xlator_t *this);
-
-glfs_t *
-svs_get_latest_snapshot (xlator_t *this);
-
-glfs_t *
-svs_initialise_snapshot_volume (xlator_t *this, const char *name,
- int32_t *op_errno);
-
-glfs_t *
-__svs_initialise_snapshot_volume (xlator_t *this, const char *name,
- int32_t *op_errno);
-
-snap_dirent_t *
-__svs_get_snap_dirent (xlator_t *this, const char *name);
-
-int
-svs_mgmt_init (xlator_t *this);
-
-int32_t
-svs_get_handle (xlator_t *this, loc_t *loc, svs_inode_t *inode_ctx,
- int32_t *op_errno);
-
-#endif /* __SNAP_VIEW_H__ */
diff --git a/xlators/features/trash/src/Makefile.am b/xlators/features/trash/src/Makefile.am
index 5251eb08256..15998a56ec7 100644
--- a/xlators/features/trash/src/Makefile.am
+++ b/xlators/features/trash/src/Makefile.am
@@ -1,16 +1,15 @@
xlator_LTLIBRARIES = trash.la
xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/testing/features
-trash_la_LDFLAGS = -module -avoid-version
+trash_la_LDFLAGS = -module -avoidversion
trash_la_SOURCES = trash.c
trash_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la
-noinst_HEADERS = trash.h trash-mem-types.h
+noinst_HEADERS = trash.h
-AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src
-
-AM_CFLAGS = -Wall $(GF_CFLAGS)
+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/features/trash/src/trash-mem-types.h b/xlators/features/trash/src/trash-mem-types.h
deleted file mode 100644
index 0e6ef572fcc..00000000000
--- a/xlators/features/trash/src/trash-mem-types.h
+++ /dev/null
@@ -1,22 +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 __TRASH_MEM_TYPES_H__
-#define __TRASH_MEM_TYPES_H__
-
-#include "mem-types.h"
-
-enum gf_trash_mem_types_ {
- gf_trash_mt_trash_private_t = gf_common_mt_end + 1,
- gf_trash_mt_char,
- gf_trash_mt_trash_elim_pattern_t,
- gf_trash_mt_end
-};
-#endif
-
diff --git a/xlators/features/trash/src/trash.c b/xlators/features/trash/src/trash.c
index addeb66a053..aa5cea0d156 100644
--- a/xlators/features/trash/src/trash.c
+++ b/xlators/features/trash/src/trash.c
@@ -1,42 +1,52 @@
/*
- Copyright (c) 2006-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) 2006-2009 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 "trash.h"
-#include "trash-mem-types.h"
+
int32_t
trash_ftruncate_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 *iobuf);
+ struct stat *stbuf, struct iobref *iobuf);
int32_t
trash_truncate_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);
+ struct stat *prebuf, struct stat *postbuf);
int32_t
trash_truncate_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);
+ struct stat *stbuf, struct stat *preparent,
+ struct stat *postparent);
int32_t
trash_unlink_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 op_ret, int32_t op_errno, struct stat *buf,
+ struct stat *preoldparent, struct stat *postoldparent,
+ struct stat *prenewparent, struct stat *postnewparent);
void
trash_local_wipe (trash_local_t *local)
@@ -53,7 +63,7 @@ trash_local_wipe (trash_local_t *local)
if (local->newfd)
fd_unref (local->newfd);
- mem_put (local);
+ FREE (local);
out:
return;
}
@@ -61,17 +71,17 @@ out:
int32_t
trash_common_unwind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno,
- struct iatt *preparent, struct iatt *postparent)
+ struct stat *preparent, struct stat *postparent)
{
- TRASH_STACK_UNWIND (unlink, frame, op_ret, op_errno, preparent, postparent);
+ TRASH_STACK_UNWIND (frame, op_ret, op_errno, preparent, postparent);
return 0;
}
int32_t
trash_unlink_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)
+ struct stat *stbuf, struct stat *preparent,
+ struct stat *postparent)
{
trash_local_t *local = NULL;
char *tmp_str = NULL;
@@ -84,10 +94,9 @@ trash_unlink_mkdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
loc_t tmp_loc = {0,};
local = frame->local;
- tmp_str = gf_strdup (local->newpath);
+ tmp_str = strdup (local->newpath);
if (!tmp_str) {
- gf_log (this->name, GF_LOG_ERROR, "out of memory");
- goto out;
+ gf_log (this->name, GF_LOG_DEBUG, "out of memory");
}
loop_count = local->loop_count;
@@ -104,8 +113,7 @@ trash_unlink_mkdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
}
tmp_path = memdup (local->newpath, count);
if (!tmp_path) {
- gf_log (this->name, GF_LOG_ERROR, "out of memory");
- goto out;
+ gf_log (this->name, GF_LOG_DEBUG, "out of memory");
}
tmp_loc.path = tmp_path;
@@ -114,7 +122,7 @@ trash_unlink_mkdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
STACK_WIND_COOKIE (frame, trash_unlink_mkdir_cbk, tmp_path,
this->children->xlator,
this->children->xlator->fops->mkdir,
- &tmp_loc, 0755, NULL);
+ &tmp_loc, 0755);
goto out;
}
@@ -148,19 +156,18 @@ trash_unlink_mkdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
}
tmp_path = memdup (local->newpath, count);
if (!tmp_path) {
- gf_log (this->name, GF_LOG_ERROR, "out of memory");
- goto out;
+ gf_log (this->name, GF_LOG_DEBUG, "out of memory");
}
tmp_loc.path = tmp_path;
STACK_WIND_COOKIE (frame, trash_unlink_mkdir_cbk, tmp_path,
this->children->xlator,
this->children->xlator->fops->mkdir,
- &tmp_loc, 0755, NULL);
+ &tmp_loc, 0755);
out:
- GF_FREE (cookie);
- GF_FREE (tmp_str);
+ free (cookie);
+ free (tmp_str);
return 0;
}
@@ -168,25 +175,27 @@ out:
int32_t
trash_rename_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);
+ struct stat *stbuf, struct stat *preparent,
+ struct stat *postparent);
int32_t
trash_unlink_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 op_ret, int32_t op_errno, struct stat *buf,
+ struct stat *preoldparent, struct stat *postoldparent,
+ struct stat *prenewparent, struct stat *postnewparent)
{
trash_local_t *local = NULL;
+ trash_private_t *priv = NULL;
char *tmp_str = NULL;
char *dir_name = NULL;
char *tmp_cookie = NULL;
loc_t tmp_loc = {0,};
+ priv = this->private;
local = frame->local;
if ((op_ret == -1) && (op_errno == ENOENT)) {
- tmp_str = gf_strdup (local->newpath);
+ tmp_str = strdup (local->newpath);
if (!tmp_str) {
gf_log (this->name, GF_LOG_DEBUG, "out of memory");
}
@@ -194,7 +203,7 @@ trash_unlink_rename_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
tmp_loc.path = dir_name;
- tmp_cookie = gf_strdup (dir_name);
+ tmp_cookie = strdup (dir_name);
if (!tmp_cookie) {
gf_log (this->name, GF_LOG_DEBUG, "out of memory");
}
@@ -202,9 +211,9 @@ trash_unlink_rename_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
STACK_WIND_COOKIE (frame, trash_unlink_mkdir_cbk, tmp_cookie,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->mkdir,
- &tmp_loc, 0755, NULL);
+ &tmp_loc, 0755);
- GF_FREE (tmp_str);
+ free (tmp_str);
return 0;
}
@@ -234,7 +243,7 @@ trash_unlink_rename_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
}
/* All other cases, unlink should return success */
- TRASH_STACK_UNWIND (unlink, frame, 0, op_errno, &local->preparent,
+ TRASH_STACK_UNWIND (frame, 0, op_errno, &local->preparent,
&local->postparent);
return 0;
@@ -245,19 +254,19 @@ trash_unlink_rename_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t
trash_common_unwind_buf_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno,
- struct iatt *prebuf, struct iatt *postbuf)
+ struct stat *prebuf, struct stat *postbuf)
{
- TRASH_STACK_UNWIND (truncate, frame, op_ret, op_errno, prebuf, postbuf);
+ TRASH_STACK_UNWIND (frame, op_ret, op_errno, prebuf, postbuf);
return 0;
}
int
trash_common_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)
+ int32_t op_ret, int32_t op_errno, struct stat *stbuf,
+ struct stat *preoldparent, struct stat *postoldparent,
+ struct stat *prenewparent, struct stat *postnewparent)
{
- TRASH_STACK_UNWIND (rename, frame, op_ret, op_errno, stbuf, preoldparent,
+ TRASH_STACK_UNWIND (frame, op_ret, op_errno, stbuf, preoldparent,
postoldparent, prenewparent, postnewparent);
return 0;
}
@@ -265,7 +274,7 @@ trash_common_rename_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t
trash_unlink_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct iatt *buf)
+ int32_t op_ret, int32_t op_errno, struct stat *buf)
{
trash_private_t *priv = NULL;
trash_local_t *local = NULL;
@@ -280,15 +289,15 @@ trash_unlink_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
goto fail;
}
- if ((buf->ia_size == 0) ||
- (buf->ia_size > priv->max_trash_file_size)) {
+ if ((buf->st_size == 0) ||
+ (buf->st_size > priv->max_trash_file_size)) {
/* if the file is too big or zero, just unlink it */
- if (buf->ia_size > priv->max_trash_file_size) {
+ if (buf->st_size > priv->max_trash_file_size) {
gf_log (this->name, GF_LOG_DEBUG,
- "%s: file size too big (%"PRId64") to "
+ "%s: file size too big (%"GF_PRI_SIZET") to "
"move into trash directory",
- local->loc.path, buf->ia_size);
+ local->loc.path, buf->st_size);
}
STACK_WIND (frame, trash_common_unwind_cbk,
@@ -307,8 +316,8 @@ trash_unlink_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
return 0;
fail:
- TRASH_STACK_UNWIND (unlink, frame, op_ret, op_errno, buf,
- NULL);
+ TRASH_STACK_UNWIND (frame, op_ret, op_errno, buf,
+ NULL, NULL, NULL, NULL);
return 0;
@@ -316,9 +325,9 @@ fail:
int32_t
trash_rename_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 op_ret, int32_t op_errno, struct stat *buf,
+ struct stat *preoldparent, struct stat *postoldparent,
+ struct stat *prenewparent, struct stat *postnewparent)
{
trash_local_t *local = NULL;
char *tmp_str = NULL;
@@ -328,7 +337,7 @@ trash_rename_rename_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
local = frame->local;
if ((op_ret == -1) && (op_errno == ENOENT)) {
- tmp_str = gf_strdup (local->newpath);
+ tmp_str = strdup (local->newpath);
if (!tmp_str) {
gf_log (this->name, GF_LOG_DEBUG, "out of memory");
}
@@ -337,7 +346,7 @@ trash_rename_rename_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
/* check for the errno, if its ENOENT create directory and call
* rename later
*/
- tmp_path = gf_strdup (dir_name);
+ tmp_path = strdup (dir_name);
if (!tmp_path) {
gf_log (this->name, GF_LOG_DEBUG, "out of memory");
}
@@ -347,9 +356,9 @@ trash_rename_rename_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
STACK_WIND_COOKIE (frame, trash_rename_mkdir_cbk, tmp_path,
this->children->xlator,
this->children->xlator->fops->mkdir,
- &tmp_loc, 0755, NULL);
+ &tmp_loc, 0755);
- GF_FREE (tmp_str);
+ free (tmp_str);
return 0;
}
@@ -375,8 +384,8 @@ trash_rename_rename_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t
trash_rename_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)
+ struct stat *stbuf, struct stat *preparent,
+ struct stat *postparent)
{
trash_local_t *local = NULL;
char *tmp_str = NULL;
@@ -387,10 +396,9 @@ trash_rename_mkdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
loc_t tmp_loc = {0,};
local = frame->local;
- tmp_str = gf_strdup (local->newpath);
+ tmp_str = strdup (local->newpath);
if (!tmp_str) {
gf_log (this->name, GF_LOG_DEBUG, "out of memory");
- goto out;
}
if ((op_ret == -1) && (op_errno == ENOENT)) {
@@ -413,7 +421,7 @@ trash_rename_mkdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
STACK_WIND_COOKIE (frame, trash_rename_mkdir_cbk,
tmp_path, this->children->xlator,
this->children->xlator->fops->mkdir,
- &tmp_loc, 0755, NULL);
+ &tmp_loc, 0755);
}
goto out;
@@ -430,8 +438,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);
+ free (cookie); /* strdup (dir_name) was sent here :) */
+ free (tmp_str);
return 0;
}
@@ -439,8 +447,8 @@ out:
int32_t
trash_rename_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)
+ struct stat *buf, dict_t *xattr,
+ struct stat *postparent)
{
trash_private_t *priv = NULL;
trash_local_t *local = NULL;
@@ -456,15 +464,15 @@ trash_rename_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
&local->loc, &local->newloc);
return 0;
}
- if ((buf->ia_size == 0) ||
- (buf->ia_size > priv->max_trash_file_size)) {
+ if ((buf->st_size == 0) ||
+ (buf->st_size > priv->max_trash_file_size)) {
/* if the file is too big or zero, just unlink it */
- if (buf->ia_size > priv->max_trash_file_size) {
+ if (buf->st_size > priv->max_trash_file_size) {
gf_log (this->name, GF_LOG_DEBUG,
- "%s: file size too big (%"PRId64") to "
+ "%s: file size too big (%"GF_PRI_SIZET") to "
"move into trash directory",
- local->newloc.path, buf->ia_size);
+ local->newloc.path, buf->st_size);
}
STACK_WIND (frame, trash_common_rename_cbk,
@@ -492,7 +500,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;
@@ -519,10 +529,10 @@ trash_rename (call_frame_t *frame, xlator_t *this, loc_t *oldloc,
return 0;
}
- local = mem_get0 (this->local_pool);
+ local = CALLOC (1, sizeof (trash_local_t));
if (!local) {
gf_log (this->name, GF_LOG_ERROR, "out of memory");
- TRASH_STACK_UNWIND (rename, frame, -1, ENOMEM,
+ TRASH_STACK_UNWIND (frame, -1, ENOMEM,
NULL, NULL, NULL, NULL, NULL);
return 0;
}
@@ -539,8 +549,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);
}
@@ -559,7 +570,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;
@@ -592,10 +605,10 @@ trash_unlink (call_frame_t *frame, xlator_t *this, loc_t *loc)
return 0;
}
- local = mem_get0 (this->local_pool);
+ local = CALLOC (1, sizeof (trash_local_t));
if (!local) {
gf_log (this->name, GF_LOG_DEBUG, "out of memory");
- TRASH_STACK_UNWIND (unlink, frame, -1, ENOMEM, NULL, NULL);
+ TRASH_STACK_UNWIND (frame, -1, ENOMEM, NULL, NULL);
return 0;
}
frame->local = local;
@@ -608,8 +621,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);
}
@@ -625,7 +639,7 @@ trash_unlink (call_frame_t *frame, xlator_t *this, loc_t *loc)
int32_t
trash_truncate_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)
+ struct stat *preparent, struct stat *postparent)
{
/* use this Function when a failure occurs, and
delete the newly created file. */
@@ -650,7 +664,7 @@ int32_t
trash_truncate_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 *iobuf)
+ struct stat *stbuf, struct iobref *iobuf)
{
trash_local_t *local = NULL;
@@ -667,10 +681,10 @@ trash_truncate_readv_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
goto out;
}
- local->fsize = stbuf->ia_size;
+ local->fsize = stbuf->st_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;
@@ -680,7 +694,7 @@ out:
int32_t
trash_truncate_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)
+ struct stat *prebuf, struct stat *postbuf)
{
trash_local_t *local = NULL;
@@ -703,7 +717,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;
}
@@ -743,7 +757,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;
@@ -753,8 +767,8 @@ out:
int32_t
trash_truncate_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)
+ inode_t *inode, struct stat *buf,
+ struct stat *preparent, struct stat *postparent)
{
trash_local_t *local = NULL;
char *tmp_str = NULL;
@@ -767,13 +781,13 @@ trash_truncate_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
if ((op_ret == -1) && (op_errno == ENOENT)) {
//Creating the directory structure here.
- tmp_str = gf_strdup (local->newpath);
+ tmp_str = strdup (local->newpath);
if (!tmp_str) {
gf_log (this->name, GF_LOG_DEBUG, "out of memory");
}
dir_name = dirname (tmp_str);
- tmp_path = gf_strdup (dir_name);
+ tmp_path = strdup (dir_name);
if (!tmp_path) {
gf_log (this->name, GF_LOG_DEBUG, "out of memory");
}
@@ -783,8 +797,8 @@ trash_truncate_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
STACK_WIND_COOKIE (frame, trash_truncate_mkdir_cbk,
tmp_path, FIRST_CHILD(this),
FIRST_CHILD(this)->fops->mkdir,
- &tmp_loc, 0755, NULL);
- GF_FREE (tmp_str);
+ &tmp_loc, 0755);
+ free (tmp_str);
goto out;
}
@@ -816,8 +830,8 @@ out:
int32_t
trash_truncate_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)
+ struct stat *stbuf, struct stat *preparent,
+ struct stat *postparent)
{
trash_local_t *local = NULL;
char *tmp_str = NULL;
@@ -832,14 +846,13 @@ trash_truncate_mkdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
local = frame->local;
if (!local)
- goto out;
+ return 0;
loop_count = local->loop_count;
- tmp_str = gf_strdup (local->newpath);
+ tmp_str = strdup (local->newpath);
if (!tmp_str) {
gf_log (this->name, GF_LOG_DEBUG, "out of memory");
- goto out;
}
if ((op_ret == -1) && (op_errno == ENOENT)) {
@@ -861,7 +874,7 @@ trash_truncate_mkdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
STACK_WIND_COOKIE (frame, trash_truncate_mkdir_cbk,
tmp_path, this->children->xlator,
this->children->xlator->fops->mkdir,
- &tmp_loc, 0755, NULL);
+ &tmp_loc, 0755);
goto out;
}
@@ -870,14 +883,12 @@ trash_truncate_mkdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
dir_name = dirname (tmp_str);
if (strcmp ((char*)cookie, dir_name) == 0) {
flags = O_CREAT|O_EXCL|O_WRONLY;
- ia_prot_t prot = {0, };
//Call create again once directory structure is created.
STACK_WIND (frame, trash_truncate_create_cbk,
FIRST_CHILD(this), FIRST_CHILD(this)->fops->create,
- &local->newloc, flags,
- st_mode_from_ia (prot, local->loc.inode->ia_type),
- local->newfd, NULL);
+ &local->newloc, flags, local->loc.inode->st_mode,
+ local->newfd);
goto out;
}
}
@@ -887,7 +898,6 @@ trash_truncate_mkdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
loop_count = ++local->loop_count;
}
UNLOCK (&frame->lock);
-
tmp_dirname = strchr (tmp_str, '/');
while (tmp_dirname) {
count = tmp_dirname - tmp_str;
@@ -908,11 +918,11 @@ trash_truncate_mkdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
STACK_WIND_COOKIE (frame, trash_truncate_mkdir_cbk, tmp_path,
this->children->xlator,
this->children->xlator->fops->mkdir,
- &tmp_loc, 0755, NULL);
+ &tmp_loc, 0755);
out:
- GF_FREE (cookie); /* strdup (dir_name) was sent here :) */
- GF_FREE (tmp_str);
+ free (cookie); /* strdup (dir_name) was sent here :) */
+ free (tmp_str);
return 0;
}
@@ -920,12 +930,14 @@ out:
int32_t
trash_truncate_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct iatt *buf)
+ int32_t op_ret, int32_t op_errno, struct stat *buf)
{
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;
@@ -936,13 +948,13 @@ trash_truncate_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
"fstat on the file failed: %s",
strerror (op_errno));
- TRASH_STACK_UNWIND (truncate, frame, op_ret, op_errno, buf, NULL);
+ TRASH_STACK_UNWIND (frame, op_ret, op_errno, buf);
return 0;
}
- if ((buf->ia_size == 0) || (buf->ia_size > priv->max_trash_file_size)) {
+ if ((buf->st_size == 0) || (buf->st_size > priv->max_trash_file_size)) {
// If the file is too big, just unlink it.
- if (buf->ia_size > priv->max_trash_file_size)
+ if (buf->st_size > priv->max_trash_file_size)
gf_log (this->name, GF_LOG_DEBUG, "%s: file too big, "
"not moving to trash", local->loc.path);
@@ -957,16 +969,18 @@ 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);
strcat (loc_newname,timestr);
- local->newloc.name = gf_strdup (loc_newname);
- local->newloc.path = gf_strdup (local->newpath);
+ local->newloc.name = strdup (loc_newname);
+ local->newloc.path = 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;
@@ -974,9 +988,8 @@ trash_truncate_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
STACK_WIND (frame, trash_truncate_create_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->create,
- &local->newloc, flags,
- st_mode_from_ia (buf->ia_prot, local->loc.inode->ia_type),
- local->newfd, NULL);
+ &local->newloc, flags, local->loc.inode->st_mode,
+ local->newfd);
return 0;
}
@@ -1020,10 +1033,10 @@ trash_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc,
LOCK_INIT (&frame->lock);
- local = mem_get0 (this->local_pool);
+ local = CALLOC (1, sizeof (trash_local_t));
if (!local) {
gf_log (this->name, GF_LOG_DEBUG, "out of memory");
- TRASH_STACK_UNWIND (truncate, frame, -1, ENOMEM, NULL, NULL);
+ TRASH_STACK_UNWIND (frame, -1, ENOMEM, NULL);
return 0;
}
@@ -1044,7 +1057,7 @@ out:
int32_t
trash_ftruncate_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)
+ struct stat *preparent, struct stat *postparent)
{
trash_local_t *local = NULL;
@@ -1067,7 +1080,7 @@ trash_ftruncate_unlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t
trash_ftruncate_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)
+ struct stat *prebuf, struct stat *postbuf)
{
trash_local_t *local = NULL;
@@ -1085,7 +1098,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;
}
@@ -1101,12 +1114,12 @@ int32_t
trash_ftruncate_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 *iobuf)
+ struct stat *stbuf, struct iobref *iobuf)
{
trash_local_t *local = NULL;
local = frame->local;
- local->fsize = stbuf->ia_size;
+ local->fsize = stbuf->st_size;
if (op_ret == -1) {
STACK_WIND (frame, trash_ftruncate_unlink_cbk,
@@ -1117,7 +1130,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;
}
@@ -1126,8 +1139,8 @@ trash_ftruncate_readv_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t
trash_ftruncate_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)
+ inode_t *inode, struct stat *buf,
+ struct stat *preparent, struct stat *postparent)
{
trash_local_t *local = NULL;
char *tmp_str = NULL;
@@ -1138,13 +1151,13 @@ trash_ftruncate_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
local = frame->local;
if ((op_ret == -1) && (op_errno == ENOENT)) {
- tmp_str = gf_strdup (local->newpath);
+ tmp_str = strdup (local->newpath);
if (!tmp_str) {
gf_log (this->name, GF_LOG_DEBUG, "out of memory");
}
dir_name = dirname (tmp_str);
- tmp_path = gf_strdup (dir_name);
+ tmp_path = strdup (dir_name);
if (!tmp_path) {
gf_log (this->name, GF_LOG_DEBUG, "out of memory");
}
@@ -1154,8 +1167,8 @@ trash_ftruncate_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
STACK_WIND_COOKIE (frame, trash_truncate_mkdir_cbk,
tmp_path, FIRST_CHILD(this),
FIRST_CHILD(this)->fops->mkdir,
- &tmp_loc, 0755, NULL);
- GF_FREE (tmp_str);
+ &tmp_loc, 0755);
+ free (tmp_str);
return 0;
}
@@ -1169,7 +1182,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;
}
@@ -1178,8 +1191,8 @@ trash_ftruncate_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t
trash_ftruncate_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)
+ struct stat *stbuf, struct stat *preparent,
+ struct stat *postparent)
{
trash_local_t *local = NULL;
char *tmp_str = NULL;
@@ -1194,14 +1207,13 @@ trash_ftruncate_mkdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
local = frame->local;
if (!local)
- goto out;
+ return 0;
loop_count = local->loop_count;
- tmp_str = gf_strdup (local->newpath);
+ tmp_str = strdup (local->newpath);
if (!tmp_str) {
gf_log (this->name, GF_LOG_DEBUG, "out of memory");
- goto out;
}
if ((op_ret == -1) && (op_errno == ENOENT)) {
@@ -1223,7 +1235,7 @@ trash_ftruncate_mkdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
STACK_WIND_COOKIE (frame, trash_ftruncate_mkdir_cbk,
tmp_path, this->children->xlator,
this->children->xlator->fops->mkdir,
- &tmp_loc, 0755, NULL);
+ &tmp_loc, 0755);
goto out;
}
@@ -1231,7 +1243,6 @@ trash_ftruncate_mkdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
if (op_ret == 0) {
dir_name = dirname (tmp_str);
if (strcmp ((char*)cookie, dir_name) == 0) {
- ia_prot_t prot = {0, };
flags = O_CREAT|O_EXCL|O_WRONLY;
//Call create again once directory structure is created.
@@ -1239,8 +1250,7 @@ trash_ftruncate_mkdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->create,
&local->newloc, flags,
- st_mode_from_ia (prot, local->loc.inode->ia_type),
- local->newfd, NULL);
+ local->loc.inode->st_mode, local->newfd);
goto out;
}
}
@@ -1270,11 +1280,11 @@ trash_ftruncate_mkdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
STACK_WIND_COOKIE (frame, trash_ftruncate_mkdir_cbk, tmp_path,
this->children->xlator,
this->children->xlator->fops->mkdir,
- &tmp_loc, 0755, NULL);
+ &tmp_loc, 0755);
out:
- GF_FREE (cookie); /* strdup (dir_name) was sent here :) */
- GF_FREE (tmp_str);
+ free (cookie); /* strdup (dir_name) was sent here :) */
+ free (tmp_str);
return 0;
}
@@ -1282,7 +1292,7 @@ out:
int32_t
trash_ftruncate_fstat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct iatt *buf)
+ int32_t op_ret, int32_t op_errno, struct stat *buf)
{
trash_private_t *priv = NULL;
trash_local_t *local = NULL;
@@ -1294,10 +1304,10 @@ trash_ftruncate_fstat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
gf_log (this->name, GF_LOG_DEBUG,
"%s: %s",local->newloc.path, strerror(op_errno));
- TRASH_STACK_UNWIND (ftruncate, frame, -1, op_errno, buf, NULL);
+ TRASH_STACK_UNWIND (frame, -1, op_errno, buf, NULL);
return 0;
}
- if ((buf->ia_size == 0) || (buf->ia_size > priv->max_trash_file_size))
+ if ((buf->st_size == 0) || (buf->st_size > priv->max_trash_file_size))
{
STACK_WIND (frame, trash_common_unwind_buf_cbk,
this->children->xlator,
@@ -1310,8 +1320,7 @@ trash_ftruncate_fstat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
STACK_WIND (frame, trash_ftruncate_create_cbk, FIRST_CHILD(this),
FIRST_CHILD(this)->fops->create, &local->newloc,
( O_CREAT | O_EXCL | O_WRONLY ),
- st_mode_from_ia (buf->ia_prot, local->loc.inode->ia_type),
- local->newfd, NULL);
+ local->loc.inode->st_mode, local->newfd);
return 0;
}
@@ -1323,9 +1332,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;
@@ -1357,14 +1368,17 @@ trash_ftruncate (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset)
return 0;
}
- local = mem_get0 (this->local_pool);
+ local = CALLOC (1, sizeof (trash_local_t));
if (!local) {
gf_log (this->name, GF_LOG_DEBUG, "out of memory");
- TRASH_STACK_UNWIND (ftruncate, frame, -1, ENOMEM, NULL, NULL);
+ TRASH_STACK_UNWIND (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);
@@ -1378,6 +1392,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;
@@ -1395,6 +1410,7 @@ trash_ftruncate (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset)
int32_t
init (xlator_t *this)
{
+ int32_t ret = 0;
data_t *data = NULL;
trash_private_t *_priv = NULL;
trash_elim_pattern_t *trav = NULL;
@@ -1402,7 +1418,6 @@ init (xlator_t *this)
char *strtokptr = NULL;
char *component = NULL;
char trash_dir[PATH_MAX] = {0,};
- uint64_t max_trash_file_size64 = 0;
/* Create .trashcan directory in init */
if (!this->children || this->children->next) {
@@ -1416,7 +1431,7 @@ init (xlator_t *this)
"dangling volume. check volfile ");
}
- _priv = GF_CALLOC (1, sizeof (*_priv), gf_trash_mt_trash_private_t);
+ _priv = CALLOC (1, sizeof (*_priv));
if (!_priv) {
gf_log (this->name, GF_LOG_ERROR, "out of memory");
return -1;
@@ -1424,20 +1439,20 @@ init (xlator_t *this)
data = dict_get (this->options, "trash-dir");
if (!data) {
- gf_log (this->name, GF_LOG_INFO,
+ gf_log (this->name, GF_LOG_NORMAL,
"no option specified for 'trash-dir', "
"using \"/.trashcan/\"");
- _priv->trash_dir = gf_strdup ("/.trashcan");
+ _priv->trash_dir = strdup ("/.trashcan");
} else {
/* Need a path with '/' as the first char, if not
given, append it */
if (data->data[0] == '/') {
- _priv->trash_dir = gf_strdup (data->data);
+ _priv->trash_dir = strdup (data->data);
} else {
/* TODO: Make sure there is no ".." in the path */
strcpy (trash_dir, "/");
strcat (trash_dir, data->data);
- _priv->trash_dir = gf_strdup (trash_dir);
+ _priv->trash_dir = strdup (trash_dir);
}
}
@@ -1446,7 +1461,7 @@ init (xlator_t *this)
gf_log (this->name, GF_LOG_TRACE,
"no option specified for 'eliminate', using NULL");
} else {
- tmp_str = gf_strdup (data->data);
+ tmp_str = strdup (data->data);
if (!tmp_str) {
gf_log (this->name, GF_LOG_DEBUG, "out of memory");
}
@@ -1454,11 +1469,9 @@ init (xlator_t *this)
/* Match Filename to option specified in eliminate. */
component = strtok_r (tmp_str, "|", &strtokptr);
while (component) {
- trav = GF_CALLOC (1, sizeof (*trav),
- gf_trash_mt_trash_elim_pattern_t);
+ trav = CALLOC (1, sizeof (*trav));
if (!trav) {
gf_log (this->name, GF_LOG_DEBUG, "out of memory");
- break;
}
trav->pattern = component;
trav->next = _priv->eliminate;
@@ -1477,27 +1490,18 @@ init (xlator_t *this)
GF_DEFAULT_MAX_FILE_SIZE / GF_UNIT_MB);
_priv->max_trash_file_size = GF_DEFAULT_MAX_FILE_SIZE;
} else {
- (void)gf_string2bytesize (data->data,
- &max_trash_file_size64);
- if( max_trash_file_size64 > GF_ALLOWED_MAX_FILE_SIZE ) {
+ ret = gf_string2bytesize (data->data,
+ &_priv->max_trash_file_size);
+ if( _priv->max_trash_file_size > GF_ALLOWED_MAX_FILE_SIZE ) {
gf_log (this->name, GF_LOG_DEBUG,
"Size specified for max-size(in MB) is too "
"large so using 1GB as max-size (NOT IDEAL)");
_priv->max_trash_file_size = GF_ALLOWED_MAX_FILE_SIZE;
- } else
- _priv->max_trash_file_size = max_trash_file_size64;
+ }
gf_log (this->name, GF_LOG_DEBUG, "%"GF_PRI_SIZET" max-size",
_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;
}
@@ -1508,7 +1512,8 @@ fini (xlator_t *this)
trash_private_t *priv = NULL;
priv = this->private;
- GF_FREE (priv);
+ if (priv)
+ FREE (priv);
return;
}
@@ -1520,6 +1525,9 @@ struct xlator_fops fops = {
.ftruncate = trash_ftruncate,
};
+struct xlator_mops mops = {
+};
+
struct xlator_cbks cbks = {
};
diff --git a/xlators/features/trash/src/trash.h b/xlators/features/trash/src/trash.h
index 9a7c033617d..e1a1c314dc8 100644
--- a/xlators/features/trash/src/trash.h
+++ b/xlators/features/trash/src/trash.h
@@ -1,12 +1,22 @@
/*
- Copyright (c) 2006-2012 Red Hat, Inc. <http://www.redhat.com>
- This file is part of GlusterFS.
+ Copyright (c) 2006-2009 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 General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that 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 __TRASH_H__
#define __TRASH_H__
@@ -49,8 +59,8 @@ struct trash_struct {
char origpath[PATH_MAX];
char newpath[PATH_MAX];
int32_t loop_count;
- struct iatt preparent;
- struct iatt postparent;
+ struct stat preparent;
+ struct stat postparent;
};
typedef struct trash_struct trash_local_t;
@@ -67,11 +77,11 @@ struct trash_priv {
};
typedef struct trash_priv trash_private_t;
-#define TRASH_STACK_UNWIND(op, frame, params ...) do { \
+#define TRASH_STACK_UNWIND(frame, params ...) do { \
trash_local_t *__local = NULL; \
__local = frame->local; \
frame->local = NULL; \
- STACK_UNWIND_STRICT (op, frame, params); \
+ STACK_UNWIND (frame, params); \
trash_local_wipe (__local); \
} while (0)
diff --git a/xlators/lib/src/libxlator.c b/xlators/lib/src/libxlator.c
deleted file mode 100644
index 4e680c510ca..00000000000
--- a/xlators/lib/src/libxlator.c
+++ /dev/null
@@ -1,527 +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 "mem-types.h"
-#include "libxlator.h"
-
-
-int marker_xtime_default_gauge[] = {
- [MCNT_FOUND] = 1,
- [MCNT_NOTFOUND] = -1,
- [MCNT_ENODATA] = -1,
- [MCNT_ENOTCONN] = -1,
- [MCNT_ENOENT] = -1,
- [MCNT_EOTHER] = -1,
-};
-
-int marker_uuid_default_gauge[] = {
- [MCNT_FOUND] = 1,
- [MCNT_NOTFOUND] = 0,
- [MCNT_ENODATA] = 0,
- [MCNT_ENOTCONN] = 0,
- [MCNT_ENOENT] = 0,
- [MCNT_EOTHER] = 0,
-};
-
-static int marker_idx_errno_map[] = {
- [MCNT_FOUND] = EINVAL,
- [MCNT_NOTFOUND] = EINVAL,
- [MCNT_ENOENT] = ENOENT,
- [MCNT_ENOTCONN] = ENOTCONN,
- [MCNT_ENODATA] = ENODATA,
- [MCNT_EOTHER] = EINVAL,
- [MCNT_MAX] = 0,
-};
-
-/*Copy the contents of oldtimebuf to newtimbuf*/
-static void
-update_timebuf (uint32_t *oldtimbuf, uint32_t *newtimebuf)
-{
- newtimebuf[0] = (oldtimbuf[0]);
- newtimebuf[1] = (oldtimbuf[1]);
-}
-
-/* Convert Timebuf in network order to host order */
-static void
-get_hosttime (uint32_t *oldtimbuf, uint32_t *newtimebuf)
-{
- newtimebuf[0] = ntohl (oldtimbuf[0]);
- newtimebuf[1] = ntohl (oldtimbuf[1]);
-}
-
-
-
-/* Match the Incoming trusted.glusterfs.<uuid>.xtime against volume uuid */
-int
-match_uuid_local (const char *name, char *uuid)
-{
- name = strtail ((char *)name, MARKER_XATTR_PREFIX);
- if (!name || name++[0] != '.')
- return -1;
-
- name = strtail ((char *)name, uuid);
- if (!name || strcmp (name, ".xtime") != 0)
- return -1;
-
- return 0;
-}
-
-static void
-marker_local_incr_errcount (xl_marker_local_t *local, int op_errno)
-{
- marker_result_idx_t i = -1;
-
- if (!local)
- return;
-
- switch (op_errno) {
- case ENODATA:
- i = MCNT_ENODATA;
- break;
- case ENOENT:
- i = MCNT_ENOENT;
- break;
- case ENOTCONN:
- i = MCNT_ENOTCONN;
- break;
- default:
- i = MCNT_EOTHER;
- break;
- }
-
- local->count[i]++;
-}
-
-static int
-evaluate_marker_results (int *gauge, int *count)
-{
- int i = 0;
- int op_errno = 0;
- gf_boolean_t sane = _gf_true;
-
- /* check if the policy of the gauge is violated;
- * if yes, try to get the best errno, ie. look
- * for the first position where there is a more
- * specific kind of vioilation than the generic EINVAL
- */
- for (i = 0; i < MCNT_MAX; i++) {
- if (sane) {
- if ((gauge[i] > 0 && count[i] < gauge[i]) ||
- (gauge[i] < 0 && count[i] >= -gauge[i])) {
- sane = _gf_false;
- /* generic action: adopt corresponding errno */
- op_errno = marker_idx_errno_map[i];
- }
- } else {
- /* already insane; trying to get a more informative
- * errno by checking subsequent counters
- */
- if (count[i] > 0)
- op_errno = marker_idx_errno_map[i];
- }
- if (op_errno && op_errno != EINVAL)
- break;
- }
-
- return op_errno;
-}
-
-/* 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)
-
-{
-
- 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;
-
- if (!this || !frame || !frame->local || !cookie) {
- gf_log ("", GF_LOG_DEBUG, "possible NULL deref");
- need_unwind = 1;
- 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;
-
- vol_uuid = local->vol_uuid;
-
- if (op_ret) {
- marker_local_incr_errcount (local, op_errno);
- goto unlock;
- }
-
- if (!gf_asprintf (&marker_xattr, "%s.%s.%s",
- MARKER_XATTR_PREFIX, vol_uuid, XTIME)) {
- op_errno = ENOMEM;
- goto unlock;
- }
-
-
- if (dict_get_ptr (dict, marker_xattr, (void **)&net_timebuf)) {
- gf_log (this->name, GF_LOG_WARNING,
- "Unable to get <uuid>.xtime attr");
- local->count[MCNT_NOTFOUND]++;
- goto unlock;
- }
-
- if (local->count[MCNT_FOUND]) {
- 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 {
- get_hosttime (net_timebuf, local->host_timebuf);
- update_timebuf (net_timebuf, local->net_timebuf);
- local->count[MCNT_FOUND]++;
- }
-
- }
-unlock:
- UNLOCK (&frame->lock);
-
- if (!callcnt) {
- op_ret = 0;
- op_errno = 0;
- need_unwind = 1;
-
- if (local->count[MCNT_FOUND]) {
- if (!dict)
- dict = dict_new();
-
- ret = dict_set_static_bin (dict, marker_xattr,
- (void *)local->net_timebuf, 8);
- if (ret) {
- op_ret = -1;
- op_errno = ENOMEM;
- goto out;
- }
- }
-
- op_errno = evaluate_marker_results (local->gauge, local->count);
- if (op_errno)
- op_ret = -1;
- }
-
-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);
- GF_FREE (local);
- } else if (need_unwind) {
- STACK_UNWIND_STRICT (getxattr, frame, op_ret, op_errno,
- dict, xdata);
- }
-
- 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)
-{
- 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;
-
- if (!this || !frame || !cookie) {
- gf_log ("", GF_LOG_DEBUG, "possible NULL deref");
- need_unwind = 1;
- goto out;
- }
-
- local = frame->local;
-
- if (!local) {
- 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;
-
- if (op_ret) {
- marker_local_incr_errcount (local, op_errno);
- goto unlock;
- }
-
- ret = dict_get_bin (dict, GF_XATTR_MARKER_KEY,
- (void *)&volmark);
- if (ret)
- goto unlock;
-
- if (local->count[MCNT_FOUND]) {
- if ((local->volmark->major != volmark->major) ||
- (local->volmark->minor != volmark->minor)) {
- op_ret = -1;
- op_errno = EINVAL;
- goto unlock;
- }
-
- 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));
- }
-
- } else {
- local->volmark = memdup (volmark, sizeof (*volmark));
- VALIDATE_OR_GOTO (local->volmark, unlock);
- uuid_unparse (volmark->uuid, vol_uuid);
- if (volmark->retval)
- local->retval = volmark->retval;
- local->count[MCNT_FOUND]++;
- }
- }
-unlock:
- UNLOCK (&frame->lock);
-
- if (!callcnt) {
- op_ret = 0;
- op_errno = 0;
- need_unwind = 1;
-
- if (local->count[MCNT_FOUND]) {
- if (!dict)
- dict = dict_new();
-
- if (dict_set_bin (dict, GF_XATTR_MARKER_KEY,
- local->volmark,
- sizeof (struct volume_mark))) {
- op_ret = -1;
- op_errno = ENOMEM;
- }
- }
- op_errno = evaluate_marker_results (local->gauge, local->count);
- if (op_errno)
- op_ret = -1;
- }
-
- 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);
- GF_FREE (local);
- return 0;
- } else if (need_unwind){
- STACK_UNWIND_STRICT (getxattr, frame, op_ret, op_errno,
- dict, xdata);
- }
- return 0;
-}
-
-
-int32_t
-cluster_getmarkerattr (call_frame_t *frame,xlator_t *this, loc_t *loc,
- const char *name, void *xl_local,
- xlator_specf_unwind_t xl_specf_getxattr_unwind,
- xlator_t **sub_volumes, int count, int type,
- int *gauge, char *vol_uuid)
-{
- int i = 0;
- xl_marker_local_t *local = NULL;
-
- VALIDATE_OR_GOTO (frame, err);
- VALIDATE_OR_GOTO (this, err);
- VALIDATE_OR_GOTO (loc, err);
- VALIDATE_OR_GOTO (loc->path, err);
- VALIDATE_OR_GOTO (loc->inode, err);
- VALIDATE_OR_GOTO (name, err);
- VALIDATE_OR_GOTO (xl_specf_getxattr_unwind, err);
-
- local = GF_CALLOC (sizeof (struct marker_str), 1,
- gf_common_mt_libxl_marker_local);
-
- if (!local)
- goto err;
-
- local->xl_local = xl_local;
- local->call_count = count;
- local->xl_specf_unwind = xl_specf_getxattr_unwind;
- local->vol_uuid = vol_uuid;
- memcpy (local->gauge, gauge, sizeof (local->gauge));
-
- frame->local = local;
-
- 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);
- else if (MARKER_XTIME_TYPE == type)
- STACK_WIND (frame, cluster_markerxtime_cbk,
- *(sub_volumes + i),
- (*(sub_volumes + i))->fops->getxattr,
- loc, name, NULL);
- else {
- gf_log (this->name, GF_LOG_WARNING,
- "Unrecognized type (%d) of marker attr "
- "received", type);
- STACK_WIND (frame, default_getxattr_cbk,
- *(sub_volumes + i),
- (*(sub_volumes + i))->fops->getxattr,
- loc, name, NULL);
- break;
- }
- }
-
- return 0;
-err:
- return -1;
-
-}
-
-int
-gf_get_min_stime (xlator_t *this, dict_t *dst, char *key, data_t *value)
-{
- int ret = -1;
- uint32_t *net_timebuf = NULL;
- uint32_t *value_timebuf = NULL;
- uint32_t host_timebuf[2] = {0,};
- uint32_t host_value_timebuf[2] = {0,};
-
- /* stime should be minimum of all the other nodes */
- ret = dict_get_bin (dst, key, (void **)&net_timebuf);
- if (ret < 0) {
- net_timebuf = GF_CALLOC (1, sizeof (int64_t),
- gf_common_mt_char);
- if (!net_timebuf)
- goto out;
-
- ret = dict_set_bin (dst, key, net_timebuf, sizeof (int64_t));
- if (ret < 0) {
- gf_log (this->name, GF_LOG_WARNING,
- "key=%s: dict set failed", key);
- goto error;
- }
- }
-
- value_timebuf = data_to_bin (value);
- if (!value_timebuf) {
- gf_log (this->name, GF_LOG_WARNING,
- "key=%s: getting value of stime failed", key);
- ret = -1;
- goto out;
- }
-
- get_hosttime (value_timebuf, host_value_timebuf);
- get_hosttime (net_timebuf, host_timebuf);
-
- /* can't use 'min()' macro here as we need to compare two fields
- in the array, selectively */
- if ((host_value_timebuf[0] < host_timebuf[0]) ||
- ((host_value_timebuf[0] == host_timebuf[0]) &&
- (host_value_timebuf[1] < host_timebuf[1]))) {
- update_timebuf (value_timebuf, net_timebuf);
- }
-
- ret = 0;
-out:
- return ret;
-error:
- /* To be used only when net_timebuf is not set in the dict */
- if (net_timebuf)
- GF_FREE (net_timebuf);
-
- return ret;
-}
-
-int
-gf_get_max_stime (xlator_t *this, dict_t *dst, char *key, data_t *value)
-{
- int ret = -1;
- uint32_t *net_timebuf = NULL;
- uint32_t *value_timebuf = NULL;
- uint32_t host_timebuf[2] = {0,};
- uint32_t host_value_timebuf[2] = {0,};
-
- /* stime should be maximum of all the other nodes */
- ret = dict_get_bin (dst, key, (void **)&net_timebuf);
- if (ret < 0) {
- net_timebuf = GF_CALLOC (1, sizeof (int64_t),
- gf_common_mt_char);
- if (!net_timebuf)
- goto out;
-
- ret = dict_set_bin (dst, key, net_timebuf, sizeof (int64_t));
- if (ret < 0) {
- gf_log (this->name, GF_LOG_WARNING,
- "key=%s: dict set failed", key);
- goto error;
- }
- }
-
- value_timebuf = data_to_bin (value);
- if (!value_timebuf) {
- gf_log (this->name, GF_LOG_WARNING,
- "key=%s: getting value of stime failed", key);
- ret = -1;
- goto out;
- }
-
- get_hosttime (value_timebuf, host_value_timebuf);
- get_hosttime (net_timebuf, host_timebuf);
-
- /* can't use 'max()' macro here as we need to compare two fields
- in the array, selectively */
- if ((host_value_timebuf[0] > host_timebuf[0]) ||
- ((host_value_timebuf[0] == host_timebuf[0]) &&
- (host_value_timebuf[1] > host_timebuf[1]))) {
- update_timebuf (value_timebuf, net_timebuf);
- }
-
- ret = 0;
-out:
- return ret;
-error:
- /* To be used only when net_timebuf is not set in the dict */
- if (net_timebuf)
- GF_FREE (net_timebuf);
-
- return ret;
-}
diff --git a/xlators/lib/src/libxlator.h b/xlators/lib/src/libxlator.h
deleted file mode 100644
index 175d3141d45..00000000000
--- a/xlators/lib/src/libxlator.h
+++ /dev/null
@@ -1,157 +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 _LIBXLATOR_H
-#define _LIBXLATOR_H
-
-
-#ifndef _CONFIG_H
-#define _CONFIG_H
-#include "config.h"
-#endif
-
-#include "xlator.h"
-#include "logging.h"
-#include "defaults.h"
-#include "common-utils.h"
-#include "compat.h"
-#include "compat-errno.h"
-
-
-#define MARKER_XATTR_PREFIX "trusted.glusterfs"
-#define XTIME "xtime"
-#define VOLUME_MARK "volume-mark"
-#define GF_XATTR_MARKER_KEY MARKER_XATTR_PREFIX "." VOLUME_MARK
-#define UUID_SIZE 36
-#define MARKER_UUID_TYPE 1
-#define MARKER_XTIME_TYPE 2
-#define GF_XATTR_QUOTA_SIZE_KEY "trusted.glusterfs.quota.size"
-#define GF_XATTR_QUOTA_LIMIT_LIST "trusted.limit.list"
-
-
-typedef int32_t (*xlator_specf_unwind_t) (call_frame_t *frame,
- int op_ret, int op_errno,
- dict_t *dict, dict_t *xdata);
-
-
-struct volume_mark {
- uint8_t major;
- uint8_t minor;
- uint8_t uuid[16];
- uint8_t retval;
- uint32_t sec;
- uint32_t usec;
-}__attribute__ ((__packed__));
-
-
-/*
- * The enumerated type here
- * is used to index two kind
- * of integer arrays:
- * - gauges
- * - counters
-
- * A counter is used internally,
- * in getxattr callbacks, to count
- * the results, categorized as
- * the enum names suggest. So values
- * in the counter are always non-negative.
-
- * Gauges are part of the API.
- * The caller passes one to the
- * top-level aggregator function,
- * cluster_getmarkerattr(). The gauge
- * defines an evaluation policy for the
- * counter. That is, at the
- * end of the aggregation process
- * the gauge is matched against the
- * counter, and the policy
- * represented by the gauge decides
- * whether to return with success or failure,
- * and in latter case, what particular failure
- * case (errno).
-
- * The rules are the following: for some index i,
- * - if gauge[i] == 0, no requirement is set
- * against counter[i];
- * - if gauge[i] > 0, counter[i] >= gauge[i]
- * is required;
- * - if gauge[i] < 0, counter[i] < |gauge[i]|
- * is required.
-
- * If the requirement is not met, then i is mapped
- * to the respective errno (MCNT_ENOENT -> ENOENT),
- * or in lack of that, EINVAL.
-
- * Cf. evaluate_marker_results() and marker_idx_errno_map[]
- * in libxlator.c
-
- * We provide two default gauges, one inteded for xtime
- * aggregation, other for volume mark aggregation. The
- * policies they represent agree with the hard-coded
- * one prior to gauges. Cf. marker_xtime_default_gauge
- * and marker_uuid_default_gauge in libxlator.c
- */
-
-typedef enum {
- MCNT_FOUND,
- MCNT_NOTFOUND,
- MCNT_ENODATA,
- MCNT_ENOTCONN,
- MCNT_ENOENT,
- MCNT_EOTHER,
- MCNT_MAX
-} marker_result_idx_t;
-
-extern int marker_xtime_default_gauge[];
-extern int marker_uuid_default_gauge[];
-
-struct marker_str {
- struct volume_mark *volmark;
- data_t *data;
-
- uint32_t host_timebuf[2];
- uint32_t net_timebuf[2];
- int32_t call_count;
- int gauge[MCNT_MAX];
- int count[MCNT_MAX];
-
- xlator_specf_unwind_t xl_specf_unwind;
- void *xl_local;
- char *vol_uuid;
- uint8_t retval;
-};
-
-typedef struct marker_str xl_marker_local_t;
-
-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);
-
-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);
-
-int32_t
-cluster_getmarkerattr (call_frame_t *frame,xlator_t *this, loc_t *loc,
- const char *name, void *xl_local,
- xlator_specf_unwind_t xl_specf_getxattr_unwind,
- xlator_t **sub_volumes, int count, int type,
- int *gauge, char *vol_uuid);
-
-int
-match_uuid_local (const char *name, char *uuid);
-
-int
-gf_get_min_stime (xlator_t *this, dict_t *dst, char *key, data_t *value);
-
-int
-gf_get_max_stime (xlator_t *this, dict_t *dst, char *key, data_t *value);
-
-#endif /* !_LIBXLATOR_H */
diff --git a/xlators/meta/src/Makefile.am b/xlators/meta/src/Makefile.am
index b705e86b60a..385ff553f59 100644
--- a/xlators/meta/src/Makefile.am
+++ b/xlators/meta/src/Makefile.am
@@ -1,43 +1,10 @@
-xlator_LTLIBRARIES = meta.la
-xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator
+xlator_PROGRAMS = meta.so
+xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/
-meta_la_LDFLAGS = -module -avoid-version
+meta_so_SOURCES = meta.c tree.c misc.c view.c
+noinst_HEADERS = meta.h tree.h misc.h view.h
-meta_la_SOURCES = meta.c meta-helpers.c meta-defaults.c \
- root-dir.c \
- graphs-dir.c \
- frames-file.c \
- graph-dir.c \
- active-link.c \
- xlator-dir.c \
- top-link.c \
- logging-dir.c \
- logfile-link.c \
- loglevel-file.c \
- process_uuid-file.c \
- volfile-file.c \
- view-dir.c \
- subvolumes-dir.c \
- subvolume-link.c \
- type-file.c \
- version-file.c \
- options-dir.c \
- option-file.c \
- cmdline-file.c \
- name-file.c \
- private-file.c \
- history-file.c \
- mallinfo-file.c \
- meminfo-file.c \
- measure-file.c \
- profile-file.c
+AM_CFLAGS = -fPIC -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -Wall \
+ -I$(top_srcdir)/libglusterfs/src -shared -nostartfiles
-meta_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la
-
-noinst_HEADERS = meta.h meta-hooks.h meta-mem-types.h
-
-AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src
-
-AM_CFLAGS = -Wall $(GF_CFLAGS)
-
-CLEANFILES =
+CLEANFILES =
diff --git a/xlators/meta/src/active-link.c b/xlators/meta/src/active-link.c
deleted file mode 100644
index 99d38597bdf..00000000000
--- a/xlators/meta/src/active-link.c
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- Copyright (c) 2014 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 "xlator.h"
-#include "defaults.h"
-
-#include "meta-mem-types.h"
-#include "meta.h"
-
-
-static int
-active_link_fill (xlator_t *this, inode_t *inode, strfd_t *strfd)
-{
- strprintf (strfd, "%s", this->ctx->active->graph_uuid);
-
- return 0;
-}
-
-
-struct meta_ops active_link_ops = {
- .link_fill = active_link_fill
-};
-
-
-int
-meta_active_link_hook (call_frame_t *frame, xlator_t *this, loc_t *loc,
- dict_t *xdata)
-{
- meta_ops_set (loc->inode, this, &active_link_ops);
-
- return 0;
-}
diff --git a/xlators/meta/src/cmdline-file.c b/xlators/meta/src/cmdline-file.c
deleted file mode 100644
index 88411f2629b..00000000000
--- a/xlators/meta/src/cmdline-file.c
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- Copyright (c) 2014 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 "xlator.h"
-#include "defaults.h"
-
-#include "meta-mem-types.h"
-#include "meta.h"
-#include "strfd.h"
-#include "globals.h"
-#include "lkowner.h"
-
-
-static int
-cmdline_file_fill (xlator_t *this, inode_t *file, strfd_t *strfd)
-{
- if (this->ctx->cmdlinestr)
- strprintf (strfd, "{ \n \"Cmdlinestr\": \"%s\"\n}",
- this->ctx->cmdlinestr);
- return strfd->size;
-}
-
-
-static struct meta_ops cmdline_file_ops = {
- .file_fill = cmdline_file_fill,
-};
-
-
-int
-meta_cmdline_file_hook (call_frame_t *frame, xlator_t *this, loc_t *loc,
- dict_t *xdata)
-{
- meta_ops_set (loc->inode, this, &cmdline_file_ops);
-
- return 0;
-}
diff --git a/xlators/meta/src/frames-file.c b/xlators/meta/src/frames-file.c
deleted file mode 100644
index 0e9777c9da2..00000000000
--- a/xlators/meta/src/frames-file.c
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- Copyright (c) 2014 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 "xlator.h"
-#include "defaults.h"
-
-#include "meta-mem-types.h"
-#include "meta.h"
-#include "strfd.h"
-#include "globals.h"
-#include "lkowner.h"
-
-static int
-frames_file_fill (xlator_t *this, inode_t *file, strfd_t *strfd)
-{
- struct call_pool *pool = NULL;
- call_stack_t *stack = NULL;
- call_frame_t *frame = NULL;
- int i = 0;
- int j = 1;
-
- if (!this || !file || !strfd)
- return -1;
-
- pool = this->ctx->pool;
-
- LOCK (&pool->lock);
- {
- strprintf (strfd, "{ \n\t\"Stack\": [\n");
- list_for_each_entry (stack, &pool->all_frames, all_frames) {
- strprintf (strfd, "\t {\n");
- strprintf (strfd, "\t\t\"Number\": %d,\n", ++i);
- strprintf (strfd, "\t\t\"Frame\": [\n");
- j = 1;
- for (frame = &stack->frames; frame;
- frame = frame->next) {
- strprintf (strfd, "\t\t {\n");
- strprintf (strfd, "\t\t\t\"Number\": %d,\n",
- j++);
- strprintf (strfd,
- "\t\t\t\"Xlator\": \"%s\",\n",
- frame->this->name);
- if (frame->begin.tv_sec)
- strprintf (strfd,
- "\t\t\t\"Creation_time\": %d.%d,\n",
- (int)frame->begin.tv_sec,
- (int)frame->begin.tv_usec);
- strprintf (strfd, " \t\t\t\"Refcount\": %d,\n",
- frame->ref_count);
- if (frame->parent)
- strprintf (strfd, "\t\t\t\"Parent\": \"%s\",\n",
- frame->parent->this->name);
- if (frame->wind_from)
- strprintf (strfd, "\t\t\t\"Wind_from\": \"%s\",\n",
- frame->wind_from);
- if (frame->wind_to)
- strprintf (strfd, "\t\t\t\"Wind_to\": \"%s\",\n",
- frame->wind_to);
- if (frame->unwind_from)
- strprintf (strfd, "\t\t\t\"Unwind_from\": \"%s\",\n",
- frame->unwind_from);
- if (frame->unwind_to)
- strprintf (strfd, "\t\t\t\"Unwind_to\": \"%s\",\n",
- frame->unwind_to);
- strprintf (strfd, "\t\t\t\"Complete\": %d\n",
- frame->complete);
- if (frame->next == NULL)
- strprintf (strfd, "\t\t }\n");
- else
- strprintf (strfd, "\t\t },\n");
- }
- strprintf (strfd, "\t\t],\n");
- strprintf (strfd, "\t\t\"Unique\": %"PRId64",\n",
- stack->unique);
- strprintf (strfd, "\t\t\"Type\": \"%s\",\n",
- gf_fop_list[stack->op]);
- strprintf (strfd, "\t\t\"UID\": %d,\n",
- stack->uid);
- strprintf (strfd, "\t\t\"GID\": %d,\n",
- stack->gid);
- strprintf (strfd, "\t\t\"LK_owner\": \"%s\"\n",
- lkowner_utoa (&stack->lk_owner));
- if (i == (int)pool->cnt)
- strprintf (strfd, "\t }\n");
- else
- strprintf (strfd, "\t },\n");
- }
- strprintf (strfd, "\t],\n");
- strprintf (strfd, "\t\"Call_Count\": %d\n",
- (int)pool->cnt);
- strprintf (strfd, "}");
- }
- UNLOCK (&pool->lock);
-
- return strfd->size;
-}
-
-
-static struct meta_ops frames_file_ops = {
- .file_fill = frames_file_fill,
-};
-
-
-int
-meta_frames_file_hook (call_frame_t *frame, xlator_t *this, loc_t *loc,
- dict_t *xdata)
-{
- meta_ops_set (loc->inode, this, &frames_file_ops);
- return 0;
-}
diff --git a/xlators/meta/src/graph-dir.c b/xlators/meta/src/graph-dir.c
deleted file mode 100644
index 3cd6b482e74..00000000000
--- a/xlators/meta/src/graph-dir.c
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- Copyright (c) 2014 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 "xlator.h"
-#include "defaults.h"
-
-#include "meta-mem-types.h"
-#include "meta.h"
-#include "meta-hooks.h"
-
-
-static struct meta_dirent graph_dir_dirents[] = {
- DOT_DOTDOT,
-
- { .name = "top",
- .type = IA_IFLNK,
- .hook = meta_top_link_hook,
- },
- { .name = "volfile",
- .type = IA_IFREG,
- .hook = meta_volfile_file_hook,
- },
- { .name = NULL }
-};
-
-
-static int
-graph_dir_fill (xlator_t *this, inode_t *inode, struct meta_dirent **dp)
-{
- struct meta_dirent *dirents = NULL;
- glusterfs_graph_t *graph = NULL;
- int i = 0;
- int count = 0;
- xlator_t *xl = NULL;
-
- graph = meta_ctx_get (inode, this);
-
- for (xl = graph->first; xl; xl = xl->next)
- count++;
-
- dirents = GF_CALLOC (sizeof (*dirents), count, gf_meta_mt_dirents_t);
- if (!dirents)
- return -1;
-
- i = 0;
- for (xl = graph->first; xl; xl = xl->next) {
- dirents[i].name = gf_strdup (xl->name);
- dirents[i].type = IA_IFDIR;
- dirents[i].hook = meta_xlator_dir_hook;
- i++;
- }
-
- *dp = dirents;
- return i;
-}
-
-
-struct meta_ops graph_dir_ops = {
- .fixed_dirents = graph_dir_dirents,
- .dir_fill = graph_dir_fill,
-};
-
-
-static glusterfs_graph_t *
-glusterfs_graph_lookup (xlator_t *this, const char *graph_uuid)
-{
- glusterfs_graph_t *graph = NULL;
- glusterfs_graph_t *tmp = NULL;
-
- list_for_each_entry (tmp, &this->ctx->graphs, list) {
- if (strcmp (graph_uuid, tmp->graph_uuid) == 0) {
- graph = tmp;
- break;
- }
- }
-
- return graph;
-}
-
-
-int
-meta_graph_dir_hook (call_frame_t *frame, xlator_t *this, loc_t *loc,
- dict_t *xdata)
-{
- glusterfs_graph_t *graph = NULL;
-
- graph = glusterfs_graph_lookup (this, loc->name);
-
- meta_ops_set (loc->inode, this, &graph_dir_ops);
-
- meta_ctx_set (loc->inode, this, (void *) graph);
-
- return 0;
-}
diff --git a/xlators/meta/src/graphs-dir.c b/xlators/meta/src/graphs-dir.c
deleted file mode 100644
index 4a538fb6176..00000000000
--- a/xlators/meta/src/graphs-dir.c
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- Copyright (c) 2014 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 "xlator.h"
-#include "defaults.h"
-
-#include "meta-mem-types.h"
-#include "meta.h"
-#include "meta-hooks.h"
-
-
-static struct meta_dirent graphs_dir_dirents[] = {
- DOT_DOTDOT,
-
- { .name = "active",
- .type = IA_IFLNK,
- .hook = meta_active_link_hook,
- },
- { .name = NULL }
-};
-
-
-static int
-graphs_dir_fill (xlator_t *this, inode_t *dir, struct meta_dirent **dp)
-{
- glusterfs_graph_t *graph = NULL;
- int graphs_count = 0;
- int i = 0;
- struct meta_dirent *dirents = NULL;
-
- list_for_each_entry (graph, &this->ctx->graphs, list) {
- graphs_count++;
- }
-
- dirents = GF_CALLOC (sizeof (*dirents), graphs_count + 3,
- gf_meta_mt_dirents_t);
- if (!dirents)
- return -1;
-
- i = 0;
- list_for_each_entry (graph, &this->ctx->graphs, list) {
- dirents[i].name = gf_strdup (graph->graph_uuid);
- dirents[i].type = IA_IFDIR;
- dirents[i].hook = meta_graph_dir_hook;
- i++;
- }
-
- *dp = dirents;
-
- return i;
-}
-
-
-struct meta_ops graphs_dir_ops = {
- .fixed_dirents = graphs_dir_dirents,
- .dir_fill = graphs_dir_fill
-};
-
-
-int
-meta_graphs_dir_hook (call_frame_t *frame, xlator_t *this, loc_t *loc,
- dict_t *xdata)
-{
- meta_ops_set (loc->inode, this, &graphs_dir_ops);
-
- return 0;
-}
diff --git a/xlators/meta/src/history-file.c b/xlators/meta/src/history-file.c
deleted file mode 100644
index d88040fe58f..00000000000
--- a/xlators/meta/src/history-file.c
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- Copyright (c) 2014 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 "xlator.h"
-#include "defaults.h"
-
-#include "meta-mem-types.h"
-#include "meta.h"
-#include "strfd.h"
-#include "statedump.h"
-
-
-static int
-history_file_fill (xlator_t *this, inode_t *file, strfd_t *strfd)
-{
- xlator_t *xl = NULL;
-
- xl = meta_ctx_get (file, this);
-
- gf_proc_dump_xlator_history (xl, strfd);
-
- return strfd->size;
-}
-
-
-static struct meta_ops history_file_ops = {
- .file_fill = history_file_fill,
-};
-
-
-int
-meta_history_file_hook (call_frame_t *frame, xlator_t *this, loc_t *loc,
- dict_t *xdata)
-{
- meta_ops_set (loc->inode, this, &history_file_ops);
-
- meta_ctx_set (loc->inode, this, meta_ctx_get (loc->parent, this));
-
- return 0;
-}
diff --git a/xlators/meta/src/logfile-link.c b/xlators/meta/src/logfile-link.c
deleted file mode 100644
index 435cab80c33..00000000000
--- a/xlators/meta/src/logfile-link.c
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- Copyright (c) 2014 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 "xlator.h"
-#include "defaults.h"
-
-#include "meta-mem-types.h"
-#include "meta.h"
-
-
-static int
-logfile_link_fill (xlator_t *this, inode_t *inode, strfd_t *strfd)
-{
- strprintf (strfd, "%s", this->ctx->log.filename);
-
- return 0;
-}
-
-
-struct meta_ops logfile_link_ops = {
- .link_fill = logfile_link_fill
-};
-
-
-int
-meta_logfile_link_hook (call_frame_t *frame, xlator_t *this, loc_t *loc,
- dict_t *xdata)
-{
- meta_ops_set (loc->inode, this, &logfile_link_ops);
-
- return 0;
-}
diff --git a/xlators/meta/src/logging-dir.c b/xlators/meta/src/logging-dir.c
deleted file mode 100644
index 783d38e8e12..00000000000
--- a/xlators/meta/src/logging-dir.c
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- Copyright (c) 2014 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 "xlator.h"
-#include "defaults.h"
-
-#include "meta-mem-types.h"
-#include "meta.h"
-#include "meta-hooks.h"
-
-
-static struct meta_dirent logging_dir_dirents[] = {
- DOT_DOTDOT,
-
- { .name = "logfile",
- .type = IA_IFLNK,
- .hook = meta_logfile_link_hook,
- },
- { .name = "loglevel",
- .type = IA_IFREG,
- .hook = meta_loglevel_file_hook,
- },
- { .name = NULL }
-};
-
-
-struct meta_ops logging_dir_ops = {
- .fixed_dirents = logging_dir_dirents,
-};
-
-
-int
-meta_logging_dir_hook (call_frame_t *frame, xlator_t *this, loc_t *loc,
- dict_t *xdata)
-{
- meta_ops_set (loc->inode, this, &logging_dir_ops);
-
- return 0;
-}
diff --git a/xlators/meta/src/loglevel-file.c b/xlators/meta/src/loglevel-file.c
deleted file mode 100644
index 6b00d123a2c..00000000000
--- a/xlators/meta/src/loglevel-file.c
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- Copyright (c) 2014 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 "xlator.h"
-#include "defaults.h"
-
-#include "meta-mem-types.h"
-#include "meta.h"
-#include "strfd.h"
-
-
-static int
-loglevel_file_fill (xlator_t *this, inode_t *file, strfd_t *strfd)
-{
- strprintf (strfd, "%d\n", this->ctx->log.loglevel);
-
- return strfd->size;
-}
-
-
-static int
-loglevel_file_write (xlator_t *this, fd_t *fd, struct iovec *iov, int count)
-{
- long int level = -1;
-
- level = strtol (iov[0].iov_base, NULL, 0);
- if (level >= GF_LOG_NONE && level <= GF_LOG_TRACE)
- gf_log_set_loglevel (level);
-
- return iov_length (iov, count);
-}
-
-
-static struct meta_ops loglevel_file_ops = {
- .file_fill = loglevel_file_fill,
- .file_write = loglevel_file_write,
-};
-
-
-int
-meta_loglevel_file_hook (call_frame_t *frame, xlator_t *this, loc_t *loc,
- dict_t *xdata)
-{
- meta_ops_set (loc->inode, this, &loglevel_file_ops);
-
- return 0;
-}
diff --git a/xlators/meta/src/mallinfo-file.c b/xlators/meta/src/mallinfo-file.c
deleted file mode 100644
index 38589f515ff..00000000000
--- a/xlators/meta/src/mallinfo-file.c
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- Copyright (c) 2014 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 "xlator.h"
-#include "defaults.h"
-
-#include "meta-mem-types.h"
-#include "meta.h"
-#include "statedump.h"
-
-
-static int
-mallinfo_file_fill (xlator_t *this, inode_t *file, strfd_t *strfd)
-{
- gf_proc_dump_mallinfo (strfd);
- return strfd->size;
-}
-
-
-static struct meta_ops mallinfo_file_ops = {
- .file_fill = mallinfo_file_fill,
-};
-
-
-int
-meta_mallinfo_file_hook (call_frame_t *frame, xlator_t *this, loc_t *loc,
- dict_t *xdata)
-{
- meta_ops_set (loc->inode, this, &mallinfo_file_ops);
-
- return 0;
-}
diff --git a/xlators/meta/src/measure-file.c b/xlators/meta/src/measure-file.c
deleted file mode 100644
index e4498ab092e..00000000000
--- a/xlators/meta/src/measure-file.c
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- Copyright (c) 2014 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 "xlator.h"
-#include "defaults.h"
-
-#include "meta-mem-types.h"
-#include "meta.h"
-#include "strfd.h"
-
-
-static int
-measure_file_fill (xlator_t *this, inode_t *file, strfd_t *strfd)
-{
- strprintf (strfd, "%d\n", this->ctx->measure_latency);
-
- return strfd->size;
-}
-
-
-static int
-measure_file_write (xlator_t *this, fd_t *fd, struct iovec *iov, int count)
-{
- long int num = -1;
-
- num = strtol (iov[0].iov_base, NULL, 0);
- this->ctx->measure_latency = !!num;
-
- return iov_length (iov, count);
-}
-
-static struct meta_ops measure_file_ops = {
- .file_fill = measure_file_fill,
- .file_write = measure_file_write,
-};
-
-
-int
-meta_measure_file_hook (call_frame_t *frame, xlator_t *this, loc_t *loc,
- dict_t *xdata)
-{
- meta_ops_set (loc->inode, this, &measure_file_ops);
-
- return 0;
-}
diff --git a/xlators/meta/src/meminfo-file.c b/xlators/meta/src/meminfo-file.c
deleted file mode 100644
index 807446cfdc4..00000000000
--- a/xlators/meta/src/meminfo-file.c
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- Copyright (c) 2014 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 "xlator.h"
-#include "defaults.h"
-
-#include "meta-mem-types.h"
-#include "meta.h"
-#include "strfd.h"
-#include "statedump.h"
-
-
-static int
-meminfo_file_fill (xlator_t *this, inode_t *file, strfd_t *strfd)
-{
- xlator_t *xl = NULL;
-
- xl = meta_ctx_get (file, this);
-
- gf_proc_dump_xlator_meminfo (xl, strfd);
-
- return strfd->size;
-}
-
-
-static struct meta_ops meminfo_file_ops = {
- .file_fill = meminfo_file_fill,
-};
-
-
-int
-meta_meminfo_file_hook (call_frame_t *frame, xlator_t *this, loc_t *loc,
- dict_t *xdata)
-{
- meta_ops_set (loc->inode, this, &meminfo_file_ops);
-
- meta_ctx_set (loc->inode, this, meta_ctx_get (loc->parent, this));
-
- return 0;
-}
diff --git a/xlators/meta/src/meta-defaults.c b/xlators/meta/src/meta-defaults.c
deleted file mode 100644
index c34055bb221..00000000000
--- a/xlators/meta/src/meta-defaults.c
+++ /dev/null
@@ -1,641 +0,0 @@
-/*
- Copyright (c) 2014 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 "xlator.h"
-#include "defaults.h"
-
-#include "meta-mem-types.h"
-#include "meta.h"
-
-#include "compat-errno.h"
-
-int
-meta_default_fgetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
- const char *name, dict_t *xdata)
-{
- return default_fgetxattr_failure_cbk (frame, EPERM);
-}
-
-int
-meta_default_fsetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
- dict_t *dict, int32_t flags, dict_t *xdata)
-{
- return default_fsetxattr_failure_cbk (frame, EPERM);
-}
-
-int
-meta_default_setxattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
- dict_t *dict, int32_t flags, dict_t *xdata)
-{
- return default_setxattr_failure_cbk (frame, EPERM);
-}
-
-int
-meta_default_statfs (call_frame_t *frame, xlator_t *this, loc_t *loc,
- dict_t *xdata)
-{
- return default_statfs_failure_cbk (frame, EPERM);
-}
-
-int
-meta_default_fsyncdir (call_frame_t *frame, xlator_t *this, fd_t *fd,
- int32_t flags, dict_t *xdata)
-{
- return default_fsyncdir_failure_cbk (frame, EPERM);
-}
-
-int
-meta_default_opendir (call_frame_t *frame, xlator_t *this, loc_t *loc,
- fd_t *fd, dict_t *xdata)
-{
- META_STACK_UNWIND (opendir, frame, 0, 0, fd, xdata);
- return 0;
-}
-
-int
-meta_default_fstat (call_frame_t *frame, xlator_t *this, fd_t *fd,
- dict_t *xdata)
-{
- struct iatt iatt = { };
-
- meta_iatt_fill (&iatt, fd->inode, fd->inode->ia_type);
-
- META_STACK_UNWIND (fstat, frame, 0, 0, &iatt, xdata);
-
- return 0;
-}
-
-int
-meta_default_fsync (call_frame_t *frame, xlator_t *this, fd_t *fd,
- int32_t flags, dict_t *xdata)
-{
- return default_fsync_failure_cbk (frame, EPERM);
-}
-
-int
-meta_default_flush (call_frame_t *frame, xlator_t *this, fd_t *fd,
- dict_t *xdata)
-{
- META_STACK_UNWIND (flush, frame, 0, 0, xdata);
- return 0;
-}
-
-int
-meta_default_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 meta_ops *ops = NULL;
- int ret = 0;
- struct iatt dummy = { };
-
- ops = meta_ops_get (fd->inode, this);
- if (!ops)
- goto err;
-
- if (!ops->file_write)
- goto err;
-
- ret = ops->file_write (this, fd, vector, count);
-
- META_STACK_UNWIND (writev, frame, (ret >= 0 ? ret : -1), (ret < 0 ? -ret : 0),
- &dummy, &dummy, xdata);
- return 0;
-err:
- return default_writev_failure_cbk (frame, EPERM);
-}
-
-int
-meta_default_readv (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
- off_t offset, uint32_t flags, dict_t *xdata)
-{
- meta_fd_t *meta_fd = NULL;
- struct iovec iov = {};
- struct iobuf *iobuf = NULL;
- struct iobref *iobref = NULL;
- off_t copy_offset = 0;
- size_t copy_size = 0;
- struct iatt iatt = {};
-
-
- meta_fd = meta_fd_get (fd, this);
- if (!meta_fd)
- return default_readv_failure_cbk (frame, ENODATA);
-
- if (!meta_fd->size)
- meta_file_fill (this, fd);
-
- iobuf = iobuf_get2 (this->ctx->iobuf_pool, size);
- if (!iobuf)
- return default_readv_failure_cbk (frame, ENOMEM);
-
- iobref = iobref_new ();
- if (!iobref) {
- iobuf_unref (iobuf);
- return default_readv_failure_cbk (frame, ENOMEM);
- }
-
- if (iobref_add (iobref, iobuf) != 0) {
- iobref_unref (iobref);
- iobuf_unref (iobuf);
- return default_readv_failure_cbk (frame, ENOMEM);
- }
-
- iov.iov_base = iobuf_ptr (iobuf);
-
- copy_offset = min (meta_fd->size, offset);
- copy_size = min (size, (meta_fd->size - copy_offset));
-
- if (copy_size)
- memcpy (iov.iov_base, meta_fd->data + copy_offset, copy_size);
- iov.iov_len = copy_size;
-
- META_STACK_UNWIND (readv, frame, copy_size, 0, &iov, 1, &iatt, iobref, 0);
-
- return 0;
-}
-
-
-int
-meta_default_open (call_frame_t *frame, xlator_t *this, loc_t *loc,
- int32_t flags, fd_t *fd, dict_t *xdata)
-{
- dict_t *xdata_rsp = NULL;
-
- xdata_rsp = meta_direct_io_mode (xdata, frame);
-
- META_STACK_UNWIND (open, frame, 0, 0, fd, xdata_rsp);
-
- return 0;
-}
-
-int
-meta_default_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)
-{
- return default_create_failure_cbk (frame, EPERM);
-}
-
-int
-meta_default_link (call_frame_t *frame, xlator_t *this, loc_t *oldloc,
- loc_t *newloc, dict_t *xdata)
-{
- return default_link_failure_cbk (frame, EPERM);
-}
-
-int
-meta_default_rename (call_frame_t *frame, xlator_t *this, loc_t *oldloc,
- loc_t *newloc, dict_t *xdata)
-{
- return default_rename_failure_cbk (frame, EPERM);
-}
-
-int
-meta_default_symlink (call_frame_t *frame, xlator_t *this, const char *linkpath,
- loc_t *loc, mode_t umask, dict_t *xdata)
-{
- return default_symlink_failure_cbk (frame, EPERM);
-}
-
-int
-meta_default_rmdir (call_frame_t *frame, xlator_t *this, loc_t *loc, int flags,
- dict_t *xdata)
-{
- return default_rmdir_failure_cbk (frame, EPERM);
-}
-
-int
-meta_default_unlink (call_frame_t *frame, xlator_t *this, loc_t *loc, int xflag,
- dict_t *xdata)
-{
- return default_unlink_failure_cbk (frame, EPERM);
-}
-
-int
-meta_default_mkdir (call_frame_t *frame, xlator_t *this, loc_t *loc,
- mode_t mode, mode_t umask, dict_t *xdata)
-{
- return default_mkdir_failure_cbk (frame, EPERM);
-}
-
-int
-meta_default_mknod (call_frame_t *frame, xlator_t *this, loc_t *loc,
- mode_t mode, dev_t rdev, mode_t umask, dict_t *xdata)
-{
- return default_mknod_failure_cbk (frame, EPERM);
-}
-
-int
-meta_default_readlink (call_frame_t *frame, xlator_t *this, loc_t *loc,
- size_t size, dict_t *xdata)
-{
- struct meta_ops *ops = NULL;
- strfd_t *strfd = NULL;
- struct iatt iatt = { };
-
- ops = meta_ops_get (loc->inode, this);
- if (!ops->link_fill) {
- META_STACK_UNWIND (readlink, frame, -1, EPERM, 0, 0, 0);
- return 0;
- }
-
- strfd = strfd_open ();
- if (!strfd) {
- META_STACK_UNWIND (readlink, frame, -1, ENOMEM, 0, 0, 0);
- return 0;
- }
-
- ops->link_fill (this, loc->inode, strfd);
-
- meta_iatt_fill (&iatt, loc->inode, IA_IFLNK);
-
- if (strfd->data)
- META_STACK_UNWIND (readlink, frame, strlen (strfd->data), 0,
- strfd->data, &iatt, xdata);
- else
- META_STACK_UNWIND (readlink, frame, -1, ENODATA, 0, 0, 0);
-
- strfd_close (strfd);
-
- return 0;
-}
-
-int
-meta_default_access (call_frame_t *frame, xlator_t *this, loc_t *loc,
- int32_t mask, dict_t *xdata)
-{
- return default_access_failure_cbk (frame, EPERM);
-}
-
-int
-meta_default_ftruncate (call_frame_t *frame, xlator_t *this, fd_t *fd,
- off_t offset, dict_t *xdata)
-{
- struct iatt iatt = { };
-
- meta_iatt_fill (&iatt, fd->inode, IA_IFREG);
-
- META_STACK_UNWIND (ftruncate, frame, 0, 0, &iatt, &iatt, xdata);
-
- return 0;
-}
-
-int
-meta_default_getxattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
- const char *name, dict_t *xdata)
-{
- return default_getxattr_failure_cbk (frame, EPERM);
-}
-
-int
-meta_default_xattrop (call_frame_t *frame, xlator_t *this, loc_t *loc,
- gf_xattrop_flags_t flags, dict_t *dict, dict_t *xdata)
-{
- return default_xattrop_failure_cbk (frame, EPERM);
-}
-
-int
-meta_default_fxattrop (call_frame_t *frame, xlator_t *this, fd_t *fd,
- gf_xattrop_flags_t flags, dict_t *dict, dict_t *xdata)
-{
- return default_fxattrop_failure_cbk (frame, EPERM);
-}
-
-int
-meta_default_removexattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
- const char *name, dict_t *xdata)
-{
- return default_removexattr_failure_cbk (frame, EPERM);
-}
-
-int
-meta_default_fremovexattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
- const char *name, dict_t *xdata)
-{
- return default_fremovexattr_failure_cbk (frame, EPERM);
-}
-
-int
-meta_default_lk (call_frame_t *frame, xlator_t *this, fd_t *fd,
- int32_t cmd, struct gf_flock *lock, dict_t *xdata)
-{
- return default_lk_failure_cbk (frame, EPERM);
-}
-
-
-int
-meta_default_inodelk (call_frame_t *frame, xlator_t *this, const char *volume,
- loc_t *loc, int32_t cmd, struct gf_flock *lock,
- dict_t *xdata)
-{
- return default_inodelk_failure_cbk (frame, EPERM);
-}
-
-int
-meta_default_finodelk (call_frame_t *frame, xlator_t *this, const char *volume,
- fd_t *fd, int32_t cmd, struct gf_flock *lock,
- dict_t *xdata)
-{
- return default_finodelk_failure_cbk (frame, EPERM);
-}
-
-int
-meta_default_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)
-{
- return default_entrylk_failure_cbk (frame, EPERM);
-}
-
-int
-meta_default_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)
-{
- return default_fentrylk_failure_cbk (frame, EPERM);
-}
-
-int
-meta_default_rchecksum (call_frame_t *frame, xlator_t *this, fd_t *fd,
- off_t offset, int32_t len, dict_t *xdata)
-{
- return default_rchecksum_failure_cbk (frame, EPERM);
-}
-
-
-int
-meta_default_readdir (call_frame_t *frame, xlator_t *this, fd_t *fd,
- size_t size, off_t off, dict_t *xdata)
-{
- meta_fd_t *meta_fd = NULL;
- int i = 0;
- gf_dirent_t head;
- gf_dirent_t *list = NULL;
- int ret = 0;
- int this_size = 0;
- int filled_size = 0;
- int fixed_size = 0;
- int dyn_size = 0;
- struct meta_dirent *fixed_dirents = NULL;
- struct meta_dirent *dyn_dirents = NULL;
- struct meta_dirent *dirents = NULL;
- struct meta_dirent *end = NULL;
- struct meta_ops *ops = NULL;
-
- INIT_LIST_HEAD (&head.list);
-
- ops = meta_ops_get (fd->inode, this);
- if (!ops)
- goto err;
-
- meta_fd = meta_fd_get (fd, this);
- if (!meta_fd)
- goto err;
-
- meta_dir_fill (this, fd);
-
- fixed_dirents = ops->fixed_dirents;
- fixed_size = fixed_dirents_len (fixed_dirents);
-
- dyn_dirents = meta_fd->dirents;
- dyn_size = meta_fd->size;
-
- for (i = off; i < (fixed_size + dyn_size);) {
- if (i >= fixed_size) {
- dirents = dyn_dirents + (i - fixed_size);
- end = dyn_dirents + dyn_size;
- } else {
- dirents = fixed_dirents + i;
- end = fixed_dirents + fixed_size;
- }
-
- while (dirents < end) {
- this_size = sizeof (gf_dirent_t) +
- strlen (dirents->name) + 1;
- if (this_size + filled_size > size)
- goto unwind;
-
- list = gf_dirent_for_name (dirents->name);
- if (!list)
- break;
-
- list->d_off = i + 1;
- list->d_ino = i + 42;
- switch (dirents->type) {
- case IA_IFDIR: list->d_type = DT_DIR; break;
- case IA_IFCHR: list->d_type = DT_CHR; break;
- case IA_IFBLK: list->d_type = DT_BLK; break;
- case IA_IFIFO: list->d_type = DT_FIFO; break;
- case IA_IFLNK: list->d_type = DT_LNK; break;
- case IA_IFREG: list->d_type = DT_REG; break;
- case IA_IFSOCK: list->d_type = DT_SOCK; break;
- case IA_INVAL: list->d_type = DT_UNKNOWN; break;
- }
-
- list_add_tail (&list->list, &head.list);
- ret++; i++; dirents++;
- filled_size += this_size;
- }
- }
-
-unwind:
- META_STACK_UNWIND (readdir, frame, ret, 0, &head, xdata);
-
- gf_dirent_free (&head);
-
- return 0;
-err:
- META_STACK_UNWIND (readdir, frame, -1, ENOMEM, 0, 0);
- return 0;
-}
-
-
-int
-meta_default_readdirp (call_frame_t *frame, xlator_t *this, fd_t *fd,
- size_t size, off_t off, dict_t *xdata)
-{
- return meta_default_readdir (frame, this, fd, size, off, xdata);
-}
-
-int
-meta_default_setattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
- struct iatt *stbuf, int32_t valid,
- dict_t *xdata)
-{
- return default_setattr_failure_cbk (frame, EPERM);
-}
-
-int
-meta_default_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc,
- off_t offset, dict_t *xdata)
-{
- struct iatt iatt = { };
-
- meta_iatt_fill (&iatt, loc->inode, IA_IFREG);
-
- META_STACK_UNWIND (truncate, frame, 0, 0, &iatt, &iatt, xdata);
-
- return 0;
-}
-
-int
-meta_default_stat (call_frame_t *frame, xlator_t *this, loc_t *loc,
- dict_t *xdata)
-{
- struct iatt iatt = { };
-
- meta_iatt_fill (&iatt, loc->inode, loc->inode->ia_type);
-
- META_STACK_UNWIND (stat, frame, 0, 0, &iatt, xdata);
-
- return 0;
-}
-
-int
-meta_default_lookup (call_frame_t *frame, xlator_t *this, loc_t *loc,
- dict_t *xdata)
-{
- struct meta_ops *ops = NULL;
- struct meta_dirent *dirent = NULL;
- struct meta_dirent *dp = NULL;
- int i = 0;
- int ret = 0;
-
- if (!loc->name)
- return meta_inode_discover (frame, this, loc, xdata);
-
- ops = meta_ops_get (loc->parent, this);
- if (!ops)
- return default_lookup_failure_cbk (frame, EPERM);
-
- for (dirent = ops->fixed_dirents; dirent && dirent->name; dirent++) {
- if (strcmp (dirent->name, loc->name) == 0)
- goto hook;
- }
-
- dirent = NULL;
- if (ops->dir_fill)
- ret = ops->dir_fill (this, loc->parent, &dp);
-
- for (i = 0; i < ret; i++) {
- if (strcmp (dp[i].name, loc->name) == 0) {
- dirent = &dp[i];
- goto hook;
- }
- }
-hook:
- if (dirent && dirent->hook) {
- struct iatt parent = { };
- struct iatt iatt = { };
-
- dirent->hook (frame, this, loc, xdata);
-
- meta_iatt_fill (&iatt, loc->inode, dirent->type);
-
- META_STACK_UNWIND (lookup, frame, 0, 0, loc->inode, &iatt,
- xdata, &parent);
- } else {
- META_STACK_UNWIND (lookup, frame, -1, ENOENT, 0, 0, 0, 0);
- }
-
- for (i = 0; i < ret; i++)
- GF_FREE ((void *)dp[i].name);
- GF_FREE (dp);
-
- return 0;
-}
-
-int
-meta_default_fsetattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
- struct iatt *stbuf, int32_t valid, dict_t *xdata)
-{
- return default_fsetattr_failure_cbk (frame, EPERM);
-}
-
-int
-meta_default_fallocate (call_frame_t *frame, xlator_t *this, fd_t *fd,
- int32_t keep_size, off_t offset, size_t len,
- dict_t *xdata)
-{
- return default_fallocate_failure_cbk (frame, EPERM);
-}
-
-int
-meta_default_discard (call_frame_t *frame, xlator_t *this, fd_t *fd,
- off_t offset, size_t len, dict_t *xdata)
-{
- return default_discard_failure_cbk (frame, EPERM);
-}
-
-int
-meta_default_zerofill (call_frame_t *frame, xlator_t *this, fd_t *fd,
- off_t offset, off_t len, dict_t *xdata)
-{
- return default_zerofill_failure_cbk (frame, EPERM);
-}
-
-#define SET_META_DEFAULT_FOP(f,name) do { if (!f->name) f->name = meta_default_##name ; } while (0)
-
-struct xlator_fops *
-meta_defaults_init (struct xlator_fops *fops)
-{
- SET_META_DEFAULT_FOP (fops,create);
- SET_META_DEFAULT_FOP (fops,open);
- SET_META_DEFAULT_FOP (fops,stat);
- SET_META_DEFAULT_FOP (fops,readlink);
- SET_META_DEFAULT_FOP (fops,mknod);
- SET_META_DEFAULT_FOP (fops,mkdir);
- SET_META_DEFAULT_FOP (fops,unlink);
- SET_META_DEFAULT_FOP (fops,rmdir);
- SET_META_DEFAULT_FOP (fops,symlink);
- SET_META_DEFAULT_FOP (fops,rename);
- SET_META_DEFAULT_FOP (fops,link);
- SET_META_DEFAULT_FOP (fops,truncate);
- SET_META_DEFAULT_FOP (fops,readv);
- SET_META_DEFAULT_FOP (fops,writev);
- SET_META_DEFAULT_FOP (fops,statfs);
- SET_META_DEFAULT_FOP (fops,flush);
- SET_META_DEFAULT_FOP (fops,fsync);
- SET_META_DEFAULT_FOP (fops,setxattr);
- SET_META_DEFAULT_FOP (fops,getxattr);
- SET_META_DEFAULT_FOP (fops,fsetxattr);
- SET_META_DEFAULT_FOP (fops,fgetxattr);
- SET_META_DEFAULT_FOP (fops,removexattr);
- SET_META_DEFAULT_FOP (fops,fremovexattr);
- SET_META_DEFAULT_FOP (fops,opendir);
- SET_META_DEFAULT_FOP (fops,readdir);
- SET_META_DEFAULT_FOP (fops,readdirp);
- SET_META_DEFAULT_FOP (fops,fsyncdir);
- SET_META_DEFAULT_FOP (fops,access);
- SET_META_DEFAULT_FOP (fops,ftruncate);
- SET_META_DEFAULT_FOP (fops,fstat);
- SET_META_DEFAULT_FOP (fops,lk);
- SET_META_DEFAULT_FOP (fops,inodelk);
- SET_META_DEFAULT_FOP (fops,finodelk);
- SET_META_DEFAULT_FOP (fops,entrylk);
- SET_META_DEFAULT_FOP (fops,fentrylk);
- SET_META_DEFAULT_FOP (fops,lookup);
- SET_META_DEFAULT_FOP (fops,rchecksum);
- SET_META_DEFAULT_FOP (fops,xattrop);
- SET_META_DEFAULT_FOP (fops,fxattrop);
- SET_META_DEFAULT_FOP (fops,setattr);
- SET_META_DEFAULT_FOP (fops,fsetattr);
- SET_META_DEFAULT_FOP (fops,fallocate);
- SET_META_DEFAULT_FOP (fops,discard);
- SET_META_DEFAULT_FOP (fops,zerofill);
-
- return fops;
-}
diff --git a/xlators/meta/src/meta-helpers.c b/xlators/meta/src/meta-helpers.c
deleted file mode 100644
index a67671050b8..00000000000
--- a/xlators/meta/src/meta-helpers.c
+++ /dev/null
@@ -1,370 +0,0 @@
-/*
- Copyright (c) 2014 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 "xlator.h"
-#include "defaults.h"
-
-#include "meta-mem-types.h"
-#include "meta.h"
-
-
-meta_fd_t *
-meta_fd_get (fd_t *fd, xlator_t *this)
-{
- uint64_t value = 0;
- meta_fd_t *meta_fd = NULL;
-
- LOCK (&fd->lock);
- {
- __fd_ctx_get (fd, this, &value);
- if (!value) {
- meta_fd = GF_CALLOC (1, sizeof (*meta_fd),
- gf_meta_mt_fd_t);
- if (!meta_fd)
- goto unlock;
-
- value = (long) meta_fd;
- __fd_ctx_set (fd, this, value);
- }
-
- meta_fd = (void *) value;
- }
-unlock:
- UNLOCK (&fd->lock);
-
- return meta_fd;
-}
-
-
-int
-meta_fd_release (fd_t *fd, xlator_t *this)
-{
- uint64_t value = 0;
- meta_fd_t *meta_fd = NULL;
- int i = 0;
-
- fd_ctx_get (fd, this, &value);
- meta_fd = (void *) value;
-
- if (meta_fd->dirents) {
- for (i = 0; i < meta_fd->size; i++)
- GF_FREE ((void *)meta_fd->dirents[i].name);
- GF_FREE (meta_fd->dirents);
- }
-
- if (meta_fd) {
- GF_FREE (meta_fd->data);
- GF_FREE (meta_fd);
- }
- return 0;
-}
-
-
-struct meta_ops *
-meta_ops_get (inode_t *inode, xlator_t *this)
-{
- struct meta_ops *ops = NULL;
- uint64_t value = 0;
-
- inode_ctx_get2 (inode, this, NULL, &value);
-
- ops = (void *) value;
-
- return ops;
-}
-
-
-struct xlator_fops *
-meta_fops_get (inode_t *inode, xlator_t *this)
-{
- struct meta_ops *ops = NULL;
-
- ops = meta_ops_get (inode, this);
- if (!ops)
- return default_fops;
-
- return &ops->fops;
-}
-
-
-int
-meta_ops_set (inode_t *inode, xlator_t *this, struct meta_ops *ops)
-{
- uint64_t value = 0;
- int ret = 0;
-
- meta_defaults_init (&ops->fops);
-
- value = (long) ops;
-
- ret = inode_ctx_set2 (inode, this, NULL, &value);
-
- return ret;
-}
-
-void *
-meta_ctx_get (inode_t *inode, xlator_t *this)
-{
- void *ctx = NULL;
- uint64_t value = 0;
-
- inode_ctx_get2 (inode, this, &value, 0);
-
- ctx = (void *) value;
-
- return ctx;
-}
-
-
-int
-meta_ctx_set (inode_t *inode, xlator_t *this, void *ctx)
-{
- uint64_t value = 0;
- int ret = 0;
-
- value = (long) ctx;
-
- ret = inode_ctx_set2 (inode, this, &value, 0);
-
- return ret;
-}
-
-
-void
-meta_local_cleanup (meta_local_t *local, xlator_t *this)
-{
- if (!local)
- return;
-
- if (local->xdata)
- dict_unref (local->xdata);
-
- GF_FREE (local);
- return;
-}
-
-
-meta_local_t *
-meta_local (call_frame_t *frame)
-{
- meta_local_t *local = NULL;
-
- local = frame->local;
- if (!local)
- local = frame->local = GF_CALLOC (1, sizeof(*local),
- gf_meta_mt_local_t);
- return local;
-}
-
-
-dict_t *
-meta_direct_io_mode (dict_t *xdata, call_frame_t *frame)
-{
- meta_local_t *local = NULL;
-
- if (!xdata) {
- local = meta_local (frame);
- if (!local)
- return NULL;
- xdata = local->xdata = dict_new();
- if (!xdata)
- return NULL;
- }
-
- if (dict_set_int8 (xdata, "direct-io-mode", 1) != 0)
- return NULL;
-
- return xdata;
-}
-
-
-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;
-}
-
-
-static void
-meta_uuid_copy (uuid_t dst, uuid_t src)
-{
- uuid_copy (dst, src);
- if (uuid_is_null (dst))
- uuid_generate (dst);
-}
-
-
-static void
-default_meta_iatt_fill (struct iatt *iatt, inode_t *inode, ia_type_t type)
-{
- struct timeval tv = { };
-
- iatt->ia_type = type;
- switch (type)
- {
- case IA_IFDIR:
- iatt->ia_prot = ia_prot_from_st_mode (0755);
- iatt->ia_nlink = 2;
- break;
- case IA_IFLNK:
- iatt->ia_prot = ia_prot_from_st_mode (0777);
- iatt->ia_nlink = 1;
- break;
- default:
- iatt->ia_prot = ia_prot_from_st_mode (0644);
- iatt->ia_nlink = 1;
- break;
- }
- iatt->ia_uid = 0;
- iatt->ia_gid = 0;
- iatt->ia_size = 0;
-
- meta_uuid_copy (iatt->ia_gfid, inode->gfid);
- iatt->ia_ino = gfid_to_ino (iatt->ia_gfid);
-
- gettimeofday (&tv, 0);
- iatt->ia_mtime = iatt->ia_ctime = iatt->ia_atime = tv.tv_sec;
- iatt->ia_mtime_nsec = iatt->ia_ctime_nsec = iatt->ia_atime_nsec =
- (tv.tv_usec * 1000);
- return;
-}
-
-
-void
-meta_iatt_fill (struct iatt *iatt, inode_t *inode, ia_type_t type)
-{
- struct meta_ops *ops = NULL;
-
- ops = meta_ops_get (inode, THIS);
- if (!ops)
- return;
-
- if (!ops->iatt_fill)
- default_meta_iatt_fill (iatt, inode, type);
- else
- ops->iatt_fill (THIS, inode, iatt);
- return;
-}
-
-
-int
-meta_inode_discover (call_frame_t *frame, xlator_t *this, loc_t *loc,
- dict_t *xdata)
-{
- struct iatt iatt = { };
- struct iatt postparent = { };
-
- meta_iatt_fill (&iatt, loc->inode, loc->inode->ia_type);
-
- META_STACK_UNWIND (lookup, frame, 0, 0, loc->inode, &iatt, xdata,
- &postparent);
- return 0;
-}
-
-
-int
-meta_file_fill (xlator_t *this, fd_t *fd)
-{
- meta_fd_t *meta_fd = NULL;
- strfd_t *strfd = NULL;
- struct meta_ops *ops = NULL;
- int ret = 0;
-
- meta_fd = meta_fd_get (fd, this);
- if (!meta_fd)
- return -1;
-
- if (meta_fd->data)
- return meta_fd->size;
-
- strfd = strfd_open ();
- if (!strfd)
- return -1;
-
- ops = meta_ops_get (fd->inode, this);
- if (!ops) {
- strfd_close (strfd);
- return -1;
- }
-
- if (ops->file_fill)
- ret = ops->file_fill (this, fd->inode, strfd);
-
- if (ret >= 0) {
- meta_fd->data = strfd->data;
- meta_fd->size = strfd->size;
-
- strfd->data = NULL;
- }
-
- strfd_close (strfd);
-
- return meta_fd->size;
-}
-
-
-int
-meta_dir_fill (xlator_t *this, fd_t *fd)
-{
- meta_fd_t *meta_fd = NULL;
- struct meta_ops *ops = NULL;
- struct meta_dirent *dp = NULL;
- int ret = 0;
-
- meta_fd = meta_fd_get (fd, this);
- if (!meta_fd)
- return -1;
-
- if (meta_fd->dirents)
- return meta_fd->size;
-
- ops = meta_ops_get (fd->inode, this);
- if (!ops)
- return -1;
-
- if (ops->dir_fill)
- ret = ops->dir_fill (this, fd->inode, &dp);
-
- if (dp) {
- meta_fd->dirents = dp;
- meta_fd->size = ret;
- }
-
- return meta_fd->size;
-}
-
-
-int
-fixed_dirents_len (struct meta_dirent *dirents)
-{
- int i = 0;
- struct meta_dirent *dirent = NULL;
-
- if (!dirents)
- return 0;
-
- for (dirent = dirents; dirent->name; dirent++)
- i++;
-
- return i;
-}
diff --git a/xlators/meta/src/meta-hooks.h b/xlators/meta/src/meta-hooks.h
deleted file mode 100644
index bcf3643d223..00000000000
--- a/xlators/meta/src/meta-hooks.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- Copyright (c) 2014 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 __META_HOOKS_H
-#define __META_HOOKS_H
-#include "xlator.h"
-
-#define DECLARE_HOOK(name) int meta_##name##_hook (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
-
-DECLARE_HOOK(root_dir);
-DECLARE_HOOK(graphs_dir);
-DECLARE_HOOK(frames_file);
-DECLARE_HOOK(graph_dir);
-DECLARE_HOOK(active_link);
-DECLARE_HOOK(xlator_dir);
-DECLARE_HOOK(top_link);
-DECLARE_HOOK(logging_dir);
-DECLARE_HOOK(logfile_link);
-DECLARE_HOOK(loglevel_file);
-DECLARE_HOOK(process_uuid_file);
-DECLARE_HOOK(volfile_file);
-DECLARE_HOOK(view_dir);
-DECLARE_HOOK(subvolumes_dir);
-DECLARE_HOOK(subvolume_link);
-DECLARE_HOOK(type_file);
-DECLARE_HOOK(version_file);
-DECLARE_HOOK(options_dir);
-DECLARE_HOOK(option_file);
-DECLARE_HOOK(cmdline_file);
-DECLARE_HOOK(name_file);
-DECLARE_HOOK(private_file);
-DECLARE_HOOK(mallinfo_file);
-DECLARE_HOOK(history_file);
-DECLARE_HOOK(master_dir);
-DECLARE_HOOK(meminfo_file);
-DECLARE_HOOK(measure_file);
-DECLARE_HOOK(profile_file);
-
-#endif
diff --git a/xlators/meta/src/meta-mem-types.h b/xlators/meta/src/meta-mem-types.h
deleted file mode 100644
index e8a31856e71..00000000000
--- a/xlators/meta/src/meta-mem-types.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- Copyright (c) 2014 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 __META_MEM_TYPES_H__
-#define __META_MEM_TYPES_H__
-
-#include "mem-types.h"
-
-enum gf_meta_mem_types_ {
- gf_meta_mt_priv_t = gf_common_mt_end + 1,
- gf_meta_mt_fd_t,
- gf_meta_mt_fd_data_t,
- gf_meta_mt_strfd_t,
- gf_meta_mt_dirents_t,
- gf_meta_mt_local_t,
- gf_meta_mt_end
-};
-#endif
-
diff --git a/xlators/meta/src/meta.c b/xlators/meta/src/meta.c
index 036ed112acf..7843e816939 100644
--- a/xlators/meta/src/meta.c
+++ b/xlators/meta/src/meta.c
@@ -1,268 +1,1285 @@
/*
- Copyright (c) 2014 Red Hat, Inc. <http://www.redhat.com>
+ Copyright (c) 2006-2009 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 General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that 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 <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
#ifndef _CONFIG_H
#define _CONFIG_H
#include "config.h"
#endif
+#include "glusterfs.h"
+#include "dict.h"
#include "xlator.h"
-#include "defaults.h"
-#include "meta-mem-types.h"
#include "meta.h"
+#include "view.h"
+
+int32_t
+meta_getattr_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ struct stat *buf)
+{
+ STACK_UNWIND (frame, op_ret, op_errno, buf);
+ return 0;
+}
-#include "meta-hooks.h"
+int32_t
+meta_getattr (call_frame_t *frame,
+ xlator_t *this,
+ const char *path)
+{
+ meta_private_t *priv = (meta_private_t *) this->private;
+ meta_dirent_t *root = priv->tree;
+ meta_dirent_t *file = lookup_meta_entry (root, path, NULL);
+
+ if (file) {
+ if (file->fops && file->fops->getattr) {
+ STACK_WIND (frame, meta_getattr_cbk,
+ this, file->fops->getattr, path);
+ return 0;
+ }
+ else {
+ STACK_UNWIND (frame, 0, 0, file->stbuf);
+ return 0;
+ }
+ }
+ else {
+ STACK_WIND (frame, meta_getattr_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->getattr,
+ path);
+ return 0;
+ }
+}
+int32_t
+meta_chmod_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ struct stat *buf)
+{
+ STACK_UNWIND (frame,
+ op_ret,
+ op_errno,
+ buf);
+ return 0;
+}
-int
-meta_lookup (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
+int32_t
+meta_chmod (call_frame_t *frame,
+ xlator_t *this,
+ const char *path,
+ mode_t mode)
{
- inode_t *inode = NULL;
+ STACK_WIND (frame,
+ meta_chmod_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->chmod,
+ path,
+ mode);
+ return 0;
+}
+
+int32_t
+meta_chown_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ struct stat *buf)
+{
+ STACK_UNWIND (frame,
+ op_ret,
+ op_errno,
+ buf);
+ return 0;
+}
- if (META_HOOK (loc) || IS_META_ROOT_GFID (loc->gfid)) {
- struct iatt iatt = { };
- struct iatt parent = { };
+int32_t
+meta_chown (call_frame_t *frame,
+ xlator_t *this,
+ const char *path,
+ uid_t uid,
+ gid_t gid)
+{
+ STACK_WIND (frame,
+ meta_chown_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->chown,
+ path,
+ uid,
+ gid);
+ return 0;
+}
- meta_root_dir_hook (frame, this, loc, xdata);
- meta_iatt_fill (&iatt, loc->inode, IA_IFDIR);
- uuid_parse (META_ROOT_GFID, iatt.ia_gfid);
+int32_t
+meta_truncate_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ struct stat *buf)
+{
+ STACK_UNWIND (frame,
+ op_ret,
+ op_errno,
+ buf);
+ return 0;
+}
- META_STACK_UNWIND (lookup, frame, 0, 0, loc->inode, &iatt,
- xdata, &parent);
- return 0;
- }
+int32_t
+meta_truncate (call_frame_t *frame,
+ xlator_t *this,
+ const char *path,
+ off_t offset)
+{
+ STACK_WIND (frame,
+ meta_truncate_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->truncate,
+ path,
+ offset);
+ return 0;
+}
- if (loc->parent)
- inode = loc->parent;
- else
- inode = loc->inode;
- META_FOP (inode, lookup, frame, this, loc, xdata);
+int32_t
+meta_ftruncate_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ struct stat *buf)
+{
+ STACK_UNWIND (frame,
+ op_ret,
+ op_errno,
+ buf);
+ return 0;
+}
- return 0;
+int32_t
+meta_ftruncate (call_frame_t *frame,
+ xlator_t *this,
+ dict_t *fd,
+ off_t offset)
+{
+ STACK_WIND (frame,
+ meta_ftruncate_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->ftruncate,
+ fd,
+ offset);
+ return 0;
}
-int
-meta_opendir (call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd,
- dict_t *xdata)
+int32_t
+meta_utimes_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ struct stat *buf)
{
- META_FOP (fd->inode, opendir, frame, this, loc, fd, xdata);
+ STACK_UNWIND (frame,
+ op_ret,
+ op_errno,
+ buf);
+ return 0;
+}
- return 0;
+int32_t
+meta_utimes (call_frame_t *frame,
+ xlator_t *this,
+ const char *path,
+ struct timespec *buf)
+{
+ STACK_WIND (frame,
+ meta_utimes_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->utimes,
+ path,
+ buf);
+ return 0;
}
-int
-meta_open (call_frame_t *frame, xlator_t *this, loc_t *loc, int flags, fd_t *fd,
- dict_t *xdata)
+int32_t
+meta_access_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno)
{
- META_FOP (fd->inode, open, frame, this, loc, flags, fd, xdata);
+ STACK_UNWIND (frame,
+ op_ret,
+ op_errno);
+ return 0;
+}
- return 0;
+int32_t
+meta_access (call_frame_t *frame,
+ xlator_t *this,
+ const char *path,
+ mode_t mode)
+{
+ STACK_WIND (frame,
+ meta_access_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->access,
+ path,
+ mode);
+ return 0;
}
+int32_t
+meta_readlink_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ char *dest)
+{
+ STACK_UNWIND (frame,
+ op_ret,
+ op_errno,
+ dest);
+ return 0;
+}
-int
-meta_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
+meta_readlink (call_frame_t *frame,
+ xlator_t *this,
+ const char *path,
+ size_t size)
{
- META_FOP (fd->inode, readv, frame, this, fd, size, offset, flags, xdata);
+ STACK_WIND (frame,
+ meta_readlink_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->readlink,
+ path,
+ size);
+ return 0;
+}
- return 0;
+int32_t
+meta_mknod_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ struct stat *buf)
+{
+ STACK_UNWIND (frame,
+ op_ret,
+ op_errno,
+ buf);
+ return 0;
}
+int32_t
+meta_mknod (call_frame_t *frame,
+ xlator_t *this,
+ const char *path,
+ mode_t mode,
+ dev_t dev)
+{
+ STACK_WIND (frame,
+ meta_mknod_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->mknod,
+ path,
+ mode,
+ dev);
+ return 0;
+}
-int
-meta_flush (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
+int32_t
+meta_mkdir_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ struct stat *buf)
{
- META_FOP (fd->inode, flush, frame, this, fd, xdata);
+ STACK_UNWIND (frame,
+ op_ret,
+ op_errno,
+ buf);
+ return 0;
+}
- return 0;
+int32_t
+meta_mkdir (call_frame_t *frame,
+ xlator_t *this,
+ const char *path,
+ mode_t mode)
+{
+ STACK_WIND (frame,
+ meta_mkdir_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->mkdir,
+ path,
+ mode);
+ return 0;
}
+int32_t
+meta_unlink_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;
+}
-int
-meta_stat (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
+int32_t
+meta_unlink (call_frame_t *frame,
+ xlator_t *this,
+ const char *path)
{
- META_FOP (loc->inode, stat, frame, this, loc, xdata);
+ STACK_WIND (frame,
+ meta_unlink_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->unlink,
+ path);
+ return 0;
+}
- return 0;
+int32_t
+meta_rmdir_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;
+}
+
+int32_t
+meta_rmdir (call_frame_t *frame,
+ xlator_t *this,
+ const char *path)
+{
+ STACK_WIND (frame,
+ meta_rmdir_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->rmdir,
+ path);
+ return 0;
}
+int32_t
+meta_symlink_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ struct stat *buf)
+{
+ STACK_UNWIND (frame,
+ op_ret,
+ op_errno,
+ buf);
+ return 0;
+}
-int
-meta_fstat (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
+int32_t
+meta_symlink (call_frame_t *frame,
+ xlator_t *this,
+ const char *oldpath,
+ const char *newpath)
{
- META_FOP (fd->inode, fstat, frame, this, fd, xdata);
+ STACK_WIND (frame,
+ meta_symlink_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->symlink,
+ oldpath,
+ newpath);
+ return 0;
+}
- return 0;
+int32_t
+meta_rename_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;
}
+int32_t
+meta_rename (call_frame_t *frame,
+ xlator_t *this,
+ const char *oldpath,
+ const char *newpath)
+{
+ STACK_WIND (frame,
+ meta_rename_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->rename,
+ oldpath,
+ newpath);
+ return 0;
+}
-int
-meta_readdir (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
- off_t offset, dict_t *xdata)
+int32_t
+meta_link_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ struct stat *buf)
{
- META_FOP (fd->inode, readdir, frame, this, fd, size, offset, xdata);
+ STACK_UNWIND (frame,
+ op_ret,
+ op_errno,
+ buf);
+ return 0;
+}
- return 0;
+int32_t
+meta_link (call_frame_t *frame,
+ xlator_t *this,
+ const char *oldpath,
+ const char *newpath)
+{
+ STACK_WIND (frame,
+ meta_link_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->link,
+ oldpath,
+ newpath);
+ return 0;
}
+struct _open_local {
+ const char *path;
+};
-int
-meta_readdirp (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
- off_t offset, dict_t *xdata)
+int32_t
+meta_open_cbk (call_frame_t *frame, void *cookie,
+ xlator_t *this, int32_t op_ret, int32_t op_errno,
+ dict_t *ctx, struct stat *buf)
{
- META_FOP (fd->inode, readdirp, frame, this, fd, size, offset, xdata);
+ struct _open_local *local = frame->local;
+ if (local)
+ dict_set (ctx, this->name, str_to_data (local->path));
+ STACK_UNWIND (frame, op_ret, op_errno, ctx, buf);
+ return 0;
+}
- return 0;
+int32_t
+meta_open (call_frame_t *frame, xlator_t *this,
+ const char *path, int32_t flags, mode_t mode)
+{
+ meta_private_t *priv = (meta_private_t *) this->private;
+ meta_dirent_t *root = priv->tree;
+ meta_dirent_t *file = lookup_meta_entry (root, path, NULL);
+
+ if (file) {
+ if (file->fops && file->fops->open) {
+ struct _open_local *local = CALLOC (1, sizeof (struct _open_local));
+ ERR_ABORT (local);
+ local->path = strdup (path);
+ frame->local = local;
+ STACK_WIND (frame, meta_open_cbk,
+ this, file->fops->open,
+ path, flags, mode);
+ return 0;
+ }
+ else {
+ dict_t *ctx = get_new_dict ();
+ dict_ref (ctx);
+ dict_set (ctx, this->name, str_to_data (strdup (path)));
+ STACK_UNWIND (frame, 0, 0, ctx, file->stbuf);
+ return 0;
+ }
+ }
+ else {
+ STACK_WIND (frame, meta_open_cbk,
+ FIRST_CHILD(this), FIRST_CHILD(this)->fops->open,
+ path, flags, mode);
+ return 0;
+ }
}
+int32_t
+meta_create (call_frame_t *frame, xlator_t *this,
+ const char *path, int32_t flags, mode_t mode)
+{
+ meta_private_t *priv = (meta_private_t *) this->private;
+ meta_dirent_t *root = priv->tree;
+ meta_dirent_t *file = lookup_meta_entry (root, path, NULL);
+
+ if (file) {
+ if (file->fops && file->fops->create) {
+ struct _open_local *local = CALLOC (1, sizeof (struct _open_local));
+ ERR_ABORT (local);
+ local->path = strdup (path);
+ frame->local = local;
+ STACK_WIND (frame, meta_open_cbk,
+ this, file->fops->create,
+ path, flags, mode);
+ return 0;
+ }
+ else {
+ STACK_UNWIND (frame, -1, 0, NULL, NULL);
+ return 0;
+ }
+ }
+ else {
+ STACK_WIND (frame, meta_open_cbk,
+ FIRST_CHILD(this), FIRST_CHILD(this)->fops->create,
+ path, flags, mode);
+ return 0;
+ }
+}
-int
-meta_readlink (call_frame_t *frame, xlator_t *this, loc_t *loc, size_t size,
- dict_t *xdata)
+int32_t
+meta_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)
{
- META_FOP (loc->inode, readlink, frame, this, loc, size, xdata);
+ STACK_UNWIND (frame,
+ op_ret,
+ op_errno,
+ vector,
+ count);
+ return 0;
+}
- return 0;
+int32_t
+meta_readv (call_frame_t *frame,
+ xlator_t *this,
+ dict_t *fd,
+ size_t size,
+ off_t offset)
+{
+ meta_private_t *priv = (meta_private_t *) this->private;
+ meta_dirent_t *root = priv->tree;
+ data_t *path_data = dict_get (fd, this->name);
+
+ if (path_data) {
+ const char *path = data_to_str (path_data);
+ meta_dirent_t *file = lookup_meta_entry (root, path, NULL);
+
+ if (file && file->fops && file->fops->readv) {
+ STACK_WIND (frame, meta_readv_cbk,
+ this, file->fops->readv,
+ fd, size, offset);
+ return 0;
+ }
+ }
+ else {
+ STACK_WIND (frame, meta_readv_cbk,
+ FIRST_CHILD(this), FIRST_CHILD(this)->fops->readv,
+ fd, size, offset);
+ return 0;
+ }
}
+int32_t
+meta_writev_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;
+}
-int
-meta_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
+meta_writev (call_frame_t *frame, xlator_t *this,
+ dict_t *fd,
+ struct iovec *vector, int32_t count, off_t offset)
{
- META_FOP (fd->inode, writev, frame, this, fd, iov, count, offset, flags,
- iobref, xdata);
+ meta_private_t *priv = (meta_private_t *) this->private;
+ meta_dirent_t *root = priv->tree;
+ data_t *path_data = dict_get (fd, this->name);
+
+ if (path_data) {
+ const char *path = data_to_str (path_data);
+ meta_dirent_t *file = lookup_meta_entry (root, path, NULL);
+
+ if (file && file->fops && file->fops->writev) {
+ STACK_WIND (frame, meta_writev_cbk,
+ this, file->fops->writev,
+ fd, vector, count, offset);
+ return 0;
+ }
+ }
+ else {
+ STACK_WIND (frame, meta_readv_cbk,
+ FIRST_CHILD(this), FIRST_CHILD(this)->fops->writev,
+ fd, vector, count, offset);
+ return 0;
+ }
+}
+
+int32_t
+meta_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;
+}
+
+int32_t
+meta_flush (call_frame_t *frame,
+ xlator_t *this,
+ dict_t *fd)
+{
+ meta_private_t *priv = (meta_private_t *) this->private;
+ meta_dirent_t *root = priv->tree;
+ data_t *path_data = dict_get (fd, this->name);
+
+ if (path_data) {
+ const char *path = data_to_str (path_data);
+ meta_dirent_t *file = lookup_meta_entry (root, path, NULL);
+
+ if (file) {
+ if (file->fops && file->fops->flush) {
+ STACK_WIND (frame, meta_flush_cbk,
+ this, file->fops->flush,
+ fd);
+ return 0;
+ }
+ else {
+ STACK_UNWIND (frame, 0, 0);
return 0;
+ }
+ }
+ }
+ else {
+ STACK_WIND (frame, meta_flush_cbk,
+ FIRST_CHILD(this), FIRST_CHILD(this)->fops->flush,
+ fd);
+ return 0;
+ }
}
+int32_t
+meta_release_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;
+}
-int
-meta_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset,
- dict_t *xdata)
+int32_t
+meta_release (call_frame_t *frame,
+ xlator_t *this,
+ dict_t *fd)
{
- META_FOP (loc->inode, truncate, frame, this, loc, offset, xdata);
+ meta_private_t *priv = (meta_private_t *) this->private;
+ meta_dirent_t *root = priv->tree;
+ data_t *path_data = dict_get (fd, this->name);
+
+ if (path_data) {
+ const char *path = data_to_str (path_data);
+ meta_dirent_t *file = lookup_meta_entry (root, path, NULL);
+
+ if (file) {
+ dict_unref (fd);
+ STACK_UNWIND (frame, 0, 0);
+ return 0;
+ }
+ }
+ else {
+ STACK_WIND (frame, meta_release_cbk,
+ FIRST_CHILD(this), FIRST_CHILD(this)->fops->release,
+ fd);
+ return 0;
+ }
+}
- return 0;
+int32_t
+meta_fsync_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;
}
+int32_t
+meta_fsync (call_frame_t *frame,
+ xlator_t *this,
+ dict_t *fd,
+ int32_t flags)
+{
+ STACK_WIND (frame,
+ meta_fsync_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->fsync,
+ fd,
+ flags);
+ return 0;
+}
-int
-meta_ftruncate (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
- dict_t *xdata)
+int32_t
+meta_fgetattr_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ struct stat *buf)
{
- META_FOP (fd->inode, ftruncate, frame, this, fd, offset, xdata);
+ STACK_UNWIND (frame,
+ op_ret,
+ op_errno,
+ buf);
+ return 0;
+}
- return 0;
+int32_t
+meta_fgetattr (call_frame_t *frame,
+ xlator_t *this,
+ dict_t *fd)
+{
+ STACK_WIND (frame,
+ meta_fgetattr_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->fgetattr,
+ fd);
+ return 0;
}
-int
-meta_forget (xlator_t *this, inode_t *inode)
+int32_t
+meta_opendir_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ dict_t *fd)
{
- return 0;
+ STACK_UNWIND (frame,
+ op_ret,
+ op_errno,
+ fd);
+ return 0;
}
+int32_t
+meta_opendir (call_frame_t *frame,
+ xlator_t *this,
+ const char *path)
+{
+ meta_private_t *priv = (meta_private_t *) this->private;
+ meta_dirent_t *root = priv->tree;
+ meta_dirent_t *dir = lookup_meta_entry (root, path, NULL);
+
+ if (dir) {
+ dict_t *ctx = get_new_dict ();
+ dict_set (ctx, this->name, str_to_data (strdup (path)));
+ STACK_UNWIND (frame, 0, 0, ctx);
+ return 0;
+ }
+ else {
+ STACK_WIND (frame, meta_opendir_cbk,
+ FIRST_CHILD(this), FIRST_CHILD(this)->fops->opendir,
+ path);
+ return 0;
+ }
+}
-int
-meta_release (xlator_t *this, fd_t *fd)
+int32_t
+meta_readdir_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ dir_entry_t *entries,
+ int32_t count)
{
- return meta_fd_release (fd, this);
+ meta_private_t *priv = (meta_private_t *)this->private;
+
+ if ((int) cookie == 1) {
+ dir_entry_t *dir = CALLOC (1, sizeof (dir_entry_t));
+ ERR_ABORT (dir);
+
+ dir->name = strdup (".meta");
+ memcpy (&dir->buf, priv->tree->stbuf, sizeof (struct stat));
+ dir->next = entries->next;
+ entries->next = dir;
+
+ STACK_UNWIND (frame, op_ret, op_errno, entries, count+1);
+ return 0;
+ }
+
+ STACK_UNWIND (frame, op_ret, op_errno, entries, count);
+ return 0;
}
+int32_t
+meta_readdir (call_frame_t *frame,
+ xlator_t *this,
+ const char *path)
+{
+ meta_private_t *priv = (meta_private_t *) this->private;
+ meta_dirent_t *root = priv->tree;
+
+ meta_dirent_t *dir = lookup_meta_entry (root, path, NULL);
+ if (dir) {
+ if (dir->fops && dir->fops->readdir) {
+ STACK_WIND (frame, meta_readdir_cbk,
+ this, dir->fops->readdir, path);
+ return 0;
+ }
+ else {
+ int count = 0;
+ dir = dir->children;
+ dir_entry_t *entries = NULL;
+
+ while (dir) {
+ dir_entry_t *d = CALLOC (1, sizeof (dir_entry_t));
+ ERR_ABORT (d);
+ d->name = dir->name;
+ d->buf = *dir->stbuf;
+ d->next = entries;
+ entries = d;
+ count++;
+ dir = dir->next;
+ }
+
+ dir_entry_t *header = CALLOC (1, sizeof (dir_entry_t));
+ ERR_ABORT (header);
+ header->next = entries;
+ STACK_UNWIND (frame, 0, 0, header, count);
+ return 0;
+ }
+ }
+ else {
+ if (!strcmp (path, "/")) {
+ STACK_WIND_COOKIE (frame, meta_readdir_cbk,
+ (int) 1, /* cookie to tell _cbk to add .meta entry */
+ FIRST_CHILD(this), FIRST_CHILD(this)->fops->readdir,
+ path);
+ }
+ else {
+ STACK_WIND (frame, meta_readdir_cbk,
+ FIRST_CHILD(this), FIRST_CHILD(this)->fops->readdir,
+ path);
+ }
+ }
+ return 0;
+}
-int
-meta_releasedir (xlator_t *this, fd_t *fd)
+int32_t
+meta_releasedir_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno)
{
- return meta_fd_release (fd, this);
+ STACK_UNWIND (frame,
+ op_ret,
+ op_errno);
+ return 0;
}
+int32_t
+meta_releasedir (call_frame_t *frame,
+ xlator_t *this,
+ dict_t *fd)
+{
+ STACK_WIND (frame,
+ meta_releasedir_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->releasedir,
+ fd);
+ return 0;
+}
-int
-mem_acct_init (xlator_t *this)
+int32_t
+meta_fsyncdir_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno)
{
- int ret = -1;
+ STACK_UNWIND (frame,
+ op_ret,
+ op_errno);
+ return 0;
+}
- if (!this)
- return ret;
+int32_t
+meta_fsyncdir (call_frame_t *frame,
+ xlator_t *this,
+ dict_t *fd,
+ int32_t flags)
+{
+ STACK_WIND (frame,
+ meta_fsyncdir_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->fsyncdir,
+ fd,
+ flags);
+ return 0;
+}
- ret = xlator_mem_acct_init (this, gf_meta_mt_end + 1);
+int32_t
+meta_statfs_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ struct statvfs *buf)
+{
+ STACK_UNWIND (frame,
+ op_ret,
+ op_errno,
+ buf);
+ return 0;
+}
- if (ret != 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "Memory accounting init failed");
- return ret;
- }
+int32_t
+meta_statfs (call_frame_t *frame,
+ xlator_t *this,
+ const char *path)
+{
+ STACK_WIND (frame,
+ meta_statfs_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->statfs,
+ path);
+ return 0;
+}
- return ret;
+int32_t
+meta_setxattr_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;
}
+int32_t
+meta_setxattr (call_frame_t *frame,
+ xlator_t *this,
+ const char *path,
+ const char *name,
+ const char *value,
+ size_t size,
+ int32_t flags)
+{
+ STACK_WIND (frame,
+ meta_setxattr_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->setxattr,
+ path,
+ name,
+ value,
+ size,
+ flags);
+ return 0;
+}
-int
-init (xlator_t *this)
+int32_t
+meta_getxattr_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ char *value)
{
- meta_priv_t *priv = NULL;
+ STACK_UNWIND (frame,
+ op_ret,
+ op_errno,
+ value);
+ return 0;
+}
- priv = GF_CALLOC (sizeof(*priv), 1, gf_meta_mt_priv_t);
- if (!priv)
- return -1;
+int32_t
+meta_getxattr (call_frame_t *frame,
+ xlator_t *this,
+ const char *path,
+ const char *name,
+ size_t size)
+{
+ STACK_WIND (frame,
+ meta_getxattr_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->getxattr,
+ path,
+ name,
+ size);
+ return 0;
+}
- GF_OPTION_INIT ("meta-dir-name", priv->meta_dir_name, str, out);
+int32_t
+meta_listxattr_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ char *value)
+{
+ STACK_UNWIND (frame,
+ op_ret,
+ op_errno,
+ value);
+ return 0;
+}
- this->private = priv;
-out:
- return 0;
+int32_t
+meta_listxattr (call_frame_t *frame,
+ xlator_t *this,
+ const char *path,
+ size_t size)
+{
+ STACK_WIND (frame,
+ meta_listxattr_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->listxattr,
+ path,
+ size);
+ return 0;
}
+int32_t
+meta_removexattr_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;
+}
-int
-fini (xlator_t *this)
+int32_t
+meta_removexattr (call_frame_t *frame,
+ xlator_t *this,
+ const char *path,
+ const char *name)
{
- return 0;
+ STACK_WIND (frame,
+ meta_removexattr_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->removexattr,
+ path,
+ name);
+ return 0;
}
+int32_t
+meta_lk_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ struct flock *lock)
+{
+ STACK_UNWIND (frame,
+ op_ret,
+ op_errno,
+ lock);
+ return 0;
+}
-struct xlator_fops fops = {
- .lookup = meta_lookup,
- .opendir = meta_opendir,
- .open = meta_open,
- .readv = meta_readv,
- .flush = meta_flush,
- .stat = meta_stat,
- .fstat = meta_fstat,
- .readdir = meta_readdir,
- .readdirp = meta_readdirp,
- .readlink = meta_readlink,
- .writev = meta_writev,
- .truncate = meta_truncate,
- .ftruncate = meta_ftruncate
-};
+int32_t
+meta_lk (call_frame_t *frame,
+ xlator_t *this,
+ dict_t *file,
+ int32_t cmd,
+ struct flock *lock)
+{
+ STACK_WIND (frame,
+ meta_lk_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->lk,
+ file,
+ cmd,
+ lock);
+ return 0;
+}
+static void
+add_xlator_to_tree (meta_dirent_t *tree, xlator_t *this,
+ const char *prefix)
+{
+ char *dir;
+ asprintf (&dir, "%s/%s", prefix, this->name);
+
+ char *children;
+ asprintf (&children, "%s/%s", dir, "subvolumes");
+
+ char *type;
+ asprintf (&type, "%s/%s", dir, "type");
+
+ char *view;
+ asprintf (&view, "%s/%s", dir, "view");
+
+ insert_meta_entry (tree, dir, S_IFDIR, NULL, NULL);
+ insert_meta_entry (tree, children, S_IFDIR, NULL, NULL);
+ meta_dirent_t *v = insert_meta_entry (tree, view, S_IFDIR, NULL,
+ &meta_xlator_view_fops);
+ v->view_xlator = this;
+ meta_dirent_t *t = insert_meta_entry (tree, type, S_IFREG, NULL,
+ &meta_xlator_type_fops);
+ t->view_xlator = this;
+
+ xlator_list_t *trav = this->children;
+ while (trav) {
+ add_xlator_to_tree (tree, trav->xlator, children);
+ trav = trav->next;
+ }
+}
-struct xlator_cbks cbks = {
- .forget = meta_forget,
- .release = meta_release,
- .releasedir = meta_releasedir,
-};
+static void
+build_meta_tree (xlator_t *this)
+{
+ meta_private_t *priv = (meta_private_t *) this->private;
+ priv->tree = CALLOC (1, sizeof (meta_dirent_t));
+ ERR_ABORT (priv->tree);
+ priv->tree->name = strdup (".meta");
+ priv->tree->stbuf = new_stbuf ();
+ priv->tree->stbuf->st_mode = S_IFDIR | S_IRUSR | S_IRGRP | S_IROTH |
+ S_IXUSR | S_IXGRP | S_IXOTH;
+
+ insert_meta_entry (priv->tree, "/.meta/version",
+ S_IFREG, NULL, &meta_version_fops);
+
+ insert_meta_entry (priv->tree, "/.meta/xlators",
+ S_IFDIR, NULL, NULL);
+
+ xlator_list_t *trav = this->children;
+ while (trav) {
+ add_xlator_to_tree (priv->tree, trav->xlator, "/.meta/xlators");
+ trav = trav->next;
+ }
+}
+
+int32_t
+init (xlator_t *this)
+{
+ if (this->parent != NULL) {
+ gf_log ("meta", GF_LOG_ERROR, "FATAL: meta should be the root of the xlator tree");
+ return -1;
+ }
+
+ meta_private_t *priv = CALLOC (1, sizeof (meta_private_t));
+ ERR_ABORT (priv);
+
+ data_t *directory = dict_get (this->options, "directory");
+ if (directory) {
+ priv->directory = strdup (data_to_str (directory));
+ }
+ else {
+ priv->directory = ".meta";
+ }
+
+ this->private = priv;
+ build_meta_tree (this);
+
+ return 0;
+}
+
+int32_t
+fini (xlator_t *this)
+{
+ return 0;
+}
+struct xlator_fops fops = {
+ .getattr = meta_getattr,
+ .readlink = meta_readlink,
+ .mknod = meta_mknod,
+ .mkdir = meta_mkdir,
+ .unlink = meta_unlink,
+ .rmdir = meta_rmdir,
+ .symlink = meta_symlink,
+ .rename = meta_rename,
+ .link = meta_link,
+ .chmod = meta_chmod,
+ .chown = meta_chown,
+ .truncate = meta_truncate,
+ .utimes = meta_utimes,
+ .open = meta_open,
+ .readv = meta_readv,
+ .writev = meta_writev,
+ .statfs = meta_statfs,
+ .flush = meta_flush,
+ .release = meta_release,
+ .fsync = meta_fsync,
+ .setxattr = meta_setxattr,
+ .getxattr = meta_getxattr,
+ .listxattr = meta_listxattr,
+ .removexattr = meta_removexattr,
+ .opendir = meta_opendir,
+ .readdir = meta_readdir,
+ .releasedir = meta_releasedir,
+ .fsyncdir = meta_fsyncdir,
+ .access = meta_access,
+ .ftruncate = meta_ftruncate,
+ .fgetattr = meta_fgetattr,
+ .create = meta_create,
+ .lk = meta_lk,
+};
-struct volume_options options[] = {
- { .key = {"meta-dir-name"},
- .type = GF_OPTION_TYPE_STR,
- .default_value = DEFAULT_META_DIR_NAME,
- .description = "Name of default meta directory."
- },
- { .key = {NULL} },
+struct xlator_mops mops = {
};
diff --git a/xlators/meta/src/meta.h b/xlators/meta/src/meta.h
index 652ebd7321c..7f44162cc10 100644
--- a/xlators/meta/src/meta.h
+++ b/xlators/meta/src/meta.h
@@ -1,12 +1,22 @@
/*
- Copyright (c) 2014 Red Hat, Inc. <http://www.redhat.com>
+ Copyright (c) 2006-2009 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 General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that 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 __META_H__
#define __META_H__
@@ -15,112 +25,24 @@
#include "config.h"
#endif
-#include "strfd.h"
-
-#define DEFAULT_META_DIR_NAME ".meta"
-
-#define META_ROOT_GFID "ba926388-bb9c-4eec-ad60-79dba4cc083a"
-
-#define IS_META_ROOT_GFID(g) (strcmp (uuid_utoa(g), META_ROOT_GFID) == 0)
-
-typedef int (*meta_hook_t) (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata);
-
-typedef struct {
- dict_t *xdata;
-} meta_local_t;
-
-typedef struct {
- char *meta_dir_name;
-} meta_priv_t;
-
-struct meta_dirent {
- const char *name;
- ia_type_t type;
- meta_hook_t hook;
-};
-
-#define DOT_DOTDOT { .name = ".", .type = IA_IFDIR }, { .name = "..", .type = IA_IFDIR }
-
-struct meta_ops {
- struct meta_dirent *fixed_dirents;
- int (*dir_fill) (xlator_t *this, inode_t *dir, struct meta_dirent **entries);
- int (*file_fill) (xlator_t *this, inode_t *file, strfd_t *strfd);
- int (*iatt_fill) (xlator_t *this, inode_t *inode, struct iatt *iatt);
- int (*link_fill) (xlator_t *this, inode_t *inode, strfd_t *strfd);
- int (*file_write) (xlator_t *this, fd_t *fd, struct iovec *iov, int count);
- struct xlator_fops fops;
- struct xlator_cbks cbks;
+struct _meta_dirent {
+ const char *name;
+ int type;
+ struct _meta_dirent *children;
+ struct _meta_dirent *parent;
+ struct _meta_dirent *next;
+ struct stat *stbuf;
+ xlator_t *view_xlator;
+ struct xlator_fops *fops;
};
+typedef struct _meta_dirent meta_dirent_t;
typedef struct {
- char *data;
- struct meta_dirent *dirents;
- size_t size;
-} meta_fd_t;
-
-
-#define COUNT(arr) (sizeof(arr)/sizeof(arr[0]))
-
-#define META_HOOK(loc) (__is_root_gfid (loc->pargfid) && !strcmp (loc->name, META_PRIV(THIS)->meta_dir_name))
-
-#define META_PRIV(t) ((meta_priv_t *)(t->private))
-
-#define META_STACK_UNWIND(fop, frame, params ...) \
- do { \
- meta_local_t *__local = NULL; \
- xlator_t *__this = NULL; \
- if (frame) { \
- __local = frame->local; \
- __this = frame->this; \
- frame->local = NULL; \
- } \
- STACK_UNWIND_STRICT (fop, frame, params); \
- if (__local) { \
- meta_local_cleanup (__local, __this); \
- } \
- } while (0)
-
-
-#define META_FOP(i, fop, fr, t, params ...) { \
- struct xlator_fops *_fops = NULL; \
- \
- _fops = meta_fops_get (i, t); \
- \
- _fops->fop (fr, t, params); \
- } while (0)
-
-
-void meta_iatt_fill (struct iatt *iatt, inode_t *inode, ia_type_t type);
-
-int meta_inode_discover (call_frame_t *frame, xlator_t *this, loc_t *loc,
- dict_t *xdata);
-
-int meta_ops_set (inode_t *inode, xlator_t *this, struct meta_ops *ops);
-
-struct xlator_fops *meta_fops_get (inode_t *inode, xlator_t *this);
-struct xlator_cbks *meta_cbks_get (inode_t *inode, xlator_t *this);
-struct meta_ops *meta_ops_get (inode_t *inode, xlator_t *this);
-
-int meta_ctx_set (inode_t *inode, xlator_t *this, void *ctx);
-
-void *meta_ctx_get (inode_t *inode, xlator_t *this);
-
-
-void meta_local_cleanup (meta_local_t *local, xlator_t *this);
-
-struct xlator_fops *meta_defaults_init (struct xlator_fops *fops);
-
-meta_fd_t *meta_fd_get (fd_t *fd, xlator_t *this);
-
-int meta_fd_release (fd_t *fd, xlator_t *this);
-
-dict_t *meta_direct_io_mode (dict_t *xdata, call_frame_t *frame);
-
-meta_local_t *meta_local (call_frame_t *frame);
-
-int meta_file_fill (xlator_t *this, fd_t *fd);
+ const char *directory;
+ meta_dirent_t *tree;
+} meta_private_t;
-int meta_dir_fill (xlator_t *this, fd_t *fd);
+#include "tree.h"
+#include "misc.h"
-int fixed_dirents_len (struct meta_dirent *dirents);
#endif /* __META_H__ */
diff --git a/xlators/meta/src/misc.c b/xlators/meta/src/misc.c
new file mode 100644
index 00000000000..062e741f25d
--- /dev/null
+++ b/xlators/meta/src/misc.c
@@ -0,0 +1,67 @@
+/*
+ Copyright (c) 2006-2009 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 <sys/uio.h>
+
+#ifndef _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+#include "xlator.h"
+#include "meta.h"
+
+#define min(x,y) ((x) < (y) ? (x) : (y))
+
+/* /.meta/version */
+static const char *version_str = PACKAGE_NAME " " PACKAGE_VERSION "\n";
+
+int32_t
+meta_version_readv (call_frame_t *frame, xlator_t *this,
+ dict_t *fd, size_t size, off_t offset)
+{
+ static int version_size;
+ version_size = strlen (version_str);
+
+ struct iovec vec;
+ vec.iov_base = version_str + offset;
+ vec.iov_len = min (version_size - offset, size);
+
+ STACK_UNWIND (frame, vec.iov_len, 0, &vec, 1);
+ return 0;
+}
+
+int32_t
+meta_version_getattr (call_frame_t *frame,
+ xlator_t *this,
+ const char *path)
+{
+ meta_private_t *priv = (meta_private_t *) this->private;
+ meta_dirent_t *root = priv->tree;
+ meta_dirent_t *file = lookup_meta_entry (root, path, NULL);
+ file->stbuf->st_size = strlen (version_str);
+ STACK_UNWIND (frame, 0, 0, file->stbuf);
+}
+
+struct xlator_fops meta_version_fops = {
+ .readv = meta_version_readv,
+ .getattr = meta_version_getattr
+};
+
diff --git a/xlators/meta/src/misc.h b/xlators/meta/src/misc.h
new file mode 100644
index 00000000000..8ede1328b3d
--- /dev/null
+++ b/xlators/meta/src/misc.h
@@ -0,0 +1,31 @@
+/*
+ Copyright (c) 2006-2009 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 __MISC_H__
+#define __MISC_H__
+
+#ifndef _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+
+struct xlator_fops meta_version_fops;
+
+#endif /* __MISC_H__ */
diff --git a/xlators/meta/src/name-file.c b/xlators/meta/src/name-file.c
deleted file mode 100644
index 8ddd42945d7..00000000000
--- a/xlators/meta/src/name-file.c
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- Copyright (c) 2014 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 "xlator.h"
-#include "defaults.h"
-
-#include "meta-mem-types.h"
-#include "meta.h"
-#include "strfd.h"
-#include "globals.h"
-#include "lkowner.h"
-
-
-static int
-name_file_fill (xlator_t *this, inode_t *file, strfd_t *strfd)
-{
- xlator_t *xl = NULL;
-
- xl = meta_ctx_get (file, this);
-
- strprintf (strfd, "%s\n", xl->name);
-
- return strfd->size;
-}
-
-
-static struct meta_ops name_file_ops = {
- .file_fill = name_file_fill,
-};
-
-
-int
-meta_name_file_hook (call_frame_t *frame, xlator_t *this, loc_t *loc,
- dict_t *xdata)
-{
- meta_ops_set (loc->inode, this, &name_file_ops);
-
- meta_ctx_set (loc->inode, this, meta_ctx_get (loc->parent, this));
-
- return 0;
-}
diff --git a/xlators/meta/src/option-file.c b/xlators/meta/src/option-file.c
deleted file mode 100644
index 4f9067e1490..00000000000
--- a/xlators/meta/src/option-file.c
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- Copyright (c) 2014 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 "xlator.h"
-#include "defaults.h"
-
-#include "meta-mem-types.h"
-#include "meta.h"
-#include "meta-hooks.h"
-
-
-static int
-option_file_fill (xlator_t *this, inode_t *inode, strfd_t *strfd)
-{
- data_t *data = NULL;
-
- data = meta_ctx_get (inode, this);
-
- strprintf (strfd, "%s\n", data_to_str (data));
-
- return strfd->size;
-}
-
-
-static struct meta_ops option_file_ops = {
- .file_fill = option_file_fill
-};
-
-
-int
-meta_option_file_hook (call_frame_t *frame, xlator_t *this, loc_t *loc,
- dict_t *xdata)
-{
- xlator_t *xl = NULL;
-
- xl = meta_ctx_get (loc->parent, this);
-
- meta_ctx_set (loc->inode, this,
- dict_get (xl->options, (char *) loc->name));
-
- meta_ops_set (loc->inode, this, &option_file_ops);
-
- return 0;
-}
diff --git a/xlators/meta/src/options-dir.c b/xlators/meta/src/options-dir.c
deleted file mode 100644
index 229d365a9c7..00000000000
--- a/xlators/meta/src/options-dir.c
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- Copyright (c) 2014 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 "xlator.h"
-#include "defaults.h"
-
-#include "meta-mem-types.h"
-#include "meta.h"
-#include "meta-hooks.h"
-
-
-static int
-dict_key_add (dict_t *dict, char *key, data_t *value, void *data)
-{
- struct meta_dirent **direntp = data;
-
- (*direntp)->name = gf_strdup (key);
- (*direntp)->type = IA_IFREG;
- (*direntp)->hook = meta_option_file_hook;
-
- (*direntp)++;
- return 0;
-}
-
-
-static int
-options_dir_fill (xlator_t *this, inode_t *inode, struct meta_dirent **dp)
-{
- struct meta_dirent *dirent = NULL;
- struct meta_dirent *direntp = NULL;
- xlator_t *xl = NULL;
-
- xl = meta_ctx_get (inode, this);
-
- dirent = GF_CALLOC (sizeof (*dirent), xl->options->count,
- gf_meta_mt_dirents_t);
- if (!dirent)
- return -1;
-
- direntp = dirent;
-
- dict_foreach (xl->options, dict_key_add, &direntp);
-
- *dp = dirent;
-
- return xl->options->count;
-}
-
-
-static struct meta_ops options_dir_ops = {
- .dir_fill = options_dir_fill
-};
-
-
-int
-meta_options_dir_hook (call_frame_t *frame, xlator_t *this, loc_t *loc,
- dict_t *xdata)
-{
- meta_ctx_set (loc->inode, this, meta_ctx_get (loc->parent, this));
-
- meta_ops_set (loc->inode, this, &options_dir_ops);
-
- return 0;
-}
diff --git a/xlators/meta/src/private-file.c b/xlators/meta/src/private-file.c
deleted file mode 100644
index d2402c08bb4..00000000000
--- a/xlators/meta/src/private-file.c
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- Copyright (c) 2014 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 "xlator.h"
-#include "defaults.h"
-
-#include "meta-mem-types.h"
-#include "meta.h"
-#include "strfd.h"
-#include "statedump.h"
-
-
-static int
-private_file_fill (xlator_t *this, inode_t *file, strfd_t *strfd)
-{
- xlator_t *xl = NULL;
-
- xl = meta_ctx_get (file, this);
-
- gf_proc_dump_xlator_private (xl, strfd);
-
- return strfd->size;
-}
-
-
-static struct meta_ops private_file_ops = {
- .file_fill = private_file_fill,
-};
-
-
-int
-meta_private_file_hook (call_frame_t *frame, xlator_t *this, loc_t *loc,
- dict_t *xdata)
-{
- meta_ops_set (loc->inode, this, &private_file_ops);
-
- meta_ctx_set (loc->inode, this, meta_ctx_get (loc->parent, this));
-
- return 0;
-}
diff --git a/xlators/meta/src/process_uuid-file.c b/xlators/meta/src/process_uuid-file.c
deleted file mode 100644
index c16ceaac150..00000000000
--- a/xlators/meta/src/process_uuid-file.c
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- Copyright (c) 2014 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 "xlator.h"
-#include "defaults.h"
-
-#include "meta-mem-types.h"
-#include "meta.h"
-#include "strfd.h"
-#include "globals.h"
-#include "lkowner.h"
-
-
-static int
-process_uuid_file_fill (xlator_t *this, inode_t *file, strfd_t *strfd)
-{
- strprintf (strfd, "%s\n", this->ctx->process_uuid);
- return strfd->size;
-}
-
-
-static struct meta_ops process_uuid_file_ops = {
- .file_fill = process_uuid_file_fill,
-};
-
-
-int
-meta_process_uuid_file_hook (call_frame_t *frame, xlator_t *this, loc_t *loc,
- dict_t *xdata)
-{
- meta_ops_set (loc->inode, this, &process_uuid_file_ops);
-
- return 0;
-}
diff --git a/xlators/meta/src/profile-file.c b/xlators/meta/src/profile-file.c
deleted file mode 100644
index 2a25c154699..00000000000
--- a/xlators/meta/src/profile-file.c
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- Copyright (c) 2014 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 "xlator.h"
-#include "defaults.h"
-
-#include "meta-mem-types.h"
-#include "meta.h"
-#include "strfd.h"
-#include "statedump.h"
-
-
-static int
-profile_file_fill (xlator_t *this, inode_t *file, strfd_t *strfd)
-{
- xlator_t *xl = NULL;
-
- xl = meta_ctx_get (file, this);
-
- gf_proc_dump_xlator_profile (xl, strfd);
-
- return strfd->size;
-}
-
-
-static struct meta_ops profile_file_ops = {
- .file_fill = profile_file_fill,
-};
-
-
-int
-meta_profile_file_hook (call_frame_t *frame, xlator_t *this, loc_t *loc,
- dict_t *xdata)
-{
- meta_ops_set (loc->inode, this, &profile_file_ops);
-
- meta_ctx_set (loc->inode, this, meta_ctx_get (loc->parent, this));
-
- return 0;
-}
diff --git a/xlators/meta/src/root-dir.c b/xlators/meta/src/root-dir.c
deleted file mode 100644
index d104d842cf9..00000000000
--- a/xlators/meta/src/root-dir.c
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- Copyright (c) 2014 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 "xlator.h"
-#include "defaults.h"
-
-#include "meta-mem-types.h"
-#include "meta.h"
-#include "meta-hooks.h"
-
-
-static struct meta_dirent root_dir_dirents[] = {
- DOT_DOTDOT,
-
- { .name = "graphs",
- .type = IA_IFDIR,
- .hook = meta_graphs_dir_hook,
- },
- { .name = "frames",
- .type = IA_IFREG,
- .hook = meta_frames_file_hook,
- },
- { .name = "logging",
- .type = IA_IFDIR,
- .hook = meta_logging_dir_hook,
- },
- { .name = "process_uuid",
- .type = IA_IFREG,
- .hook = meta_process_uuid_file_hook,
- },
- { .name = "version",
- .type = IA_IFREG,
- .hook = meta_version_file_hook,
- },
- { .name = "cmdline",
- .type = IA_IFREG,
- .hook = meta_cmdline_file_hook,
- },
- { .name = "mallinfo",
- .type = IA_IFREG,
- .hook = meta_mallinfo_file_hook,
- },
- { .name = "master",
- .type = IA_IFDIR,
- .hook = meta_master_dir_hook,
- },
- { .name = "measure_latency",
- .type = IA_IFREG,
- .hook = meta_measure_file_hook,
- },
- { .name = NULL }
-};
-
-
-static struct meta_ops meta_root_dir_ops = {
- .fixed_dirents = root_dir_dirents
-};
-
-
-int
-meta_root_dir_hook (call_frame_t *frame, xlator_t *this, loc_t *loc,
- dict_t *xdata)
-{
- meta_ops_set (loc->inode, this, &meta_root_dir_ops);
-
- return 0;
-}
diff --git a/xlators/meta/src/subvolume-link.c b/xlators/meta/src/subvolume-link.c
deleted file mode 100644
index ca71a751541..00000000000
--- a/xlators/meta/src/subvolume-link.c
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- Copyright (c) 2014 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 "xlator.h"
-#include "defaults.h"
-
-#include "meta-mem-types.h"
-#include "meta.h"
-
-
-static int
-subvolume_link_fill (xlator_t *this, inode_t *inode, strfd_t *strfd)
-{
- xlator_t *xl = NULL;
-
- xl = meta_ctx_get (inode, this);
-
- strprintf (strfd, "../../%s", xl->name);
-
- return 0;
-}
-
-
-struct meta_ops subvolume_link_ops = {
- .link_fill = subvolume_link_fill
-};
-
-
-int
-meta_subvolume_link_hook (call_frame_t *frame, xlator_t *this, loc_t *loc,
- dict_t *xdata)
-{
- int count = 0;
- int i = 0;
- xlator_t *xl = NULL;
- xlator_list_t *subv = NULL;
- xlator_t *subvol = NULL;
-
- count = strtol (loc->name, 0, 0);
- xl = meta_ctx_get (loc->parent, this);
-
- for (subv = xl->children; subv; subv = subv->next) {
- if (i == count) {
- subvol = subv->xlator;
- break;
- }
- i++;
- }
-
- meta_ctx_set (loc->inode, this, subvol);
-
- meta_ops_set (loc->inode, this, &subvolume_link_ops);
- return 0;
-}
diff --git a/xlators/meta/src/subvolumes-dir.c b/xlators/meta/src/subvolumes-dir.c
deleted file mode 100644
index f8d0e8039a1..00000000000
--- a/xlators/meta/src/subvolumes-dir.c
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- Copyright (c) 2014 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 "xlator.h"
-#include "defaults.h"
-
-#include "meta-mem-types.h"
-#include "meta.h"
-#include "meta-hooks.h"
-
-
-static int
-subvolumes_dir_fill (xlator_t *this, inode_t *dir, struct meta_dirent **dp)
-{
- struct meta_dirent *dirents = NULL;
- xlator_t *xl = NULL;
- xlator_list_t *subv = NULL;
- int i = 0;
- int count = 0;
-
- xl = meta_ctx_get (dir, this);
-
- for (subv = xl->children; subv; subv = subv->next)
- count++;
-
- dirents = GF_CALLOC (sizeof (*dirents), count, gf_meta_mt_dirents_t);
- if (!dirents)
- return -1;
-
- for (subv = xl->children; subv; subv = subv->next) {
- char num[16] = { };
- snprintf (num, 16, "%d", i);
-
- dirents[i].name = gf_strdup (num);
- dirents[i].type = IA_IFLNK;
- dirents[i].hook = meta_subvolume_link_hook;
- i++;
- }
-
- *dp = dirents;
-
- return count;
-}
-
-
-static struct meta_ops subvolumes_dir_ops = {
- .dir_fill = subvolumes_dir_fill
-};
-
-
-int
-meta_subvolumes_dir_hook (call_frame_t *frame, xlator_t *this, loc_t *loc,
- dict_t *xdata)
-{
- meta_ctx_set (loc->inode, this, meta_ctx_get (loc->parent, this));
-
- meta_ops_set (loc->inode, this, &subvolumes_dir_ops);
-
- return 0;
-}
diff --git a/xlators/meta/src/top-link.c b/xlators/meta/src/top-link.c
deleted file mode 100644
index 94b7f7a9f56..00000000000
--- a/xlators/meta/src/top-link.c
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- Copyright (c) 2014 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 "xlator.h"
-#include "defaults.h"
-
-#include "meta-mem-types.h"
-#include "meta.h"
-
-
-static int
-top_link_fill (xlator_t *this, inode_t *inode, strfd_t *strfd)
-{
- glusterfs_graph_t *graph = NULL;
-
- graph = meta_ctx_get (inode, this);
-
- strprintf (strfd, "%s", ((xlator_t *)graph->top)->name);
-
- return 0;
-}
-
-
-struct meta_ops top_link_ops = {
- .link_fill = top_link_fill
-};
-
-
-int
-meta_top_link_hook (call_frame_t *frame, xlator_t *this, loc_t *loc,
- dict_t *xdata)
-{
- meta_ops_set (loc->inode, this, &top_link_ops);
-
- meta_ctx_set (loc->inode, this, meta_ctx_get (loc->parent, this));
-
- return 0;
-}
diff --git a/xlators/meta/src/tree.c b/xlators/meta/src/tree.c
new file mode 100644
index 00000000000..a5ba08a3f3c
--- /dev/null
+++ b/xlators/meta/src/tree.c
@@ -0,0 +1,176 @@
+/*
+ Copyright (c) 2006-2009 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 <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <string.h>
+
+#include "glusterfs.h"
+#include "xlator.h"
+
+#include "meta.h"
+
+static int
+is_meta_path (const char *path)
+{
+ while (*path == '/')
+ path++;
+ if (!strncmp (path, ".meta", strlen (".meta")))
+ return 1;
+ return 0;
+}
+
+struct stat *
+new_stbuf (void)
+{
+ static int next_inode = 0;
+ struct stat *stbuf = CALLOC (1, sizeof (struct stat));
+
+ ERR_ABORT (stbuf);
+
+ stbuf->st_dev = 0;
+ stbuf->st_ino = next_inode++;
+ stbuf->st_mode = S_IRUSR | S_IRGRP | S_IROTH;
+ stbuf->st_nlink = 1;
+ stbuf->st_uid = 0;
+ stbuf->st_gid = 0;
+ stbuf->st_rdev = 0;
+ stbuf->st_size = 0;
+ stbuf->st_blksize = 0;
+ stbuf->st_blocks = 0;
+ stbuf->st_atime = time (NULL);
+ stbuf->st_atim.tv_nsec = 0;
+ stbuf->st_mtime = stbuf->st_atime;
+ stbuf->st_mtim.tv_nsec = 0;
+ stbuf->st_ctime = stbuf->st_ctime;
+ stbuf->st_ctim.tv_nsec = 0;
+
+ return stbuf;
+}
+
+/* find an entry among the siblings of an entry */
+static meta_dirent_t *
+find_entry (meta_dirent_t *node, const char *dir)
+{
+ meta_dirent_t *trav = node;
+ while (trav) {
+ if (!strcmp (trav->name, dir))
+ return trav;
+ trav = trav->next;
+ }
+ return NULL;
+}
+
+/*
+ * Return the meta_dirent_t corresponding to the pathname.
+ *
+ * If pathname does not exist in the meta tree, try to return
+ * its highest parent that does exist. The part of the
+ * pathname that is left over is returned in the value-result
+ * variable {remain}.
+ * For example, for "/.meta/xlators/brick1/view/foo/bar/baz",
+ * return the entry for "/.meta/xlators/brick1/view"
+ * and set remain to "/bar/baz"
+ */
+
+meta_dirent_t *
+lookup_meta_entry (meta_dirent_t *root, const char *path,
+ char **remain)
+{
+ char *_path = strdup (path);
+
+ if (!is_meta_path (path))
+ return NULL;
+
+ meta_dirent_t *trav = root;
+ char *dir = strtok (_path, "/");
+ dir = strtok (NULL, "/");
+
+ while (dir) {
+ meta_dirent_t *ntrav;
+ ntrav = find_entry (trav->children, dir);
+ if (!ntrav) {
+ /* we have reached bottom of the meta tree.
+ Unknown dragons lie further below */
+ if (remain) {
+ char *piece = dir;
+ while (piece) {
+ char *tmp = *remain;
+ if (*remain)
+ asprintf (remain, "/%s/%s", *remain, piece);
+ else
+ asprintf (remain, "/%s", piece);
+ if (tmp) free (tmp);
+ piece = strtok (NULL, "/");
+ }
+ }
+ return trav;
+ }
+ dir = strtok (NULL, "/");
+ trav = ntrav;
+ }
+
+ free (_path);
+ return trav;
+}
+
+meta_dirent_t *
+insert_meta_entry (meta_dirent_t *root, const char *path,
+ int type, struct stat *stbuf, struct xlator_fops *fops)
+{
+ if (!is_meta_path (path))
+ return NULL;
+ char *slashpos = strrchr (path, '/');
+ char *dir = strndup (path, slashpos - path);
+ meta_dirent_t *parent = lookup_meta_entry (root, dir, NULL);
+ if (!dir)
+ return NULL;
+
+ meta_dirent_t *new = CALLOC (1, sizeof (meta_dirent_t));
+ ERR_ABORT (new);
+ new->name = strdup (slashpos+1);
+ new->type = type;
+ new->parent = parent;
+ new->next = parent->children;
+ parent->children = new;
+ if (stbuf)
+ new->stbuf = stbuf;
+ else
+ new->stbuf = new_stbuf ();
+
+ new->stbuf->st_mode |= type;
+ new->fops = fops;
+ return new;
+}
+
+int main (void)
+{
+ meta_dirent_t *root = CALLOC (1, sizeof (meta_dirent_t));
+ ERR_ABORT (root);
+ root->name = strdup (".meta");
+
+ insert_meta_entry (root, "/.meta/version", S_IFREG, NULL, NULL);
+ return 0;
+}
diff --git a/xlators/meta/src/tree.h b/xlators/meta/src/tree.h
new file mode 100644
index 00000000000..bb2ffb976cb
--- /dev/null
+++ b/xlators/meta/src/tree.h
@@ -0,0 +1,35 @@
+/*
+ Copyright (c) 2006-2009 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 __TREE_H__
+#define __TREE_H__
+
+#ifndef _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+meta_dirent_t *
+insert_meta_entry (meta_dirent_t *root, const char *path,
+ int type, struct stat *stbuf, struct xlator_fops *fops);
+meta_dirent_t *
+lookup_meta_entry (meta_dirent_t *root, const char *path,
+ char **remain);
+
+#endif /* __TREE_H__ */
diff --git a/xlators/meta/src/type-file.c b/xlators/meta/src/type-file.c
deleted file mode 100644
index 1970f4e33e8..00000000000
--- a/xlators/meta/src/type-file.c
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- Copyright (c) 2014 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 "xlator.h"
-#include "defaults.h"
-
-#include "meta-mem-types.h"
-#include "meta.h"
-#include "strfd.h"
-#include "globals.h"
-#include "lkowner.h"
-
-
-static int
-type_file_fill (xlator_t *this, inode_t *file, strfd_t *strfd)
-{
- xlator_t *xl = NULL;
-
- xl = meta_ctx_get (file, this);
-
- strprintf (strfd, "%s\n", xl->type);
-
- return strfd->size;
-}
-
-
-static struct meta_ops type_file_ops = {
- .file_fill = type_file_fill,
-};
-
-
-int
-meta_type_file_hook (call_frame_t *frame, xlator_t *this, loc_t *loc,
- dict_t *xdata)
-{
- meta_ops_set (loc->inode, this, &type_file_ops);
-
- meta_ctx_set (loc->inode, this, meta_ctx_get (loc->parent, this));
-
- return 0;
-}
diff --git a/xlators/meta/src/version-file.c b/xlators/meta/src/version-file.c
deleted file mode 100644
index c402453ee96..00000000000
--- a/xlators/meta/src/version-file.c
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- Copyright (c) 2014 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 "xlator.h"
-#include "defaults.h"
-
-#include "meta-mem-types.h"
-#include "meta.h"
-#include "strfd.h"
-#include "globals.h"
-#include "lkowner.h"
-
-
-static int
-version_file_fill (xlator_t *this, inode_t *file, strfd_t *strfd)
-{
- strprintf (strfd, "{ \n \"Package Version\": \"%s\"\n}",
- PACKAGE_VERSION);
- return strfd->size;
-}
-
-
-static struct meta_ops version_file_ops = {
- .file_fill = version_file_fill,
-};
-
-
-int
-meta_version_file_hook (call_frame_t *frame, xlator_t *this, loc_t *loc,
- dict_t *xdata)
-{
- meta_ops_set (loc->inode, this, &version_file_ops);
-
- return 0;
-}
diff --git a/xlators/meta/src/view-dir.c b/xlators/meta/src/view-dir.c
deleted file mode 100644
index 6edd455b072..00000000000
--- a/xlators/meta/src/view-dir.c
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- Copyright (c) 2014 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 "xlator.h"
-#include "defaults.h"
-
-#include "meta-mem-types.h"
-#include "meta.h"
-#include "meta-hooks.h"
-
-
-static struct meta_dirent view_dir_dirents[] = {
- DOT_DOTDOT,
-
- { .name = NULL }
-};
-
-
-static struct meta_ops view_dir_ops = {
- .fixed_dirents = view_dir_dirents
-};
-
-
-int
-meta_view_dir_hook (call_frame_t *frame, xlator_t *this, loc_t *loc,
- dict_t *xdata)
-{
- meta_ctx_set (loc->inode, this, meta_ctx_get (loc->parent, this));
-
- meta_ops_set (loc->inode, this, &view_dir_ops);
-
- return 0;
-}
diff --git a/xlators/meta/src/view.c b/xlators/meta/src/view.c
new file mode 100644
index 00000000000..cbb0b710a97
--- /dev/null
+++ b/xlators/meta/src/view.c
@@ -0,0 +1,258 @@
+/*
+ Copyright (c) 2006-2009 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 "glusterfs.h"
+#include "xlator.h"
+
+#include "meta.h"
+
+/*
+ * This file contains fops for the files and directories in
+ * an xlator directory
+ */
+
+/* /.meta/xlators/.../type */
+
+int32_t
+meta_xlator_type_readv (call_frame_t *frame, xlator_t *this,
+ dict_t *fd, size_t size, off_t offset)
+{
+ meta_private_t *priv = (meta_private_t *) this->private;
+ meta_dirent_t *root = priv->tree;
+ data_t *path_data = dict_get (fd, this->name);
+
+ if (path_data) {
+ const char *path = data_to_str (path_data);
+ meta_dirent_t *file = lookup_meta_entry (root, path, NULL);
+ xlator_t *view_xlator = file->view_xlator;
+
+ int type_size;
+ type_size = strlen (view_xlator->type);
+
+ struct iovec vec;
+ vec.iov_base = view_xlator->type + offset;
+ vec.iov_len = min (type_size - offset, size);
+
+ STACK_UNWIND (frame, vec.iov_len, 0, &vec, 1);
+ return 0;
+ }
+}
+
+int32_t
+meta_xlator_type_getattr (call_frame_t *frame,
+ xlator_t *this,
+ const char *path)
+{
+ meta_private_t *priv = (meta_private_t *) this->private;
+ meta_dirent_t *root = priv->tree;
+
+ meta_dirent_t *file = lookup_meta_entry (root, path, NULL);
+ xlator_t *view_xlator = file->view_xlator;
+ file->stbuf->st_size = strlen (view_xlator->type);
+
+ STACK_UNWIND (frame, 0, 0, file->stbuf);
+ return 0;
+}
+
+struct xlator_fops meta_xlator_type_fops = {
+ .readv = meta_xlator_type_readv,
+ .getattr = meta_xlator_type_getattr
+};
+
+/*
+ * fops for the "view" directory
+ * {xlator}/view shows the filesystem as it appears
+ * to {xlator}
+ */
+
+static int32_t
+meta_xlator_view_getattr_cbk (call_frame_t *frame, void *cookie,
+ xlator_t *this, int32_t op_ret, int32_t op_errno,
+ struct stat *buf)
+{
+ STACK_UNWIND (frame, op_ret, op_errno, buf);
+ return 0;
+}
+
+int32_t
+meta_xlator_view_getattr (call_frame_t *frame,
+ xlator_t *this,
+ const char *path)
+{
+ meta_private_t *priv = (meta_private_t *) this->private;
+ meta_dirent_t *root = priv->tree;
+ char *op_path = NULL;
+
+ meta_dirent_t *file = lookup_meta_entry (root, path, &op_path);
+
+ if (op_path) {
+ STACK_WIND (frame, meta_xlator_view_getattr_cbk, file->view_xlator,
+ file->view_xlator->fops->getattr,
+ op_path);
+ }
+ else {
+ STACK_UNWIND (frame, 0, 0, file->stbuf);
+ }
+
+ return 0;
+}
+
+static int32_t
+meta_xlator_view_readdir_cbk (call_frame_t *frame, void *cookie,
+ xlator_t *this, int32_t op_ret, int32_t op_errno,
+ dir_entry_t *entries, int32_t count)
+{
+ STACK_UNWIND (frame, op_ret, op_errno, entries, count);
+ return 0;
+}
+
+int32_t
+meta_xlator_view_readdir (call_frame_t *frame,
+ xlator_t *this,
+ const char *path)
+{
+ meta_private_t *priv = (meta_private_t *) this->private;
+ meta_dirent_t *root = priv->tree;
+ char *op_path = NULL;
+
+ meta_dirent_t *dir = lookup_meta_entry (root, path, &op_path);
+
+ STACK_WIND (frame, meta_xlator_view_readdir_cbk,
+ dir->view_xlator, dir->view_xlator->fops->readdir,
+ op_path ? op_path : "/");
+ return 0;
+}
+
+static int32_t
+meta_xlator_view_open_cbk (call_frame_t *frame, void *cookie,
+ xlator_t *this,
+ int32_t op_ret, int32_t op_errno,
+ dict_t *ctx, struct stat *buf)
+{
+ STACK_UNWIND (frame, op_ret, op_errno, ctx, buf);
+ return 0;
+}
+
+int32_t
+meta_xlator_view_open (call_frame_t *frame, xlator_t *this,
+ const char *path, int32_t flags, mode_t mode)
+{
+ meta_private_t *priv = (meta_private_t *) this->private;
+ meta_dirent_t *root = priv->tree;
+ char *op_path = NULL;
+
+ meta_dirent_t *file = lookup_meta_entry (root, path, &op_path);
+ STACK_WIND (frame, meta_xlator_view_open_cbk,
+ file->view_xlator, file->view_xlator->fops->open,
+ op_path, flags, mode);
+ return 0;
+}
+
+int32_t
+meta_xlator_view_create (call_frame_t *frame, xlator_t *this,
+ const char *path, int32_t flags, mode_t mode)
+{
+ meta_private_t *priv = (meta_private_t *) this->private;
+ meta_dirent_t *root = priv->tree;
+ char *op_path = NULL;
+
+ meta_dirent_t *file = lookup_meta_entry (root, path, &op_path);
+ STACK_WIND (frame, meta_xlator_view_open_cbk,
+ file->view_xlator, file->view_xlator->fops->create,
+ op_path, flags, mode);
+ return 0;
+}
+
+static int32_t
+meta_xlator_view_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)
+{
+ STACK_UNWIND (frame, op_ret, op_errno, vector, count);
+ return 0;
+}
+
+int32_t
+meta_xlator_view_readv (call_frame_t *frame, xlator_t *this,
+ dict_t *fd, size_t size, off_t offset)
+{
+ meta_private_t *priv = (meta_private_t *) this->private;
+ meta_dirent_t *root = priv->tree;
+ data_t *path_data = dict_get (fd, this->name);
+
+ if (path_data) {
+ const char *path = data_to_str (path_data);
+ meta_dirent_t *file = lookup_meta_entry (root, path, NULL);
+
+ STACK_WIND (frame, meta_xlator_view_readv_cbk,
+ file->view_xlator, file->view_xlator->fops->readv,
+ fd, size, offset);
+ return 0;
+ }
+
+ STACK_UNWIND (frame, -1, EBADFD, NULL, 0);
+ return 0;
+}
+
+static int32_t
+meta_xlator_view_writev_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;
+}
+
+int32_t
+meta_xlator_view_writev (call_frame_t *frame, xlator_t *this,
+ dict_t *fd,
+ struct iovec *vector, int32_t count, off_t offset)
+{
+ meta_private_t *priv = (meta_private_t *) this->private;
+ meta_dirent_t *root = priv->tree;
+ data_t *path_data = dict_get (fd, this->name);
+
+ if (path_data) {
+ const char *path = data_to_str (path_data);
+ meta_dirent_t *file = lookup_meta_entry (root, path, NULL);
+
+ STACK_WIND (frame, meta_xlator_view_writev_cbk,
+ file->view_xlator, file->view_xlator->fops->writev,
+ fd, vector, count, offset);
+ return 0;
+ }
+
+ STACK_UNWIND (frame, -1, EBADFD, NULL, 0);
+ return 0;
+}
+
+struct xlator_fops meta_xlator_view_fops = {
+ .getattr = meta_xlator_view_getattr,
+ .readdir = meta_xlator_view_readdir,
+ .open = meta_xlator_view_open,
+ .create = meta_xlator_view_create,
+ .readv = meta_xlator_view_readv,
+ .writev = meta_xlator_view_writev
+};
diff --git a/xlators/meta/src/view.h b/xlators/meta/src/view.h
new file mode 100644
index 00000000000..d26d42e26c4
--- /dev/null
+++ b/xlators/meta/src/view.h
@@ -0,0 +1,32 @@
+/*
+ Copyright (c) 2006-2009 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 __VIEW_H__
+#define __VIEW_H__
+
+#ifndef _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+
+struct xlator_fops meta_xlator_type_fops;
+struct xlator_fops meta_xlator_view_fops;
+
+#endif /* __VIEW_H__ */
diff --git a/xlators/meta/src/volfile-file.c b/xlators/meta/src/volfile-file.c
deleted file mode 100644
index 899285763e0..00000000000
--- a/xlators/meta/src/volfile-file.c
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- Copyright (c) 2014 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 "xlator.h"
-#include "defaults.h"
-
-#include "meta-mem-types.h"
-#include "meta.h"
-#include "strfd.h"
-
-
-
-static int
-xldump_options (dict_t *this, char *key, data_t *value, void *strfd)
-{
- strprintf (strfd, " option %s %s\n", key, value->data);
- return 0;
-}
-
-
-static void
-xldump_subvolumes (xlator_t *this, void *strfd)
-{
- xlator_list_t *subv = NULL;
-
- if (!this->children)
- return;
-
- strprintf (strfd, " subvolumes");
-
- for (subv = this->children; subv; subv= subv->next)
- strprintf (strfd, " %s", subv->xlator->name);
-
- strprintf (strfd, "\n");
-}
-
-
-static void
-xldump (xlator_t *each, void *strfd)
-{
- strprintf (strfd, "volume %s\n", each->name);
- strprintf (strfd, " type %s\n", each->type);
- dict_foreach (each->options, xldump_options, strfd);
-
- xldump_subvolumes (each, strfd);
-
- strprintf (strfd, "end-volume\n");
- strprintf (strfd, "\n");
-}
-
-
-static int
-volfile_file_fill (xlator_t *this, inode_t *file, strfd_t *strfd)
-{
- glusterfs_graph_t *graph = NULL;
-
- graph = meta_ctx_get (file, this);
-
- xlator_foreach_depth_first (graph->top, xldump, strfd);
-
- return strfd->size;
-}
-
-
-static struct meta_ops volfile_file_ops = {
- .file_fill = volfile_file_fill,
-};
-
-
-int
-meta_volfile_file_hook (call_frame_t *frame, xlator_t *this, loc_t *loc,
- dict_t *xdata)
-{
- meta_ops_set (loc->inode, this, &volfile_file_ops);
-
- meta_ctx_set (loc->inode, this, meta_ctx_get (loc->parent, this));
-
- return 0;
-}
diff --git a/xlators/meta/src/xlator-dir.c b/xlators/meta/src/xlator-dir.c
deleted file mode 100644
index 09b7bde62de..00000000000
--- a/xlators/meta/src/xlator-dir.c
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- Copyright (c) 2014 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 "xlator.h"
-#include "defaults.h"
-
-#include "meta-mem-types.h"
-#include "meta.h"
-#include "meta-hooks.h"
-
-
-static struct meta_dirent xlator_dir_dirents[] = {
- DOT_DOTDOT,
-
- { .name = "view",
- .type = IA_IFDIR,
- .hook = meta_view_dir_hook,
- },
- { .name = "type",
- .type = IA_IFREG,
- .hook = meta_type_file_hook,
- },
- { .name = "name",
- .type = IA_IFREG,
- .hook = meta_name_file_hook,
- },
- { .name = "subvolumes",
- .type = IA_IFDIR,
- .hook = meta_subvolumes_dir_hook,
- },
- { .name = "options",
- .type = IA_IFDIR,
- .hook = meta_options_dir_hook,
- },
- { .name = "private",
- .type = IA_IFREG,
- .hook = meta_private_file_hook,
- },
- { .name = "history",
- .type = IA_IFREG,
- .hook = meta_history_file_hook,
- },
- { .name = "meminfo",
- .type = IA_IFREG,
- .hook = meta_meminfo_file_hook,
- },
- { .name = "profile",
- .type = IA_IFREG,
- .hook = meta_profile_file_hook,
- },
- { .name = NULL }
-};
-
-
-static struct meta_ops xlator_dir_ops = {
- .fixed_dirents = xlator_dir_dirents
-};
-
-
-int
-meta_xlator_dir_hook (call_frame_t *frame, xlator_t *this, loc_t *loc,
- dict_t *xdata)
-{
- glusterfs_graph_t *graph = NULL;
- xlator_t *xl = NULL;
-
- graph = meta_ctx_get (loc->parent, this);
-
- xl = xlator_search_by_name (graph->first, loc->name);
-
- meta_ctx_set (loc->inode, this, xl);
-
- meta_ops_set (loc->inode, this, &xlator_dir_ops);
-
- return 0;
-}
-
-
-int
-meta_master_dir_hook (call_frame_t *frame, xlator_t *this, loc_t *loc,
- dict_t *xdata)
-{
- meta_ctx_set (loc->inode, this, this->ctx->master);
-
- meta_ops_set (loc->inode, this, &xlator_dir_ops);
-
- return 0;
-}
diff --git a/xlators/mgmt/Makefile.am b/xlators/mgmt/Makefile.am
deleted file mode 100644
index bf09b07c309..00000000000
--- a/xlators/mgmt/Makefile.am
+++ /dev/null
@@ -1,3 +0,0 @@
-SUBDIRS = glusterd
-
-CLEANFILES =
diff --git a/xlators/mgmt/glusterd/Makefile.am b/xlators/mgmt/glusterd/Makefile.am
deleted file mode 100644
index d471a3f9243..00000000000
--- a/xlators/mgmt/glusterd/Makefile.am
+++ /dev/null
@@ -1,3 +0,0 @@
-SUBDIRS = src
-
-CLEANFILES =
diff --git a/xlators/mgmt/glusterd/src/Makefile.am b/xlators/mgmt/glusterd/src/Makefile.am
deleted file mode 100644
index 7514eb4d914..00000000000
--- a/xlators/mgmt/glusterd/src/Makefile.am
+++ /dev/null
@@ -1,49 +0,0 @@
-xlator_LTLIBRARIES = glusterd.la
-xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/mgmt
-glusterd_la_CPPFLAGS = $(AM_CPPFLAGS) "-DFILTERDIR=\"$(libdir)/glusterfs/$(PACKAGE_VERSION)/filter\""
-glusterd_la_LDFLAGS = -module -avoid-version
-if ENABLE_BD_XLATOR
-glusterd_la_LDFLAGS += -llvm2app
-endif
-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-volume-set.c \
- glusterd-locks.c glusterd-snapshot.c glusterd-mgmt-handler.c \
- glusterd-mgmt.c glusterd-peer-utils.c
-
-glusterd_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la \
- $(top_builddir)/rpc/xdr/src/libgfxdr.la \
- $(top_builddir)/rpc/rpc-lib/src/libgfrpc.la \
- $(XML_LIBS) -lcrypto
-
-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 glusterd-locks.h \
- glusterd-mgmt.h glusterd-messages.h glusterd-peer-utils.h
-
-AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \
- -I$(rpclibdir) -I$(CONTRIBDIR)/rbtree \
- -I$(top_srcdir)/rpc/xdr/src -I$(top_srcdir)/rpc/rpc-lib/src \
- -I$(CONTRIBDIR)/uuid -I$(CONTRIBDIR)/mount \
- -DSBIN_DIR=\"$(sbindir)\" -DDATADIR=\"$(localstatedir)\" \
- -DGSYNCD_PREFIX=\"$(libexecdir)/glusterfs\"\
- -DSYNCDAEMON_COMPILE=$(SYNCDAEMON_COMPILE) $(XML_CPPFLAGS)
-
-AM_CFLAGS = -Wall $(GF_CFLAGS)
-
-AM_LDFLAGS = -L$(xlatordir)
-
-CLEANFILES =
-
-install-data-hook:
-if GF_INSTALL_GLUSTERD_WORKDIR
- $(MKDIR_P) $(DESTDIR)$(GLUSTERD_WORKDIR)
- (stat $(DESTDIR)$(sysconfdir)/glusterd && \
- mv $(DESTDIR)$(sysconfdir)/glusterd $(DESTDIR)$(GLUSTERD_WORKDIR)) || true;
- (ln -sf $(DESTDIR)$(GLUSTERD_WORKDIR) $(sysconfdir)/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 089c7d637c9..00000000000
--- a/xlators/mgmt/glusterd/src/glusterd-brick-ops.c
+++ /dev/null
@@ -1,2191 +0,0 @@
-/*
- Copyright (c) 2011-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 "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;
- case GF_CLUSTER_TYPE_DISPERSE:
- snprintf (err_str, err_len, "Volume %s cannot be converted "
- "from dispersed to striped-"
- "dispersed", volinfo->volname);
- gf_log(THIS->name, GF_LOG_ERROR, "%s", err_str);
- goto out;
- }
-
-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;
- case GF_CLUSTER_TYPE_DISPERSE:
- snprintf (err_str, err_len, "Volume %s cannot be converted "
- "from dispersed to replicated-"
- "dispersed", volinfo->volname);
- gf_log(THIS->name, GF_LOG_ERROR, "%s", err_str);
- goto out;
- }
-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:
- case GF_CLUSTER_TYPE_DISPERSE:
- 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;
- 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);
-
- ret = xdr_to_generic (req->msg[0], &cli_req,
- (xdrproc_t)xdr_gf_cli_req);
- if (ret < 0) {
- //failed to decode msg;
- req->rpc_err = GARBAGE_ARGS;
- snprintf (err_str, sizeof (err_str), "Garbage args received");
- goto out;
- }
-
- gf_log (this->name, 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 (this->name, GF_LOG_ERROR,
- "failed to "
- "unserialize req-buffer to dictionary");
- snprintf (err_str, sizeof (err_str), "Unable to decode "
- "the command");
- goto out;
- }
- }
-
- ret = dict_get_str (dict, "volname", &volname);
-
- if (ret) {
- snprintf (err_str, sizeof (err_str), "Unable to get volume "
- "name");
- gf_log (this->name, GF_LOG_ERROR, "%s", err_str);
- goto out;
- }
-
- if (!(ret = glusterd_check_volume_exists (volname))) {
- ret = -1;
- snprintf (err_str, sizeof (err_str), "Volume %s does not exist",
- volname);
- gf_log (this->name, GF_LOG_ERROR, "%s", err_str);
- goto out;
- }
-
- ret = dict_get_int32 (dict, "count", &brick_count);
- if (ret) {
- snprintf (err_str, sizeof (err_str), "Unable to get volume "
- "brick count");
- gf_log (this->name, 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, "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);
- }
-
- if (!dict_get (dict, "force")) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to get flag");
- goto out;
- }
-
- 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 (this->name, 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, sizeof (err_str), "Incorrect number "
- "of bricks supplied %d with count %d",
- brick_count, volinfo->dist_leaf_count);
- gf_log (this->name, 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 (this->name, 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 (this->name, 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 (this->name, GF_LOG_ERROR, "%s", err_str);
- goto out;
- }
-
- 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_synctask (req, GD_OP_ADD_BRICK, dict);
-
-out:
- if (ret) {
- 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_to_cli (req, cli_rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gf_cli_rsp, dict);
- ret = 0; //sent error to cli, prevent second reply
- }
-
- free (cli_req.dict.dict_val); //its malloced by xdr
-
- return ret;
-}
-
-int
-glusterd_handle_add_brick (rpcsvc_request_t *req)
-{
- return glusterd_big_locked_handler (req, __glusterd_handle_add_brick);
-}
-
-static int
-subvol_matcher_init (int **subvols, int count)
-{
- int ret = -1;
-
- *subvols = GF_CALLOC (count, sizeof(int), gf_gld_mt_int);
- if (*subvols)
- ret = 0;
-
- return ret;
-}
-
-static void
-subvol_matcher_update (int *subvols, glusterd_volinfo_t *volinfo,
- glusterd_brickinfo_t *brickinfo)
-{
- glusterd_brickinfo_t *tmp = NULL;
- int32_t sub_volume = 0;
- int 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 (THIS->name, GF_LOG_DEBUG, LOGSTR_FOUND_BRICK,
- brickinfo->hostname, brickinfo->path,
- volinfo->volname);
- sub_volume = (pos / volinfo->dist_leaf_count);
- subvols[sub_volume]++;
- break;
- }
-
-}
-
-static int
-subvol_matcher_verify (int *subvols, glusterd_volinfo_t *volinfo, char *err_str,
- size_t err_len, char *vol_type, int replica_count)
-{
- int i = 0;
- int ret = 0;
- int count = volinfo->replica_count-replica_count;
-
- if (replica_count) {
- for (i = 0; i < volinfo->subvol_count; i++) {
- if (subvols[i] != count) {
- ret = -1;
- snprintf (err_str, err_len, "Remove exactly %d"
- " brick(s) from each subvolume.", count);
- break;
- }
- }
- return ret;
- }
-
- do {
-
- if (subvols[i] % volinfo->dist_leaf_count == 0) {
- continue;
- } else {
- ret = -1;
- snprintf (err_str, err_len,
- "Bricks not from same subvol for %s", vol_type);
- break;
- }
- } while (++i < volinfo->subvol_count);
-
- return ret;
-}
-
-static void
-subvol_matcher_destroy (int *subvols)
-{
- GF_FREE (subvols);
-}
-
-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;
- int *subvols = 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;
- char *volname = 0;
- xlator_t *this = NULL;
-
- GF_ASSERT (req);
- this = THIS;
- GF_ASSERT (this);
-
- ret = xdr_to_generic (req->msg[0], &cli_req,
- (xdrproc_t)xdr_gf_cli_req);
- if (ret < 0) {
- //failed to decode msg;
- req->rpc_err = GARBAGE_ARGS;
- snprintf (err_str, sizeof (err_str), "Received garbage args");
- goto out;
- }
-
-
- gf_log (this->name, 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 (this->name, GF_LOG_ERROR,
- "failed to "
- "unserialize req-buffer to dictionary");
- snprintf (err_str, sizeof (err_str), "Unable to decode "
- "the command");
- goto out;
- }
- }
-
- ret = dict_get_str (dict, "volname", &volname);
- if (ret) {
- snprintf (err_str, sizeof (err_str), "Unable to get volume "
- "name");
- gf_log (this->name, GF_LOG_ERROR, "%s", err_str);
- goto out;
- }
-
- ret = dict_get_int32 (dict, "count", &count);
- if (ret) {
- snprintf (err_str, sizeof (err_str), "Unable to get brick "
- "count");
- gf_log (this->name, GF_LOG_ERROR, "%s", err_str);
- goto out;
- }
-
- ret = glusterd_volinfo_find (volname, &volinfo);
- if (ret) {
- snprintf (err_str, sizeof (err_str),"Volume %s does not exist",
- volname);
- gf_log (this->name, 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 if (volinfo->type == GF_CLUSTER_TYPE_DISPERSE) {
- strcpy (vol_type, "disperse");
- } else {
- strcpy (vol_type, "distribute");
- }
-
- /* Do not allow remove-brick if the volume is a stripe volume*/
- if ((volinfo->type == GF_CLUSTER_TYPE_STRIPE) &&
- (volinfo->brick_count == volinfo->stripe_count)) {
- snprintf (err_str, sizeof (err_str),
- "Removing brick from a stripe volume is not allowed");
- gf_log (this->name, 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, sizeof(err_str),
- "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, sizeof (err_str),
- "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, sizeof (err_str), "Remove brick "
- "incorrect brick count of %d for %s %d",
- count, vol_type, volinfo->dist_leaf_count);
- gf_log (this->name, 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, " ");
-
- if ((volinfo->type != GF_CLUSTER_TYPE_NONE) &&
- (volinfo->subvol_count > 1)) {
- ret = subvol_matcher_init (&subvols, volinfo->subvol_count);
- if (ret)
- goto out;
- }
-
- while ( i <= count) {
- snprintf (key, sizeof (key), "brick%d", i);
- ret = dict_get_str (dict, key, &brick);
- if (ret) {
- snprintf (err_str, sizeof (err_str), "Unable to get %s",
- key);
- gf_log (this->name, GF_LOG_ERROR, "%s", err_str);
- goto out;
- }
- gf_log (this->name, 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, sizeof (err_str), "Incorrect brick "
- "%s for volume %s", brick, volname);
- gf_log (this->name, 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;
-
- /* Find which subvolume the brick belongs to */
- subvol_matcher_update (subvols, volinfo, brickinfo);
- }
-
- /* Check if the bricks belong to the same subvolumes.*/
- if ((volinfo->type != GF_CLUSTER_TYPE_NONE) &&
- (volinfo->subvol_count > 1)) {
- ret = subvol_matcher_verify (subvols, volinfo,
- err_str, sizeof(err_str),
- vol_type, replica_count);
- if (ret)
- goto out;
- }
-
- ret = glusterd_op_begin_synctask (req, GD_OP_REMOVE_BRICK, dict);
-
-out:
- if (ret) {
- rsp.op_ret = -1;
- rsp.op_errno = 0;
- if (err_str[0] == '\0')
- snprintf (err_str, sizeof (err_str),
- "Operation failed");
- gf_log (this->name, GF_LOG_ERROR, "%s", err_str);
- rsp.op_errstr = err_str;
- cli_rsp = &rsp;
- glusterd_to_cli (req, cli_rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gf_cli_rsp, dict);
-
- ret = 0; //sent error to cli, prevent second reply
-
- }
-
- GF_FREE (brick_list);
- subvol_matcher_destroy (subvols);
- free (cli_req.dict.dict_val); //its malloced by xdr
-
- return ret;
-}
-
-int
-glusterd_handle_remove_brick (rpcsvc_request_t *req)
-{
- return glusterd_big_locked_handler (req,
- __glusterd_handle_remove_brick);
-}
-
-static int
-_glusterd_restart_gsync_session (dict_t *this, char *key,
- data_t *value, void *data)
-{
- char *slave = NULL;
- char *slave_buf = NULL;
- char *path_list = NULL;
- char *slave_vol = NULL;
- char *slave_host = NULL;
- char *slave_url = NULL;
- char *conf_path = NULL;
- char **errmsg = NULL;
- int ret = -1;
- glusterd_gsync_status_temp_t *param = NULL;
- gf_boolean_t is_running = _gf_false;
-
- param = (glusterd_gsync_status_temp_t *)data;
-
- GF_ASSERT (param);
- GF_ASSERT (param->volinfo);
-
- slave = strchr(value->data, ':');
- if (slave) {
- slave++;
- slave_buf = gf_strdup (slave);
- if (!slave_buf) {
- gf_log ("", GF_LOG_ERROR,
- "Failed to gf_strdup");
- ret = -1;
- goto out;
- }
- }
- else
- return 0;
-
- ret = dict_set_dynstr (param->rsp_dict, "slave", slave_buf);
- if (ret) {
- gf_log ("", GF_LOG_ERROR,
- "Unable to store slave");
- if (slave_buf)
- GF_FREE(slave_buf);
- goto out;
- }
-
- ret = glusterd_get_slave_details_confpath (param->volinfo,
- param->rsp_dict, &slave_url,
- &slave_host, &slave_vol,
- &conf_path, errmsg);
- if (ret) {
- if (*errmsg)
- gf_log ("", GF_LOG_ERROR, "%s", *errmsg);
- else
- gf_log ("", GF_LOG_ERROR,
- "Unable to fetch slave or confpath details.");
- goto out;
- }
-
- /* In cases that gsyncd is not running, we will not invoke it
- * because of add-brick. */
- ret = glusterd_check_gsync_running_local (param->volinfo->volname,
- slave, conf_path,
- &is_running);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "gsync running validation failed.");
- goto out;
- }
- if (_gf_false == is_running) {
- gf_log ("", GF_LOG_DEBUG, "gsync session for %s and %s is"
- " not running on this node. Hence not restarting.",
- param->volinfo->volname, slave);
- ret = 0;
- goto out;
- }
-
- ret = glusterd_get_local_brickpaths (param->volinfo, &path_list);
- if (!path_list) {
- gf_log ("", GF_LOG_DEBUG, "This node not being part of"
- " volume should not be running gsyncd. Hence"
- " no gsyncd process to restart.");
- ret = 0;
- goto out;
- }
-
- ret = glusterd_check_restart_gsync_session (param->volinfo, slave,
- param->rsp_dict, path_list,
- conf_path, 0);
- if (ret)
- gf_log ("", GF_LOG_ERROR,
- "Unable to restart gsync session.");
-
-out:
- gf_log ("", GF_LOG_DEBUG, "Returning %d.", ret);
- return ret;
-}
-
-/* op-sm */
-
-int
-glusterd_op_perform_add_bricks (glusterd_volinfo_t *volinfo, int32_t count,
- char *bricks, dict_t *dict)
-{
- 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;
- glusterd_brickinfo_t *brickinfo = NULL;
- glusterd_gsync_status_temp_t param = {0, };
- gf_boolean_t restart_needed = 0;
- char msg[1024] __attribute__((unused)) = {0, };
- int caps = 0;
- int brickid = 0;
- char key[PATH_MAX] = "";
- char *brick_mount_dir = NULL;
- xlator_t *this = NULL;
- glusterd_conf_t *conf = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (volinfo);
-
- conf = this->private;
- GF_ASSERT (conf);
-
- 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);
- }
-
- brickid = glusterd_get_next_available_brickid (volinfo);
- if (brickid < 0)
- goto out;
- while ( i <= count) {
- ret = glusterd_brickinfo_new_from_brick (brick, &brickinfo);
- if (ret)
- goto out;
-
- GLUSTERD_ASSIGN_BRICKID_TO_BRICKINFO (brickinfo, volinfo,
- brickid++);
-
- /* A bricks mount dir is required only by snapshots which were
- * introduced in gluster-3.6.0
- */
- if (conf->op_version >= GD_OP_VERSION_3_6_0) {
- brick_mount_dir = NULL;
-
- snprintf (key, sizeof(key), "brick%d.mount_dir", i);
- ret = dict_get_str (dict, key, &brick_mount_dir);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "%s not present", key);
- goto out;
- }
- strncpy (brickinfo->mount_dir, brick_mount_dir,
- sizeof(brickinfo->mount_dir));
- }
-
- 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 = glusterd_get_dist_leaf_count (volinfo);
-
- /* backward compatibility */
- volinfo->sub_count = ((volinfo->dist_leaf_count == 1) ? 0:
- volinfo->dist_leaf_count);
-
- volinfo->subvol_count = (volinfo->brick_count /
- volinfo->dist_leaf_count);
-
- ret = glusterd_create_volfiles_and_notify_services (volinfo);
- if (ret)
- goto out;
-
- ret = 0;
- if (GLUSTERD_STATUS_STARTED != volinfo->status)
- goto out;
-
- brick_list = gf_strdup (bricks);
- free_ptr2 = brick_list;
- i = 1;
-
- if (count)
- brick = strtok_r (brick_list+1, " \n", &saveptr);
-#ifdef HAVE_BD_XLATOR
- if (brickinfo->vg[0])
- caps = CAPS_BD | CAPS_THIN |
- CAPS_OFFLOAD_COPY | CAPS_OFFLOAD_SNAPSHOT;
-#endif
-
- while (i <= count) {
- ret = glusterd_volume_brickinfo_get_by_brick (brick, volinfo,
- &brickinfo);
- if (ret)
- goto out;
-#ifdef HAVE_BD_XLATOR
- /* Check for VG/thin pool if its BD volume */
- if (brickinfo->vg[0]) {
- ret = glusterd_is_valid_vg (brickinfo, 0, msg);
- if (ret) {
- gf_log (THIS->name, GF_LOG_CRITICAL, "%s", msg);
- goto out;
- }
- /* if anyone of the brick does not have thin support,
- disable it for entire volume */
- caps &= brickinfo->caps;
- } else
- caps = 0;
-#endif
-
- if (uuid_is_null (brickinfo->uuid)) {
- ret = glusterd_resolve_brick (brickinfo);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, FMTSTR_RESOLVE_BRICK,
- brickinfo->hostname, brickinfo->path);
- goto out;
- }
- }
-
- ret = glusterd_brick_start (volinfo, brickinfo,
- _gf_true);
- if (ret)
- goto out;
- i++;
- brick = strtok_r (NULL, " \n", &saveptr);
-
- /* Check if the brick is added in this node, and set
- * the restart_needed flag. */
- if ((!uuid_compare (brickinfo->uuid, MY_UUID)) &&
- !restart_needed) {
- restart_needed = 1;
- gf_log ("", GF_LOG_DEBUG,
- "Restart gsyncd session, if it's already "
- "running.");
- }
- }
-
- /* If the restart_needed flag is set, restart gsyncd sessions for that
- * particular master with all the slaves. */
- if (restart_needed) {
- param.rsp_dict = dict;
- param.volinfo = volinfo;
- dict_foreach (volinfo->gsync_slaves,
- _glusterd_restart_gsync_session, &param);
- }
- volinfo->caps = caps;
-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) {
- ret = glusterd_brick_stop (volinfo, brickinfo,
- _gf_true);
- if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR, "Unable to stop "
- "glusterfs, ret: %d", ret);
- }
- 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, dict_t *rsp_dict)
-{
- int ret = 0;
- char *volname = NULL;
- int count = 0;
- int replica_count = 0;
- int i = 0;
- int32_t local_brick_count = 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;
- xlator_t *this = NULL;
- char msg[2048] = {0,};
- char key[PATH_MAX] = "";
- gf_boolean_t brick_alloc = _gf_false;
- char *all_bricks = NULL;
- char *str_ret = NULL;
- gf_boolean_t is_force = _gf_false;
- glusterd_conf_t *conf = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- conf = this->private;
- GF_ASSERT (conf);
-
- ret = dict_get_int32 (dict, "replica-count", &replica_count);
- if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR,
- "Unable to get replica count");
- }
-
- if (replica_count > 0) {
- ret = op_version_check (this, GD_OP_VER_PERSISTENT_AFR_XATTRS,
- msg, sizeof(msg));
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "%s", msg);
- *op_errstr = gf_strdup (msg);
- 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;
- }
-
- is_force = dict_get_str_boolean (dict, "force", _gf_false);
-
- 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)) {
-#ifdef HAVE_BD_XLATOR
- if (brickinfo->vg[0]) {
- ret = glusterd_is_valid_vg (brickinfo, 1, msg);
- if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR, "%s",
- msg);
- *op_errstr = gf_strdup (msg);
- goto out;
- }
- }
-#endif
-
- ret = glusterd_validate_and_create_brickpath (brickinfo,
- volinfo->volume_id,
- op_errstr, is_force);
- if (ret)
- goto out;
-
- /* A bricks mount dir is required only by snapshots which were
- * introduced in gluster-3.6.0
- */
- if (conf->op_version >= GD_OP_VERSION_3_6_0) {
- ret = glusterd_get_brick_mount_dir
- (brickinfo->path, brickinfo->hostname,
- brickinfo->mount_dir);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to get brick mount_dir");
- goto out;
- }
-
- snprintf (key, sizeof(key), "brick%d.mount_dir",
- i + 1);
- ret = dict_set_dynstr_with_alloc
- (rsp_dict, key, brickinfo->mount_dir);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to set %s", key);
- goto out;
- }
- }
-
- local_brick_count = i + 1;
- }
-
- glusterd_brickinfo_delete (brickinfo);
- brick_alloc = _gf_false;
- brickinfo = NULL;
- brick = strtok_r (NULL, " \n", &saveptr);
- i++;
- }
-
- ret = dict_set_int32 (rsp_dict, "brick_count",
- local_brick_count);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to set local_brick_count");
- goto out;
- }
-
-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;
- char *task_id_str = NULL;
- xlator_t *this = NULL;
- int i = 1;
- char key[256] = {0,};
- char *brick = NULL;
- glusterd_brickinfo_t *brickinfo = NULL;
-
- this = THIS;
- GF_ASSERT (this);
-
- ret = op_version_check (this, GD_OP_VER_PERSISTENT_AFR_XATTRS,
- msg, sizeof(msg));
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "%s", msg);
- *op_errstr = gf_strdup (msg);
- 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, "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 (this->name, GF_LOG_ERROR,
- "Unable to get brick command");
- goto out;
- }
- cmd = flag;
-
- ret = dict_get_int32 (dict, "count", &brick_count);
- if (ret) {
- gf_log (this->name, 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;
- }
-
- 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 ((volinfo->type == GF_CLUSTER_TYPE_REPLICATE) &&
- dict_get (dict, "replica-count")) {
- snprintf (msg, sizeof(msg), "Migration of data is not "
- "needed when reducing replica count. Use the"
- " 'force' option");
- errstr = gf_strdup (msg);
- gf_log (this->name, GF_LOG_ERROR, "%s", errstr);
- goto out;
- }
-
- 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 (!gd_is_remove_brick_committed (volinfo)) {
- snprintf (msg, sizeof (msg), "An earlier remove-brick "
- "task exists for volume %s. Either commit it"
- " or stop it before starting a new task.",
- volinfo->volname);
- errstr = gf_strdup (msg);
- gf_log (this->name, GF_LOG_ERROR, "Earlier remove-brick"
- " task exists for volume %s.",
- volinfo->volname);
- goto out;
- }
- if (glusterd_is_defrag_on(volinfo)) {
- errstr = gf_strdup("Rebalance is in progress. Please "
- "retry after completion");
- gf_log (this->name, GF_LOG_ERROR, "%s", errstr);
- goto out;
- }
-
- if (is_origin_glusterd (dict)) {
- ret = glusterd_generate_and_set_task_id
- (dict, GF_REMOVE_BRICK_TID_KEY);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to generate task-id");
- goto out;
- }
- } else {
- ret = dict_get_str (dict, GF_REMOVE_BRICK_TID_KEY,
- &task_id_str);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING,
- "Missing remove-brick-id");
- ret = 0;
- }
- }
- 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;
- }
-
- /* Do not allow commit if the bricks are not decommissioned */
- for ( i = 1; i <= brick_count; i++ ) {
- snprintf (key, sizeof (key), "brick%d", i);
- ret = dict_get_str (dict, key, &brick);
- if (ret) {
- snprintf (msg, sizeof (msg),
- "Unable to get %s", key);
- errstr = gf_strdup (msg);
- goto out;
- }
-
- ret =
- glusterd_volume_brickinfo_get_by_brick(brick, volinfo,
- &brickinfo);
- if (ret) {
- snprintf (msg, sizeof (msg), "Incorrect brick "
- "%s for volume %s", brick, volname);
- errstr = gf_strdup (msg);
- goto out;
- }
- if ( !brickinfo->decommissioned ) {
- snprintf (msg, sizeof (msg), "Brick %s "
- "is not decommissioned. "
- "Use start or force option",
- brick);
- errstr = gf_strdup (msg);
- ret = -1;
- goto out;
- }
- }
-
- break;
-
- case GF_OP_CMD_COMMIT_FORCE:
- break;
- }
- ret = 0;
-
-out:
- gf_log (this->name, 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) {
- /*TODO: use the 'atomic' flavour of brick_stop*/
- 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;
- }
-
- 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;
- char *task_id_str = NULL;
- xlator_t *this = NULL;
- dict_t *bricks_dict = NULL;
- char *brick_tmpstr = NULL;
-
- this = THIS;
- GF_ASSERT (this);
-
- 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 allocate memory");
- goto out;
- }
-
- ret = dict_get_int32 (dict, "command", &flag);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Unable to get command");
- goto out;
- }
- cmd = flag;
-
- /* Set task-id, if available, in ctx dict for operations other than
- * start
- */
- if (is_origin_glusterd (dict) && (cmd != GF_OP_CMD_START)) {
- if (!uuid_is_null (volinfo->rebal.rebalance_id)) {
- ret = glusterd_copy_uuid_to_dict
- (volinfo->rebal.rebalance_id, dict,
- GF_REMOVE_BRICK_TID_KEY);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to set remove-brick-id");
- goto out;
- }
- }
- }
-
- /* Clear task-id, rebal.op and stored bricks on commmitting/stopping
- * remove-brick */
- if ((cmd != GF_OP_CMD_START) || (cmd != GF_OP_CMD_STATUS)) {
- uuid_clear (volinfo->rebal.rebalance_id);
- volinfo->rebal.op = GD_OP_NONE;
- dict_unref (volinfo->rebal.dict);
- volinfo->rebal.dict = NULL;
- }
-
- 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:
- /* Reset defrag status to 'NOT STARTED' whenever a
- * remove-brick/rebalance command is issued to remove
- * stale information from previous run.
- */
- volinfo->rebal.defrag_status = GF_DEFRAG_STATUS_NOT_STARTED;
- ret = dict_get_str (dict, GF_REMOVE_BRICK_TID_KEY, &task_id_str);
- if (ret) {
- gf_log (this->name, GF_LOG_DEBUG,
- "Missing remove-brick-id");
- ret = 0;
- } else {
- uuid_parse (task_id_str, volinfo->rebal.rebalance_id) ;
- volinfo->rebal.op = GD_OP_REMOVE_BRICK;
- }
- force = 0;
- break;
-
- case GF_OP_CMD_COMMIT:
- force = 1;
- break;
-
- case GF_OP_CMD_COMMIT_FORCE:
-
- if (volinfo->decommission_in_progress) {
- if (volinfo->rebal.defrag) {
- LOCK (&volinfo->rebal.defrag->lock);
- /* Fake 'rebalance-complete' so the graph change
- happens right away */
- volinfo->rebal.defrag_status =
- GF_DEFRAG_STATUS_COMPLETE;
-
- UNLOCK (&volinfo->rebal.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;
- }
-
- /* Save the list of bricks for later usage only on starting a
- * remove-brick. Right now this is required for displaying the task
- * parameters with task status in volume status.
- */
- if (GF_OP_CMD_START == cmd) {
- bricks_dict = dict_new ();
- if (!bricks_dict) {
- ret = -1;
- goto out;
- }
- ret = dict_set_int32 (bricks_dict, "count", count);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to save remove-brick count");
- goto out;
- }
- }
- while ( i <= count) {
- snprintf (key, 256, "brick%d", i);
- ret = dict_get_str (dict, key, &brick);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Unable to get %s",
- key);
- goto out;
- }
-
- if (GF_OP_CMD_START == cmd) {
- brick_tmpstr = gf_strdup (brick);
- if (!brick_tmpstr) {
- ret = -1;
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to duplicate brick name");
- goto out;
- }
- ret = dict_set_dynstr (bricks_dict, key, brick_tmpstr);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to add brick to dict");
- goto out;
- }
- brick_tmpstr = NULL;
- }
-
- ret = glusterd_op_perform_remove_brick (volinfo, brick, force,
- &need_rebalance);
- if (ret)
- goto out;
- i++;
- }
- if (GF_OP_CMD_START == cmd)
- volinfo->rebal.dict = dict_ref (bricks_dict);
-
- 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->sub_count = replica_count;
- volinfo->dist_leaf_count = glusterd_get_dist_leaf_count (volinfo);
- volinfo->subvol_count = (volinfo->brick_count /
- volinfo->dist_leaf_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;
- }
-
- if (GF_OP_CMD_START == cmd &&
- volinfo->status == GLUSTERD_STATUS_STARTED) {
- ret = glusterd_nodesvcs_handle_reconfigure (volinfo);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING,
- "Unable to reconfigure NFS-Server");
- goto out;
- }
- }
-
- /* Need to reset the defrag/rebalance status accordingly */
- switch (volinfo->rebal.defrag_status) {
- case GF_DEFRAG_STATUS_FAILED:
- case GF_DEFRAG_STATUS_COMPLETE:
- volinfo->rebal.defrag_status = 0;
- default:
- break;
- }
- if (!force && need_rebalance) {
- /* perform the rebalance operations */
- ret = glusterd_handle_defrag_start
- (volinfo, err_str, sizeof (err_str),
- GF_DEFRAG_CMD_START_FORCE,
- glusterd_remove_brick_migrate_cbk, GD_OP_REMOVE_BRICK);
-
- 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);
-
- GF_FREE (brick_tmpstr);
- if (bricks_dict)
- dict_unref (bricks_dict);
-
- return ret;
-}
-
-int
-glusterd_op_stage_barrier (dict_t *dict, char **op_errstr)
-{
- int ret = -1;
- xlator_t *this = NULL;
- char *volname = NULL;
- glusterd_volinfo_t *vol = NULL;
-
- GF_ASSERT (dict);
- this = THIS;
- GF_ASSERT (this);
-
- ret = dict_get_str (dict, "volname", &volname);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Volname not present in "
- "dict");
- goto out;
- }
-
- ret = glusterd_volinfo_find (volname, &vol);
- if (ret) {
- gf_asprintf (op_errstr, "Volume %s does not exist", volname);
- gf_log (this->name, GF_LOG_ERROR, "%s", *op_errstr);
- goto out;
- }
-
- if (!glusterd_is_volume_started (vol)) {
- gf_asprintf (op_errstr, "Volume %s is not started", volname);
- ret = -1;
- goto out;
- }
-
- ret = dict_get_str_boolean (dict, "barrier", -1);
- if (ret == -1) {
- gf_asprintf (op_errstr, "Barrier op for volume %s not present "
- "in dict", volname);
- gf_log (this->name, GF_LOG_ERROR, "%s", *op_errstr);
- goto out;
- }
- ret = 0;
-out:
- gf_log (this->name, GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-
-int
-glusterd_op_barrier (dict_t *dict, char **op_errstr)
-{
- int ret = -1;
- xlator_t *this = NULL;
- char *volname = NULL;
- glusterd_volinfo_t *vol = NULL;
- char *barrier_op = NULL;
-
- GF_ASSERT (dict);
- this = THIS;
- GF_ASSERT (this);
-
- ret = dict_get_str (dict, "volname", &volname);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Volname not present in "
- "dict");
- goto out;
- }
-
- ret = glusterd_volinfo_find (volname, &vol);
- if (ret) {
- gf_asprintf (op_errstr, "Volume %s does not exist", volname);
- gf_log (this->name, GF_LOG_ERROR, "%s", *op_errstr);
- goto out;
- }
-
- ret = dict_get_str (dict, "barrier", &barrier_op);
- if (ret) {
- gf_asprintf (op_errstr, "Barrier op for volume %s not present "
- "in dict", volname);
- gf_log (this->name, GF_LOG_ERROR, "%s", *op_errstr);
- goto out;
- }
-
- ret = dict_set_dynstr_with_alloc (vol->dict, "features.barrier",
- barrier_op);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to set barrier op in"
- " volume option dict");
- goto out;
- }
-
- gd_update_volume_op_versions (vol);
- ret = glusterd_create_volfiles (vol);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to create volfiles");
- goto out;
- }
- ret = glusterd_store_volinfo (vol, GLUSTERD_VOLINFO_VER_AC_INCREMENT);
-
-out:
- gf_log (this->name, GF_LOG_DEBUG, "Returning %d", ret);
- 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 b48ea6f40fd..00000000000
--- a/xlators/mgmt/glusterd/src/glusterd-geo-rep.c
+++ /dev/null
@@ -1,5359 +0,0 @@
-/*
- Copyright (c) 2011-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 "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 int
-dict_get_param (dict_t *dict, char *key, char **param);
-
-struct gsync_config_opt_vals_ gsync_confopt_vals[] = {
- {.op_name = "change_detector",
- .no_of_pos_vals = 2,
- .case_sensitive = _gf_true,
- .values = {"xsync", "changelog"},
- },
- {.op_name = "special_sync_mode",
- .no_of_pos_vals = 2,
- .case_sensitive = _gf_true,
- .values = {"partial", "recover"}
- },
- {.op_name = "log-level",
- .no_of_pos_vals = 5,
- .case_sensitive = _gf_false,
- .values = {"critical", "error", "warning", "info", "debug"}
- },
- {.op_name = "use-tarssh",
- .no_of_pos_vals = 6,
- .case_sensitive = _gf_false,
- .values = {"true", "false", "0", "1", "yes", "no"}
- },
- {.op_name = NULL,
- },
-};
-
-static char *gsync_reserved_opts[] = {
- "gluster-command-dir",
- "pid-file",
- "remote-gsyncd"
- "state-file",
- "session-owner",
- "state-socket-unencoded",
- "socketdir",
- "ignore-deletes",
- "local-id",
- "local-path",
- "slave-id",
- NULL
-};
-
-static char *gsync_no_restart_opts[] = {
- "checkpoint",
- NULL
-};
-
-int
-__glusterd_handle_sys_exec (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_SYS_EXEC;
- glusterd_conf_t *priv = NULL;
- char *host_uuid = NULL;
- char err_str[2048] = {0,};
- xlator_t *this = NULL;
-
- GF_ASSERT (req);
-
- this = THIS;
- GF_ASSERT (this);
- priv = this->private;
- GF_ASSERT (priv);
-
- ret = xdr_to_generic (req->msg[0], &cli_req,
- (xdrproc_t)xdr_gf_cli_req);
- if (ret < 0) {
- 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 (this->name, GF_LOG_ERROR, "failed to "
- "unserialize req-buffer to dictionary");
- snprintf (err_str, sizeof (err_str), "Unable to decode "
- "the command");
- goto out;
- } else {
- dict->extra_stdfree = cli_req.dict.dict_val;
- }
-
- host_uuid = gf_strdup (uuid_utoa(MY_UUID));
- if (host_uuid == NULL) {
- snprintf (err_str, sizeof (err_str), "Failed to get "
- "the uuid of local glusterd");
- ret = -1;
- goto out;
- }
-
- ret = dict_set_dynstr (dict, "host-uuid", host_uuid);
- if (ret)
- goto out;
- }
-
- ret = glusterd_op_begin_synctask (req, cli_op, dict);
-
-out:
- if (ret) {
- if (err_str[0] == '\0')
- snprintf (err_str, sizeof (err_str),
- "Operation failed");
- ret = glusterd_op_send_cli_response (cli_op, ret, 0, req,
- dict, err_str);
- }
- return ret;
-}
-
-int
-__glusterd_handle_copy_file (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_COPY_FILE;
- glusterd_conf_t *priv = NULL;
- char *host_uuid = NULL;
- char err_str[2048] = {0,};
- xlator_t *this = NULL;
-
- GF_ASSERT (req);
-
- this = THIS;
- GF_ASSERT (this);
- priv = this->private;
- GF_ASSERT (priv);
-
- ret = xdr_to_generic (req->msg[0], &cli_req,
- (xdrproc_t)xdr_gf_cli_req);
- if (ret < 0) {
- 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 (this->name, GF_LOG_ERROR, "failed to "
- "unserialize req-buffer to dictionary");
- snprintf (err_str, sizeof (err_str), "Unable to decode "
- "the command");
- goto out;
- } else {
- dict->extra_stdfree = cli_req.dict.dict_val;
- }
-
- host_uuid = gf_strdup (uuid_utoa(MY_UUID));
- if (host_uuid == NULL) {
- snprintf (err_str, sizeof (err_str), "Failed to get "
- "the uuid of local glusterd");
- ret = -1;
- goto out;
- }
-
- ret = dict_set_dynstr (dict, "host-uuid", host_uuid);
- if (ret)
- goto out;
- }
-
- ret = glusterd_op_begin_synctask (req, cli_op, dict);
-
-out:
- if (ret) {
- if (err_str[0] == '\0')
- snprintf (err_str, sizeof (err_str),
- "Operation failed");
- ret = glusterd_op_send_cli_response (cli_op, ret, 0, req,
- dict, err_str);
- }
- return ret;
-}
-
-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;
- char err_str[2048] = {0,};
- xlator_t *this = NULL;
-
- GF_ASSERT (req);
-
- this = THIS;
- GF_ASSERT (this);
- priv = this->private;
- GF_ASSERT (priv);
-
- ret = xdr_to_generic (req->msg[0], &cli_req,
- (xdrproc_t)xdr_gf_cli_req);
- if (ret < 0) {
- 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 (this->name, GF_LOG_ERROR, "failed to "
- "unserialize req-buffer to dictionary");
- snprintf (err_str, sizeof (err_str), "Unable to decode "
- "the command");
- goto out;
- } else {
- dict->extra_stdfree = cli_req.dict.dict_val;
- }
-
- host_uuid = gf_strdup (uuid_utoa(MY_UUID));
- if (host_uuid == NULL) {
- snprintf (err_str, sizeof (err_str), "Failed to get "
- "the uuid of local glusterd");
- 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 (this->name, 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 (this->name, GF_LOG_INFO, "slave not found, while "
- "handling "GEOREP" options");
- slave = "(No Slave)";
- }
-
- ret = dict_get_int32 (dict, "type", &type);
- if (ret < 0) {
- snprintf (err_str, sizeof (err_str), "Command type not found "
- "while handling "GEOREP" options");
- gf_log (this->name, GF_LOG_ERROR, "%s", err_str);
- goto out;
- }
-
- switch (type) {
- case GF_GSYNC_OPTION_TYPE_CREATE:
- strncpy (operation, "create", sizeof (operation));
- cli_op = GD_OP_GSYNC_CREATE;
- break;
-
- 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_PAUSE:
- strncpy (operation, "pause", sizeof (operation));
- break;
-
- case GF_GSYNC_OPTION_TYPE_RESUME:
- strncpy (operation, "resume", 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;
- }
-
- ret = glusterd_op_begin_synctask (req, cli_op, dict);
-
-out:
- if (ret) {
- if (err_str[0] == '\0')
- snprintf (err_str, sizeof (err_str),
- "Operation failed");
- ret = glusterd_op_send_cli_response (cli_op, ret, 0, req,
- dict, err_str);
- }
- return ret;
-}
-
-int
-glusterd_handle_sys_exec (rpcsvc_request_t *req)
-{
- return glusterd_big_locked_handler (req, __glusterd_handle_sys_exec);
-}
-
-int
-glusterd_handle_copy_file (rpcsvc_request_t *req)
-{
- return glusterd_big_locked_handler (req, __glusterd_handle_copy_file);
-}
-
-int
-glusterd_handle_gsync_set (rpcsvc_request_t *req)
-{
- return glusterd_big_locked_handler (req, __glusterd_handle_gsync_set);
-}
-
-/*****
- *
- * 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 int
-_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);
-
- return 0;
-}
-
-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) {
- void *p = linearr;
- arr_len <<= 1;
- p = GF_REALLOC (linearr, arr_len);
- if (!p) {
- GF_FREE (line);
- error = _gf_true;
- goto out;
- }
- linearr = p;
- }
- 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 int
-_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++;
- return 0;
-}
-
-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 *conf_path, 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", conf_path);
- runner_argprintf (&runner, "--iprefix=%s", DATADIR);
- 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 *conf_path)
-{
- runner_t runner = {0,};
-
- runinit (&runner);
- runner_add_args (&runner, GSYNCD_PREFIX"/gsyncd", "-c", NULL);
- runner_argprintf (&runner, "%s", conf_path);
- runner_argprintf (&runner, "--iprefix=%s", DATADIR);
- 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
-gsyncd_getpidfile (char *master, char *slave, char *pidfile,
- char *conf_path, gf_boolean_t *is_template_in_use)
-{
- char temp_conf_path[PATH_MAX] = "";
- char *working_conf_path = NULL;
- glusterd_conf_t *priv = NULL;
- int ret = -1;
- struct stat stbuf = {0,};
-
- GF_ASSERT (THIS);
- GF_ASSERT (THIS->private);
- GF_ASSERT (conf_path);
-
- priv = THIS->private;
-
- GF_VALIDATE_OR_GOTO ("gsync", master, out);
- GF_VALIDATE_OR_GOTO ("gsync", slave, out);
-
- snprintf (temp_conf_path, sizeof(temp_conf_path) - 1,
- "%s/"GSYNC_CONF_TEMPLATE, priv->workdir);
-
- ret = lstat (conf_path, &stbuf);
- if (!ret) {
- gf_log ("", GF_LOG_DEBUG, "Using passed config template(%s).",
- conf_path);
- working_conf_path = conf_path;
- } else {
- gf_log ("", GF_LOG_WARNING, "Config file (%s) missing. "
- "Looking for template config file (%s)",
- conf_path, temp_conf_path);
- ret = lstat (temp_conf_path, &stbuf);
- if (ret) {
- gf_log ("", GF_LOG_ERROR,
- "Template config file (%s) missing.",
- temp_conf_path);
- goto out;
- }
- gf_log ("", GF_LOG_INFO, "Using default config template(%s).",
- temp_conf_path);
- working_conf_path = temp_conf_path;
- *is_template_in_use = _gf_true;
- }
-
-fetch_data:
-
- ret = glusterd_gsync_get_param_file (pidfile, "pid", master,
- slave, working_conf_path);
- if ((ret == -1) || strlen(pidfile) == 0) {
- if (*is_template_in_use == _gf_false) {
- gf_log ("", GF_LOG_WARNING,
- "failed to create the pidfile string. "
- "Trying default config template");
- working_conf_path = temp_conf_path;
- *is_template_in_use = _gf_true;
- goto fetch_data;
- } else {
- ret = -2;
- gf_log ("", GF_LOG_WARNING,
- "failed to create the pidfile string from template config");
- goto out;
- }
- }
-
- gf_log ("", GF_LOG_DEBUG, "pidfile = %s", pidfile);
-
- 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, char *conf_path,
- int *status, gf_boolean_t *is_template_in_use)
-{
- char pidfile[PATH_MAX] = {0,};
- int fd = -1;
-
- fd = gsyncd_getpidfile (master, slave, pidfile,
- conf_path, is_template_in_use);
- 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
-glusterd_verify_gsyncd_spawn (char *master, char *slave)
-{
- int ret = 0;
- runner_t runner = {0,};
-
- runinit (&runner);
- runner_add_args (&runner, GSYNCD_PREFIX"/gsyncd",
- "--verify", "spawning", NULL);
- runner_argprintf (&runner, ":%s", master);
- runner_add_args (&runner, slave, NULL);
- runner_redir (&runner, STDOUT_FILENO, RUN_PIPE);
- ret = runner_start (&runner);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "spawning child failed");
- ret = -1;
- goto out;
- }
-
- if (runner_end (&runner) != 0)
- ret = -1;
-
-out:
- gf_log ("", GF_LOG_DEBUG, "returning %d", ret);
- return ret;
-}
-
-static int
-gsync_verify_config_options (dict_t *dict, char **op_errstr, char *volname)
-{
- char **resopt = NULL;
- int i = 0;
- int ret = -1;
- char *subop = NULL;
- char *slave = NULL;
- char *op_name = NULL;
- char *op_value = NULL;
- char *t = NULL;
- char errmsg[PATH_MAX] = "";
- gf_boolean_t banned = _gf_true;
- gf_boolean_t op_match = _gf_true;
- gf_boolean_t val_match = _gf_true;
- struct gsync_config_opt_vals_ *conf_vals = NULL;
-
- 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)) {
- ret = glusterd_verify_gsyncd_spawn (volname, slave);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Unable to spawn gsyncd");
- return 0;
- }
-
- 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;
- }
- }
-
- /* Check options in gsync_confopt_vals for invalid values */
- for (conf_vals = gsync_confopt_vals; conf_vals->op_name; conf_vals++) {
- op_match = _gf_true;
- for (i = 0; conf_vals->op_name[i] && op_name[i]; i++) {
- if (conf_vals->op_name[i] == op_name[i] ||
- (conf_vals->op_name[i] == '_' && op_name[i] == '-'))
- continue;
- op_match = _gf_false;
- }
-
- if (op_match) {
- if (!op_value)
- goto out;
- val_match = _gf_false;
- for (i = 0; i < conf_vals->no_of_pos_vals; i++) {
- if(conf_vals->case_sensitive){
- if (!strcmp (conf_vals->values[i], op_value))
- val_match = _gf_true;
- } else {
- if (!strcasecmp (conf_vals->values[i], op_value))
- val_match = _gf_true;
- }
- }
-
- if (!val_match) {
- ret = snprintf (errmsg, sizeof(errmsg) - 1,
- "Invalid value(%s) for"
- " option %s", op_value,
- op_name);
- errmsg[ret] = '\0';
-
- gf_log ("", GF_LOG_ERROR, "%s", errmsg);
- *op_errstr = gf_strdup (errmsg);
- return -1;
- }
- }
- }
-out:
- return 0;
-}
-
-static int
-glusterd_get_gsync_status_mst_slv (glusterd_volinfo_t *volinfo,
- char *slave, char *conf_path,
- dict_t *rsp_dict, char *node);
-
-static int
-_get_status_mst_slv (dict_t *this, char *key, data_t *value, void *data)
-{
- glusterd_gsync_status_temp_t *param = NULL;
- char *slave = NULL;
- char *slave_buf = NULL;
- char *slave_url = NULL;
- char *slave_vol = NULL;
- char *slave_host = NULL;
- char *errmsg = NULL;
- char conf_path[PATH_MAX] = "";
- int ret = -1;
- glusterd_conf_t *priv = NULL;
-
- param = (glusterd_gsync_status_temp_t *)data;
-
- GF_ASSERT (param);
- GF_ASSERT (param->volinfo);
-
- if (THIS)
- priv = THIS->private;
- if (priv == NULL) {
- gf_log ("", GF_LOG_ERROR, "priv of glusterd not present");
- goto out;
- }
-
- slave = strchr(value->data, ':');
- if (!slave)
- return 0;
- slave++;
-
- ret = glusterd_get_slave_info (slave, &slave_url,
- &slave_host, &slave_vol, &errmsg);
- if (ret) {
- if (errmsg)
- gf_log ("", GF_LOG_ERROR, "Unable to fetch "
- "slave details. Error: %s", errmsg);
- else
- gf_log ("", GF_LOG_ERROR,
- "Unable to fetch slave details.");
- ret = -1;
- goto out;
- }
-
- ret = snprintf (conf_path, sizeof(conf_path) - 1,
- "%s/"GEOREP"/%s_%s_%s/gsyncd.conf",
- priv->workdir, param->volinfo->volname,
- slave_host, slave_vol);
- conf_path[ret] = '\0';
-
- ret = glusterd_get_gsync_status_mst_slv(param->volinfo,
- slave, conf_path,
- param->rsp_dict,
- param->node);
-out:
-
- GF_FREE (errmsg);
-
- if (slave_buf)
- GF_FREE(slave_buf);
-
- gf_log ("", GF_LOG_DEBUG, "Returning %d.", ret);
- return ret;
-}
-
-
-static int
-_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;
-
- return 0;
-}
-
-static int
-glusterd_remove_slave_in_info (glusterd_volinfo_t *volinfo, char *slave,
- char **op_errstr)
-{
- int zero_slave_entries = _gf_true;
- int ret = 0;
- char *slavekey = NULL;
-
- GF_ASSERT (volinfo);
- GF_ASSERT (slave);
-
- do {
- ret = glusterd_get_slave (volinfo, slave, &slavekey);
- if (ret < 0 && zero_slave_entries) {
- ret++;
- goto out;
- }
- zero_slave_entries = _gf_false;
- dict_del (volinfo->gsync_slaves, slavekey);
- } while (ret >= 0);
-
- 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;
-}
-
-int
-glusterd_check_gsync_running_local (char *master, char *slave,
- char *conf_path,
- gf_boolean_t *is_run)
-{
- int ret = -1;
- int ret_status = 0;
- gf_boolean_t is_template_in_use = _gf_false;
-
- GF_ASSERT (master);
- GF_ASSERT (slave);
- GF_ASSERT (is_run);
-
- *is_run = _gf_false;
- ret = gsync_status (master, slave, conf_path,
- &ret_status, &is_template_in_use);
- 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,
- gf_boolean_t is_force)
-{
- 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:
- if (!is_force)
- 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);
- if (!is_force)
- GF_ASSERT (!t || *t != ':');
-
- if (is_force) {
- gf_log ("", GF_LOG_DEBUG, GEOREP" has already been "
- "invoked for the %s (master) and %s (slave)."
- " Allowing without saving info again due to"
- " force command.", volinfo->volname, slave);
- ret = 0;
- goto out;
- }
-
- 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 "
- "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 *conf_path,
- char *statefile, char **op_errstr,
- gf_boolean_t is_force)
-{
- int ret = -1;
- int ret_status = 0;
- gf_boolean_t is_template_in_use = _gf_false;
- char msg[2048] = {0};
- uuid_t uuid = {0};
- glusterd_conf_t *priv = NULL;
- xlator_t *this = NULL;
- struct stat stbuf = {0,};
-
- this = THIS;
-
- GF_ASSERT (volinfo);
- GF_ASSERT (slave);
- GF_ASSERT (op_errstr);
- GF_ASSERT (conf_path);
- 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;
- }
-
- ret = lstat (statefile, &stbuf);
- if (ret) {
- snprintf (msg, sizeof (msg), "Session between %s and %s has"
- " not been created. Please create session and retry.",
- volinfo->volname, slave);
- gf_log ("", GF_LOG_ERROR, "%s", msg);
- *op_errstr = gf_strdup (msg);
- goto out;
- }
-
- /* Check if the gsync slave info is stored. If not
- * session has not been created */
- ret = glusterd_gsync_get_uuid (slave, volinfo, uuid);
- if (ret) {
- snprintf (msg, sizeof (msg), "Session between %s and %s has"
- " not been created. Please create session and retry.",
- volinfo->volname, slave);
- gf_log ("", GF_LOG_ERROR, "%s", msg);
- goto out;
- }
-
- /*Check if the gsync is already started in cmd. inited host
- * If so initiate add it into the glusterd's priv*/
- ret = gsync_status (volinfo->volname, slave, conf_path,
- &ret_status, &is_template_in_use);
- if (ret == 0) {
- if ((ret_status == 0) && !is_force) {
- snprintf (msg, sizeof (msg), GEOREP " session between"
- " %s & %s already started", volinfo->volname,
- slave);
- ret = -1;
- goto out;
- }
- } else if (ret == -1) {
- snprintf (msg, sizeof (msg), GEOREP" start option "
- "validation failed ");
- goto out;
- }
-
- if (is_template_in_use == _gf_true) {
- snprintf (msg, sizeof (msg), GEOREP" start "
- "failed : pid-file entry missing "
- "in config file.");
- ret = -1;
- goto out;
- }
-
- ret = glusterd_verify_gsyncd_spawn (volinfo->volname, slave);
- if (ret && !is_force) {
- snprintf (msg, sizeof (msg), "Unable to spawn gsyncd");
- gf_log ("", GF_LOG_ERROR, "%s", msg);
- }
-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;
-}
-
-/*
- * is_geo_rep_active:
- * This function reads the state_file and sets is_active to 1 if the
- * monitor status is neither "Stopped" or "Not Started"
- *
- * RETURN VALUE:
- * 0: On successful read of state_file.
- * -1: error.
- */
-
-static int
-is_geo_rep_active (glusterd_volinfo_t *volinfo, char *slave,
- char *conf_path, int *is_active)
-{
- dict_t *confd = NULL;
- char *statefile = NULL;
- char *master = NULL;
- char monitor_status[PATH_MAX] = "";
- int ret = -1;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
-
- master = volinfo->volname;
-
- confd = dict_new ();
- if (!confd) {
- gf_log ("", GF_LOG_ERROR, "Not able to create dict.");
- goto out;
- }
-
- ret = glusterd_gsync_get_config (master, slave, conf_path,
- confd);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Unable to get configuration data "
- "for %s(master), %s(slave)", master, slave);
- ret = -1;
- goto out;
- }
-
- ret = dict_get_param (confd, "state_file", &statefile);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Unable to get state_file's name "
- "for %s(master), %s(slave). Please check gsync "
- "config file.", master, slave);
- ret = -1;
- goto out;
- }
-
- ret = glusterd_gsync_read_frm_status (statefile, monitor_status,
- sizeof (monitor_status));
- if (ret <= 0) {
- gf_log ("", GF_LOG_ERROR, "Unable to read the status "
- "file for %s(master), %s(slave)", master, slave);
- strncpy (monitor_status, "defunct", sizeof (monitor_status));
- }
-
- if ((!strcmp(monitor_status, "Stopped")) ||
- (!strcmp(monitor_status, "Not Started"))) {
- *is_active = 0;
- } else {
- *is_active = 1;
- }
- ret = 0;
-out:
- if (confd)
- dict_destroy (confd);
- return ret;
-}
-
-/*
- * _get_slave_status:
- * Called for each slave in the volume from dict_foreach.
- * It calls is_geo_rep_active to get the monitor status.
- *
- * RETURN VALUE:
- * 0: On successful read of state_file from is_geo_rep_active.
- * When it is found geo-rep is already active from previous calls.
- * When there is no slave.
- * -1: On error.
- */
-
-int
-_get_slave_status (dict_t *dict, char *key, data_t *value, void *data)
-{
- gsync_status_param_t *param = NULL;
- char *slave = NULL;
- char *slave_url = NULL;
- char *slave_vol = NULL;
- char *slave_host = NULL;
- char *errmsg = NULL;
- char conf_path[PATH_MAX] = "";
- int ret = -1;
- glusterd_conf_t *priv = NULL;
- xlator_t *this = NULL;
-
- param = (gsync_status_param_t *)data;
-
- GF_ASSERT (param);
- GF_ASSERT (param->volinfo);
-
- if (param->is_active) {
- ret = 0;
- goto out;
- }
-
- this = THIS;
- GF_ASSERT (this);
-
- if (this)
- priv = this->private;
- if (priv == NULL) {
- gf_log ("", GF_LOG_ERROR, "priv of glusterd not present");
- goto out;
- }
-
- slave = strchr(value->data, ':');
- if (!slave) {
- ret = 0;
- goto out;
- }
- slave++;
-
- ret = glusterd_get_slave_info (slave, &slave_url,
- &slave_host, &slave_vol, &errmsg);
- if (ret) {
- if (errmsg)
- gf_log ("", GF_LOG_ERROR, "Unable to fetch "
- "slave details. Error: %s", errmsg);
- else
- gf_log ("", GF_LOG_ERROR,
- "Unable to fetch slave details.");
- ret = -1;
- goto out;
- }
-
- ret = snprintf (conf_path, sizeof(conf_path) - 1,
- "%s/"GEOREP"/%s_%s_%s/gsyncd.conf",
- priv->workdir, param->volinfo->volname,
- slave_host, slave_vol);
- if (ret < 0) {
- gf_log ("", GF_LOG_ERROR, "Unable to assign conf_path.");
- ret = -1;
- goto out;
- }
- conf_path[ret] = '\0';
-
- ret = is_geo_rep_active (param->volinfo,slave, conf_path,
- &param->is_active);
-out:
- GF_FREE(errmsg);
- return ret;
-}
-
-static int
-glusterd_op_verify_gsync_running (glusterd_volinfo_t *volinfo,
- char *slave, char *conf_path,
- char **op_errstr)
-{
- int pfd = -1;
- int ret = -1;
- char msg[2048] = {0};
- char pidfile[PATH_MAX] = {0,};
- gf_boolean_t is_template_in_use = _gf_false;
-
- GF_ASSERT (THIS && THIS->private);
- GF_ASSERT (volinfo);
- GF_ASSERT (slave);
- GF_ASSERT (conf_path);
- 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;
- }
-
- pfd = gsyncd_getpidfile (volinfo->volname, slave, pidfile,
- conf_path, &is_template_in_use);
- if (pfd == -2) {
- gf_log ("", GF_LOG_ERROR, GEOREP" stop validation "
- "failed for %s & %s", volinfo->volname, slave);
- ret = -1;
- goto out;
- }
- if (gsync_status_byfd (pfd) == -1) {
- snprintf (msg, sizeof (msg), GEOREP" session b/w %s & %s is not"
- " running on this node.", volinfo->volname, slave);
- gf_log ("", GF_LOG_ERROR, "%s", msg);
- ret = -1;
- /* monitor gsyncd already dead */
- goto out;
- }
-
- if (is_template_in_use) {
- snprintf (msg, sizeof (msg), "pid-file entry missing in "
- "the config file(%s).", conf_path);
- gf_log ("", GF_LOG_ERROR, "%s", msg);
- ret = -1;
- goto out;
- }
-
- if (pfd < 0)
- 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;
- char *conf_path = NULL;
- char *slave_url = NULL;
- char *slave_host = NULL;
- char *slave_vol = NULL;
- glusterd_conf_t *priv = NULL;
-
- 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;
- }
-
- 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;
- }
-
- ret = glusterd_get_slave_details_confpath (volinfo, dict, &slave_url,
- &slave_host, &slave_vol,
- &conf_path, op_errstr);
- if (ret) {
- gf_log ("", GF_LOG_ERROR,
- "Unable to fetch slave or confpath details.");
- ret = -1;
- 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, char **host_uuid)
-{
-
- 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;
- }
- }
-
- if (host_uuid) {
- ret = dict_get_str (dict, "host-uuid", host_uuid);
- if (ret < 0) {
- gf_log ("", GF_LOG_WARNING, "host_uuid not found");
- *op_errstr = gf_strdup ("host_uuid not found");
- goto out;
- }
- }
-
- ret = 0;
-out:
- gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-
-int
-glusterd_op_stage_sys_exec (dict_t *dict, char **op_errstr)
-{
- char errmsg[PATH_MAX] = "";
- char *command = NULL;
- char command_path[PATH_MAX] = "";
- struct stat st = {0,};
- int ret = -1;
- glusterd_conf_t *conf = NULL;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- conf = this->private;
- GF_ASSERT (conf);
-
- if (conf->op_version < 2) {
- gf_log ("", GF_LOG_ERROR, "Op Version not supported.");
- snprintf (errmsg, sizeof(errmsg), "One or more nodes do not"
- " support the required op version.");
- *op_errstr = gf_strdup (errmsg);
- ret = -1;
- goto out;
- }
-
- ret = dict_get_str (dict, "command", &command);
- if (ret) {
- strcpy (errmsg, "internal error");
- gf_log ("", GF_LOG_ERROR,
- "Unable to get command from dict");
- goto out;
- }
-
- /* enforce local occurrence of the command */
- if (strchr (command, '/')) {
- strcpy (errmsg, "invalid command name");
- ret = -1;
- goto out;
- }
-
- sprintf (command_path, GSYNCD_PREFIX"/peer_%s", command);
- /* check if it's executable */
- ret = access (command_path, X_OK);
- if (!ret)
- /* check if it's a regular file */
- ret = stat (command_path, &st);
- if (!ret && !S_ISREG (st.st_mode))
- ret = -1;
-
-out:
- if (ret) {
- if (errmsg[0] == '\0') {
- if (command)
- snprintf (errmsg, sizeof (errmsg),
- "gsync peer_%s command not found.",
- command);
- else
- snprintf (errmsg, sizeof (errmsg), "%s",
- "gsync peer command was not specified");
- }
- *op_errstr = gf_strdup (errmsg);
- gf_log ("", GF_LOG_ERROR, "%s", errmsg);
- }
-
- gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-
-int
-glusterd_op_stage_copy_file (dict_t *dict, char **op_errstr)
-{
- char abs_filename[PATH_MAX] = "";
- char errmsg[PATH_MAX] = "";
- char *filename = NULL;
- char *host_uuid = NULL;
- char uuid_str [64] = {0};
- int ret = -1;
- glusterd_conf_t *priv = NULL;
- struct stat stbuf = {0,};
-
- 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 (priv->op_version < 2) {
- gf_log ("", GF_LOG_ERROR, "Op Version not supported.");
- snprintf (errmsg, sizeof(errmsg), "One or more nodes do not"
- " support the required op version.");
- *op_errstr = gf_strdup (errmsg);
- ret = -1;
- goto out;
- }
-
- ret = dict_get_str (dict, "host-uuid", &host_uuid);
- if (ret < 0) {
- gf_log ("", GF_LOG_ERROR, "Unable to fetch"
- " host-uuid from dict.");
- goto out;
- }
-
- uuid_utoa_r (MY_UUID, uuid_str);
- if (!strcmp (uuid_str, host_uuid)) {
- ret = dict_get_str (dict, "source", &filename);
- if (ret < 0) {
- gf_log ("", GF_LOG_ERROR, "Unable to fetch"
- " filename from dict.");
- *op_errstr = gf_strdup ("command unsuccessful");
- goto out;
- }
- snprintf (abs_filename, sizeof(abs_filename),
- "%s/%s", priv->workdir, filename);
-
- ret = lstat (abs_filename, &stbuf);
- if (ret) {
- snprintf (errmsg, sizeof (errmsg), "Source file"
- " does not exist in %s", priv->workdir);
- *op_errstr = gf_strdup (errmsg);
- goto out;
- }
-
- if (!S_ISREG(stbuf.st_mode)) {
- snprintf (errmsg, sizeof (errmsg), "Source file"
- " is not a regular file.");
- *op_errstr = gf_strdup (errmsg);
- gf_log ("", GF_LOG_ERROR, "%s", errmsg);
- ret = -1;
- goto out;
- }
- }
-
- ret = 0;
-out:
- gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-
-int
-glusterd_get_statefile_name (glusterd_volinfo_t *volinfo, char *slave,
- char *conf_path, char **statefile,
- gf_boolean_t *is_template_in_use)
-{
- char *master = NULL;
- char *buf = NULL;
- char *working_conf_path = NULL;
- char temp_conf_path[PATH_MAX] = "";
- dict_t *confd = NULL;
- glusterd_conf_t *priv = NULL;
- int ret = -1;
- struct stat stbuf = {0,};
-
- GF_ASSERT (THIS);
- GF_ASSERT (THIS->private);
- GF_ASSERT (volinfo);
- GF_ASSERT (conf_path);
- GF_ASSERT (is_template_in_use);
-
- master = volinfo->volname;
-
- confd = dict_new ();
- if (!confd) {
- gf_log ("", GF_LOG_ERROR, "Unable to create new dict");
- goto out;
- }
-
- priv = THIS->private;
-
- snprintf (temp_conf_path, sizeof(temp_conf_path) - 1,
- "%s/"GSYNC_CONF_TEMPLATE, priv->workdir);
-
- ret = lstat (conf_path, &stbuf);
- if (!ret) {
- gf_log ("", GF_LOG_INFO, "Using passed config template(%s).",
- conf_path);
- working_conf_path = conf_path;
- } else {
- gf_log ("", GF_LOG_WARNING, "Config file (%s) missing. "
- "Looking for template config file (%s)",
- conf_path, temp_conf_path);
- ret = lstat (temp_conf_path, &stbuf);
- if (ret) {
- gf_log ("", GF_LOG_ERROR,
- "Template config file (%s) missing.",
- temp_conf_path);
- goto out;
- }
- gf_log ("", GF_LOG_INFO, "Using default config template(%s).",
- temp_conf_path);
- working_conf_path = temp_conf_path;
- *is_template_in_use = _gf_true;
- }
-
-fetch_data:
- ret = glusterd_gsync_get_config (master, slave, working_conf_path,
- confd);
- if (ret) {
- if (*is_template_in_use == _gf_false) {
- gf_log ("", GF_LOG_ERROR,
- "Unable to get configuration data "
- "for %s(master), %s(slave). "
- "Trying template config.",
- master, slave);
- working_conf_path = temp_conf_path;
- *is_template_in_use = _gf_true;
- goto fetch_data;
- } else {
- gf_log ("", GF_LOG_ERROR,
- "Unable to get configuration data "
- "for %s(master), %s(slave) from "
- "template config",
- master, slave);
- goto out;
- }
- }
-
- ret = dict_get_param (confd, "state_file", &buf);
- if (ret) {
- if (*is_template_in_use == _gf_false) {
- gf_log ("", GF_LOG_ERROR,
- "Unable to get state_file's name. "
- "Trying template config.");
- working_conf_path = temp_conf_path;
- *is_template_in_use = _gf_true;
- goto fetch_data;
- } else {
- gf_log ("", GF_LOG_ERROR,
- "Unable to get state_file's "
- "name from template.");
- goto out;
- }
- }
-
- ret = 0;
- out:
- if (buf) {
- *statefile = gf_strdup(buf);
- if (!*statefile)
- ret = -1;
- }
-
- if (confd)
- dict_destroy (confd);
-
- gf_log ("", GF_LOG_DEBUG, "Returning %d ", ret);
- return ret;
-}
-
-int
-glusterd_create_status_file (char *master, char *slave, char *slave_host,
- char *slave_vol, char *status)
-{
- int ret = -1;
- runner_t runner = {0,};
- glusterd_conf_t *priv = NULL;
-
- if (THIS)
- priv = THIS->private;
- if (priv == NULL) {
- gf_log ("", GF_LOG_ERROR, "priv of glusterd not present");
- goto out;
- }
-
- if (!status) {
- gf_log ("", GF_LOG_ERROR, "Status Empty");
- goto out;
- }
- gf_log ("", GF_LOG_DEBUG, "slave = %s", slave);
-
- runinit (&runner);
- runner_add_args (&runner, GSYNCD_PREFIX"/gsyncd", "--create",
- status, "-c", NULL);
- runner_argprintf (&runner, "%s/"GEOREP"/%s_%s_%s/gsyncd.conf",
- priv->workdir, master, slave_host, slave_vol);
- runner_argprintf (&runner, "--iprefix=%s", DATADIR);
- runner_argprintf (&runner, ":%s", master);
- runner_add_args (&runner, slave, NULL);
- synclock_unlock (&priv->big_lock);
- ret = runner_run (&runner);
- synclock_lock (&priv->big_lock);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Creating status file failed.");
- ret = -1;
- goto out;
- }
-
- ret = 0;
-out:
- gf_log ("", GF_LOG_DEBUG, "returning %d", ret);
- return ret;
-}
-
-static int
-glusterd_verify_slave (char *volname, char *slave_url, char *slave_vol,
- char **op_errstr, gf_boolean_t *is_force_blocker)
-{
- int32_t ret = -1;
- runner_t runner = {0,};
- char log_file_path[PATH_MAX] = "";
- char buf[PATH_MAX] = "";
- char *tmp = NULL;
- char *slave_url_buf = NULL;
- char *save_ptr = NULL;
- char *slave_user = NULL;
- char *slave_ip = NULL;
- glusterd_conf_t *priv = NULL;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- priv = this->private;
- GF_ASSERT (priv);
- GF_ASSERT (volname);
- GF_ASSERT (slave_url);
- GF_ASSERT (slave_vol);
-
- /* Fetch the slave_user and slave_ip from the slave_url.
- * If the slave_user is not present. Use "root"
- */
- if (strstr(slave_url, "@")) {
- slave_url_buf = gf_strdup (slave_url);
- if (!slave_url_buf)
- goto out;
-
- slave_user = strtok_r (slave_url_buf, "@", &save_ptr);
- slave_ip = strtok_r (NULL, "@", &save_ptr);
- } else {
- slave_user = "root";
- slave_ip = slave_url;
- }
-
- if (!slave_user || !slave_ip) {
- gf_log (this->name, GF_LOG_ERROR, "Invalid slave url.");
- goto out;
- }
-
- snprintf (log_file_path, sizeof(log_file_path),
- DEFAULT_LOG_FILE_DIRECTORY"/create_verify_log");
-
- runinit (&runner);
- runner_add_args (&runner, GSYNCD_PREFIX"/gverify.sh", NULL);
- runner_argprintf (&runner, "%s", volname);
- runner_argprintf (&runner, "%s", slave_user);
- runner_argprintf (&runner, "%s", slave_ip);
- runner_argprintf (&runner, "%s", slave_vol);
- runner_argprintf (&runner, "%s", log_file_path);
- runner_redir (&runner, STDOUT_FILENO, RUN_PIPE);
- synclock_unlock (&priv->big_lock);
- ret = runner_run (&runner);
- synclock_lock (&priv->big_lock);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Not a valid slave");
- ret = glusterd_gsync_read_frm_status (log_file_path,
- buf, sizeof(buf));
- if (ret <= 0) {
- gf_log ("", GF_LOG_ERROR, "Unable to read from %s",
- log_file_path);
- goto out;
- }
-
- /* Tokenize the error message from gverify.sh to figure out
- * if the error is a force blocker or not. */
- tmp = strtok_r (buf, "|", &save_ptr);
- if (!strcmp (tmp, "FORCE_BLOCKER"))
- *is_force_blocker = 1;
- else {
- /* No FORCE_BLOCKER flag present so all that is
- * present is the error message. */
- *is_force_blocker = 0;
- if (tmp)
- *op_errstr = gf_strdup (tmp);
- ret = -1;
- goto out;
- }
-
- /* Copy rest of the error message to op_errstr */
- tmp = strtok_r (NULL, "|", &save_ptr);
- if (tmp)
- *op_errstr = gf_strdup (tmp);
- ret = -1;
- goto out;
- }
- ret = 0;
-out:
- GF_FREE (slave_url_buf);
- unlink (log_file_path);
- gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-
-/** @slave_ip remains unmodified */
-int
-glusterd_geo_rep_parse_slave (char *slave_url,
- char **hostname, char **op_errstr)
-{
- int ret = -1;
- char *tmp = NULL;
- char *save_ptr = NULL;
- char *host = NULL;
- char errmsg[PATH_MAX] = "";
- char *saved_url = NULL;
-
- GF_ASSERT (slave_url);
- GF_ASSERT (*slave_url);
-
- saved_url = gf_strdup (slave_url);
- if (!saved_url)
- goto out;
-
- /* Checking if hostname has user specified */
- host = strstr (saved_url, "@");
- if (!host) { /* no user specified */
- if (hostname) {
- *hostname = gf_strdup (saved_url);
- if (!*hostname)
- goto out;
- }
-
- ret = 0;
- goto out;
- } else {
- /* Moving the host past the '@' and checking if the
- * actual hostname also has '@' */
- host++;
- if (strstr (host, "@")) {
- gf_log ("", GF_LOG_DEBUG, "host = %s", host);
- ret = snprintf (errmsg, sizeof(errmsg) - 1,
- "Invalid Hostname (%s).", host);
- errmsg[ret] = '\0';
- gf_log ("", GF_LOG_ERROR, "%s", errmsg);
- ret = -1;
- if (op_errstr)
- *op_errstr = gf_strdup (errmsg);
- goto out;
- }
-
- ret = -1;
-
- /**
- * preliminary check for valid slave format.
- */
- tmp = strtok_r (saved_url, "@", &save_ptr);
- tmp = strtok_r (NULL, "@", &save_ptr);
- if (!tmp)
- goto out;
- if (hostname) {
- *hostname = gf_strdup (tmp);
- if (!*hostname)
- goto out;
- }
- }
-
- ret = 0;
-out:
- GF_FREE (saved_url);
- if (ret)
- if (hostname)
- GF_FREE (*hostname);
- gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-
-int
-glusterd_op_stage_gsync_create (dict_t *dict, char **op_errstr)
-{
- char *down_peerstr = NULL;
- char *slave = NULL;
- char *volname = NULL;
- char *host_uuid = NULL;
- char *statefile = NULL;
- char *slave_url = NULL;
- char *slave_host = NULL;
- char *slave_vol = NULL;
- char *conf_path = NULL;
- char errmsg[PATH_MAX] = "";
- char common_pem_file[PATH_MAX] = "";
- char hook_script[PATH_MAX] = "";
- char uuid_str [64] = "";
- int ret = -1;
- int is_pem_push = -1;
- gf_boolean_t is_force = -1;
- gf_boolean_t is_force_blocker = -1;
- gf_boolean_t exists = _gf_false;
- gf_boolean_t is_template_in_use = _gf_false;
- glusterd_conf_t *conf = NULL;
- glusterd_volinfo_t *volinfo = NULL;
- struct stat stbuf = {0,};
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- conf = this->private;
- GF_ASSERT (conf);
-
- ret = glusterd_op_gsync_args_get (dict, op_errstr, &volname,
- &slave, &host_uuid);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Unable to fetch arguments");
- gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
- return -1;
- }
-
- if (conf->op_version < 2) {
- gf_log ("", GF_LOG_ERROR, "Op Version not supported.");
- snprintf (errmsg, sizeof(errmsg), "One or more nodes do not"
- " support the required op version.");
- *op_errstr = gf_strdup (errmsg);
- ret = -1;
- 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);
- gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
- return -1;
- }
-
- ret = glusterd_get_slave_details_confpath (volinfo, dict, &slave_url,
- &slave_host, &slave_vol,
- &conf_path, op_errstr);
- if (ret) {
- gf_log ("", GF_LOG_ERROR,
- "Unable to fetch slave or confpath details.");
- ret = -1;
- goto out;
- }
-
- is_force = dict_get_str_boolean (dict, "force", _gf_false);
-
- uuid_utoa_r (MY_UUID, uuid_str);
- if (!strcmp (uuid_str, host_uuid)) {
- ret = glusterd_are_vol_all_peers_up (volinfo,
- &conf->peers,
- &down_peerstr);
- if ((ret == _gf_false) && !is_force) {
- snprintf (errmsg, sizeof (errmsg), "Peer %s,"
- " which is a part of %s volume, is"
- " down. Please bring up the peer and"
- " retry.", down_peerstr,
- volinfo->volname);
- gf_log ("", GF_LOG_ERROR, "%s", errmsg);
- *op_errstr = gf_strdup (errmsg);
- GF_FREE (down_peerstr);
- down_peerstr = NULL;
- gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
- return -1;
- } else if (ret == _gf_false) {
- gf_log ("", GF_LOG_INFO, "Peer %s,"
- " which is a part of %s volume, is"
- " down. Force creating geo-rep session."
- " On bringing up the peer, re-run"
- " \"gluster system:: execute"
- " gsec_create\" and \"gluster volume"
- " geo-replication %s %s create push-pem"
- " force\"", down_peerstr, volinfo->volname,
- volinfo->volname, slave);
- GF_FREE (down_peerstr);
- down_peerstr = NULL;
- }
-
- /* Checking if slave host is pingable, has proper passwordless
- * ssh login setup, slave volume is created, slave vol is empty,
- * and if it has enough memory and bypass in case of force if
- * the error is not a force blocker */
- ret = glusterd_verify_slave (volname, slave_url, slave_vol,
- op_errstr, &is_force_blocker);
- if (ret) {
- if (is_force && !is_force_blocker) {
- gf_log ("", GF_LOG_INFO, "%s is not a valid slave"
- " volume. Error: %s. Force creating geo-rep"
- " session.", slave, *op_errstr);
- } else {
- gf_log ("", GF_LOG_ERROR,
- "%s is not a valid slave volume. Error: %s",
- slave, *op_errstr);
- ret = -1;
- goto out;
- }
- }
-
- ret = dict_get_int32 (dict, "push_pem", &is_pem_push);
- if (!ret && is_pem_push) {
- ret = snprintf (common_pem_file,
- sizeof(common_pem_file) - 1,
- "%s"GLUSTERD_COMMON_PEM_PUB_FILE,
- conf->workdir);
- common_pem_file[ret] = '\0';
-
- ret = snprintf (hook_script, sizeof(hook_script) - 1,
- "%s"GLUSTERD_CREATE_HOOK_SCRIPT,
- conf->workdir);
- hook_script[ret] = '\0';
-
- ret = lstat (common_pem_file, &stbuf);
- if (ret) {
- snprintf (errmsg, sizeof (errmsg), "%s"
- " required for push-pem is"
- " not present. Please run"
- " \"gluster system:: execute"
- " gsec_create\"", common_pem_file);
- gf_log ("", GF_LOG_ERROR, "%s", errmsg);
- *op_errstr = gf_strdup (errmsg);
- ret = -1;
- goto out;
- }
-
- ret = lstat (hook_script, &stbuf);
- if (ret) {
- snprintf (errmsg, sizeof (errmsg),
- "The hook-script (%s) required "
- "for push-pem is not present. "
- "Please install the hook-script "
- "and retry", hook_script);
- gf_log ("", GF_LOG_ERROR, "%s", errmsg);
- *op_errstr = gf_strdup (errmsg);
- ret = -1;
- goto out;
- }
-
- if (!S_ISREG(stbuf.st_mode)) {
- snprintf (errmsg, sizeof (errmsg), "%s"
- " required for push-pem is"
- " not a regular file. Please run"
- " \"gluster system:: execute"
- " gsec_create\"", common_pem_file);
- gf_log ("", GF_LOG_ERROR, "%s", errmsg);
- ret = -1;
- goto out;
- }
- }
- }
-
- ret = glusterd_get_statefile_name (volinfo, slave,
- conf_path, &statefile,
- &is_template_in_use);
- if (ret) {
- if (!strstr(slave, "::"))
- snprintf (errmsg, sizeof (errmsg),
- "%s is not a valid slave url.", slave);
- else
- snprintf (errmsg, sizeof (errmsg), "Please check gsync "
- "config file. Unable to get statefile's name");
- gf_log ("", GF_LOG_ERROR, "%s", errmsg);
- ret = -1;
- goto out;
- }
-
- ret = dict_set_str (dict, "statefile", statefile);
- if (ret) {
- gf_log ("", GF_LOG_ERROR,
- "Unable to store statefile path");
- goto out;
- }
-
- ret = lstat (statefile, &stbuf);
- if (!ret && !is_force) {
- snprintf (errmsg, sizeof (errmsg), "Session between %s"
- " and %s is already created.",
- volinfo->volname, slave);
- gf_log ("", GF_LOG_ERROR, "%s", errmsg);
- ret = -1;
- goto out;
- } else if (!ret)
- gf_log ("", GF_LOG_INFO, "Session between %s"
- " and %s is already created. Force"
- " creating again.", volinfo->volname, slave);
-
- ret = glusterd_verify_gsyncd_spawn (volinfo->volname, slave);
- if (ret) {
- snprintf (errmsg, sizeof (errmsg), "Unable to spawn gsyncd.");
- gf_log ("", GF_LOG_ERROR, "%s", errmsg);
- goto out;
- }
-
- ret = 0;
-out:
-
- if (ret && errmsg[0] != '\0')
- *op_errstr = gf_strdup (errmsg);
-
- gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-
-/* pre-condition check for geo-rep pause/resume.
- * Return: 0 on success
- * -1 on any check failed.
- */
-static int
-gd_pause_resume_validation (int type, glusterd_volinfo_t *volinfo,
- char *slave, char *statefile, char **op_errstr)
-{
- int ret = 0;
- char errmsg[PATH_MAX] = {0,};
- char monitor_status[NAME_MAX] = {0,};
-
- GF_ASSERT (volinfo);
- GF_ASSERT (slave);
- GF_ASSERT (statefile);
- GF_ASSERT (op_errstr);
-
- ret = glusterd_gsync_read_frm_status (statefile, monitor_status,
- sizeof (monitor_status));
- if (ret <= 0) {
- snprintf (errmsg, sizeof(errmsg), "Pause check Failed:"
- " Geo-rep session is not setup");
- ret = -1;
- goto out;
- }
-
- if ( type == GF_GSYNC_OPTION_TYPE_PAUSE &&
- strstr (monitor_status, "Paused")) {
- snprintf (errmsg, sizeof(errmsg), "Geo-replication"
- " session between %s and %s already Paused.",
- volinfo->volname, slave);
- ret = -1;
- goto out;
- }
- if ( type == GF_GSYNC_OPTION_TYPE_RESUME &&
- !strstr (monitor_status, "Paused")) {
- snprintf (errmsg, sizeof(errmsg), "Geo-replication"
- " session between %s and %s is not Paused.",
- volinfo->volname, slave);
- ret = -1;
- goto out;
- }
- ret = 0;
-out:
- if (ret && (errmsg[0] != '\0')) {
- *op_errstr = gf_strdup (errmsg);
- }
- return ret;
-}
-
-int
-glusterd_op_stage_gsync_set (dict_t *dict, char **op_errstr)
-{
- int ret = 0;
- int type = 0;
- int pfd = -1;
- char *volname = NULL;
- char *slave = NULL;
- char *slave_url = NULL;
- char *slave_host = NULL;
- char *slave_vol = NULL;
- char *down_peerstr = NULL;
- char *statefile = NULL;
- char *path_list = NULL;
- char *conf_path = NULL;
- gf_boolean_t exists = _gf_false;
- glusterd_volinfo_t *volinfo = NULL;
- char errmsg[PATH_MAX] = {0,};
- char pidfile[PATH_MAX] = {0,};
- dict_t *ctx = NULL;
- gf_boolean_t is_force = 0;
- gf_boolean_t is_running = _gf_false;
- gf_boolean_t is_template_in_use = _gf_false;
- uuid_t uuid = {0};
- char uuid_str [64] = {0};
- char *host_uuid = NULL;
- xlator_t *this = NULL;
- glusterd_conf_t *conf = NULL;
- struct stat stbuf = {0,};
-
- this = THIS;
- GF_ASSERT (this);
- conf = this->private;
- GF_ASSERT (conf);
-
- 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;
- }
-
- if (type == GF_GSYNC_OPTION_TYPE_STATUS) {
- ret = glusterd_verify_gsync_status_opts (dict, op_errstr);
- goto out;
- }
-
- ret = glusterd_op_gsync_args_get (dict, op_errstr,
- &volname, &slave, &host_uuid);
- if (ret)
- goto out;
-
- uuid_utoa_r (MY_UUID, uuid_str);
-
- if (conf->op_version < 2) {
- snprintf (errmsg, sizeof(errmsg), "One or more nodes do not"
- " support the required op version.");
- ret = -1;
- goto out;
- }
-
- exists = glusterd_check_volume_exists (volname);
- ret = glusterd_volinfo_find (volname, &volinfo);
- if ((ret) || (!exists)) {
- snprintf (errmsg, sizeof(errmsg), "Volume name %s does not"
- " exist", volname);
- ret = -1;
- goto out;
- }
-
- ret = glusterd_get_slave_details_confpath (volinfo, dict, &slave_url,
- &slave_host, &slave_vol,
- &conf_path, op_errstr);
- if (ret) {
- gf_log ("", GF_LOG_ERROR,
- "Unable to fetch slave or confpath details.");
- ret = -1;
- goto out;
- }
-
- is_force = dict_get_str_boolean (dict, "force", _gf_false);
-
- ret = glusterd_get_statefile_name (volinfo, slave,
- conf_path, &statefile,
- &is_template_in_use);
- if (ret) {
- if (!strstr(slave, "::")) {
- snprintf (errmsg, sizeof(errmsg),
- "%s is not a valid slave url.", slave);
- ret = -1;
- goto out;
- } else {
- gf_log ("", GF_LOG_ERROR,
- "state_file entry missing in config file (%s)",
- conf_path);
-
- if ((type == GF_GSYNC_OPTION_TYPE_STOP) && is_force) {
- gf_log ("", GF_LOG_WARNING, "Allowing stop "
- "force to bypass missing statefile "
- "entry in config file (%s), and "
- "template file", conf_path);
- ret = 0;
- } else
- goto out;
- }
- } else {
- ret = dict_set_str (dict, "statefile", statefile);
- if (ret) {
- gf_log ("", GF_LOG_ERROR,
- "Unable to store statefile path");
- goto out;
- }
- }
-
- /* Allowing stop force to bypass the statefile check
- * as this command acts as a fail safe method to stop geo-rep
- * session. */
- if ((type == GF_GSYNC_OPTION_TYPE_CONFIG) ||
- ((type == GF_GSYNC_OPTION_TYPE_STOP) && !is_force) ||
- (type == GF_GSYNC_OPTION_TYPE_DELETE) ||
- (type == GF_GSYNC_OPTION_TYPE_PAUSE) ||
- (type == GF_GSYNC_OPTION_TYPE_RESUME)) {
- ret = lstat (statefile, &stbuf);
- if (ret) {
- snprintf (errmsg, sizeof(errmsg), "Geo-replication"
- " session between %s and %s does not exist.",
- volinfo->volname, slave);
- gf_log ("", GF_LOG_ERROR, "%s. statefile = %s",
- errmsg, statefile);
- ret = -1;
- goto out;
- }
- }
-
- /* Check if all peers that are a part of the volume are up or not */
- if ((type == GF_GSYNC_OPTION_TYPE_DELETE) ||
- ((type == GF_GSYNC_OPTION_TYPE_STOP) && !is_force) ||
- (type == GF_GSYNC_OPTION_TYPE_PAUSE) ||
- (type == GF_GSYNC_OPTION_TYPE_RESUME)) {
- if (!strcmp (uuid_str, host_uuid)) {
- ret = glusterd_are_vol_all_peers_up (volinfo,
- &conf->peers,
- &down_peerstr);
- if (ret == _gf_false) {
- snprintf (errmsg, sizeof (errmsg), "Peer %s,"
- " which is a part of %s volume, is"
- " down. Please bring up the peer and"
- " retry.", down_peerstr,
- volinfo->volname);
- ret = -1;
- GF_FREE (down_peerstr);
- down_peerstr = NULL;
- goto out;
- }
- }
- }
-
- switch (type) {
- case GF_GSYNC_OPTION_TYPE_START:
- if (is_template_in_use) {
- snprintf (errmsg, sizeof(errmsg), "state-file entry "
- "missing in the config file(%s).",
- conf_path);
- ret = -1;
- goto out;
- }
-
- /* don't attempt to start gsync if replace-brick is
- * in progress */
- if (glusterd_is_rb_ongoing (volinfo)) {
- snprintf (errmsg, sizeof(errmsg), "replace-brick is in"
- " progress, not starting geo-replication");
- ret = -1;
- goto out;
- }
-
- ret = glusterd_op_verify_gsync_start_options (volinfo, slave,
- conf_path,
- statefile,
- op_errstr, is_force);
- 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");
- ret = -1;
- goto out;
- }
- }
- break;
-
- case GF_GSYNC_OPTION_TYPE_STOP:
- if (!is_force) {
- if (is_template_in_use) {
- snprintf (errmsg, sizeof(errmsg),
- "state-file entry missing in "
- "the config file(%s).", conf_path);
- ret = -1;
- goto out;
- }
-
- ret = glusterd_op_verify_gsync_running (volinfo, slave,
- conf_path,
- op_errstr);
- if (ret) {
- ret = glusterd_get_local_brickpaths (volinfo,
- &path_list);
- if (path_list)
- ret = -1;
- }
- }
- break;
-
- case GF_GSYNC_OPTION_TYPE_PAUSE:
- case GF_GSYNC_OPTION_TYPE_RESUME:
- if (is_template_in_use) {
- snprintf (errmsg, sizeof(errmsg),
- "state-file entry missing in "
- "the config file(%s).", conf_path);
- ret = -1;
- goto out;
- }
-
- ret = glusterd_op_verify_gsync_running (volinfo, slave,
- conf_path, op_errstr);
- if (ret)
- goto out;
- if (!is_force) {
- ret = gd_pause_resume_validation (type, volinfo, slave,
- statefile, op_errstr);
- if (ret)
- goto out;
- }
- break;
-
- case GF_GSYNC_OPTION_TYPE_CONFIG:
- if (is_template_in_use) {
- snprintf (errmsg, sizeof(errmsg), "state-file entry "
- "missing in the config file(%s).",
- conf_path);
- ret = -1;
- goto out;
- }
-
- pfd = gsyncd_getpidfile (volname, slave, pidfile,
- conf_path, &is_template_in_use);
- if (is_template_in_use) {
- snprintf (errmsg, sizeof(errmsg), "pid-file entry "
- "missing in the config file(%s).",
- conf_path);
- ret = -1;
- goto out;
- }
-
- ret = gsync_verify_config_options (dict, op_errstr, volname);
- goto out;
- break;
-
- case GF_GSYNC_OPTION_TYPE_DELETE:
- /* Check if the gsync session is still running
- * If so ask the user to stop geo-replication first.*/
- if (is_template_in_use) {
- snprintf (errmsg, sizeof(errmsg), "state-file entry "
- "missing in the config file(%s).",
- conf_path);
- ret = -1;
- goto out;
- }
-
- ret = glusterd_gsync_get_uuid (slave, volinfo, uuid);
- if (ret) {
- snprintf (errmsg, sizeof(errmsg), "Geo-replication"
- " session between %s and %s does not exist.",
- volinfo->volname, slave);
- ret = -1;
- goto out;
- } else {
- ret = glusterd_check_gsync_running_local (volinfo->volname,
- slave, conf_path,
- &is_running);
- if (_gf_true == is_running) {
- snprintf (errmsg, sizeof (errmsg), GEOREP
- " session between %s & %s is "
- "still active. Please stop the "
- "session and retry.",
- volinfo->volname, slave);
- ret = -1;
- goto out;
- }
- }
-
- ret = glusterd_verify_gsyncd_spawn (volinfo->volname, slave);
- if (ret) {
- snprintf (errmsg, sizeof (errmsg),
- "Unable to spawn gsyncd");
- }
-
- break;
- }
-
-out:
- if (path_list)
- GF_FREE (path_list);
-
- if (ret && errmsg[0] != '\0') {
- gf_log (this->name, GF_LOG_ERROR, "%s", errmsg);
- *op_errstr = gf_strdup (errmsg);
- }
-
- gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-
-static int
-gd_pause_or_resume_gsync (dict_t *dict, char *master, char *slave,
- char *slave_host, char *slave_vol, char *conf_path,
- char **op_errstr, gf_boolean_t is_pause)
-{
- int32_t ret = 0;
- int pfd = -1;
- pid_t pid = 0;
- char pidfile[PATH_MAX] = {0,};
- char errmsg[PATH_MAX] = "";
- char buf [1024] = {0,};
- int i = 0;
- gf_boolean_t is_template_in_use = _gf_false;
- char monitor_status[NAME_MAX] = {0,};
- char *statefile = NULL;
- char *token = NULL;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (dict);
- GF_ASSERT (master);
- GF_ASSERT (slave);
- GF_ASSERT (slave_host);
- GF_ASSERT (slave_vol);
- GF_ASSERT (conf_path);
-
- pfd = gsyncd_getpidfile (master, slave, pidfile,
- conf_path, &is_template_in_use);
- if (pfd == -2) {
- snprintf (errmsg, sizeof(errmsg),
- "pid-file entry mising in config file and "
- "template config file.");
- gf_log (this->name, GF_LOG_ERROR, "%s", errmsg);
- *op_errstr = gf_strdup (errmsg);
- ret = -1;
- goto out;
- }
-
- if (gsync_status_byfd (pfd) == -1) {
- gf_log (this->name, GF_LOG_ERROR, "gsyncd b/w %s & %s is not"
- " running", master, slave);
- /* monitor gsyncd already dead */
- goto out;
- }
-
- if (pfd < 0)
- goto out;
-
- /* Prepare to update status file*/
- ret = dict_get_str (dict, "statefile", &statefile);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Pause/Resume Failed:"
- " Unable to fetch statefile path");
- goto out;
- }
- ret = glusterd_gsync_read_frm_status (statefile, monitor_status,
- sizeof (monitor_status));
- if (ret <= 0) {
- gf_log (this->name, GF_LOG_ERROR, "Pause/Resume Failed: "
- "Unable to read status file for %s(master)"
- " %s(slave)", master, slave);
- goto out;
- }
-
- ret = read (pfd, buf, 1024);
- if (ret > 0) {
- pid = strtol (buf, NULL, 10);
- if (is_pause) {
- ret = kill (-pid, SIGSTOP);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed"
- " to pause gsyncd. Error: %s",
- strerror (errno));
- goto out;
- }
- /*On pause force, if status is already paused
- do not update status again*/
- if (strstr (monitor_status, "Paused"))
- goto out;
- (void) strcat (monitor_status, "(Paused)");
- ret = glusterd_create_status_file ( master, slave,
- slave_host, slave_vol,
- monitor_status);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Unable to update state_file."
- " Error : %s", strerror (errno));
- /* If status cannot be updated resume back */
- if (kill (-pid, SIGCONT)) {
- snprintf (errmsg, sizeof(errmsg),
- "Pause successful but could "
- "not update status file. "
- "Please use 'resume force' to"
- " resume back and retry pause"
- " to reflect in status");
- gf_log (this->name, GF_LOG_ERROR,
- "Resume back Failed. Error: %s",
- strerror (errno));
- *op_errstr = gf_strdup (errmsg);
- }
- goto out;
- }
- } else {
- token = strtok (monitor_status, "(");
- ret = glusterd_create_status_file (master, slave,
- slave_host,
- slave_vol, token);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Resume Failed: Unable to update "
- "state_file. Error : %s",
- strerror (errno));
- goto out;
- }
- ret = kill (-pid, SIGCONT);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Resumed Failed: Unable to send"
- " SIGCONT. Error: %s",
- strerror (errno));
- /* Process can't be resumed, update status
- * back to paused. */
- ret = glusterd_create_status_file (master,
- slave,
- slave_host,
- slave_vol,
- monitor_status);
- if (ret) {
- snprintf (errmsg, sizeof(errmsg),
- "Resume failed!!! Status "
- "inconsistent. Please use "
- "'resume force' to resume and"
- " reach consistent state");
- gf_log (this->name, GF_LOG_ERROR,
- "Updating status back to paused"
- " Failed. Error: %s",
- strerror (errno));
- *op_errstr = gf_strdup (errmsg);
- }
- goto out;
- }
- }
- }
- ret = 0;
-
-out:
- sys_close (pfd);
- return ret;
-}
-
-static int
-stop_gsync (char *master, char *slave, char **msg,
- char *conf_path, char **op_errstr,
- gf_boolean_t is_force)
-{
- int32_t ret = 0;
- int pfd = -1;
- pid_t pid = 0;
- char pidfile[PATH_MAX] = {0,};
- char errmsg[PATH_MAX] = "";
- char buf [1024] = {0,};
- int i = 0;
- gf_boolean_t is_template_in_use = _gf_false;
-
- GF_ASSERT (THIS);
- GF_ASSERT (THIS->private);
-
- pfd = gsyncd_getpidfile (master, slave, pidfile,
- conf_path, &is_template_in_use);
- if (pfd == -2) {
- snprintf (errmsg, sizeof(errmsg) - 1,
- "pid-file entry mising in config file and "
- "template config file.");
- gf_log ("", GF_LOG_ERROR, "%s", errmsg);
- *op_errstr = gf_strdup (errmsg);
- ret = -1;
- goto out;
- }
- if (gsync_status_byfd (pfd) == -1 && !is_force) {
- gf_log ("", GF_LOG_ERROR, "gsyncd b/w %s & %s is not"
- " running", master, slave);
- /* 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 && !is_force) {
- 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;
-}
-
-/*
- * glusterd_gsync_op_already_set:
- * This funcion checks whether the op_value is same as in the
- * gsyncd.conf file.
- *
- * RETURN VALUE:
- * 0 : op_value matches the conf file.
- * 1 : op_value does not matches the conf file or op_param not
- * found in conf file.
- * -1 : error
- */
-
-int
-glusterd_gsync_op_already_set (char* master, char* slave, char* conf_path,
- char* op_name, char* op_value)
-{
- dict_t *confd = NULL;
- char *op_val_buf = NULL;
- int32_t op_val_conf = 0;
- int32_t op_val_cli = 0;
- int32_t ret = -1;
- gf_boolean_t is_bool = _gf_true;
-
- confd = dict_new ();
- if (!confd) {
- gf_log ("", GF_LOG_ERROR, "Not able to create dict.");
- return -1;
- }
-
- ret = glusterd_gsync_get_config (master, slave, conf_path,
- confd);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Unable to get configuration data"
- "for %s(master), %s(slave)", master, slave);
- goto out;
- }
-
- ret = dict_get_param (confd, op_name, &op_val_buf);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Unable to get op_value "
- "for %s(master), %s(slave). Please check gsync "
- "config file.", master, slave);
- ret = 1;
- goto out;
- }
-
- gf_log("",GF_LOG_DEBUG, "val_cli:%s val_conf:%s",op_value,op_val_buf);
-
- if (!strcmp(op_val_buf,"true") || !strcmp(op_val_buf,"1")
- || !strcmp(op_val_buf,"yes")) {
- op_val_conf = 1;
- } else if(!strcmp(op_val_buf,"false") || !strcmp(op_val_buf,"0")
- || !strcmp(op_val_buf,"no")) {
- op_val_conf = 0;
- } else {
- is_bool = _gf_false;
- }
-
- if (is_bool) {
- if (!strcmp(op_value,"true") || !strcmp(op_value,"1")
- || !strcmp(op_value,"yes")) {
- op_val_cli = 1;
- } else {
- op_val_cli = 0;
- }
-
- if ( op_val_cli == op_val_conf ) {
- ret = 0;
- goto out;
- }
- } else {
- if (!strcmp(op_val_buf,op_value)) {
- ret = 0;
- goto out;
- }
- }
-
- ret = 1;
-
-out:
- dict_unref(confd);
- return ret;
-}
-
-static int
-glusterd_gsync_configure (glusterd_volinfo_t *volinfo, char *slave,
- char *path_list, 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;
- char *conf_path = NULL;
- char *slave_host = NULL;
- char *slave_vol = NULL;
- struct stat stbuf = {0, };
- gf_boolean_t restart_required = _gf_true;
- char **resopt = NULL;
- gf_boolean_t op_already_set = _gf_false;
-
- 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;
- }
-
- ret = dict_get_str (dict, "conf_path", &conf_path);
- if (ret) {
- gf_log ("", GF_LOG_ERROR,
- "Unable to fetch conf file path.");
- goto out;
- }
-
- master = "";
- runinit (&runner);
- runner_add_args (&runner, GSYNCD_PREFIX"/gsyncd", "-c", NULL);
- runner_argprintf (&runner, "%s", conf_path);
- runner_argprintf (&runner, "--iprefix=%s", DATADIR);
- 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);
-
- if ( strcmp(op_name,"checkpoint") != 0 && strtail (subop, "set")) {
- ret = glusterd_gsync_op_already_set(master,slave,conf_path,
- op_name,op_value);
- if (ret == -1) {
- gf_log ("", GF_LOG_WARNING,
- "glusterd_gsync_op_already_set failed.");
- gf_asprintf (op_errstr, GEOREP" config-%s failed for "
- "%s %s", subop, master, slave);
- goto out;
- }
- if (ret == 0) {
- gf_log("", GF_LOG_DEBUG, "op_value is already set");
- op_already_set = _gf_true;
- goto out;
- }
- }
-
- synclock_unlock (&priv->big_lock);
- ret = runner_run (&runner);
- synclock_lock (&priv->big_lock);
- 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;
- }
-
- if ((!strcmp (op_name, "state_file")) && (op_value)) {
-
- ret = lstat (op_value, &stbuf);
- if (ret) {
- ret = dict_get_str (dict, "slave_host", &slave_host);
- if (ret) {
- gf_log ("", GF_LOG_ERROR,
- "Unable to fetch slave host.");
- goto out;
- }
-
- ret = dict_get_str (dict, "slave_vol", &slave_vol);
- if (ret) {
- gf_log ("", GF_LOG_ERROR,
- "Unable to fetch slave volume name.");
- goto out;
- }
-
- ret = glusterd_create_status_file (volinfo->volname,
- slave, slave_host,
- slave_vol,
- "Switching Status "
- "File");
- if (ret || lstat (op_value, &stbuf)) {
- gf_log ("", GF_LOG_ERROR, "Unable to create %s"
- ". Error : %s", op_value,
- strerror (errno));
- ret = -1;
- goto out;
- }
- }
- }
-
- ret = 0;
- gf_asprintf (op_errstr, "config-%s successful", subop);
-
-out:
- if (!ret && volinfo && !op_already_set) {
- for (resopt = gsync_no_restart_opts; *resopt; resopt++) {
- restart_required = _gf_true;
- if (!strcmp ((*resopt), op_name)){
- restart_required = _gf_false;
- break;
- }
- }
-
- if (restart_required) {
- ret = glusterd_check_restart_gsync_session (volinfo, slave,
- resp_dict, path_list,
- conf_path, 0);
- 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 *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';
- }
- } else if (ret < 0)
- gf_log ("", GF_LOG_ERROR, "Status file of gsyncd is corrupt");
-
- close (status_fd);
- 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) {
- ret = -1;
- goto out;
- }
- x = (*s == '-') ? '_' : '-';
- *s++ = x;
- while ((s = strpbrk (s, "-_")))
- *s++ = x;
-
- ret = dict_get_str (dict, dk, param);
-out:
- GF_FREE (dk);
- return ret;
-}
-
-static int
-glusterd_parse_gsync_status (char *buf, gf_gsync_status_t *sts_val)
-{
- int ret = -1;
- int i = -1;
- int num_of_fields = 8;
- char *token = NULL;
- char **tokens = NULL;
- char **ptr = NULL;
- char *save_ptr = NULL;
- char na_buf[] = "N/A";
-
- if (!buf) {
- gf_log ("", GF_LOG_ERROR, "Empty buf");
- goto out;
- }
-
- tokens = calloc (num_of_fields, sizeof (char *));
- if (!tokens) {
- gf_log ("", GF_LOG_ERROR, "Out of memory");
- goto out;
- }
-
- ptr = tokens;
-
- for (token = strtok_r (buf, ",", &save_ptr); token;
- token = strtok_r (NULL, ",", &save_ptr)) {
- *ptr = gf_strdup(token);
- if (!*ptr) {
- gf_log ("", GF_LOG_ERROR, "Out of memory");
- goto out;
- }
- ptr++;
- }
-
- for (i = 0; i < num_of_fields; i++) {
- token = strtok_r (tokens[i], ":", &save_ptr);
- token = strtok_r (NULL, "\0", &save_ptr);
- token++;
-
- /* token NULL check */
- if (!token && (i != 0) &&
- (i != 5) && (i != 7))
- token = na_buf;
-
- if (i == 0) {
- if (!token)
- token = na_buf;
- else {
- token++;
- if (!token)
- token = na_buf;
- else
- token[strlen(token) - 1] = '\0';
- }
- memcpy (sts_val->slave_node, token, strlen(token));
- }
- if (i == 1)
- memcpy (sts_val->files_syncd, token, strlen(token));
- if (i == 2)
- memcpy (sts_val->purges_remaining, token, strlen(token));
- if (i == 3)
- memcpy (sts_val->total_files_skipped, token, strlen(token));
- if (i == 4)
- memcpy (sts_val->files_remaining, token, strlen(token));
- if (i == 5) {
- if (!token)
- token = na_buf;
- else {
- token++;
- if (!token)
- token = na_buf;
- else
- token[strlen(token) - 1] = '\0';
- }
- memcpy (sts_val->worker_status, token, strlen(token));
- }
- if (i == 6)
- memcpy (sts_val->bytes_remaining, token, strlen(token));
- if (i == 7) {
- if (!token)
- token = na_buf;
- else {
- token++;
- if (!token)
- token = na_buf;
- else
- token[strlen(token) - 2] = '\0';
- }
- memcpy (sts_val->crawl_status, token, strlen(token));
- }
- }
-
- ret = 0;
-out:
- for (i = 0; i< num_of_fields; i++)
- if (tokens[i])
- GF_FREE(tokens[i]);
-
- gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-
-static int
-glusterd_gsync_fetch_status_extra (char *path, gf_gsync_status_t *sts_val)
-{
- char sockpath[PATH_MAX] = {0,};
- struct sockaddr_un sa = {0,};
- int s = -1;
- struct pollfd pfd = {0,};
- int ret = 0;
-
- 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 = fcntl (s, F_GETFL);
- if (ret != -1)
- ret = fcntl (s, F_SETFL, ret | O_NONBLOCK);
- if (ret == -1)
- goto out;
-
- 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, sts_val->checkpoint_status,
- sizeof(sts_val->checkpoint_status));
- /* we expect a terminating 0 byte */
- if (ret == 0 || (ret > 0 && sts_val->checkpoint_status[ret - 1]))
- ret = -1;
- if (ret > 0) {
- ret = 0;
- }
-
-out:
- close (s);
- return ret;
-}
-
-int
-glusterd_fetch_values_from_config (char *master, char *slave,
- char *confpath, dict_t *confd,
- char **statefile,
- char **georep_session_wrkng_dir,
- char **socketfile)
-{
- int ret = 0;
-
- ret = glusterd_gsync_get_config (master, slave, confpath,
- confd);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Unable to get configuration data"
- "for %s(master), %s(slave)", master, slave);
- goto out;
- }
-
- if (statefile) {
- ret = dict_get_param (confd, "state_file", statefile);
- if (ret) {
- gf_log ("", GF_LOG_ERROR,
- "Unable to get state_file's name "
- "for %s(master), %s(slave). "
- "Please check gsync config file.",
- master, slave);
- goto out;
- }
- }
-
- if (georep_session_wrkng_dir) {
- ret = dict_get_param (confd, "georep_session_working_dir",
- georep_session_wrkng_dir);
- if (ret) {
- gf_log ("", GF_LOG_ERROR,
- "Unable to get geo-rep session's "
- "working directory name for %s(master), "
- "%s(slave). Please check gsync config file.",
- master, slave);
- goto out;
- }
- }
-
- if (socketfile) {
- ret = dict_get_param (confd, "state_socket_unencoded",
- socketfile);
- if (ret) {
- gf_log ("", GF_LOG_ERROR,
- "Unable to get socket file's name "
- "for %s(master), %s(slave). "
- "Please check gsync config file.",
- master, slave);
- goto out;
- }
- }
-
- ret = 0;
-out:
- gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-
-int
-glusterd_read_status_file (glusterd_volinfo_t *volinfo, char *slave,
- char *conf_path, dict_t *dict, char *node)
-{
- char brick_state_file[PATH_MAX] = "";
- char brick_path[PATH_MAX] = "";
- char temp_conf_path[PATH_MAX] = "";
- char *working_conf_path = NULL;
- char *georep_session_wrkng_dir = NULL;
- char *master = NULL;
- char tmp[1024] = "";
- char sts_val_name[1024] = "";
- char monitor_status[NAME_MAX] = "";
- char *statefile = NULL;
- char *socketfile = NULL;
- dict_t *confd = NULL;
- char *slavekey = NULL;
- char *slaveentry = NULL;
- char *brick_host_uuid = NULL;
- int brick_host_uuid_length = 0;
- int gsync_count = 0;
- int i = 0;
- int ret = 0;
- glusterd_brickinfo_t *brickinfo = NULL;
- gf_gsync_status_t *sts_val = NULL;
- gf_boolean_t is_template_in_use = _gf_false;
- glusterd_conf_t *priv = NULL;
- struct stat stbuf = {0,};
-
- GF_ASSERT (THIS);
- GF_ASSERT (THIS->private);
- GF_ASSERT (volinfo);
- GF_ASSERT (conf_path);
-
- master = volinfo->volname;
-
- confd = dict_new ();
- if (!confd) {
- gf_log ("", GF_LOG_ERROR, "Not able to create dict.");
- return -1;
- }
-
- priv = THIS->private;
-
- snprintf (temp_conf_path, sizeof(temp_conf_path) - 1,
- "%s/"GSYNC_CONF_TEMPLATE, priv->workdir);
-
- ret = lstat (conf_path, &stbuf);
- if (!ret) {
- gf_log ("", GF_LOG_INFO, "Using passed config template(%s).",
- conf_path);
- working_conf_path = conf_path;
- } else {
- gf_log ("", GF_LOG_WARNING, "Config file (%s) missing. "
- "Looking for template config file (%s)",
- conf_path, temp_conf_path);
- ret = lstat (temp_conf_path, &stbuf);
- if (ret) {
- gf_log ("", GF_LOG_ERROR,
- "Template config file (%s) missing.",
- temp_conf_path);
- goto out;
- }
- gf_log ("", GF_LOG_INFO, "Using default config template(%s).",
- temp_conf_path);
- working_conf_path = temp_conf_path;
- is_template_in_use = _gf_true;
- }
-
-fetch_data:
- ret = glusterd_fetch_values_from_config (master, slave,
- working_conf_path,
- confd,
- &statefile,
- &georep_session_wrkng_dir,
- &socketfile);
- if (ret) {
- if (is_template_in_use == _gf_false) {
- gf_log ("", GF_LOG_ERROR,
- "Unable to fetch config values "
- "for %s(master), %s(slave). "
- "Trying default config template",
- master, slave);
- working_conf_path = temp_conf_path;
- is_template_in_use = _gf_true;
- goto fetch_data;
- } else {
- gf_log ("", GF_LOG_ERROR,
- "Unable to fetch config values "
- "for %s(master), %s(slave)",
- master, slave);
- goto out;
- }
- }
-
- ret = glusterd_gsync_read_frm_status (statefile, monitor_status,
- sizeof (monitor_status));
- if (ret <= 0) {
- gf_log ("", GF_LOG_ERROR, "Unable to read the status"
- "file for %s(master), %s(slave)", master, slave);
- strncpy (monitor_status, "defunct", sizeof (monitor_status));
- }
-
- ret = dict_get_int32 (dict, "gsync-count", &gsync_count);
- if (ret)
- gsync_count = 0;
-
- list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) {
- if (uuid_compare (brickinfo->uuid, MY_UUID))
- continue;
-
- sts_val = GF_CALLOC (1, sizeof(gf_gsync_status_t),
- gf_common_mt_gsync_status_t);
- if (!sts_val) {
- gf_log ("", GF_LOG_ERROR, "Out Of Memory");
- goto out;
- }
-
- /* Creating the brick state file's path */
- memset(brick_state_file, '\0', PATH_MAX);
- memcpy (brick_path, brickinfo->path, PATH_MAX - 1);
- for (i = 0; i < strlen(brick_path) - 1; i++)
- if (brick_path[i] == '/')
- brick_path[i] = '_';
- ret = snprintf(brick_state_file, PATH_MAX - 1, "%s%s.status",
- georep_session_wrkng_dir, brick_path);
- brick_state_file[ret] = '\0';
-
- gf_log ("", GF_LOG_DEBUG, "brick_state_file = %s", brick_state_file);
-
- memset (tmp, '\0', sizeof(tmp));
-
- ret = glusterd_gsync_read_frm_status (brick_state_file,
- tmp, sizeof (tmp));
- if (ret <= 0) {
- gf_log ("", GF_LOG_ERROR, "Unable to read the status"
- "file for %s brick for %s(master), %s(slave) "
- "session", brickinfo->path, master, slave);
- memcpy (sts_val->slave_node, slave, strlen(slave));
- sts_val->slave_node[strlen(slave)] = '\0';
- ret = snprintf (sts_val->worker_status, sizeof(sts_val->worker_status), "N/A");
- sts_val->worker_status[ret] = '\0';
- ret = snprintf (sts_val->checkpoint_status, sizeof(sts_val->checkpoint_status), "N/A");
- sts_val->checkpoint_status[ret] = '\0';
- ret = snprintf (sts_val->crawl_status, sizeof(sts_val->crawl_status), "N/A");
- sts_val->crawl_status[ret] = '\0';
- ret = snprintf (sts_val->files_syncd, sizeof(sts_val->files_syncd), "N/A");
- sts_val->files_syncd[ret] = '\0';
- ret = snprintf (sts_val->purges_remaining, sizeof(sts_val->purges_remaining), "N/A");
- sts_val->purges_remaining[ret] = '\0';
- ret = snprintf (sts_val->total_files_skipped, sizeof(sts_val->total_files_skipped), "N/A");
- sts_val->total_files_skipped[ret] = '\0';
- ret = snprintf (sts_val->files_remaining, sizeof(sts_val->files_remaining), "N/A");
- sts_val->files_remaining[ret] = '\0';
- ret = snprintf (sts_val->bytes_remaining, sizeof(sts_val->bytes_remaining), "N/A");
- sts_val->bytes_remaining[ret] = '\0';
- goto store_status;
- }
-
- ret = glusterd_gsync_fetch_status_extra (socketfile, sts_val);
- if (ret || strlen(sts_val->checkpoint_status) == 0) {
- gf_log ("", GF_LOG_DEBUG, "No checkpoint status"
- "for %s(master), %s(slave)", master, slave);
- ret = snprintf (sts_val->checkpoint_status, sizeof(sts_val->checkpoint_status), "N/A");
- sts_val->checkpoint_status[ret] = '\0';
- }
-
- ret = glusterd_parse_gsync_status (tmp, sts_val);
- if (ret) {
- gf_log ("", GF_LOG_ERROR,
- "Unable to parse the gsync status for %s",
- brickinfo->path);
- memcpy (sts_val->slave_node, slave, strlen(slave));
- sts_val->slave_node[strlen(slave)] = '\0';
- ret = snprintf (sts_val->worker_status, sizeof(sts_val->worker_status), "N/A");
- sts_val->worker_status[ret] = '\0';
- ret = snprintf (sts_val->checkpoint_status, sizeof(sts_val->checkpoint_status), "N/A");
- sts_val->checkpoint_status[ret] = '\0';
- ret = snprintf (sts_val->crawl_status, sizeof(sts_val->crawl_status), "N/A");
- sts_val->crawl_status[ret] = '\0';
- ret = snprintf (sts_val->files_syncd, sizeof(sts_val->files_syncd), "N/A");
- sts_val->files_syncd[ret] = '\0';
- ret = snprintf (sts_val->purges_remaining, sizeof(sts_val->purges_remaining), "N/A");
- sts_val->purges_remaining[ret] = '\0';
- ret = snprintf (sts_val->total_files_skipped, sizeof(sts_val->total_files_skipped), "N/A");
- sts_val->total_files_skipped[ret] = '\0';
- ret = snprintf (sts_val->files_remaining, sizeof(sts_val->files_remaining), "N/A");
- sts_val->files_remaining[ret] = '\0';
- ret = snprintf (sts_val->bytes_remaining, sizeof(sts_val->bytes_remaining), "N/A");
- sts_val->bytes_remaining[ret] = '\0';
- }
-
-store_status:
- if ((strcmp (monitor_status, "Stable"))) {
- memcpy (sts_val->worker_status, monitor_status, strlen(monitor_status));
- sts_val->worker_status[strlen(monitor_status)] = '\0';
- ret = snprintf (sts_val->crawl_status, sizeof(sts_val->crawl_status), "N/A");
- sts_val->crawl_status[ret] = '\0';
- ret = snprintf (sts_val->checkpoint_status, sizeof(sts_val->checkpoint_status), "N/A");
- sts_val->checkpoint_status[ret] = '\0';
- }
-
- if (is_template_in_use) {
- ret = snprintf (sts_val->worker_status,
- sizeof(sts_val->worker_status),
- "Config Corrupted");
- sts_val->worker_status[ret] = '\0';
- }
-
- if (strcmp (sts_val->worker_status, "Active")) {
- ret = snprintf (sts_val->checkpoint_status, sizeof(sts_val->checkpoint_status), "N/A");
- sts_val->checkpoint_status[ret] = '\0';
- ret = snprintf (sts_val->crawl_status, sizeof(sts_val->crawl_status), "N/A");
- sts_val->crawl_status[ret] = '\0';
- }
-
- if (!strcmp (sts_val->slave_node, "N/A")) {
- memcpy (sts_val->slave_node, slave, strlen(slave));
- sts_val->slave_node[strlen(slave)] = '\0';
- }
-
- memcpy (sts_val->node, node, strlen(node));
- sts_val->node[strlen(node)] = '\0';
- memcpy (sts_val->brick, brickinfo->path, strlen(brickinfo->path));
- sts_val->brick[strlen(brickinfo->path)] = '\0';
-
- ret = glusterd_get_slave (volinfo, slave, &slavekey);
- if (ret < 0) {
- GF_FREE (sts_val);
- goto out;
- }
- memcpy (sts_val->slavekey, slavekey, strlen(slavekey));
- sts_val->slavekey[strlen(slavekey)] = '\0';
-
- brick_host_uuid = uuid_utoa(brickinfo->uuid);
- brick_host_uuid_length = strlen (brick_host_uuid);
- memcpy (sts_val->brick_host_uuid, brick_host_uuid,
- brick_host_uuid_length);
- sts_val->brick_host_uuid[brick_host_uuid_length] = '\0';
-
- memcpy (sts_val->master, master, strlen(master));
- sts_val->master[strlen(master)] = '\0';
-
- ret = dict_get_str (volinfo->gsync_slaves, slavekey,
- &slaveentry);
- if (ret < 0) {
- GF_FREE (sts_val);
- goto out;
- }
- memcpy (sts_val->session_slave, slaveentry,
- strlen(slaveentry));
- sts_val->session_slave[strlen(slaveentry)] = '\0';
-
- snprintf (sts_val_name, sizeof (sts_val_name), "status_value%d", gsync_count);
- ret = dict_set_bin (dict, sts_val_name, sts_val, sizeof(gf_gsync_status_t));
- if (ret) {
- GF_FREE (sts_val);
- goto out;
- }
-
- gsync_count++;
- sts_val = NULL;
- }
-
- ret = dict_set_int32 (dict, "gsync-count", gsync_count);
- if (ret)
- goto out;
-
-out:
- dict_unref (confd);
-
- return 0;
-}
-
-int
-glusterd_check_restart_gsync_session (glusterd_volinfo_t *volinfo, char *slave,
- dict_t *resp_dict, char *path_list,
- char *conf_path, gf_boolean_t is_force)
-{
-
- int ret = 0;
- glusterd_conf_t *priv = NULL;
- char *status_msg = NULL;
- gf_boolean_t is_running = _gf_false;
- char *op_errstr = NULL;
- char *key = NULL;
- xlator_t *this = NULL;
-
- GF_ASSERT (volinfo);
- GF_ASSERT (slave);
- this = THIS;
- GF_ASSERT (this);
- priv = this->private;
- GF_ASSERT (priv);
-
- key = slave;
-
- ret = glusterd_check_gsync_running_local (volinfo->volname,
- slave, conf_path,
- &is_running);
- if (!ret && (_gf_true != is_running))
- /* gsynd not running, nothing to do */
- goto out;
-
- ret = stop_gsync (volinfo->volname, slave, &status_msg,
- conf_path, &op_errstr,
- is_force);
- if (ret == 0 && status_msg)
- ret = dict_set_str (resp_dict, "gsync-status",
- status_msg);
- if (ret == 0) {
- dict_del (volinfo->gsync_active_slaves, key);
- ret = glusterd_start_gsync (volinfo, slave, path_list,
- conf_path, uuid_utoa(MY_UUID),
- NULL, _gf_false);
- if (!ret) {
- /* Add slave to the dict indicating geo-rep session is
- * running.*/
- ret = dict_set_dynstr_with_alloc (
- volinfo->gsync_active_slaves,
- key, "running");
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Unable to set "
- "key:%s value:running in dict. But the "
- "config succeeded.", key);
- goto out;
- }
- }
- }
-
- out:
- gf_log (this->name, GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-
-static int32_t
-glusterd_marker_changelog_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_gsync_knob (glusterd_volinfo_t *volinfo, char *key, int *vc)
-{
- int ret = -1;
- int conf_enabled = _gf_false;
-
- GF_ASSERT (THIS);
- GF_ASSERT (THIS->private);
-
- conf_enabled = glusterd_volinfo_get_boolean (volinfo, key);
- if (conf_enabled == -1) {
- gf_log ("", GF_LOG_ERROR,
- "failed to get key %s from volinfo", key);
- goto out;
- }
-
- ret = 0;
- if (conf_enabled == _gf_false) {
- *vc = 1;
- ret = glusterd_gsync_volinfo_dict_set (volinfo,
- key, "on");
- }
-
- out:
- gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-
-static int
-glusterd_set_gsync_confs (glusterd_volinfo_t *volinfo)
-{
- int ret = -1;
- int volfile_changed = 0;
-
- ret = glusterd_set_gsync_knob (volinfo,
- VKEY_MARKER_XTIME, &volfile_changed);
- if (ret)
- goto out;
-
- /**
- * enable ignore-pid-check blindly as it could be needed for
- * cascading setups.
- */
- ret = glusterd_set_gsync_knob (volinfo, VKEY_MARKER_XTIME_FORCE,
- &volfile_changed);
- if (ret)
- goto out;
-
- ret = glusterd_set_gsync_knob (volinfo,
- VKEY_CHANGELOG, &volfile_changed);
- if (ret)
- goto out;
-
- if (volfile_changed)
- ret = glusterd_marker_changelog_create_volfile (volinfo);
-
- out:
- return ret;
-}
-
-static int
-glusterd_get_gsync_status_mst_slv (glusterd_volinfo_t *volinfo,
- char *slave, char *conf_path,
- dict_t *rsp_dict, char *node)
-{
- char *statefile = NULL;
- uuid_t uuid = {0, };
- glusterd_conf_t *priv = NULL;
- int ret = 0;
- gf_boolean_t is_template_in_use = _gf_false;
- struct stat stbuf = {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) {
- gf_log ("", GF_LOG_INFO, "geo-replication status %s %s :"
- "session is not active", volinfo->volname, slave);
-
- ret = glusterd_get_statefile_name (volinfo, slave,
- conf_path, &statefile,
- &is_template_in_use);
- if (ret) {
- if (!strstr(slave, "::"))
- gf_log ("", GF_LOG_INFO,
- "%s is not a valid slave url.", slave);
- else
- gf_log ("", GF_LOG_INFO, "Unable to get"
- " statefile's name");
- ret = 0;
- goto out;
- }
-
- ret = lstat (statefile, &stbuf);
- if (ret) {
- gf_log ("", GF_LOG_INFO, "%s statefile not present.",
- statefile);
- ret = 0;
- goto out;
- }
- }
-
- ret = glusterd_read_status_file (volinfo, slave, conf_path,
- rsp_dict, node);
-out:
- if (statefile)
- GF_FREE (statefile);
-
- 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,
- char *node)
-{
- glusterd_gsync_status_temp_t param = {0, };
-
- GF_ASSERT (volinfo);
-
- param.rsp_dict = rsp_dict;
- param.volinfo = volinfo;
- param.node = node;
- dict_foreach (volinfo->gsync_slaves, _get_status_mst_slv, &param);
-
- return 0;
-}
-
-static int
-glusterd_get_gsync_status_all (dict_t *rsp_dict, char *node)
-{
-
- 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, node);
- 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 *conf_path = NULL;
- char errmsg[PATH_MAX] = {0, };
- gf_boolean_t exists = _gf_false;
- glusterd_volinfo_t *volinfo = NULL;
- int ret = 0;
- char my_hostname[256] = {0,};
-
- ret = gethostname(my_hostname, 256);
- if (ret) {
- /* stick to N/A */
- (void) strcpy (my_hostname, "N/A");
- }
-
- ret = dict_get_str (dict, "master", &volname);
- if (ret < 0){
- ret = glusterd_get_gsync_status_all (rsp_dict, my_hostname);
- 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, my_hostname);
- goto out;
- }
-
- ret = dict_get_str (dict, "conf_path", &conf_path);
- if (ret) {
- gf_log ("", GF_LOG_ERROR,
- "Unable to fetch conf file path.");
- goto out;
- }
-
- ret = glusterd_get_gsync_status_mst_slv (volinfo, slave, conf_path,
- rsp_dict, my_hostname);
-
- out:
- gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-
-static int
-glusterd_gsync_delete (glusterd_volinfo_t *volinfo, char *slave,
- char *slave_host, char *slave_vol, char *path_list,
- dict_t *dict, dict_t *resp_dict, char **op_errstr)
-{
- int32_t ret = -1;
- runner_t runner = {0,};
- glusterd_conf_t *priv = NULL;
- char *master = NULL;
- char *gl_workdir = NULL;
- char geo_rep_dir[PATH_MAX] = "";
- char *conf_path = NULL;
-
- GF_ASSERT (slave);
- GF_ASSERT (slave_host);
- GF_ASSERT (slave_vol);
- GF_ASSERT (op_errstr);
- GF_ASSERT (dict);
- GF_ASSERT (resp_dict);
-
- 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;
- }
-
- ret = dict_get_str (dict, "conf_path", &conf_path);
- if (ret) {
- gf_log ("", GF_LOG_ERROR,
- "Unable to fetch conf file path.");
- goto out;
- }
-
- gl_workdir = priv->workdir;
- master = "";
- runinit (&runner);
- runner_add_args (&runner, GSYNCD_PREFIX"/gsyncd",
- "--delete", "-c", NULL);
- runner_argprintf (&runner, "%s", conf_path);
- runner_argprintf (&runner, "--iprefix=%s", DATADIR);
-
- if (volinfo) {
- master = volinfo->volname;
- runner_argprintf (&runner, ":%s", master);
- }
- runner_add_arg (&runner, slave);
- runner_redir (&runner, STDOUT_FILENO, RUN_PIPE);
- synclock_unlock (&priv->big_lock);
- ret = runner_run (&runner);
- synclock_lock (&priv->big_lock);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "gsyncd failed to "
- "delete session info for %s and %s peers",
- master, slave);
-
- gf_asprintf (op_errstr, "gsyncd failed to "
- "delete session info for %s and %s peers",
- master, slave);
-
- goto out;
- }
-
- ret = snprintf (geo_rep_dir, sizeof(geo_rep_dir) - 1,
- "%s/"GEOREP"/%s_%s_%s", gl_workdir,
- volinfo->volname, slave_host, slave_vol);
- geo_rep_dir[ret] = '\0';
-
- ret = rmdir (geo_rep_dir);
- if (ret) {
- if (errno == ENOENT)
- gf_log ("", GF_LOG_DEBUG, "Geo Rep Dir(%s) Not Present.",
- geo_rep_dir);
- else {
- gf_log ("", GF_LOG_ERROR, "Unable to delete "
- "Geo Rep Dir(%s). Error: %s", geo_rep_dir,
- strerror (errno));
- goto out;
- }
- }
-
- ret = 0;
-
- gf_asprintf (op_errstr, "delete successful");
-
-out:
- gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-
-int
-glusterd_op_sys_exec (dict_t *dict, char **op_errstr, dict_t *rsp_dict)
-{
- char buf[PATH_MAX] = "";
- char cmd_arg_name[PATH_MAX] = "";
- char output_name[PATH_MAX] = "";
- char errmsg[PATH_MAX] = "";
- char *ptr = NULL;
- char *bufp = NULL;
- char *command = NULL;
- char **cmd_args = NULL;
- int ret = -1;
- int i = -1;
- int cmd_args_count = 0;
- int output_count = 0;
- glusterd_conf_t *priv = NULL;
- runner_t runner = {0,};
-
- GF_ASSERT (dict);
- GF_ASSERT (op_errstr);
- GF_ASSERT (rsp_dict);
-
- 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;
- }
-
- ret = dict_get_str (dict, "command", &command);
- if (ret) {
- gf_log ("", GF_LOG_ERROR,
- "Unable to get command from dict");
- goto out;
- }
-
- ret = dict_get_int32 (dict, "cmd_args_count", &cmd_args_count);
- if (ret)
- gf_log ("", GF_LOG_INFO, "No cmd_args_count");
-
- if (cmd_args_count) {
- cmd_args = GF_CALLOC (cmd_args_count, sizeof (char*),
- gf_common_mt_char);
- if (!cmd_args) {
- gf_log ("", GF_LOG_ERROR, "Unable to calloc. "
- "Errno = %s", strerror(errno));
- goto out;
- }
-
- for (i=1; i <= cmd_args_count; i++) {
- memset (cmd_arg_name, '\0', sizeof(cmd_arg_name));
- snprintf (cmd_arg_name, sizeof(cmd_arg_name),
- "cmd_arg_%d", i);
- ret = dict_get_str (dict, cmd_arg_name, &cmd_args[i-1]);
- if (ret) {
- gf_log ("", GF_LOG_ERROR,
- "Unable to get %s in dict",
- cmd_arg_name);
- goto out;
- }
- }
- }
-
- runinit (&runner);
- runner_argprintf (&runner, GSYNCD_PREFIX"/peer_%s", command);
- for (i=0; i < cmd_args_count; i++)
- runner_add_arg (&runner, cmd_args[i]);
- runner_redir (&runner, STDOUT_FILENO, RUN_PIPE);
- synclock_unlock (&priv->big_lock);
- ret = runner_start (&runner);
- if (ret == -1) {
- snprintf (errmsg, sizeof (errmsg), "Unable to "
- "execute command. Error : %s",
- strerror (errno));
- *op_errstr = gf_strdup (errmsg);
- gf_log ("", GF_LOG_ERROR, "%s", errmsg);
- ret = -1;
- synclock_lock (&priv->big_lock);
- goto out;
- }
-
- do {
- ptr = fgets(buf, sizeof(buf), runner_chio (&runner, STDOUT_FILENO));
- if (ptr) {
- ret = dict_get_int32 (rsp_dict, "output_count", &output_count);
- if (ret)
- output_count = 1;
- else
- output_count++;
- memset (output_name, '\0', sizeof (output_name));
- snprintf (output_name, sizeof (output_name),
- "output_%d", output_count);
- if (buf[strlen(buf) - 1] == '\n')
- buf[strlen(buf) - 1] = '\0';
- bufp = gf_strdup (buf);
- if (!bufp)
- gf_log ("", GF_LOG_ERROR, "gf_strdup failed.");
- ret = dict_set_dynstr (rsp_dict, output_name, bufp);
- if (ret) {
- GF_FREE (bufp);
- gf_log ("", GF_LOG_ERROR, "output set failed.");
- }
- ret = dict_set_int32 (rsp_dict, "output_count", output_count);
- if (ret)
- gf_log ("", GF_LOG_ERROR, "output_count set failed.");
- }
- } while (ptr);
-
- ret = runner_end (&runner);
- if (ret) {
- snprintf (errmsg, sizeof (errmsg), "Unable to "
- "end. Error : %s",
- strerror (errno));
- *op_errstr = gf_strdup (errmsg);
- gf_log ("", GF_LOG_ERROR, "%s", errmsg);
- ret = -1;
- synclock_lock (&priv->big_lock);
- goto out;
- }
- synclock_lock (&priv->big_lock);
-
- ret = 0;
-out:
- if (cmd_args) {
- GF_FREE (cmd_args);
- cmd_args = NULL;
- }
-
- gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-
-int
-glusterd_op_copy_file (dict_t *dict, char **op_errstr)
-{
- char abs_filename[PATH_MAX] = "";
- char errmsg[PATH_MAX] = "";
- char *filename = NULL;
- char *host_uuid = NULL;
- char uuid_str [64] = {0};
- char *contents = NULL;
- char buf[1024] = "";
- int ret = -1;
- int fd = -1;
- int bytes_writen = 0;
- int bytes_read = 0;
- int contents_size = -1;
- int file_mode = -1;
- glusterd_conf_t *priv = NULL;
- struct stat stbuf = {0,};
- gf_boolean_t free_contents = _gf_true;
-
- 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;
- }
-
- ret = dict_get_str (dict, "host-uuid", &host_uuid);
- if (ret < 0)
- goto out;
-
- ret = dict_get_str (dict, "source", &filename);
- if (ret < 0) {
- gf_log ("", GF_LOG_ERROR, "Unable to fetch"
- " filename from dict.");
- *op_errstr = gf_strdup ("command unsuccessful");
- goto out;
- }
- snprintf (abs_filename, sizeof(abs_filename),
- "%s/%s", priv->workdir, filename);
-
- uuid_utoa_r (MY_UUID, uuid_str);
- if (!strcmp (uuid_str, host_uuid)) {
- ret = lstat (abs_filename, &stbuf);
- if (ret) {
- snprintf (errmsg, sizeof (errmsg), "Source file"
- " does not exist in %s", priv->workdir);
- *op_errstr = gf_strdup (errmsg);
- gf_log ("", GF_LOG_ERROR, "%s", errmsg);
- goto out;
- }
-
- contents = GF_CALLOC(1, stbuf.st_size+1, gf_common_mt_char);
- if (!contents) {
- snprintf (errmsg, sizeof (errmsg),
- "Unable to allocate memory");
- *op_errstr = gf_strdup (errmsg);
- gf_log ("", GF_LOG_ERROR, "%s", errmsg);
- ret = -1;
- goto out;
- }
-
- fd = open (abs_filename, O_RDONLY);
- if (fd < 0) {
- snprintf (errmsg, sizeof (errmsg), "Unable to open %s",
- abs_filename);
- *op_errstr = gf_strdup (errmsg);
- gf_log ("", GF_LOG_ERROR, "%s", errmsg);
- ret = -1;
- goto out;
- }
-
- do {
- ret = read (fd, buf, sizeof(buf));
- if (ret > 0) {
- memcpy (contents+bytes_read, buf, ret);
- bytes_read += ret;
- memset (buf, '\0', sizeof(buf));
- }
- } while (ret > 0);
-
- if (bytes_read != stbuf.st_size) {
- snprintf (errmsg, sizeof (errmsg), "Unable to read all "
- "the data from %s", abs_filename);
- *op_errstr = gf_strdup (errmsg);
- gf_log ("", GF_LOG_ERROR, "%s", errmsg);
- ret = -1;
- goto out;
- }
-
- ret = dict_set_int32 (dict, "contents_size", stbuf.st_size);
- if (ret) {
- snprintf (errmsg, sizeof (errmsg), "Unable to set"
- " contents size in dict.");
- *op_errstr = gf_strdup (errmsg);
- gf_log ("", GF_LOG_ERROR, "%s", errmsg);
- goto out;
- }
-
- ret = dict_set_int32 (dict, "file_mode",
- (int32_t)stbuf.st_mode);
- if (ret) {
- snprintf (errmsg, sizeof (errmsg), "Unable to set"
- " file mode in dict.");
- *op_errstr = gf_strdup (errmsg);
- gf_log ("", GF_LOG_ERROR, "%s", errmsg);
- goto out;
- }
-
- ret = dict_set_bin (dict, "common_pem_contents",
- contents, stbuf.st_size);
- if (ret) {
- snprintf (errmsg, sizeof (errmsg), "Unable to set"
- " pem contents in dict.");
- *op_errstr = gf_strdup (errmsg);
- gf_log ("", GF_LOG_ERROR, "%s", errmsg);
- goto out;
- }
- free_contents = _gf_false;
- } else {
- free_contents = _gf_false;
- ret = dict_get_bin (dict, "common_pem_contents",
- (void **) &contents);
- if (ret) {
- snprintf (errmsg, sizeof (errmsg), "Unable to get"
- " pem contents in dict.");
- *op_errstr = gf_strdup (errmsg);
- gf_log ("", GF_LOG_ERROR, "%s", errmsg);
- goto out;
- }
- ret = dict_get_int32 (dict, "contents_size", &contents_size);
- if (ret) {
- snprintf (errmsg, sizeof (errmsg), "Unable to set"
- " contents size in dict.");
- *op_errstr = gf_strdup (errmsg);
- gf_log ("", GF_LOG_ERROR, "%s", errmsg);
- goto out;
- }
-
- ret = dict_get_int32 (dict, "file_mode", &file_mode);
- if (ret) {
- snprintf (errmsg, sizeof (errmsg), "Unable to get"
- " file mode in dict.");
- *op_errstr = gf_strdup (errmsg);
- gf_log ("", GF_LOG_ERROR, "%s", errmsg);
- goto out;
- }
-
- fd = open (abs_filename, O_WRONLY | O_TRUNC | O_CREAT, 0600);
- if (fd < 0) {
- snprintf (errmsg, sizeof (errmsg), "Unable to open %s",
- abs_filename);
- *op_errstr = gf_strdup (errmsg);
- gf_log ("", GF_LOG_ERROR, "%s", errmsg);
- ret = -1;
- goto out;
- }
-
- bytes_writen = write (fd, contents, contents_size);
-
- if (bytes_writen != contents_size) {
- snprintf (errmsg, sizeof (errmsg), "Failed to write"
- " to %s", abs_filename);
- *op_errstr = gf_strdup (errmsg);
- gf_log ("", GF_LOG_ERROR, "%s", errmsg);
- ret = -1;
- goto out;
- }
-
- fchmod (fd, file_mode);
- }
-
- ret = 0;
-out:
- if (fd != -1)
- close (fd);
-
- if (free_contents)
- GF_FREE(contents);
-
- 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;
- char *host_uuid = NULL;
- char *slave = NULL;
- char *slave_url = NULL;
- char *slave_vol = NULL;
- char *slave_host = NULL;
- char *volname = NULL;
- char *path_list = NULL;
- glusterd_volinfo_t *volinfo = NULL;
- glusterd_conf_t *priv = NULL;
- gf_boolean_t is_force = _gf_false;
- char *status_msg = NULL;
- gf_boolean_t is_running = _gf_false;
- char *conf_path = NULL;
- char errmsg[PATH_MAX] = "";
- char *key = NULL;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- priv = this->private;
- GF_ASSERT (priv);
- GF_ASSERT (dict);
- GF_ASSERT (op_errstr);
- GF_ASSERT (rsp_dict);
-
- 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) {
- ret = glusterd_get_gsync_status (dict, op_errstr, rsp_dict);
- goto out;
- }
-
- ret = dict_get_str (dict, "slave", &slave);
- if (ret < 0)
- goto out;
-
- key = slave;
-
- ret = dict_get_str (dict, "slave_url", &slave_url);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Unable to fetch slave url.");
- goto out;
- }
-
- ret = dict_get_str (dict, "slave_host", &slave_host);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Unable to fetch slave hostname.");
- goto out;
- }
-
- ret = dict_get_str (dict, "slave_vol", &slave_vol);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Unable to fetch slave volume name.");
- goto out;
- }
-
- ret = dict_get_str (dict, "conf_path", &conf_path);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Unable to fetch conf file path.");
- goto out;
- }
-
- if (dict_get_str (dict, "master", &volname) == 0) {
- ret = glusterd_volinfo_find (volname, &volinfo);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING, "Volinfo for"
- " %s (master) not found", volname);
- goto out;
- }
-
- ret = glusterd_get_local_brickpaths (volinfo, &path_list);
- }
-
- if (type == GF_GSYNC_OPTION_TYPE_CONFIG) {
- ret = glusterd_gsync_configure (volinfo, slave, path_list,
- dict, rsp_dict, op_errstr);
- if (!ret) {
- ret = dict_set_str (rsp_dict, "conf_path", conf_path);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Unable to store conf_file_path.");
- goto out;
- }
- }
- goto out;
- }
-
- if (type == GF_GSYNC_OPTION_TYPE_DELETE) {
- ret = glusterd_remove_slave_in_info(volinfo, slave, op_errstr);
- if (ret && !is_force && path_list)
- goto out;
-
- ret = glusterd_gsync_delete (volinfo, slave, slave_host,
- slave_vol, path_list, dict,
- rsp_dict, op_errstr);
- goto out;
- }
-
- if (!volinfo) {
- ret = -1;
- goto out;
- }
-
- is_force = dict_get_str_boolean (dict, "force", _gf_false);
-
- if (type == GF_GSYNC_OPTION_TYPE_START) {
- /* Add slave to the dict indicating geo-rep session is running*/
- ret = dict_set_dynstr_with_alloc (volinfo->gsync_active_slaves,
- key, "running");
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Unable to set key:%s"
- " value:running in the dict", key);
- goto out;
- }
-
- ret = glusterd_start_gsync (volinfo, slave, path_list,
- conf_path, host_uuid, op_errstr,
- _gf_false);
-
- /* Delete added slave in the dict if start fails*/
- if (ret)
- dict_del (volinfo->gsync_active_slaves, key);
- }
-
- if (type == GF_GSYNC_OPTION_TYPE_STOP ||
- type == GF_GSYNC_OPTION_TYPE_PAUSE ||
- type == GF_GSYNC_OPTION_TYPE_RESUME) {
- ret = glusterd_check_gsync_running_local (volinfo->volname,
- slave, conf_path,
- &is_running);
- if (!ret && !is_force && path_list &&
- (_gf_true != is_running)) {
- gf_log (this->name, 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;
- }
-
- if (type == GF_GSYNC_OPTION_TYPE_PAUSE) {
- ret = gd_pause_or_resume_gsync (dict, volname, slave,
- slave_host, slave_vol,
- conf_path, op_errstr,
- _gf_true);
- if (ret)
- gf_log(this->name, GF_LOG_ERROR, GEOREP
- " Pause Failed");
- else
- dict_del (volinfo->gsync_active_slaves, key);
-
- } else if (type == GF_GSYNC_OPTION_TYPE_RESUME) {
-
- /* Add slave to the dict indicating geo-rep session is
- * running*/
- ret = dict_set_dynstr_with_alloc (
- volinfo->gsync_active_slaves,
- key, "running");
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Unable to set "
- "key:%s value:running in dict", key);
- goto out;
- }
-
- ret = gd_pause_or_resume_gsync (dict, volname, slave,
- slave_host, slave_vol,
- conf_path, op_errstr,
- _gf_false);
- if (ret) {
- gf_log(this->name, GF_LOG_ERROR, GEOREP
- " Resume Failed");
- dict_del (volinfo->gsync_active_slaves, key);
- }
- } else {
-
- ret = stop_gsync (volname, slave, &status_msg,
- conf_path, op_errstr, is_force);
-
- if (ret == 0 && status_msg)
- ret = dict_set_str (rsp_dict, "gsync-status",
- status_msg);
- if (!ret) {
- ret = glusterd_create_status_file (
- volinfo->volname,
- slave, slave_host,
- slave_vol,"Stopped");
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Unable to update state_file. "
- "Error : %s", strerror (errno));
- }
- dict_del (volinfo->gsync_active_slaves, key);
- }
- }
- }
-
-out:
- if (path_list) {
- GF_FREE (path_list);
- path_list = NULL;
- }
-
- gf_log (this->name, GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-
-int
-glusterd_get_slave_details_confpath (glusterd_volinfo_t *volinfo,
- dict_t *dict, char **slave_url,
- char **slave_host, char **slave_vol,
- char **conf_path, char **op_errstr)
-{
- int ret = -1;
- char confpath[PATH_MAX] = "";
- glusterd_conf_t *priv = NULL;
- char *slave = NULL;
-
- GF_ASSERT (THIS);
- priv = THIS->private;
- GF_ASSERT (priv);
-
- ret = dict_get_str (dict, "slave", &slave);
- if (ret || !slave) {
- gf_log ("", GF_LOG_ERROR, "Unable to fetch slave from dict");
- ret = -1;
- goto out;
- }
-
- ret = glusterd_get_slave_info (slave, slave_url,
- slave_host, slave_vol, op_errstr);
- if (ret) {
- gf_log ("", GF_LOG_ERROR,
- "Unable to fetch slave details.");
- ret = -1;
- goto out;
- }
-
- ret = dict_set_str (dict, "slave_url", *slave_url);
- if (ret) {
- gf_log ("", GF_LOG_ERROR,
- "Unable to store slave IP.");
- goto out;
- }
-
- ret = dict_set_str (dict, "slave_host", *slave_host);
- if (ret) {
- gf_log ("", GF_LOG_ERROR,
- "Unable to store slave hostname");
- goto out;
- }
-
- ret = dict_set_str (dict, "slave_vol", *slave_vol);
- if (ret) {
- gf_log ("", GF_LOG_ERROR,
- "Unable to store slave volume name.");
- goto out;
- }
-
- ret = snprintf (confpath, sizeof(confpath) - 1,
- "%s/"GEOREP"/%s_%s_%s/gsyncd.conf",
- priv->workdir, volinfo->volname,
- *slave_host, *slave_vol);
- confpath[ret] = '\0';
- *conf_path = gf_strdup (confpath);
- if (!(*conf_path)) {
- gf_log ("", GF_LOG_ERROR,
- "Unable to gf_strdup. Error: %s", strerror (errno));
- ret = -1;
- goto out;
- }
-
- ret = dict_set_str (dict, "conf_path", *conf_path);
- if (ret) {
- gf_log ("", GF_LOG_ERROR,
- "Unable to store conf_path");
- goto out;
- }
-
-out:
- gf_log ("", GF_LOG_DEBUG,"Returning %d", ret);
- return ret;
-
-}
-
-int
-glusterd_get_slave_info (char *slave,
- char **slave_url, char **hostname,
- char **slave_vol, char **op_errstr)
-{
- char *tmp = NULL;
- char *save_ptr = NULL;
- char **linearr = NULL;
- int32_t ret = -1;
- char errmsg[PATH_MAX] = "";
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
-
- ret = glusterd_urltransform_single (slave, "normalize",
- &linearr);
- if (ret == -1) {
- ret = snprintf (errmsg, sizeof(errmsg) - 1,
- "Invalid Url: %s", slave);
- errmsg[ret] = '\0';
- *op_errstr = gf_strdup (errmsg);
- gf_log (this->name, GF_LOG_ERROR, "Failed to normalize url");
- goto out;
- }
-
- tmp = strtok_r (linearr[0], "/", &save_ptr);
- tmp = strtok_r (NULL, "/", &save_ptr);
- slave = strtok_r (tmp, ":", &save_ptr);
- if (slave) {
- ret = glusterd_geo_rep_parse_slave (slave, hostname, op_errstr);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Invalid slave url: %s", *op_errstr);
- goto out;
- }
- gf_log (this->name, GF_LOG_DEBUG, "Hostname : %s", *hostname);
-
- *slave_url = gf_strdup (slave);
- if (!*slave_url) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to gf_strdup");
- ret = -1;
- goto out;
- }
- gf_log (this->name, GF_LOG_DEBUG, "Slave URL : %s", *slave_url);
- ret = 0;
- } else {
- gf_log (this->name, GF_LOG_ERROR, "Invalid slave name");
- goto out;
- }
-
- slave = strtok_r (NULL, ":", &save_ptr);
- if (slave) {
- *slave_vol = gf_strdup (slave);
- if (!*slave_vol) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to gf_strdup");
- ret = -1;
- GF_FREE (*slave_url);
- goto out;
- }
- gf_log (this->name, GF_LOG_DEBUG, "Slave Vol : %s", *slave_vol);
- ret = 0;
- } else {
- gf_log (this->name, GF_LOG_ERROR, "Invalid slave name");
- goto out;
- }
-
-out:
- gf_log (this->name, GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-
-static void
-runinit_gsyncd_setrx (runner_t *runner, char *conf_path)
-{
- runinit (runner);
- runner_add_args (runner, GSYNCD_PREFIX"/gsyncd", "-c", NULL);
- runner_argprintf (runner, "%s", conf_path);
- runner_add_arg (runner, "--config-set-rx");
-}
-
-static int
-glusterd_check_gsync_present (int *valid_state)
-{
- char buff[PATH_MAX] = {0, };
- runner_t runner = {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;
- }
- goto out;
- }
-
- ptr = fgets(buff, sizeof(buff), runner_chio (&runner, STDOUT_FILENO));
- 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:
-
- runner_end (&runner);
-
- gf_log ("glusterd", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-
-}
-
-static int
-create_conf_file (glusterd_conf_t *conf, char *conf_path)
-#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;
- runner_t runner = {0,};
- char georepdir[PATH_MAX] = {0,};
- int valid_state = 0;
-
- valid_state = -1;
- ret = glusterd_check_gsync_present (&valid_state);
- if (-1 == ret) {
- ret = valid_state;
- goto out;
- }
-
- ret = snprintf (georepdir, sizeof(georepdir) - 1, "%s/"GEOREP,
- conf->workdir);
- georepdir[ret] = '\0';
-
- /************
- * master pre-configuration
- ************/
-
- /* remote-gsyncd */
- runinit_gsyncd_setrx (&runner, conf_path);
- runner_add_args (&runner, "remote-gsyncd", GSYNCD_PREFIX"/gsyncd", ".", ".", NULL);
- RUN_GSYNCD_CMD;
-
- runinit_gsyncd_setrx (&runner, conf_path);
- runner_add_args (&runner, "remote-gsyncd", "/nonexistent/gsyncd",
- ".", "^ssh:", NULL);
- RUN_GSYNCD_CMD;
-
- /* gluster-command-dir */
- runinit_gsyncd_setrx (&runner, conf_path);
- runner_add_args (&runner, "gluster-command-dir", SBIN_DIR"/",
- ".", ".", NULL);
- RUN_GSYNCD_CMD;
-
- /* gluster-params */
- runinit_gsyncd_setrx (&runner, conf_path);
- runner_add_args (&runner, "gluster-params",
- "aux-gfid-mount",
- ".", ".", NULL);
- RUN_GSYNCD_CMD;
-
- /* ssh-command */
- runinit_gsyncd_setrx (&runner, conf_path);
- 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;
-
- /* ssh-command tar */
- runinit_gsyncd_setrx (&runner, conf_path);
- runner_add_arg (&runner, "ssh-command-tar");
- runner_argprintf (&runner,
- "ssh -oPasswordAuthentication=no "
- "-oStrictHostKeyChecking=no "
- "-i %s/tar_ssh.pem", georepdir);
- runner_add_args (&runner, ".", ".", NULL);
- RUN_GSYNCD_CMD;
-
- /* pid-file */
- runinit_gsyncd_setrx (&runner, conf_path);
- runner_add_arg (&runner, "pid-file");
- runner_argprintf (&runner, "%s/${mastervol}_${remotehost}_${slavevol}/${eSlave}.pid", georepdir);
- runner_add_args (&runner, ".", ".", NULL);
- RUN_GSYNCD_CMD;
-
- /* geo-rep-working-dir */
- runinit_gsyncd_setrx (&runner, conf_path);
- runner_add_arg (&runner, "georep-session-working-dir");
- runner_argprintf (&runner, "%s/${mastervol}_${remotehost}_${slavevol}/", georepdir);
- runner_add_args (&runner, ".", ".", NULL);
- RUN_GSYNCD_CMD;
-
- /* state-file */
- runinit_gsyncd_setrx (&runner, conf_path);
- runner_add_arg (&runner, "state-file");
- runner_argprintf (&runner, "%s/${mastervol}_${remotehost}_${slavevol}/${eSlave}.status", georepdir);
- runner_add_args (&runner, ".", ".", NULL);
- RUN_GSYNCD_CMD;
-
- /* state-detail-file */
- runinit_gsyncd_setrx (&runner, conf_path);
- runner_add_arg (&runner, "state-detail-file");
- runner_argprintf (&runner, "%s/${mastervol}_${remotehost}_${slavevol}/${eSlave}-detail.status", georepdir);
- runner_add_args (&runner, ".", ".", NULL);
- RUN_GSYNCD_CMD;
-
- /* state-socket */
- runinit_gsyncd_setrx (&runner, conf_path);
- runner_add_arg (&runner, "state-socket-unencoded");
- runner_argprintf (&runner, "%s/${mastervol}_${remotehost}_${slavevol}/${eSlave}.socket", georepdir);
- runner_add_args (&runner, ".", ".", NULL);
- RUN_GSYNCD_CMD;
-
- /* socketdir */
- runinit_gsyncd_setrx (&runner, conf_path);
- runner_add_args (&runner, "socketdir", GLUSTERD_SOCK_DIR, ".", ".", NULL);
- RUN_GSYNCD_CMD;
-
- /* log-file */
- runinit_gsyncd_setrx (&runner, conf_path);
- runner_add_args (&runner,
- "log-file",
- DEFAULT_LOG_FILE_DIRECTORY"/"GEOREP"/${mastervol}/${eSlave}.log",
- ".", ".", NULL);
- RUN_GSYNCD_CMD;
-
- /* changelog-log-file */
- runinit_gsyncd_setrx (&runner, conf_path);
- runner_add_args (&runner,
- "changelog-log-file",
- DEFAULT_LOG_FILE_DIRECTORY"/"GEOREP"/${mastervol}/${eSlave}${local_id}-changes.log",
- ".", ".", NULL);
- RUN_GSYNCD_CMD;
-
- /* gluster-log-file */
- runinit_gsyncd_setrx (&runner, conf_path);
- runner_add_args (&runner,
- "gluster-log-file",
- DEFAULT_LOG_FILE_DIRECTORY"/"GEOREP"/${mastervol}/${eSlave}${local_id}.gluster.log",
- ".", ".", NULL);
- RUN_GSYNCD_CMD;
-
- /* ignore-deletes */
- runinit_gsyncd_setrx (&runner, conf_path);
- runner_add_args (&runner, "ignore-deletes", "true", ".", ".", NULL);
- RUN_GSYNCD_CMD;
-
- /* special-sync-mode */
- runinit_gsyncd_setrx (&runner, conf_path);
- runner_add_args (&runner, "special-sync-mode", "partial", ".", ".", NULL);
- RUN_GSYNCD_CMD;
-
- /* change-detector == changelog */
- runinit_gsyncd_setrx (&runner, conf_path);
- runner_add_args(&runner, "change-detector", "changelog", ".", ".", NULL);
- RUN_GSYNCD_CMD;
-
- runinit_gsyncd_setrx (&runner, conf_path);
- runner_add_arg(&runner, "working-dir");
- runner_argprintf(&runner, "%s/${mastervol}/${eSlave}",
- DEFAULT_GLUSTERFSD_MISC_DIRETORY);
- runner_add_args (&runner, ".", ".", NULL);
- RUN_GSYNCD_CMD;
-
- /************
- * slave pre-configuration
- ************/
-
- /* gluster-command-dir */
- runinit_gsyncd_setrx (&runner, conf_path);
- runner_add_args (&runner, "gluster-command-dir", SBIN_DIR"/",
- ".", NULL);
- RUN_GSYNCD_CMD;
-
- /* gluster-params */
- runinit_gsyncd_setrx (&runner, conf_path);
- runner_add_args (&runner, "gluster-params",
- "aux-gfid-mount",
- ".", NULL);
- RUN_GSYNCD_CMD;
-
- /* log-file */
- runinit_gsyncd_setrx (&runner, conf_path);
- runner_add_args (&runner,
- "log-file",
- DEFAULT_LOG_FILE_DIRECTORY"/"GEOREP"-slaves/${session_owner}:${eSlave}.log",
- ".", NULL);
- RUN_GSYNCD_CMD;
-
- /* MountBroker log-file */
- runinit_gsyncd_setrx (&runner, conf_path);
- runner_add_args (&runner,
- "log-file-mbr",
- DEFAULT_LOG_FILE_DIRECTORY"/"GEOREP"-slaves/mbr/${session_owner}:${eSlave}.log",
- ".", NULL);
- RUN_GSYNCD_CMD;
-
- /* gluster-log-file */
- runinit_gsyncd_setrx (&runner, conf_path);
- runner_add_args (&runner,
- "gluster-log-file",
- DEFAULT_LOG_FILE_DIRECTORY"/"GEOREP"-slaves/${session_owner}:${eSlave}.gluster.log",
- ".", NULL);
- RUN_GSYNCD_CMD;
-
- out:
- return ret ? -1 : 0;
-}
-
-static int
-glusterd_create_essential_dir_files (glusterd_volinfo_t *volinfo, dict_t *dict,
- char *slave, char *slave_host,
- char *slave_vol, char **op_errstr)
-{
- int ret = -1;
- char *conf_path = NULL;
- char *statefile = NULL;
- char buf[PATH_MAX] = "";
- char errmsg[PATH_MAX] = "";
- glusterd_conf_t *conf = NULL;
- struct stat stbuf = {0,};
-
- GF_ASSERT (THIS);
- conf = THIS->private;
-
- ret = dict_get_str (dict, "conf_path", &conf_path);
- if (ret) {
- snprintf (errmsg, sizeof (errmsg),
- "Unable to fetch conf file path.");
- gf_log ("", GF_LOG_ERROR, "%s", errmsg);
- goto out;
- }
-
- ret = dict_get_str (dict, "statefile", &statefile);
- if (ret) {
- snprintf (errmsg, sizeof (errmsg),
- "Unable to fetch statefile path.");
- gf_log ("", GF_LOG_ERROR, "%s", errmsg);
- goto out;
- }
-
- ret = snprintf (buf, sizeof(buf) - 1, "%s/"GEOREP"/%s_%s_%s",
- conf->workdir, volinfo->volname, slave_host, slave_vol);
- buf[ret] = '\0';
- ret = mkdir_p (buf, 0777, _gf_true);
- if (ret) {
- snprintf (errmsg, sizeof (errmsg), "Unable to create %s"
- ". Error : %s", buf, strerror (errno));
- *op_errstr = gf_strdup (errmsg);
- gf_log ("", GF_LOG_ERROR, "%s", errmsg);
- goto out;
- }
-
- ret = snprintf (buf, PATH_MAX, DEFAULT_LOG_FILE_DIRECTORY"/"GEOREP"/%s",
- volinfo->volname);
- buf[ret] = '\0';
- ret = mkdir_p (buf, 0777, _gf_true);
- if (ret) {
- snprintf (errmsg, sizeof (errmsg), "Unable to create %s"
- ". Error : %s", buf, strerror (errno));
- *op_errstr = gf_strdup (errmsg);
- gf_log ("", GF_LOG_ERROR, "%s", errmsg);
- goto out;
- }
-
- ret = lstat (conf_path, &stbuf);
- if (!ret) {
- gf_log ("", GF_LOG_DEBUG, "Session already running."
- " Not creating config file again.");
- } else {
- ret = create_conf_file (conf, conf_path);
- if (ret || lstat (conf_path, &stbuf)) {
- snprintf (errmsg, sizeof (errmsg), "Failed to create"
- " config file(%s).", conf_path);
- gf_log ("", GF_LOG_ERROR, "%s", errmsg);
- goto out;
- }
- }
-
- ret = lstat (statefile, &stbuf);
- if (!ret) {
- gf_log ("", GF_LOG_DEBUG, "Session already running."
- " Not creating status file again.");
- goto out;
- } else {
- ret = glusterd_create_status_file (volinfo->volname, slave,
- slave_host, slave_vol,
- "Not Started");
- if (ret || lstat (statefile, &stbuf)) {
- snprintf (errmsg, sizeof (errmsg), "Unable to create %s"
- ". Error : %s", statefile, strerror (errno));
- *op_errstr = gf_strdup (errmsg);
- gf_log ("", GF_LOG_ERROR, "%s", errmsg);
- ret = -1;
- goto out;
- }
- }
-
-out:
- gf_log ("", GF_LOG_DEBUG,"Returning %d", ret);
- return ret;
-}
-
-int
-glusterd_op_gsync_create (dict_t *dict, char **op_errstr, dict_t *rsp_dict)
-{
- char common_pem_file[PATH_MAX] = "";
- char errmsg[PATH_MAX] = "";
- char hooks_args[PATH_MAX] = "";
- char uuid_str [64] = "";
- char *host_uuid = NULL;
- char *slave_url = NULL;
- char *slave_url_buf = NULL;
- char *slave_user = NULL;
- char *slave_ip = NULL;
- char *save_ptr = NULL;
- char *slave_host = NULL;
- char *slave_vol = NULL;
- char *arg_buf = NULL;
- char *volname = NULL;
- char *slave = NULL;
- int32_t ret = -1;
- int32_t is_pem_push = -1;
- gf_boolean_t is_force = -1;
- glusterd_conf_t *conf = NULL;
- glusterd_volinfo_t *volinfo = NULL;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- conf = this->private;
- GF_ASSERT (conf);
- GF_ASSERT (dict);
- GF_ASSERT (op_errstr);
-
- ret = glusterd_op_gsync_args_get (dict, op_errstr,
- &volname, &slave, &host_uuid);
- if (ret)
- goto out;
-
- snprintf (common_pem_file, sizeof(common_pem_file),
- "%s"GLUSTERD_COMMON_PEM_PUB_FILE, conf->workdir);
-
- ret = glusterd_volinfo_find (volname, &volinfo);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Volinfo for %s"
- " (master) not found", volname);
- goto out;
- }
-
- ret = dict_get_str (dict, "slave_vol", &slave_vol);
- if (ret) {
- snprintf (errmsg, sizeof (errmsg),
- "Unable to fetch slave volume name.");
- gf_log ("", GF_LOG_ERROR, "%s", errmsg);
- goto out;
- }
-
- ret = dict_get_str (dict, "slave_url", &slave_url);
- if (ret) {
- snprintf (errmsg, sizeof (errmsg),
- "Unable to fetch slave IP.");
- gf_log ("", GF_LOG_ERROR, "%s", errmsg);
- ret = -1;
- goto out;
- }
-
- /* Fetch the slave_user and slave_ip from the slave_url.
- * If the slave_user is not present. Use "root"
- */
- if (strstr(slave_url, "@")) {
- slave_url_buf = gf_strdup (slave_url);
- if (!slave_url_buf) {
- ret = -1;
- goto out;
- }
- slave_user = strtok_r (slave_url, "@", &save_ptr);
- slave_ip = strtok_r (NULL, "@", &save_ptr);
- } else {
- slave_user = "root";
- slave_ip = slave_url;
- }
-
- if (!slave_user || !slave_ip) {
- gf_log (this->name, GF_LOG_ERROR, "Invalid slave url.");
- ret = -1;
- goto out;
- }
-
- ret = dict_get_str (dict, "slave_host", &slave_host);
- if (ret) {
- snprintf (errmsg, sizeof (errmsg),
- "Unable to fetch slave host");
- gf_log ("", GF_LOG_ERROR, "%s", errmsg);
- ret = -1;
- goto out;
- }
-
- is_force = dict_get_str_boolean (dict, "force", _gf_false);
-
- uuid_utoa_r (MY_UUID, uuid_str);
- if (!strcmp (uuid_str, host_uuid)) {
- ret = dict_get_int32 (dict, "push_pem", &is_pem_push);
- if (!ret && is_pem_push) {
- gf_log ("", GF_LOG_DEBUG, "Trying to setup"
- " pem files in slave");
- is_pem_push = 1;
- } else
- is_pem_push = 0;
-
- snprintf(hooks_args, sizeof(hooks_args),
- "is_push_pem=%d,pub_file=%s,slave_user=%s,slave_ip=%s",
- is_pem_push, common_pem_file, slave_user, slave_ip);
-
- } else
- snprintf(hooks_args, sizeof(hooks_args),
- "This argument will stop the hooks script");
-
- arg_buf = gf_strdup (hooks_args);
- if (!arg_buf) {
- gf_log ("", GF_LOG_ERROR, "Failed to"
- " gf_strdup");
- if (is_force) {
- ret = 0;
- goto create_essentials;
- }
- ret = -1;
- goto out;
- }
-
- ret = dict_set_str (dict, "hooks_args", arg_buf);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Failed to set"
- " hooks_args in dict.");
- if (is_force) {
- ret = 0;
- goto create_essentials;
- }
- goto out;
- }
-
-create_essentials:
-
- ret = glusterd_create_essential_dir_files (volinfo, dict, slave,
- slave_host, slave_vol,
- op_errstr);
- if (ret)
- goto out;
-
- ret = glusterd_store_slave_in_info (volinfo, slave,
- host_uuid, op_errstr,
- is_force);
- if (ret) {
- snprintf (errmsg, sizeof (errmsg), "Unable to store"
- " slave info.");
- gf_log ("", GF_LOG_ERROR, "%s", errmsg);
- goto out;
- }
-
- /* Enable marker and changelog */
- ret = glusterd_set_gsync_confs (volinfo);
- if (ret != 0) {
- gf_log (this->name, GF_LOG_WARNING, "marker/changelog"
- " start failed");
- *op_errstr = gf_strdup ("Index initialization failed");
- ret = -1;
- goto out;
- }
-
-out:
- GF_FREE (slave_url_buf);
- 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
deleted file mode 100644
index 67f6e9eaf04..00000000000
--- a/xlators/mgmt/glusterd/src/glusterd-handler.c
+++ /dev/null
@@ -1,4578 +0,0 @@
-/*
- Copyright (c) 2006-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 <inttypes.h>
-
-
-#include "globals.h"
-#include "glusterfs.h"
-#include "compat.h"
-#include "dict.h"
-#include "protocol-common.h"
-#include "xlator.h"
-#include "logging.h"
-#include "timer.h"
-#include "defaults.h"
-#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"
-#include "glusterd-op-sm.h"
-#include "glusterd-utils.h"
-#include "glusterd-store.h"
-#include "glusterd-locks.h"
-
-#include "glusterd1-xdr.h"
-#include "cli1-xdr.h"
-#include "xdr-generic.h"
-#include "rpc-clnt.h"
-#include "glusterd-volgen.h"
-#include "glusterd-mountbroker.h"
-#include "glusterd-messages.h"
-
-#include <sys/resource.h>
-#include <inttypes.h>
-
-#include "defaults.c"
-#include "common-utils.h"
-
-#include "globals.h"
-#include "glusterd-syncop.h"
-#include "glusterd-messages.h"
-
-#ifdef HAVE_BD_XLATOR
-#include <lvm2app.h>
-#endif
-
-extern glusterd_op_info_t opinfo;
-
-int glusterd_big_locked_notify (struct rpc_clnt *rpc, void *mydata,
- rpc_clnt_event_t event,
- void *data, rpc_clnt_notify_t notify_fn)
-{
- glusterd_conf_t *priv = THIS->private;
- int ret = -1;
- synclock_lock (&priv->big_lock);
- ret = notify_fn (rpc, mydata, event, data);
- synclock_unlock (&priv->big_lock);
- return ret;
-}
-
-int glusterd_big_locked_handler (rpcsvc_request_t *req, rpcsvc_actor actor_fn)
-{
- glusterd_conf_t *priv = THIS->private;
- int ret = -1;
-
- synclock_lock (&priv->big_lock);
- ret = actor_fn (req);
- synclock_unlock (&priv->big_lock);
-
- return ret;
-}
-
-static int
-glusterd_handle_friend_req (rpcsvc_request_t *req, uuid_t uuid,
- char *hostname, int port,
- gd1_mgmt_friend_req *friend_req)
-{
- int ret = -1;
- glusterd_peerinfo_t *peerinfo = NULL;
- glusterd_friend_sm_event_t *event = NULL;
- glusterd_friend_req_ctx_t *ctx = NULL;
- char rhost[UNIX_PATH_MAX + 1] = {0};
- uuid_t friend_uuid = {0};
- dict_t *dict = NULL;
-
- uuid_parse (uuid_utoa (uuid), friend_uuid);
- if (!port)
- port = GF_DEFAULT_BASE_PORT;
-
- ret = glusterd_remote_hostname_get (req, rhost, sizeof (rhost));
- peerinfo = glusterd_peerinfo_find (uuid, rhost);
-
- if (peerinfo == NULL) {
- ret = glusterd_xfer_friend_add_resp (req, hostname, rhost, port,
- -1, GF_PROBE_UNKNOWN_PEER);
- if (friend_req->vols.vols_val) {
- free (friend_req->vols.vols_val);
- friend_req->vols.vols_val = NULL;
- }
- goto out;
- }
-
- ret = glusterd_friend_sm_new_event
- (GD_FRIEND_EVENT_RCVD_FRIEND_REQ, &event);
-
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "event generation failed: %d", ret);
- return ret;
- }
-
- event->peerinfo = peerinfo;
-
- ctx = GF_CALLOC (1, sizeof (*ctx), gf_gld_mt_friend_req_ctx_t);
-
- if (!ctx) {
- gf_log ("", GF_LOG_ERROR, "Unable to allocate memory");
- ret = -1;
- goto out;
- }
-
- uuid_copy (ctx->uuid, uuid);
- if (hostname)
- ctx->hostname = gf_strdup (hostname);
- ctx->req = req;
-
- dict = dict_new ();
- if (!dict) {
- ret = -1;
- goto out;
- }
-
- ret = dict_unserialize (friend_req->vols.vols_val,
- friend_req->vols.vols_len,
- &dict);
-
- if (ret)
- goto out;
- else
- dict->extra_stdfree = friend_req->vols.vols_val;
-
- ctx->vols = dict;
- event->ctx = ctx;
-
- ret = glusterd_friend_sm_inject_event (event);
- if (ret) {
- gf_log ("glusterd", GF_LOG_ERROR, "Unable to inject event %d, "
- "ret = %d", event->event, ret);
- goto out;
- }
-
- ret = 0;
-
-out:
- if (0 != ret) {
- if (ctx && ctx->hostname)
- GF_FREE (ctx->hostname);
- 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);
- }
- GF_FREE (event);
- } else {
- if (peerinfo && (0 == peerinfo->connected))
- ret = GLUSTERD_CONNECTION_AWAITED;
- }
- return ret;
-}
-
-static int
-glusterd_handle_unfriend_req (rpcsvc_request_t *req, uuid_t uuid,
- char *hostname, int port)
-{
- int ret = -1;
- glusterd_peerinfo_t *peerinfo = NULL;
- glusterd_friend_sm_event_t *event = NULL;
- glusterd_friend_req_ctx_t *ctx = NULL;
-
- if (!port)
- port = GF_DEFAULT_BASE_PORT;
-
- peerinfo = glusterd_peerinfo_find (uuid, hostname);
-
- if (peerinfo == NULL) {
- gf_log ("glusterd", GF_LOG_CRITICAL,
- "Received remove-friend from unknown peer %s",
- hostname);
- ret = glusterd_xfer_friend_remove_resp (req, hostname,
- port);
- goto out;
- }
-
- ret = glusterd_friend_sm_new_event
- (GD_FRIEND_EVENT_RCVD_REMOVE_FRIEND, &event);
-
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "event generation failed: %d", ret);
- return ret;
- }
-
- event->peerinfo = peerinfo;
-
- ctx = GF_CALLOC (1, sizeof (*ctx), gf_gld_mt_friend_req_ctx_t);
-
- if (!ctx) {
- gf_log ("", GF_LOG_ERROR, "Unable to allocate memory");
- ret = -1;
- goto out;
- }
-
- uuid_copy (ctx->uuid, uuid);
- if (hostname)
- ctx->hostname = gf_strdup (hostname);
- ctx->req = req;
-
- event->ctx = ctx;
-
- ret = glusterd_friend_sm_inject_event (event);
-
- if (ret) {
- gf_log ("glusterd", GF_LOG_ERROR, "Unable to inject event %d, "
- "ret = %d", event->event, ret);
- goto out;
- }
-
- ret = 0;
-
-out:
- if (0 != ret) {
- if (ctx && ctx->hostname)
- GF_FREE (ctx->hostname);
- GF_FREE (ctx);
- }
-
- return ret;
-}
-
-struct args_pack {
- dict_t *dict;
- int vol_count;
- int opt_count;
-};
-
-static int
-_build_option_key (dict_t *d, char *k, data_t *v, void *tmp)
-{
- char reconfig_key[256] = {0, };
- struct args_pack *pack = NULL;
- int ret = -1;
- xlator_t *this = NULL;
- glusterd_conf_t *priv = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- priv = this->private;
- GF_ASSERT (priv);
-
- pack = tmp;
- if (strcmp (k, GLUSTERD_GLOBAL_OPT_VERSION) == 0)
- return 0;
-
- if (priv->op_version > GD_OP_VERSION_MIN) {
- if ((strcmp (k, "features.limit-usage") == 0) ||
- (strcmp (k, "features.soft-limit") == 0))
- return 0;
- }
- snprintf (reconfig_key, 256, "volume%d.option.%s",
- pack->vol_count, k);
- ret = dict_set_str (pack->dict, reconfig_key, v->data);
- if (0 == ret)
- pack->opt_count++;
-
- return 0;
-}
-
-int
-glusterd_add_volume_detail_to_dict (glusterd_volinfo_t *volinfo,
- dict_t *volumes, int count)
-{
-
- int ret = -1;
- char key[256] = {0, };
- glusterd_brickinfo_t *brickinfo = NULL;
- char *buf = NULL;
- int i = 1;
- dict_t *dict = NULL;
- glusterd_conf_t *priv = NULL;
- char *volume_id_str = NULL;
- struct args_pack pack = {0,};
- xlator_t *this = NULL;
- GF_UNUSED int caps = 0;
-
- GF_ASSERT (volinfo);
- GF_ASSERT (volumes);
-
- this = THIS;
- priv = this->private;
-
- GF_ASSERT (priv);
-
- snprintf (key, 256, "volume%d.name", count);
- ret = dict_set_str (volumes, key, volinfo->volname);
- if (ret)
- goto out;
-
- snprintf (key, 256, "volume%d.type", count);
- ret = dict_set_int32 (volumes, key, volinfo->type);
- if (ret)
- goto out;
-
- snprintf (key, 256, "volume%d.status", count);
- ret = dict_set_int32 (volumes, key, volinfo->status);
- if (ret)
- goto out;
-
- snprintf (key, 256, "volume%d.brick_count", count);
- ret = dict_set_int32 (volumes, key, volinfo->brick_count);
- 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);
- if (ret)
- goto out;
-
- snprintf (key, 256, "volume%d.disperse_count", count);
- ret = dict_set_int32 (volumes, key, volinfo->disperse_count);
- if (ret)
- goto out;
-
- snprintf (key, 256, "volume%d.redundancy_count", count);
- ret = dict_set_int32 (volumes, key, volinfo->redundancy_count);
- if (ret)
- goto out;
-
- snprintf (key, 256, "volume%d.transport", count);
- ret = dict_set_int32 (volumes, key, volinfo->transport_type);
- 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->rebal.defrag_cmd);
- if (ret)
- goto out;
-
-#ifdef HAVE_BD_XLATOR
- if (volinfo->caps) {
- caps = 0;
- snprintf (key, 256, "volume%d.xlator0", count);
- buf = GF_MALLOC (256, gf_common_mt_char);
- if (!buf) {
- ret = ENOMEM;
- goto out;
- }
- if (volinfo->caps & CAPS_BD)
- snprintf (buf, 256, "BD");
- ret = dict_set_dynstr (volumes, key, buf);
- if (ret) {
- GF_FREE (buf);
- goto out;
- }
-
- if (volinfo->caps & CAPS_THIN) {
- snprintf (key, 256, "volume%d.xlator0.caps%d", count,
- caps++);
- buf = GF_MALLOC (256, gf_common_mt_char);
- if (!buf) {
- ret = ENOMEM;
- goto out;
- }
- snprintf (buf, 256, "thin");
- ret = dict_set_dynstr (volumes, key, buf);
- if (ret) {
- GF_FREE (buf);
- goto out;
- }
- }
-
- if (volinfo->caps & CAPS_OFFLOAD_COPY) {
- snprintf (key, 256, "volume%d.xlator0.caps%d", count,
- caps++);
- buf = GF_MALLOC (256, gf_common_mt_char);
- if (!buf) {
- ret = ENOMEM;
- goto out;
- }
- snprintf (buf, 256, "offload_copy");
- ret = dict_set_dynstr (volumes, key, buf);
- if (ret) {
- GF_FREE (buf);
- goto out;
- }
- }
-
- if (volinfo->caps & CAPS_OFFLOAD_SNAPSHOT) {
- snprintf (key, 256, "volume%d.xlator0.caps%d", count,
- caps++);
- buf = GF_MALLOC (256, gf_common_mt_char);
- if (!buf) {
- ret = ENOMEM;
- goto out;
- }
- snprintf (buf, 256, "offload_snapshot");
- ret = dict_set_dynstr (volumes, key, buf);
- if (ret) {
- GF_FREE (buf);
- goto out;
- }
- }
-
- if (volinfo->caps & CAPS_OFFLOAD_ZERO) {
- snprintf (key, 256, "volume%d.xlator0.caps%d", count,
- caps++);
- buf = GF_MALLOC (256, gf_common_mt_char);
- if (!buf) {
- ret = ENOMEM;
- goto out;
- }
- snprintf (buf, 256, "offload_zerofill");
- ret = dict_set_dynstr (volumes, key, buf);
- if (ret) {
- GF_FREE (buf);
- goto out;
- }
- }
-
- }
-#endif
-
- list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) {
- char brick[1024] = {0,};
- char brick_uuid[64] = {0,};
- snprintf (key, 256, "volume%d.brick%d", count, i);
- snprintf (brick, 1024, "%s:%s", brickinfo->hostname,
- brickinfo->path);
- buf = gf_strdup (brick);
- ret = dict_set_dynstr (volumes, key, buf);
- if (ret)
- goto out;
- snprintf (key, 256, "volume%d.brick%d.uuid", count, i);
- snprintf (brick_uuid, 64, "%s", uuid_utoa (brickinfo->uuid));
- buf = gf_strdup (brick_uuid);
- if (!buf)
- goto out;
- ret = dict_set_dynstr (volumes, key, buf);
- if (ret)
- goto out;
-
-#ifdef HAVE_BD_XLATOR
- if (volinfo->caps & CAPS_BD) {
- snprintf (key, 256, "volume%d.vg%d", count, i);
- snprintf (brick, 1024, "%s", brickinfo->vg);
- buf = gf_strdup (brick);
- ret = dict_set_dynstr (volumes, key, buf);
- if (ret)
- goto out;
- }
-#endif
- i++;
- }
-
- dict = volinfo->dict;
- if (!dict) {
- ret = 0;
- goto out;
- }
-
- pack.dict = volumes;
- pack.vol_count = count;
- pack.opt_count = 0;
- dict_foreach (dict, _build_option_key, (void *) &pack);
- dict_foreach (priv->opts, _build_option_key, &pack);
-
- snprintf (key, 256, "volume%d.opt_count", pack.vol_count);
- ret = dict_set_int32 (volumes, key, pack.opt_count);
-out:
- return ret;
-}
-
-int32_t
-glusterd_op_txn_begin (rpcsvc_request_t *req, glusterd_op_t op, void *ctx,
- char *err_str, size_t err_len)
-{
- int32_t ret = -1;
- int npeers = 0;
- dict_t *dict = NULL;
- xlator_t *this = NULL;
- glusterd_conf_t *priv = NULL;
- int32_t locked = 0;
- char *tmp = NULL;
- char *volname = NULL;
- uuid_t *txn_id = NULL;
- glusterd_op_info_t txn_op_info = {{0},};
- glusterd_op_sm_event_type_t event_type = GD_OP_EVENT_NONE;
-
- GF_ASSERT (req);
- GF_ASSERT ((op > GD_OP_NONE) && (op < GD_OP_MAX));
- GF_ASSERT (NULL != ctx);
-
- this = THIS;
- GF_ASSERT (this);
- priv = this->private;
- GF_ASSERT (priv);
-
- dict = ctx;
-
- /* Generate a transaction-id for this operation and
- * save it in the dict. This transaction id distinguishes
- * each transaction, and helps separate opinfos in the
- * op state machine. */
- ret = glusterd_generate_txn_id (dict, &txn_id);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to generate transaction id");
- goto out;
- }
-
- /* Save the MY_UUID as the originator_uuid. This originator_uuid
- * will be used by is_origin_glusterd() to determine if a node
- * is the originator node for a command. */
- ret = glusterd_set_originator_uuid (dict);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to set originator_uuid.");
- goto out;
- }
-
- /* Based on the op_version, acquire a cluster or mgmt_v3 lock */
- if (priv->op_version < GD_OP_VERSION_3_6_0) {
- ret = glusterd_lock (MY_UUID);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Unable to acquire lock on localhost, ret: %d",
- ret);
- snprintf (err_str, err_len,
- "Another transaction is in progress. "
- "Please try again after sometime.");
- goto out;
- }
- } else {
- /* If no volname is given as a part of the command, locks will
- * not be held */
- ret = dict_get_str (dict, "volname", &tmp);
- if (ret) {
- gf_log ("", GF_LOG_INFO,
- "No Volume name present. "
- "Locks not being held.");
- goto local_locking_done;
- } else {
- /* Use a copy of volname, as cli response will be
- * sent before the unlock, and the volname in the
- * dict, might be removed */
- volname = gf_strdup (tmp);
- if (!volname)
- goto out;
- }
-
- ret = glusterd_mgmt_v3_lock (volname, MY_UUID, "vol");
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Unable to acquire lock for %s", volname);
- snprintf (err_str, err_len,
- "Another transaction is in progress for %s. "
- "Please try again after sometime.", volname);
- goto out;
- }
- }
-
- locked = 1;
- gf_log (this->name, GF_LOG_DEBUG, "Acquired lock on localhost");
-
-local_locking_done:
- txn_op_info.local_xaction_peers =
- GF_CALLOC (1, sizeof (struct list_head),
- gf_common_mt_list_head_t);
- if (!txn_op_info.local_xaction_peers) {
- ret = -1;
- gf_log (this->name, GF_LOG_ERROR, "Out of memory");
- goto out;
- }
- INIT_LIST_HEAD (txn_op_info.local_xaction_peers);
-
- /* Maintain xaction_peers on per transaction basis */
- npeers = gd_build_local_xaction_peers_list
- (&priv->peers,
- txn_op_info.local_xaction_peers,
- op);
-
- /* If no volname is given as a part of the command, locks will
- * not be held, hence sending stage event. */
- if (volname || (priv->op_version < GD_OP_VERSION_3_6_0))
- event_type = GD_OP_EVENT_START_LOCK;
- else {
- txn_op_info.state.state = GD_OP_STATE_LOCK_SENT;
- event_type = GD_OP_EVENT_ALL_ACC;
- }
-
- /* Save opinfo for this transaction with the transaction id */
- glusterd_txn_opinfo_init (&txn_op_info, NULL, &op, ctx, req);
-
- ret = glusterd_set_txn_opinfo (txn_id, &txn_op_info);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Unable to set transaction's opinfo");
- if (ctx)
- dict_unref (ctx);
- goto out;
- }
-
- ret = glusterd_op_sm_inject_event (event_type, txn_id, ctx);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to acquire cluster"
- " lock.");
- goto out;
- }
-
-out:
- if (locked && ret) {
- /* Based on the op-version, we release the
- * cluster or mgmt_v3 lock */
- if (priv->op_version < GD_OP_VERSION_3_6_0)
- glusterd_unlock (MY_UUID);
- else {
- ret = glusterd_mgmt_v3_unlock (volname, MY_UUID,
- "vol");
- if (ret)
- gf_log (this->name, GF_LOG_ERROR,
- "Unable to release lock for %s",
- volname);
- ret = -1;
- }
- }
-
- if (volname)
- GF_FREE (volname);
-
- gf_log (this->name, GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-
-int
-__glusterd_handle_cluster_lock (rpcsvc_request_t *req)
-{
- dict_t *op_ctx = NULL;
- int32_t ret = -1;
- gd1_mgmt_cluster_lock_req lock_req = {{0},};
- glusterd_op_lock_ctx_t *ctx = NULL;
- glusterd_op_t op = GD_OP_EVENT_LOCK;
- glusterd_op_info_t txn_op_info = {{0},};
- glusterd_conf_t *priv = NULL;
- uuid_t *txn_id = NULL;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- priv = this->private;
- GF_ASSERT (priv);
- GF_ASSERT (req);
-
- txn_id = &priv->global_txn_id;
-
- ret = xdr_to_generic (req->msg[0], &lock_req,
- (xdrproc_t)xdr_gd1_mgmt_cluster_lock_req);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to decode lock "
- "request received from peer");
- req->rpc_err = GARBAGE_ARGS;
- goto out;
- }
-
- gf_log (this->name, GF_LOG_DEBUG, "Received LOCK from uuid: %s",
- uuid_utoa (lock_req.uuid));
-
- if (glusterd_peerinfo_find_by_uuid (lock_req.uuid) == NULL) {
- 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);
-
- if (!ctx) {
- //respond here
- return -1;
- }
-
- uuid_copy (ctx->uuid, lock_req.uuid);
- ctx->req = req;
- ctx->dict = NULL;
-
- op_ctx = dict_new ();
- if (!op_ctx) {
- gf_log (this->name, GF_LOG_ERROR,
- "Unable to set new dict");
- goto out;
- }
-
- glusterd_txn_opinfo_init (&txn_op_info, NULL, &op, op_ctx, req);
-
- ret = glusterd_set_txn_opinfo (txn_id, &txn_op_info);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Unable to set transaction's opinfo");
- dict_unref (txn_op_info.op_ctx);
- goto out;
- }
-
- ret = glusterd_op_sm_inject_event (GD_OP_EVENT_LOCK, txn_id, ctx);
- if (ret)
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to inject event GD_OP_EVENT_LOCK");
-
-out:
- gf_log (this->name, GF_LOG_DEBUG, "Returning %d", ret);
-
- glusterd_friend_sm ();
- glusterd_op_sm ();
-
- return ret;
-}
-
-int
-glusterd_handle_cluster_lock (rpcsvc_request_t *req)
-{
- return glusterd_big_locked_handler (req,
- __glusterd_handle_cluster_lock);
-}
-
-int
-glusterd_req_ctx_create (rpcsvc_request_t *rpc_req,
- glusterd_op_t op, uuid_t uuid,
- char *buf_val, size_t buf_len,
- 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;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
-
- uuid_unparse (uuid, str);
- gf_log (this->name, GF_LOG_DEBUG, "Received op from uuid %s", str);
-
- 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 (this->name, GF_LOG_WARNING,
- "failed to unserialize the dictionary");
- goto out;
- }
-
- req_ctx->dict = dict;
- req_ctx->req = rpc_req;
- *req_ctx_out = req_ctx;
- ret = 0;
-out:
- if (ret) {
- if (dict)
- dict_unref (dict);
- GF_FREE (req_ctx);
- }
- return ret;
-}
-
-int
-__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},};
- xlator_t *this = NULL;
- uuid_t *txn_id = NULL;
- glusterd_op_info_t txn_op_info = {{0},};
- glusterd_op_sm_state_info_t state = {0,};
- glusterd_conf_t *priv = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- priv = this->private;
- GF_ASSERT (priv);
- GF_ASSERT (req);
-
- txn_id = &priv->global_txn_id;
-
- ret = xdr_to_generic (req->msg[0], &op_req,
- (xdrproc_t)xdr_gd1_mgmt_stage_op_req);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to decode stage "
- "request received from peer");
- req->rpc_err = GARBAGE_ARGS;
- 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);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to create req_ctx");
- goto out;
- }
-
- ret = dict_get_bin (req_ctx->dict, "transaction_id", (void **)&txn_id);
- gf_log (this->name, GF_LOG_DEBUG, "transaction ID = %s",
- uuid_utoa (*txn_id));
-
- if (glusterd_peerinfo_find_by_uuid (op_req.uuid) == NULL) {
- 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;
- }
-
- /* In cases where there is no volname, the receivers won't have a
- * transaction opinfo created, as for those operations, the locking
- * phase where the transaction opinfos are created, won't be called. */
- ret = glusterd_get_txn_opinfo (txn_id, &txn_op_info);
- if (ret) {
- gf_log (this->name, GF_LOG_DEBUG,
- "No transaction's opinfo set");
-
- state.state = GD_OP_STATE_LOCKED;
- glusterd_txn_opinfo_init (&txn_op_info, &state,
- &op_req.op, req_ctx->dict, req);
-
- ret = glusterd_set_txn_opinfo (txn_id, &txn_op_info);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Unable to set transaction's opinfo");
- dict_unref (req_ctx->dict);
- goto out;
- }
- }
-
- ret = glusterd_op_sm_inject_event (GD_OP_EVENT_STAGE_OP,
- txn_id, req_ctx);
- if (ret)
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to inject event GD_OP_EVENT_STAGE_OP");
-
- out:
- free (op_req.buf.buf_val);//malloced by xdr
- glusterd_friend_sm ();
- glusterd_op_sm ();
- return ret;
-}
-
-int
-glusterd_handle_stage_op (rpcsvc_request_t *req)
-{
- return glusterd_big_locked_handler (req, __glusterd_handle_stage_op);
-}
-
-
-int
-__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},};
- xlator_t *this = NULL;
- uuid_t *txn_id = NULL;
- glusterd_conf_t *priv = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- priv = this->private;
- GF_ASSERT (priv);
- GF_ASSERT (req);
-
- txn_id = &priv->global_txn_id;
-
- ret = xdr_to_generic (req->msg[0], &op_req,
- (xdrproc_t)xdr_gd1_mgmt_commit_op_req);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to decode commit "
- "request received from peer");
- req->rpc_err = GARBAGE_ARGS;
- goto out;
- }
-
- if (glusterd_peerinfo_find_by_uuid (op_req.uuid) == NULL) {
- 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,
- op_req.buf.buf_val, op_req.buf.buf_len,
- gf_gld_mt_op_commit_ctx_t, &req_ctx);
- if (ret)
- goto out;
-
- ret = dict_get_bin (req_ctx->dict, "transaction_id", (void **)&txn_id);
- gf_log (this->name, GF_LOG_DEBUG, "transaction ID = %s",
- uuid_utoa (*txn_id));
-
- ret = glusterd_op_sm_inject_event (GD_OP_EVENT_COMMIT_OP,
- txn_id, req_ctx);
-
-out:
- free (op_req.buf.buf_val);//malloced by xdr
- glusterd_friend_sm ();
- glusterd_op_sm ();
- return ret;
-}
-
-int
-glusterd_handle_commit_op (rpcsvc_request_t *req)
-{
- return glusterd_big_locked_handler (req, __glusterd_handle_commit_op);
-}
-
-int
-__glusterd_handle_cli_probe (rpcsvc_request_t *req)
-{
- int32_t ret = -1;
- gf_cli_req cli_req = {{0,},};
- glusterd_peerinfo_t *peerinfo = NULL;
- gf_boolean_t run_fsm = _gf_true;
- xlator_t *this = NULL;
- char *bind_name = NULL;
- dict_t *dict = NULL;
- char *hostname = NULL;
- int port = 0;
- int op_errno = 0;
-
- GF_ASSERT (req);
- this = THIS;
-
- ret = xdr_to_generic (req->msg[0], &cli_req, (xdrproc_t)xdr_gf_cli_req);
- if (ret < 0) {
- //failed to decode msg;
- gf_log ("", GF_LOG_ERROR, "xdr decoding error");
- 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;
- }
- }
-
- ret = dict_get_str (dict, "hostname", &hostname);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to get hostname");
- goto out;
- }
-
- ret = dict_get_int32 (dict, "port", &port);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to get port");
- goto out;
- }
-
- if (glusterd_is_any_volume_in_server_quorum (this) &&
- !does_gd_meet_server_quorum (this, NULL, _gf_false)) {
- glusterd_xfer_cli_probe_resp (req, -1, GF_PROBE_QUORUM_NOT_MET,
- NULL, hostname, port, dict);
- gf_msg (this->name, GF_LOG_CRITICAL, 0,
- GD_MSG_SERVER_QUORUM_NOT_MET,
- "Server quorum not met. Rejecting operation.");
- ret = 0;
- goto out;
- }
-
- gf_log ("glusterd", GF_LOG_INFO, "Received CLI probe req %s %d",
- hostname, port);
-
- if (dict_get_str(this->options,"transport.socket.bind-address",
- &bind_name) == 0) {
- gf_log ("glusterd", GF_LOG_DEBUG,
- "only checking probe address vs. bind address");
- ret = gf_is_same_address (bind_name, hostname);
- }
- else {
- ret = gf_is_local_addr (hostname);
- }
- if (ret) {
- glusterd_xfer_cli_probe_resp (req, 0, GF_PROBE_LOCALHOST,
- NULL, hostname, port, dict);
- ret = 0;
- goto out;
- }
-
- peerinfo = glusterd_peerinfo_find_by_hostname (hostname);
- if (peerinfo && gd_peer_has_address (peerinfo, hostname)) {
- gf_log ("glusterd", GF_LOG_DEBUG, "Probe host %s port %d "
- "already a peer", hostname, port);
- glusterd_xfer_cli_probe_resp (req, 0, GF_PROBE_FRIEND, NULL,
- hostname, port, dict);
- goto out;
- }
- ret = glusterd_probe_begin (req, hostname, port, dict, &op_errno);
-
- if (ret == GLUSTERD_CONNECTION_AWAITED) {
- //fsm should be run after connection establishes
- run_fsm = _gf_false;
- ret = 0;
-
- } else if (ret == -1) {
- glusterd_xfer_cli_probe_resp (req, -1, op_errno,
- NULL, hostname, port, dict);
- goto out;
- }
-
-out:
- free (cli_req.dict.dict_val);
-
- if (run_fsm) {
- glusterd_friend_sm ();
- glusterd_op_sm ();
- }
-
- return ret;
-}
-
-int
-glusterd_handle_cli_probe (rpcsvc_request_t *req)
-{
- return glusterd_big_locked_handler (req, __glusterd_handle_cli_probe);
-}
-
-int
-__glusterd_handle_cli_deprobe (rpcsvc_request_t *req)
-{
- int32_t ret = -1;
- gf_cli_req cli_req = {{0,},};
- uuid_t uuid = {0};
- int op_errno = 0;
- xlator_t *this = NULL;
- glusterd_conf_t *priv = NULL;
- dict_t *dict = NULL;
- char *hostname = NULL;
- int port = 0;
- int flags = 0;
- glusterd_volinfo_t *volinfo = NULL;
- glusterd_volinfo_t *tmp = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- priv = this->private;
- GF_ASSERT (priv);
- GF_ASSERT (req);
-
- ret = xdr_to_generic (req->msg[0], &cli_req,
- (xdrproc_t)xdr_gf_cli_req);
- if (ret < 0) {
- //failed to decode msg;
- 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;
- }
- }
-
- gf_log ("glusterd", GF_LOG_INFO, "Received CLI deprobe req");
-
- ret = dict_get_str (dict, "hostname", &hostname);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to get hostname");
- goto out;
- }
-
- ret = dict_get_int32 (dict, "port", &port);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to get port");
- goto out;
- }
- ret = dict_get_int32 (dict, "flags", &flags);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to get flags");
- goto out;
- }
-
- ret = glusterd_hostname_to_uuid (hostname, uuid);
- if (ret) {
- op_errno = GF_DEPROBE_NOT_FRIEND;
- goto out;
- }
-
- if (!uuid_compare (uuid, MY_UUID)) {
- op_errno = GF_DEPROBE_LOCALHOST;
- ret = -1;
- goto out;
- }
-
- if (!(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;
- }
- }
-
- /* Check for if volumes exist with some bricks on the peer being
- * detached. It's not a problem if a volume contains none or all
- * of its bricks on the peer being detached
- */
- list_for_each_entry_safe (volinfo, tmp, &priv->volumes,
- vol_list) {
- ret = glusterd_friend_contains_vol_bricks (volinfo,
- uuid);
- if (ret == 1) {
- op_errno = GF_DEPROBE_BRICK_EXIST;
- goto out;
- }
- }
-
- if (!(flags & GF_CLI_FLAG_OP_FORCE)) {
- if (glusterd_is_any_volume_in_server_quorum (this) &&
- !does_gd_meet_server_quorum (this, NULL, _gf_false)) {
- gf_msg (this->name, GF_LOG_CRITICAL, 0,
- GD_MSG_SERVER_QUORUM_NOT_MET,
- "Server quorum not met. Rejecting operation.");
- ret = -1;
- op_errno = GF_DEPROBE_QUORUM_NOT_MET;
- goto out;
- }
- }
-
- if (!uuid_is_null (uuid)) {
- ret = glusterd_deprobe_begin (req, hostname, port, uuid, dict,
- &op_errno);
- } else {
- ret = glusterd_deprobe_begin (req, hostname, port, NULL, dict,
- &op_errno);
- }
-
-out:
- free (cli_req.dict.dict_val);
-
- if (ret) {
- ret = glusterd_xfer_cli_deprobe_resp (req, ret, op_errno, NULL,
- hostname, dict);
- }
-
- glusterd_friend_sm ();
- glusterd_op_sm ();
-
- return ret;
-}
-
-int
-glusterd_handle_cli_deprobe (rpcsvc_request_t *req)
-{
- return glusterd_big_locked_handler (req, __glusterd_handle_cli_deprobe);
-}
-
-int
-__glusterd_handle_cli_list_friends (rpcsvc_request_t *req)
-{
- int32_t ret = -1;
- gf1_cli_peer_list_req cli_req = {0,};
- dict_t *dict = NULL;
-
- GF_ASSERT (req);
-
- ret = xdr_to_generic (req->msg[0], &cli_req,
- (xdrproc_t)xdr_gf1_cli_peer_list_req);
- if (ret < 0) {
- //failed to decode msg;
- req->rpc_err = GARBAGE_ARGS;
- goto out;
- }
-
- gf_log ("glusterd", GF_LOG_INFO, "Received cli list 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;
- } else {
- dict->extra_stdfree = cli_req.dict.dict_val;
- }
- }
-
- ret = glusterd_list_friends (req, dict, cli_req.flags);
-
-out:
- if (dict)
- dict_unref (dict);
-
- glusterd_friend_sm ();
- glusterd_op_sm ();
-
- return ret;
-}
-
-int
-glusterd_handle_cli_list_friends (rpcsvc_request_t *req)
-{
- return glusterd_big_locked_handler (req,
- __glusterd_handle_cli_list_friends);
-}
-
-int
-__glusterd_handle_cli_get_volume (rpcsvc_request_t *req)
-{
- int32_t ret = -1;
- gf_cli_req cli_req = {{0,}};
- dict_t *dict = NULL;
- int32_t flags = 0;
-
- GF_ASSERT (req);
-
- ret = xdr_to_generic (req->msg[0], &cli_req, (xdrproc_t)xdr_gf_cli_req);
- if (ret < 0) {
- //failed to decode msg;
- req->rpc_err = GARBAGE_ARGS;
- goto out;
- }
-
- gf_log ("glusterd", GF_LOG_INFO, "Received get vol 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;
- } else {
- dict->extra_stdfree = cli_req.dict.dict_val;
- }
- }
-
- ret = dict_get_int32 (dict, "flags", &flags);
- if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR, "failed to get flags");
- goto out;
- }
-
- ret = glusterd_get_volumes (req, dict, flags);
-
-out:
- if (dict)
- dict_unref (dict);
-
- glusterd_friend_sm ();
- glusterd_op_sm ();
-
- return ret;
-}
-
-int
-glusterd_handle_cli_get_volume (rpcsvc_request_t *req)
-{
- return glusterd_big_locked_handler (req,
- __glusterd_handle_cli_get_volume);
-}
-
-int
-__glusterd_handle_cli_uuid_reset (rpcsvc_request_t *req)
-{
- int ret = -1;
- dict_t *dict = NULL;
- xlator_t *this = NULL;
- glusterd_conf_t *priv = NULL;
- uuid_t uuid = {0};
- gf_cli_rsp rsp = {0,};
- gf_cli_req cli_req = {{0,}};
- char msg_str[2048] = {0,};
-
- GF_ASSERT (req);
-
- this = THIS;
- priv = this->private;
- GF_ASSERT (priv);
-
- ret = xdr_to_generic (req->msg[0], &cli_req, (xdrproc_t)xdr_gf_cli_req);
- if (ret < 0) {
- //failed to decode msg;
- req->rpc_err = GARBAGE_ARGS;
- goto out;
- }
-
- gf_log ("glusterd", GF_LOG_DEBUG, "Received uuid reset 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 (msg_str, sizeof (msg_str), "Unable to decode "
- "the buffer");
- goto out;
- } else {
- dict->extra_stdfree = cli_req.dict.dict_val;
- }
- }
-
- /* In the above section if dict_unserialize is successful, ret is set
- * to zero.
- */
- ret = -1;
- // Do not allow peer reset if there are any volumes in the cluster
- if (!list_empty (&priv->volumes)) {
- snprintf (msg_str, sizeof (msg_str), "volumes are already "
- "present in the cluster. Resetting uuid is not "
- "allowed");
- gf_log (this->name, GF_LOG_WARNING, "%s", msg_str);
- goto out;
- }
-
- // Do not allow peer reset if trusted storage pool is already formed
- if (!list_empty (&priv->peers)) {
- snprintf (msg_str, sizeof (msg_str),"trusted storage pool "
- "has been already formed. Please detach this peer "
- "from the pool and reset its uuid.");
- gf_log (this->name, GF_LOG_WARNING, "%s", msg_str);
- goto out;
- }
-
- uuid_copy (uuid, priv->uuid);
- ret = glusterd_uuid_generate_save ();
-
- if (!uuid_compare (uuid, MY_UUID)) {
- snprintf (msg_str, sizeof (msg_str), "old uuid and the new uuid"
- " are same. Try gluster peer reset again");
- gf_log (this->name, GF_LOG_ERROR, "%s", msg_str);
- ret = -1;
- goto out;
- }
-
-out:
- if (ret) {
- rsp.op_ret = -1;
- if (msg_str[0] == '\0')
- snprintf (msg_str, sizeof (msg_str), "Operation "
- "failed");
- rsp.op_errstr = msg_str;
- ret = 0;
- } else {
- rsp.op_errstr = "";
- }
-
- glusterd_to_cli (req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gf_cli_rsp, dict);
-
- return ret;
-}
-
-int
-glusterd_handle_cli_uuid_reset (rpcsvc_request_t *req)
-{
- return glusterd_big_locked_handler (req,
- __glusterd_handle_cli_uuid_reset);
-}
-
-int
-__glusterd_handle_cli_uuid_get (rpcsvc_request_t *req)
-{
- int ret = -1;
- dict_t *dict = NULL;
- dict_t *rsp_dict = NULL;
- xlator_t *this = NULL;
- glusterd_conf_t *priv = NULL;
- gf_cli_rsp rsp = {0,};
- gf_cli_req cli_req = {{0,}};
- char msg_str[2048] = {0,};
- char uuid_str[64] = {0,};
-
- GF_ASSERT (req);
-
- this = THIS;
- priv = this->private;
- GF_ASSERT (priv);
-
- ret = xdr_to_generic (req->msg[0], &cli_req, (xdrproc_t)xdr_gf_cli_req);
- if (ret < 0) {
- req->rpc_err = GARBAGE_ARGS;
- goto out;
- }
-
- gf_log ("glusterd", GF_LOG_DEBUG, "Received uuid get req");
-
- if (cli_req.dict.dict_len) {
- dict = dict_new ();
- if (!dict) {
- ret = -1;
- 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");
- snprintf (msg_str, sizeof (msg_str), "Unable to decode "
- "the buffer");
- goto out;
-
- } else {
- dict->extra_stdfree = cli_req.dict.dict_val;
-
- }
- }
-
- rsp_dict = dict_new ();
- if (!rsp_dict) {
- ret = -1;
- goto out;
- }
-
- uuid_utoa_r (MY_UUID, uuid_str);
- ret = dict_set_str (rsp_dict, "uuid", uuid_str);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to set uuid in "
- "dictionary.");
- goto out;
- }
-
- ret = dict_allocate_and_serialize (rsp_dict, &rsp.dict.dict_val,
- &rsp.dict.dict_len);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to serialize "
- "dictionary.");
- goto out;
- }
- ret = 0;
-out:
- if (ret) {
- rsp.op_ret = -1;
- if (msg_str[0] == '\0')
- snprintf (msg_str, sizeof (msg_str), "Operation "
- "failed");
- rsp.op_errstr = msg_str;
-
- } else {
- rsp.op_errstr = "";
-
- }
-
- glusterd_to_cli (req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gf_cli_rsp, dict);
-
- return 0;
-}
-int
-glusterd_handle_cli_uuid_get (rpcsvc_request_t *req)
-{
- return glusterd_big_locked_handler (req,
- __glusterd_handle_cli_uuid_get);
-}
-
-int
-__glusterd_handle_cli_list_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,};
-
- GF_ASSERT (req);
-
- priv = THIS->private;
- GF_ASSERT (priv);
-
- 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++;
- }
-
- ret = dict_set_int32 (dict, "count", count);
- if (ret)
- goto out;
-
- ret = dict_allocate_and_serialize (dict, &rsp.dict.dict_val,
- &rsp.dict.dict_len);
- if (ret)
- goto out;
-
- ret = 0;
-
-out:
- rsp.op_ret = ret;
- if (ret)
- rsp.op_errstr = "Error listing volumes";
- else
- rsp.op_errstr = "";
-
- glusterd_submit_reply (req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gf_cli_rsp);
- ret = 0;
-
- if (dict)
- dict_unref (dict);
-
- glusterd_friend_sm ();
- glusterd_op_sm ();
-
- return ret;
-}
-
-int
-glusterd_handle_cli_list_volume (rpcsvc_request_t *req)
-{
- return glusterd_big_locked_handler (req,
- __glusterd_handle_cli_list_volume);
-}
-
-int32_t
-glusterd_op_begin (rpcsvc_request_t *req, glusterd_op_t op, void *ctx,
- char *err_str, size_t err_len)
-{
- int ret = -1;
-
- ret = glusterd_op_txn_begin (req, op, ctx, err_str, err_len);
-
- return ret;
-}
-
-int
-__glusterd_handle_reset_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_RESET_VOLUME;
- char *volname = NULL;
- char err_str[2048] = {0,};
- xlator_t *this = NULL;
-
- GF_ASSERT (req);
- this = THIS;
- GF_ASSERT (this);
-
- ret = xdr_to_generic (req->msg[0], &cli_req, (xdrproc_t)xdr_gf_cli_req);
- if (ret < 0) {
- snprintf (err_str, sizeof (err_str), "Failed to decode request "
- "received from cli");
- gf_log (this->name, GF_LOG_ERROR, "%s", err_str);
- 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");
- snprintf (err_str, sizeof (err_str), "Unable to decode "
- "the command");
- goto out;
- } else {
- dict->extra_stdfree = cli_req.dict.dict_val;
- }
- }
-
- ret = dict_get_str (dict, "volname", &volname);
- if (ret) {
- snprintf (err_str, sizeof (err_str), "Failed to get volume "
- "name");
- gf_log (this->name, GF_LOG_ERROR, "%s", err_str);
- goto out;
- }
- gf_log (this->name, GF_LOG_DEBUG, "Received volume reset request for "
- "volume %s", volname);
-
- ret = glusterd_op_begin_synctask (req, GD_OP_RESET_VOLUME, dict);
-
-out:
- if (ret) {
- if (err_str[0] == '\0')
- snprintf (err_str, sizeof (err_str),
- "Operation failed");
- ret = glusterd_op_send_cli_response (cli_op, ret, 0, req,
- dict, err_str);
- }
-
- return ret;
-}
-
-int
-glusterd_handle_reset_volume (rpcsvc_request_t *req)
-{
- return glusterd_big_locked_handler (req,
- __glusterd_handle_reset_volume);
-}
-
-int
-__glusterd_handle_set_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_SET_VOLUME;
- char *key = NULL;
- char *value = NULL;
- char *volname = NULL;
- char *op_errstr = NULL;
- gf_boolean_t help = _gf_false;
- char err_str[2048] = {0,};
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
-
- GF_ASSERT (req);
-
- ret = xdr_to_generic (req->msg[0], &cli_req, (xdrproc_t)xdr_gf_cli_req);
- if (ret < 0) {
- snprintf (err_str, sizeof (err_str), "Failed to decode "
- "request received from cli");
- gf_log (this->name, GF_LOG_ERROR, "%s", err_str);
- 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");
- snprintf (err_str, sizeof (err_str), "Unable to decode "
- "the command");
- goto out;
- } else {
- dict->extra_stdfree = cli_req.dict.dict_val;
- }
- }
-
- ret = dict_get_str (dict, "volname", &volname);
- if (ret) {
- snprintf (err_str, sizeof (err_str), "Failed to get volume "
- "name while handling volume set command");
- gf_log (this->name, GF_LOG_ERROR, "%s", err_str);
- goto out;
- }
-
- if (strcmp (volname, "help") == 0 ||
- strcmp (volname, "help-xml") == 0) {
- ret = glusterd_volset_help (dict, &op_errstr);
- help = _gf_true;
- goto out;
- }
-
- ret = dict_get_str (dict, "key1", &key);
- if (ret) {
- snprintf (err_str, sizeof (err_str), "Failed to get key while"
- " handling volume set for %s", volname);
- gf_log (this->name, GF_LOG_ERROR, "%s", err_str);
- goto out;
- }
-
- ret = dict_get_str (dict, "value1", &value);
- if (ret) {
- snprintf (err_str, sizeof (err_str), "Failed to get value while"
- " handling volume set for %s", volname);
- gf_log (this->name, GF_LOG_ERROR, "%s", err_str);
- goto out;
- }
- gf_log (this->name, GF_LOG_DEBUG, "Received volume set request for "
- "volume %s", volname);
-
- ret = glusterd_op_begin_synctask (req, GD_OP_SET_VOLUME, dict);
-
-out:
- if (help)
- ret = glusterd_op_send_cli_response (cli_op, ret, 0, req, dict,
- (op_errstr)? op_errstr:"");
- else if (ret) {
- if (err_str[0] == '\0')
- snprintf (err_str, sizeof (err_str),
- "Operation failed");
- ret = glusterd_op_send_cli_response (cli_op, ret, 0, req,
- dict, err_str);
- }
- if (op_errstr)
- GF_FREE (op_errstr);
-
- return ret;
-}
-
-int
-glusterd_handle_set_volume (rpcsvc_request_t *req)
-{
- return glusterd_big_locked_handler (req, __glusterd_handle_set_volume);
-}
-
-int
-__glusterd_handle_sync_volume (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,};
- char *volname = NULL;
- gf1_cli_sync_volume flags = 0;
- char *hostname = NULL;
- xlator_t *this = NULL;
-
- GF_ASSERT (req);
- this = THIS;
- GF_ASSERT (this);
-
- ret = xdr_to_generic (req->msg[0], &cli_req, (xdrproc_t)xdr_gf_cli_req);
- if (ret < 0) {
- //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");
- snprintf (msg, sizeof (msg), "Unable to decode the "
- "command");
- goto out;
- } else {
- dict->extra_stdfree = cli_req.dict.dict_val;
- }
- }
-
- ret = dict_get_str (dict, "hostname", &hostname);
- if (ret) {
- snprintf (msg, sizeof (msg), "Failed to get hostname");
- gf_log (this->name, GF_LOG_ERROR, "%s", msg);
- goto out;
- }
-
- ret = dict_get_str (dict, "volname", &volname);
- if (ret) {
- ret = dict_get_int32 (dict, "flags", (int32_t*)&flags);
- if (ret) {
- snprintf (msg, sizeof (msg), "Failed to get volume name"
- " or flags");
- gf_log (this->name, GF_LOG_ERROR, "%s", msg);
- goto out;
- }
- }
-
- gf_log (this->name, GF_LOG_INFO, "Received volume sync req "
- "for volume %s", (flags & GF_CLI_SYNC_ALL) ? "all" : volname);
-
- if (gf_is_local_addr (hostname)) {
- ret = -1;
- snprintf (msg, sizeof (msg), "sync from localhost"
- " not allowed");
- gf_log (this->name, GF_LOG_ERROR, "%s", msg);
- goto out;
- }
-
- ret = glusterd_op_begin_synctask (req, GD_OP_SYNC_VOLUME, dict);
-
-out:
- if (ret) {
- cli_rsp.op_ret = -1;
- cli_rsp.op_errstr = msg;
- if (msg[0] == '\0')
- snprintf (msg, sizeof (msg), "Operation failed");
- glusterd_to_cli (req, &cli_rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gf_cli_rsp, dict);
-
- ret = 0; //sent error to cli, prevent second reply
- }
-
- return ret;
-}
-
-int
-glusterd_handle_sync_volume (rpcsvc_request_t *req)
-{
- return glusterd_big_locked_handler (req, __glusterd_handle_sync_volume);
-}
-
-int
-glusterd_fsm_log_send_resp (rpcsvc_request_t *req, int op_ret,
- char *op_errstr, dict_t *dict)
-{
-
- int ret = -1;
- gf1_cli_fsm_log_rsp rsp = {0};
-
- GF_ASSERT (req);
- GF_ASSERT (op_errstr);
-
- rsp.op_ret = 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);
-
- 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_log ("glusterd", GF_LOG_DEBUG, "Responded, ret: %d", ret);
-
- return 0;
-}
-
-int
-__glusterd_handle_fsm_log (rpcsvc_request_t *req)
-{
- int32_t ret = -1;
- gf1_cli_fsm_log_req cli_req = {0,};
- dict_t *dict = NULL;
- glusterd_sm_tr_log_t *log = NULL;
- xlator_t *this = NULL;
- glusterd_conf_t *conf = NULL;
- char msg[2048] = {0};
- glusterd_peerinfo_t *peerinfo = NULL;
-
- GF_ASSERT (req);
-
- ret = xdr_to_generic (req->msg[0], &cli_req,
- (xdrproc_t)xdr_gf1_cli_fsm_log_req);
- if (ret < 0) {
- //failed to decode msg;
- req->rpc_err = GARBAGE_ARGS;
- snprintf (msg, sizeof (msg), "Garbage request");
- goto out;
- }
-
- if (strcmp ("", cli_req.name) == 0) {
- this = THIS;
- conf = this->private;
- log = &conf->op_sm_log;
- } else {
- peerinfo = glusterd_peerinfo_find_by_hostname (cli_req.name);
- if (!peerinfo) {
- snprintf (msg, sizeof (msg), "%s is not a peer",
- cli_req.name);
- goto out;
- }
- log = &peerinfo->sm_log;
- }
-
- dict = dict_new ();
- if (!dict) {
- ret = -1;
- goto out;
- }
-
- 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 (dict)
- dict_unref (dict);
-
- glusterd_friend_sm ();
- glusterd_op_sm ();
-
- return 0;//send 0 to avoid double reply
-}
-
-int
-glusterd_handle_fsm_log (rpcsvc_request_t *req)
-{
- return glusterd_big_locked_handler (req, __glusterd_handle_fsm_log);
-}
-
-int
-glusterd_op_lock_send_resp (rpcsvc_request_t *req, int32_t status)
-{
-
- gd1_mgmt_cluster_lock_rsp rsp = {{0},};
- int ret = -1;
-
- GF_ASSERT (req);
- glusterd_get_uuid (&rsp.uuid);
- rsp.op_ret = status;
-
- ret = glusterd_submit_reply (req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gd1_mgmt_cluster_lock_rsp);
-
- gf_log (THIS->name, GF_LOG_DEBUG, "Responded to lock, ret: %d", ret);
-
- return 0;
-}
-
-int
-glusterd_op_unlock_send_resp (rpcsvc_request_t *req, int32_t status)
-{
-
- gd1_mgmt_cluster_unlock_rsp rsp = {{0},};
- int ret = -1;
-
- GF_ASSERT (req);
- rsp.op_ret = status;
- glusterd_get_uuid (&rsp.uuid);
-
- ret = glusterd_submit_reply (req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gd1_mgmt_cluster_unlock_rsp);
-
- gf_log (THIS->name, GF_LOG_DEBUG, "Responded to unlock, ret: %d", ret);
-
- return ret;
-}
-
-int
-glusterd_op_mgmt_v3_lock_send_resp (rpcsvc_request_t *req, uuid_t *txn_id,
- int32_t status)
-{
-
- gd1_mgmt_v3_lock_rsp rsp = {{0},};
- int ret = -1;
-
- GF_ASSERT (req);
- GF_ASSERT (txn_id);
- glusterd_get_uuid (&rsp.uuid);
- rsp.op_ret = status;
- if (rsp.op_ret)
- rsp.op_errno = errno;
- uuid_copy (rsp.txn_id, *txn_id);
-
- ret = glusterd_submit_reply (req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gd1_mgmt_v3_lock_rsp);
-
- gf_log (THIS->name, GF_LOG_DEBUG, "Responded to mgmt_v3 lock, ret: %d",
- ret);
-
- return ret;
-}
-
-int
-glusterd_op_mgmt_v3_unlock_send_resp (rpcsvc_request_t *req, uuid_t *txn_id,
- int32_t status)
-{
-
- gd1_mgmt_v3_unlock_rsp rsp = {{0},};
- int ret = -1;
-
- GF_ASSERT (req);
- GF_ASSERT (txn_id);
- rsp.op_ret = status;
- if (rsp.op_ret)
- rsp.op_errno = errno;
- glusterd_get_uuid (&rsp.uuid);
- uuid_copy (rsp.txn_id, *txn_id);
-
- ret = glusterd_submit_reply (req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gd1_mgmt_v3_unlock_rsp);
-
- gf_log (THIS->name, GF_LOG_DEBUG, "Responded to mgmt_v3 unlock, ret: %d",
- ret);
-
- return ret;
-}
-
-int
-__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;
- xlator_t *this = NULL;
- uuid_t *txn_id = NULL;
- glusterd_conf_t *priv = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- priv = this->private;
- GF_ASSERT (priv);
- GF_ASSERT (req);
-
- txn_id = &priv->global_txn_id;
-
- ret = xdr_to_generic (req->msg[0], &unlock_req,
- (xdrproc_t)xdr_gd1_mgmt_cluster_unlock_req);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to decode unlock "
- "request received from peer");
- req->rpc_err = GARBAGE_ARGS;
- goto out;
- }
-
-
- gf_log (this->name, GF_LOG_DEBUG,
- "Received UNLOCK from uuid: %s", uuid_utoa (unlock_req.uuid));
-
- if (glusterd_peerinfo_find_by_uuid (unlock_req.uuid) == NULL) {
- 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) {
- //respond here
- return -1;
- }
- uuid_copy (ctx->uuid, unlock_req.uuid);
- ctx->req = req;
- ctx->dict = NULL;
-
- ret = glusterd_op_sm_inject_event (GD_OP_EVENT_UNLOCK, txn_id, ctx);
-
-out:
- glusterd_friend_sm ();
- glusterd_op_sm ();
-
- return ret;
-}
-
-int
-glusterd_handle_cluster_unlock (rpcsvc_request_t *req)
-{
- return glusterd_big_locked_handler (req,
- __glusterd_handle_cluster_unlock);
-}
-
-int
-glusterd_op_stage_send_resp (rpcsvc_request_t *req,
- int32_t op, int32_t status,
- char *op_errstr, dict_t *rsp_dict)
-{
- gd1_mgmt_stage_op_rsp rsp = {{0},};
- int ret = -1;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (req);
-
- rsp.op_ret = status;
- glusterd_get_uuid (&rsp.uuid);
- rsp.op = op;
- if (op_errstr)
- rsp.op_errstr = op_errstr;
- else
- rsp.op_errstr = "";
-
- ret = dict_allocate_and_serialize (rsp_dict, &rsp.dict.dict_val,
- &rsp.dict.dict_len);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "failed to get serialized length of dict");
- return ret;
- }
-
- ret = glusterd_submit_reply (req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gd1_mgmt_stage_op_rsp);
-
- gf_log (this->name, GF_LOG_DEBUG, "Responded to stage, ret: %d", ret);
- GF_FREE (rsp.dict.dict_val);
-
- return ret;
-}
-
-int
-glusterd_op_commit_send_resp (rpcsvc_request_t *req,
- int32_t op, int32_t status, char *op_errstr,
- dict_t *rsp_dict)
-{
- gd1_mgmt_commit_op_rsp rsp = {{0}, };
- int ret = -1;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (req);
- rsp.op_ret = status;
- glusterd_get_uuid (&rsp.uuid);
- rsp.op = op;
-
- if (op_errstr)
- rsp.op_errstr = op_errstr;
- else
- rsp.op_errstr = "";
-
- if (rsp_dict) {
- ret = dict_allocate_and_serialize (rsp_dict, &rsp.dict.dict_val,
- &rsp.dict.dict_len);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "failed to get serialized length of dict");
- goto out;
- }
- }
-
-
- ret = glusterd_submit_reply (req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gd1_mgmt_commit_op_rsp);
-
- gf_log (this->name, GF_LOG_DEBUG, "Responded to commit, ret: %d", ret);
-
-out:
- GF_FREE (rsp.dict.dict_val);
- return ret;
-}
-
-int
-__glusterd_handle_incoming_friend_req (rpcsvc_request_t *req)
-{
- int32_t ret = -1;
- gd1_mgmt_friend_req friend_req = {{0},};
- gf_boolean_t run_fsm = _gf_true;
-
- GF_ASSERT (req);
- ret = xdr_to_generic (req->msg[0], &friend_req,
- (xdrproc_t)xdr_gd1_mgmt_friend_req);
- if (ret < 0) {
- //failed to decode msg;
- req->rpc_err = GARBAGE_ARGS;
- goto out;
- }
-
- gf_log ("glusterd", GF_LOG_INFO,
- "Received probe from uuid: %s", uuid_utoa (friend_req.uuid));
- ret = glusterd_handle_friend_req (req, friend_req.uuid,
- friend_req.hostname, friend_req.port,
- &friend_req);
-
- if (ret == GLUSTERD_CONNECTION_AWAITED) {
- //fsm should be run after connection establishes
- run_fsm = _gf_false;
- ret = 0;
- }
-
-out:
- free (friend_req.hostname);//malloced by xdr
-
- if (run_fsm) {
- glusterd_friend_sm ();
- glusterd_op_sm ();
- }
-
- return ret;
-}
-
-int
-glusterd_handle_incoming_friend_req (rpcsvc_request_t *req)
-{
- return glusterd_big_locked_handler (req,
- __glusterd_handle_incoming_friend_req);
-}
-
-int
-__glusterd_handle_incoming_unfriend_req (rpcsvc_request_t *req)
-{
- int32_t ret = -1;
- gd1_mgmt_friend_req friend_req = {{0},};
- char remote_hostname[UNIX_PATH_MAX + 1] = {0,};
-
- GF_ASSERT (req);
- ret = xdr_to_generic (req->msg[0], &friend_req,
- (xdrproc_t)xdr_gd1_mgmt_friend_req);
- if (ret < 0) {
- //failed to decode msg;
- req->rpc_err = GARBAGE_ARGS;
- goto out;
- }
-
- gf_log ("glusterd", GF_LOG_INFO,
- "Received unfriend from uuid: %s", uuid_utoa (friend_req.uuid));
-
- ret = glusterd_remote_hostname_get (req, remote_hostname,
- sizeof (remote_hostname));
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Unable to get the remote hostname");
- goto out;
- }
- ret = glusterd_handle_unfriend_req (req, friend_req.uuid,
- remote_hostname, friend_req.port);
-
-out:
- free (friend_req.hostname);//malloced by xdr
- free (friend_req.vols.vols_val);//malloced by xdr
-
- glusterd_friend_sm ();
- glusterd_op_sm ();
-
- return ret;
-}
-
-int
-glusterd_handle_incoming_unfriend_req (rpcsvc_request_t *req)
-{
- return glusterd_big_locked_handler (req,
- __glusterd_handle_incoming_unfriend_req);
-
-}
-
-int
-glusterd_handle_friend_update_delete (dict_t *dict)
-{
- char *hostname = NULL;
- int32_t ret = -1;
-
- GF_ASSERT (dict);
-
- ret = dict_get_str (dict, "hostname", &hostname);
- if (ret)
- goto out;
-
- ret = glusterd_friend_remove (NULL, hostname);
-
-out:
- gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-
-int
-glusterd_peer_hostname_update (glusterd_peerinfo_t *peerinfo,
- const char *hostname, gf_boolean_t store_update)
-{
- int ret = 0;
-
- GF_ASSERT (peerinfo);
- GF_ASSERT (hostname);
-
- ret = gd_add_address_to_peer (peerinfo, hostname);
- if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR,
- "Couldn't add address to the peer info");
- goto out;
- }
-
- if (store_update)
- ret = glusterd_store_peerinfo (peerinfo);
-out:
- gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-
-int
-__glusterd_handle_friend_update (rpcsvc_request_t *req)
-{
- int32_t ret = -1;
- gd1_mgmt_friend_update friend_req = {{0},};
- glusterd_peerinfo_t *peerinfo = NULL;
- glusterd_conf_t *priv = NULL;
- xlator_t *this = NULL;
- gd1_mgmt_friend_update_rsp rsp = {{0},};
- dict_t *dict = NULL;
- char key[100] = {0,};
- char *uuid_buf = NULL;
- int i = 1;
- int count = 0;
- uuid_t uuid = {0,};
- glusterd_peerctx_args_t args = {0};
- int32_t op = 0;
-
- GF_ASSERT (req);
-
- this = THIS;
- GF_ASSERT (this);
- priv = this->private;
- GF_ASSERT (priv);
-
- ret = xdr_to_generic (req->msg[0], &friend_req,
- (xdrproc_t)xdr_gd1_mgmt_friend_update);
- if (ret < 0) {
- //failed to decode msg;
- req->rpc_err = GARBAGE_ARGS;
- goto out;
- }
-
- if (glusterd_peerinfo_find (friend_req.uuid, NULL) == NULL) {
- ret = -1;
- gf_log ("", GF_LOG_CRITICAL, "Received friend update request "
- "from unknown peer %s", uuid_utoa (friend_req.uuid));
- goto out;
- }
- gf_log ("glusterd", GF_LOG_INFO,
- "Received friend update from uuid: %s", uuid_utoa (friend_req.uuid));
-
- if (friend_req.friends.friends_len) {
- /* Unserialize the dictionary */
- dict = dict_new ();
-
- ret = dict_unserialize (friend_req.friends.friends_val,
- friend_req.friends.friends_len,
- &dict);
- if (ret < 0) {
- gf_log ("glusterd", GF_LOG_ERROR,
- "failed to "
- "unserialize req-buffer to dictionary");
- goto out;
- } else {
- dict->extra_stdfree = friend_req.friends.friends_val;
- }
- }
-
- ret = dict_get_int32 (dict, "count", &count);
- if (ret)
- goto out;
-
- ret = dict_get_int32 (dict, "op", &op);
- if (ret)
- goto out;
-
- if (GD_FRIEND_UPDATE_DEL == op) {
- ret = glusterd_handle_friend_update_delete (dict);
- goto out;
- }
-
- args.mode = GD_MODE_ON;
- while ( i <= count) {
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "friend%d.uuid", i);
- ret = dict_get_str (dict, key, &uuid_buf);
- if (ret)
- goto out;
- uuid_parse (uuid_buf, uuid);
-
- if (!uuid_compare (uuid, MY_UUID)) {
- gf_log (this->name, GF_LOG_INFO,
- "Received my uuid as Friend");
- i++;
- continue;
- }
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "friend%d", i);
-
- peerinfo = glusterd_peerinfo_find (uuid, NULL);
- if (peerinfo == NULL) {
- /* Create a new peer and add it to the list as there is
- * no existing peer with the uuid
- */
- peerinfo = gd_peerinfo_from_dict (dict, key);
- if (peerinfo == NULL) {
- ret = -1;
- gf_log (this->name, GF_LOG_ERROR,
- "Could not create peerinfo from dict "
- "for prefix %s", key);
- goto out;
- }
-
- /* As this is a new peer, it should be added as a
- * friend. The friend state machine will take care of
- * correcting the state as required
- */
- peerinfo->state.state = GD_FRIEND_STATE_BEFRIENDED;
-
- ret = glusterd_friend_add_from_peerinfo (peerinfo, 0,
- &args);
- } else {
- /* As an existing peer was found, update it with the new
- * information
- */
- ret = gd_update_peerinfo_from_dict (peerinfo, dict,
- key);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to "
- "update peer %s", peerinfo->hostname);
- goto out;
- }
- ret = glusterd_store_peerinfo (peerinfo);
- if (ret)
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to store peerinfo");
- }
-
- peerinfo = NULL;
- i++;
- }
-
-out:
- uuid_copy (rsp.uuid, MY_UUID);
- ret = glusterd_submit_reply (req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gd1_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 (peerinfo)
- glusterd_peerinfo_cleanup (peerinfo);
-
- glusterd_friend_sm ();
- glusterd_op_sm ();
-
- return ret;
-}
-
-int
-glusterd_handle_friend_update (rpcsvc_request_t *req)
-{
- return glusterd_big_locked_handler (req,
- __glusterd_handle_friend_update);
-}
-
-int
-__glusterd_handle_probe_query (rpcsvc_request_t *req)
-{
- int32_t ret = -1;
- xlator_t *this = NULL;
- glusterd_conf_t *conf = NULL;
- gd1_mgmt_probe_req probe_req = {{0},};
- gd1_mgmt_probe_rsp rsp = {{0},};
- glusterd_peerinfo_t *peerinfo = NULL;
- glusterd_peerctx_args_t args = {0};
- int port = 0;
- char remote_hostname[UNIX_PATH_MAX + 1] = {0,};
-
- GF_ASSERT (req);
-
- ret = xdr_to_generic (req->msg[0], &probe_req,
- (xdrproc_t)xdr_gd1_mgmt_probe_req);
- if (ret < 0) {
- //failed to decode msg;
- req->rpc_err = GARBAGE_ARGS;
- goto out;
- }
-
- this = THIS;
-
- conf = this->private;
- if (probe_req.port)
- port = probe_req.port;
- else
- port = GF_DEFAULT_BASE_PORT;
-
- 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) {
- gf_log ("", GF_LOG_ERROR, "Unable to get the remote hostname");
- goto out;
- }
- peerinfo = glusterd_peerinfo_find (probe_req.uuid, remote_hostname);
- if ((peerinfo == NULL) && (!list_empty (&conf->peers))) {
- rsp.op_ret = -1;
- rsp.op_errno = GF_PROBE_ANOTHER_CLUSTER;
- } else if (peerinfo == NULL) {
- gf_log ("glusterd", GF_LOG_INFO, "Unable to find peerinfo"
- " for host: %s (%d)", remote_hostname, port);
- args.mode = GD_MODE_ON;
- ret = glusterd_friend_add (remote_hostname, port,
- GD_FRIEND_STATE_PROBE_RCVD,
- NULL, &peerinfo, 0, &args);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Failed to add peer %s",
- remote_hostname);
- rsp.op_errno = GF_PROBE_ADD_FAILED;
- }
- }
-
-respond:
- uuid_copy (rsp.uuid, MY_UUID);
-
- rsp.hostname = probe_req.hostname;
- rsp.op_errstr = "";
-
- glusterd_submit_reply (req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gd1_mgmt_probe_rsp);
- ret = 0;
-
- gf_log ("glusterd", GF_LOG_INFO, "Responded to %s, op_ret: %d, "
- "op_errno: %d, ret: %d", remote_hostname,
- rsp.op_ret, rsp.op_errno, ret);
-
-out:
- free (probe_req.hostname);//malloced by xdr
-
- glusterd_friend_sm ();
- glusterd_op_sm ();
-
- return ret;
-}
-
-int glusterd_handle_probe_query (rpcsvc_request_t *req)
-{
- return glusterd_big_locked_handler (req, __glusterd_handle_probe_query);
-}
-
-int
-__glusterd_handle_cli_profile_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_PROFILE_VOLUME;
- char *volname = NULL;
- int32_t op = 0;
- char err_str[2048] = {0,};
- xlator_t *this = NULL;
-
- GF_ASSERT (req);
- this = THIS;
- GF_ASSERT (this);
-
- ret = xdr_to_generic (req->msg[0], &cli_req, (xdrproc_t)xdr_gf_cli_req);
- if (ret < 0) {
- //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);
- }
-
- ret = dict_get_str (dict, "volname", &volname);
- if (ret) {
- snprintf (err_str, sizeof (err_str), "Unable to get volume "
- "name");
- gf_log (this->name, GF_LOG_ERROR, "%s", err_str);
- goto out;
- }
-
- gf_log (this->name, GF_LOG_INFO, "Received volume profile req "
- "for volume %s", volname);
- ret = dict_get_int32 (dict, "op", &op);
- if (ret) {
- snprintf (err_str, sizeof (err_str), "Unable to get operation");
- gf_log (this->name, GF_LOG_ERROR, "%s", err_str);
- goto out;
- }
-
- ret = glusterd_op_begin (req, cli_op, dict, err_str, sizeof (err_str));
-
-out:
- glusterd_friend_sm ();
- glusterd_op_sm ();
-
- free (cli_req.dict.dict_val);
-
- if (ret) {
- if (err_str[0] == '\0')
- snprintf (err_str, sizeof (err_str),
- "Operation failed");
- ret = glusterd_op_send_cli_response (cli_op, ret, 0, req,
- dict, err_str);
- }
-
- gf_log (this->name, GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-
-int
-glusterd_handle_cli_profile_volume (rpcsvc_request_t *req)
-{
- return glusterd_big_locked_handler (req,
- __glusterd_handle_cli_profile_volume);
-}
-
-int
-__glusterd_handle_getwd (rpcsvc_request_t *req)
-{
- int32_t ret = -1;
- gf1_cli_getwd_rsp rsp = {0,};
- glusterd_conf_t *priv = NULL;
-
- GF_ASSERT (req);
-
- priv = THIS->private;
- GF_ASSERT (priv);
-
- gf_log ("glusterd", GF_LOG_INFO, "Received getwd req");
-
- rsp.wd = priv->workdir;
-
- glusterd_submit_reply (req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gf1_cli_getwd_rsp);
- ret = 0;
-
- glusterd_friend_sm ();
- glusterd_op_sm ();
-
- return ret;
-}
-
-int
-glusterd_handle_getwd (rpcsvc_request_t *req)
-{
- return glusterd_big_locked_handler (req, __glusterd_handle_getwd);
-}
-
-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;
- glusterd_conf_t *priv = NULL;
-
- GF_ASSERT (req);
- priv = THIS->private;
-
- ret = xdr_to_generic (req->msg[0], &mnt_req,
- (xdrproc_t)xdr_gf1_cli_mount_req);
- if (ret < 0) {
- //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;
- }
- }
-
- synclock_unlock (&priv->big_lock);
- rsp.op_ret = glusterd_do_mount (mnt_req.label, dict,
- &rsp.path, &rsp.op_errno);
- synclock_lock (&priv->big_lock);
-
- out:
- if (!rsp.path)
- rsp.path = "";
-
- glusterd_submit_reply (req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gf1_cli_mount_rsp);
- ret = 0;
-
- if (dict)
- dict_unref (dict);
- if (*rsp.path)
- GF_FREE (rsp.path);
-
- glusterd_friend_sm ();
- glusterd_op_sm ();
-
- return ret;
-}
-
-int
-glusterd_handle_mount (rpcsvc_request_t *req)
-{
- return glusterd_big_locked_handler (req, __glusterd_handle_mount);
-}
-
-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;
- glusterd_conf_t *priv = NULL;
-
- GF_ASSERT (req);
- GF_ASSERT (this);
- priv = this->private;
-
- ret = xdr_to_generic (req->msg[0], &umnt_req,
- (xdrproc_t)xdr_gf1_cli_umount_req);
- if (ret < 0) {
- //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;
- }
-
- synclock_unlock (&priv->big_lock);
-
- if (umnt_req.lazy) {
- rsp.op_ret = gf_umount_lazy (this->name, umnt_req.path, 0);
- } else {
- runinit (&runner);
- runner_add_args (&runner, _PATH_UMOUNT, umnt_req.path, NULL);
- rsp.op_ret = runner_run (&runner);
- }
-
- synclock_lock (&priv->big_lock);
- 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;
-
- glusterd_submit_reply (req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gf1_cli_umount_rsp);
- ret = 0;
-
- glusterd_friend_sm ();
- glusterd_op_sm ();
-
- return ret;
-}
-
-int
-glusterd_handle_umount (rpcsvc_request_t *req)
-{
- return glusterd_big_locked_handler (req, __glusterd_handle_umount);
-}
-
-int
-glusterd_friend_remove (uuid_t uuid, char *hostname)
-{
- int ret = -1;
- glusterd_peerinfo_t *peerinfo = NULL;
-
- peerinfo = glusterd_peerinfo_find (uuid, hostname);
- if (peerinfo == NULL)
- goto out;
-
- ret = glusterd_friend_remove_cleanup_vols (peerinfo->uuid);
- if (ret)
- gf_log (THIS->name, GF_LOG_WARNING, "Volumes cleanup failed");
- ret = glusterd_peerinfo_cleanup (peerinfo);
-out:
- gf_log ("", GF_LOG_DEBUG, "returning %d", ret);
- return ret;
-}
-
-int
-glusterd_rpc_create (struct rpc_clnt **rpc,
- dict_t *options,
- rpc_clnt_notify_t notify_fn,
- void *notify_data)
-{
- struct rpc_clnt *new_rpc = NULL;
- int ret = -1;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
-
- GF_ASSERT (options);
-
- /* TODO: is 32 enough? or more ? */
- new_rpc = rpc_clnt_new (options, this->ctx, this->name, 16);
- if (!new_rpc)
- goto out;
-
- ret = rpc_clnt_register_notify (new_rpc, notify_fn, notify_data);
- *rpc = new_rpc;
- if (ret)
- goto out;
- ret = rpc_clnt_start (new_rpc);
-out:
- if (ret) {
- if (new_rpc) {
- (void) rpc_clnt_unref (new_rpc);
- }
- }
-
- gf_log (this->name, GF_LOG_DEBUG, "returning %d", ret);
- return ret;
-}
-
-int
-glusterd_transport_keepalive_options_get (int *interval, int *time)
-{
- int ret = 0;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
-
- ret = dict_get_int32 (this->options,
- "transport.socket.keepalive-interval",
- interval);
- ret = dict_get_int32 (this->options,
- "transport.socket.keepalive-time",
- time);
- return 0;
-}
-
-int
-glusterd_transport_inet_options_build (dict_t **options, const char *hostname,
- int port)
-{
- dict_t *dict = NULL;
- int32_t interval = -1;
- int32_t time = -1;
- int ret = 0;
-
- GF_ASSERT (options);
- GF_ASSERT (hostname);
-
- if (!port)
- port = GLUSTERD_DEFAULT_PORT;
-
- /* Build default transport options */
- ret = rpc_transport_inet_options_build (&dict, hostname, port);
- if (ret)
- goto out;
-
- /* Set frame-timeout to 10mins. Default timeout of 30 mins is too long
- * when compared to 2 mins for cli timeout. This ensures users don't
- * wait too long after cli timesout before being able to resume normal
- * operations
- */
- ret = dict_set_int32 (dict, "frame-timeout", 600);
- if (ret) {
- gf_log ("glusterd", GF_LOG_ERROR,
- "Failed to set frame-timeout");
- goto out;
- }
-
- /* Set keepalive options */
- glusterd_transport_keepalive_options_get (&interval, &time);
-
- if ((interval > 0) || (time > 0))
- ret = rpc_transport_keepalive_options_set (dict, interval, time);
- *options = dict;
-out:
- gf_log ("glusterd", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-
-int
-glusterd_friend_rpc_create (xlator_t *this, glusterd_peerinfo_t *peerinfo,
- glusterd_peerctx_args_t *args)
-{
- dict_t *options = NULL;
- int ret = -1;
- glusterd_peerctx_t *peerctx = NULL;
- data_t *data = NULL;
-
- peerctx = GF_CALLOC (1, sizeof (*peerctx), gf_gld_mt_peerctx_t);
- if (!peerctx)
- goto out;
-
- if (args)
- peerctx->args = *args;
-
- peerctx->peerinfo = peerinfo;
-
- ret = glusterd_transport_inet_options_build (&options,
- peerinfo->hostname,
- peerinfo->port);
- if (ret)
- goto out;
-
- /*
- * For simulated multi-node testing, we need to make sure that we
- * create our RPC endpoint with the same address that the peer would
- * use to reach us.
- */
- if (this->options) {
- data = dict_get(this->options,"transport.socket.bind-address");
- if (data) {
- ret = dict_set(options,
- "transport.socket.source-addr",data);
- }
- data = dict_get(this->options,"ping-timeout");
- if (data) {
- ret = dict_set(options,
- "ping-timeout",data);
- }
- }
-
- /* Enable encryption for the client connection if management encryption
- * is enabled
- */
- if (this->ctx->secure_mgmt) {
- ret = dict_set_str (options, "transport.socket.ssl-enabled",
- "on");
- if (ret) {
- gf_log ("glusterd", GF_LOG_ERROR,
- "failed to set ssl-enabled in dict");
- goto out;
- }
- }
-
- ret = glusterd_rpc_create (&peerinfo->rpc, options,
- glusterd_peer_rpc_notify, peerctx);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "failed to create rpc for"
- " peer %s", peerinfo->hostname);
- goto out;
- }
- peerctx = NULL;
- ret = 0;
-out:
- GF_FREE (peerctx);
- return ret;
-}
-
-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)
-{
- int ret = 0;
- xlator_t *this = NULL;
- glusterd_conf_t *conf = NULL;
-
- this = THIS;
- conf = this->private;
- GF_ASSERT (conf);
- GF_ASSERT (hoststr);
- GF_ASSERT (friend);
-
- *friend = glusterd_peerinfo_new (state, uuid, hoststr, port);
- if (*friend == NULL) {
- ret = -1;
- goto out;
- }
-
- /*
- * We can't add to the list after calling glusterd_friend_rpc_create,
- * even if it succeeds, because by then the callback to take it back
- * off and free might have happened already (notably in the case of an
- * invalid peer name). That would mean we're adding something that had
- * just been free, and we're likely to crash later.
- */
- list_add_tail (&(*friend)->uuid_list, &conf->peers);
-
- //restore needs to first create the list of peers, then create rpcs
- //to keep track of quorum in race-free manner. In restore for each peer
- //rpc-create calls rpc_notify when the friend-list is partially
- //constructed, leading to wrong quorum calculations.
- if (!restore) {
- ret = glusterd_store_peerinfo (*friend);
- if (ret == 0) {
- ret = glusterd_friend_rpc_create (this, *friend, args);
- }
- else {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to store peerinfo");
- }
- }
-
- if (ret) {
- (void) glusterd_peerinfo_cleanup (*friend);
- *friend = NULL;
- }
-
-out:
- gf_log (this->name, GF_LOG_INFO, "connect returned %d", ret);
- return ret;
-}
-
-/* glusterd_friend_add_from_peerinfo() adds a new peer into the local friends
- * list from a pre created @peerinfo object. It otherwise works similarly to
- * glusterd_friend_add()
- */
-int
-glusterd_friend_add_from_peerinfo (glusterd_peerinfo_t *friend,
- gf_boolean_t restore,
- glusterd_peerctx_args_t *args)
-{
- int ret = 0;
- xlator_t *this = NULL;
- glusterd_conf_t *conf = NULL;
-
- this = THIS;
- conf = this->private;
- GF_ASSERT (conf);
-
- GF_VALIDATE_OR_GOTO (this->name, (friend != NULL), out);
-
- /*
- * We can't add to the list after calling glusterd_friend_rpc_create,
- * even if it succeeds, because by then the callback to take it back
- * off and free might have happened already (notably in the case of an
- * invalid peer name). That would mean we're adding something that had
- * just been free, and we're likely to crash later.
- */
- list_add_tail (&friend->uuid_list, &conf->peers);
-
- //restore needs to first create the list of peers, then create rpcs
- //to keep track of quorum in race-free manner. In restore for each peer
- //rpc-create calls rpc_notify when the friend-list is partially
- //constructed, leading to wrong quorum calculations.
- if (!restore) {
- ret = glusterd_store_peerinfo (friend);
- if (ret == 0) {
- ret = glusterd_friend_rpc_create (this, friend, args);
- }
- else {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to store peerinfo");
- }
- }
-
-out:
- gf_log (this->name, GF_LOG_INFO, "connect returned %d", ret);
- return ret;
-}
-
-int
-glusterd_probe_begin (rpcsvc_request_t *req, const char *hoststr, int port,
- dict_t *dict, int *op_errno)
-{
- int ret = -1;
- glusterd_peerinfo_t *peerinfo = NULL;
- glusterd_peerctx_args_t args = {0};
- glusterd_friend_sm_event_t *event = NULL;
-
- GF_ASSERT (hoststr);
-
- peerinfo = glusterd_peerinfo_find (NULL, hoststr);
-
- if (peerinfo == NULL) {
- gf_log ("glusterd", GF_LOG_INFO, "Unable to find peerinfo"
- " for host: %s (%d)", hoststr, port);
- args.mode = GD_MODE_ON;
- args.req = req;
- args.dict = dict;
- ret = glusterd_friend_add (hoststr, port,
- GD_FRIEND_STATE_DEFAULT,
- NULL, &peerinfo, 0, &args);
- if ((!ret) && (!peerinfo->connected)) {
- ret = GLUSTERD_CONNECTION_AWAITED;
- }
-
- } else if (peerinfo->connected &&
- (GD_FRIEND_STATE_BEFRIENDED == peerinfo->state.state)) {
- if (peerinfo->detaching) {
- ret = -1;
- if (op_errno)
- *op_errno = GF_PROBE_FRIEND_DETACHING;
- goto out;
- }
- ret = glusterd_peer_hostname_update (peerinfo, hoststr,
- _gf_false);
- if (ret)
- goto out;
- //this is just to rename so inject local acc for cluster update
- ret = glusterd_friend_sm_new_event (GD_FRIEND_EVENT_LOCAL_ACC,
- &event);
- if (!ret) {
- event->peerinfo = peerinfo;
- ret = glusterd_friend_sm_inject_event (event);
- glusterd_xfer_cli_probe_resp (req, 0, GF_PROBE_SUCCESS,
- NULL, (char*)hoststr,
- port, dict);
- }
- } else {
- glusterd_xfer_cli_probe_resp (req, 0, GF_PROBE_FRIEND, NULL,
- (char*)hoststr, port, dict);
- }
-
-out:
- gf_log ("", GF_LOG_DEBUG, "returning %d", ret);
- return ret;
-}
-
-int
-glusterd_deprobe_begin (rpcsvc_request_t *req, const char *hoststr, int port,
- uuid_t uuid, dict_t *dict, int *op_errno)
-{
- int ret = -1;
- glusterd_peerinfo_t *peerinfo = NULL;
- glusterd_friend_sm_event_t *event = NULL;
- glusterd_probe_ctx_t *ctx = NULL;
-
- GF_ASSERT (hoststr);
- GF_ASSERT (req);
-
- peerinfo = glusterd_peerinfo_find (uuid, hoststr);
-
- if (peerinfo == NULL) {
- ret = -1;
- gf_log ("glusterd", GF_LOG_INFO, "Unable to find peerinfo"
- " for host: %s %d", hoststr, port);
- goto out;
- }
-
- if (!peerinfo->rpc) {
- //handle this case
- goto out;
- }
-
- if (peerinfo->detaching) {
- ret = -1;
- if (op_errno)
- *op_errno = GF_DEPROBE_FRIEND_DETACHING;
- goto out;
- }
-
- ret = glusterd_friend_sm_new_event
- (GD_FRIEND_EVENT_INIT_REMOVE_FRIEND, &event);
-
- if (ret) {
- gf_log ("glusterd", GF_LOG_ERROR,
- "Unable to get new event");
- return ret;
- }
-
- ctx = GF_CALLOC (1, sizeof(*ctx), gf_gld_mt_probe_ctx_t);
-
- if (!ctx) {
- goto out;
- }
-
- ctx->hostname = gf_strdup (hoststr);
- ctx->port = port;
- ctx->req = req;
- ctx->dict = dict;
-
- event->ctx = ctx;
-
- event->peerinfo = peerinfo;
-
- ret = glusterd_friend_sm_inject_event (event);
-
- if (ret) {
- gf_log ("glusterd", GF_LOG_ERROR, "Unable to inject event %d, "
- "ret = %d", event->event, ret);
- goto out;
- }
- peerinfo->detaching = _gf_true;
-
-out:
- return ret;
-}
-
-
-int
-glusterd_xfer_friend_remove_resp (rpcsvc_request_t *req, char *hostname, int port)
-{
- gd1_mgmt_friend_rsp rsp = {{0}, };
- int32_t ret = -1;
- xlator_t *this = NULL;
- glusterd_conf_t *conf = NULL;
-
- GF_ASSERT (hostname);
-
- rsp.op_ret = 0;
- this = THIS;
- GF_ASSERT (this);
-
- conf = this->private;
-
- uuid_copy (rsp.uuid, MY_UUID);
- rsp.hostname = hostname;
- rsp.port = port;
- ret = glusterd_submit_reply (req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gd1_mgmt_friend_rsp);
-
- gf_log ("glusterd", GF_LOG_INFO,
- "Responded to %s (%d), ret: %d", hostname, port, ret);
- return ret;
-}
-
-
-int
-glusterd_xfer_friend_add_resp (rpcsvc_request_t *req, char *myhostname,
- char *remote_hostname, int port, int32_t op_ret,
- int32_t op_errno)
-{
- gd1_mgmt_friend_rsp rsp = {{0}, };
- int32_t ret = -1;
- xlator_t *this = NULL;
- glusterd_conf_t *conf = NULL;
-
- GF_ASSERT (myhostname);
-
- this = THIS;
- GF_ASSERT (this);
-
- conf = this->private;
-
- uuid_copy (rsp.uuid, MY_UUID);
- rsp.op_ret = op_ret;
- rsp.op_errno = op_errno;
- rsp.hostname = gf_strdup (myhostname);
- rsp.port = port;
-
- ret = glusterd_submit_reply (req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gd1_mgmt_friend_rsp);
-
- gf_log ("glusterd", GF_LOG_INFO,
- "Responded to %s (%d), ret: %d", remote_hostname, port, ret);
- GF_FREE (rsp.hostname);
- return ret;
-}
-
-static void
-set_probe_error_str (int op_ret, int op_errno, char *op_errstr, char *errstr,
- size_t len, char *hostname, int port)
-{
- if ((op_errstr) && (strcmp (op_errstr, ""))) {
- snprintf (errstr, len, "%s", op_errstr);
- return;
- }
-
- if (!op_ret) {
- switch (op_errno) {
- case GF_PROBE_LOCALHOST:
- snprintf (errstr, len, "Probe on localhost not "
- "needed");
- break;
-
- case GF_PROBE_FRIEND:
- snprintf (errstr, len, "Host %s port %d already"
- " in peer list", hostname, port);
- break;
-
- case GF_PROBE_FRIEND_DETACHING:
- snprintf (errstr, len, "Peer is already being "
- "detached from cluster.\n"
- "Check peer status by running "
- "gluster peer status");
- break;
- default:
- if (op_errno != 0)
- snprintf (errstr, len, "Probe returned "
- "with unknown errno %d",
- op_errno);
- break;
- }
- } else {
- switch (op_errno) {
- case GF_PROBE_ANOTHER_CLUSTER:
- snprintf (errstr, len, "%s is already part of "
- "another cluster", hostname);
- break;
-
- case GF_PROBE_VOLUME_CONFLICT:
- snprintf (errstr, len, "Atleast one volume on "
- "%s conflicts with existing volumes "
- "in the cluster", hostname);
- break;
-
- case GF_PROBE_UNKNOWN_PEER:
- snprintf (errstr, len, "%s responded with "
- "'unknown peer' error, this could "
- "happen if %s doesn't have localhost "
- "in its peer database", hostname,
- hostname);
- break;
-
- case GF_PROBE_ADD_FAILED:
- snprintf (errstr, len, "Failed to add peer "
- "information on %s", hostname);
- break;
-
- case GF_PROBE_SAME_UUID:
- snprintf (errstr, len, "Peer uuid (host %s) is "
- "same as local uuid", hostname);
- break;
-
- case GF_PROBE_QUORUM_NOT_MET:
- snprintf (errstr, len, "Cluster quorum is not "
- "met. Changing peers is not allowed "
- "in this state");
- break;
-
- case GF_PROBE_MISSED_SNAP_CONFLICT:
- snprintf (errstr, len, "Failed to update "
- "list of missed snapshots from "
- "peer %s", hostname);
- break;
-
- case GF_PROBE_SNAP_CONFLICT:
- snprintf (errstr, len, "Conflict in comparing "
- "list of snapshots from "
- "peer %s", hostname);
- break;
-
- default:
- snprintf (errstr, len, "Probe returned with "
- "unknown errno %d", op_errno);
- break;
- }
- }
-}
-
-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, dict_t *dict)
-{
- gf_cli_rsp rsp = {0,};
- int32_t ret = -1;
- char errstr[2048] = {0,};
- char *cmd_str = NULL;
- xlator_t *this = THIS;
-
- GF_ASSERT (req);
- GF_ASSERT (this);
-
- (void) set_probe_error_str (op_ret, op_errno, op_errstr, errstr,
- sizeof (errstr), hostname, port);
-
- if (dict) {
- ret = dict_get_str (dict, "cmd-str", &cmd_str);
- if (ret)
- gf_log (this->name, GF_LOG_ERROR, "Failed to get "
- "command string");
- }
-
- rsp.op_ret = op_ret;
- rsp.op_errno = op_errno;
- rsp.op_errstr = (errstr[0] != '\0') ? errstr : "";
-
- gf_cmd_log ("", "%s : %s %s %s", cmd_str,
- (op_ret) ? "FAILED" : "SUCCESS",
- (errstr[0] != '\0') ? ":" : " ",
- (errstr[0] != '\0') ? errstr : " ");
-
- ret = glusterd_submit_reply (req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gf_cli_rsp);
-
- if (dict)
- dict_unref (dict);
- gf_log (this->name, GF_LOG_DEBUG, "Responded to CLI, ret: %d",ret);
-
- return ret;
-}
-
-static void
-set_deprobe_error_str (int op_ret, int op_errno, char *op_errstr, char *errstr,
- size_t len, char *hostname)
-{
- if ((op_errstr) && (strcmp (op_errstr, ""))) {
- snprintf (errstr, len, "%s", op_errstr);
- return;
- }
-
- if (op_ret) {
- switch (op_errno) {
- case GF_DEPROBE_LOCALHOST:
- snprintf (errstr, len, "%s is localhost",
- hostname);
- break;
-
- case GF_DEPROBE_NOT_FRIEND:
- snprintf (errstr, len, "%s is not part of "
- "cluster", hostname);
- break;
-
- case GF_DEPROBE_BRICK_EXIST:
- snprintf (errstr, len, "Brick(s) with the peer "
- "%s exist in cluster", hostname);
- break;
-
- case GF_DEPROBE_FRIEND_DOWN:
- snprintf (errstr, len, "One of the peers is "
- "probably down. Check with "
- "'peer status'");
- break;
-
- case GF_DEPROBE_QUORUM_NOT_MET:
- snprintf (errstr, len, "Cluster quorum is not "
- "met. Changing peers is not allowed "
- "in this state");
- break;
-
- case GF_DEPROBE_FRIEND_DETACHING:
- snprintf (errstr, len, "Peer is already being "
- "detached from cluster.\n"
- "Check peer status by running "
- "gluster peer status");
- break;
- default:
- snprintf (errstr, len, "Detach returned with "
- "unknown errno %d", op_errno);
- break;
-
- }
- }
-}
-
-
-int
-glusterd_xfer_cli_deprobe_resp (rpcsvc_request_t *req, int32_t op_ret,
- int32_t op_errno, char *op_errstr,
- char *hostname, dict_t *dict)
-{
- gf_cli_rsp rsp = {0,};
- int32_t ret = -1;
- char *cmd_str = NULL;
- char errstr[2048] = {0,};
-
- GF_ASSERT (req);
-
- (void) set_deprobe_error_str (op_ret, op_errno, op_errstr, errstr,
- sizeof (errstr), hostname);
-
- if (dict) {
- ret = dict_get_str (dict, "cmd-str", &cmd_str);
- if (ret)
- gf_log (THIS->name, GF_LOG_ERROR, "Failed to get "
- "command string");
- }
-
- rsp.op_ret = op_ret;
- rsp.op_errno = op_errno;
- rsp.op_errstr = (errstr[0] != '\0') ? errstr : "";
-
- gf_cmd_log ("", "%s : %s %s %s", cmd_str,
- (op_ret) ? "FAILED" : "SUCCESS",
- (errstr[0] != '\0') ? ":" : " ",
- (errstr[0] != '\0') ? errstr : " ");
-
- ret = glusterd_submit_reply (req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gf_cli_rsp);
-
- gf_log (THIS->name, GF_LOG_DEBUG, "Responded to CLI, ret: %d",ret);
-
- return ret;
-}
-
-int32_t
-glusterd_list_friends (rpcsvc_request_t *req, dict_t *dict, int32_t flags)
-{
- int32_t ret = -1;
- glusterd_conf_t *priv = NULL;
- glusterd_peerinfo_t *entry = NULL;
- int32_t count = 0;
- dict_t *friends = NULL;
- gf1_cli_peer_list_rsp rsp = {0,};
- char my_uuid_str[64] = {0,};
- char key[256] = {0,};
-
- priv = THIS->private;
- GF_ASSERT (priv);
-
- friends = dict_new ();
- if (!friends) {
- gf_log ("", GF_LOG_WARNING, "Out of Memory");
- goto out;
- }
- if (!list_empty (&priv->peers)) {
- list_for_each_entry (entry, &priv->peers, uuid_list) {
- count++;
- ret = gd_add_peer_detail_to_dict (entry,
- friends, count);
- if (ret)
- goto out;
- }
- }
-
- if (flags == GF_CLI_LIST_POOL_NODES) {
- count++;
- snprintf (key, 256, "friend%d.uuid", count);
- uuid_utoa_r (MY_UUID, my_uuid_str);
- ret = dict_set_str (friends, key, my_uuid_str);
- if (ret)
- goto out;
-
- snprintf (key, 256, "friend%d.hostname", count);
- ret = dict_set_str (friends, key, "localhost");
- if (ret)
- goto out;
-
- snprintf (key, 256, "friend%d.connected", count);
- ret = dict_set_int32 (friends, key, 1);
- if (ret)
- goto out;
- }
-
- ret = dict_set_int32 (friends, "count", count);
- if (ret)
- goto out;
-
- ret = dict_allocate_and_serialize (friends, &rsp.friends.friends_val,
- &rsp.friends.friends_len);
-
- if (ret)
- goto out;
-
- ret = 0;
-out:
-
- if (friends)
- dict_unref (friends);
-
- rsp.op_ret = ret;
-
- glusterd_submit_reply (req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gf1_cli_peer_list_rsp);
- ret = 0;
- GF_FREE (rsp.friends.friends_val);
-
- return ret;
-}
-
-int32_t
-glusterd_get_volumes (rpcsvc_request_t *req, dict_t *dict, int32_t flags)
-{
- int32_t ret = -1;
- glusterd_conf_t *priv = NULL;
- glusterd_volinfo_t *entry = NULL;
- int32_t count = 0;
- dict_t *volumes = NULL;
- gf_cli_rsp rsp = {0,};
- char *volname = NULL;
-
- priv = THIS->private;
- GF_ASSERT (priv);
-
- volumes = dict_new ();
- if (!volumes) {
- gf_log ("", GF_LOG_WARNING, "Out of Memory");
- goto out;
- }
-
- if (list_empty (&priv->volumes)) {
- ret = 0;
- goto respond;
- }
-
- if (flags == GF_CLI_GET_VOLUME_ALL) {
- list_for_each_entry (entry, &priv->volumes, vol_list) {
- ret = glusterd_add_volume_detail_to_dict (entry,
- volumes, count);
- if (ret)
- goto respond;
-
- count++;
-
- }
-
- } else if (flags == GF_CLI_GET_NEXT_VOLUME) {
- ret = dict_get_str (dict, "volname", &volname);
-
- if (ret) {
- if (priv->volumes.next) {
- entry = list_entry (priv->volumes.next,
- typeof (*entry),
- vol_list);
- }
- } else {
- ret = glusterd_volinfo_find (volname, &entry);
- if (ret)
- goto respond;
- entry = list_entry (entry->vol_list.next,
- typeof (*entry),
- vol_list);
- }
-
- if (&entry->vol_list == &priv->volumes) {
- goto respond;
- } else {
- ret = glusterd_add_volume_detail_to_dict (entry,
- volumes, count);
- if (ret)
- goto respond;
-
- count++;
- }
- } else if (flags == GF_CLI_GET_VOLUME) {
- ret = dict_get_str (dict, "volname", &volname);
- if (ret)
- goto respond;
-
- ret = glusterd_volinfo_find (volname, &entry);
- if (ret)
- goto respond;
-
- ret = glusterd_add_volume_detail_to_dict (entry,
- volumes, count);
- if (ret)
- goto respond;
-
- count++;
- }
-
-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);
-
- if (ret)
- goto out;
-
- ret = 0;
-out:
- rsp.op_ret = ret;
-
- rsp.op_errstr = "";
- glusterd_submit_reply (req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gf_cli_rsp);
- ret = 0;
-
- 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;
- char err_str[2048] = {0,};
- xlator_t *this = NULL;
- glusterd_conf_t *conf = NULL;
-
- GF_ASSERT (req);
- this = THIS;
- GF_ASSERT (this);
- conf = this->private;
- GF_ASSERT (conf);
-
- ret = xdr_to_generic (req->msg[0], &cli_req, (xdrproc_t)xdr_gf_cli_req);
- if (ret < 0) {
- //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");
- snprintf (err_str, sizeof (err_str), "Unable to decode "
- "the command");
- 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) {
- snprintf (err_str, sizeof (err_str), "Unable to get "
- "volume name");
- gf_log (this->name, GF_LOG_ERROR, "%s", err_str);
- goto out;
- }
- gf_log (this->name, GF_LOG_INFO,
- "Received status volume req for volume %s", volname);
-
- }
- if ((cmd & GF_CLI_STATUS_QUOTAD) &&
- (conf->op_version == GD_OP_VERSION_MIN)) {
- snprintf (err_str, sizeof (err_str), "The cluster is operating "
- "at version 1. Getting the status of quotad is not "
- "allowed in this state.");
- ret = -1;
- goto out;
- }
-
- if ((cmd & GF_CLI_STATUS_SNAPD) &&
- (conf->op_version < GD_OP_VERSION_3_6_0)) {
- snprintf (err_str, sizeof (err_str), "The cluster is operating "
- "at a lesser version than %d. Getting the status of "
- "snapd is not allowed in this state",
- GD_OP_VERSION_3_6_0);
- ret = -1;
- goto out;
- }
-
- ret = glusterd_op_begin_synctask (req, GD_OP_STATUS_VOLUME, dict);
-
-out:
-
- if (ret) {
- if (err_str[0] == '\0')
- snprintf (err_str, sizeof (err_str),
- "Operation failed");
- ret = glusterd_op_send_cli_response (cli_op, ret, 0, req,
- dict, err_str);
- }
- free (cli_req.dict.dict_val);
-
- return ret;
-}
-
-int
-glusterd_handle_status_volume (rpcsvc_request_t *req)
-{
- return glusterd_big_locked_handler (req,
- __glusterd_handle_status_volume);
-}
-
-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;
- char err_str[2048] = {0,};
- xlator_t *this = NULL;
-
- GF_ASSERT (req);
- this = THIS;
- GF_ASSERT (this);
-
- ret = -1;
- ret = xdr_to_generic (req->msg[0], &cli_req, (xdrproc_t)xdr_gf_cli_req);
- if (ret < 0) {
- 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");
- snprintf (err_str, sizeof (err_str), "unable to decode "
- "the command");
- 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) {
- snprintf (err_str, sizeof (err_str), "Unable to get volume "
- "name");
- gf_log (this->name, GF_LOG_ERROR, "%s", err_str);
- goto out;
- }
-
- gf_log (this->name, GF_LOG_INFO, "Received clear-locks volume req "
- "for volume %s", volname);
-
- ret = glusterd_op_begin_synctask (req, GD_OP_CLEARLOCKS_VOLUME, dict);
-
-out:
- if (ret) {
- if (err_str[0] == '\0')
- snprintf (err_str, sizeof (err_str),
- "Operation failed");
- ret = glusterd_op_send_cli_response (cli_op, ret, 0, req,
- dict, err_str);
- }
- free (cli_req.dict.dict_val);
-
- return ret;
-}
-
-int
-glusterd_handle_cli_clearlocks_volume (rpcsvc_request_t *req)
-{
- return glusterd_big_locked_handler (req,
- __glusterd_handle_cli_clearlocks_volume);
-}
-
-static int
-get_volinfo_from_brickid (char *brickid, glusterd_volinfo_t **volinfo)
-{
- int ret = -1;
- char *volid_str = NULL;
- char *brick = NULL;
- char *brickid_dup = NULL;
- uuid_t volid = {0};
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (brickid);
-
- brickid_dup = gf_strdup (brickid);
- if (!brickid_dup)
- goto out;
-
- volid_str = brickid_dup;
- brick = strchr (brickid_dup, ':');
- if (!brick) {
- gf_log (this->name, GF_LOG_ERROR,
- "Invalid brickid");
- goto out;
- }
-
- *brick = '\0';
- brick++;
- uuid_parse (volid_str, volid);
- ret = glusterd_volinfo_find_by_volume_id (volid, volinfo);
- if (ret) {
- /* Check if it is a snapshot volume */
- ret = glusterd_snap_volinfo_find_by_volume_id (volid, volinfo);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING,
- "Failed to find volinfo");
- goto out;
- }
- }
-
- ret = 0;
-out:
- GF_FREE (brickid_dup);
- return ret;
-}
-
-static int
-__glusterd_handle_barrier (rpcsvc_request_t *req)
-{
- int ret = -1;
- xlator_t *this = NULL;
- gf_cli_req cli_req = {{0,}};
- dict_t *dict = NULL;
- char *volname = NULL;
-
- GF_ASSERT (req);
- this = THIS;
- GF_ASSERT(this);
-
- ret = xdr_to_generic (req->msg[0], &cli_req, (xdrproc_t)xdr_gf_cli_req);
- if (ret < 0) {
- req->rpc_err = GARBAGE_ARGS;
- goto out;
- }
-
- if (!cli_req.dict.dict_len) {
- ret = -1;
- goto out;
- }
-
- dict = dict_new();
- if (!dict) {
- ret = -1;
- 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 "
- "request dictionary.");
- goto out;
- }
-
- ret = dict_get_str (dict, "volname", &volname);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Volname not present in "
- "dict");
- goto out;
- }
- gf_log (this->name, GF_LOG_INFO, "Received barrier volume request for "
- "volume %s", volname);
-
- ret = glusterd_op_begin_synctask (req, GD_OP_BARRIER, dict);
-
-out:
- if (ret) {
- ret = glusterd_op_send_cli_response (GD_OP_BARRIER, ret, 0, req,
- dict, "Operation failed");
- }
- free (cli_req.dict.dict_val);
- return ret;
-}
-
-int
-glusterd_handle_barrier (rpcsvc_request_t *req)
-{
- return glusterd_big_locked_handler (req, __glusterd_handle_barrier);
-}
-static int
-get_brickinfo_from_brickid (char *brickid, glusterd_brickinfo_t **brickinfo)
-{
- glusterd_volinfo_t *volinfo = NULL;
- char *volid_str = NULL;
- char *brick = NULL;
- char *brickid_dup = NULL;
- uuid_t volid = {0};
- int ret = -1;
-
- brickid_dup = gf_strdup (brickid);
- if (!brickid_dup)
- goto out;
-
- volid_str = brickid_dup;
- brick = strchr (brickid_dup, ':');
- if (!volid_str || !brick)
- goto out;
-
- *brick = '\0';
- brick++;
- uuid_parse (volid_str, volid);
- ret = glusterd_volinfo_find_by_volume_id (volid, &volinfo);
- if (ret) {
- /* Check if it a snapshot volume */
- ret = glusterd_snap_volinfo_find_by_volume_id (volid, &volinfo);
- if (ret)
- goto out;
- }
-
- ret = glusterd_volume_brickinfo_get_by_brick (brick, volinfo,
- brickinfo);
- if (ret)
- goto out;
-
- ret = 0;
-out:
- GF_FREE (brickid_dup);
- return ret;
-}
-
-int
-__glusterd_brick_rpc_notify (struct rpc_clnt *rpc, void *mydata,
- rpc_clnt_event_t event, void *data)
-{
- char *brickid = NULL;
- int ret = 0;
- glusterd_conf_t *conf = NULL;
- glusterd_brickinfo_t *brickinfo = NULL;
- glusterd_volinfo_t *volinfo = NULL;
- xlator_t *this = NULL;
-
- brickid = mydata;
- if (!brickid)
- return 0;
-
- ret = get_brickinfo_from_brickid (brickid, &brickinfo);
- if (ret)
- return 0;
-
- this = THIS;
- GF_ASSERT (this);
- conf = this->private;
- GF_ASSERT (conf);
-
- switch (event) {
- case RPC_CLNT_CONNECT:
- /* If a node on coming back up, already starts a brick
- * before the handshake, and the notification comes after
- * the handshake is done, then we need to check if this
- * is a restored brick with a snapshot pending. If so, we
- * need to stop the brick
- */
- if (brickinfo->snap_status == -1) {
- gf_log (this->name, GF_LOG_INFO,
- "Snapshot is pending on %s:%s. "
- "Hence not starting the brick",
- brickinfo->hostname,
- brickinfo->path);
- ret = get_volinfo_from_brickid (brickid, &volinfo);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to get volinfo from "
- "brickid(%s)", brickid);
- goto out;
- }
-
- ret = glusterd_brick_stop (volinfo, brickinfo,
- _gf_false);
- if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR,
- "Unable to stop %s:%s",
- brickinfo->hostname, brickinfo->path);
- goto out;
- }
-
- break;
- }
- gf_log (this->name, GF_LOG_DEBUG, "Connected to %s:%s",
- brickinfo->hostname, brickinfo->path);
- glusterd_set_brick_status (brickinfo, GF_BRICK_STARTED);
- ret = default_notify (this, GF_EVENT_CHILD_UP, NULL);
-
- break;
-
- case RPC_CLNT_DISCONNECT:
- if (glusterd_is_brick_started (brickinfo))
- gf_msg (this->name, GF_LOG_INFO, 0,
- GD_MSG_BRICK_DISCONNECTED,
- "Brick %s:%s has disconnected from glusterd.",
- brickinfo->hostname, brickinfo->path);
-
- glusterd_set_brick_status (brickinfo, GF_BRICK_STOPPED);
- break;
-
- case RPC_CLNT_DESTROY:
- GF_FREE (mydata);
- mydata = NULL;
- break;
- default:
- gf_log (this->name, GF_LOG_TRACE,
- "got some other RPC event %d", event);
- break;
- }
-
-out:
- return ret;
-}
-
-int
-glusterd_brick_rpc_notify (struct rpc_clnt *rpc, void *mydata,
- rpc_clnt_event_t event, void *data)
-{
- return glusterd_big_locked_notify (rpc, mydata, event, data,
- __glusterd_brick_rpc_notify);
-}
-
-int
-__glusterd_snapd_rpc_notify (struct rpc_clnt *rpc, void *mydata,
- rpc_clnt_event_t event, void *data)
-{
- xlator_t *this = NULL;
- glusterd_conf_t *conf = NULL;
- glusterd_volinfo_t *volinfo = NULL;
- int ret = 0;
-
- this = THIS;
- GF_ASSERT (this);
- conf = this->private;
- GF_ASSERT (conf);
-
- volinfo = mydata;
- if (!volinfo)
- return 0;
-
- switch (event) {
- case RPC_CLNT_CONNECT:
- gf_log (this->name, GF_LOG_DEBUG, "got RPC_CLNT_CONNECT");
-
- (void) glusterd_snapd_set_online_status (volinfo, _gf_true);
-
- break;
-
- case RPC_CLNT_DISCONNECT:
- if (glusterd_is_snapd_online (volinfo)) {
- gf_msg (this->name, GF_LOG_INFO, 0,
- GD_MSG_NODE_DISCONNECTED,
- "snapd for volume %s has disconnected from "
- "glusterd.", volinfo->volname);
-
- (void) glusterd_snapd_set_online_status
- (volinfo, _gf_false);
- }
- break;
-
- case RPC_CLNT_DESTROY:
- glusterd_volinfo_unref (volinfo);
- break;
-
- default:
- gf_log (this->name, GF_LOG_TRACE,
- "got some other RPC event %d", event);
- break;
- }
-
- return ret;
-}
-
-int
-glusterd_snapd_rpc_notify (struct rpc_clnt *rpc, void *mydata,
- rpc_clnt_event_t event, void *data)
-{
- return glusterd_big_locked_notify (rpc, mydata, event, data,
- __glusterd_snapd_rpc_notify);
-}
-
-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_online_status (server, _gf_true);
- ret = default_notify (this, GF_EVENT_CHILD_UP, NULL);
-
- break;
-
- case RPC_CLNT_DISCONNECT:
- if (glusterd_is_nodesvc_online (server)) {
- gf_msg (this->name, GF_LOG_INFO, 0, GD_MSG_NODE_DISCONNECTED,
- "%s has disconnected from glusterd.", server);
- (void) glusterd_nodesvc_set_online_status (server, _gf_false);
- }
- break;
-
- default:
- gf_log (this->name, GF_LOG_TRACE,
- "got some other RPC event %d", event);
- break;
- }
-
- return ret;
-}
-
-int
-glusterd_nodesvc_rpc_notify (struct rpc_clnt *rpc, void *mydata,
- rpc_clnt_event_t event, void *data)
-{
- return glusterd_big_locked_notify (rpc, mydata, event, data,
- __glusterd_nodesvc_rpc_notify);
-}
-
-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;
- dict_t *dict = NULL;
-
- GF_ASSERT (peerctx);
-
- peerinfo = peerctx->peerinfo;
- req = peerctx->args.req;
- dict = peerctx->args.dict;
- 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, dict);
-
- new_event->peerinfo = peerinfo;
- ret = glusterd_friend_sm_inject_event (new_event);
-
- } 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;
- gf_boolean_t quorum_action = _gf_false;
- glusterd_volinfo_t *volinfo = NULL;
- uuid_t uuid;
-
- peerctx = mydata;
- if (!peerctx)
- return 0;
-
- peerinfo = peerctx->peerinfo;
- this = THIS;
- conf = this->private;
-
- switch (event) {
- case RPC_CLNT_CONNECT:
- {
- rpc_clnt_set_connected (&rpc->conn);
- gf_log (this->name, GF_LOG_DEBUG, "got RPC_CLNT_CONNECT");
- peerinfo->connected = 1;
- peerinfo->quorum_action = _gf_true;
-
- ret = glusterd_peer_dump_version (this, rpc, peerctx);
- if (ret)
- gf_log ("", GF_LOG_ERROR, "glusterd handshake failed");
- break;
- }
-
- case RPC_CLNT_DISCONNECT:
- {
- rpc_clnt_unset_connected (&rpc->conn);
- gf_msg (this->name, GF_LOG_INFO, 0,
- GD_MSG_PEER_DISCONNECTED,
- "Peer %s, in %s state, has disconnected from glusterd.",
- uuid_utoa (peerinfo->uuid),
- glusterd_friend_sm_state_name_get (peerinfo->state.state));
-
- if (peerinfo->connected) {
- if (conf->op_version < GD_OP_VERSION_3_6_0) {
- glusterd_get_lock_owner (&uuid);
- if (!uuid_is_null (uuid) &&
- !uuid_compare (peerinfo->uuid, uuid))
- glusterd_unlock (peerinfo->uuid);
- } else {
- list_for_each_entry (volinfo, &conf->volumes,
- vol_list) {
- ret = glusterd_mgmt_v3_unlock
- (volinfo->volname,
- peerinfo->uuid,
- "vol");
- if (ret)
- gf_log (this->name,
- GF_LOG_TRACE,
- "Lock not released "
- "for %s",
- volinfo->volname);
- }
- }
-
- ret = 0;
- }
-
- if ((peerinfo->quorum_contrib != QUORUM_DOWN) &&
- (peerinfo->state.state == GD_FRIEND_STATE_BEFRIENDED)) {
- peerinfo->quorum_contrib = QUORUM_DOWN;
- quorum_action = _gf_true;
- peerinfo->quorum_action = _gf_false;
- }
-
- /* Remove peer if it is not a friend and connection/handshake
- * fails, and notify cli. Happens only during probe.
- */
- if (peerinfo->state.state == GD_FRIEND_STATE_DEFAULT) {
- glusterd_friend_remove_notify (peerctx);
- goto out;
- }
-
- peerinfo->connected = 0;
- break;
- }
- default:
- gf_log (this->name, GF_LOG_TRACE,
- "got some other RPC event %d", event);
- ret = 0;
- break;
- }
-
-out:
- glusterd_friend_sm ();
- glusterd_op_sm ();
- if (quorum_action)
- glusterd_do_quorum_action ();
- return ret;
-}
-
-int
-glusterd_peer_rpc_notify (struct rpc_clnt *rpc, void *mydata,
- rpc_clnt_event_t event, void *data)
-{
- return glusterd_big_locked_notify (rpc, mydata, event, data,
- __glusterd_peer_rpc_notify);
-}
-
-int
-glusterd_null (rpcsvc_request_t *req)
-{
-
- return 0;
-}
-
-rpcsvc_actor_t gd_svc_mgmt_actors[GLUSTERD_MGMT_MAXVALUE] = {
- [GLUSTERD_MGMT_NULL] = { "NULL", GLUSTERD_MGMT_NULL, glusterd_null, NULL, 0, DRC_NA},
- [GLUSTERD_MGMT_CLUSTER_LOCK] = { "CLUSTER_LOCK", GLUSTERD_MGMT_CLUSTER_LOCK, glusterd_handle_cluster_lock, NULL, 0, DRC_NA},
- [GLUSTERD_MGMT_CLUSTER_UNLOCK] = { "CLUSTER_UNLOCK", GLUSTERD_MGMT_CLUSTER_UNLOCK, glusterd_handle_cluster_unlock, NULL, 0, DRC_NA},
- [GLUSTERD_MGMT_STAGE_OP] = { "STAGE_OP", GLUSTERD_MGMT_STAGE_OP, glusterd_handle_stage_op, NULL, 0, DRC_NA},
- [GLUSTERD_MGMT_COMMIT_OP] = { "COMMIT_OP", GLUSTERD_MGMT_COMMIT_OP, glusterd_handle_commit_op, NULL, 0, DRC_NA},
-};
-
-struct rpcsvc_program gd_svc_mgmt_prog = {
- .progname = "GlusterD svc mgmt",
- .prognum = GD_MGMT_PROGRAM,
- .progver = GD_MGMT_VERSION,
- .numactors = GLUSTERD_MGMT_MAXVALUE,
- .actors = gd_svc_mgmt_actors,
- .synctask = _gf_true,
-};
-
-rpcsvc_actor_t gd_svc_peer_actors[GLUSTERD_FRIEND_MAXVALUE] = {
- [GLUSTERD_FRIEND_NULL] = { "NULL", GLUSTERD_MGMT_NULL, glusterd_null, NULL, 0, DRC_NA},
- [GLUSTERD_PROBE_QUERY] = { "PROBE_QUERY", GLUSTERD_PROBE_QUERY, glusterd_handle_probe_query, NULL, 0, DRC_NA},
- [GLUSTERD_FRIEND_ADD] = { "FRIEND_ADD", GLUSTERD_FRIEND_ADD, glusterd_handle_incoming_friend_req, NULL, 0, DRC_NA},
- [GLUSTERD_FRIEND_REMOVE] = { "FRIEND_REMOVE", GLUSTERD_FRIEND_REMOVE, glusterd_handle_incoming_unfriend_req, NULL, 0, DRC_NA},
- [GLUSTERD_FRIEND_UPDATE] = { "FRIEND_UPDATE", GLUSTERD_FRIEND_UPDATE, glusterd_handle_friend_update, NULL, 0, DRC_NA},
-};
-
-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,
- .synctask = _gf_false,
-};
-
-
-
-rpcsvc_actor_t gd_svc_cli_actors[GLUSTER_CLI_MAXVALUE] = {
- [GLUSTER_CLI_PROBE] = { "CLI_PROBE", GLUSTER_CLI_PROBE, glusterd_handle_cli_probe, NULL, 0, DRC_NA},
- [GLUSTER_CLI_CREATE_VOLUME] = { "CLI_CREATE_VOLUME", GLUSTER_CLI_CREATE_VOLUME, glusterd_handle_create_volume, NULL, 0, DRC_NA},
- [GLUSTER_CLI_DEFRAG_VOLUME] = { "CLI_DEFRAG_VOLUME", GLUSTER_CLI_DEFRAG_VOLUME, glusterd_handle_defrag_volume, NULL, 0, DRC_NA},
- [GLUSTER_CLI_DEPROBE] = { "FRIEND_REMOVE", GLUSTER_CLI_DEPROBE, glusterd_handle_cli_deprobe, NULL, 0, DRC_NA},
- [GLUSTER_CLI_LIST_FRIENDS] = { "LIST_FRIENDS", GLUSTER_CLI_LIST_FRIENDS, glusterd_handle_cli_list_friends, NULL, 0, DRC_NA},
- [GLUSTER_CLI_UUID_RESET] = { "UUID_RESET", GLUSTER_CLI_UUID_RESET, glusterd_handle_cli_uuid_reset, NULL, 0, DRC_NA},
- [GLUSTER_CLI_UUID_GET] = { "UUID_GET", GLUSTER_CLI_UUID_GET, glusterd_handle_cli_uuid_get, NULL, 0, DRC_NA},
- [GLUSTER_CLI_START_VOLUME] = { "START_VOLUME", GLUSTER_CLI_START_VOLUME, glusterd_handle_cli_start_volume, NULL, 0, DRC_NA},
- [GLUSTER_CLI_STOP_VOLUME] = { "STOP_VOLUME", GLUSTER_CLI_STOP_VOLUME, glusterd_handle_cli_stop_volume, NULL, 0, DRC_NA},
- [GLUSTER_CLI_DELETE_VOLUME] = { "DELETE_VOLUME", GLUSTER_CLI_DELETE_VOLUME, glusterd_handle_cli_delete_volume, NULL, 0, DRC_NA},
- [GLUSTER_CLI_GET_VOLUME] = { "GET_VOLUME", GLUSTER_CLI_GET_VOLUME, glusterd_handle_cli_get_volume, NULL, 0, DRC_NA},
- [GLUSTER_CLI_ADD_BRICK] = { "ADD_BRICK", GLUSTER_CLI_ADD_BRICK, glusterd_handle_add_brick, NULL, 0, DRC_NA},
- [GLUSTER_CLI_REPLACE_BRICK] = { "REPLACE_BRICK", GLUSTER_CLI_REPLACE_BRICK, glusterd_handle_replace_brick, NULL, 0, DRC_NA},
- [GLUSTER_CLI_REMOVE_BRICK] = { "REMOVE_BRICK", GLUSTER_CLI_REMOVE_BRICK, glusterd_handle_remove_brick, NULL, 0, DRC_NA},
- [GLUSTER_CLI_LOG_ROTATE] = { "LOG FILENAME", GLUSTER_CLI_LOG_ROTATE, glusterd_handle_log_rotate, NULL, 0, DRC_NA},
- [GLUSTER_CLI_SET_VOLUME] = { "SET_VOLUME", GLUSTER_CLI_SET_VOLUME, glusterd_handle_set_volume, NULL, 0, DRC_NA},
- [GLUSTER_CLI_SYNC_VOLUME] = { "SYNC_VOLUME", GLUSTER_CLI_SYNC_VOLUME, glusterd_handle_sync_volume, NULL, 0, DRC_NA},
- [GLUSTER_CLI_RESET_VOLUME] = { "RESET_VOLUME", GLUSTER_CLI_RESET_VOLUME, glusterd_handle_reset_volume, NULL, 0, DRC_NA},
- [GLUSTER_CLI_FSM_LOG] = { "FSM_LOG", GLUSTER_CLI_FSM_LOG, glusterd_handle_fsm_log, NULL, 0, DRC_NA},
- [GLUSTER_CLI_GSYNC_SET] = { "GSYNC_SET", GLUSTER_CLI_GSYNC_SET, glusterd_handle_gsync_set, NULL, 0, DRC_NA},
- [GLUSTER_CLI_PROFILE_VOLUME] = { "STATS_VOLUME", GLUSTER_CLI_PROFILE_VOLUME, glusterd_handle_cli_profile_volume, NULL, 0, DRC_NA},
- [GLUSTER_CLI_QUOTA] = { "QUOTA", GLUSTER_CLI_QUOTA, glusterd_handle_quota, NULL, 0, DRC_NA},
- [GLUSTER_CLI_GETWD] = { "GETWD", GLUSTER_CLI_GETWD, glusterd_handle_getwd, NULL, 1, DRC_NA},
- [GLUSTER_CLI_STATUS_VOLUME] = {"STATUS_VOLUME", GLUSTER_CLI_STATUS_VOLUME, glusterd_handle_status_volume, NULL, 0, DRC_NA},
- [GLUSTER_CLI_MOUNT] = { "MOUNT", GLUSTER_CLI_MOUNT, glusterd_handle_mount, NULL, 1, DRC_NA},
- [GLUSTER_CLI_UMOUNT] = { "UMOUNT", GLUSTER_CLI_UMOUNT, glusterd_handle_umount, NULL, 1, DRC_NA},
- [GLUSTER_CLI_HEAL_VOLUME] = { "HEAL_VOLUME", GLUSTER_CLI_HEAL_VOLUME, glusterd_handle_cli_heal_volume, NULL, 0, DRC_NA},
- [GLUSTER_CLI_STATEDUMP_VOLUME] = {"STATEDUMP_VOLUME", GLUSTER_CLI_STATEDUMP_VOLUME, glusterd_handle_cli_statedump_volume, NULL, 0, DRC_NA},
- [GLUSTER_CLI_LIST_VOLUME] = {"LIST_VOLUME", GLUSTER_CLI_LIST_VOLUME, glusterd_handle_cli_list_volume, NULL, 0, DRC_NA},
- [GLUSTER_CLI_CLRLOCKS_VOLUME] = {"CLEARLOCKS_VOLUME", GLUSTER_CLI_CLRLOCKS_VOLUME, glusterd_handle_cli_clearlocks_volume, NULL, 0, DRC_NA},
- [GLUSTER_CLI_COPY_FILE] = {"COPY_FILE", GLUSTER_CLI_COPY_FILE, glusterd_handle_copy_file, NULL, 0, DRC_NA},
- [GLUSTER_CLI_SYS_EXEC] = {"SYS_EXEC", GLUSTER_CLI_SYS_EXEC, glusterd_handle_sys_exec, NULL, 0, DRC_NA},
- [GLUSTER_CLI_SNAP] = {"SNAP", GLUSTER_CLI_SNAP, glusterd_handle_snapshot, NULL, 0, DRC_NA},
- [GLUSTER_CLI_BARRIER_VOLUME] = {"BARRIER_VOLUME", GLUSTER_CLI_BARRIER_VOLUME, glusterd_handle_barrier, NULL, 0, DRC_NA},
-};
-
-struct rpcsvc_program gd_svc_cli_prog = {
- .progname = "GlusterD svc cli",
- .prognum = GLUSTER_CLI_PROGRAM,
- .progver = GLUSTER_CLI_VERSION,
- .numactors = GLUSTER_CLI_MAXVALUE,
- .actors = gd_svc_cli_actors,
- .synctask = _gf_true,
-};
-
-/**
- * This set of RPC progs are deemed to be trusted. Most of the actors support
- * read only queries, the only exception being MOUNT/UMOUNT which is required
- * by geo-replication to supprt unprivileged master -> slave sessions.
- */
-rpcsvc_actor_t gd_svc_cli_trusted_actors[GLUSTER_CLI_MAXVALUE] = {
- [GLUSTER_CLI_LIST_FRIENDS] = { "LIST_FRIENDS", GLUSTER_CLI_LIST_FRIENDS, glusterd_handle_cli_list_friends, NULL, 0, DRC_NA},
- [GLUSTER_CLI_UUID_GET] = { "UUID_GET", GLUSTER_CLI_UUID_GET, glusterd_handle_cli_uuid_get, NULL, 0, DRC_NA},
- [GLUSTER_CLI_GET_VOLUME] = { "GET_VOLUME", GLUSTER_CLI_GET_VOLUME, glusterd_handle_cli_get_volume, NULL, 0, DRC_NA},
- [GLUSTER_CLI_GETWD] = { "GETWD", GLUSTER_CLI_GETWD, glusterd_handle_getwd, NULL, 1, DRC_NA},
- [GLUSTER_CLI_STATUS_VOLUME] = {"STATUS_VOLUME", GLUSTER_CLI_STATUS_VOLUME, glusterd_handle_status_volume, NULL, 0, DRC_NA},
- [GLUSTER_CLI_LIST_VOLUME] = {"LIST_VOLUME", GLUSTER_CLI_LIST_VOLUME, glusterd_handle_cli_list_volume, NULL, 0, DRC_NA},
- [GLUSTER_CLI_MOUNT] = { "MOUNT", GLUSTER_CLI_MOUNT, glusterd_handle_mount, NULL, 1, DRC_NA},
- [GLUSTER_CLI_UMOUNT] = { "UMOUNT", GLUSTER_CLI_UMOUNT, glusterd_handle_umount, NULL, 1, DRC_NA},
-};
-
-struct rpcsvc_program gd_svc_cli_trusted_progs = {
- .progname = "GlusterD svc cli read-only",
- .prognum = GLUSTER_CLI_PROGRAM,
- .progver = GLUSTER_CLI_VERSION,
- .numactors = GLUSTER_CLI_MAXVALUE,
- .actors = gd_svc_cli_trusted_actors,
- .synctask = _gf_true,
-};
diff --git a/xlators/mgmt/glusterd/src/glusterd-handshake.c b/xlators/mgmt/glusterd/src/glusterd-handshake.c
deleted file mode 100644
index 8414fa8e9bb..00000000000
--- a/xlators/mgmt/glusterd/src/glusterd-handshake.c
+++ /dev/null
@@ -1,2015 +0,0 @@
-/*
- Copyright (c) 2010-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 "xlator.h"
-#include "defaults.h"
-#include "glusterfs.h"
-#include "compat-errno.h"
-
-#include "glusterd.h"
-#include "glusterd-utils.h"
-#include "glusterd-op-sm.h"
-#include "glusterd-store.h"
-
-#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;
-extern struct rpc_clnt_program gd_mgmt_v3_prog;
-
-
-#define TRUSTED_PREFIX "trusted-"
-
-typedef ssize_t (*gfs_serialize_t) (struct iovec outmsg, void *data);
-
-static int
-get_snap_volname_and_volinfo (const char *volpath, char **volname,
- glusterd_volinfo_t **volinfo)
-{
- int ret = -1;
- char *save_ptr = NULL;
- char *str_token = NULL;
- char *snapname = NULL;
- char *volname_token = NULL;
- char *vol = NULL;
- glusterd_snap_t *snap = NULL;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (volpath);
- GF_ASSERT (volinfo);
-
- str_token = gf_strdup (volpath);
- if (NULL == str_token) {
- goto out;
- }
-
- /* Input volname will have below formats:
- * /snaps/<snapname>/<volname>.<hostname>
- * or
- * /snaps/<snapname>/<parent-volname>
- * We need to extract snapname and parent_volname */
-
- /*split string by "/" */
- strtok_r (str_token, "/", &save_ptr);
- snapname = strtok_r(NULL, "/", &save_ptr);
- if (!snapname) {
- gf_log(this->name, GF_LOG_ERROR, "Invalid path: %s", volpath);
- goto out;
- }
-
- volname_token = strtok_r(NULL, "/", &save_ptr);
- if (!volname_token) {
- gf_log(this->name, GF_LOG_ERROR, "Invalid path: %s", volpath);
- goto out;
- }
-
- snap = glusterd_find_snap_by_name (snapname);
- if (!snap) {
- gf_log(this->name, GF_LOG_ERROR, "Failed to "
- "fetch snap %s", snapname);
- goto out;
- }
-
- /* Find if its a parent volume name or snap volume
- * name. This function will succeed if volname_token
- * is a parent volname
- */
- ret = glusterd_volinfo_find (volname_token, volinfo);
- if (ret) {
- *volname = gf_strdup (volname_token);
- if (NULL == *volname) {
- ret = -1;
- goto out;
- }
-
- ret = glusterd_snap_volinfo_find (volname_token, snap,
- volinfo);
- if (ret) {
- /* Split the volume name */
- vol = strtok_r (volname_token, ".", &save_ptr);
- if (!vol) {
- gf_log(this->name, GF_LOG_ERROR, "Invalid "
- "volname (%s)", volname_token);
- goto out;
- }
-
- ret = glusterd_snap_volinfo_find (vol, snap, volinfo);
- if (ret) {
- gf_log(this->name, GF_LOG_ERROR, "Failed to "
- "fetch snap volume from volname (%s)",
- vol);
- goto out;
- }
- }
- } else {
- /*volname_token is parent volname*/
- ret = glusterd_snap_volinfo_find_from_parent_volname (
- volname_token, snap, volinfo);
- if (ret) {
- gf_log(this->name, GF_LOG_ERROR, "Failed to "
- "fetch snap volume from parent "
- "volname (%s)", volname_token);
- goto out;
- }
-
- /* Since volname_token is a parent volname we should
- * get the snap volname here*/
- *volname = gf_strdup ((*volinfo)->volname);
- if (NULL == *volname) {
- ret = -1;
- goto out;
- }
- }
-
-out:
- if (ret && NULL != *volname) {
- GF_FREE (*volname);
- *volname = NULL;
- }
- return ret;
-}
-
-static size_t
-build_volfile_path (char *volume_id, char *path,
- size_t path_len, char *trusted_str)
-{
- struct stat stbuf = {0,};
- int32_t ret = -1;
- char *vol = NULL;
- char *dup_volname = NULL;
- char *save_ptr = NULL;
- char *free_ptr = NULL;
- char *volname = NULL;
- char *volid_ptr = NULL;
- char dup_volid[PATH_MAX] = {0,};
- char path_prefix[PATH_MAX] = {0,};
- xlator_t *this = NULL;
- glusterd_volinfo_t *volinfo = NULL;
- glusterd_conf_t *priv = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- priv = this->private;
- GF_ASSERT (priv);
- GF_ASSERT (volume_id);
- GF_ASSERT (path);
-
- volid_ptr = strstr (volume_id, "snapd/");
- if (volid_ptr) {
- volid_ptr = strchr (volid_ptr, '/');
- if (!volid_ptr) {
- ret = -1;
- goto out;
- }
- volid_ptr++;
-
- ret = glusterd_volinfo_find (volid_ptr, &volinfo);
- if (ret == -1) {
- gf_log (this->name, GF_LOG_ERROR,
- "Couldn't find volinfo");
- goto out;
- }
- glusterd_get_snapd_volfile (volinfo, path, path_len);
- ret = 0;
- goto out;
-
- }
-
- volid_ptr = strstr (volume_id, "gluster/");
- if (volid_ptr) {
- volid_ptr = strchr (volid_ptr, '/');
- if (!volid_ptr) {
- ret = -1;
- goto out;
- }
- volid_ptr++;
-
- glusterd_get_nodesvc_volfile (volid_ptr, priv->workdir,
- path, path_len);
- ret = 0;
- goto out;
-
- }
-
- volid_ptr = strstr (volume_id, "/snaps/");
- if (volid_ptr) {
- ret = get_snap_volname_and_volinfo (volid_ptr, &volname,
- &volinfo);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to get snap"
- " volinfo from path (%s)", volume_id);
- ret = -1;
- goto out;
- }
-
- snprintf (path_prefix, sizeof (path_prefix), "%s/snaps/%s",
- priv->workdir, volinfo->snapshot->snapname);
-
- volid_ptr = volname;
- /* this is to ensure that volname recvd from
- get_snap_volname_and_volinfo is free'd */
- free_ptr = volname;
- goto gotvolinfo;
-
- }
-
- volid_ptr = strstr (volume_id, "rebalance/");
- if (volid_ptr) {
- volid_ptr = strchr (volid_ptr, '/');
- if (!volid_ptr) {
- ret = -1;
- goto out;
- }
- volid_ptr++;
-
- ret = glusterd_volinfo_find (volid_ptr, &volinfo);
- if (ret == -1) {
- gf_log (this->name, GF_LOG_ERROR,
- "Couldn't find volinfo");
- goto out;
- }
- glusterd_get_rebalance_volfile (volinfo, path, path_len);
- ret = 0;
- goto out;
- }
-
- if (volume_id[0] == '/') {
- /* Normal behavior */
- volid_ptr = volume_id;
- volid_ptr++;
-
- } else {
- /* Bringing in NFS like behavior for mount command, */
- /* With this, one can mount a volume with below cmd */
- /* bash# mount -t glusterfs server:/volume /mnt/pnt */
- volid_ptr = volume_id;
- }
-
- snprintf (path_prefix, sizeof (path_prefix), "%s/vols",
- priv->workdir);
-
- ret = glusterd_volinfo_find (volid_ptr, &volinfo);
-
- if (ret) {
- dup_volname = gf_strdup (volid_ptr);
- if (!dup_volname) {
- ret = -1;
- goto out;
- }
- /* Split the volume name */
- vol = strtok_r (dup_volname, ".", &save_ptr);
- if (!vol) {
- ret = -1;
- goto out;
- }
- ret = glusterd_volinfo_find (vol, &volinfo);
- if (ret)
- goto out;
- }
-
-gotvolinfo:
- if (!glusterd_auth_get_username (volinfo))
- trusted_str = NULL;
-
- ret = snprintf (path, path_len, "%s/%s/%s.vol", path_prefix,
- volinfo->volname, volid_ptr);
- if (ret == -1)
- goto out;
-
- ret = stat (path, &stbuf);
-
- if ((ret == -1) && (errno == ENOENT)) {
- strcpy (dup_volid, volid_ptr);
- if (!strchr (dup_volid, '.')) {
- switch (volinfo->transport_type) {
- case GF_TRANSPORT_TCP:
- strcat (dup_volid, ".tcp");
- break;
- case GF_TRANSPORT_RDMA:
- strcat (dup_volid, ".rdma");
- break;
- case GF_TRANSPORT_BOTH_TCP_RDMA:
- strcat (dup_volid, ".tcp");
- break;
- default:
- ret = -1;
- break;
- }
- }
- snprintf (path, path_len, "%s/%s/%s%s-fuse.vol",
- path_prefix, volinfo->volname,
- (trusted_str ? trusted_str : ""),
- dup_volid);
- ret = stat (path, &stbuf);
- }
-out:
- if (dup_volname)
- GF_FREE (dup_volname);
- if (free_ptr)
- GF_FREE (free_ptr);
- return ret;
-}
-
-/* Get and store op-versions of the clients sending the getspec request
- * Clients of versions <= 3.3, don't send op-versions, their op-versions are
- * defaulted to 1. Also fetch brick_name.
- */
-int32_t
-glusterd_get_args_from_dict (gf_getspec_req *args, peer_info_t *peerinfo,
- char **brick_name)
-{
- dict_t *dict = NULL;
- int client_max_op_version = 1;
- int client_min_op_version = 1;
- int32_t ret = -1;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (args);
- GF_ASSERT (peerinfo);
-
- if (!args->xdata.xdata_len) {
- ret = 0;
- goto out;
- }
-
- dict = dict_new ();
- if (!dict) {
- ret = -1;
- goto out;
- }
-
- ret = dict_unserialize (args->xdata.xdata_val,
- args->xdata.xdata_len, &dict);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to unserialize request dictionary");
- goto out;
- }
-
- ret = dict_get_int32 (dict, "min-op-version",
- &client_min_op_version);
- if (ret) {
- gf_log ("glusterd", GF_LOG_ERROR,
- "Failed to get client-min-op-version");
- goto out;
- }
-
- ret = dict_get_int32 (dict, "max-op-version",
- &client_max_op_version);
- if (ret) {
- gf_log ("glusterd", GF_LOG_ERROR,
- "Failed to get client-max-op-version");
- goto out;
- }
-
- ret = dict_get_str (dict, "brick_name",
- brick_name);
- if (ret) {
- gf_log (this->name, GF_LOG_DEBUG,
- "No brick name present");
- ret = 0;
- goto out;
- }
-
- gf_log (this->name, GF_LOG_DEBUG, "brick_name = %s", *brick_name);
-out:
- peerinfo->max_op_version = client_max_op_version;
- peerinfo->min_op_version = client_min_op_version;
-
- return ret;
-}
-
-/* Given the missed_snapinfo and snap_opinfo take the
- * missed lvm snapshot
- */
-int32_t
-glusterd_create_missed_snap (glusterd_missed_snap_info *missed_snapinfo,
- glusterd_snap_op_t *snap_opinfo)
-{
- char *device = NULL;
- glusterd_conf_t *priv = NULL;
- glusterd_snap_t *snap = NULL;
- glusterd_volinfo_t *snap_vol = NULL;
- glusterd_volinfo_t *volinfo = NULL;
- glusterd_brickinfo_t *brickinfo = NULL;
- int32_t ret = -1;
- int32_t i = 0;
- uuid_t snap_uuid = {0,};
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- priv = this->private;
- GF_ASSERT (priv);
- GF_ASSERT (missed_snapinfo);
- GF_ASSERT (snap_opinfo);
-
- uuid_parse (missed_snapinfo->snap_uuid, snap_uuid);
-
- /* Find the snap-object */
- snap = glusterd_find_snap_by_id (snap_uuid);
- if (!snap) {
- gf_log (this->name, GF_LOG_ERROR,
- "Unable to find the snap with snap_uuid %s",
- missed_snapinfo->snap_uuid);
- ret = -1;
- goto out;
- }
-
- /* Find the snap_vol */
- list_for_each_entry (volinfo, &snap->volumes, vol_list) {
- if (!strcmp (volinfo->volname,
- snap_opinfo->snap_vol_id)) {
- snap_vol = volinfo;
- break;
- }
- }
-
- if (!snap_vol) {
- gf_log (this->name, GF_LOG_ERROR,
- "Unable to find the snap_vol(%s) "
- "for snap(%s)", snap_opinfo->snap_vol_id,
- snap->snapname);
- ret = -1;
- goto out;
- }
-
- /* Find the missed brick in the snap volume */
- list_for_each_entry (brickinfo, &snap_vol->bricks, brick_list) {
- i++;
- if (i == snap_opinfo->brick_num)
- break;
- }
-
- if (brickinfo->snap_status != -1) {
- gf_log (this->name, GF_LOG_ERROR,
- "The snap status of the missed "
- "brick(%s) is not pending", brickinfo->path);
- goto out;
- }
-
- /* Fetch the device path */
- device = glusterd_get_brick_mount_device (snap_opinfo->brick_path);
- if (!device) {
- gf_log (this->name, GF_LOG_ERROR, "Getting device name for the"
- "brick %s:%s failed", brickinfo->hostname,
- snap_opinfo->brick_path);
- ret = -1;
- goto out;
- }
-
- device = glusterd_build_snap_device_path (device, snap_vol->volname,
- snap_opinfo->brick_num - 1);
- if (!device) {
- gf_log (this->name, GF_LOG_ERROR, "cannot copy the snapshot "
- "device name (volname: %s, snapname: %s)",
- snap_vol->volname, snap->snapname);
- ret = -1;
- goto out;
- }
- strncpy (brickinfo->device_path, device,
- sizeof(brickinfo->device_path));
-
- /* Update the backend file-system type of snap brick in
- * snap volinfo. */
- ret = glusterd_update_mntopts (snap_opinfo->brick_path, brickinfo);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to update "
- "mount options for %s brick", brickinfo->path);
- /* We should not fail snapshot operation if we fail to get
- * the file-system type */
- }
-
- ret = glusterd_take_lvm_snapshot (brickinfo, snap_opinfo->brick_path);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to take snapshot of %s",
- snap_opinfo->brick_path);
- goto out;
- }
-
- /* After the snapshot both the origin brick (LVM brick) and
- * the snapshot brick will have the same file-system label. This
- * will cause lot of problems at mount time. Therefore we must
- * generate a new label for the snapshot brick
- */
- ret = glusterd_update_fs_label (brickinfo);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to update "
- "file-system label for %s brick", brickinfo->path);
- /* Failing to update label should not cause snapshot failure.
- * Currently label is updated only for XFS and ext2/ext3/ext4
- * file-system.
- */
- }
-
- /* Create and mount the snap brick */
- ret = glusterd_snap_brick_create (snap_vol, brickinfo,
- snap_opinfo->brick_num - 1);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to "
- " create and mount the brick(%s) for the snap %s",
- snap_opinfo->brick_path,
- snap_vol->snapshot->snapname);
- goto out;
- }
-
- brickinfo->snap_status = 0;
- ret = glusterd_store_volinfo (snap_vol,
- GLUSTERD_VOLINFO_VER_AC_NONE);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to store snapshot "
- "volinfo (%s) for snap %s", snap_vol->volname,
- snap->snapname);
- goto out;
- }
-
- ret = glusterd_brick_start (snap_vol, brickinfo, _gf_false);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING, "starting the "
- "brick %s:%s for the snap %s failed",
- brickinfo->hostname, brickinfo->path,
- snap->snapname);
- goto out;
- }
-out:
- if (device)
- GF_FREE (device);
-
- return ret;
-}
-
-/* Look into missed_snap_list, to see it the given brick_name,
- * has any missed snap creates for the local node */
-int32_t
-glusterd_take_missing_brick_snapshots (char *brick_name)
-{
- char *my_node_uuid = NULL;
- glusterd_conf_t *priv = NULL;
- glusterd_missed_snap_info *missed_snapinfo = NULL;
- glusterd_snap_op_t *snap_opinfo = NULL;
- int32_t ret = -1;
- gf_boolean_t update_list = _gf_false;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- priv = this->private;
- GF_ASSERT (priv);
- GF_ASSERT (brick_name);
-
- my_node_uuid = uuid_utoa (MY_UUID);
-
- list_for_each_entry (missed_snapinfo, &priv->missed_snaps_list,
- missed_snaps) {
- /* If the missed snap op is not for the local node
- * then continue
- */
- if (strcmp (my_node_uuid, missed_snapinfo->node_uuid))
- continue;
-
- list_for_each_entry (snap_opinfo, &missed_snapinfo->snap_ops,
- snap_ops_list) {
- /* Check if the missed snap's op is a create for
- * the brick name in question
- */
- if ((snap_opinfo->op == GF_SNAP_OPTION_TYPE_CREATE) &&
- (!strcmp (brick_name, snap_opinfo->brick_path))) {
- /* Perform a snap create if the
- * op is still pending
- */
- if (snap_opinfo->status ==
- GD_MISSED_SNAP_PENDING) {
- ret = glusterd_create_missed_snap
- (missed_snapinfo,
- snap_opinfo);
- if (ret) {
- gf_log (this->name,
- GF_LOG_ERROR,
- "Failed to create "
- "missed snap for %s",
- brick_name);
- /* At this stage, we will mark
- * the entry as done. Because
- * of the failure other
- * snapshots will not be
- * affected, and neither the
- * brick. Only the current snap
- * brick will always remain as
- * pending.
- */
- }
- snap_opinfo->status =
- GD_MISSED_SNAP_DONE;
- update_list = _gf_true;
- }
- /* One snap-id won't have more than one missed
- * create for the same brick path. Hence
- * breaking in search of another missed create
- * for the same brick path in the local node
- */
- break;
- }
- }
- }
-
- if (update_list == _gf_true) {
- ret = glusterd_store_update_missed_snaps ();
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to update missed_snaps_list");
- goto out;
- }
- }
-
- ret = 0;
-out:
- return ret;
-}
-
-/* Checks if the client supports the volume, ie. client can understand all the
- * options in the volfile
- */
-static gf_boolean_t
-_client_supports_volume (peer_info_t *peerinfo, int32_t *op_errno)
-{
- gf_boolean_t ret = _gf_true;
- glusterd_volinfo_t *volinfo = NULL;
-
- GF_ASSERT (peerinfo);
- GF_ASSERT (op_errno);
-
-
- /* Only check when the volfile being requested is a volume. Not finding
- * a volinfo implies that the volfile requested for is not of a gluster
- * volume. A non volume volfile is requested by the local gluster
- * services like shd and nfs-server. These need not be checked as they
- * will be running at the same op-version as glusterd and will be able
- * to support all the features
- */
- if ((glusterd_volinfo_find (peerinfo->volname, &volinfo) == 0) &&
- ((peerinfo->min_op_version > volinfo->client_op_version) ||
- (peerinfo->max_op_version < volinfo->client_op_version))) {
- ret = _gf_false;
- *op_errno = ENOTSUP;
- gf_log ("glusterd", GF_LOG_INFO,
- "Client %s (%d -> %d) doesn't support required "
- "op-version (%d). Rejecting volfile request.",
- peerinfo->identifier, peerinfo->min_op_version,
- peerinfo->max_op_version, volinfo->client_op_version);
- }
-
- return ret;
-}
-
-int
-__server_getspec (rpcsvc_request_t *req)
-{
- int32_t ret = -1;
- int32_t op_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 *brick_name = NULL;
- 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};
- peer_info_t *peerinfo = NULL;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
-
- ret = xdr_to_generic (req->msg[0], &args,
- (xdrproc_t)xdr_gf_getspec_req);
- if (ret < 0) {
- //failed to decode msg;
- req->rpc_err = GARBAGE_ARGS;
- goto fail;
- }
-
- peerinfo = &req->trans->peerinfo;
-
- volume = args.key;
- /* Need to strip leading '/' from volnames. This was introduced to
- * support nfs style mount parameters for native gluster mount
- */
- if (volume[0] == '/')
- strncpy (peerinfo->volname, &volume[1], strlen(&volume[1]));
- else
- strncpy (peerinfo->volname, volume, strlen(volume));
-
- ret = glusterd_get_args_from_dict (&args, peerinfo, &brick_name);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to get args from dict");
- goto fail;
- }
-
- if (!_client_supports_volume (peerinfo, &op_errno)) {
- ret = -1;
- goto fail;
- }
-
- trans = req->trans;
- /* addrstr will be empty for cli socket connections */
- ret = rpcsvc_transport_peername (trans, (char *)&addrstr,
- sizeof (addrstr));
- if (ret)
- goto fail;
-
- tmp = strrchr (addrstr, ':');
- if (tmp)
- *tmp = '\0';
-
- /* The trusted volfiles are given to the glusterd owned process like NFS
- * server, self-heal daemon etc., so that they are not inadvertently
- * blocked by a auth.{allow,reject} setting. The trusted volfile is not
- * meant for external users.
- */
- if (strlen (addrstr) && gf_is_local_addr (addrstr)) {
-
- ret = build_volfile_path (volume, filename,
- sizeof (filename),
- TRUSTED_PREFIX);
- } else {
- ret = build_volfile_path (volume, filename,
- sizeof (filename), NULL);
- }
-
- if (ret == 0) {
- /* to allocate the proper buffer to hold the file data */
- ret = stat (filename, &stbuf);
- if (ret < 0){
- gf_log ("glusterd", 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 ("glusterd", GF_LOG_ERROR,
- "Unable to open %s (%s)",
- filename, strerror (errno));
- goto fail;
- }
- ret = file_len = stbuf.st_size;
- } else {
- op_errno = ENOENT;
- goto fail;
- }
-
- if (file_len) {
- rsp.spec = CALLOC (file_len+1, sizeof (char));
- if (!rsp.spec) {
- ret = -1;
- op_errno = ENOMEM;
- goto fail;
- }
- ret = read (spec_fd, rsp.spec, file_len);
- }
-
- if (brick_name) {
- gf_log (this->name, GF_LOG_DEBUG,
- "Look for missing snap creates for %s", brick_name);
- op_ret = glusterd_take_missing_brick_snapshots (brick_name);
- if (op_ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to take missing brick snapshots");
- ret = -1;
- goto fail;
- }
- }
-
- /* convert to XDR */
-fail:
- if (spec_fd > 0)
- close (spec_fd);
-
- rsp.op_ret = ret;
-
- if (op_errno)
- rsp.op_errno = gf_errno_to_error (op_errno);
- if (cookie)
- rsp.op_errno = cookie;
-
- if (!rsp.spec)
- rsp.spec = strdup ("");
-
- glusterd_submit_reply (req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gf_getspec_rsp);
- free (args.key);//malloced by xdr
- free (rsp.spec);
-
- return 0;
-}
-
-int
-server_getspec (rpcsvc_request_t *req)
-{
- return glusterd_big_locked_handler (req, __server_getspec);
-}
-
-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;
-
- ret = xdr_to_generic (req->msg[0], &args,
- (xdrproc_t)xdr_gf_event_notify_req);
- if (ret < 0) {
- 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,
- "received defrag status updated");
- if (dict) {
- glusterd_defrag_event_notify_handle (dict);
- need_rsp = _gf_false;
- }
- break;
- default:
- gf_log ("", GF_LOG_ERROR, "Unknown op received 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;
-}
-
-int32_t
-server_event_notify (rpcsvc_request_t *req)
-{
- return glusterd_big_locked_handler (req, __server_event_notify);
-}
-
-int
-gd_validate_cluster_op_version (xlator_t *this, int cluster_op_version,
- char *peerid)
-{
- int ret = -1;
- glusterd_conf_t *conf = NULL;
-
- conf = this->private;
-
- if (cluster_op_version > GD_OP_VERSION_MAX) {
- gf_log (this->name, GF_LOG_ERROR,
- "operating version %d is more than the maximum "
- "supported (%d) on the machine (as per peer request "
- "from %s)", cluster_op_version, GD_OP_VERSION_MAX,
- peerid);
- goto out;
- }
-
- /* The peer can only reduce its op-version when it doesn't have any
- * volumes. Reducing op-version when it already contains volumes can
- * lead to inconsistencies in the cluster
- */
- if ((cluster_op_version < conf->op_version) &&
- !list_empty (&conf->volumes)) {
- gf_log (this->name, GF_LOG_ERROR,
- "cannot reduce operating version to %d from current "
- "version %d as volumes exist (as per peer request from "
- "%s)", cluster_op_version, conf->op_version, peerid);
- goto out;
- }
-
- ret = 0;
-out:
- return ret;
-}
-
-/* Validate if glusterd can serve the management handshake request
- *
- * Requests are allowed if,
- * - glusterd has no peers, or
- * - the request came from a known peer
- */
-gf_boolean_t
-gd_validate_mgmt_hndsk_req (rpcsvc_request_t *req)
-{
- int ret = -1;
- char hostname[UNIX_PATH_MAX + 1] = {0,};
- glusterd_peerinfo_t *peer = NULL;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
-
- if (!glusterd_have_peers ())
- return _gf_true;
-
- /* If you cannot get the hostname, you cannot authenticate */
- ret = glusterd_remote_hostname_get (req, hostname, sizeof (hostname));
- if (ret)
- return _gf_false;
-
- peer = glusterd_peerinfo_find (NULL, hostname);
- if (peer == NULL) {
- ret = -1;
- gf_log (this->name, GF_LOG_ERROR, "Rejecting management "
- "handshake request from unknown peer %s",
- req->trans->peerinfo.identifier);
- return _gf_false;
- }
-
- return _gf_true;
-}
-
-int
-__glusterd_mgmt_hndsk_versions (rpcsvc_request_t *req)
-{
- dict_t *dict = NULL;
- xlator_t *this = NULL;
- glusterd_conf_t *conf = NULL;
- int ret = -1;
- int op_errno = EINVAL;
- gf_mgmt_hndsk_req args = {{0,},};
- gf_mgmt_hndsk_rsp rsp = {0,};
-
- this = THIS;
- conf = this->private;
-
- /* Check if we can service the request */
- if (!gd_validate_mgmt_hndsk_req (req)) {
- ret = -1;
- goto out;
- }
-
- ret = xdr_to_generic (req->msg[0], &args,
- (xdrproc_t)xdr_gf_mgmt_hndsk_req);
- if (ret < 0) {
- //failed to decode msg;
- req->rpc_err = GARBAGE_ARGS;
- goto out;
- }
-
- dict = dict_new ();
- if (!dict)
- goto out;
-
- ret = dict_set_int32 (dict, GD_OP_VERSION_KEY, conf->op_version);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING,
- "failed to set operating version");
- rsp.op_ret = ret;
- goto out;
- }
-
- ret = dict_set_int32 (dict, GD_MIN_OP_VERSION_KEY, GD_OP_VERSION_MIN);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING,
- "failed to set %s", GD_MIN_OP_VERSION_KEY);
- rsp.op_ret = ret;
- goto out;
- }
-
- ret = dict_set_int32 (dict, GD_MAX_OP_VERSION_KEY, GD_OP_VERSION_MAX);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING,
- "failed to set %s", GD_MAX_OP_VERSION_KEY);
- rsp.op_ret = ret;
- goto out;
- }
-
- ret = 0;
-
- GF_PROTOCOL_DICT_SERIALIZE (this, dict, (&rsp.hndsk.hndsk_val),
- rsp.hndsk.hndsk_len, op_errno, out);
-out:
-
- rsp.op_ret = ret;
- rsp.op_errno = op_errno;
-
- glusterd_submit_reply (req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gf_mgmt_hndsk_rsp);
-
- ret = 0;
-
- if (dict)
- dict_unref (dict);
-
- if (args.hndsk.hndsk_val)
- free (args.hndsk.hndsk_val);
-
- if (rsp.hndsk.hndsk_val)
- GF_FREE (rsp.hndsk.hndsk_val);
-
- return ret;
-}
-
-int
-glusterd_mgmt_hndsk_versions (rpcsvc_request_t *req)
-{
- return glusterd_big_locked_handler (req,
- __glusterd_mgmt_hndsk_versions);
-}
-
-int
-__glusterd_mgmt_hndsk_versions_ack (rpcsvc_request_t *req)
-{
- dict_t *clnt_dict = NULL;
- xlator_t *this = NULL;
- glusterd_conf_t *conf = NULL;
- int ret = -1;
- int op_errno = EINVAL;
- int peer_op_version = 0;
- gf_mgmt_hndsk_req args = {{0,},};
- gf_mgmt_hndsk_rsp rsp = {0,};
-
- this = THIS;
- conf = this->private;
-
- /* Check if we can service the request */
- if (!gd_validate_mgmt_hndsk_req (req)) {
- ret = -1;
- goto out;
- }
-
- ret = xdr_to_generic (req->msg[0], &args,
- (xdrproc_t)xdr_gf_mgmt_hndsk_req);
- if (ret < 0) {
- //failed to decode msg;
- req->rpc_err = GARBAGE_ARGS;
- goto out;
- }
-
- GF_PROTOCOL_DICT_UNSERIALIZE (this, clnt_dict, args.hndsk.hndsk_val,
- (args.hndsk.hndsk_len), ret, op_errno,
- out);
-
- ret = dict_get_int32 (clnt_dict, GD_OP_VERSION_KEY, &peer_op_version);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING,
- "failed to get the op-version key peer=%s",
- req->trans->peerinfo.identifier);
- goto out;
- }
-
- ret = gd_validate_cluster_op_version (this, peer_op_version,
- req->trans->peerinfo.identifier);
- if (ret)
- goto out;
-
-
- /* As this is ACK from the Cluster for the versions supported,
- can set the op-version of 'this' glusterd to the one
- received. */
- gf_log (this->name, GF_LOG_INFO, "using the op-version %d",
- peer_op_version);
- conf->op_version = peer_op_version;
- ret = glusterd_store_global_info (this);
- if (ret)
- gf_log (this->name, GF_LOG_ERROR, "Failed to store op-version");
-
-out:
- rsp.op_ret = ret;
- rsp.op_errno = op_errno;
-
- glusterd_submit_reply (req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gf_mgmt_hndsk_rsp);
-
- ret = 0;
-
- if (clnt_dict)
- dict_unref (clnt_dict);
-
- if (args.hndsk.hndsk_val)
- free (args.hndsk.hndsk_val);
-
- return ret;
-}
-
-int
-glusterd_mgmt_hndsk_versions_ack (rpcsvc_request_t *req)
-{
- return glusterd_big_locked_handler (req,
- __glusterd_mgmt_hndsk_versions_ack);
-}
-
-int
-__server_get_volume_info (rpcsvc_request_t *req)
-{
- int ret = -1;
- int32_t op_errno = ENOENT;
- gf_get_volume_info_req vol_info_req = {{0,}};
- gf_get_volume_info_rsp vol_info_rsp = {0,};
- char *volname = NULL;
- glusterd_volinfo_t *volinfo = NULL;
- dict_t *dict = NULL;
- dict_t *dict_rsp = NULL;
- char *volume_id_str = NULL;
- int32_t flags = 0;
-
- ret = xdr_to_generic (req->msg[0], &vol_info_req,
- (xdrproc_t)xdr_gf_get_volume_info_req);
- if (ret < 0) {
- /* failed to decode msg */
- req->rpc_err = GARBAGE_ARGS;
- goto out;
- }
- gf_log ("glusterd", GF_LOG_INFO, "Received get volume info req");
-
- if (vol_info_req.dict.dict_len) {
- /* Unserialize the dictionary */
- dict = dict_new ();
- if (!dict) {
- gf_log ("", GF_LOG_WARNING, "Out of Memory");
- op_errno = ENOMEM;
- ret = -1;
- goto out;
- }
-
- ret = dict_unserialize (vol_info_req.dict.dict_val,
- vol_info_req.dict.dict_len,
- &dict);
- if (ret < 0) {
- gf_log ("glusterd", GF_LOG_ERROR,
- "failed to "
- "unserialize req-buffer to dictionary");
- op_errno = -ret;
- ret = -1;
- goto out;
- } else {
- dict->extra_stdfree = vol_info_req.dict.dict_val;
- }
- }
-
- ret = dict_get_int32 (dict, "flags", &flags);
- if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR, "failed to get flags");
- op_errno = -ret;
- ret = -1;
- goto out;
- }
-
- if (!flags) {
- /* Nothing to query about. Just return success */
- gf_log (THIS->name, GF_LOG_ERROR, "No flags set");
- ret = 0;
- goto out;
- }
-
- ret = dict_get_str (dict, "volname", &volname);
- if (ret) {
- op_errno = EINVAL;
- ret = -1;
- goto out;
- }
-
- ret = glusterd_volinfo_find (volname, &volinfo);
- if (ret) {
- op_errno = EINVAL;
- ret = -1;
- goto out;
- }
-
- if (flags | (int32_t)GF_GET_VOLUME_UUID) {
- volume_id_str = gf_strdup (uuid_utoa (volinfo->volume_id));
- if (!volume_id_str) {
- op_errno = ENOMEM;
- ret = -1;
- goto out;
- }
-
- dict_rsp = dict_new ();
- if (!dict_rsp) {
- gf_log ("", GF_LOG_WARNING, "Out of Memory");
- op_errno = ENOMEM;
- ret = -1;
- goto out;
- }
- ret = dict_set_dynstr (dict_rsp, "volume_id", volume_id_str);
- if (ret) {
- op_errno = -ret;
- ret = -1;
- goto out;
- }
- }
- ret = dict_allocate_and_serialize (dict_rsp, &vol_info_rsp.dict.dict_val,
- &vol_info_rsp.dict.dict_len);
- if (ret) {
- op_errno = -ret;
- ret = -1;
- goto out;
- }
-
-out:
- vol_info_rsp.op_ret = ret;
- vol_info_rsp.op_errno = op_errno;
- vol_info_rsp.op_errstr = "";
- glusterd_submit_reply (req, &vol_info_rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gf_get_volume_info_rsp);
- ret = 0;
-
- if (dict) {
- dict_unref (dict);
- }
-
- if (dict_rsp) {
- dict_unref (dict_rsp);
- }
-
- if (vol_info_rsp.dict.dict_val) {
- GF_FREE (vol_info_rsp.dict.dict_val);
- }
- return ret;
-}
-
-int
-server_get_volume_info (rpcsvc_request_t *req)
-{
- return glusterd_big_locked_handler (req,
- __server_get_volume_info);
-}
-
-
-/*
- * glusterd function to get the list of snapshot names and uuids
- */
-int
-__server_get_snap_info (rpcsvc_request_t *req)
-{
- int ret = -1;
- int op_errno = ENOENT;
- gf_getsnap_name_uuid_req snap_info_req = {{0,}};
- gf_getsnap_name_uuid_rsp snap_info_rsp = {0,};
- dict_t *dict = NULL;
- dict_t *dict_rsp = NULL;
- glusterd_volinfo_t *volinfo = NULL;
- char *volname = NULL;
-
- GF_ASSERT (req);
-
- ret = xdr_to_generic (req->msg[0], &snap_info_req,
- (xdrproc_t)xdr_gf_getsnap_name_uuid_req);
- if (ret < 0) {
- req->rpc_err = GARBAGE_ARGS;
- gf_log ("glusterd", GF_LOG_ERROR,
- "Failed to decode management handshake response");
- goto out;
- }
-
- if (snap_info_req.dict.dict_len) {
- dict = dict_new ();
- if (!dict) {
- op_errno = ENOMEM;
- ret = -1;
- goto out;
- }
-
- ret = dict_unserialize (snap_info_req.dict.dict_val,
- snap_info_req.dict.dict_len,
- &dict);
- if (ret < 0) {
- gf_log ("glusterd", GF_LOG_ERROR,
- "Failed to unserialize dictionary");
- op_errno = EINVAL;
- ret = -1;
- goto out;
- } else {
- dict->extra_stdfree = snap_info_req.dict.dict_val;
- }
- }
-
- ret = dict_get_str (dict, "volname", &volname);
- if (ret) {
- op_errno = EINVAL;
- gf_log ("glusterd", GF_LOG_ERROR,
- "Failed to retrieve volname");
- ret = -1;
- goto out;
- }
-
- dict_rsp = dict_new ();
- if (!dict_rsp) {
- op_errno = ENOMEM;
- ret = -1;
- goto out;
- }
-
- ret = glusterd_snapshot_get_volnames_uuids (dict_rsp, volname,
- &snap_info_rsp);
-
- if (ret) {
- gf_log ("glusterd", GF_LOG_ERROR,
- "Error getting snapshot volume names and uuids : %s",
- volname);
- op_errno = EINVAL;
- }
-
-out:
- snap_info_rsp.op_ret = ret;
- snap_info_rsp.op_errno = op_errno;
- snap_info_rsp.op_errstr = "";
- glusterd_submit_reply (req, &snap_info_rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gf_getsnap_name_uuid_rsp);
-
- if (dict) {
- dict_unref (dict);
- }
-
- if (dict_rsp) {
- dict_unref (dict_rsp);
- }
-
- if (snap_info_rsp.dict.dict_val) {
- GF_FREE (snap_info_rsp.dict.dict_val);
- }
-
- return 0;
-}
-
-int
-server_get_snap_info (rpcsvc_request_t *req)
-{
- return glusterd_big_locked_handler (req,
- __server_get_snap_info);
-}
-
-rpcsvc_actor_t gluster_handshake_actors[GF_HNDSK_MAXVALUE] = {
- [GF_HNDSK_NULL] = {"NULL", GF_HNDSK_NULL, NULL, NULL, 0, DRC_NA},
- [GF_HNDSK_GETSPEC] = {"GETSPEC", GF_HNDSK_GETSPEC, server_getspec, NULL, 0, DRC_NA},
- [GF_HNDSK_EVENT_NOTIFY] = {"EVENTNOTIFY", GF_HNDSK_EVENT_NOTIFY, server_event_notify, NULL, 0, DRC_NA},
- [GF_HNDSK_GET_VOLUME_INFO] = {"GETVOLUMEINFO", GF_HNDSK_GET_VOLUME_INFO, server_get_volume_info, NULL, 0, DRC_NA},
- [GF_HNDSK_GET_SNAPSHOT_INFO] = {"GETSNAPINFO", GF_HNDSK_GET_SNAPSHOT_INFO, server_get_snap_info, NULL, 0, DRC_NA},
-};
-
-
-struct rpcsvc_program gluster_handshake_prog = {
- .progname = "Gluster Handshake",
- .prognum = GLUSTER_HNDSK_PROGRAM,
- .progver = GLUSTER_HNDSK_VERSION,
- .actors = gluster_handshake_actors,
- .numactors = GF_HNDSK_MAXVALUE,
-};
-
-/* A minimal RPC program just for the cli getspec command */
-rpcsvc_actor_t gluster_cli_getspec_actors[GF_HNDSK_MAXVALUE] = {
- [GF_HNDSK_GETSPEC] = {"GETSPEC", GF_HNDSK_GETSPEC, server_getspec, NULL, 0, DRC_NA},
-};
-
-struct rpcsvc_program gluster_cli_getspec_prog = {
- .progname = "Gluster Handshake (CLI Getspec)",
- .prognum = GLUSTER_HNDSK_PROGRAM,
- .progver = GLUSTER_HNDSK_VERSION,
- .actors = gluster_cli_getspec_actors,
- .numactors = GF_HNDSK_MAXVALUE,
-};
-
-
-char *glusterd_dump_proc[GF_DUMP_MAXVALUE] = {
- [GF_DUMP_NULL] = "NULL",
- [GF_DUMP_DUMP] = "DUMP",
- [GF_DUMP_PING] = "PING",
-};
-
-rpc_clnt_prog_t glusterd_dump_prog = {
- .progname = "GLUSTERD-DUMP",
- .prognum = GLUSTER_DUMP_PROGRAM,
- .progver = GLUSTER_DUMP_VERSION,
- .procnames = glusterd_dump_proc,
-};
-
-
-rpcsvc_actor_t glusterd_mgmt_hndsk_actors[GD_MGMT_HNDSK_MAXVALUE] = {
- [GD_MGMT_HNDSK_NULL] = {"NULL", GD_MGMT_HNDSK_NULL, NULL,
- NULL, 0, DRC_NA},
- [GD_MGMT_HNDSK_VERSIONS] = {"MGMT-VERS", GD_MGMT_HNDSK_VERSIONS,
- glusterd_mgmt_hndsk_versions, NULL,
- 0, DRC_NA},
- [GD_MGMT_HNDSK_VERSIONS_ACK] = {"MGMT-VERS-ACK",
- GD_MGMT_HNDSK_VERSIONS_ACK,
- glusterd_mgmt_hndsk_versions_ack,
- NULL, 0, DRC_NA},
-};
-
-struct rpcsvc_program glusterd_mgmt_hndsk_prog = {
- .progname = "Gluster MGMT Handshake",
- .prognum = GD_MGMT_HNDSK_PROGRAM,
- .progver = GD_MGMT_HNDSK_VERSION,
- .actors = glusterd_mgmt_hndsk_actors,
- .numactors = GD_MGMT_HNDSK_MAXVALUE,
-};
-
-char *glusterd_mgmt_hndsk_proc[GD_MGMT_HNDSK_MAXVALUE] = {
- [GD_MGMT_HNDSK_NULL] = "NULL",
- [GD_MGMT_HNDSK_VERSIONS] = "MGMT-VERS",
- [GD_MGMT_HNDSK_VERSIONS_ACK] = "MGMT-VERS-ACK",
-};
-
-rpc_clnt_prog_t gd_clnt_mgmt_hndsk_prog = {
- .progname = "Gluster MGMT Handshake",
- .prognum = GD_MGMT_HNDSK_PROGRAM,
- .progver = GD_MGMT_HNDSK_VERSION,
- .procnames = glusterd_mgmt_hndsk_proc,
-};
-
-
-static int
-glusterd_event_connected_inject (glusterd_peerctx_t *peerctx)
-{
- GF_ASSERT (peerctx);
-
- glusterd_friend_sm_event_t *event = NULL;
- glusterd_probe_ctx_t *ctx = NULL;
- int ret = -1;
- glusterd_peerinfo_t *peerinfo = NULL;
-
-
- ret = glusterd_friend_sm_new_event
- (GD_FRIEND_EVENT_CONNECTED, &event);
-
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Unable to get new event");
- goto out;
- }
-
- ctx = GF_CALLOC (1, sizeof(*ctx), gf_gld_mt_probe_ctx_t);
-
- if (!ctx) {
- ret = -1;
- gf_log ("", GF_LOG_ERROR, "Memory not available");
- goto out;
- }
-
- peerinfo = peerctx->peerinfo;
- ctx->hostname = gf_strdup (peerinfo->hostname);
- ctx->port = peerinfo->port;
- ctx->req = peerctx->args.req;
- ctx->dict = peerctx->args.dict;
-
- event->peerinfo = peerinfo;
- event->ctx = ctx;
-
- ret = glusterd_friend_sm_inject_event (event);
-
- if (ret) {
- gf_log ("glusterd", GF_LOG_ERROR, "Unable to inject "
- "EVENT_CONNECTED ret = %d", ret);
- goto out;
- }
-
-out:
- gf_log ("", GF_LOG_DEBUG, "returning %d", ret);
- return ret;
-}
-
-
-int
-gd_validate_peer_op_version (xlator_t *this, glusterd_peerinfo_t *peerinfo,
- dict_t *dict, char **errstr)
-{
- int ret = -1;
- glusterd_conf_t *conf = NULL;
- int32_t peer_op_version = 0;
- int32_t peer_min_op_version = 0;
- int32_t peer_max_op_version = 0;
-
- if (!dict && !this && !peerinfo)
- goto out;
-
- conf = this->private;
-
- ret = dict_get_int32 (dict, GD_OP_VERSION_KEY, &peer_op_version);
- if (ret)
- goto out;
-
- ret = dict_get_int32 (dict, GD_MAX_OP_VERSION_KEY,
- &peer_max_op_version);
- if (ret)
- goto out;
-
- ret = dict_get_int32 (dict, GD_MIN_OP_VERSION_KEY,
- &peer_min_op_version);
- if (ret)
- goto out;
-
- ret = -1;
- /* Check if peer can support our op_version */
- if ((peer_max_op_version < conf->op_version) ||
- (peer_min_op_version > conf->op_version)) {
- ret = gf_asprintf (errstr, "Peer %s does not support required "
- "op-version", peerinfo->hostname);
- ret = -1;
- goto out;
- }
-
- ret = 0;
-out:
- gf_log (this->name , GF_LOG_DEBUG, "Peer %s %s", peerinfo->hostname,
- ((ret < 0) ? "rejected" : "accepted"));
- return ret;
-}
-
-int
-__glusterd_mgmt_hndsk_version_ack_cbk (struct rpc_req *req, struct iovec *iov,
- int count, void *myframe)
-{
- int ret = -1;
- int op_errno = EINVAL;
- gf_mgmt_hndsk_rsp rsp = {0,};
- xlator_t *this = NULL;
- call_frame_t *frame = NULL;
- glusterd_peerinfo_t *peerinfo = NULL;
- glusterd_peerctx_t *peerctx = NULL;
- char msg[1024] = {0,};
-
- this = THIS;
- frame = myframe;
- peerctx = frame->local;
- 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);
- goto out;
- }
-
- ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_mgmt_hndsk_rsp);
- if (ret < 0) {
- snprintf (msg, sizeof (msg), "Failed to decode XDR");
- gf_log ("", GF_LOG_ERROR, "%s", msg);
- peerctx->errstr = gf_strdup (msg);
- goto out;
- }
-
- op_errno = rsp.op_errno;
- if (-1 == rsp.op_ret) {
- ret = -1;
- snprintf (msg, sizeof (msg),
- "Failed to get handshake ack from remote server");
- gf_log (frame->this->name, GF_LOG_ERROR, "%s", msg);
- peerctx->errstr = gf_strdup (msg);
- goto out;
- }
-
- /* TODO: this is hardcoded as of now, but I don't forsee any problems
- * with this as long as we are properly handshaking operating versions
- */
- peerinfo->mgmt = &gd_mgmt_prog;
- peerinfo->peer = &gd_peer_prog;
- peerinfo->mgmt_v3 = &gd_mgmt_v3_prog;
-
- ret = default_notify (this, GF_EVENT_CHILD_UP, NULL);
-
- if (GD_MODE_ON == peerctx->args.mode) {
- ret = glusterd_event_connected_inject (peerctx);
- peerctx->args.req = NULL;
- } else if (GD_MODE_SWITCH_ON == peerctx->args.mode) {
- peerctx->args.mode = GD_MODE_ON;
- } else {
- gf_log (this->name, GF_LOG_WARNING, "unknown mode %d",
- peerctx->args.mode);
- }
-
- glusterd_friend_sm ();
-
- ret = 0;
-out:
-
- frame->local = NULL;
- STACK_DESTROY (frame->root);
-
- if (ret != 0)
- rpc_transport_disconnect (peerinfo->rpc->conn.trans);
-
- if (rsp.hndsk.hndsk_val)
- free (rsp.hndsk.hndsk_val);
-
- return 0;
-}
-
-int
-glusterd_mgmt_hndsk_version_ack_cbk (struct rpc_req *req, struct iovec *iov,
- int count, void *myframe)
-{
- return glusterd_big_locked_cbk (req, iov, count, myframe,
- __glusterd_mgmt_hndsk_version_ack_cbk);
-}
-
-int
-__glusterd_mgmt_hndsk_version_cbk (struct rpc_req *req, struct iovec *iov,
- int count, void *myframe)
-{
- int ret = -1;
- int op_errno = EINVAL;
- gf_mgmt_hndsk_rsp rsp = {0,};
- gf_mgmt_hndsk_req arg = {{0,}};
- xlator_t *this = NULL;
- call_frame_t *frame = NULL;
- glusterd_peerinfo_t *peerinfo = NULL;
- glusterd_peerctx_t *peerctx = NULL;
- dict_t *dict = NULL;
- dict_t *rsp_dict = NULL;
- glusterd_conf_t *conf = NULL;
- char msg[1024] = {0,};
-
- this = THIS;
- conf = this->private;
- frame = myframe;
- peerctx = frame->local;
- peerinfo = peerctx->peerinfo;
-
- if (-1 == req->rpc_status) {
- ret = -1;
- snprintf (msg, sizeof (msg),
- "Error through RPC layer, retry again later");
- gf_log (this->name, GF_LOG_ERROR, "%s", msg);
- peerctx->errstr = gf_strdup (msg);
- goto out;
- }
-
- ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_mgmt_hndsk_rsp);
- if (ret < 0) {
- snprintf (msg, sizeof (msg), "Failed to decode management "
- "handshake response");
- gf_log (this->name, GF_LOG_ERROR, "%s", msg);
- peerctx->errstr = gf_strdup (msg);
- goto out;
- }
-
- GF_PROTOCOL_DICT_UNSERIALIZE (this, dict, rsp.hndsk.hndsk_val,
- rsp.hndsk.hndsk_len, ret, op_errno,
- out);
-
- op_errno = rsp.op_errno;
- if (-1 == rsp.op_ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "failed to get the 'versions' from peer (%s)",
- req->conn->trans->peerinfo.identifier);
- goto out;
- }
-
- /* Check if peer can be part of cluster */
- ret = gd_validate_peer_op_version (this, peerinfo, dict,
- &peerctx->errstr);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "failed to validate the operating version of peer (%s)",
- peerinfo->hostname);
- goto out;
- }
-
- rsp_dict = dict_new ();
- if (!rsp_dict)
- goto out;
-
- ret = dict_set_int32 (rsp_dict, GD_OP_VERSION_KEY, conf->op_version);
- if (ret) {
- gf_log(this->name, GF_LOG_ERROR,
- "failed to set operating version in dict");
- goto out;
- }
-
- GF_PROTOCOL_DICT_SERIALIZE (this, rsp_dict, (&arg.hndsk.hndsk_val),
- arg.hndsk.hndsk_len, op_errno, out);
-
- ret = glusterd_submit_request (peerctx->peerinfo->rpc, &arg, frame,
- &gd_clnt_mgmt_hndsk_prog,
- GD_MGMT_HNDSK_VERSIONS_ACK, NULL, this,
- glusterd_mgmt_hndsk_version_ack_cbk,
- (xdrproc_t)xdr_gf_mgmt_hndsk_req);
-
-out:
- if (ret) {
- frame->local = NULL;
- STACK_DESTROY (frame->root);
- rpc_transport_disconnect (peerinfo->rpc->conn.trans);
- }
-
- if (rsp.hndsk.hndsk_val)
- free (rsp.hndsk.hndsk_val);
-
- if (arg.hndsk.hndsk_val)
- GF_FREE (arg.hndsk.hndsk_val);
-
- if (dict)
- dict_unref (dict);
-
- if (rsp_dict)
- dict_unref (rsp_dict);
-
- return 0;
-}
-
-int
-glusterd_mgmt_hndsk_version_cbk (struct rpc_req *req, struct iovec *iov,
- int count, void *myframe)
-{
- return glusterd_big_locked_cbk (req, iov, count, myframe,
- __glusterd_mgmt_hndsk_version_cbk);
-}
-
-int
-glusterd_mgmt_handshake (xlator_t *this, glusterd_peerctx_t *peerctx)
-{
- call_frame_t *frame = NULL;
- gf_mgmt_hndsk_req req = {{0,},};
- int ret = -1;
-
- frame = create_frame (this, this->ctx->pool);
- if (!frame)
- goto out;
-
- frame->local = peerctx;
-
- ret = glusterd_submit_request (peerctx->peerinfo->rpc, &req, frame,
- &gd_clnt_mgmt_hndsk_prog,
- GD_MGMT_HNDSK_VERSIONS, NULL, this,
- glusterd_mgmt_hndsk_version_cbk,
- (xdrproc_t)xdr_gf_mgmt_hndsk_req);
- ret = 0;
-out:
- if (ret && frame)
- STACK_DESTROY (frame->root);
-
- return ret;
-}
-
-int
-glusterd_set_clnt_mgmt_program (glusterd_peerinfo_t *peerinfo,
- gf_prog_detail *prog)
-{
- gf_prog_detail *trav = NULL;
- int ret = -1;
-
- if (!peerinfo || !prog)
- goto out;
-
- trav = prog;
-
- while (trav) {
- ret = -1;
- if ((gd_mgmt_prog.prognum == trav->prognum) &&
- (gd_mgmt_prog.progver == trav->progver)) {
- peerinfo->mgmt = &gd_mgmt_prog;
- ret = 0;
- }
-
- if ((gd_peer_prog.prognum == trav->prognum) &&
- (gd_peer_prog.progver == trav->progver)) {
- peerinfo->peer = &gd_peer_prog;
- ret = 0;
- }
-
- if (ret) {
- gf_log ("", GF_LOG_DEBUG,
- "%s (%"PRId64":%"PRId64") not supported",
- trav->progname, trav->prognum,
- trav->progver);
- }
-
- trav = trav->next;
- }
-
- if (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);
- }
-
- if (peerinfo->mgmt_v3) {
- gf_log ("", GF_LOG_INFO,
- "Using Program %s, Num (%d), Version (%d)",
- peerinfo->mgmt_v3->progname,
- peerinfo->mgmt_v3->prognum,
- peerinfo->mgmt_v3->progver);
- }
-
- ret = 0;
-out:
- return ret;
-
-}
-
-static gf_boolean_t
-_mgmt_hndsk_prog_present (gf_prog_detail *prog) {
- gf_boolean_t ret = _gf_false;
- gf_prog_detail *trav = NULL;
-
- GF_ASSERT (prog);
-
- trav = prog;
-
- while (trav) {
- if ((trav->prognum == GD_MGMT_HNDSK_PROGRAM) &&
- (trav->progver == GD_MGMT_HNDSK_VERSION)) {
- ret = _gf_true;
- goto out;
- }
- trav = trav->next;
- }
-out:
- return ret;
-}
-
-int
-__glusterd_peer_dump_version_cbk (struct rpc_req *req, struct iovec *iov,
- int count, void *myframe)
-{
- int ret = -1;
- gf_dump_rsp rsp = {0,};
- xlator_t *this = NULL;
- gf_prog_detail *trav = NULL;
- gf_prog_detail *next = NULL;
- call_frame_t *frame = NULL;
- glusterd_peerinfo_t *peerinfo = NULL;
- glusterd_peerctx_t *peerctx = NULL;
- glusterd_conf_t *conf = NULL;
- char msg[1024] = {0,};
-
- this = THIS;
- conf = this->private;
- frame = myframe;
- peerctx = frame->local;
- 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);
- goto out;
- }
-
- ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_dump_rsp);
- if (ret < 0) {
- snprintf (msg, sizeof (msg), "Failed to decode XDR");
- gf_log ("", GF_LOG_ERROR, "%s", msg);
- peerctx->errstr = gf_strdup (msg);
- 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);
- goto out;
- }
-
- if (_mgmt_hndsk_prog_present (rsp.prog)) {
- gf_log (this->name, GF_LOG_DEBUG,
- "Proceeding to op-version handshake with peer %s",
- peerinfo->hostname);
- ret = glusterd_mgmt_handshake (this, peerctx);
- goto out;
- } else if (conf->op_version > 1) {
- ret = -1;
- snprintf (msg, sizeof (msg),
- "Peer %s does not support required op-version",
- peerinfo->hostname);
- peerctx->errstr = gf_strdup (msg);
- gf_log (this->name, GF_LOG_ERROR, "%s", msg);
- goto out;
- }
-
- /* Make sure we assign the proper program to peer */
- ret = glusterd_set_clnt_mgmt_program (peerinfo, rsp.prog);
- if (ret) {
- gf_log ("", GF_LOG_WARNING, "failed to set the mgmt program");
- goto out;
- }
-
- ret = default_notify (this, GF_EVENT_CHILD_UP, NULL);
-
- if (GD_MODE_ON == peerctx->args.mode) {
- ret = glusterd_event_connected_inject (peerctx);
- peerctx->args.req = NULL;
- } else if (GD_MODE_SWITCH_ON == peerctx->args.mode) {
- peerctx->args.mode = GD_MODE_ON;
- } else {
- gf_log ("", GF_LOG_WARNING, "unknown mode %d",
- peerctx->args.mode);
- }
-
- glusterd_friend_sm();
- glusterd_op_sm();
-
- ret = 0;
-
-out:
-
- /* don't use GF_FREE, buffer was allocated by libc */
- if (rsp.prog) {
- trav = rsp.prog;
- while (trav) {
- next = trav->next;
- free (trav->progname);
- free (trav);
- trav = next;
- }
- }
-
- frame->local = NULL;
- STACK_DESTROY (frame->root);
-
- if (ret != 0)
- rpc_transport_disconnect (peerinfo->rpc->conn.trans);
-
- return 0;
-}
-
-
-int
-glusterd_peer_dump_version_cbk (struct rpc_req *req, struct iovec *iov,
- int count, void *myframe)
-{
- return glusterd_big_locked_cbk (req, iov, count, myframe,
- __glusterd_peer_dump_version_cbk);
-}
-
-int
-glusterd_peer_dump_version (xlator_t *this, struct rpc_clnt *rpc,
- glusterd_peerctx_t *peerctx)
-{
- call_frame_t *frame = NULL;
- gf_dump_req req = {0,};
- int ret = -1;
-
- frame = create_frame (this, this->ctx->pool);
- if (!frame)
- goto out;
-
- frame->local = peerctx;
-
- req.gfs_id = 0xcafe;
-
- 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);
-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 f36764e4832..00000000000
--- a/xlators/mgmt/glusterd/src/glusterd-hooks.c
+++ /dev/null
@@ -1,568 +0,0 @@
-/*
- Copyright (c) 2007-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 "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] = "reset",
- [GD_OP_SYNC_VOLUME] = EMPTY,
- [GD_OP_LOG_ROTATE] = EMPTY,
- [GD_OP_GSYNC_CREATE] = "gsync-create",
- [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' && (fnmatch ("*.rpmsave", script, 0) != 0)
- && (fnmatch ("*.rpmnew", script, 0) != 0));
-}
-
-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];
-}
-
-void
-glusterd_hooks_add_working_dir (runner_t *runner, glusterd_conf_t *priv)
-{
- runner_argprintf (runner, "--gd-workdir=%s", priv->workdir);
-}
-
-void
-glusterd_hooks_add_op (runner_t *runner, char *op)
-{
- runner_argprintf (runner, "--volume-op=%s", op);
-}
-
-void
-glusterd_hooks_add_hooks_version (runner_t* runner)
-{
- runner_argprintf (runner, "--version=%d", GLUSTERD_HOOK_VER);
-}
-
-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)
-{
- char *hooks_args = NULL;
- 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");
-
- glusterd_hooks_add_hooks_version (runner);
- glusterd_hooks_add_op (runner, "start");
- glusterd_hooks_add_working_dir (runner, priv);
-
- 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);
- glusterd_hooks_add_working_dir (runner, priv);
- break;
-
- case GD_OP_GSYNC_CREATE:
- ret = dict_get_str (op_ctx, "hooks_args", &hooks_args);
- if (ret)
- gf_log ("", GF_LOG_DEBUG,
- "No Hooks Arguments.");
- else
- gf_log ("", GF_LOG_DEBUG,
- "Hooks Args = %s", hooks_args);
- if (hooks_args)
- runner_argprintf (runner, "%s", hooks_args);
- break;
-
- case GD_OP_ADD_BRICK:
- glusterd_hooks_add_hooks_version (runner);
- glusterd_hooks_add_op (runner, "add-brick");
- glusterd_hooks_add_working_dir (runner, priv);
- break;
-
- case GD_OP_RESET_VOLUME:
- glusterd_hooks_add_hooks_version (runner);
- glusterd_hooks_add_op (runner, "reset");
- glusterd_hooks_add_working_dir (runner, priv);
- 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 c597ddd2a7d..00000000000
--- a/xlators/mgmt/glusterd/src/glusterd-hooks.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- Copyright (c) 2006-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 _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-locks.c b/xlators/mgmt/glusterd/src/glusterd-locks.c
deleted file mode 100644
index b2629fd87b8..00000000000
--- a/xlators/mgmt/glusterd/src/glusterd-locks.c
+++ /dev/null
@@ -1,672 +0,0 @@
-/*
- Copyright (c) 2013-2014 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 "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 "glusterd-locks.h"
-#include "run.h"
-#include "syscall.h"
-
-#include <signal.h>
-
-#define GF_MAX_LOCKING_ENTITIES 2
-
-/* Valid entities that the mgmt_v3 lock can hold locks upon *
- * To add newer entities to be locked, we can just add more *
- * entries to this table along with the type and default value */
-glusterd_valid_entities valid_types[] = {
- { "vol", _gf_true },
- { "snap", _gf_false },
- { NULL },
-};
-
-/* Checks if the lock request is for a valid entity */
-gf_boolean_t
-glusterd_mgmt_v3_is_type_valid (char *type)
-{
- int32_t i = 0;
- gf_boolean_t ret = _gf_false;
-
- GF_ASSERT (type);
-
- for (i = 0; valid_types[i].type; i++) {
- if (!strcmp (type, valid_types[i].type)) {
- ret = _gf_true;
- break;
- }
- }
-
- return ret;
-}
-
-/* Initialize the global mgmt_v3 lock list(dict) when
- * glusterd is spawned */
-int32_t
-glusterd_mgmt_v3_lock_init ()
-{
- int32_t ret = -1;
- xlator_t *this = NULL;
- glusterd_conf_t *priv = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- priv = this->private;
- GF_ASSERT (priv);
-
- priv->mgmt_v3_lock = dict_new ();
- if (!priv->mgmt_v3_lock)
- goto out;
-
- ret = 0;
-out:
- return ret;
-}
-
-/* Destroy the global mgmt_v3 lock list(dict) when
- * glusterd cleanup is performed */
-void
-glusterd_mgmt_v3_lock_fini ()
-{
- xlator_t *this = NULL;
- glusterd_conf_t *priv = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- priv = this->private;
- GF_ASSERT (priv);
-
- if (priv->mgmt_v3_lock)
- dict_unref (priv->mgmt_v3_lock);
-}
-
-int32_t
-glusterd_get_mgmt_v3_lock_owner (char *key, uuid_t *uuid)
-{
- int32_t ret = -1;
- glusterd_mgmt_v3_lock_obj *lock_obj = NULL;
- glusterd_conf_t *priv = NULL;
- uuid_t no_owner = {0,};
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- priv = this->private;
- GF_ASSERT (priv);
-
- if (!key || !uuid) {
- gf_log (this->name, GF_LOG_ERROR, "key or uuid is null.");
- ret = -1;
- goto out;
- }
-
- ret = dict_get_bin (priv->mgmt_v3_lock, key, (void **) &lock_obj);
- if (!ret)
- uuid_copy (*uuid, lock_obj->lock_owner);
- else
- uuid_copy (*uuid, no_owner);
-
- ret = 0;
-out:
- gf_log (this->name, GF_LOG_TRACE, "Returning %d", ret);
- return ret;
-}
-
-/* This function is called with the locked_count and type, to *
- * release all the acquired locks. */
-static int32_t
-glusterd_release_multiple_locks_per_entity (dict_t *dict, uuid_t uuid,
- int32_t locked_count,
- char *type)
-{
- char name_buf[PATH_MAX] = "";
- char *name = NULL;
- int32_t i = -1;
- int32_t op_ret = 0;
- int32_t ret = -1;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT(this);
- GF_ASSERT (dict);
- GF_ASSERT (type);
-
- if (locked_count == 0) {
- gf_log (this->name, GF_LOG_DEBUG,
- "No %s locked as part of this transaction",
- type);
- goto out;
- }
-
- /* Release all the locks held */
- for (i = 0; i < locked_count; i++) {
- snprintf (name_buf, sizeof(name_buf),
- "%sname%d", type, i+1);
-
- /* Looking for volname1, volname2 or snapname1, *
- * as key in the dict snapname2 */
- ret = dict_get_str (dict, name_buf, &name);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Unable to get %s locked_count = %d",
- name_buf, locked_count);
- op_ret = ret;
- continue;
- }
-
- ret = glusterd_mgmt_v3_unlock (name, uuid, type);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to release lock for %s.",
- name);
- op_ret = ret;
- }
- }
-
-out:
- gf_log (this->name, GF_LOG_TRACE, "Returning %d", op_ret);
- return op_ret;
-}
-
-/* Given the count and type of the entity this function acquires *
- * locks on multiple elements of the same entity. For example: *
- * If type is "vol" this function tries to acquire locks on multiple *
- * volumes */
-static int32_t
-glusterd_acquire_multiple_locks_per_entity (dict_t *dict, uuid_t uuid,
- int32_t count, char *type)
-{
- char name_buf[PATH_MAX] = "";
- char *name = NULL;
- int32_t i = -1;
- int32_t ret = -1;
- int32_t locked_count = 0;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT(this);
- GF_ASSERT (dict);
- GF_ASSERT (type);
-
- /* Locking one element after other */
- for (i = 0; i < count; i++) {
- snprintf (name_buf, sizeof(name_buf),
- "%sname%d", type, i+1);
-
- /* Looking for volname1, volname2 or snapname1, *
- * as key in the dict snapname2 */
- ret = dict_get_str (dict, name_buf, &name);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Unable to get %s count = %d",
- name_buf, count);
- break;
- }
-
- ret = glusterd_mgmt_v3_lock (name, uuid, type);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to acquire lock for %s %s "
- "on behalf of %s. Reversing "
- "this transaction", type, name,
- uuid_utoa(uuid));
- break;
- }
- locked_count++;
- }
-
- if (count == locked_count) {
- /* If all locking ops went successfuly, return as success */
- ret = 0;
- goto out;
- }
-
- /* If we failed to lock one element, unlock others and return failure */
- ret = glusterd_release_multiple_locks_per_entity (dict, uuid,
- locked_count,
- type);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to release multiple %s locks",
- type);
- }
- ret = -1;
-out:
- gf_log (this->name, GF_LOG_TRACE, "Returning %d", ret);
- return ret;
-}
-
-/* Given the type of entity, this function figures out if it should unlock a *
- * single element of multiple elements of the said entity. For example: *
- * if the type is "vol", this function will accordingly unlock a single volume *
- * or multiple volumes */
-static int32_t
-glusterd_mgmt_v3_unlock_entity (dict_t *dict, uuid_t uuid, char *type,
- gf_boolean_t default_value)
-{
- char name_buf[PATH_MAX] = "";
- char *name = NULL;
- int32_t count = -1;
- int32_t ret = -1;
- gf_boolean_t hold_locks = _gf_false;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT(this);
- GF_ASSERT (dict);
- GF_ASSERT (type);
-
- snprintf (name_buf, sizeof(name_buf), "hold_%s_locks", type);
- hold_locks = dict_get_str_boolean (dict, name_buf, default_value);
-
- if (hold_locks == _gf_false) {
- /* Locks were not held for this particular entity *
- * Hence nothing to release */
- ret = 0;
- goto out;
- }
-
- /* Looking for volcount or snapcount in the dict */
- snprintf (name_buf, sizeof(name_buf), "%scount", type);
- ret = dict_get_int32 (dict, name_buf, &count);
- if (ret) {
- /* count is not present. Only one *
- * element name needs to be unlocked */
- snprintf (name_buf, sizeof(name_buf), "%sname",
- type);
- ret = dict_get_str (dict, name_buf, &name);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Unable to fetch %sname", type);
- goto out;
- }
-
- ret = glusterd_mgmt_v3_unlock (name, uuid, type);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to release lock for %s %s "
- "on behalf of %s.", type, name,
- uuid_utoa(uuid));
- goto out;
- }
- } else {
- /* Unlocking one element name after another */
- ret = glusterd_release_multiple_locks_per_entity (dict,
- uuid,
- count,
- type);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to release all %s locks", type);
- goto out;
- }
- }
-
- ret = 0;
-out:
- gf_log (this->name, GF_LOG_TRACE, "Returning %d", ret);
- return ret;
-}
-
-/* Given the type of entity, this function figures out if it should lock a *
- * single element or multiple elements of the said entity. For example: *
- * if the type is "vol", this function will accordingly lock a single volume *
- * or multiple volumes */
-static int32_t
-glusterd_mgmt_v3_lock_entity (dict_t *dict, uuid_t uuid, char *type,
- gf_boolean_t default_value)
-{
- char name_buf[PATH_MAX] = "";
- char *name = NULL;
- int32_t count = -1;
- int32_t ret = -1;
- gf_boolean_t hold_locks = _gf_false;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT(this);
- GF_ASSERT (dict);
- GF_ASSERT (type);
-
- snprintf (name_buf, sizeof(name_buf), "hold_%s_locks", type);
- hold_locks = dict_get_str_boolean (dict, name_buf, default_value);
-
- if (hold_locks == _gf_false) {
- /* Not holding locks for this particular entity */
- ret = 0;
- goto out;
- }
-
- /* Looking for volcount or snapcount in the dict */
- snprintf (name_buf, sizeof(name_buf), "%scount", type);
- ret = dict_get_int32 (dict, name_buf, &count);
- if (ret) {
- /* count is not present. Only one *
- * element name needs to be locked */
- snprintf (name_buf, sizeof(name_buf), "%sname",
- type);
- ret = dict_get_str (dict, name_buf, &name);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Unable to fetch %sname", type);
- goto out;
- }
-
- ret = glusterd_mgmt_v3_lock (name, uuid, type);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to acquire lock for %s %s "
- "on behalf of %s.", type, name,
- uuid_utoa(uuid));
- goto out;
- }
- } else {
- /* Locking one element name after another */
- ret = glusterd_acquire_multiple_locks_per_entity (dict,
- uuid,
- count,
- type);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to acquire all %s locks", type);
- goto out;
- }
- }
-
- ret = 0;
-out:
- gf_log (this->name, GF_LOG_TRACE, "Returning %d", ret);
- return ret;
-}
-
-/* Try to release locks of multiple entities like *
- * volume, snaps etc. */
-int32_t
-glusterd_multiple_mgmt_v3_unlock (dict_t *dict, uuid_t uuid)
-{
- int32_t i = -1;
- int32_t ret = -1;
- int32_t op_ret = 0;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT(this);
-
- if (!dict) {
- gf_log (this->name, GF_LOG_ERROR, "dict is null.");
- ret = -1;
- goto out;
- }
-
- for (i = 0; valid_types[i].type; i++) {
- ret = glusterd_mgmt_v3_unlock_entity
- (dict, uuid,
- valid_types[i].type,
- valid_types[i].default_value);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Unable to unlock all %s",
- valid_types[i].type);
- op_ret = ret;
- }
- }
-
- ret = op_ret;
-out:
- gf_log (this->name, GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-
-/* Try to acquire locks on multiple entities like *
- * volume, snaps etc. */
-int32_t
-glusterd_multiple_mgmt_v3_lock (dict_t *dict, uuid_t uuid)
-{
- int32_t i = -1;
- int32_t ret = -1;
- int32_t locked_count = 0;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT(this);
-
- if (!dict) {
- gf_log (this->name, GF_LOG_ERROR, "dict is null.");
- ret = -1;
- goto out;
- }
-
- /* Locking one entity after other */
- for (i = 0; valid_types[i].type; i++) {
- ret = glusterd_mgmt_v3_lock_entity
- (dict, uuid,
- valid_types[i].type,
- valid_types[i].default_value);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Unable to lock all %s",
- valid_types[i].type);
- break;
- }
- locked_count++;
- }
-
- if (locked_count == GF_MAX_LOCKING_ENTITIES) {
- /* If all locking ops went successfuly, return as success */
- ret = 0;
- goto out;
- }
-
- /* If we failed to lock one entity, unlock others and return failure */
- for (i = 0; i < locked_count; i++) {
- ret = glusterd_mgmt_v3_unlock_entity
- (dict, uuid,
- valid_types[i].type,
- valid_types[i].default_value);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Unable to unlock all %s",
- valid_types[i].type);
- }
- }
- ret = -1;
-out:
- gf_log (this->name, GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-
-
-int32_t
-glusterd_mgmt_v3_lock (const char *name, uuid_t uuid, char *type)
-{
- char key[PATH_MAX] = "";
- int32_t ret = -1;
- glusterd_mgmt_v3_lock_obj *lock_obj = NULL;
- glusterd_conf_t *priv = NULL;
- gf_boolean_t is_valid = _gf_true;
- uuid_t owner = {0};
- xlator_t *this = NULL;
- char *bt = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- priv = this->private;
- GF_ASSERT (priv);
-
- if (!name || !type) {
- gf_log (this->name, GF_LOG_ERROR, "name or type is null.");
- ret = -1;
- goto out;
- }
-
- is_valid = glusterd_mgmt_v3_is_type_valid (type);
- if (is_valid != _gf_true) {
- gf_log_callingfn (this->name, GF_LOG_ERROR,
- "Invalid entity. Cannot perform locking "
- "operation on %s types", type);
- ret = -1;
- goto out;
- }
-
- ret = snprintf (key, sizeof(key), "%s_%s", name, type);
- if (ret != strlen(name) + 1 + strlen(type)) {
- ret = -1;
- gf_log (this->name, GF_LOG_ERROR, "Unable to create key");
- goto out;
- }
-
- gf_log (this->name, GF_LOG_DEBUG,
- "Trying to acquire lock of %s %s for %s as %s",
- type, name, uuid_utoa (uuid), key);
-
- ret = glusterd_get_mgmt_v3_lock_owner (key, &owner);
- if (ret) {
- gf_log (this->name, GF_LOG_DEBUG,
- "Unable to get mgmt_v3 lock owner");
- goto out;
- }
-
- /* If the lock has already been held for the given volume
- * we fail */
- if (!uuid_is_null (owner)) {
- gf_log_callingfn (this->name, GF_LOG_WARNING,
- "Lock for %s held by %s",
- name, uuid_utoa (owner));
- ret = -1;
- goto out;
- }
-
- lock_obj = GF_CALLOC (1, sizeof(glusterd_mgmt_v3_lock_obj),
- gf_common_mt_mgmt_v3_lock_obj_t);
- if (!lock_obj) {
- ret = -1;
- goto out;
- }
-
- uuid_copy (lock_obj->lock_owner, uuid);
-
- ret = dict_set_bin (priv->mgmt_v3_lock, key, lock_obj,
- sizeof(glusterd_mgmt_v3_lock_obj));
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Unable to set lock owner in mgmt_v3 lock");
- if (lock_obj)
- GF_FREE (lock_obj);
- goto out;
- }
-
- /* Saving the backtrace into the pre-allocated buffer, ctx->btbuf*/
- if ((bt = gf_backtrace_save (NULL))) {
- snprintf (key, sizeof (key), "debug.last-success-bt-%s-%s",
- name, type);
- ret = dict_set_dynstr_with_alloc (priv->mgmt_v3_lock, key, bt);
- if (ret)
- gf_log (this->name, GF_LOG_WARNING, "Failed to save "
- "the back trace for lock %s-%s granted to %s",
- name, type, uuid_utoa (uuid));
- ret = 0;
- }
-
- gf_log (this->name, GF_LOG_DEBUG,
- "Lock for %s %s successfully held by %s",
- type, name, uuid_utoa (uuid));
-
- ret = 0;
-out:
- gf_log (this->name, GF_LOG_TRACE, "Returning %d", ret);
- return ret;
-}
-
-int32_t
-glusterd_mgmt_v3_unlock (const char *name, uuid_t uuid, char *type)
-{
- char key[PATH_MAX] = "";
- int32_t ret = -1;
- gf_boolean_t is_valid = _gf_true;
- glusterd_conf_t *priv = NULL;
- uuid_t owner = {0};
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- priv = this->private;
- GF_ASSERT (priv);
-
- if (!name || !type) {
- gf_log (this->name, GF_LOG_ERROR, "name is null.");
- ret = -1;
- goto out;
- }
-
- is_valid = glusterd_mgmt_v3_is_type_valid (type);
- if (is_valid != _gf_true) {
- gf_log_callingfn (this->name, GF_LOG_ERROR,
- "Invalid entity. Cannot perform unlocking "
- "operation on %s types", type);
- ret = -1;
- goto out;
- }
-
- ret = snprintf (key, sizeof(key), "%s_%s",
- name, type);
- if (ret != strlen(name) + 1 + strlen(type)) {
- gf_log (this->name, GF_LOG_ERROR, "Unable to create key");
- ret = -1;
- goto out;
- }
-
- gf_log (this->name, GF_LOG_DEBUG,
- "Trying to release lock of %s %s for %s as %s",
- type, name, uuid_utoa (uuid), key);
-
- ret = glusterd_get_mgmt_v3_lock_owner (key, &owner);
- if (ret) {
- gf_log (this->name, GF_LOG_DEBUG,
- "Unable to get mgmt_v3 lock owner");
- goto out;
- }
-
- if (uuid_is_null (owner)) {
- gf_log_callingfn (this->name, GF_LOG_WARNING,
- "Lock for %s %s not held", type, name);
- ret = -1;
- goto out;
- }
-
- ret = uuid_compare (uuid, owner);
- if (ret) {
- gf_log_callingfn (this->name, GF_LOG_WARNING,
- "Lock owner mismatch. "
- "Lock for %s %s held by %s",
- type, name, uuid_utoa (owner));
- goto out;
- }
-
- /* Removing the mgmt_v3 lock from the global list */
- dict_del (priv->mgmt_v3_lock, key);
-
- gf_log (this->name, GF_LOG_DEBUG,
- "Lock for %s %s successfully released",
- type, name);
-
- ret = 0;
-out:
- gf_log (this->name, GF_LOG_TRACE, "Returning %d", ret);
- return ret;
-}
diff --git a/xlators/mgmt/glusterd/src/glusterd-locks.h b/xlators/mgmt/glusterd/src/glusterd-locks.h
deleted file mode 100644
index b9cc8c0d1e4..00000000000
--- a/xlators/mgmt/glusterd/src/glusterd-locks.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- Copyright (c) 2013-2014 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 _GLUSTERD_LOCKS_H_
-#define _GLUSTERD_LOCKS_H_
-
-#ifndef _CONFIG_H
-#define _CONFIG_H
-#include "config.h"
-#endif
-
-typedef struct glusterd_mgmt_v3_lock_object_ {
- uuid_t lock_owner;
-} glusterd_mgmt_v3_lock_obj;
-
-typedef struct glusterd_mgmt_v3_lock_valid_entities {
- char *type; /* Entity type like vol, snap */
- gf_boolean_t default_value; /* The default value that *
- * determines if the locks *
- * should be held for that *
- * entity */
-} glusterd_valid_entities;
-
-int32_t
-glusterd_mgmt_v3_lock_init ();
-
-void
-glusterd_mgmt_v3_lock_fini ();
-
-int32_t
-glusterd_get_mgmt_v3_lock_owner (char *volname, uuid_t *uuid);
-
-int32_t
-glusterd_mgmt_v3_lock (const char *key, uuid_t uuid, char *type);
-
-int32_t
-glusterd_mgmt_v3_unlock (const char *key, uuid_t uuid, char *type);
-
-int32_t
-glusterd_multiple_mgmt_v3_lock (dict_t *dict, uuid_t uuid);
-
-int32_t
-glusterd_multiple_mgmt_v3_unlock (dict_t *dict, uuid_t uuid);
-
-#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 33bd95c031a..00000000000
--- a/xlators/mgmt/glusterd/src/glusterd-log-ops.c
+++ /dev/null
@@ -1,271 +0,0 @@
-/*
- Copyright (c) 2011-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 "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;
- char msg[2048] = {0,};
- xlator_t *this = NULL;
-
- GF_ASSERT (req);
- this = THIS;
- GF_ASSERT (this);
-
- ret = xdr_to_generic (req->msg[0], &cli_req, (xdrproc_t)xdr_gf_cli_req);
- if (ret < 0) {
- //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");
- snprintf (msg, sizeof (msg), "Unable to decode the "
- "command");
- goto out;
- }
- }
-
- 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);
- goto out;
- }
-
- gf_log (this->name, 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_synctask (req, GD_OP_LOG_ROTATE, dict);
-
-out:
- if (ret) {
- if (msg[0] == '\0')
- snprintf (msg, sizeof (msg), "Operation failed");
- ret = glusterd_op_send_cli_response (cli_op, ret, 0, req,
- dict, msg);
- }
-
- free (cli_req.dict.dict_val);
- return ret;
-}
-
-int
-glusterd_handle_log_rotate (rpcsvc_request_t *req)
-{
- return glusterd_big_locked_handler (req,
- __glusterd_handle_log_rotate);
-}
-
-/* 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 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_BRICK_PIDFILE (pidfile, volinfo, brickinfo, priv);
- 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
deleted file mode 100644
index ed171b69b66..00000000000
--- a/xlators/mgmt/glusterd/src/glusterd-mem-types.h
+++ /dev/null
@@ -1,77 +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 __GLUSTERD_MEM_TYPES_H__
-#define __GLUSTERD_MEM_TYPES_H__
-
-#include "mem-types.h"
-
-typedef enum gf_gld_mem_types_ {
- gf_gld_mt_dir_entry_t = gf_common_mt_end + 1,
- gf_gld_mt_volfile_ctx = gf_common_mt_end + 2,
- gf_gld_mt_glusterd_state_t = gf_common_mt_end + 3,
- gf_gld_mt_glusterd_conf_t = gf_common_mt_end + 4,
- gf_gld_mt_locker = gf_common_mt_end + 5,
- gf_gld_mt_string = gf_common_mt_end + 6,
- gf_gld_mt_lock_table = gf_common_mt_end + 7,
- gf_gld_mt_char = gf_common_mt_end + 8,
- gf_gld_mt_glusterd_connection_t = gf_common_mt_end + 9,
- gf_gld_mt_resolve_comp = gf_common_mt_end + 10,
- gf_gld_mt_peerinfo_t = gf_common_mt_end + 11,
- gf_gld_mt_friend_sm_event_t = gf_common_mt_end + 12,
- gf_gld_mt_friend_req_ctx_t = gf_common_mt_end + 13,
- gf_gld_mt_friend_update_ctx_t = gf_common_mt_end + 14,
- gf_gld_mt_op_sm_event_t = gf_common_mt_end + 15,
- gf_gld_mt_op_lock_ctx_t = gf_common_mt_end + 16,
- gf_gld_mt_op_stage_ctx_t = gf_common_mt_end + 17,
- gf_gld_mt_op_commit_ctx_t = gf_common_mt_end + 18,
- gf_gld_mt_mop_stage_req_t = gf_common_mt_end + 19,
- gf_gld_mt_probe_ctx_t = gf_common_mt_end + 20,
- gf_gld_mt_create_volume_ctx_t = gf_common_mt_end + 21,
- gf_gld_mt_start_volume_ctx_t = gf_common_mt_end + 22,
- gf_gld_mt_stop_volume_ctx_t = gf_common_mt_end + 23,
- gf_gld_mt_delete_volume_ctx_t = gf_common_mt_end + 24,
- gf_gld_mt_glusterd_volinfo_t = gf_common_mt_end + 25,
- gf_gld_mt_glusterd_brickinfo_t = gf_common_mt_end + 26,
- gf_gld_mt_peer_hostname_t = gf_common_mt_end + 27,
- gf_gld_mt_ifreq = gf_common_mt_end + 28,
- gf_gld_mt_store_handle_t = gf_common_mt_end + 29,
- gf_gld_mt_store_iter_t = gf_common_mt_end + 30,
- gf_gld_mt_defrag_info = gf_common_mt_end + 31,
- gf_gld_mt_log_filename_ctx_t = gf_common_mt_end + 32,
- gf_gld_mt_log_locate_ctx_t = gf_common_mt_end + 33,
- gf_gld_mt_log_rotate_ctx_t = gf_common_mt_end + 34,
- gf_gld_mt_peerctx_t = gf_common_mt_end + 35,
- gf_gld_mt_sm_tr_log_t = gf_common_mt_end + 36,
- gf_gld_mt_pending_node_t = gf_common_mt_end + 37,
- 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_mop_commit_req_t = gf_common_mt_end + 52,
- gf_gld_mt_int = gf_common_mt_end + 53,
- gf_gld_mt_snap_t = gf_common_mt_end + 54,
- gf_gld_mt_missed_snapinfo_t = gf_common_mt_end + 55,
- gf_gld_mt_snap_create_args_t = gf_common_mt_end + 56,
- gf_gld_mt_local_peers_t = gf_common_mt_end + 57,
- gf_gld_mt_end = gf_common_mt_end + 58,
-} gf_gld_mem_types_t;
-#endif
-
diff --git a/xlators/mgmt/glusterd/src/glusterd-messages.h b/xlators/mgmt/glusterd/src/glusterd-messages.h
deleted file mode 100644
index b4f8585097a..00000000000
--- a/xlators/mgmt/glusterd/src/glusterd-messages.h
+++ /dev/null
@@ -1,221 +0,0 @@
-/*
- Copyright (c) 2014 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 _GLUSTERD_MESSAGES_H_
-#define _GLUSTERD_MESSAGES_H_
-
-#ifndef _CONFIG_H
-#define _CONFIG_H
-#include "config.h"
-#endif
-
-#include "glfs-message-id.h"
-
-/*! \file glusterd-messages.h
- * \brief Glusterd log-message IDs and their descriptions
- */
-
-/* NOTE: Rules for message additions
- * 1) Each instance of a message is _better_ left with a unique message ID, even
- * if the message format is the same. Reasoning is that, if the message
- * format needs to change in one instance, the other instances are not
- * impacted or the new change does not change the ID of the instance being
- * modified.
- * 2) Addition of a message,
- * - Should increment the GLFS_NUM_MESSAGES
- * - Append to the list of messages defined, towards the end
- * - Retain macro naming as glfs_msg_X (for redability across developers)
- * NOTE: Rules for message format modifications
- * 3) Check acorss the code if the message ID macro in question is reused
- * anywhere. If reused then then the modifications should ensure correctness
- * everywhere, or needs a new message ID as (1) above was not adhered to. If
- * not used anywhere, proceed with the required modification.
- * NOTE: Rules for message deletion
- * 4) Check (3) and if used anywhere else, then cannot be deleted. If not used
- * anywhere, then can be deleted, but will leave a hole by design, as
- * addition rules specify modification to the end of the list and not filling
- * holes.
- */
-
-#define GLUSTERD_COMP_BASE GLFS_MSGID_GLUSTERD
-#define GLFS_NUM_MESSAGES 20
-#define GLFS_MSGID_END (GLUSTERD_COMP_BASE + GLFS_NUM_MESSAGES + 1)
-/* Messaged with message IDs */
-#define glfs_msg_start_x GLFS_COMP_BASE, "Invalid: Start of messages"
-/*------------*/
-
-/*!
- * @messageid 106001
- * @diagnosis Operation could not be performed because the server quorum was not
- * met
- * @recommendedaction Ensure that other peer nodes are online and reachable from
- * the local peer node
- */
-#define GD_MSG_SERVER_QUORUM_NOT_MET (GLUSTERD_COMP_BASE + 1)
-
-/*!
- * @messageid 106002
- * @diagnosis The local bricks belonging to the volume were killed because
- * the server-quorum was not met
- * @recommendedaction Ensure that other peer nodes are online and reachable from
- * the local peer node
- */
-#define GD_MSG_SERVER_QUORUM_LOST_STOPPING_BRICKS (GLUSTERD_COMP_BASE + 2)
-
-/*!
- * @messageid 106003
- * @diagnosis The local bricks belonging to the named volume were (re)started
- * because the server-quorum was met
- * @recommendedaction None
- */
-#define GD_MSG_SERVER_QUORUM_MET_STARTING_BRICKS (GLUSTERD_COMP_BASE + 3)
-
-/*!
- * @messageid 106004
- * @diagnosis Glusterd on the peer might be down or unreachable
- * @recommendedaction Check if glusterd is running on the peer node or if
- * the firewall rules are not blocking port 24007
- */
-#define GD_MSG_PEER_DISCONNECTED (GLUSTERD_COMP_BASE + 4)
-
-/*!
- * @messageid 106005
- * @diagnosis Brick process might be down
- * @recommendedaction Check brick log files to get more information on the cause
- * for the brick's offline status. To bring the brick back
- * online,run gluster volume start <VOLNAME> force
- */
-#define GD_MSG_BRICK_DISCONNECTED (GLUSTERD_COMP_BASE + 5)
-
-/*!
- * @messageid 106006
- * @diagnosis NFS Server or Self-heal daemon might be down
- * @recommendedaction Check nfs or self-heal daemon log files to get more
- * information on the cause for the brick's offline status.
- * To bring the brick back online, run gluster volume
- * start <VOLNAME> force
- */
-#define GD_MSG_NODE_DISCONNECTED (GLUSTERD_COMP_BASE + 6)
-
-/*!
- * @messageid 106007
- * @diagnosis Rebalance process might be down
- * @recommendedaction None
- */
-#define GD_MSG_REBALANCE_DISCONNECTED (GLUSTERD_COMP_BASE + 7)
-
-/*!
- * @messageid 106008
- * @diagnosis Volume cleanup failed
- * @recommendedaction None
- */
-#define GD_MSG_VOL_CLEANUP_FAIL (GLUSTERD_COMP_BASE + 8)
-
-/*!
- * @messageid 106009
- * @diagnosis Volume version mismatch while adding a peer
- * @recommendedaction None
- */
-#define GD_MSG_VOL_VERS_MISMATCH (GLUSTERD_COMP_BASE + 9)
-
-/*!
- * @messageid 106010
- * @diagnosis Volume checksum mismatch while adding a peer
- * @recommendedaction Check for which node the checksum mismatch happens
- * and delete the volume configuration files from it andi
- * restart glusterd
- */
-#define GD_MSG_CKSUM_VERS_MISMATCH (GLUSTERD_COMP_BASE + 10)
-
-/*!
- * @messageid 106011
- * @diagnosis A volume quota-conf version mismatch occured while adding a peer
- * @recommendedaction None
- */
-#define GD_MSG_QUOTA_CONFIG_VERS_MISMATCH (GLUSTERD_COMP_BASE + 11)
-
-/*!
- * @messageid 106012
- * @diagnosis A quota-conf checksum mismatch occured while adding a peer
- * @recommendedaction Check for which node the checksum mismatch happens
- * and delete the volume configuration files from it and
- * restart glusterd
- */
-#define GD_MSG_QUOTA_CONFIG_CKSUM_MISMATCH (GLUSTERD_COMP_BASE + 12)
-
-/*!
- * @messageid 106013
- * @diagnosis Brick process could not be terminated
- * @recommendedaction Find the pid of the brick process from the log file and
- * manually kill it
- */
-#define GD_MSG_BRICK_STOP_FAIL (GLUSTERD_COMP_BASE + 13)
-
-/*!
- * @messageid 106014
- * @diagnosis One of the listed services:NFS Server, Quota Daemon, Self Heal
- * Daemon, or brick process could not be brought offline
- * @recommendedaction Find the pid of the process from the log file and
- * manually kill it
- */
-#define GD_MSG_SVC_KILL_FAIL (GLUSTERD_COMP_BASE + 14)
-
-/*!
- * @messageid 106015
- * @diagnosis The process could not be killed with the specified PID
- * @recommendedaction None
- */
-#define GD_MSG_PID_KILL_FAIL (GLUSTERD_COMP_BASE + 15)
-
-/*!
- * @messageid 106016
- * @diagnosis Rebalance socket file is not found
- * @recommendedaction Rebalance failed as the socket file for rebalance is
- * missing. Restart the rebalance process
- */
-#define GD_MSG_REBAL_NO_SOCK_FILE (GLUSTERD_COMP_BASE + 16)
-
-/*!
- * @messageid 106017
- * @diagnosis Unix options could not be set
- * @recommendedaction Server is out of memory and needs a restart
- */
-#define GD_MSG_UNIX_OP_BUILD_FAIL (GLUSTERD_COMP_BASE + 17)
-
-/*!
- * @messageid 106018
- * @diagnosis RPC creation failed
- * @recommendedaction Rebalance failed as glusterd could not establish an RPC
- * connection. Check the log file for the exact reason of the
- * failure and then restart the rebalance process
- */
-#define GD_MSG_RPC_CREATE_FAIL (GLUSTERD_COMP_BASE + 18)
-
-/*!
- * @messageid 106019
- * @diagnosis The default options on volume could not be set with the volume
- * create and volume reset commands
- * @recommendedaction Check glusterd log files to see the exact reason for
- * failure to set default options
- */
-#define GD_MSG_FAIL_DEFAULT_OPT_SET (GLUSTERD_COMP_BASE + 19)
-
-/*!
- * @messageid 106020
- * @diagnosis Failed to release cluster wide lock for one of the peer
- * @recommendedaction Restart the glusterd service on the node where the command
- * was issued
- */
-#define GD_MSG_CLUSTER_UNLOCK_FAILED (GLUSTERD_COMP_BASE + 20)
-
-/*------------*/
-#define glfs_msg_end_x GLFS_MSGID_END, "Invalid: End of messages"
-
-#endif /* !_GLUSTERD_MESSAGES_H_ */
diff --git a/xlators/mgmt/glusterd/src/glusterd-mgmt-handler.c b/xlators/mgmt/glusterd/src/glusterd-mgmt-handler.c
deleted file mode 100644
index c0c1cfcba18..00000000000
--- a/xlators/mgmt/glusterd/src/glusterd-mgmt-handler.c
+++ /dev/null
@@ -1,930 +0,0 @@
-/*
- Copyright (c) 2013-2014 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.
-*/
-/* rpc related syncops */
-#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-utils.h"
-#include "glusterd-locks.h"
-#include "glusterd-mgmt.h"
-#include "glusterd-op-sm.h"
-
-static int
-glusterd_mgmt_v3_null (rpcsvc_request_t *req)
-{
- return 0;
-}
-
-static int
-glusterd_mgmt_v3_lock_send_resp (rpcsvc_request_t *req, int32_t status)
-{
-
- gd1_mgmt_v3_lock_rsp rsp = {{0},};
- int ret = -1;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (req);
-
- rsp.op_ret = status;
- if (rsp.op_ret)
- rsp.op_errno = errno;
-
- glusterd_get_uuid (&rsp.uuid);
-
- ret = glusterd_submit_reply (req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gd1_mgmt_v3_lock_rsp);
-
- gf_log (this->name, GF_LOG_DEBUG,
- "Responded to mgmt_v3 lock, ret: %d", ret);
-
- return ret;
-}
-
-static int
-glusterd_synctasked_mgmt_v3_lock (rpcsvc_request_t *req,
- gd1_mgmt_v3_lock_req *lock_req,
- glusterd_op_lock_ctx_t *ctx)
-{
- int32_t ret = -1;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (req);
- GF_ASSERT (ctx);
- GF_ASSERT (ctx->dict);
-
- /* Trying to acquire multiple mgmt_v3 locks */
- ret = glusterd_multiple_mgmt_v3_lock (ctx->dict, ctx->uuid);
- if (ret)
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to acquire mgmt_v3 locks for %s",
- uuid_utoa (ctx->uuid));
-
- ret = glusterd_mgmt_v3_lock_send_resp (req, ret);
-
- gf_log (this->name, GF_LOG_TRACE, "Returning %d", ret);
- return ret;
-}
-
-static int
-glusterd_op_state_machine_mgmt_v3_lock (rpcsvc_request_t *req,
- gd1_mgmt_v3_lock_req *lock_req,
- glusterd_op_lock_ctx_t *ctx)
-{
- int32_t ret = -1;
- xlator_t *this = NULL;
- glusterd_op_info_t txn_op_info = {{0},};
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (req);
-
- glusterd_txn_opinfo_init (&txn_op_info, NULL, &lock_req->op,
- ctx->dict, req);
-
- ret = glusterd_set_txn_opinfo (&lock_req->txn_id, &txn_op_info);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Unable to set transaction's opinfo");
- goto out;
- }
-
- ret = glusterd_op_sm_inject_event (GD_OP_EVENT_LOCK,
- &lock_req->txn_id, ctx);
- if (ret)
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to inject event GD_OP_EVENT_LOCK");
-
-out:
- glusterd_friend_sm ();
- glusterd_op_sm ();
-
- gf_log (this->name, GF_LOG_TRACE, "Returning %d", ret);
- return ret;
-}
-
-static int
-glusterd_handle_mgmt_v3_lock_fn (rpcsvc_request_t *req)
-{
- gd1_mgmt_v3_lock_req lock_req = {{0},};
- int32_t ret = -1;
- glusterd_op_lock_ctx_t *ctx = NULL;
- xlator_t *this = NULL;
- gf_boolean_t is_synctasked = _gf_false;
- gf_boolean_t free_ctx = _gf_false;
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (req);
-
- ret = xdr_to_generic (req->msg[0], &lock_req,
- (xdrproc_t)xdr_gd1_mgmt_v3_lock_req);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to decode lock "
- "request received from peer");
- req->rpc_err = GARBAGE_ARGS;
- goto out;
- }
-
- gf_log (this->name, GF_LOG_DEBUG, "Received mgmt_v3 lock req "
- "from uuid: %s", uuid_utoa (lock_req.uuid));
-
- if (glusterd_peerinfo_find_by_uuid (lock_req.uuid) == NULL) {
- 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);
- if (!ctx) {
- ret = -1;
- goto out;
- }
-
- uuid_copy (ctx->uuid, lock_req.uuid);
- ctx->req = req;
-
- ctx->dict = dict_new ();
- if (!ctx->dict) {
- ret = -1;
- goto out;
- }
-
- ret = dict_unserialize (lock_req.dict.dict_val,
- lock_req.dict.dict_len, &ctx->dict);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING,
- "failed to unserialize the dictionary");
- goto out;
- }
-
- is_synctasked = dict_get_str_boolean (ctx->dict,
- "is_synctasked", _gf_false);
- if (is_synctasked) {
- ret = glusterd_synctasked_mgmt_v3_lock (req, &lock_req, ctx);
- /* The above function does not take ownership of ctx.
- * Therefore we need to free the ctx explicitly. */
- free_ctx = _gf_true;
- }
- else {
- ret = glusterd_op_state_machine_mgmt_v3_lock (req, &lock_req,
- ctx);
- }
-
-out:
-
- if (ctx && (ret || free_ctx)) {
- if (ctx->dict)
- dict_unref (ctx->dict);
-
- GF_FREE (ctx);
- }
-
- free (lock_req.dict.dict_val);
-
- gf_log (this->name, GF_LOG_TRACE, "Returning %d", ret);
- return ret;
-}
-
-static int
-glusterd_mgmt_v3_pre_validate_send_resp (rpcsvc_request_t *req,
- int32_t op, int32_t status,
- char *op_errstr, dict_t *rsp_dict)
-{
- gd1_mgmt_v3_pre_val_rsp rsp = {{0},};
- int ret = -1;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (req);
-
- rsp.op_ret = status;
- glusterd_get_uuid (&rsp.uuid);
- rsp.op = op;
- if (op_errstr)
- rsp.op_errstr = op_errstr;
- else
- rsp.op_errstr = "";
-
- ret = dict_allocate_and_serialize (rsp_dict, &rsp.dict.dict_val,
- &rsp.dict.dict_len);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "failed to get serialized length of dict");
- goto out;
- }
-
- ret = glusterd_submit_reply (req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gd1_mgmt_v3_pre_val_rsp);
-
- GF_FREE (rsp.dict.dict_val);
-out:
- gf_log (this->name, GF_LOG_DEBUG,
- "Responded to pre validation, ret: %d", ret);
- return ret;
-}
-
-static int
-glusterd_handle_pre_validate_fn (rpcsvc_request_t *req)
-{
- int32_t ret = -1;
- gd1_mgmt_v3_pre_val_req op_req = {{0},};
- xlator_t *this = NULL;
- char *op_errstr = NULL;
- dict_t *dict = NULL;
- dict_t *rsp_dict = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (req);
-
- ret = xdr_to_generic (req->msg[0], &op_req,
- (xdrproc_t)xdr_gd1_mgmt_v3_pre_val_req);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to decode pre validation "
- "request received from peer");
- req->rpc_err = GARBAGE_ARGS;
- goto out;
- }
-
- if (glusterd_peerinfo_find_by_uuid (op_req.uuid) == NULL) {
- 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;
- }
-
- dict = dict_new ();
- if (!dict)
- goto out;
-
- ret = dict_unserialize (op_req.dict.dict_val,
- op_req.dict.dict_len, &dict);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING,
- "failed to unserialize the dictionary");
- goto out;
- }
-
- rsp_dict = dict_new ();
- if (!rsp_dict) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to get new dictionary");
- return -1;
- }
-
- ret = gd_mgmt_v3_pre_validate_fn (op_req.op, dict, &op_errstr,
- rsp_dict);
-
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Pre Validation failed on operation %s",
- gd_op_list[op_req.op]);
- }
-
- ret = glusterd_mgmt_v3_pre_validate_send_resp (req, op_req.op,
- ret, op_errstr,
- rsp_dict);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to send Pre Validation "
- "response for operation %s",
- gd_op_list[op_req.op]);
- goto out;
- }
-
-out:
- if (op_errstr && (strcmp (op_errstr, "")))
- GF_FREE (op_errstr);
-
- free (op_req.dict.dict_val);
-
- if (dict)
- dict_unref (dict);
-
- if (rsp_dict)
- dict_unref (rsp_dict);
-
- gf_log (this->name, GF_LOG_TRACE, "Returning %d", ret);
- return ret;
-}
-
-static int
-glusterd_mgmt_v3_brick_op_send_resp (rpcsvc_request_t *req,
- int32_t op, int32_t status,
- char *op_errstr, dict_t *rsp_dict)
-{
- gd1_mgmt_v3_brick_op_rsp rsp = {{0},};
- int ret = -1;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (req);
-
- rsp.op_ret = status;
- glusterd_get_uuid (&rsp.uuid);
- rsp.op = op;
- if (op_errstr)
- rsp.op_errstr = op_errstr;
- else
- rsp.op_errstr = "";
-
- ret = dict_allocate_and_serialize (rsp_dict, &rsp.dict.dict_val,
- &rsp.dict.dict_len);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "failed to get serialized length of dict");
- goto out;
- }
-
- ret = glusterd_submit_reply (req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gd1_mgmt_v3_brick_op_rsp);
-
- GF_FREE (rsp.dict.dict_val);
-out:
- gf_log (this->name, GF_LOG_DEBUG,
- "Responded to brick op, ret: %d", ret);
- return ret;
-}
-
-static int
-glusterd_handle_brick_op_fn (rpcsvc_request_t *req)
-{
- int32_t ret = -1;
- gd1_mgmt_v3_brick_op_req op_req = {{0},};
- xlator_t *this = NULL;
- char *op_errstr = NULL;
- dict_t *dict = NULL;
- dict_t *rsp_dict = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (req);
-
- ret = xdr_to_generic (req->msg[0], &op_req,
- (xdrproc_t)xdr_gd1_mgmt_v3_brick_op_req);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to decode brick op "
- "request received from peer");
- req->rpc_err = GARBAGE_ARGS;
- goto out;
- }
-
- if (glusterd_peerinfo_find_by_uuid (op_req.uuid) == NULL) {
- 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;
- }
-
- dict = dict_new ();
- if (!dict)
- goto out;
-
- ret = dict_unserialize (op_req.dict.dict_val,
- op_req.dict.dict_len, &dict);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING,
- "failed to unserialize the dictionary");
- goto out;
- }
-
- rsp_dict = dict_new ();
- if (!rsp_dict) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to get new dictionary");
- return -1;
- }
-
- ret = gd_mgmt_v3_brick_op_fn (op_req.op, dict, &op_errstr,
- rsp_dict);
-
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Brick Op failed on operation %s",
- gd_op_list[op_req.op]);
- }
-
- ret = glusterd_mgmt_v3_brick_op_send_resp (req, op_req.op,
- ret, op_errstr,
- rsp_dict);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to send brick op "
- "response for operation %s",
- gd_op_list[op_req.op]);
- goto out;
- }
-
-out:
- if (op_errstr && (strcmp (op_errstr, "")))
- GF_FREE (op_errstr);
-
- free (op_req.dict.dict_val);
-
- if (dict)
- dict_unref (dict);
-
- if (rsp_dict)
- dict_unref (rsp_dict);
-
- gf_log (this->name, GF_LOG_TRACE, "Returning %d", ret);
- return ret;
-}
-
-static int
-glusterd_mgmt_v3_commit_send_resp (rpcsvc_request_t *req,
- int32_t op, int32_t status,
- char *op_errstr, dict_t *rsp_dict)
-{
- gd1_mgmt_v3_commit_rsp rsp = {{0},};
- int ret = -1;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (req);
-
- rsp.op_ret = status;
- glusterd_get_uuid (&rsp.uuid);
- rsp.op = op;
- if (op_errstr)
- rsp.op_errstr = op_errstr;
- else
- rsp.op_errstr = "";
-
- ret = dict_allocate_and_serialize (rsp_dict, &rsp.dict.dict_val,
- &rsp.dict.dict_len);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "failed to get serialized length of dict");
- goto out;
- }
-
- ret = glusterd_submit_reply (req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gd1_mgmt_v3_commit_rsp);
-
- GF_FREE (rsp.dict.dict_val);
-out:
- gf_log (this->name, GF_LOG_DEBUG, "Responded to commit, ret: %d", ret);
- return ret;
-}
-
-static int
-glusterd_handle_commit_fn (rpcsvc_request_t *req)
-{
- int32_t ret = -1;
- gd1_mgmt_v3_commit_req op_req = {{0},};
- xlator_t *this = NULL;
- char *op_errstr = NULL;
- dict_t *dict = NULL;
- dict_t *rsp_dict = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (req);
-
- ret = xdr_to_generic (req->msg[0], &op_req,
- (xdrproc_t)xdr_gd1_mgmt_v3_commit_req);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to decode commit "
- "request received from peer");
- req->rpc_err = GARBAGE_ARGS;
- goto out;
- }
-
- if (glusterd_peerinfo_find_by_uuid (op_req.uuid) == NULL) {
- 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;
- }
-
- dict = dict_new ();
- if (!dict)
- goto out;
-
- ret = dict_unserialize (op_req.dict.dict_val,
- op_req.dict.dict_len, &dict);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING,
- "failed to unserialize the dictionary");
- goto out;
- }
-
- rsp_dict = dict_new ();
- if (!rsp_dict) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to get new dictionary");
- return -1;
- }
-
- ret = gd_mgmt_v3_commit_fn (op_req.op, dict, &op_errstr,
- rsp_dict);
-
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "commit failed on operation %s",
- gd_op_list[op_req.op]);
- }
-
- ret = glusterd_mgmt_v3_commit_send_resp (req, op_req.op,
- ret, op_errstr,
- rsp_dict);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to send commit "
- "response for operation %s",
- gd_op_list[op_req.op]);
- goto out;
- }
-
-out:
- if (op_errstr && (strcmp (op_errstr, "")))
- GF_FREE (op_errstr);
-
- free (op_req.dict.dict_val);
-
- if (dict)
- dict_unref (dict);
-
- if (rsp_dict)
- dict_unref (rsp_dict);
-
- gf_log (this->name, GF_LOG_TRACE, "Returning %d", ret);
- return ret;
-}
-
-static int
-glusterd_mgmt_v3_post_validate_send_resp (rpcsvc_request_t *req,
- int32_t op, int32_t status,
- char *op_errstr, dict_t *rsp_dict)
-{
- gd1_mgmt_v3_post_val_rsp rsp = {{0},};
- int ret = -1;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (req);
-
- rsp.op_ret = status;
- glusterd_get_uuid (&rsp.uuid);
- rsp.op = op;
- if (op_errstr)
- rsp.op_errstr = op_errstr;
- else
- rsp.op_errstr = "";
-
- ret = dict_allocate_and_serialize (rsp_dict, &rsp.dict.dict_val,
- &rsp.dict.dict_len);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "failed to get serialized length of dict");
- goto out;
- }
-
- ret = glusterd_submit_reply (req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gd1_mgmt_v3_post_val_rsp);
-
- GF_FREE (rsp.dict.dict_val);
-out:
- gf_log (this->name, GF_LOG_DEBUG,
- "Responded to post validation, ret: %d", ret);
- return ret;
-}
-
-static int
-glusterd_handle_post_validate_fn (rpcsvc_request_t *req)
-{
- int32_t ret = -1;
- gd1_mgmt_v3_post_val_req op_req = {{0},};
- xlator_t *this = NULL;
- char *op_errstr = NULL;
- dict_t *dict = NULL;
- dict_t *rsp_dict = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (req);
-
- ret = xdr_to_generic (req->msg[0], &op_req,
- (xdrproc_t)xdr_gd1_mgmt_v3_post_val_req);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to decode post validation "
- "request received from peer");
- req->rpc_err = GARBAGE_ARGS;
- goto out;
- }
-
- if (glusterd_peerinfo_find_by_uuid (op_req.uuid) == NULL) {
- 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;
- }
-
- dict = dict_new ();
- if (!dict)
- goto out;
-
- ret = dict_unserialize (op_req.dict.dict_val,
- op_req.dict.dict_len, &dict);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING,
- "failed to unserialize the dictionary");
- goto out;
- }
-
- rsp_dict = dict_new ();
- if (!rsp_dict) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to get new dictionary");
- return -1;
- }
-
- ret = gd_mgmt_v3_post_validate_fn (op_req.op, op_req.op_ret, dict,
- &op_errstr, rsp_dict);
-
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Post Validation failed on operation %s",
- gd_op_list[op_req.op]);
- }
-
- ret = glusterd_mgmt_v3_post_validate_send_resp (req, op_req.op,
- ret, op_errstr,
- rsp_dict);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to send Post Validation "
- "response for operation %s",
- gd_op_list[op_req.op]);
- goto out;
- }
-
-out:
- if (op_errstr && (strcmp (op_errstr, "")))
- GF_FREE (op_errstr);
-
- free (op_req.dict.dict_val);
-
- if (dict)
- dict_unref (dict);
-
- if (rsp_dict)
- dict_unref (rsp_dict);
-
- gf_log (this->name, GF_LOG_TRACE, "Returning %d", ret);
- return ret;
-}
-
-static int
-glusterd_mgmt_v3_unlock_send_resp (rpcsvc_request_t *req, int32_t status)
-{
-
- gd1_mgmt_v3_unlock_rsp rsp = {{0},};
- int ret = -1;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (req);
-
- rsp.op_ret = status;
- if (rsp.op_ret)
- rsp.op_errno = errno;
-
- glusterd_get_uuid (&rsp.uuid);
-
- ret = glusterd_submit_reply (req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gd1_mgmt_v3_unlock_rsp);
-
- gf_log (this->name, GF_LOG_DEBUG,
- "Responded to mgmt_v3 unlock, ret: %d", ret);
-
- return ret;
-}
-
-static int
-glusterd_syctasked_mgmt_v3_unlock (rpcsvc_request_t *req,
- gd1_mgmt_v3_unlock_req *unlock_req,
- glusterd_op_lock_ctx_t *ctx)
-{
- int32_t ret = -1;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (req);
- GF_ASSERT (ctx);
-
- /* Trying to release multiple mgmt_v3 locks */
- ret = glusterd_multiple_mgmt_v3_unlock (ctx->dict, ctx->uuid);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to release mgmt_v3 locks for %s",
- uuid_utoa(ctx->uuid));
- }
-
- ret = glusterd_mgmt_v3_unlock_send_resp (req, ret);
-
- gf_log (this->name, GF_LOG_TRACE, "Returning %d", ret);
- return ret;
-}
-
-
-static int
-glusterd_op_state_machine_mgmt_v3_unlock (rpcsvc_request_t *req,
- gd1_mgmt_v3_unlock_req *lock_req,
- glusterd_op_lock_ctx_t *ctx)
-{
- int32_t ret = -1;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (req);
-
- ret = glusterd_op_sm_inject_event (GD_OP_EVENT_UNLOCK,
- &lock_req->txn_id, ctx);
- if (ret)
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to inject event GD_OP_EVENT_UNLOCK");
-
- glusterd_friend_sm ();
- glusterd_op_sm ();
-
- gf_log (this->name, GF_LOG_TRACE, "Returning %d", ret);
- return ret;
-}
-
-static int
-glusterd_handle_mgmt_v3_unlock_fn (rpcsvc_request_t *req)
-{
- gd1_mgmt_v3_unlock_req lock_req = {{0},};
- int32_t ret = -1;
- glusterd_op_lock_ctx_t *ctx = NULL;
- xlator_t *this = NULL;
- gf_boolean_t is_synctasked = _gf_false;
- gf_boolean_t free_ctx = _gf_false;
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (req);
-
- ret = xdr_to_generic (req->msg[0], &lock_req,
- (xdrproc_t)xdr_gd1_mgmt_v3_unlock_req);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to decode unlock "
- "request received from peer");
- req->rpc_err = GARBAGE_ARGS;
- goto out;
- }
-
- gf_log (this->name, GF_LOG_DEBUG, "Received volume unlock req "
- "from uuid: %s", uuid_utoa (lock_req.uuid));
-
- if (glusterd_peerinfo_find_by_uuid (lock_req.uuid) == NULL) {
- 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);
- if (!ctx) {
- ret = -1;
- goto out;
- }
-
- uuid_copy (ctx->uuid, lock_req.uuid);
- ctx->req = req;
-
- ctx->dict = dict_new ();
- if (!ctx->dict) {
- ret = -1;
- goto out;
- }
-
- ret = dict_unserialize (lock_req.dict.dict_val,
- lock_req.dict.dict_len, &ctx->dict);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING,
- "failed to unserialize the dictionary");
- goto out;
- }
-
- is_synctasked = dict_get_str_boolean (ctx->dict,
- "is_synctasked", _gf_false);
- if (is_synctasked) {
- ret = glusterd_syctasked_mgmt_v3_unlock (req, &lock_req, ctx);
- /* The above function does not take ownership of ctx.
- * Therefore we need to free the ctx explicitly. */
- free_ctx = _gf_true;
- }
- else {
- ret = glusterd_op_state_machine_mgmt_v3_unlock (req, &lock_req,
- ctx);
- }
-
-out:
-
- if (ctx && (ret || free_ctx)) {
- if (ctx->dict)
- dict_unref (ctx->dict);
-
- GF_FREE (ctx);
- }
-
- free (lock_req.dict.dict_val);
-
- gf_log (this->name, GF_LOG_TRACE, "Returning %d", ret);
- return ret;
-}
-
-int
-glusterd_handle_mgmt_v3_lock (rpcsvc_request_t *req)
-{
- return glusterd_big_locked_handler (req,
- glusterd_handle_mgmt_v3_lock_fn);
-}
-
-static int
-glusterd_handle_pre_validate (rpcsvc_request_t *req)
-{
- return glusterd_big_locked_handler (req,
- glusterd_handle_pre_validate_fn);
-}
-
-static int
-glusterd_handle_brick_op (rpcsvc_request_t *req)
-{
- return glusterd_big_locked_handler (req,
- glusterd_handle_brick_op_fn);
-}
-
-static int
-glusterd_handle_commit (rpcsvc_request_t *req)
-{
- return glusterd_big_locked_handler (req,
- glusterd_handle_commit_fn);
-}
-
-static int
-glusterd_handle_post_validate (rpcsvc_request_t *req)
-{
- return glusterd_big_locked_handler (req,
- glusterd_handle_post_validate_fn);
-}
-
-int
-glusterd_handle_mgmt_v3_unlock (rpcsvc_request_t *req)
-{
- return glusterd_big_locked_handler (req,
- glusterd_handle_mgmt_v3_unlock_fn);
-}
-
-rpcsvc_actor_t gd_svc_mgmt_v3_actors[GLUSTERD_MGMT_V3_MAXVALUE] = {
- [GLUSTERD_MGMT_V3_NULL] = { "NULL", GLUSTERD_MGMT_V3_NULL, glusterd_mgmt_v3_null, NULL, 0, DRC_NA},
- [GLUSTERD_MGMT_V3_LOCK] = { "MGMT_V3_LOCK", GLUSTERD_MGMT_V3_LOCK, glusterd_handle_mgmt_v3_lock, NULL, 0, DRC_NA},
- [GLUSTERD_MGMT_V3_PRE_VALIDATE] = { "PRE_VAL", GLUSTERD_MGMT_V3_PRE_VALIDATE, glusterd_handle_pre_validate, NULL, 0, DRC_NA},
- [GLUSTERD_MGMT_V3_BRICK_OP] = { "BRCK_OP", GLUSTERD_MGMT_V3_BRICK_OP, glusterd_handle_brick_op, NULL, 0, DRC_NA},
- [GLUSTERD_MGMT_V3_COMMIT] = { "COMMIT", GLUSTERD_MGMT_V3_COMMIT, glusterd_handle_commit, NULL, 0, DRC_NA},
- [GLUSTERD_MGMT_V3_POST_VALIDATE] = { "POST_VAL", GLUSTERD_MGMT_V3_POST_VALIDATE, glusterd_handle_post_validate, NULL, 0, DRC_NA},
- [GLUSTERD_MGMT_V3_UNLOCK] = { "MGMT_V3_UNLOCK", GLUSTERD_MGMT_V3_UNLOCK, glusterd_handle_mgmt_v3_unlock, NULL, 0, DRC_NA},
-};
-
-struct rpcsvc_program gd_svc_mgmt_v3_prog = {
- .progname = "GlusterD svc mgmt v3",
- .prognum = GD_MGMT_PROGRAM,
- .progver = GD_MGMT_V3_VERSION,
- .numactors = GLUSTERD_MGMT_V3_MAXVALUE,
- .actors = gd_svc_mgmt_v3_actors,
- .synctask = _gf_true,
-};
diff --git a/xlators/mgmt/glusterd/src/glusterd-mgmt.c b/xlators/mgmt/glusterd/src/glusterd-mgmt.c
deleted file mode 100644
index 1c99f92e114..00000000000
--- a/xlators/mgmt/glusterd/src/glusterd-mgmt.c
+++ /dev/null
@@ -1,2011 +0,0 @@
-/*
- Copyright (c) 2013-2014 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.
-*/
-/* rpc related syncops */
-#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-utils.h"
-#include "glusterd-locks.h"
-#include "glusterd-mgmt.h"
-#include "glusterd-op-sm.h"
-#include "glusterd-volgen.h"
-#include "glusterd-store.h"
-
-extern struct rpc_clnt_program gd_mgmt_v3_prog;
-
-
-void
-gd_mgmt_v3_collate_errors (struct syncargs *args, int op_ret, int op_errno,
- char *op_errstr, int op_code,
- glusterd_peerinfo_t *peerinfo, u_char *uuid)
-{
- char *peer_str = NULL;
- char err_str[PATH_MAX] = "Please check log file for details.";
- char op_err[PATH_MAX] = "";
- int32_t len = -1;
- xlator_t *this = NULL;
- int is_operrstr_blk = 0;
- char *err_string = NULL;
- char *cli_err_str = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (args);
- GF_ASSERT (uuid);
-
- if (op_ret) {
- args->op_ret = op_ret;
- args->op_errno = op_errno;
-
- if (peerinfo)
- peer_str = peerinfo->hostname;
- else
- peer_str = uuid_utoa (uuid);
-
- is_operrstr_blk = (op_errstr && strcmp (op_errstr, ""));
- err_string = (is_operrstr_blk) ? op_errstr : err_str;
-
- switch (op_code) {
- case GLUSTERD_MGMT_V3_LOCK:
- {
- len = snprintf (op_err, sizeof(op_err),
- "Locking failed "
- "on %s. %s", peer_str,
- err_string);
- break;
- }
- case GLUSTERD_MGMT_V3_PRE_VALIDATE:
- {
- len = snprintf (op_err, sizeof(op_err),
- "Pre Validation failed "
- "on %s. %s", peer_str,
- err_string);
- break;
- }
- case GLUSTERD_MGMT_V3_BRICK_OP:
- {
- len = snprintf (op_err, sizeof(op_err),
- "Brick ops failed "
- "on %s. %s", peer_str,
- err_string);
- break;
- }
- case GLUSTERD_MGMT_V3_COMMIT:
- {
- len = snprintf (op_err, sizeof(op_err),
- "Commit failed"
- " on %s. %s", peer_str,
- err_string);
- break;
- }
- case GLUSTERD_MGMT_V3_POST_VALIDATE:
- {
- len = snprintf (op_err, sizeof(op_err),
- "Post Validation failed "
- "on %s. %s", peer_str,
- err_string);
- break;
- }
- case GLUSTERD_MGMT_V3_UNLOCK:
- {
- len = snprintf (op_err, sizeof(op_err),
- "Unlocking failed "
- "on %s. %s", peer_str,
- err_string);
- break;
- }
- default :
- len = snprintf (op_err, sizeof(op_err),
- "Unknown error! "
- "on %s. %s", peer_str,
- err_string);
- }
-
- cli_err_str = ((is_operrstr_blk) ? op_errstr : op_err);
-
- if (args->errstr) {
- len = snprintf (err_str, sizeof(err_str),
- "%s\n%s", args->errstr,
- cli_err_str);
- GF_FREE (args->errstr);
- args->errstr = NULL;
- } else
- len = snprintf (err_str, sizeof(err_str),
- "%s", cli_err_str);
-
- gf_log (this->name, GF_LOG_ERROR, "%s", op_err);
- args->errstr = gf_strdup (err_str);
- }
-
- return;
-}
-
-int32_t
-gd_mgmt_v3_pre_validate_fn (glusterd_op_t op, dict_t *dict,
- char **op_errstr, dict_t *rsp_dict)
-{
- int32_t ret = -1;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (dict);
- GF_ASSERT (op_errstr);
- GF_ASSERT (rsp_dict);
-
- switch (op) {
- case GD_OP_SNAP:
- ret = glusterd_snapshot_prevalidate (dict, op_errstr,
- rsp_dict);
-
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING,
- "Snapshot Prevalidate Failed");
- goto out;
- }
-
- break;
-
- default:
- break;
- }
-
- ret = 0;
-out:
- gf_log (this->name, GF_LOG_DEBUG, "OP = %d. Returning %d", op, ret);
- return ret;
-}
-
-int32_t
-gd_mgmt_v3_brick_op_fn (glusterd_op_t op, dict_t *dict,
- char **op_errstr, dict_t *rsp_dict)
-{
- int32_t ret = -1;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (dict);
- GF_ASSERT (op_errstr);
- GF_ASSERT (rsp_dict);
-
- switch (op) {
- case GD_OP_SNAP:
- {
- ret = glusterd_snapshot_brickop (dict, op_errstr, rsp_dict);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING, "snapshot brickop "
- "failed");
- goto out;
- }
- break;
- }
- default:
- break;
- }
-
- ret = 0;
-out:
- gf_log (this->name, GF_LOG_TRACE, "OP = %d. Returning %d", op, ret);
- return ret;
-}
-
-int32_t
-gd_mgmt_v3_commit_fn (glusterd_op_t op, dict_t *dict,
- char **op_errstr, dict_t *rsp_dict)
-{
- int32_t ret = -1;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (dict);
- GF_ASSERT (op_errstr);
- GF_ASSERT (rsp_dict);
-
- switch (op) {
- case GD_OP_SNAP:
- {
- ret = glusterd_snapshot (dict, op_errstr, rsp_dict);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING,
- "Snapshot Commit Failed");
- goto out;
- }
- break;
- }
- default:
- break;
- }
-
- ret = 0;
-out:
- gf_log (this->name, GF_LOG_DEBUG, "OP = %d. Returning %d", op, ret);
- return ret;
-}
-
-int32_t
-gd_mgmt_v3_post_validate_fn (glusterd_op_t op, int32_t op_ret, dict_t *dict,
- char **op_errstr, dict_t *rsp_dict)
-{
- int32_t ret = -1;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (dict);
- GF_ASSERT (op_errstr);
- GF_ASSERT (rsp_dict);
-
- switch (op) {
- case GD_OP_SNAP:
- {
- ret = glusterd_snapshot_postvalidate (dict, op_ret,
- op_errstr,
- rsp_dict);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING,
- "postvalidate operation failed");
- goto out;
- }
- break;
- }
- default:
- break;
- }
-
- ret = 0;
-
-out:
- gf_log (this->name, GF_LOG_TRACE, "OP = %d. Returning %d", op, ret);
- return ret;
-}
-
-int32_t
-gd_mgmt_v3_lock_cbk_fn (struct rpc_req *req, struct iovec *iov,
- int count, void *myframe)
-{
- int32_t ret = -1;
- struct syncargs *args = NULL;
- glusterd_peerinfo_t *peerinfo = NULL;
- gd1_mgmt_v3_lock_rsp rsp = {{0},};
- call_frame_t *frame = NULL;
- int32_t op_ret = -1;
- int32_t op_errno = -1;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (req);
- GF_ASSERT (myframe);
-
- /* Even though the lock command has failed, while collating the errors
- (gd_mgmt_v3_collate_errors), args->op_ret and args->op_errno will be
- used. @args is obtained from frame->local. So before checking the
- status of the request and going out if its a failure, args should be
- set to frame->local. Otherwise, while collating args will be NULL.
- This applies to other phases such as prevalidate, brickop, commit and
- postvalidate also.
- */
- frame = myframe;
- args = frame->local;
- peerinfo = frame->cookie;
- frame->local = NULL;
- frame->cookie = NULL;
-
- if (-1 == req->rpc_status) {
- op_errno = ENOTCONN;
- goto out;
- }
-
- if (!iov) {
- gf_log (this->name, GF_LOG_ERROR, "iov is NULL");
- op_errno = EINVAL;
- goto out;
- }
-
- ret = xdr_to_generic (*iov, &rsp,
- (xdrproc_t)xdr_gd1_mgmt_v3_lock_rsp);
- if (ret < 0)
- goto out;
-
- uuid_copy (args->uuid, rsp.uuid);
-
- op_ret = rsp.op_ret;
- op_errno = rsp.op_errno;
-
-out:
- gd_mgmt_v3_collate_errors (args, op_ret, op_errno, NULL,
- GLUSTERD_MGMT_V3_LOCK,
- peerinfo, rsp.uuid);
- if (rsp.dict.dict_val)
- free (rsp.dict.dict_val);
- STACK_DESTROY (frame->root);
- synctask_barrier_wake(args);
- return 0;
-}
-
-int32_t
-gd_mgmt_v3_lock_cbk (struct rpc_req *req, struct iovec *iov,
- int count, void *myframe)
-{
- return glusterd_big_locked_cbk (req, iov, count, myframe,
- gd_mgmt_v3_lock_cbk_fn);
-}
-
-int
-gd_mgmt_v3_lock (glusterd_op_t op, dict_t *op_ctx,
- glusterd_peerinfo_t *peerinfo,
- struct syncargs *args, uuid_t my_uuid,
- uuid_t recv_uuid)
-{
- gd1_mgmt_v3_lock_req req = {{0},};
- glusterd_conf_t *conf = THIS->private;
- int32_t ret = -1;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (op_ctx);
- GF_ASSERT (peerinfo);
- GF_ASSERT (args);
-
- ret = dict_allocate_and_serialize (op_ctx,
- &req.dict.dict_val,
- &req.dict.dict_len);
- if (ret)
- goto out;
-
- uuid_copy (req.uuid, my_uuid);
- req.op = op;
- synclock_unlock (&conf->big_lock);
- ret = gd_syncop_submit_request (peerinfo->rpc, &req, args, peerinfo,
- &gd_mgmt_v3_prog,
- GLUSTERD_MGMT_V3_LOCK,
- gd_mgmt_v3_lock_cbk,
- (xdrproc_t) xdr_gd1_mgmt_v3_lock_req);
- synclock_lock (&conf->big_lock);
-out:
- GF_FREE (req.dict.dict_val);
- gf_log (this->name, GF_LOG_TRACE, "Returning %d", ret);
- return ret;
-}
-
-int
-glusterd_mgmt_v3_initiate_lockdown (glusterd_op_t op, dict_t *dict,
- char **op_errstr, int npeers,
- gf_boolean_t *is_acquired,
- struct list_head *peers)
-{
- char *volname = NULL;
- glusterd_peerinfo_t *peerinfo = NULL;
- int32_t ret = -1;
- int32_t peer_cnt = 0;
- struct syncargs args = {0};
- uuid_t peer_uuid = {0};
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (dict);
- GF_ASSERT (op_errstr);
- GF_ASSERT (is_acquired);
-
- /* Trying to acquire multiple mgmt_v3 locks on local node */
- ret = glusterd_multiple_mgmt_v3_lock (dict, MY_UUID);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to acquire mgmt_v3 locks on localhost");
- goto out;
- }
-
- *is_acquired = _gf_true;
-
- if (!npeers) {
- ret = 0;
- goto out;
- }
-
- /* Sending mgmt_v3 lock req to other nodes in the cluster */
- gd_syncargs_init (&args, NULL);
- synctask_barrier_init((&args));
- peer_cnt = 0;
- list_for_each_local_xaction_peers (peerinfo, peers) {
- gd_mgmt_v3_lock (op, dict, peerinfo, &args,
- MY_UUID, peer_uuid);
- peer_cnt++;
- }
- gd_synctask_barrier_wait((&args), peer_cnt);
-
- if (args.errstr)
- *op_errstr = gf_strdup (args.errstr);
-
- ret = args.op_ret;
-
- gf_log (this->name, GF_LOG_DEBUG, "Sent lock op req for %s "
- "to %d peers. Returning %d", gd_op_list[op], peer_cnt, ret);
-out:
- if (ret) {
- if (*op_errstr)
- gf_log (this->name, GF_LOG_ERROR, "%s",
- *op_errstr);
-
- if (volname)
- ret = gf_asprintf (op_errstr,
- "Another transaction is in progress "
- "for %s. Please try again after "
- "sometime.", volname);
- else
- ret = gf_asprintf (op_errstr,
- "Another transaction is in progress "
- "Please try again after sometime.");
-
- if (ret == -1)
- *op_errstr = NULL;
-
- ret = -1;
- }
-
- return ret;
-}
-
-int
-glusterd_pre_validate_aggr_rsp_dict (glusterd_op_t op,
- dict_t *aggr, dict_t *rsp)
-{
- int32_t ret = 0;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (aggr);
- GF_ASSERT (rsp);
-
- switch (op) {
- case GD_OP_SNAP:
- ret = glusterd_snap_pre_validate_use_rsp_dict (aggr, rsp);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to aggregate prevalidate "
- "response dictionaries.");
- goto out;
- }
- break;
- default:
- ret = -1;
- gf_log (this->name, GF_LOG_ERROR, "Invalid op (%s)",
- gd_op_list[op]);
-
- break;
- }
-out:
- return ret;
-}
-
-int32_t
-gd_mgmt_v3_pre_validate_cbk_fn (struct rpc_req *req, struct iovec *iov,
- int count, void *myframe)
-{
- int32_t ret = -1;
- struct syncargs *args = NULL;
- glusterd_peerinfo_t *peerinfo = NULL;
- gd1_mgmt_v3_pre_val_rsp rsp = {{0},};
- call_frame_t *frame = NULL;
- int32_t op_ret = -1;
- int32_t op_errno = -1;
- dict_t *rsp_dict = NULL;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (req);
- GF_ASSERT (myframe);
-
- frame = myframe;
- args = frame->local;
- peerinfo = frame->cookie;
- frame->local = NULL;
- frame->cookie = NULL;
-
- if (-1 == req->rpc_status) {
- op_errno = ENOTCONN;
- goto out;
- }
-
- if (!iov) {
- gf_log (this->name, GF_LOG_ERROR, "iov is NULL");
- op_errno = EINVAL;
- }
-
- ret = xdr_to_generic (*iov, &rsp,
- (xdrproc_t)xdr_gd1_mgmt_v3_pre_val_rsp);
- if (ret < 0)
- goto out;
-
- if (rsp.dict.dict_len) {
- /* Unserialize the dictionary */
- rsp_dict = dict_new ();
-
- ret = dict_unserialize (rsp.dict.dict_val,
- rsp.dict.dict_len,
- &rsp_dict);
- if (ret < 0) {
- free (rsp.dict.dict_val);
- goto out;
- } else {
- rsp_dict->extra_stdfree = rsp.dict.dict_val;
- }
- }
-
- uuid_copy (args->uuid, rsp.uuid);
- pthread_mutex_lock (&args->lock_dict);
- {
- ret = glusterd_pre_validate_aggr_rsp_dict (rsp.op, args->dict,
- rsp_dict);
- }
- pthread_mutex_unlock (&args->lock_dict);
-
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "%s",
- "Failed to aggregate response from "
- " node/brick");
- if (!rsp.op_ret)
- op_ret = ret;
- else {
- op_ret = rsp.op_ret;
- op_errno = rsp.op_errno;
- }
- } else {
- op_ret = rsp.op_ret;
- op_errno = rsp.op_errno;
- }
-
-out:
- if (rsp_dict)
- dict_unref (rsp_dict);
-
- gd_mgmt_v3_collate_errors (args, op_ret, op_errno, rsp.op_errstr,
- GLUSTERD_MGMT_V3_PRE_VALIDATE,
- peerinfo, rsp.uuid);
-
- if (rsp.op_errstr)
- free (rsp.op_errstr);
-
- STACK_DESTROY (frame->root);
- synctask_barrier_wake(args);
- return 0;
-}
-
-int32_t
-gd_mgmt_v3_pre_validate_cbk (struct rpc_req *req, struct iovec *iov,
- int count, void *myframe)
-{
- return glusterd_big_locked_cbk (req, iov, count, myframe,
- gd_mgmt_v3_pre_validate_cbk_fn);
-}
-
-int
-gd_mgmt_v3_pre_validate_req (glusterd_op_t op, dict_t *op_ctx,
- glusterd_peerinfo_t *peerinfo,
- struct syncargs *args, uuid_t my_uuid,
- uuid_t recv_uuid)
-{
- int32_t ret = -1;
- gd1_mgmt_v3_pre_val_req req = {{0},};
- glusterd_conf_t *conf = THIS->private;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (op_ctx);
- GF_ASSERT (peerinfo);
- GF_ASSERT (args);
-
- ret = dict_allocate_and_serialize (op_ctx,
- &req.dict.dict_val,
- &req.dict.dict_len);
- if (ret)
- goto out;
-
- uuid_copy (req.uuid, my_uuid);
- req.op = op;
- synclock_unlock (&conf->big_lock);
- ret = gd_syncop_submit_request (peerinfo->rpc, &req, args, peerinfo,
- &gd_mgmt_v3_prog,
- GLUSTERD_MGMT_V3_PRE_VALIDATE,
- gd_mgmt_v3_pre_validate_cbk,
- (xdrproc_t) xdr_gd1_mgmt_v3_pre_val_req);
- synclock_lock (&conf->big_lock);
-out:
- GF_FREE (req.dict.dict_val);
- gf_log (this->name, GF_LOG_TRACE, "Returning %d", ret);
- return ret;
-}
-
-int
-glusterd_mgmt_v3_pre_validate (glusterd_op_t op, dict_t *req_dict,
- char **op_errstr, int npeers,
- struct list_head *peers)
-{
- int32_t ret = -1;
- int32_t peer_cnt = 0;
- dict_t *rsp_dict = NULL;
- glusterd_peerinfo_t *peerinfo = NULL;
- struct syncargs args = {0};
- uuid_t peer_uuid = {0};
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (req_dict);
- GF_ASSERT (op_errstr);
-
- rsp_dict = dict_new ();
- if (!rsp_dict) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to create response dictionary");
- goto out;
- }
-
- /* Pre Validation on local node */
- ret = gd_mgmt_v3_pre_validate_fn (op, req_dict, op_errstr,
- rsp_dict);
-
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Pre Validation failed for "
- "operation %s on local node",
- gd_op_list[op]);
-
- if (*op_errstr == NULL) {
- ret = gf_asprintf (op_errstr,
- "Pre-validation failed "
- "on localhost. Please "
- "check log file for details");
- if (ret == -1)
- *op_errstr = NULL;
-
- ret = -1;
- }
- goto out;
- }
-
- ret = glusterd_pre_validate_aggr_rsp_dict (op, req_dict,
- rsp_dict);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "%s",
- "Failed to aggregate response from "
- " node/brick");
- goto out;
- }
-
- dict_unref (rsp_dict);
- rsp_dict = NULL;
-
- if (!npeers) {
- ret = 0;
- goto out;
- }
-
- /* Sending Pre Validation req to other nodes in the cluster */
- gd_syncargs_init (&args, req_dict);
- synctask_barrier_init((&args));
- peer_cnt = 0;
- list_for_each_local_xaction_peers (peerinfo, peers) {
- gd_mgmt_v3_pre_validate_req (op, req_dict, peerinfo, &args,
- MY_UUID, peer_uuid);
- peer_cnt++;
- }
- gd_synctask_barrier_wait((&args), peer_cnt);
-
- if (args.op_ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Pre Validation failed on peers");
-
- if (args.errstr)
- *op_errstr = gf_strdup (args.errstr);
- }
-
- ret = args.op_ret;
-
- gf_log (this->name, GF_LOG_DEBUG, "Sent pre valaidation req for %s "
- "to %d peers. Returning %d", gd_op_list[op], peer_cnt, ret);
-out:
- return ret;
-}
-
-int
-glusterd_mgmt_v3_build_payload (dict_t **req, char **op_errstr, dict_t *dict,
- glusterd_op_t op)
-{
- int32_t ret = -1;
- dict_t *req_dict = NULL;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (req);
- GF_ASSERT (op_errstr);
- GF_ASSERT (dict);
-
- req_dict = dict_new ();
- if (!req_dict)
- goto out;
-
- switch (op) {
- case GD_OP_SNAP:
- dict_copy (dict, req_dict);
- break;
- default:
- break;
- }
-
- *req = req_dict;
- ret = 0;
-out:
- return ret;
-}
-
-int32_t
-gd_mgmt_v3_brick_op_cbk_fn (struct rpc_req *req, struct iovec *iov,
- int count, void *myframe)
-{
- int32_t ret = -1;
- struct syncargs *args = NULL;
- glusterd_peerinfo_t *peerinfo = NULL;
- gd1_mgmt_v3_brick_op_rsp rsp = {{0},};
- call_frame_t *frame = NULL;
- int32_t op_ret = -1;
- int32_t op_errno = -1;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (req);
- GF_ASSERT (myframe);
-
- frame = myframe;
- args = frame->local;
- peerinfo = frame->cookie;
- frame->local = NULL;
- frame->cookie = NULL;
-
- /* If the operation failed, then iov can be NULL. So better check the
- status of the operation and then worry about iov (if the status of
- the command is success)
- */
- if (-1 == req->rpc_status) {
- op_errno = ENOTCONN;
- goto out;
- }
-
- if (!iov) {
- gf_log (this->name, GF_LOG_ERROR, "iov is NULL");
- op_errno = EINVAL;
- goto out;
- }
-
- ret = xdr_to_generic (*iov, &rsp,
- (xdrproc_t)xdr_gd1_mgmt_v3_brick_op_rsp);
- if (ret < 0)
- goto out;
-
- uuid_copy (args->uuid, rsp.uuid);
-
- op_ret = rsp.op_ret;
- op_errno = rsp.op_errno;
-
-out:
- gd_mgmt_v3_collate_errors (args, op_ret, op_errno, rsp.op_errstr,
- GLUSTERD_MGMT_V3_BRICK_OP,
- peerinfo, rsp.uuid);
-
- if (rsp.op_errstr)
- free (rsp.op_errstr);
-
- if (rsp.dict.dict_val)
- free (rsp.dict.dict_val);
-
- STACK_DESTROY (frame->root);
- synctask_barrier_wake(args);
- return 0;
-}
-
-int32_t
-gd_mgmt_v3_brick_op_cbk (struct rpc_req *req, struct iovec *iov,
- int count, void *myframe)
-{
- return glusterd_big_locked_cbk (req, iov, count, myframe,
- gd_mgmt_v3_brick_op_cbk_fn);
-}
-
-int
-gd_mgmt_v3_brick_op_req (glusterd_op_t op, dict_t *op_ctx,
- glusterd_peerinfo_t *peerinfo,
- struct syncargs *args, uuid_t my_uuid,
- uuid_t recv_uuid)
-{
- int32_t ret = -1;
- gd1_mgmt_v3_brick_op_req req = {{0},};
- glusterd_conf_t *conf = THIS->private;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (op_ctx);
- GF_ASSERT (peerinfo);
- GF_ASSERT (args);
-
- ret = dict_allocate_and_serialize (op_ctx,
- &req.dict.dict_val,
- &req.dict.dict_len);
- if (ret)
- goto out;
-
- uuid_copy (req.uuid, my_uuid);
- req.op = op;
- synclock_unlock (&conf->big_lock);
- ret = gd_syncop_submit_request (peerinfo->rpc, &req, args, peerinfo,
- &gd_mgmt_v3_prog,
- GLUSTERD_MGMT_V3_BRICK_OP,
- gd_mgmt_v3_brick_op_cbk,
- (xdrproc_t) xdr_gd1_mgmt_v3_brick_op_req);
- synclock_lock (&conf->big_lock);
-out:
- GF_FREE (req.dict.dict_val);
- gf_log (this->name, GF_LOG_TRACE, "Returning %d", ret);
- return ret;
-}
-
-int
-glusterd_mgmt_v3_brick_op (glusterd_op_t op, dict_t *req_dict,
- char **op_errstr, int npeers,
- struct list_head *peers)
-{
- int32_t ret = -1;
- int32_t peer_cnt = 0;
- dict_t *rsp_dict = NULL;
- glusterd_peerinfo_t *peerinfo = NULL;
- struct syncargs args = {0};
- uuid_t peer_uuid = {0};
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (req_dict);
- GF_ASSERT (op_errstr);
-
- rsp_dict = dict_new ();
- if (!rsp_dict) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to create response dictionary");
- goto out;
- }
-
- /* Perform brick op on local node */
- ret = gd_mgmt_v3_brick_op_fn (op, req_dict, op_errstr,
- rsp_dict);
-
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Brick ops failed for "
- "operation %s on local node",
- gd_op_list[op]);
-
- if (*op_errstr == NULL) {
- ret = gf_asprintf (op_errstr,
- "Brick ops failed "
- "on localhost. Please "
- "check log file for details");
- if (ret == -1)
- *op_errstr = NULL;
-
- ret = -1;
- }
- goto out;
- }
-
- dict_unref (rsp_dict);
- rsp_dict = NULL;
-
- if (!npeers) {
- ret = 0;
- goto out;
- }
-
- /* Sending brick op req to other nodes in the cluster */
- gd_syncargs_init (&args, NULL);
- synctask_barrier_init((&args));
- peer_cnt = 0;
- list_for_each_local_xaction_peers (peerinfo, peers) {
- gd_mgmt_v3_brick_op_req (op, req_dict, peerinfo, &args,
- MY_UUID, peer_uuid);
- peer_cnt++;
- }
- gd_synctask_barrier_wait((&args), peer_cnt);
-
- if (args.op_ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Brick ops failed on peers");
-
- if (args.errstr)
- *op_errstr = gf_strdup (args.errstr);
- }
-
- ret = args.op_ret;
-
- gf_log (this->name, GF_LOG_DEBUG, "Sent brick op req for %s "
- "to %d peers. Returning %d", gd_op_list[op], peer_cnt, ret);
-out:
- return ret;
-}
-
-int32_t
-gd_mgmt_v3_commit_cbk_fn (struct rpc_req *req, struct iovec *iov,
- int count, void *myframe)
-{
- int32_t ret = -1;
- struct syncargs *args = NULL;
- glusterd_peerinfo_t *peerinfo = NULL;
- gd1_mgmt_v3_commit_rsp rsp = {{0},};
- call_frame_t *frame = NULL;
- int32_t op_ret = -1;
- int32_t op_errno = -1;
- dict_t *rsp_dict = NULL;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (req);
- GF_ASSERT (myframe);
-
- frame = myframe;
- args = frame->local;
- peerinfo = frame->cookie;
- frame->local = NULL;
- frame->cookie = NULL;
-
- if (-1 == req->rpc_status) {
- op_errno = ENOTCONN;
- goto out;
- }
-
- if (!iov) {
- gf_log (this->name, GF_LOG_ERROR, "iov is NULL");
- op_errno = EINVAL;
- goto out;
- }
-
- ret = xdr_to_generic (*iov, &rsp,
- (xdrproc_t)xdr_gd1_mgmt_v3_commit_rsp);
- if (ret < 0)
- goto out;
-
- if (rsp.dict.dict_len) {
- /* Unserialize the dictionary */
- rsp_dict = dict_new ();
-
- ret = dict_unserialize (rsp.dict.dict_val,
- rsp.dict.dict_len,
- &rsp_dict);
- if (ret < 0) {
- free (rsp.dict.dict_val);
- goto out;
- } else {
- rsp_dict->extra_stdfree = rsp.dict.dict_val;
- }
- }
-
- uuid_copy (args->uuid, rsp.uuid);
- pthread_mutex_lock (&args->lock_dict);
- {
- ret = glusterd_syncop_aggr_rsp_dict (rsp.op, args->dict,
- rsp_dict);
- }
- pthread_mutex_unlock (&args->lock_dict);
-
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "%s",
- "Failed to aggregate response from "
- " node/brick");
- if (!rsp.op_ret)
- op_ret = ret;
- else {
- op_ret = rsp.op_ret;
- op_errno = rsp.op_errno;
- }
- } else {
- op_ret = rsp.op_ret;
- op_errno = rsp.op_errno;
- }
-
-out:
- if (rsp_dict)
- dict_unref (rsp_dict);
-
- gd_mgmt_v3_collate_errors (args, op_ret, op_errno, rsp.op_errstr,
- GLUSTERD_MGMT_V3_COMMIT,
- peerinfo, rsp.uuid);
-
- STACK_DESTROY (frame->root);
- synctask_barrier_wake(args);
- return 0;
-}
-
-int32_t
-gd_mgmt_v3_commit_cbk (struct rpc_req *req, struct iovec *iov,
- int count, void *myframe)
-{
- return glusterd_big_locked_cbk (req, iov, count, myframe,
- gd_mgmt_v3_commit_cbk_fn);
-}
-
-int
-gd_mgmt_v3_commit_req (glusterd_op_t op, dict_t *op_ctx,
- glusterd_peerinfo_t *peerinfo,
- struct syncargs *args, uuid_t my_uuid,
- uuid_t recv_uuid)
-{
- int32_t ret = -1;
- gd1_mgmt_v3_commit_req req = {{0},};
- glusterd_conf_t *conf = THIS->private;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (op_ctx);
- GF_ASSERT (peerinfo);
- GF_ASSERT (args);
-
- ret = dict_allocate_and_serialize (op_ctx,
- &req.dict.dict_val,
- &req.dict.dict_len);
- if (ret)
- goto out;
-
- uuid_copy (req.uuid, my_uuid);
- req.op = op;
- synclock_unlock (&conf->big_lock);
- ret = gd_syncop_submit_request (peerinfo->rpc, &req, args, peerinfo,
- &gd_mgmt_v3_prog,
- GLUSTERD_MGMT_V3_COMMIT,
- gd_mgmt_v3_commit_cbk,
- (xdrproc_t) xdr_gd1_mgmt_v3_commit_req);
- synclock_lock (&conf->big_lock);
-out:
- GF_FREE (req.dict.dict_val);
- gf_log (this->name, GF_LOG_TRACE, "Returning %d", ret);
- return ret;
-}
-
-int
-glusterd_mgmt_v3_commit (glusterd_op_t op, dict_t *op_ctx,
- dict_t *req_dict, char **op_errstr,
- int npeers, struct list_head *peers)
-{
- int32_t ret = -1;
- int32_t peer_cnt = 0;
- dict_t *rsp_dict = NULL;
- glusterd_peerinfo_t *peerinfo = NULL;
- struct syncargs args = {0};
- uuid_t peer_uuid = {0};
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (op_ctx);
- GF_ASSERT (req_dict);
- GF_ASSERT (op_errstr);
-
- rsp_dict = dict_new ();
- if (!rsp_dict) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to create response dictionary");
- goto out;
- }
-
- /* Commit on local node */
- ret = gd_mgmt_v3_commit_fn (op, req_dict, op_errstr,
- rsp_dict);
-
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Commit failed for "
- "operation %s on local node",
- gd_op_list[op]);
-
- if (*op_errstr == NULL) {
- ret = gf_asprintf (op_errstr,
- "Commit failed "
- "on localhost. Please "
- "check log file for details.");
- if (ret == -1)
- *op_errstr = NULL;
-
- ret = -1;
- }
- goto out;
- }
-
- ret = glusterd_syncop_aggr_rsp_dict (op, op_ctx,
- rsp_dict);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "%s",
- "Failed to aggregate response from "
- " node/brick");
- goto out;
- }
-
- dict_unref (rsp_dict);
- rsp_dict = NULL;
-
- if (!npeers) {
- ret = 0;
- goto out;
- }
-
- /* Sending commit req to other nodes in the cluster */
- gd_syncargs_init (&args, op_ctx);
- synctask_barrier_init((&args));
- peer_cnt = 0;
- list_for_each_local_xaction_peers (peerinfo, peers) {
- gd_mgmt_v3_commit_req (op, req_dict, peerinfo, &args,
- MY_UUID, peer_uuid);
- peer_cnt++;
- }
- gd_synctask_barrier_wait((&args), peer_cnt);
-
- if (args.op_ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Commit failed on peers");
-
- if (args.errstr)
- *op_errstr = gf_strdup (args.errstr);
- }
-
- ret = args.op_ret;
-
- gf_log (this->name, GF_LOG_DEBUG, "Sent commit req for %s to %d "
- "peers. Returning %d", gd_op_list[op], peer_cnt, ret);
-out:
- return ret;
-}
-
-int32_t
-gd_mgmt_v3_post_validate_cbk_fn (struct rpc_req *req, struct iovec *iov,
- int count, void *myframe)
-{
- int32_t ret = -1;
- struct syncargs *args = NULL;
- glusterd_peerinfo_t *peerinfo = NULL;
- gd1_mgmt_v3_post_val_rsp rsp = {{0},};
- call_frame_t *frame = NULL;
- int32_t op_ret = -1;
- int32_t op_errno = -1;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (req);
- GF_ASSERT (myframe);
-
- frame = myframe;
- args = frame->local;
- peerinfo = frame->cookie;
- frame->local = NULL;
- frame->cookie = NULL;
-
- if (-1 == req->rpc_status) {
- op_errno = ENOTCONN;
- goto out;
- }
-
- if (!iov) {
- gf_log (this->name, GF_LOG_ERROR, "iov is NULL");
- op_errno = EINVAL;
- goto out;
- }
-
- ret = xdr_to_generic (*iov, &rsp,
- (xdrproc_t)xdr_gd1_mgmt_v3_post_val_rsp);
- if (ret < 0)
- goto out;
-
- uuid_copy (args->uuid, rsp.uuid);
-
- op_ret = rsp.op_ret;
- op_errno = rsp.op_errno;
-
-out:
- gd_mgmt_v3_collate_errors (args, op_ret, op_errno, rsp.op_errstr,
- GLUSTERD_MGMT_V3_POST_VALIDATE,
- peerinfo, rsp.uuid);
- if (rsp.op_errstr)
- free (rsp.op_errstr);
-
- if (rsp.dict.dict_val)
- free (rsp.dict.dict_val);
- STACK_DESTROY (frame->root);
- synctask_barrier_wake(args);
- return 0;
-}
-
-int32_t
-gd_mgmt_v3_post_validate_cbk (struct rpc_req *req, struct iovec *iov,
- int count, void *myframe)
-{
- return glusterd_big_locked_cbk (req, iov, count, myframe,
- gd_mgmt_v3_post_validate_cbk_fn);
-}
-
-int
-gd_mgmt_v3_post_validate_req (glusterd_op_t op, int32_t op_ret, dict_t *op_ctx,
- glusterd_peerinfo_t *peerinfo,
- struct syncargs *args, uuid_t my_uuid,
- uuid_t recv_uuid)
-{
- int32_t ret = -1;
- gd1_mgmt_v3_post_val_req req = {{0},};
- glusterd_conf_t *conf = THIS->private;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (op_ctx);
- GF_ASSERT (peerinfo);
- GF_ASSERT (args);
-
- ret = dict_allocate_and_serialize (op_ctx,
- &req.dict.dict_val,
- &req.dict.dict_len);
- if (ret)
- goto out;
-
- uuid_copy (req.uuid, my_uuid);
- req.op = op;
- req.op_ret = op_ret;
- synclock_unlock (&conf->big_lock);
- ret = gd_syncop_submit_request (peerinfo->rpc, &req, args, peerinfo,
- &gd_mgmt_v3_prog,
- GLUSTERD_MGMT_V3_POST_VALIDATE,
- gd_mgmt_v3_post_validate_cbk,
- (xdrproc_t) xdr_gd1_mgmt_v3_post_val_req);
- synclock_lock (&conf->big_lock);
-out:
- GF_FREE (req.dict.dict_val);
- gf_log (this->name, GF_LOG_TRACE, "Returning %d", ret);
- return ret;
-}
-
-int
-glusterd_mgmt_v3_post_validate (glusterd_op_t op, int32_t op_ret, dict_t *dict,
- dict_t *req_dict, char **op_errstr, int npeers,
- struct list_head *peers)
-{
- int32_t ret = -1;
- int32_t peer_cnt = 0;
- dict_t *rsp_dict = NULL;
- glusterd_peerinfo_t *peerinfo = NULL;
- struct syncargs args = {0};
- uuid_t peer_uuid = {0};
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (dict);
- GF_VALIDATE_OR_GOTO (this->name, req_dict, out);
- GF_ASSERT (op_errstr);
-
- rsp_dict = dict_new ();
- if (!rsp_dict) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to create response dictionary");
- goto out;
- }
-
- /* Copy the contents of dict like missed snaps info to req_dict */
- dict_copy (dict, req_dict);
-
- /* Post Validation on local node */
- ret = gd_mgmt_v3_post_validate_fn (op, op_ret, req_dict, op_errstr,
- rsp_dict);
-
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Post Validation failed for "
- "operation %s on local node",
- gd_op_list[op]);
-
- if (*op_errstr == NULL) {
- ret = gf_asprintf (op_errstr,
- "Post-validation failed "
- "on localhost. Please check "
- "log file for details");
- if (ret == -1)
- *op_errstr = NULL;
-
- ret = -1;
- }
- goto out;
- }
-
- dict_unref (rsp_dict);
- rsp_dict = NULL;
-
- if (!npeers) {
- ret = 0;
- goto out;
- }
-
- /* Sending Post Validation req to other nodes in the cluster */
- gd_syncargs_init (&args, req_dict);
- synctask_barrier_init((&args));
- peer_cnt = 0;
- list_for_each_local_xaction_peers (peerinfo, peers) {
- gd_mgmt_v3_post_validate_req (op, op_ret, req_dict, peerinfo,
- &args, MY_UUID, peer_uuid);
- peer_cnt++;
- }
- gd_synctask_barrier_wait((&args), peer_cnt);
-
- if (args.op_ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Post Validation failed on peers");
-
- if (args.errstr)
- *op_errstr = gf_strdup (args.errstr);
- }
-
- ret = args.op_ret;
-
- gf_log (this->name, GF_LOG_DEBUG, "Sent post valaidation req for %s "
- "to %d peers. Returning %d", gd_op_list[op], peer_cnt, ret);
-out:
- return ret;
-}
-
-int32_t
-gd_mgmt_v3_unlock_cbk_fn (struct rpc_req *req, struct iovec *iov,
- int count, void *myframe)
-{
- int32_t ret = -1;
- struct syncargs *args = NULL;
- glusterd_peerinfo_t *peerinfo = NULL;
- gd1_mgmt_v3_unlock_rsp rsp = {{0},};
- call_frame_t *frame = NULL;
- int32_t op_ret = -1;
- int32_t op_errno = -1;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (req);
- GF_ASSERT (myframe);
-
- frame = myframe;
- args = frame->local;
- peerinfo = frame->cookie;
- frame->local = NULL;
- frame->cookie = NULL;
-
- if (-1 == req->rpc_status) {
- op_errno = ENOTCONN;
- goto out;
- }
-
- if (!iov) {
- gf_log (this->name, GF_LOG_ERROR, "iov is NULL");
- op_errno = EINVAL;
- goto out;
- }
-
- ret = xdr_to_generic (*iov, &rsp,
- (xdrproc_t)xdr_gd1_mgmt_v3_unlock_rsp);
- if (ret < 0)
- goto out;
-
- uuid_copy (args->uuid, rsp.uuid);
-
- op_ret = rsp.op_ret;
- op_errno = rsp.op_errno;
-
-out:
- gd_mgmt_v3_collate_errors (args, op_ret, op_errno, NULL,
- GLUSTERD_MGMT_V3_UNLOCK,
- peerinfo, rsp.uuid);
- if (rsp.dict.dict_val)
- free (rsp.dict.dict_val);
- STACK_DESTROY (frame->root);
- synctask_barrier_wake(args);
- return 0;
-}
-
-int32_t
-gd_mgmt_v3_unlock_cbk (struct rpc_req *req, struct iovec *iov,
- int count, void *myframe)
-{
- return glusterd_big_locked_cbk (req, iov, count, myframe,
- gd_mgmt_v3_unlock_cbk_fn);
-}
-
-int
-gd_mgmt_v3_unlock (glusterd_op_t op, dict_t *op_ctx,
- glusterd_peerinfo_t *peerinfo,
- struct syncargs *args, uuid_t my_uuid,
- uuid_t recv_uuid)
-{
- int32_t ret = -1;
- gd1_mgmt_v3_unlock_req req = {{0},};
- glusterd_conf_t *conf = THIS->private;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (op_ctx);
- GF_ASSERT (peerinfo);
- GF_ASSERT (args);
-
- ret = dict_allocate_and_serialize (op_ctx,
- &req.dict.dict_val,
- &req.dict.dict_len);
- if (ret)
- goto out;
-
- uuid_copy (req.uuid, my_uuid);
- req.op = op;
- synclock_unlock (&conf->big_lock);
- ret = gd_syncop_submit_request (peerinfo->rpc, &req, args, peerinfo,
- &gd_mgmt_v3_prog,
- GLUSTERD_MGMT_V3_UNLOCK,
- gd_mgmt_v3_unlock_cbk,
- (xdrproc_t) xdr_gd1_mgmt_v3_unlock_req);
- synclock_lock (&conf->big_lock);
-out:
- GF_FREE (req.dict.dict_val);
- gf_log (this->name, GF_LOG_TRACE, "Returning %d", ret);
- return ret;
-}
-
-int
-glusterd_mgmt_v3_release_peer_locks (glusterd_op_t op,
- dict_t *dict, int32_t op_ret,
- char **op_errstr, int npeers,
- gf_boolean_t is_acquired,
- struct list_head *peers)
-{
- int32_t ret = -1;
- int32_t peer_cnt = 0;
- uuid_t peer_uuid = {0};
- xlator_t *this = NULL;
- glusterd_peerinfo_t *peerinfo = NULL;
- struct syncargs args = {0};
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (dict);
- GF_ASSERT (op_errstr);
-
- /* If the lock has not been held during this
- * transaction, do not send unlock requests */
- if (!is_acquired)
- goto out;
-
- if (!npeers) {
- ret = 0;
- goto out;
- }
-
- /* Sending mgmt_v3 unlock req to other nodes in the cluster */
- gd_syncargs_init (&args, NULL);
- synctask_barrier_init((&args));
- peer_cnt = 0;
- list_for_each_local_xaction_peers (peerinfo, peers) {
- gd_mgmt_v3_unlock (op, dict, peerinfo, &args,
- MY_UUID, peer_uuid);
- peer_cnt++;
- }
- gd_synctask_barrier_wait((&args), peer_cnt);
-
- if (args.op_ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Unlock failed on peers");
-
- if (!op_ret && args.errstr)
- *op_errstr = gf_strdup (args.errstr);
- }
-
- ret = args.op_ret;
-
- gf_log (this->name, GF_LOG_DEBUG, "Sent unlock op req for %s "
- "to %d peers. Returning %d", gd_op_list[op], peer_cnt, ret);
-
-out:
- return ret;
-}
-
-int32_t
-glusterd_mgmt_v3_initiate_all_phases (rpcsvc_request_t *req, glusterd_op_t op,
- dict_t *dict)
-{
- int32_t ret = -1;
- int32_t op_ret = -1;
- int32_t npeers = 0;
- dict_t *req_dict = NULL;
- dict_t *tmp_dict = NULL;
- glusterd_conf_t *conf = NULL;
- char *op_errstr = NULL;
- xlator_t *this = NULL;
- gf_boolean_t is_acquired = _gf_false;
- uuid_t *originator_uuid = NULL;
- struct list_head xaction_peers = {0,};
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (req);
- GF_ASSERT (dict);
- conf = this->private;
- GF_ASSERT (conf);
-
- INIT_LIST_HEAD (&xaction_peers);
- npeers = gd_build_local_xaction_peers_list (&conf->peers,
- &xaction_peers, op);
- if (npeers == -1) {
- gf_log (this->name, GF_LOG_ERROR, "building local peers list "
- "failed");
- goto rsp;
- }
-
- /* Save the MY_UUID as the originator_uuid. This originator_uuid
- * will be used by is_origin_glusterd() to determine if a node
- * is the originator node for a command. */
- originator_uuid = GF_CALLOC (1, sizeof(uuid_t),
- gf_common_mt_uuid_t);
- if (!originator_uuid) {
- ret = -1;
- goto out;
- }
-
- uuid_copy (*originator_uuid, MY_UUID);
- ret = dict_set_bin (dict, "originator_uuid",
- originator_uuid, sizeof (uuid_t));
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to set originator_uuid.");
- goto out;
- }
-
- /* Marking the operation as complete synctasked */
- ret = dict_set_int32 (dict, "is_synctasked", _gf_true);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to set synctasked flag.");
- goto out;
- }
-
- /* Use a copy at local unlock as cli response will be sent before
- * the unlock and the volname in the dict might be removed */
- tmp_dict = dict_new();
- if (!tmp_dict) {
- gf_log (this->name, GF_LOG_ERROR, "Unable to create dict");
- goto out;
- }
- dict_copy (dict, tmp_dict);
-
- /* LOCKDOWN PHASE - Acquire mgmt_v3 locks */
- ret = glusterd_mgmt_v3_initiate_lockdown (op, dict, &op_errstr,
- npeers, &is_acquired,
- &xaction_peers);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "mgmt_v3 lockdown failed.");
- goto out;
- }
-
- /* BUILD PAYLOAD */
- ret = glusterd_mgmt_v3_build_payload (&req_dict, &op_errstr, dict, op);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, LOGSTR_BUILD_PAYLOAD,
- gd_op_list[op]);
- if (op_errstr == NULL)
- gf_asprintf (&op_errstr, OPERRSTR_BUILD_PAYLOAD);
- goto out;
- }
-
- /* PRE-COMMIT VALIDATE PHASE */
- ret = glusterd_mgmt_v3_pre_validate (op, req_dict,
- &op_errstr, npeers,
- &xaction_peers);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Pre Validation Failed");
- goto out;
- }
-
- /* COMMIT OP PHASE */
- ret = glusterd_mgmt_v3_commit (op, dict, req_dict,
- &op_errstr, npeers, &xaction_peers);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Commit Op Failed");
- goto out;
- }
-
- /* POST-COMMIT VALIDATE PHASE */
- /* As of now, post_validate is not handling any other
- commands other than snapshot. So as of now, I am
- sending 0 (op_ret as 0).
- */
- ret = glusterd_mgmt_v3_post_validate (op, 0, dict, req_dict,
- &op_errstr, npeers,
- &xaction_peers);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Post Validation Failed");
- goto out;
- }
-
- ret = 0;
-out:
- op_ret = ret;
- /* UNLOCK PHASE FOR PEERS*/
- (void) glusterd_mgmt_v3_release_peer_locks (op, dict,
- op_ret, &op_errstr,
- npeers, is_acquired,
- &xaction_peers);
-
- /* LOCAL VOLUME(S) UNLOCK */
- if (is_acquired) {
- /* Trying to release multiple mgmt_v3 locks */
- ret = glusterd_multiple_mgmt_v3_unlock (tmp_dict, MY_UUID);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to release mgmt_v3 locks on localhost");
- op_ret = ret;
- }
- }
-rsp:
- /* SEND CLI RESPONSE */
- glusterd_op_send_cli_response (op, op_ret, 0, req, dict, op_errstr);
-
- gd_cleanup_local_xaction_peers_list (&xaction_peers);
-
- if (req_dict)
- dict_unref (req_dict);
-
- if (tmp_dict)
- dict_unref (tmp_dict);
-
- if (op_errstr) {
- GF_FREE (op_errstr);
- op_errstr = NULL;
- }
-
- return 0;
-}
-
-int32_t
-glusterd_set_barrier_value (dict_t *dict, char *option)
-{
- int32_t ret = -1;
- xlator_t *this = NULL;
- glusterd_volinfo_t *vol = NULL;
- char *volname = NULL;
-
- this = THIS;
- GF_ASSERT (this);
-
- GF_ASSERT (dict);
- GF_ASSERT (option);
-
- /* TODO : Change this when we support multiple volume.
- * As of now only snapshot of single volume is supported,
- * Hence volname1 is directly fetched
- */
- ret = dict_get_str (dict, "volname1", &volname);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Volname not present in "
- "dict");
- goto out;
- }
-
- ret = glusterd_volinfo_find (volname, &vol);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Volume %s not found ",
- volname);
- goto out;
- }
-
- ret = dict_set_dynstr_with_alloc (dict, "barrier", option);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to set barrier op "
- "in request dictionary");
- goto out;
- }
-
- ret = dict_set_dynstr_with_alloc (vol->dict, "features.barrier",
- option);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to set barrier op "
- "in volume option dict");
- goto out;
- }
-
- gd_update_volume_op_versions (vol);
-
- ret = glusterd_create_volfiles (vol);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to create volfiles");
- goto out;
- }
-
- ret = glusterd_store_volinfo (vol, GLUSTERD_VOLINFO_VER_AC_INCREMENT);
-
-out:
- gf_log (this->name, GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-
-int32_t
-glusterd_mgmt_v3_initiate_snap_phases (rpcsvc_request_t *req, glusterd_op_t op,
- dict_t *dict)
-{
- int32_t ret = -1;
- int32_t op_ret = -1;
- int32_t npeers = 0;
- dict_t *req_dict = NULL;
- dict_t *tmp_dict = NULL;
- glusterd_conf_t *conf = NULL;
- char *op_errstr = NULL;
- xlator_t *this = NULL;
- gf_boolean_t is_acquired = _gf_false;
- uuid_t *originator_uuid = NULL;
- gf_boolean_t success = _gf_false;
- char *cli_errstr = NULL;
- struct list_head xaction_peers = {0,};
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (req);
- GF_ASSERT (dict);
- conf = this->private;
- GF_ASSERT (conf);
-
- INIT_LIST_HEAD (&xaction_peers);
- npeers = gd_build_local_xaction_peers_list (&conf->peers,
- &xaction_peers, op);
- if (npeers == -1) {
- gf_log (this->name, GF_LOG_ERROR, "building local peers list "
- "failed");
- goto rsp;
- }
-
- /* Save the MY_UUID as the originator_uuid. This originator_uuid
- * will be used by is_origin_glusterd() to determine if a node
- * is the originator node for a command. */
- originator_uuid = GF_CALLOC (1, sizeof(uuid_t),
- gf_common_mt_uuid_t);
- if (!originator_uuid) {
- ret = -1;
- goto out;
- }
-
- uuid_copy (*originator_uuid, MY_UUID);
- ret = dict_set_bin (dict, "originator_uuid",
- originator_uuid, sizeof (uuid_t));
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to set originator_uuid.");
- goto out;
- }
-
- /* Marking the operation as complete synctasked */
- ret = dict_set_int32 (dict, "is_synctasked", _gf_true);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to set synctasked flag.");
- goto out;
- }
-
- /* Use a copy at local unlock as cli response will be sent before
- * the unlock and the volname in the dict might be removed */
- tmp_dict = dict_new();
- if (!tmp_dict) {
- gf_log (this->name, GF_LOG_ERROR, "Unable to create dict");
- goto out;
- }
- dict_copy (dict, tmp_dict);
-
- /* LOCKDOWN PHASE - Acquire mgmt_v3 locks */
- ret = glusterd_mgmt_v3_initiate_lockdown (op, dict, &op_errstr,
- npeers, &is_acquired,
- &xaction_peers);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "mgmt_v3 lockdown failed.");
- goto out;
- }
-
- /* BUILD PAYLOAD */
- ret = glusterd_mgmt_v3_build_payload (&req_dict, &op_errstr, dict, op);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, LOGSTR_BUILD_PAYLOAD,
- gd_op_list[op]);
- if (op_errstr == NULL)
- gf_asprintf (&op_errstr, OPERRSTR_BUILD_PAYLOAD);
- goto out;
- }
-
- /* PRE-COMMIT VALIDATE PHASE */
- ret = glusterd_mgmt_v3_pre_validate (op, req_dict,
- &op_errstr, npeers, &xaction_peers);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Pre Validation Failed");
- goto out;
- }
-
- /* quorum check of the volume is done here */
- ret = glusterd_snap_quorum_check (req_dict, _gf_false, &op_errstr,
- &xaction_peers);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING,
- "Volume quorum check failed");
- goto out;
- }
-
- /* Set the operation type as pre, so that differentiation can be
- * made whether the brickop is sent during pre-commit or post-commit
- */
- ret = dict_set_dynstr_with_alloc (req_dict, "operation-type", "pre");
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to set "
- "operation-type in dictionary");
- goto out;
- }
-
- ret = glusterd_mgmt_v3_brick_op (op, req_dict,
- &op_errstr, npeers, &xaction_peers);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Brick Ops Failed");
- goto unbarrier;
- }
-
- /* COMMIT OP PHASE */
- /* TODO: As of now, the plan is to do quorum check before sending the
- commit fop and if the quorum succeeds, then commit is sent to all
- the other glusterds.
- snap create functionality now creates the in memory and on disk
- objects for the snapshot (marking them as incomplete), takes the lvm
- snapshot and then updates the status of the in memory and on disk
- snap objects as complete. Suppose one of the glusterds goes down
- after taking the lvm snapshot, but before updating the snap object,
- then treat it as a snapshot create failure and trigger cleanup.
- i.e the number of commit responses received by the originator
- glusterd shold be the same as the number of peers it has sent the
- request to (i.e npeers variable). If not, then originator glusterd
- will initiate cleanup in post-validate fop.
- Question: What if one of the other glusterds goes down as explained
- above and along with it the originator glusterd also goes down?
- Who will initiate the cleanup?
- */
- ret = dict_set_int32 (req_dict, "cleanup", 1);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "failed to set dict");
- goto unbarrier;
- }
-
- ret = glusterd_mgmt_v3_commit (op, dict, req_dict,
- &op_errstr, npeers, &xaction_peers);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Commit Op Failed");
- /* If the main op fails, we should save the error string.
- Because, op_errstr will be used for unbarrier and
- unlock ops also. We might lose the actual error that
- caused the failure.
- */
- cli_errstr = op_errstr;
- op_errstr = NULL;
- goto unbarrier;
- }
-
- success = _gf_true;
-unbarrier:
- /* Set the operation type as post, so that differentiation can be
- * made whether the brickop is sent during pre-commit or post-commit
- */
- ret = dict_set_dynstr_with_alloc (req_dict, "operation-type", "post");
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to set "
- "operation-type in dictionary");
- goto out;
- }
-
- ret = glusterd_mgmt_v3_brick_op (op, req_dict,
- &op_errstr, npeers, &xaction_peers);
-
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Brick Ops Failed");
- goto out;
- }
-
- /*Do a quorum check if the commit phase is successful*/
- if (success) {
- //quorum check of the snapshot volume
- ret = glusterd_snap_quorum_check (dict, _gf_true, &op_errstr,
- &xaction_peers);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING,
- "Snapshot Volume quorum check failed");
- goto out;
- }
- }
-
- ret = 0;
-
-out:
- op_ret = ret;
-
- if (success == _gf_false)
- op_ret = -1;
-
- /* POST-COMMIT VALIDATE PHASE */
- ret = glusterd_mgmt_v3_post_validate (op, op_ret, dict, req_dict,
- &op_errstr, npeers,
- &xaction_peers);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Post Validation Failed");
- op_ret = -1;
- }
-
- /* UNLOCK PHASE FOR PEERS*/
- (void) glusterd_mgmt_v3_release_peer_locks (op, dict,
- op_ret, &op_errstr,
- npeers, is_acquired,
- &xaction_peers);
-
- /* If the commit op (snapshot taking) failed, then the error is stored
- in cli_errstr and unbarrier is called. Suppose, if unbarrier also
- fails, then the error happened in unbarrier is logged and freed.
- The error happened in commit op, which is stored in cli_errstr
- is sent to cli.
- */
- if (cli_errstr) {
- GF_FREE (op_errstr);
- op_errstr = NULL;
- op_errstr = cli_errstr;
- }
-
- /* LOCAL VOLUME(S) UNLOCK */
- if (is_acquired) {
- /* Trying to release multiple mgmt_v3 locks */
- ret = glusterd_multiple_mgmt_v3_unlock (tmp_dict, MY_UUID);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to release mgmt_v3 locks on localhost");
- op_ret = ret;
- }
- }
-rsp:
- /* SEND CLI RESPONSE */
- glusterd_op_send_cli_response (op, op_ret, 0, req, dict, op_errstr);
-
- gd_cleanup_local_xaction_peers_list (&xaction_peers);
-
- if (req_dict)
- dict_unref (req_dict);
-
- if (tmp_dict)
- dict_unref (tmp_dict);
-
- if (op_errstr) {
- GF_FREE (op_errstr);
- op_errstr = NULL;
- }
-
- return 0;
-}
diff --git a/xlators/mgmt/glusterd/src/glusterd-mgmt.h b/xlators/mgmt/glusterd/src/glusterd-mgmt.h
deleted file mode 100644
index ab9265c75c4..00000000000
--- a/xlators/mgmt/glusterd/src/glusterd-mgmt.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- Copyright (c) 2013-2014 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 _GLUSTERD_MGMT_H_
-#define _GLUSTERD_MGMT_H_
-
-#ifndef _CONFIG_H
-#define _CONFIG_H
-#include "config.h"
-#endif
-
-void gd_mgmt_v3_collate_errors (struct syncargs *args, int op_ret, int op_errno,
- char *op_errstr, int op_code,
- glusterd_peerinfo_t *peerinfo, u_char *uuid);
-
-int32_t
-gd_mgmt_v3_pre_validate_fn (glusterd_op_t op, dict_t *dict,
- char **op_errstr, dict_t *rsp_dict);
-
-int32_t
-gd_mgmt_v3_brick_op_fn (glusterd_op_t op, dict_t *dict,
- char **op_errstr, dict_t *rsp_dict);
-
-int32_t
-gd_mgmt_v3_commit_fn (glusterd_op_t op, dict_t *dict,
- char **op_errstr, dict_t *rsp_dict);
-
-int32_t
-gd_mgmt_v3_post_validate_fn (glusterd_op_t op, int32_t op_ret, dict_t *dict,
- char **op_errstr, dict_t *rsp_dict);
-
-int32_t
-glusterd_mgmt_v3_initiate_all_phases (rpcsvc_request_t *req, glusterd_op_t op,
- dict_t *dict);
-
-int32_t
-glusterd_mgmt_v3_initiate_snap_phases (rpcsvc_request_t *req, glusterd_op_t op,
- dict_t *dict);
-
-int
-glusterd_snap_pre_validate_use_rsp_dict (dict_t *dst, dict_t *src);
-
-int32_t
-glusterd_set_barrier_value (dict_t *dict, char *option);
-#endif /* _GLUSTERD_MGMT_H_ */
diff --git a/xlators/mgmt/glusterd/src/glusterd-mountbroker.c b/xlators/mgmt/glusterd/src/glusterd-mountbroker.c
deleted file mode 100644
index 30c8d8150c0..00000000000
--- a/xlators/mgmt/glusterd/src/glusterd-mountbroker.c
+++ /dev/null
@@ -1,693 +0,0 @@
-/*
- Copyright (c) 2011-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 <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("
- "aux-gfid-mount "
- "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 426252ebed8..00000000000
--- a/xlators/mgmt/glusterd/src/glusterd-mountbroker.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- Copyright (c) 2011-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.
-*/
-#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
deleted file mode 100644
index 8c341153db4..00000000000
--- a/xlators/mgmt/glusterd/src/glusterd-op-sm.c
+++ /dev/null
@@ -1,6775 +0,0 @@
-/*
- Copyright (c) 2006-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 <time.h>
-#include <sys/uio.h>
-#include <sys/resource.h>
-#include <sys/mount.h>
-
-#include <libgen.h>
-#include "uuid.h"
-
-#include "fnmatch.h"
-#include "xlator.h"
-#include "protocol-common.h"
-#include "glusterd.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 "glusterd-sm.h"
-#include "glusterd-op-sm.h"
-#include "glusterd-utils.h"
-#include "glusterd-store.h"
-#include "glusterd-hooks.h"
-#include "glusterd-volgen.h"
-#include "glusterd-locks.h"
-#include "glusterd-messages.h"
-#include "syscall.h"
-#include "cli1-xdr.h"
-#include "common-utils.h"
-#include "run.h"
-
-#include <sys/types.h>
-#include <signal.h>
-#include <sys/wait.h>
-
-#define ALL_VOLUME_OPTION_CHECK(volname, key, ret, op_errstr, label) \
- do { \
- gf_boolean_t _all = !strcmp ("all", volname); \
- gf_boolean_t _ratio = !strcmp (key, \
- GLUSTERD_QUORUM_RATIO_KEY); \
- if (_all && !_ratio) { \
- ret = -1; \
- *op_errstr = gf_strdup ("Not a valid option for all " \
- "volumes"); \
- goto label; \
- } else if (!_all && _ratio) { \
- ret = -1; \
- *op_errstr = gf_strdup ("Not a valid option for " \
- "single volume"); \
- goto label; \
- } \
- } while (0)
-
-static struct list_head gd_op_sm_queue;
-pthread_mutex_t gd_op_sm_lock;
-glusterd_op_info_t opinfo = {{0},};
-
-int32_t
-glusterd_txn_opinfo_dict_init ()
-{
- int32_t ret = -1;
- xlator_t *this = NULL;
- glusterd_conf_t *priv = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- priv = this->private;
- GF_ASSERT (priv);
-
- priv->glusterd_txn_opinfo = dict_new ();
- if (!priv->glusterd_txn_opinfo) {
- ret = -1;
- goto out;
- }
-
- memset (priv->global_txn_id, '\0', sizeof(uuid_t));
-
- ret = 0;
-out:
- return ret;
-}
-
-void
-glusterd_txn_opinfo_dict_fini ()
-{
- xlator_t *this = NULL;
- glusterd_conf_t *priv = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- priv = this->private;
- GF_ASSERT (priv);
-
- if (priv->glusterd_txn_opinfo)
- dict_unref (priv->glusterd_txn_opinfo);
-}
-
-void
-glusterd_txn_opinfo_init (glusterd_op_info_t *opinfo,
- glusterd_op_sm_state_info_t *state,
- glusterd_op_t *op,
- dict_t *op_ctx,
- rpcsvc_request_t *req)
-{
- GF_ASSERT (opinfo);
-
- if (state)
- opinfo->state = *state;
-
- if (op)
- opinfo->op = *op;
-
- if (op_ctx)
- opinfo->op_ctx = dict_ref(op_ctx);
- else
- opinfo->op_ctx = NULL;
-
- if (req)
- opinfo->req = req;
-
- return;
-}
-
-int32_t
-glusterd_generate_txn_id (dict_t *dict, uuid_t **txn_id)
-{
- int32_t ret = -1;
- glusterd_conf_t *priv = NULL;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- priv = this->private;
- GF_ASSERT (priv);
- GF_ASSERT (dict);
-
- *txn_id = GF_CALLOC (1, sizeof(uuid_t), gf_common_mt_uuid_t);
- if (!*txn_id)
- goto out;
-
- if (priv->op_version < GD_OP_VERSION_3_6_0)
- uuid_copy (**txn_id, priv->global_txn_id);
- else
- uuid_generate (**txn_id);
-
- ret = dict_set_bin (dict, "transaction_id",
- *txn_id, sizeof (**txn_id));
- if (ret) {
- gf_log ("", GF_LOG_ERROR,
- "Failed to set transaction id.");
- goto out;
- }
-
- gf_log ("", GF_LOG_DEBUG,
- "Transaction_id = %s", uuid_utoa (**txn_id));
-out:
- if (ret && *txn_id) {
- GF_FREE (*txn_id);
- *txn_id = NULL;
- }
-
- return ret;
-}
-
-int32_t
-glusterd_get_txn_opinfo (uuid_t *txn_id, glusterd_op_info_t *opinfo)
-{
- int32_t ret = -1;
- glusterd_txn_opinfo_obj *opinfo_obj = NULL;
- glusterd_conf_t *priv = NULL;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- priv = this->private;
- GF_ASSERT (priv);
-
- if (!txn_id || !opinfo) {
- gf_log ("", GF_LOG_ERROR,
- "Empty transaction id or opinfo received.");
- ret = -1;
- goto out;
- }
-
- ret = dict_get_bin(priv->glusterd_txn_opinfo,
- uuid_utoa (*txn_id),
- (void **) &opinfo_obj);
- if (ret) {
- gf_log ("", GF_LOG_ERROR,
- "Unable to get transaction opinfo "
- "for transaction ID : %s",
- uuid_utoa (*txn_id));
- goto out;
- }
-
- (*opinfo) = opinfo_obj->opinfo;
-
- gf_log ("", GF_LOG_DEBUG,
- "Successfully got opinfo for transaction ID : %s",
- uuid_utoa (*txn_id));
-
- ret = 0;
-out:
- gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-
-int32_t
-glusterd_set_txn_opinfo (uuid_t *txn_id, glusterd_op_info_t *opinfo)
-{
- int32_t ret = -1;
- glusterd_txn_opinfo_obj *opinfo_obj = NULL;
- glusterd_conf_t *priv = NULL;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- priv = this->private;
- GF_ASSERT (priv);
-
- if (!txn_id) {
- gf_log ("", GF_LOG_ERROR, "Empty transaction id received.");
- ret = -1;
- goto out;
- }
-
- ret = dict_get_bin(priv->glusterd_txn_opinfo,
- uuid_utoa (*txn_id),
- (void **) &opinfo_obj);
- if (ret) {
- opinfo_obj = GF_CALLOC (1, sizeof(glusterd_txn_opinfo_obj),
- gf_common_mt_txn_opinfo_obj_t);
- if (!opinfo_obj) {
- ret = -1;
- goto out;
- }
-
- ret = dict_set_bin(priv->glusterd_txn_opinfo,
- uuid_utoa (*txn_id), opinfo_obj,
- sizeof(glusterd_txn_opinfo_obj));
- if (ret) {
- gf_log ("", GF_LOG_ERROR,
- "Unable to set opinfo for transaction ID : %s",
- uuid_utoa (*txn_id));
- goto out;
- }
- }
-
- opinfo_obj->opinfo = (*opinfo);
-
- gf_log ("", GF_LOG_DEBUG,
- "Successfully set opinfo for transaction ID : %s",
- uuid_utoa (*txn_id));
- ret = 0;
-out:
- if (ret)
- if (opinfo_obj)
- GF_FREE (opinfo_obj);
-
- gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-
-int32_t
-glusterd_clear_txn_opinfo (uuid_t *txn_id)
-{
- int32_t ret = -1;
- glusterd_op_info_t txn_op_info = {{0},};
- glusterd_conf_t *priv = NULL;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- priv = this->private;
- GF_ASSERT (priv);
-
- if (!txn_id) {
- gf_log ("", GF_LOG_ERROR, "Empty transaction id received.");
- ret = -1;
- goto out;
- }
-
- ret = glusterd_get_txn_opinfo (txn_id, &txn_op_info);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Transaction opinfo not found");
- goto out;
- }
-
- if (txn_op_info.op_ctx)
- dict_unref (txn_op_info.op_ctx);
-
- dict_del(priv->glusterd_txn_opinfo, uuid_utoa (*txn_id));
-
- if (txn_op_info.local_xaction_peers)
- GF_FREE (txn_op_info.local_xaction_peers);
-
- gf_log ("", GF_LOG_DEBUG,
- "Successfully cleared opinfo for transaction ID : %s",
- uuid_utoa (*txn_id));
-
- ret = 0;
-out:
- gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-
-static int glusterfs_port = GLUSTERD_DEFAULT_PORT;
-static char *glusterd_op_sm_state_names[] = {
- "Default",
- "Lock sent",
- "Locked",
- "Stage op sent",
- "Staged",
- "Commit op sent",
- "Committed",
- "Unlock sent",
- "Stage op failed",
- "Commit op failed",
- "Brick op sent",
- "Brick op failed",
- "Brick op Committed",
- "Brick op Commit failed",
- "Ack drain",
- "Invalid",
-};
-
-static char *glusterd_op_sm_event_names[] = {
- "GD_OP_EVENT_NONE",
- "GD_OP_EVENT_START_LOCK",
- "GD_OP_EVENT_LOCK",
- "GD_OP_EVENT_RCVD_ACC",
- "GD_OP_EVENT_ALL_ACC",
- "GD_OP_EVENT_STAGE_ACC",
- "GD_OP_EVENT_COMMIT_ACC",
- "GD_OP_EVENT_RCVD_RJT",
- "GD_OP_EVENT_STAGE_OP",
- "GD_OP_EVENT_COMMIT_OP",
- "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"
-};
-
-extern struct volopt_map_entry glusterd_volopt_map[];
-
-char*
-glusterd_op_sm_state_name_get (int state)
-{
- if (state < 0 || state >= GD_OP_STATE_MAX)
- return glusterd_op_sm_state_names[GD_OP_STATE_MAX];
- return glusterd_op_sm_state_names[state];
-}
-
-char*
-glusterd_op_sm_event_name_get (int event)
-{
- if (event < 0 || event >= GD_OP_EVENT_MAX)
- return glusterd_op_sm_event_names[GD_OP_EVENT_MAX];
- return glusterd_op_sm_event_names[event];
-}
-
-void
-glusterd_destroy_lock_ctx (glusterd_op_lock_ctx_t *ctx)
-{
- if (!ctx)
- return;
- GF_FREE (ctx);
-}
-
-void
-glusterd_set_volume_status (glusterd_volinfo_t *volinfo,
- glusterd_volume_status status)
-{
- GF_ASSERT (volinfo);
- volinfo->status = status;
-}
-
-gf_boolean_t
-glusterd_is_volume_started (glusterd_volinfo_t *volinfo)
-{
- GF_ASSERT (volinfo);
- return (volinfo->status == GLUSTERD_STATUS_STARTED);
-}
-
-static int
-glusterd_op_sm_inject_all_acc (uuid_t *txn_id)
-{
- int32_t ret = -1;
- ret = glusterd_op_sm_inject_event (GD_OP_EVENT_ALL_ACC, txn_id, NULL);
- gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-
-static int
-glusterd_check_quota_cmd (char *key, char *value, char *errstr, size_t size)
-{
- int ret = -1;
- gf_boolean_t b = _gf_false;
-
- if ((strcmp (key, "quota") == 0) ||
- (strcmp (key, "features.quota") == 0)) {
- ret = gf_string2boolean (value, &b);
- if (ret)
- goto out;
- if (b) {
- snprintf (errstr, size," 'gluster "
- "volume set <VOLNAME> %s %s' is "
- "deprecated. Use 'gluster volume "
- "quota <VOLNAME> enable' instead.",
- key, value);
- ret = -1;
- goto out;
- } else {
- snprintf (errstr, size, " 'gluster "
- "volume set <VOLNAME> %s %s' is "
- "deprecated. Use 'gluster volume "
- "quota <VOLNAME> disable' instead.",
- key, value);
- ret = -1;
- goto out;
- }
- }
- ret = 0;
-out:
- return ret;
-}
-
-int
-glusterd_brick_op_build_payload (glusterd_op_t op, glusterd_brickinfo_t *brickinfo,
- gd1_mgmt_brick_op_req **req, dict_t *dict)
-{
- 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;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
-
- GF_ASSERT (op < GD_OP_MAX);
- GF_ASSERT (op > GD_OP_NONE);
- GF_ASSERT (req);
-
-
- switch (op) {
- case GD_OP_REMOVE_BRICK:
- case GD_OP_STOP_VOLUME:
- brick_req = GF_CALLOC (1, sizeof (*brick_req),
- gf_gld_mt_mop_brick_req_t);
- if (!brick_req)
- goto out;
- brick_req->op = GLUSTERD_BRICK_TERMINATE;
- brick_req->name = "";
- break;
- case GD_OP_PROFILE_VOLUME:
- brick_req = GF_CALLOC (1, sizeof (*brick_req),
- gf_gld_mt_mop_brick_req_t);
-
- if (!brick_req)
- goto out;
-
- brick_req->op = GLUSTERD_BRICK_XLATOR_INFO;
- brick_req->name = brickinfo->path;
-
- break;
- case GD_OP_HEAL_VOLUME:
- {
- brick_req = GF_CALLOC (1, sizeof (*brick_req),
- gf_gld_mt_mop_brick_req_t);
- if (!brick_req)
- goto out;
-
- brick_req->op = GLUSTERD_BRICK_XLATOR_OP;
- brick_req->name = "";
- ret = dict_get_int32 (dict, "heal-op", (int32_t*)&heal_op);
- 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)
- goto out;
- brick_req->op = GLUSTERD_BRICK_STATUS;
- brick_req->name = "";
- }
- 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)
- goto out;
-
- brick_req->op = GLUSTERD_BRICK_XLATOR_DEFRAG;
- ret = dict_get_str (dict, "volname", &volname);
- if (ret)
- goto out;
- snprintf (name, 1024, "%s-dht",volname);
- brick_req->name = gf_strdup (name);
-
- break;
- case GD_OP_SNAP:
- brick_req = GF_CALLOC (1, sizeof (*brick_req),
- gf_gld_mt_mop_brick_req_t);
- if (!brick_req)
- goto out;
-
- brick_req->op = GLUSTERD_BRICK_BARRIER;
- ret = dict_get_str (dict, "volname", &volname);
- if (ret)
- goto out;
- brick_req->name = gf_strdup (volname);
-
- break;
- case GD_OP_BARRIER:
- brick_req = GF_CALLOC (1, sizeof(*brick_req),
- gf_gld_mt_mop_brick_req_t);
- if (!brick_req)
- goto out;
- brick_req->op = GLUSTERD_BRICK_BARRIER;
- ret = dict_get_str(dict, "volname", &volname);
- if (ret)
- goto out;
- brick_req->name = gf_strdup (volname);
- break;
-
- default:
- goto out;
- break;
- }
-
- ret = dict_allocate_and_serialize (dict, &brick_req->input.input_val,
- &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 (this->name, 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)
-{
- int ret = -1;
- gd1_mgmt_brick_op_req *brick_req = NULL;
-
- GF_ASSERT (op < GD_OP_MAX);
- GF_ASSERT (op > GD_OP_NONE);
- GF_ASSERT (req);
-
- 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)
- goto out;
-
- brick_req->op = GLUSTERD_NODE_PROFILE;
- brick_req->name = "";
-
- break;
-
- case GD_OP_STATUS_VOLUME:
- brick_req = GF_CALLOC (1, sizeof (*brick_req),
- gf_gld_mt_mop_brick_req_t);
- if (!brick_req)
- goto out;
-
- brick_req->op = GLUSTERD_NODE_STATUS;
- brick_req->name = "";
-
- break;
-
- default:
- goto out;
- }
-
- ret = dict_allocate_and_serialize (dict, &brick_req->input.input_val,
- &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 (THIS->name, GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-
-static int
-glusterd_validate_quorum_options (xlator_t *this, char *fullkey, char *value,
- char **op_errstr)
-{
- int ret = 0;
- char *key = NULL;
- volume_option_t *opt = NULL;
-
- if (!glusterd_is_quorum_option (fullkey))
- goto out;
- key = strchr (fullkey, '.');
- if (key == NULL) {
- ret = -1;
- goto out;
- }
- key++;
- opt = xlator_volume_option_get (this, key);
- ret = xlator_option_validate (this, key, value, opt, op_errstr);
-out:
- return ret;
-}
-
-static int
-glusterd_check_client_op_version_support (char *volname, uint32_t op_version,
- char **op_errstr)
-{
- int ret = 0;
- xlator_t *this = NULL;
- glusterd_conf_t *priv = NULL;
- rpc_transport_t *xprt = NULL;
-
- this = THIS;
- GF_ASSERT(this);
- priv = this->private;
- GF_ASSERT(priv);
-
- pthread_mutex_lock (&priv->xprt_lock);
- list_for_each_entry (xprt, &priv->xprt_list, list) {
- if ((!strcmp(volname, xprt->peerinfo.volname)) &&
- ((op_version > xprt->peerinfo.max_op_version) ||
- (op_version < xprt->peerinfo.min_op_version))) {
- ret = -1;
- break;
- }
- }
- pthread_mutex_unlock (&priv->xprt_lock);
-
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "One or more clients "
- "don't support the required op-version");
- ret = gf_asprintf (op_errstr, "One or more connected clients "
- "cannot support the feature being set. "
- "These clients need to be upgraded or "
- "disconnected before running this command"
- " again");
- return -1;
- }
- return 0;
-}
-
-static int
-glusterd_op_stage_set_volume (dict_t *dict, char **op_errstr)
-{
- int ret = -1;
- char *volname = NULL;
- int exists = 0;
- char *key = NULL;
- char *key_fixed = NULL;
- char *value = NULL;
- char str[100] = {0, };
- int count = 0;
- int dict_count = 0;
- char errstr[2048] = {0, };
- glusterd_volinfo_t *volinfo = NULL;
- dict_t *val_dict = NULL;
- gf_boolean_t global_opt = _gf_false;
- glusterd_volinfo_t *voliter = NULL;
- glusterd_conf_t *priv = NULL;
- xlator_t *this = NULL;
- uint32_t new_op_version = 0;
- uint32_t local_new_op_version = 0;
- uint32_t key_op_version = 0;
- uint32_t local_key_op_version = 0;
- gf_boolean_t origin_glusterd = _gf_true;
- gf_boolean_t check_op_version = _gf_true;
- gf_boolean_t all_vol = _gf_false;
- struct volopt_map_entry *vme = NULL;
-
- GF_ASSERT (dict);
- this = THIS;
- GF_ASSERT (this);
- priv = this->private;
- GF_ASSERT (priv);
-
- val_dict = dict_new();
- if (!val_dict)
- goto out;
-
- /* Check if we can support the required op-version
- * This check is not done on the originator glusterd. The originator
- * glusterd sets this value.
- */
- origin_glusterd = is_origin_glusterd (dict);
-
- if (!origin_glusterd) {
- /* Check for v3.3.x origin glusterd */
- check_op_version = dict_get_str_boolean (dict,
- "check-op-version",
- _gf_false);
-
- if (check_op_version) {
- ret = dict_get_uint32 (dict, "new-op-version",
- &new_op_version);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to get new_op_version");
- goto out;
- }
-
- if ((new_op_version > GD_OP_VERSION_MAX) ||
- (new_op_version < GD_OP_VERSION_MIN)) {
- ret = -1;
- snprintf (errstr, sizeof (errstr),
- "Required op_version (%d) is not "
- "supported", new_op_version);
- gf_log (this->name, GF_LOG_ERROR, "%s", errstr);
- 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");
- goto out;
- }
-
- if (strcasecmp (volname, "all") != 0) {
- exists = glusterd_check_volume_exists (volname);
- if (!exists) {
- snprintf (errstr, sizeof (errstr),
- FMTSTR_CHECK_VOL_EXISTS, volname);
- gf_log (this->name, GF_LOG_ERROR, "%s", errstr);
- ret = -1;
- goto out;
- }
-
- ret = glusterd_volinfo_find (volname, &volinfo);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- FMTSTR_CHECK_VOL_EXISTS, volname);
- goto out;
- }
-
- ret = glusterd_validate_volume_id (dict, volinfo);
- if (ret)
- goto out;
- } else {
- all_vol = _gf_true;
- }
-
- local_new_op_version = priv->op_version;
-
- 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, "config.memory-accounting") == 0) {
- gf_log (this->name, GF_LOG_DEBUG,
- "enabling memory accounting for volume %s",
- volname);
- ret = 0;
- }
-
- if (strcmp (key, "config.transport") == 0) {
- gf_log (this->name, GF_LOG_DEBUG,
- "changing transport-type for volume %s",
- volname);
- ret = 0;
- /* if value is none of 'tcp/rdma/tcp,rdma' error out */
- if (!((strcasecmp (value, "rdma") == 0) ||
- (strcasecmp (value, "tcp") == 0) ||
- (strcasecmp (value, "tcp,rdma") == 0) ||
- (strcasecmp (value, "rdma,tcp") == 0))) {
- ret = snprintf (errstr, sizeof (errstr),
- "transport-type %s does "
- "not exist", value);
- /* lets not bother about above return value,
- its a failure anyways */
- ret = -1;
- goto out;
- }
- }
-
- ret = glusterd_check_quota_cmd (key, value, errstr, sizeof (errstr));
- if (ret)
- goto out;
-
- if (is_key_glusterd_hooks_friendly (key))
- continue;
-
- for (vme = &glusterd_volopt_map[0]; vme->key; vme++) {
- if ((vme->validate_fn) &&
- ((!strcmp (key, vme->key)) ||
- (!strcmp (key, strchr (vme->key, '.') + 1)))) {
- ret = vme->validate_fn (dict, key, value,
- op_errstr);
- if (ret)
- goto out;
- break;
- }
- }
-
- 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 does not exist", key);
- ret = snprintf (errstr, sizeof (errstr),
- "option : %s does not exist",
- key);
- if (key_fixed)
- snprintf (errstr + ret, sizeof (errstr) - ret,
- "\nDid you mean %s?", key_fixed);
- ret = -1;
- goto out;
- }
-
- if (key_fixed)
- key = key_fixed;
-
- /* Check if the key is cluster.op-version and set
- * local_new_op_version to the value given if possible.
- */
- if (strcmp (key, "cluster.op-version") == 0) {
- if (!all_vol) {
- ret = -1;
- snprintf (errstr, sizeof (errstr), "Option \""
- "%s\" is not valid for a single "
- "volume", key);
- goto out;
- }
- /* Check if cluster.op-version is the only option being
- * set
- */
- if (count != 1) {
- ret = -1;
- snprintf (errstr, sizeof (errstr), "Option \""
- "%s\" cannot be set along with other "
- "options", key);
- goto out;
- }
- /* Just reusing the variable, but I'm using it for
- * storing the op-version from value
- */
- ret = gf_string2uint (value, &local_key_op_version);
- if (ret) {
- snprintf (errstr, sizeof (errstr), "invalid "
- "number format \"%s\" in option "
- "\"%s\"", value, key);
- gf_log (this->name, GF_LOG_ERROR, "%s", errstr);
- goto out;
- }
-
- if (local_key_op_version > GD_OP_VERSION_MAX ||
- local_key_op_version < GD_OP_VERSION_MIN) {
- ret = -1;
- snprintf (errstr, sizeof (errstr),
- "Required op_version (%d) is not "
- "supported", local_key_op_version);
- gf_log (this->name, GF_LOG_ERROR, "%s", errstr);
- goto out;
- }
- if (local_key_op_version > local_new_op_version)
- local_new_op_version = local_key_op_version;
- goto cont;
- }
-
- ALL_VOLUME_OPTION_CHECK (volname, key, ret, op_errstr, out);
- ret = glusterd_validate_quorum_options (this, key, value,
- op_errstr);
- if (ret)
- goto out;
-
- local_key_op_version = glusterd_get_op_version_for_key (key);
- if (local_key_op_version > local_new_op_version)
- local_new_op_version = local_key_op_version;
-
- sprintf (str, "op-version%d", count);
- if (origin_glusterd) {
- ret = dict_set_uint32 (dict, str, local_key_op_version);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to set key-op-version in dict");
- goto out;
- }
- } else if (check_op_version) {
- ret = dict_get_uint32 (dict, str, &key_op_version);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to get key-op-version from"
- " dict");
- goto out;
- }
- if (local_key_op_version != key_op_version) {
- ret = -1;
- snprintf (errstr, sizeof (errstr),
- "option: %s op-version mismatch",
- key);
- gf_log (this->name, GF_LOG_ERROR,
- "%s, required op-version = %"PRIu32", "
- "available op-version = %"PRIu32,
- errstr, key_op_version,
- local_key_op_version);
- goto out;
- }
- }
-
- if (glusterd_check_globaloption (key))
- global_opt = _gf_true;
-
- ret = dict_set_str (val_dict, key, value);
-
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Unable to set the options in 'volume set'");
- ret = -1;
- goto out;
- }
-
- *op_errstr = NULL;
- if (!global_opt && !all_vol)
- ret = glusterd_validate_reconfopts (volinfo, val_dict, op_errstr);
- else if (!all_vol) {
- voliter = NULL;
- list_for_each_entry (voliter, &priv->volumes, vol_list) {
- ret = glusterd_validate_globalopts (voliter, val_dict, op_errstr);
- if (ret)
- break;
- }
- }
-
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Could not create "
- "temp volfile, some option failed: %s",
- *op_errstr);
- goto out;
- }
- dict_del (val_dict, key);
-
- if (key_fixed) {
- GF_FREE (key_fixed);
- key_fixed = NULL;
- }
- }
-
- // Check if all the connected clients support the new op-version
- ret = glusterd_check_client_op_version_support (volname,
- local_new_op_version,
- op_errstr);
- if (ret)
- goto out;
-
-cont:
- if (origin_glusterd) {
- ret = dict_set_uint32 (dict, "new-op-version",
- local_new_op_version);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to set new-op-version in dict");
- goto out;
- }
- /* Set this value in dict so other peers know to check for
- * op-version. This is a hack for 3.3.x compatibility
- *
- * TODO: Remove this and the other places this is referred once
- * 3.3.x compatibility is not required
- */
- ret = dict_set_uint32 (dict, "check-op-version",
- _gf_true);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to set check-op-version in dict");
- goto out;
- }
- }
-
- ret = 0;
-
-out:
- if (val_dict)
- dict_unref (val_dict);
-
- GF_FREE (key_fixed);
- if (errstr[0] != '\0')
- *op_errstr = gf_strdup (errstr);
-
- if (ret) {
- if (!(*op_errstr)) {
- *op_errstr = gf_strdup ("Error, Validation Failed");
- gf_log (this->name, GF_LOG_DEBUG,
- "Error, Cannot Validate option :%s",
- *op_errstr);
- } else {
- gf_log (this->name, GF_LOG_DEBUG,
- "Error, Cannot Validate option");
- }
- }
- return ret;
-}
-
-static int
-glusterd_op_stage_reset_volume (dict_t *dict, char **op_errstr)
-{
- int ret = 0;
- char *volname = NULL;
- int exists = 0;
- char msg[2048] = {0};
- char *key = NULL;
- char *key_fixed = NULL;
- glusterd_volinfo_t *volinfo = NULL;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
-
- ret = dict_get_str (dict, "volname", &volname);
-
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Unable to get volume name");
- goto out;
- }
-
- if (strcasecmp (volname, "all") != 0) {
- exists = glusterd_check_volume_exists (volname);
- if (!exists) {
- snprintf (msg, sizeof (msg), FMTSTR_CHECK_VOL_EXISTS,
- volname);
- ret = -1;
- goto out;
- }
- ret = glusterd_volinfo_find (volname, &volinfo);
- if (ret) {
- snprintf (msg, sizeof (msg), FMTSTR_CHECK_VOL_EXISTS,
- volname);
- goto out;
- }
-
- ret = glusterd_validate_volume_id (dict, volinfo);
- if (ret)
- goto out;
- }
-
- ret = dict_get_str (dict, "key", &key);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Unable to get option key");
- goto out;
- }
- if (strcmp(key, "all")) {
- exists = glusterd_check_option_exists (key, &key_fixed);
- if (exists == -1) {
- ret = -1;
- goto out;
- }
-
- if (!exists) {
- ret = snprintf (msg, sizeof (msg),
- "Option %s does not exist", key);
- if (key_fixed)
- snprintf (msg + ret, sizeof (msg) - ret,
- "\nDid you mean %s?", key_fixed);
- ret = -1;
- goto out;
- } else if (exists > 0) {
- if (key_fixed)
- key = key_fixed;
- ALL_VOLUME_OPTION_CHECK (volname, key, ret,
- op_errstr, out);
- }
- }
-
-out:
- GF_FREE (key_fixed);
-
- if (msg[0] != '\0') {
- gf_log (this->name, GF_LOG_ERROR, "%s", msg);
- *op_errstr = gf_strdup (msg);
- }
-
- gf_log (this->name, GF_LOG_DEBUG, "Returning %d", ret);
-
- return ret;
-}
-
-
-
-static int
-glusterd_op_stage_sync_volume (dict_t *dict, char **op_errstr)
-{
- int ret = -1;
- char *volname = NULL;
- char *hostname = NULL;
- 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) {
- snprintf (msg, sizeof (msg), "hostname couldn't be "
- "retrieved from msg");
- *op_errstr = gf_strdup (msg);
- goto out;
- }
-
- if (gf_is_local_addr (hostname)) {
- //volname is not present in case of sync all
- ret = dict_get_str (dict, "volname", &volname);
- if (!ret) {
- exists = glusterd_check_volume_exists (volname);
- if (!exists) {
- snprintf (msg, sizeof (msg), "Volume %s "
- "does not exist", volname);
- *op_errstr = gf_strdup (msg);
- ret = -1;
- goto out;
- }
- ret = glusterd_volinfo_find (volname, &volinfo);
- if (ret)
- goto out;
-
- } else {
- ret = 0;
- }
- } else {
- peerinfo = glusterd_peerinfo_find (NULL, hostname);
- if (peerinfo == NULL) {
- ret = -1;
- snprintf (msg, sizeof (msg), "%s, is not a friend",
- hostname);
- *op_errstr = gf_strdup (msg);
- goto out;
- }
-
- if (!peerinfo->connected) {
- snprintf (msg, sizeof (msg), "%s, is not connected at "
- "the moment", hostname);
- *op_errstr = gf_strdup (msg);
- ret = -1;
- goto out;
- }
-
- }
-
-out:
- gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
-
- 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);
-
- ret = dict_get_uint32 (dict, "cmd", &cmd);
- if (ret)
- goto out;
-
- if (cmd & GF_CLI_STATUS_ALL)
- goto out;
-
- if ((cmd & GF_CLI_STATUS_QUOTAD) &&
- (priv->op_version == GD_OP_VERSION_MIN)) {
- snprintf (msg, sizeof (msg), "The cluster is operating at "
- "version 1. Getting the status of quotad is not "
- "allowed in this state.");
- ret = -1;
- goto out;
- }
-
- if ((cmd & GF_CLI_STATUS_SNAPD) &&
- (priv->op_version < GD_OP_VERSION_3_6_0)) {
- snprintf (msg, sizeof (msg), "The cluster is operating at "
- "version less than %d. Getting the "
- "status of snapd is not allowed in this state.",
- GD_OP_VERSION_3_6_0);
- 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");
- goto out;
- }
-
- ret = glusterd_volinfo_find (volname, &volinfo);
- if (ret) {
- snprintf (msg, sizeof(msg), FMTSTR_CHECK_VOL_EXISTS, volname);
- ret = -1;
- goto out;
- }
-
- ret = glusterd_validate_volume_id (dict, volinfo);
- if (ret)
- goto out;
-
- ret = glusterd_is_volume_started (volinfo);
- if (!ret) {
- snprintf (msg, sizeof (msg), "Volume %s is not started",
- volname);
- ret = -1;
- goto out;
- }
-
- vol_opts = volinfo->dict;
-
- 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);
- goto out;
- }
- } else if ((cmd & GF_CLI_STATUS_SHD) != 0) {
- if (!glusterd_is_volume_replicate (volinfo)) {
- ret = -1;
- snprintf (msg, sizeof (msg),
- "Volume %s is not of type replicate",
- volname);
- goto out;
- }
-
- 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);
- goto out;
- }
- } else if ((cmd & GF_CLI_STATUS_QUOTAD) != 0) {
- if (!glusterd_is_volume_quota_enabled (volinfo)) {
- ret = -1;
- snprintf (msg, sizeof (msg), "Volume %s does not have "
- "quota enabled", volname);
- goto out;
- }
- } else if ((cmd & GF_CLI_STATUS_SNAPD) != 0) {
- if (!glusterd_is_snapd_enabled (volinfo)) {
- ret = -1;
- snprintf (msg, sizeof (msg), "Volume %s does not have "
- "uss enabled", volname);
- goto out;
- }
- } 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) {
- snprintf (msg, sizeof(msg), "No brick %s in"
- " volume %s", brick, volname);
- ret = -1;
- goto out;
- }
- }
-
- ret = 0;
-
- out:
- if (ret) {
- if (msg[0] != '\0')
- *op_errstr = gf_strdup (msg);
- else
- *op_errstr = gf_strdup ("Validation Failed for Status");
- }
-
- gf_log (this->name, GF_LOG_DEBUG, "Returning: %d", ret);
- return ret;
-}
-
-
-static gf_boolean_t
-glusterd_is_profile_on (glusterd_volinfo_t *volinfo)
-{
- int ret = -1;
- gf_boolean_t is_latency_on = _gf_false;
- gf_boolean_t is_fd_stats_on = _gf_false;
-
- GF_ASSERT (volinfo);
-
- ret = glusterd_volinfo_get_boolean (volinfo, VKEY_DIAG_CNT_FOP_HITS);
- if (ret != -1)
- is_fd_stats_on = ret;
- ret = glusterd_volinfo_get_boolean (volinfo, VKEY_DIAG_LAT_MEASUREMENT);
- if (ret != -1)
- is_latency_on = ret;
- if ((_gf_true == is_latency_on) &&
- (_gf_true == is_fd_stats_on))
- return _gf_true;
- return _gf_false;
-}
-
-static int
-glusterd_op_stage_stats_volume (dict_t *dict, char **op_errstr)
-{
- int ret = -1;
- char *volname = NULL;
- gf_boolean_t exists = _gf_false;
- char msg[2048] = {0,};
- int32_t stats_op = GF_CLI_STATS_NONE;
- glusterd_volinfo_t *volinfo = NULL;
-
- ret = dict_get_str (dict, "volname", &volname);
- if (ret) {
- snprintf (msg, sizeof (msg), "Volume name get failed");
- goto out;
- }
-
- exists = glusterd_check_volume_exists (volname);
- ret = glusterd_volinfo_find (volname, &volinfo);
- if ((!exists) || (ret < 0)) {
- snprintf (msg, sizeof (msg), "Volume %s, "
- "doesn't exist", volname);
- ret = -1;
- 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");
- goto out;
- }
-
- if (GF_CLI_STATS_START == stats_op) {
- if (_gf_true == glusterd_is_profile_on (volinfo)) {
- snprintf (msg, sizeof (msg), "Profile on Volume %s is"
- " already started", volinfo->volname);
- ret = -1;
- goto out;
- }
-
- }
- if ((GF_CLI_STATS_STOP == stats_op) ||
- (GF_CLI_STATS_INFO == stats_op)) {
- if (_gf_false == glusterd_is_profile_on (volinfo)) {
- snprintf (msg, sizeof (msg), "Profile on Volume %s is"
- " not started", volinfo->volname);
- ret = -1;
-
- goto out;
- }
- }
- if ((GF_CLI_STATS_TOP == stats_op) ||
- (GF_CLI_STATS_INFO == stats_op)) {
- if (_gf_false == glusterd_is_volume_started (volinfo)) {
- snprintf (msg, sizeof (msg), "Volume %s is not started.",
- volinfo->volname);
- gf_log ("glusterd", GF_LOG_ERROR, "%s", msg);
- ret = -1;
- goto out;
- }
- }
- ret = 0;
-out:
- if (msg[0] != '\0') {
- gf_log ("glusterd", GF_LOG_ERROR, "%s", msg);
- *op_errstr = gf_strdup (msg);
- }
- gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-
-
-static int
-_delete_reconfig_opt (dict_t *this, char *key, data_t *value, void *data)
-{
- int32_t *is_force = 0;
-
- GF_ASSERT (data);
- is_force = (int32_t*)data;
-
- if (*is_force != 1) {
- if (_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 = *is_force | GD_OP_PROTECTED;
- goto out;
- } else {
- *is_force = *is_force | GD_OP_UNPROTECTED;
- }
- }
-
- gf_log ("", GF_LOG_DEBUG, "deleting dict with key=%s,value=%s",
- key, value->data);
- dict_del (this, key);
-out:
- return 0;
-}
-
-static int
-_delete_reconfig_global_opt (dict_t *this, char *key, data_t *value, void *data)
-{
- int32_t *is_force = 0;
-
- GF_ASSERT (data);
- is_force = (int32_t*)data;
-
- if (strcmp (GLUSTERD_GLOBAL_OPT_VERSION, key) == 0)
- goto out;
-
- _delete_reconfig_opt (this, key, value, data);
-out:
- return 0;
-}
-
-static int
-glusterd_options_reset (glusterd_volinfo_t *volinfo, char *key,
- int32_t *is_force)
-{
- int ret = 0;
- data_t *value = NULL;
- char *key_fixed = NULL;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (volinfo->dict);
- GF_ASSERT (key);
-
- if (!strncmp(key, "all", 3)) {
- dict_foreach (volinfo->dict, _delete_reconfig_opt, is_force);
- ret = glusterd_enable_default_options (volinfo, NULL);
- if (ret) {
- gf_msg (this->name, GF_LOG_ERROR, 0,
- GD_MSG_FAIL_DEFAULT_OPT_SET, "Failed to set "
- "default options on reset for volume %s",
- volinfo->volname);
- goto out;
- }
- } else {
- value = dict_get (volinfo->dict, key);
- if (!value) {
- gf_log (this->name, GF_LOG_DEBUG,
- "no value set for option %s", key);
- goto out;
- }
- _delete_reconfig_opt (volinfo->dict, key, value, is_force);
- ret = glusterd_enable_default_options (volinfo, key);
- if (ret) {
- gf_msg (this->name, GF_LOG_ERROR, 0,
- GD_MSG_FAIL_DEFAULT_OPT_SET, "Failed to set "
- "default value for option '%s' on reset for "
- "volume %s", key, volinfo->volname);
- goto out;
- }
- }
-
- gd_update_volume_op_versions (volinfo);
-
- ret = glusterd_create_volfiles_and_notify_services (volinfo);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Unable to create volfile for"
- " 'volume reset'");
- 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);
- if (ret)
- goto out;
- }
-
- ret = 0;
-
-out:
- GF_FREE (key_fixed);
- gf_log (this->name, GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-
-static int
-glusterd_op_reset_all_volume_options (xlator_t *this, dict_t *dict)
-{
- char *key = NULL;
- char *key_fixed = NULL;
- int ret = -1;
- int32_t is_force = 0;
- glusterd_conf_t *conf = NULL;
- dict_t *dup_opt = NULL;
- gf_boolean_t all = _gf_false;
- char *next_version = NULL;
- gf_boolean_t quorum_action = _gf_false;
-
- conf = this->private;
- ret = dict_get_str (dict, "key", &key);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to get key");
- goto out;
- }
-
- ret = dict_get_int32 (dict, "force", &is_force);
- if (ret)
- is_force = 0;
-
- if (strcmp (key, "all")) {
- ret = glusterd_check_option_exists (key, &key_fixed);
- if (ret <= 0) {
- gf_log (this->name, GF_LOG_ERROR, "Option %s does not "
- "exist", key);
- ret = -1;
- goto out;
- }
- } else {
- all = _gf_true;
- }
-
- if (key_fixed)
- key = key_fixed;
-
- ret = -1;
- dup_opt = dict_new ();
- if (!dup_opt)
- goto out;
- if (!all) {
- dict_copy (conf->opts, dup_opt);
- dict_del (dup_opt, key);
- }
- ret = glusterd_get_next_global_opt_version_str (conf->opts,
- &next_version);
- if (ret)
- goto out;
-
- ret = dict_set_str (dup_opt, GLUSTERD_GLOBAL_OPT_VERSION, next_version);
- if (ret)
- goto out;
-
- ret = glusterd_store_options (this, dup_opt);
- if (ret)
- goto out;
-
- if (glusterd_is_quorum_changed (conf->opts, key, NULL))
- quorum_action = _gf_true;
-
- ret = dict_set_dynstr (conf->opts, GLUSTERD_GLOBAL_OPT_VERSION,
- next_version);
- if (ret)
- goto out;
- else
- next_version = NULL;
-
- if (!all) {
- dict_del (conf->opts, key);
- } else {
- dict_foreach (conf->opts, _delete_reconfig_global_opt,
- &is_force);
- }
-out:
- GF_FREE (key_fixed);
- if (dup_opt)
- dict_unref (dup_opt);
-
- gf_log (this->name, GF_LOG_DEBUG, "returning %d", ret);
- if (quorum_action)
- glusterd_do_quorum_action ();
- GF_FREE (next_version);
- return ret;
-}
-
-static int
-glusterd_op_reset_volume (dict_t *dict, char **op_rspstr)
-{
- glusterd_volinfo_t *volinfo = NULL;
- int ret = -1;
- char *volname = NULL;
- char *key = NULL;
- char *key_fixed = NULL;
- int32_t is_force = 0;
- gf_boolean_t quorum_action = _gf_false;
- xlator_t *this = NULL;
-
- this = THIS;
- ret = dict_get_str (dict, "volname", &volname);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Unable to get volume name" );
- goto out;
- }
-
- if (strcasecmp (volname, "all") == 0) {
- ret = glusterd_op_reset_all_volume_options (this, dict);
- goto out;
- }
-
- ret = dict_get_int32 (dict, "force", &is_force);
- if (ret)
- is_force = 0;
-
- ret = dict_get_str (dict, "key", &key);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Unable to get option key");
- goto out;
- }
-
- ret = glusterd_volinfo_find (volname, &volinfo);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, FMTSTR_CHECK_VOL_EXISTS,
- volname);
- goto out;
- }
-
- if (strcmp (key, "all") &&
- glusterd_check_option_exists (key, &key_fixed) != 1) {
- gf_log (this->name, GF_LOG_ERROR,
- "volinfo dict inconsistency: option %s not found",
- key);
- ret = -1;
- goto out;
- }
- if (key_fixed)
- key = key_fixed;
-
- if (glusterd_is_quorum_changed (volinfo->dict, key, NULL))
- quorum_action = _gf_true;
-
- ret = glusterd_options_reset (volinfo, key, &is_force);
- if (ret == -1) {
- gf_asprintf(op_rspstr, "Volume reset : failed");
- } else if (is_force & GD_OP_PROTECTED) {
- if (is_force & GD_OP_UNPROTECTED) {
- gf_asprintf (op_rspstr, "All unprotected fields were"
- " reset. To reset the protected fields,"
- " use 'force'.");
- } else {
- ret = -1;
- gf_asprintf (op_rspstr, "'%s' is protected. To reset"
- " use 'force'.", key);
- }
- }
-
-out:
- GF_FREE (key_fixed);
- if (quorum_action)
- glusterd_do_quorum_action ();
-
- gf_log (this->name, GF_LOG_DEBUG, "'volume reset' returning %d", ret);
- return ret;
-}
-
-int
-glusterd_stop_bricks (glusterd_volinfo_t *volinfo)
-{
- glusterd_brickinfo_t *brickinfo = NULL;
-
- list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) {
- /*TODO: Need to change @del_brick in brick_stop to _gf_true
- * once we enable synctask in peer rpc prog */
- if (glusterd_brick_stop (volinfo, brickinfo, _gf_false))
- return -1;
- }
-
- return 0;
-}
-
-int
-glusterd_start_bricks (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_brick_start (volinfo, brickinfo, _gf_false);
- if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR,
- "Failed to start %s:%s for %s",
- brickinfo->hostname, brickinfo->path,
- volinfo->volname);
- goto out;
- }
- }
-
- ret = 0;
-out:
- return ret;
-}
-
-static int
-glusterd_op_set_all_volume_options (xlator_t *this, dict_t *dict)
-{
- char *key = NULL;
- char *key_fixed = NULL;
- char *value = NULL;
- char *dup_value = NULL;
- int ret = -1;
- glusterd_conf_t *conf = NULL;
- dict_t *dup_opt = NULL;
- char *next_version = NULL;
- gf_boolean_t quorum_action = _gf_false;
- uint32_t op_version = 0;
-
- conf = this->private;
- ret = dict_get_str (dict, "key1", &key);
- if (ret)
- goto out;
-
- ret = dict_get_str (dict, "value1", &value);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "invalid key,value pair in 'volume set'");
- goto out;
- }
- ret = glusterd_check_option_exists (key, &key_fixed);
- if (ret <= 0) {
- gf_log (this->name, GF_LOG_ERROR, "Invalid key %s", key);
- ret = -1;
- goto out;
- }
-
- if (key_fixed)
- key = key_fixed;
-
- /* If the key is cluster.op-version, set conf->op_version to the value
- * if needed and save it.
- */
- if (strcmp(key, "cluster.op-version") == 0) {
- ret = 0;
-
- ret = gf_string2uint (value, &op_version);
- if (ret)
- goto out;
-
- if (op_version >= conf->op_version) {
- conf->op_version = op_version;
- ret = glusterd_store_global_info (this);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to store op-version.");
- }
- }
- /* No need to save cluster.op-version in conf->opts
- */
- goto out;
- }
-
- ret = -1;
- dup_opt = dict_new ();
- if (!dup_opt)
- goto out;
- dict_copy (conf->opts, dup_opt);
- ret = dict_set_str (dup_opt, key, value);
- if (ret)
- goto out;
-
- ret = glusterd_get_next_global_opt_version_str (conf->opts,
- &next_version);
- if (ret)
- goto out;
-
- ret = dict_set_str (dup_opt, GLUSTERD_GLOBAL_OPT_VERSION, next_version);
- if (ret)
- goto out;
-
- ret = glusterd_store_options (this, dup_opt);
- if (ret)
- goto out;
-
- if (glusterd_is_quorum_changed (conf->opts, key, value))
- quorum_action = _gf_true;
-
- ret = dict_set_dynstr (conf->opts, GLUSTERD_GLOBAL_OPT_VERSION,
- next_version);
- if (ret)
- goto out;
- else
- next_version = NULL;
-
- dup_value = gf_strdup (value);
- if (!dup_value)
- goto out;
-
- ret = dict_set_dynstr (conf->opts, key, dup_value);
- if (ret)
- goto out;
- else
- dup_value = NULL; /* Protect the allocation from GF_FREE */
-
-out:
- GF_FREE (dup_value);
- GF_FREE (key_fixed);
- if (dup_opt)
- dict_unref (dup_opt);
-
- gf_log (this->name, GF_LOG_DEBUG, "returning %d", ret);
- if (quorum_action)
- glusterd_do_quorum_action ();
- GF_FREE (next_version);
- return ret;
-}
-
-static int
-glusterd_op_set_volume (dict_t *dict)
-{
- int ret = 0;
- glusterd_volinfo_t *volinfo = NULL;
- char *volname = NULL;
- 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, };
- char *op_errstr = NULL;
- gf_boolean_t global_opt = _gf_false;
- gf_boolean_t global_opts_set = _gf_false;
- glusterd_volinfo_t *voliter = NULL;
- int32_t dict_count = 0;
- gf_boolean_t check_op_version = _gf_false;
- uint32_t new_op_version = 0;
- gf_boolean_t quorum_action = _gf_false;
-
- this = THIS;
- GF_ASSERT (this);
-
- 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 (NULL, &op_errstr);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "%s",
- (op_errstr)? op_errstr:
- "Volume set help internal error");
- }
-
- GF_FREE(op_errstr);
- 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;
- }
-
- if (strcasecmp (volname, "all") == 0) {
- ret = glusterd_op_set_all_volume_options (this, dict);
- goto out;
- }
-
- ret = glusterd_volinfo_find (volname, &volinfo);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, FMTSTR_CHECK_VOL_EXISTS,
- volname);
- goto out;
- }
-
- // TODO: Remove this once v3.3 compatability is not required
- check_op_version = dict_get_str_boolean (dict, "check-op-version",
- _gf_false);
-
- if (check_op_version) {
- ret = dict_get_uint32 (dict, "new-op-version", &new_op_version);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Unable to get new op-version from dict");
- goto out;
- }
- }
-
- for (count = 1; ret != -1 ; count++) {
-
- 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, "config.memory-accounting") == 0) {
- ret = gf_string2boolean (value,
- &volinfo->memory_accounting);
- }
-
- if (strcmp (key, "config.transport") == 0) {
- gf_log (this->name, GF_LOG_INFO,
- "changing transport-type for volume %s to %s",
- volname, value);
- ret = 0;
- if (strcasecmp (value, "rdma") == 0) {
- volinfo->transport_type = GF_TRANSPORT_RDMA;
- } else if (strcasecmp (value, "tcp") == 0) {
- volinfo->transport_type = GF_TRANSPORT_TCP;
- } else if ((strcasecmp (value, "tcp,rdma") == 0) ||
- (strcasecmp (value, "rdma,tcp") == 0)) {
- volinfo->transport_type =
- GF_TRANSPORT_BOTH_TCP_RDMA;
- } else {
- ret = -1;
- goto out;
- }
- }
-
- if (!is_key_glusterd_hooks_friendly (key)) {
- ret = glusterd_check_option_exists (key, &key_fixed);
- GF_ASSERT (ret);
- if (ret <= 0) {
- key_fixed = NULL;
- goto out;
- }
- }
-
- global_opt = _gf_false;
- if (glusterd_check_globaloption (key)) {
- global_opt = _gf_true;
- global_opts_set = _gf_true;
- }
-
- if (!global_opt)
- value = gf_strdup (value);
-
- if (!value) {
- gf_log (this->name, GF_LOG_ERROR,
- "Unable to set the options in 'volume set'");
- ret = -1;
- goto out;
- }
-
- if (key_fixed)
- key = key_fixed;
-
- if (glusterd_is_quorum_changed (volinfo->dict, key, value))
- quorum_action = _gf_true;
-
- if (global_opt) {
- list_for_each_entry (voliter, &priv->volumes, vol_list) {
- value = gf_strdup (value);
- ret = dict_set_dynstr (voliter->dict, key, value);
- if (ret)
- goto out;
- }
- } else {
- ret = dict_set_dynstr (volinfo->dict, key, value);
- if (ret)
- goto out;
- }
-
- if (key_fixed) {
- GF_FREE (key_fixed);
- key_fixed = NULL;
- }
- }
-
- if (count == 1) {
- gf_log (this->name, GF_LOG_ERROR, "No options received ");
- ret = -1;
- goto out;
- }
-
- /* Update the cluster op-version before regenerating volfiles so that
- * correct volfiles are generated
- */
- if (new_op_version > priv->op_version) {
- priv->op_version = new_op_version;
- ret = glusterd_store_global_info (this);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to store op-version");
- goto out;
- }
- }
-
- if (!global_opts_set) {
- gd_update_volume_op_versions (volinfo);
-
- ret = glusterd_handle_snapd_option (volinfo);
- if (ret)
- goto out;
-
- ret = glusterd_create_volfiles_and_notify_services (volinfo);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Unable to create volfile for"
- " 'volume set'");
- 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);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING,
- "Unable to restart NFS-Server");
- goto out;
- }
- }
-
- } else {
- list_for_each_entry (voliter, &priv->volumes, vol_list) {
- volinfo = voliter;
- gd_update_volume_op_versions (volinfo);
-
- ret = glusterd_handle_snapd_option (volinfo);
- if (ret)
- goto out;
-
- ret = glusterd_create_volfiles_and_notify_services (volinfo);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Unable to create volfile for"
- " 'volume set'");
- 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);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING,
- "Unable to restart NFS-Server");
- goto out;
- }
- }
- }
- }
-
- out:
- GF_FREE (key_fixed);
- gf_log (this->name, GF_LOG_DEBUG, "returning %d", ret);
- if (quorum_action)
- glusterd_do_quorum_action ();
- return ret;
-}
-
-
-static int
-glusterd_op_sync_volume (dict_t *dict, char **op_errstr,
- dict_t *rsp_dict)
-{
- int ret = -1;
- char *volname = NULL;
- char *hostname = NULL;
- char msg[2048] = {0,};
- int count = 1;
- int vol_count = 0;
- 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, "hostname", &hostname);
- if (ret) {
- snprintf (msg, sizeof (msg), "hostname couldn't be "
- "retrieved from msg");
- *op_errstr = gf_strdup (msg);
- goto out;
- }
-
- if (!gf_is_local_addr (hostname)) {
- ret = 0;
- goto out;
- }
-
- //volname is not present in case of sync all
- ret = dict_get_str (dict, "volname", &volname);
- if (!ret) {
- ret = glusterd_volinfo_find (volname, &volinfo);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Volume with name: %s "
- "not exists", volname);
- goto out;
- }
- }
-
- if (!rsp_dict) {
- //this should happen only on source
- ret = 0;
- goto out;
- }
-
- if (volname) {
- ret = glusterd_add_volume_to_dict (volinfo, rsp_dict,
- 1, "volume");
- vol_count = 1;
- } else {
- list_for_each_entry (volinfo, &priv->volumes, vol_list) {
- ret = glusterd_add_volume_to_dict (volinfo, rsp_dict,
- count, "volume");
- if (ret)
- goto out;
-
- vol_count = count++;
- }
- }
- ret = dict_set_int32 (rsp_dict, "count", vol_count);
-
-out:
- gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
-
- return ret;
-}
-
-static int
-glusterd_add_profile_volume_options (glusterd_volinfo_t *volinfo)
-{
- int ret = -1;
- char *latency_key = NULL;
- char *fd_stats_key = NULL;
-
- GF_ASSERT (volinfo);
-
- latency_key = VKEY_DIAG_LAT_MEASUREMENT;
- fd_stats_key = VKEY_DIAG_CNT_FOP_HITS;
-
- ret = dict_set_str (volinfo->dict, latency_key, "on");
- if (ret) {
- gf_log ("glusterd", GF_LOG_ERROR, "failed to set the volume %s "
- "option %s value %s",
- volinfo->volname, latency_key, "on");
- goto out;
- }
-
- ret = dict_set_str (volinfo->dict, fd_stats_key, "on");
- if (ret) {
- gf_log ("glusterd", GF_LOG_ERROR, "failed to set the volume %s "
- "option %s value %s",
- volinfo->volname, fd_stats_key, "on");
- goto out;
- }
-out:
- gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-
-static void
-glusterd_remove_profile_volume_options (glusterd_volinfo_t *volinfo)
-{
- char *latency_key = NULL;
- char *fd_stats_key = NULL;
-
- GF_ASSERT (volinfo);
-
- latency_key = VKEY_DIAG_LAT_MEASUREMENT;
- fd_stats_key = VKEY_DIAG_CNT_FOP_HITS;
- dict_del (volinfo->dict, latency_key);
- dict_del (volinfo->dict, fd_stats_key);
-}
-
-static int
-glusterd_op_stats_volume (dict_t *dict, char **op_errstr,
- dict_t *rsp_dict)
-{
- int ret = -1;
- char *volname = NULL;
- char msg[2048] = {0,};
- glusterd_volinfo_t *volinfo = NULL;
- int32_t stats_op = GF_CLI_STATS_NONE;
-
- 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 exists",
- volname);
-
- gf_log ("", GF_LOG_ERROR, "%s", msg);
- goto out;
- }
-
- ret = dict_get_int32 (dict, "op", &stats_op);
- if (ret) {
- gf_log ("glusterd", GF_LOG_ERROR, "volume profile op get failed");
- goto out;
- }
-
- switch (stats_op) {
- case GF_CLI_STATS_START:
- ret = glusterd_add_profile_volume_options (volinfo);
- if (ret)
- goto out;
- break;
- case GF_CLI_STATS_STOP:
- glusterd_remove_profile_volume_options (volinfo);
- break;
- case GF_CLI_STATS_INFO:
- case GF_CLI_STATS_TOP:
- //info is already collected in brick op.
- //just goto out;
- ret = 0;
- goto out;
- break;
- default:
- GF_ASSERT (0);
- gf_log ("glusterd", GF_LOG_ERROR, "Invalid profile op: %d",
- stats_op);
- ret = -1;
- goto out;
- break;
- }
- ret = glusterd_create_volfiles_and_notify_services (volinfo);
-
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Unable to create volfile for"
- " 'volume set'");
- 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 = 0;
-
-out:
- gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
-
- return ret;
-}
-
-static int
-_add_brick_name_to_dict (dict_t *dict, char *key, glusterd_brickinfo_t *brick)
-{
- int ret = -1;
- char tmp[1024] = {0,};
- char *brickname = NULL;
- xlator_t *this = NULL;
-
- GF_ASSERT (dict);
- GF_ASSERT (key);
- GF_ASSERT (brick);
-
- this = THIS;
- GF_ASSERT (this);
-
- snprintf (tmp, sizeof (tmp), "%s:%s", brick->hostname, brick->path);
- brickname = gf_strdup (tmp);
- if (!brickname) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to dup brick name");
- goto out;
- }
-
- ret = dict_set_dynstr (dict, key, brickname);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to add brick name to dict");
- goto out;
- }
- brickname = NULL;
-out:
- if (brickname)
- GF_FREE (brickname);
- return ret;
-}
-
-static int
-_add_remove_bricks_to_dict (dict_t *dict, glusterd_volinfo_t *volinfo,
- char *prefix)
-{
- int ret = -1;
- int count = 0;
- int i = 0;
- char brick_key[1024] = {0,};
- char dict_key[1024] ={0,};
- char *brick = NULL;
- xlator_t *this = NULL;
-
- GF_ASSERT (dict);
- GF_ASSERT (volinfo);
- GF_ASSERT (prefix);
-
- this = THIS;
- GF_ASSERT (this);
-
- ret = dict_get_int32 (volinfo->rebal.dict, "count", &count);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to get brick count");
- goto out;
- }
-
- snprintf (dict_key, sizeof (dict_key), "%s.count", prefix);
- ret = dict_set_int32 (dict, dict_key, count);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to set brick count in dict");
- goto out;
- }
-
- for (i = 1; i <= count; i++) {
- memset (brick_key, 0, sizeof (brick_key));
- snprintf (brick_key, sizeof (brick_key), "brick%d", i);
-
- ret = dict_get_str (volinfo->rebal.dict, brick_key, &brick);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Unable to get %s", brick_key);
- goto out;
- }
-
- memset (dict_key, 0, sizeof (dict_key));
- snprintf (dict_key, sizeof (dict_key), "%s.%s", prefix,
- brick_key);
- ret = dict_set_str (dict, dict_key, brick);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to add brick to dict");
- goto out;
- }
- brick = NULL;
- }
-
-out:
- return ret;
-}
-
-/* This adds the respective task-id and all available parameters of a task into
- * a dictionary
- */
-static int
-_add_task_to_dict (dict_t *dict, glusterd_volinfo_t *volinfo, int op, int index)
-{
-
- int ret = -1;
- char key[128] = {0,};
- char *uuid_str = NULL;
- int status = 0;
- xlator_t *this = NULL;
-
- GF_ASSERT (dict);
- GF_ASSERT (volinfo);
-
- this = THIS;
- GF_ASSERT (this);
-
- switch (op) {
- case GD_OP_REMOVE_BRICK:
- snprintf (key, sizeof (key), "task%d", index);
- ret = _add_remove_bricks_to_dict (dict, volinfo, key);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to add remove bricks to dict");
- goto out;
- }
- case GD_OP_REBALANCE:
- uuid_str = gf_strdup (uuid_utoa (volinfo->rebal.rebalance_id));
- status = volinfo->rebal.defrag_status;
- break;
-
- case GD_OP_REPLACE_BRICK:
- snprintf (key, sizeof (key), "task%d.src-brick", index);
- ret = _add_brick_name_to_dict (dict, key,
- volinfo->rep_brick.src_brick);
- if (ret)
- goto out;
- memset (key, 0, sizeof (key));
-
- snprintf (key, sizeof (key), "task%d.dst-brick", index);
- ret = _add_brick_name_to_dict (dict, key,
- volinfo->rep_brick.dst_brick);
- if (ret)
- goto out;
- memset (key, 0, sizeof (key));
-
- uuid_str = gf_strdup (uuid_utoa (volinfo->rep_brick.rb_id));
- status = volinfo->rep_brick.rb_status;
- break;
-
- default:
- ret = -1;
- gf_log (this->name, GF_LOG_ERROR, "%s operation doesn't have a"
- " task_id", gd_op_list[op]);
- goto out;
- }
-
- snprintf (key, sizeof (key), "task%d.type", index);
- ret = dict_set_str (dict, key, (char *)gd_op_list[op]);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Error setting task type in dict");
- goto out;
- }
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "task%d.id", index);
-
- if (!uuid_str)
- goto out;
- ret = dict_set_dynstr (dict, key, uuid_str);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Error setting task id in dict");
- goto out;
- }
- uuid_str = NULL;
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "task%d.status", index);
- ret = dict_set_int32 (dict, key, status);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Error setting task status in dict");
- goto out;
- }
-
-out:
- if (uuid_str)
- GF_FREE (uuid_str);
- return ret;
-}
-
-static int
-glusterd_aggregate_task_status (dict_t *rsp_dict, glusterd_volinfo_t *volinfo)
-{
- int ret = -1;
- int tasks = 0;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
-
- if (!uuid_is_null (volinfo->rebal.rebalance_id)) {
- ret = _add_task_to_dict (rsp_dict, volinfo, volinfo->rebal.op,
- tasks);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to add task details to dict");
- goto out;
- }
- tasks++;
- }
-
- if (!uuid_is_null (volinfo->rep_brick.rb_id)) {
- ret = _add_task_to_dict (rsp_dict, volinfo, GD_OP_REPLACE_BRICK,
- tasks);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to add task details to dict");
- goto out;
- }
- tasks++;
- }
-
- ret = dict_set_int32 (rsp_dict, "tasks", tasks);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Error setting tasks count in dict");
- goto out;
- }
- ret = 0;
-
-out:
- return ret;
-}
-
-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;
- gf_boolean_t origin_glusterd = _gf_false;
-
- this = THIS;
- GF_ASSERT (this);
- priv = this->private;
-
- GF_ASSERT (priv);
-
- GF_ASSERT (dict);
-
- origin_glusterd = is_origin_glusterd (dict);
-
- ret = dict_get_uint32 (dict, "cmd", &cmd);
- if (ret)
- goto out;
-
- if (origin_glusterd) {
- ret = 0;
- 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_QUOTAD) != 0) {
- ret = glusterd_add_node_to_dict ("quotad", rsp_dict, 0,
- vol_opts);
- if (ret)
- goto out;
- other_count++;
- node_count++;
- } else if ((cmd & GF_CLI_STATUS_SNAPD) != 0) {
- ret = glusterd_add_node_to_dict ("snapd", 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 if ((cmd & GF_CLI_STATUS_TASKS) != 0) {
- ret = glusterd_aggregate_task_status (rsp_dict, volinfo);
- goto out;
-
- } 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;
- if (glusterd_is_snapd_enabled (volinfo)) {
- ret = glusterd_add_snapd_to_dict (volinfo,
- rsp_dict,
- other_index);
- if (ret)
- goto out;
- other_count++;
- other_index++;
- node_count++;
- }
-
- 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++;
- other_index++;
- }
- if (glusterd_is_volume_quota_enabled (volinfo)) {
- ret = glusterd_add_node_to_dict ("quotad",
- 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");
- goto out;
- }
-
- /* Active tasks */
- /* Tasks are added only for normal volume status request for either a
- * single volume or all volumes
- */
- if (!glusterd_status_has_tasks (cmd))
- goto out;
-
- ret = glusterd_aggregate_task_status (rsp_dict, volinfo);
- if (ret)
- goto out;
- ret = 0;
-
-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;
-
- gf_log (THIS->name, GF_LOG_DEBUG, "Returning with %d", ret);
-
- return ret;
-}
-
-static int
-glusterd_op_sm_locking_failed (uuid_t *txn_id)
-{
- int ret = -1;
-
- opinfo.op_ret = -1;
- opinfo.op_errstr = gf_strdup ("locking failed for one of the peer.");
-
- /* Inject a reject event such that unlocking gets triggered right away*/
- ret = glusterd_op_sm_inject_event (GD_OP_EVENT_RCVD_RJT, txn_id, NULL);
-
- return ret;
-}
-
-static int
-glusterd_op_ac_send_lock (glusterd_op_sm_event_t *event, void *ctx)
-{
- int ret = 0;
- rpc_clnt_procedure_t *proc = NULL;
- glusterd_conf_t *priv = NULL;
- xlator_t *this = NULL;
- glusterd_peerinfo_t *peerinfo = NULL;
- uint32_t pending_count = 0;
- dict_t *dict = NULL;
-
- this = THIS;
- priv = this->private;
- GF_ASSERT (priv);
-
- list_for_each_local_xaction_peers (peerinfo,
- opinfo.local_xaction_peers) {
- GF_ASSERT (peerinfo);
-
- if (!peerinfo->connected || !peerinfo->mgmt)
- continue;
- if ((peerinfo->state.state != GD_FRIEND_STATE_BEFRIENDED) &&
- (glusterd_op_get_op() != GD_OP_SYNC_VOLUME))
- continue;
-
- /* Based on the op_version, acquire a cluster or mgmt_v3 lock */
- if (priv->op_version < GD_OP_VERSION_3_6_0) {
- proc = &peerinfo->mgmt->proctable
- [GLUSTERD_MGMT_CLUSTER_LOCK];
- if (proc->fn) {
- ret = proc->fn (NULL, this, peerinfo);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING,
- "Failed to send lock request "
- "for operation 'Volume %s' to "
- "peer %s",
- gd_op_list[opinfo.op],
- peerinfo->hostname);
- goto out;
- }
- /* Mark the peer as locked*/
- peerinfo->locked = _gf_true;
- pending_count++;
- }
- } else {
- dict = glusterd_op_get_ctx ();
- dict_ref (dict);
-
- proc = &peerinfo->mgmt_v3->proctable
- [GLUSTERD_MGMT_V3_LOCK];
- if (proc->fn) {
- ret = dict_set_static_ptr (dict, "peerinfo",
- peerinfo);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "failed to set peerinfo");
- dict_unref (dict);
- goto out;
- }
-
- ret = proc->fn (NULL, this, dict);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING,
- "Failed to send mgmt_v3 lock "
- "request for operation "
- "'Volume %s' to peer %s",
- gd_op_list[opinfo.op],
- peerinfo->hostname);
- dict_unref (dict);
- goto out;
- }
- /* Mark the peer as locked*/
- peerinfo->locked = _gf_true;
- pending_count++;
- }
- }
- }
-
- opinfo.pending_count = pending_count;
- if (!opinfo.pending_count)
- ret = glusterd_op_sm_inject_all_acc (&event->txn_id);
-
-out:
- if (ret)
- ret = glusterd_op_sm_locking_failed (&event->txn_id);
-
- gf_log (this->name, GF_LOG_DEBUG, "Returning with %d", ret);
- return ret;
-}
-
-static int
-glusterd_op_ac_send_unlock (glusterd_op_sm_event_t *event, void *ctx)
-{
- int ret = 0;
- rpc_clnt_procedure_t *proc = NULL;
- glusterd_conf_t *priv = NULL;
- xlator_t *this = NULL;
- glusterd_peerinfo_t *peerinfo = NULL;
- uint32_t pending_count = 0;
- dict_t *dict = NULL;
-
- this = THIS;
- priv = this->private;
- GF_ASSERT (priv);
-
- list_for_each_local_xaction_peers (peerinfo,
- opinfo.local_xaction_peers) {
- GF_ASSERT (peerinfo);
-
- if (!peerinfo->connected || !peerinfo->mgmt ||
- !peerinfo->locked)
- continue;
- if ((peerinfo->state.state != GD_FRIEND_STATE_BEFRIENDED) &&
- (glusterd_op_get_op() != GD_OP_SYNC_VOLUME))
- continue;
- /* Based on the op_version,
- * release the cluster or mgmt_v3 lock */
- if (priv->op_version < GD_OP_VERSION_3_6_0) {
- proc = &peerinfo->mgmt->proctable
- [GLUSTERD_MGMT_CLUSTER_UNLOCK];
- if (proc->fn) {
- ret = proc->fn (NULL, this, peerinfo);
- if (ret) {
- opinfo.op_errstr = gf_strdup
- ("Unlocking failed for one of "
- "the peer.");
- gf_msg (this->name, GF_LOG_ERROR, 0,
- GD_MSG_CLUSTER_UNLOCK_FAILED,
- "Unlocking failed for operation"
- " volume %s on peer %s",
- gd_op_list[opinfo.op],
- peerinfo->hostname);
- continue;
- }
- pending_count++;
- peerinfo->locked = _gf_false;
- }
- } else {
- dict = glusterd_op_get_ctx ();
- dict_ref (dict);
-
- proc = &peerinfo->mgmt_v3->proctable
- [GLUSTERD_MGMT_V3_UNLOCK];
- if (proc->fn) {
- ret = dict_set_static_ptr (dict, "peerinfo",
- peerinfo);
- if (ret) {
- opinfo.op_errstr = gf_strdup
- ("Unlocking failed for one of the "
- "peer.");
- gf_msg (this->name, GF_LOG_ERROR, 0,
- GD_MSG_CLUSTER_UNLOCK_FAILED,
- "Unlocking failed for operation"
- " volume %s on peer %s",
- gd_op_list[opinfo.op],
- peerinfo->hostname);
- dict_unref (dict);
- continue;
- }
-
- ret = proc->fn (NULL, this, dict);
- if (ret) {
- opinfo.op_errstr = gf_strdup
- ("Unlocking failed for one of the "
- "peer.");
- gf_msg (this->name, GF_LOG_ERROR, 0,
- GD_MSG_CLUSTER_UNLOCK_FAILED,
- "Unlocking failed for operation"
- " volume %s on peer %s",
- gd_op_list[opinfo.op],
- peerinfo->hostname);
- dict_unref (dict);
- continue;
- }
- pending_count++;
- peerinfo->locked = _gf_false;
- }
- }
- }
-
- opinfo.pending_count = pending_count;
- if (!opinfo.pending_count)
- ret = glusterd_op_sm_inject_all_acc (&event->txn_id);
-
- gf_log (this->name, GF_LOG_DEBUG, "Returning with %d", ret);
- return ret;
-}
-
-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,
- &event->txn_id, NULL);
-
- gf_log (THIS->name, 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)
-{
- int32_t ret = 0;
- char *volname = NULL;
- glusterd_op_lock_ctx_t *lock_ctx = NULL;
- glusterd_conf_t *priv = NULL;
- xlator_t *this = NULL;
-
- GF_ASSERT (event);
- GF_ASSERT (ctx);
-
- this = THIS;
- priv = this->private;
-
- lock_ctx = (glusterd_op_lock_ctx_t *)ctx;
-
- /* If the req came from a node running on older op_version
- * the dict won't be present. Based on it acquiring a cluster
- * or mgmt_v3 lock */
- if (lock_ctx->dict == NULL) {
- ret = glusterd_lock (lock_ctx->uuid);
- glusterd_op_lock_send_resp (lock_ctx->req, ret);
- } else {
- ret = dict_get_str (lock_ctx->dict, "volname", &volname);
- if (ret)
- gf_log (this->name, GF_LOG_ERROR,
- "Unable to acquire volname");
- else {
- ret = glusterd_mgmt_v3_lock (volname, lock_ctx->uuid,
- "vol");
- if (ret)
- gf_log (this->name, GF_LOG_ERROR,
- "Unable to acquire lock for %s",
- volname);
- }
-
- glusterd_op_mgmt_v3_lock_send_resp (lock_ctx->req,
- &event->txn_id, ret);
-
- dict_unref (lock_ctx->dict);
- }
-
- gf_log (THIS->name, GF_LOG_DEBUG, "Lock Returned %d", ret);
- return ret;
-}
-
-static int
-glusterd_op_ac_unlock (glusterd_op_sm_event_t *event, void *ctx)
-{
- int32_t ret = 0;
- char *volname = NULL;
- glusterd_op_lock_ctx_t *lock_ctx = NULL;
- glusterd_conf_t *priv = NULL;
- xlator_t *this = NULL;
-
-
- GF_ASSERT (event);
- GF_ASSERT (ctx);
-
- this = THIS;
- priv = this->private;
-
- lock_ctx = (glusterd_op_lock_ctx_t *)ctx;
-
- /* If the req came from a node running on older op_version
- * the dict won't be present. Based on it releasing the cluster
- * or mgmt_v3 lock */
- if (lock_ctx->dict == NULL) {
- ret = glusterd_unlock (lock_ctx->uuid);
- glusterd_op_unlock_send_resp (lock_ctx->req, ret);
- } else {
- ret = dict_get_str (lock_ctx->dict, "volname", &volname);
- if (ret)
- gf_log (this->name, GF_LOG_ERROR,
- "Unable to acquire volname");
- else {
- ret = glusterd_mgmt_v3_unlock (volname, lock_ctx->uuid,
- "vol");
- if (ret)
- gf_log (this->name, GF_LOG_ERROR,
- "Unable to release lock for %s",
- volname);
- }
-
- glusterd_op_mgmt_v3_unlock_send_resp (lock_ctx->req,
- &event->txn_id, ret);
-
- dict_unref (lock_ctx->dict);
- }
-
- gf_log (this->name, GF_LOG_DEBUG, "Unlock Returned %d", ret);
-
- if (priv->pending_quorum_action)
- glusterd_do_quorum_action ();
- 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);
-
- gf_log (THIS->name, GF_LOG_DEBUG, "Unlock Returned %d", ret);
-
- return ret;
-}
-
-static int
-glusterd_op_ac_rcvd_lock_acc (glusterd_op_sm_event_t *event, void *ctx)
-{
- int ret = 0;
-
- GF_ASSERT (event);
-
- if (opinfo.pending_count > 0)
- opinfo.pending_count--;
-
- if (opinfo.pending_count > 0)
- goto out;
-
- ret = glusterd_op_sm_inject_event (GD_OP_EVENT_ALL_ACC,
- &event->txn_id, NULL);
-
- gf_log (THIS->name, GF_LOG_DEBUG, "Returning %d", ret);
-
-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,};
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
-
- if (!dict || !volname)
- goto out;
-
- ret = glusterd_volinfo_find (volname, &volinfo);
- if (ret) {
- snprintf (msg, sizeof (msg), FMTSTR_CHECK_VOL_EXISTS, volname);
- 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) {
- snprintf (msg, sizeof (msg), "Failed to set volume id of volume"
- " %s", volname);
- goto out;
- }
-out:
- if (msg[0] != '\0') {
- gf_log (this->name, GF_LOG_ERROR, "%s", msg);
- *op_errstr = gf_strdup (msg);
- }
- return ret;
-}
-
-int
-glusterd_op_build_payload (dict_t **req, char **op_errstr, dict_t *op_ctx)
-{
- int ret = -1;
- void *ctx = NULL;
- dict_t *dict = 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;
- xlator_t *this = NULL;
-
- GF_ASSERT (req);
-
- this = THIS;
- GF_ASSERT (this);
-
- req_dict = dict_new ();
- if (!req_dict)
- goto out;
-
- if (!op_ctx) {
- op = glusterd_op_get_op ();
- ctx = (void*)glusterd_op_get_ctx ();
- if (!ctx) {
- gf_log (this->name, GF_LOG_ERROR, "Null Context for "
- "op %d", op);
- ret = -1;
- goto out;
- }
-
- } else {
-#define GD_SYNC_OPCODE_KEY "sync-mgmt-operation"
- ret = dict_get_int32 (op_ctx, GD_SYNC_OPCODE_KEY, (int32_t*)&op);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to get volume"
- " operation");
- goto out;
- }
- ctx = op_ctx;
-#undef GD_SYNC_OPCODE_KEY
- }
-
- dict = ctx;
- switch (op) {
- case GD_OP_CREATE_VOLUME:
- {
- ++glusterfs_port;
- ret = dict_set_int32 (dict, "port",
- glusterfs_port);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to set port in "
- "dictionary");
- goto out;
- }
- dict_copy (dict, req_dict);
- }
- break;
-
- case GD_OP_GSYNC_CREATE:
- case GD_OP_GSYNC_SET:
- {
- ret = glusterd_op_gsync_args_get (dict,
- &errstr,
- &volname,
- NULL, 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:
- {
- 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;
- }
- if (strcmp (volname, "help") &&
- strcmp (volname, "help-xml") &&
- strcasecmp (volname, "all")) {
- ret = glusterd_dict_set_volid
- (dict, volname, op_errstr);
- if (ret)
- goto out;
- }
- dict_destroy (req_dict);
- req_dict = dict_ref (dict);
- }
- break;
-
- case GD_OP_SYNC_VOLUME:
- {
- dict_copy (dict, req_dict);
- break;
- }
-
- case GD_OP_REMOVE_BRICK:
- {
- 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_destroy (req_dict);
- req_dict = dict_ref (dict);
- }
- break;
-
- case GD_OP_STATUS_VOLUME:
- {
- 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;
- }
- }
- /*fall-through*/
- 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_RESET_VOLUME:
- case GD_OP_LOG_ROTATE:
- case GD_OP_QUOTA:
- 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:
- case GD_OP_BARRIER:
- {
- 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;
- }
-
- if (strcasecmp (volname, "all")) {
- ret = glusterd_dict_set_volid (dict,
- volname,
- op_errstr);
- if (ret)
- goto out;
- }
- dict_copy (dict, req_dict);
- }
- break;
-
- case GD_OP_COPY_FILE:
- {
- dict_copy (dict, req_dict);
- break;
- }
-
- case GD_OP_SYS_EXEC:
- {
- dict_copy (dict, req_dict);
- break;
- }
-
- default:
- break;
- }
-
- *req = req_dict;
- ret = 0;
-
-out:
- return ret;
-}
-
-gf_boolean_t
-glusterd_is_get_op (xlator_t *this, glusterd_op_t op, dict_t *dict)
-{
- char *key = NULL;
- char *volname = NULL;
- int ret = 0;
-
- if (op == GD_OP_STATUS_VOLUME)
- return _gf_true;
-
- if (op == GD_OP_SET_VOLUME) {
- //check for set volume help
- ret = dict_get_str (dict, "volname", &volname);
- if (volname &&
- ((strcmp (volname, "help") == 0) ||
- (strcmp (volname, "help-xml") == 0))) {
- ret = dict_get_str (dict, "key1", &key);
- if (ret < 0)
- return _gf_true;
- }
- }
-
- return _gf_false;
-}
-
-gf_boolean_t
-glusterd_is_op_quorum_validation_required (xlator_t *this, glusterd_op_t op,
- dict_t *dict)
-{
- gf_boolean_t required = _gf_true;
- char *key = NULL;
- char *key_fixed = NULL;
- int ret = -1;
-
- if (glusterd_is_get_op (this, op, dict)) {
- required = _gf_false;
- goto out;
- }
- if ((op != GD_OP_SET_VOLUME) && (op != GD_OP_RESET_VOLUME))
- goto out;
- if (op == GD_OP_SET_VOLUME)
- ret = dict_get_str (dict, "key1", &key);
- else if (op == GD_OP_RESET_VOLUME)
- ret = dict_get_str (dict, "key", &key);
- if (ret)
- goto out;
- ret = glusterd_check_option_exists (key, &key_fixed);
- if (ret <= 0)
- goto out;
- if (key_fixed)
- key = key_fixed;
- if (glusterd_is_quorum_option (key))
- required = _gf_false;
-out:
- GF_FREE (key_fixed);
- return required;
-}
-
-/* This function shouldn't be used when the quorum validation needs to happen
- * on the non-global peer list */
-static int
-glusterd_op_validate_quorum (xlator_t *this, glusterd_op_t op,
- dict_t *dict, char **op_errstr)
-{
- int ret = 0;
- char *volname = NULL;
- glusterd_volinfo_t *volinfo = NULL;
- char *errstr = NULL;
-
- errstr = "Quorum not met. Volume operation not allowed.";
- if (!glusterd_is_op_quorum_validation_required (this, op, dict))
- goto out;
-
- ret = dict_get_str (dict, "volname", &volname);
- if (ret) {
- ret = 0;
- goto out;
- }
-
- ret = glusterd_volinfo_find (volname, &volinfo);
- if (ret) {
- ret = 0;
- goto out;
- }
-
- /* Passing NULL implies quorum calculation will happen on global peer
- * list */
- if (does_gd_meet_server_quorum (this, NULL,
- _gf_false)) {
- ret = 0;
- goto out;
- }
-
- if (glusterd_is_volume_in_server_quorum (volinfo)) {
- ret = -1;
- *op_errstr = gf_strdup (errstr);
- goto out;
- }
- ret = 0;
-out:
- return ret;
-}
-
-static int
-glusterd_op_ac_send_stage_op (glusterd_op_sm_event_t *event, void *ctx)
-{
- int ret = 0;
- rpc_clnt_procedure_t *proc = NULL;
- glusterd_conf_t *priv = NULL;
- xlator_t *this = NULL;
- glusterd_peerinfo_t *peerinfo = NULL;
- dict_t *dict = NULL;
- dict_t *rsp_dict = NULL;
- char *op_errstr = NULL;
- glusterd_op_t op = GD_OP_NONE;
- uint32_t pending_count = 0;
-
- this = THIS;
- GF_ASSERT (this);
- priv = this->private;
- GF_ASSERT (priv);
-
- op = glusterd_op_get_op ();
-
- rsp_dict = dict_new();
- if (!rsp_dict) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to create rsp_dict");
- ret = -1;
- goto out;
- }
-
- ret = glusterd_op_build_payload (&dict, &op_errstr, NULL);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, LOGSTR_BUILD_PAYLOAD,
- gd_op_list[op]);
- if (op_errstr == NULL)
- gf_asprintf (&op_errstr, OPERRSTR_BUILD_PAYLOAD);
- opinfo.op_errstr = op_errstr;
- goto out;
- }
-
- ret = glusterd_op_validate_quorum (this, op, dict, &op_errstr);
- if (ret) {
- gf_msg (this->name, GF_LOG_CRITICAL, 0,
- GD_MSG_SERVER_QUORUM_NOT_MET,
- "Server quorum not met. Rejecting operation.");
- opinfo.op_errstr = op_errstr;
- goto out;
- }
-
- ret = glusterd_op_stage_validate (op, dict, &op_errstr, rsp_dict);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, LOGSTR_STAGE_FAIL,
- gd_op_list[op], "localhost",
- (op_errstr) ? ":" : " ", (op_errstr) ? op_errstr : " ");
- if (op_errstr == NULL)
- gf_asprintf (&op_errstr, OPERRSTR_STAGE_FAIL,
- "localhost");
- opinfo.op_errstr = op_errstr;
- goto out;
- }
-
- if (op == GD_OP_REPLACE_BRICK)
- glusterd_rb_use_rsp_dict (NULL, rsp_dict);
-
- list_for_each_local_xaction_peers (peerinfo,
- opinfo.local_xaction_peers) {
- GF_ASSERT (peerinfo);
-
- if (!peerinfo->connected || !peerinfo->mgmt)
- continue;
- if ((peerinfo->state.state != GD_FRIEND_STATE_BEFRIENDED) &&
- (glusterd_op_get_op() != GD_OP_SYNC_VOLUME))
- continue;
-
- proc = &peerinfo->mgmt->proctable[GLUSTERD_MGMT_STAGE_OP];
- GF_ASSERT (proc);
- if (proc->fn) {
- ret = dict_set_static_ptr (dict, "peerinfo", peerinfo);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "failed to "
- "set peerinfo");
- goto out;
- }
-
- ret = proc->fn (NULL, this, dict);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING, "Failed to "
- "send stage request for operation "
- "'Volume %s' to peer %s",
- gd_op_list[op], peerinfo->hostname);
- continue;
- }
- pending_count++;
- }
- }
-
- opinfo.pending_count = pending_count;
-out:
- if (rsp_dict)
- dict_unref (rsp_dict);
-
- if (dict)
- dict_unref (dict);
- if (ret) {
- glusterd_op_sm_inject_event (GD_OP_EVENT_RCVD_RJT,
- &event->txn_id, NULL);
- opinfo.op_ret = ret;
- }
-
- gf_log (this->name, GF_LOG_DEBUG, "Sent stage op request for "
- "'Volume %s' to %d peers", gd_op_list[op],
- opinfo.pending_count);
-
- if (!opinfo.pending_count)
- ret = glusterd_op_sm_inject_all_acc (&event->txn_id);
-
- gf_log (this->name, GF_LOG_DEBUG, "Returning with %d", ret);
-
- return ret;
-
-}
-
-static int32_t
-glusterd_op_start_rb_timer (dict_t *dict, uuid_t *txn_id)
-{
- int32_t op = 0;
- struct timespec timeout = {0, };
- glusterd_conf_t *priv = NULL;
- int32_t ret = -1;
- dict_t *rb_ctx = NULL;
- uuid_t *rb_txn_id = NULL;
-
- GF_ASSERT (dict);
- priv = THIS->private;
-
- ret = dict_get_int32 (dict, "operation", &op);
- if (ret) {
- gf_log ("", GF_LOG_DEBUG,
- "dict_get on operation failed");
- goto out;
- }
-
- if (op != GF_REPLACE_OP_START) {
- ret = glusterd_op_sm_inject_all_acc (txn_id);
- goto out;
- }
-
- rb_txn_id = GF_CALLOC (1, sizeof(uuid_t), gf_common_mt_uuid_t);
- if (!rb_txn_id)
- goto out;
-
- uuid_copy (*rb_txn_id, *txn_id);
- timeout.tv_sec = 5;
- timeout.tv_nsec = 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;
- }
-
- ret = dict_set_bin (rb_ctx, "transaction_id",
- rb_txn_id, sizeof (*rb_txn_id));
- if (ret) {
- gf_log ("", GF_LOG_ERROR,
- "Failed to set transaction id.");
- goto out;
- } else
- gf_log ("", GF_LOG_DEBUG,
- "transaction_id = %s", uuid_utoa (*rb_txn_id));
-
- priv->timer = gf_timer_call_after (THIS->ctx, timeout,
- glusterd_do_replace_brick,
- (void *) rb_ctx);
-
- ret = 0;
-
-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;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
-
- 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 %s to dict",
- hostname);
- GF_FREE (hostname);
- goto out;
- }
- }
- }
-
-out:
- gf_log (this->name, GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-
-static int
-reassign_defrag_status (dict_t *dict, char *key, gf_defrag_status_t *status)
-{
- int ret = 0;
-
- if (!*status)
- return ret;
-
- switch (*status) {
- case GF_DEFRAG_STATUS_STARTED:
- *status = GF_DEFRAG_STATUS_LAYOUT_FIX_STARTED;
- break;
-
- case GF_DEFRAG_STATUS_STOPPED:
- *status = GF_DEFRAG_STATUS_LAYOUT_FIX_STOPPED;
- break;
-
- case GF_DEFRAG_STATUS_COMPLETE:
- *status = GF_DEFRAG_STATUS_LAYOUT_FIX_COMPLETE;
- break;
-
- case GF_DEFRAG_STATUS_FAILED:
- *status = GF_DEFRAG_STATUS_LAYOUT_FIX_FAILED;
- break;
- default:
- break;
- }
-
- ret = dict_set_int32(dict, key, *status);
- if (ret)
- gf_log (THIS->name, GF_LOG_WARNING,
- "failed to reset defrag %s in dict", key);
-
- return ret;
-}
-
-/* Check and reassign the defrag_status enum got from the rebalance process
- * of all peers so that the rebalance-status CLI command can display if a
- * full-rebalance or just a fix-layout was carried out.
- */
-static int
-glusterd_op_check_peer_defrag_status (dict_t *dict, int count)
-{
- glusterd_volinfo_t *volinfo = NULL;
- gf_defrag_status_t status = GF_DEFRAG_STATUS_NOT_STARTED;
- char key[256] = {0,};
- char *volname = NULL;
- int ret = -1;
- int i = 1;
-
- ret = dict_get_str (dict, "volname", &volname);
- if (ret) {
- gf_log (THIS->name, GF_LOG_WARNING, "Unable to get volume name");
- goto out;
- }
-
- ret = glusterd_volinfo_find (volname, &volinfo);
- if (ret) {
- gf_log (THIS->name, GF_LOG_WARNING, FMTSTR_CHECK_VOL_EXISTS,
- volname);
- goto out;
- }
-
- if (volinfo->rebal.defrag_cmd != GF_DEFRAG_CMD_START_LAYOUT_FIX) {
- /* Fix layout was not issued; we don't need to reassign
- the status */
- ret = 0;
- goto out;
- }
-
- do {
- memset (key, 0, 256);
- snprintf (key, 256, "status-%d", i);
- ret = dict_get_int32 (dict, key, (int32_t *)&status);
- if (ret) {
- gf_log (THIS->name, GF_LOG_WARNING,
- "failed to get defrag %s", key);
- goto out;
- }
- ret = reassign_defrag_status (dict, key, &status);
- if (ret)
- goto out;
- i++;
- } while (i <= count);
-
- ret = 0;
-out:
- 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, void *ctx)
-{
- 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;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
-
- if (ctx)
- op_ctx = ctx;
- else
- 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_DEBUG,
- "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;
-
- /* add 'brick%d.peerid' into op_ctx with value of 'brick%d.path'.
- nfs/sshd like services have this additional uuid */
- {
- char key[1024];
- char *uuid_str = NULL;
- char *uuid = NULL;
- int i;
-
- for (i = brick_index_max + 1; i < count; i++) {
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "brick%d.path", i);
- ret = dict_get_str (op_ctx, key, &uuid_str);
- if (!ret) {
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key),
- "brick%d.peerid", i);
- uuid = gf_strdup (uuid_str);
- if (!uuid) {
- gf_log (this->name, GF_LOG_DEBUG,
- "unable to create dup of"
- " uuid_str");
- continue;
- }
- ret = dict_set_dynstr (op_ctx, key,
- uuid);
- if (ret != 0) {
- GF_FREE (uuid);
- }
- }
- }
- }
-
- 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;
- }
-
- /* add 'node-name-%d' into op_ctx with value uuid_str.
- this will be used to convert to hostname later */
- {
- char key[1024];
- char *uuid_str = NULL;
- char *uuid = NULL;
- int i;
-
- for (i = 1; i <= count; i++) {
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "node-uuid-%d", i);
- ret = dict_get_str (op_ctx, key, &uuid_str);
- if (!ret) {
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key),
- "node-name-%d", i);
- uuid = gf_strdup (uuid_str);
- if (!uuid) {
- gf_log (this->name, GF_LOG_DEBUG,
- "unable to create dup of"
- " uuid_str");
- continue;
- }
- ret = dict_set_dynstr (op_ctx, key,
- uuid);
- if (ret != 0) {
- GF_FREE (uuid);
- }
- }
- }
- }
-
- ret = glusterd_op_volume_dict_uuid_to_hostname (op_ctx,
- "node-name-%d",
- 1, (count + 1));
- if (ret)
- gf_log (this->name, GF_LOG_WARNING,
- "Failed uuid to hostname conversion");
-
- ret = glusterd_op_check_peer_defrag_status (op_ctx, count);
- if (ret)
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to reset defrag status for fix-layout");
- break;
-
- default:
- ret = 0;
- gf_log (this->name, GF_LOG_DEBUG,
- "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)
-{
- int ret = 0;
- rpc_clnt_procedure_t *proc = NULL;
- glusterd_conf_t *priv = NULL;
- xlator_t *this = NULL;
- dict_t *dict = NULL;
- 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;
-
- this = THIS;
- GF_ASSERT (this);
- priv = this->private;
- GF_ASSERT (priv);
-
- op = glusterd_op_get_op ();
- op_dict = glusterd_op_get_ctx ();
-
- ret = glusterd_op_build_payload (&dict, &op_errstr, NULL);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, LOGSTR_BUILD_PAYLOAD,
- gd_op_list[op]);
- if (op_errstr == NULL)
- gf_asprintf (&op_errstr, OPERRSTR_BUILD_PAYLOAD);
- opinfo.op_errstr = op_errstr;
- goto out;
- }
-
- ret = glusterd_op_commit_perform (op, dict, &op_errstr, NULL); //rsp_dict invalid for source
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, LOGSTR_COMMIT_FAIL,
- gd_op_list[op], "localhost", (op_errstr) ? ":" : " ",
- (op_errstr) ? op_errstr : " ");
- if (op_errstr == NULL)
- gf_asprintf (&op_errstr, OPERRSTR_COMMIT_FAIL,
- "localhost");
- opinfo.op_errstr = op_errstr;
- goto out;
- }
-
- list_for_each_local_xaction_peers (peerinfo,
- opinfo.local_xaction_peers) {
- GF_ASSERT (peerinfo);
-
- if (!peerinfo->connected || !peerinfo->mgmt)
- continue;
- if ((peerinfo->state.state != GD_FRIEND_STATE_BEFRIENDED) &&
- (glusterd_op_get_op() != GD_OP_SYNC_VOLUME))
- continue;
-
- proc = &peerinfo->mgmt->proctable[GLUSTERD_MGMT_COMMIT_OP];
- GF_ASSERT (proc);
- if (proc->fn) {
- ret = dict_set_static_ptr (dict, "peerinfo", peerinfo);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "failed to set peerinfo");
- goto out;
- }
- ret = proc->fn (NULL, this, dict);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING, "Failed to "
- "send commit request for operation "
- "'Volume %s' to peer %s",
- gd_op_list[op], peerinfo->hostname);
- continue;
- }
- pending_count++;
- }
- }
-
- opinfo.pending_count = pending_count;
- gf_log (this->name, GF_LOG_DEBUG, "Sent commit op req for 'Volume %s' "
- "to %d peers", gd_op_list[op], opinfo.pending_count);
-out:
- if (dict)
- dict_unref (dict);
- if (ret) {
- glusterd_op_sm_inject_event (GD_OP_EVENT_RCVD_RJT,
- &event->txn_id, NULL);
- opinfo.op_ret = ret;
- }
-
- if (!opinfo.pending_count) {
- if (op == GD_OP_REPLACE_BRICK) {
- ret = glusterd_op_start_rb_timer (op_dict,
- &event->txn_id);
-
- } else {
- glusterd_op_modify_op_ctx (op, NULL);
- ret = glusterd_op_sm_inject_all_acc (&event->txn_id);
- }
- goto err;
- }
-
-err:
- gf_log (this->name, GF_LOG_DEBUG, "Returning with %d", ret);
-
- return ret;
-
-}
-
-static int
-glusterd_op_ac_rcvd_stage_op_acc (glusterd_op_sm_event_t *event, void *ctx)
-{
- int ret = 0;
-
- GF_ASSERT (event);
-
- if (opinfo.pending_count > 0)
- opinfo.pending_count--;
-
- if (opinfo.pending_count > 0)
- goto out;
-
- ret = glusterd_op_sm_inject_event (GD_OP_EVENT_STAGE_ACC,
- &event->txn_id, NULL);
-
-out:
- gf_log (THIS->name, GF_LOG_DEBUG, "Returning %d", ret);
-
- return ret;
-}
-
-static int
-glusterd_op_ac_stage_op_failed (glusterd_op_sm_event_t *event, void *ctx)
-{
- int ret = 0;
-
- GF_ASSERT (event);
-
- if (opinfo.pending_count > 0)
- opinfo.pending_count--;
-
- if (opinfo.pending_count > 0)
- goto out;
-
- ret = glusterd_op_sm_inject_event (GD_OP_EVENT_ALL_ACK,
- &event->txn_id, NULL);
-
-out:
- gf_log (THIS->name, GF_LOG_DEBUG, "Returning %d", ret);
-
- return ret;
-}
-
-static int
-glusterd_op_ac_commit_op_failed (glusterd_op_sm_event_t *event, void *ctx)
-{
- int ret = 0;
-
- GF_ASSERT (event);
-
- if (opinfo.pending_count > 0)
- opinfo.pending_count--;
-
- if (opinfo.pending_count > 0)
- goto out;
-
- ret = glusterd_op_sm_inject_event (GD_OP_EVENT_ALL_ACK,
- &event->txn_id, NULL);
-
-out:
- gf_log (THIS->name, GF_LOG_DEBUG, "Returning %d", ret);
-
- return ret;
-}
-
-static int
-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;
- gf_boolean_t free_errstr = _gf_false;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
-
- GF_ASSERT (event);
- GF_ASSERT (ctx);
- ev_ctx = ctx;
-
- ret = glusterd_remove_pending_entry (&opinfo.pending_bricks, ev_ctx->pending_node->node);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "unknown response received ");
- ret = -1;
- free_errstr = _gf_true;
- goto out;
- }
- if (opinfo.brick_pending_count > 0)
- opinfo.brick_pending_count--;
- if (opinfo.op_ret == 0)
- opinfo.op_ret = ev_ctx->op_ret;
-
- if (opinfo.op_errstr == NULL)
- opinfo.op_errstr = ev_ctx->op_errstr;
- else
- free_errstr = _gf_true;
-
- if (opinfo.brick_pending_count > 0)
- goto out;
-
- ret = glusterd_op_sm_inject_event (GD_OP_EVENT_ALL_ACK,
- &event->txn_id, ev_ctx->commit_ctx);
-
-out:
- if (ev_ctx->rsp_dict)
- dict_unref (ev_ctx->rsp_dict);
- if (free_errstr && ev_ctx->op_errstr)
- GF_FREE (ev_ctx->op_errstr);
- GF_FREE (ctx);
- gf_log (this->name, GF_LOG_DEBUG, "Returning %d", ret);
-
- return ret;
-}
-
-static int
-glusterd_op_ac_rcvd_commit_op_acc (glusterd_op_sm_event_t *event, void *ctx)
-{
- dict_t *op_ctx = NULL;
- int ret = 0;
- gf_boolean_t commit_ack_inject = _gf_true;
- glusterd_op_t op = GD_OP_NONE;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- op = glusterd_op_get_op ();
- GF_ASSERT (event);
-
- if (opinfo.pending_count > 0)
- opinfo.pending_count--;
-
- if (opinfo.pending_count > 0)
- 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 = -1;
- goto out;
- }
-
- ret = glusterd_op_start_rb_timer (op_ctx, &event->txn_id);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Couldn't start "
- "replace-brick operation.");
- goto out;
- }
-
- commit_ack_inject = _gf_false;
- goto out;
- }
-
-
-out:
- if (commit_ack_inject) {
- if (ret)
- ret = glusterd_op_sm_inject_event (GD_OP_EVENT_RCVD_RJT,
- &event->txn_id,
- NULL);
- else if (!opinfo.pending_count) {
- glusterd_op_modify_op_ctx (op, NULL);
- ret = glusterd_op_sm_inject_event
- (GD_OP_EVENT_COMMIT_ACC,
- &event->txn_id, NULL);
- }
- /*else do nothing*/
- }
-
- return ret;
-}
-
-static int
-glusterd_op_ac_rcvd_unlock_acc (glusterd_op_sm_event_t *event, void *ctx)
-{
- int ret = 0;
-
- GF_ASSERT (event);
-
- if (opinfo.pending_count > 0)
- opinfo.pending_count--;
-
- if (opinfo.pending_count > 0)
- goto out;
-
- ret = glusterd_op_sm_inject_event (GD_OP_EVENT_ALL_ACC,
- &event->txn_id, NULL);
-
- gf_log (THIS->name, GF_LOG_DEBUG, "Returning %d", ret);
-
-out:
- return ret;
-}
-
-int32_t
-glusterd_op_clear_errstr() {
- opinfo.op_errstr = NULL;
- return 0;
-}
-
-int32_t
-glusterd_op_set_ctx (void *ctx)
-{
-
- opinfo.op_ctx = ctx;
-
- return 0;
-
-}
-
-int32_t
-glusterd_op_reset_ctx ()
-{
-
- glusterd_op_set_ctx (NULL);
-
- return 0;
-}
-
-int32_t
-glusterd_op_txn_complete (uuid_t *txn_id)
-{
- int32_t ret = -1;
- glusterd_conf_t *priv = NULL;
- int32_t op = -1;
- int32_t op_ret = 0;
- int32_t op_errno = 0;
- rpcsvc_request_t *req = NULL;
- void *ctx = NULL;
- char *op_errstr = NULL;
- char *volname = NULL;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
-
- priv = this->private;
- GF_ASSERT (priv);
-
- op = glusterd_op_get_op ();
- ctx = glusterd_op_get_ctx ();
- op_ret = opinfo.op_ret;
- op_errno = opinfo.op_errno;
- 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 ();
- gd_cleanup_local_xaction_peers_list (opinfo.local_xaction_peers);
-
- /* Based on the op-version, we release the cluster or mgmt_v3 lock */
- if (priv->op_version < GD_OP_VERSION_3_6_0) {
- ret = glusterd_unlock (MY_UUID);
- /* unlock cant/shouldnt fail here!! */
- if (ret)
- gf_log (this->name, GF_LOG_CRITICAL,
- "Unable to clear local lock, ret: %d", ret);
- else
- gf_log (this->name, GF_LOG_DEBUG, "Cleared local lock");
- } else {
- ret = dict_get_str (ctx, "volname", &volname);
- if (ret)
- gf_log ("", GF_LOG_INFO,
- "No Volume name present. "
- "Locks have not been held.");
-
- if (volname) {
- ret = glusterd_mgmt_v3_unlock (volname, MY_UUID,
- "vol");
- if (ret)
- gf_log (this->name, GF_LOG_ERROR,
- "Unable to release lock for %s",
- volname);
- }
- }
-
- ret = glusterd_op_send_cli_response (op, op_ret,
- op_errno, req, ctx, op_errstr);
-
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Responding to cli failed, "
- "ret: %d", ret);
- //Ignore this error, else state machine blocks
- ret = 0;
- }
-
- if (op_errstr && (strcmp (op_errstr, "")))
- GF_FREE (op_errstr);
-
-
- if (priv->pending_quorum_action)
- glusterd_do_quorum_action ();
-
- /* Clearing the transaction opinfo */
- ret = glusterd_clear_txn_opinfo (txn_id);
- if (ret)
- gf_log (this->name, GF_LOG_ERROR,
- "Unable to clear transaction's opinfo");
-
- gf_log (this->name, GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-
-static int
-glusterd_op_ac_unlocked_all (glusterd_op_sm_event_t *event, void *ctx)
-{
- int ret = 0;
-
- GF_ASSERT (event);
-
- ret = glusterd_op_txn_complete (&event->txn_id);
-
- gf_log (THIS->name, 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;
- glusterd_req_ctx_t *req_ctx = NULL;
- int32_t status = 0;
- dict_t *rsp_dict = NULL;
- char *op_errstr = NULL;
- dict_t *dict = NULL;
- xlator_t *this = NULL;
- uuid_t *txn_id = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (ctx);
-
- req_ctx = ctx;
-
- dict = req_ctx->dict;
-
- rsp_dict = dict_new ();
- if (!rsp_dict) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to get new dictionary");
- return -1;
- }
-
- status = glusterd_op_stage_validate (req_ctx->op, dict, &op_errstr,
- rsp_dict);
-
- if (status) {
- gf_log (this->name, GF_LOG_ERROR, "Stage failed on operation"
- " 'Volume %s', Status : %d", gd_op_list[req_ctx->op],
- status);
- }
-
- txn_id = GF_CALLOC (1, sizeof(uuid_t), gf_common_mt_uuid_t);
-
- if (txn_id)
- uuid_copy (*txn_id, event->txn_id);
- else {
- ret = -1;
- goto out;
- }
-
- ret = dict_set_bin (rsp_dict, "transaction_id",
- txn_id, sizeof(*txn_id));
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to set transaction id.");
- goto out;
- }
-
- ret = glusterd_op_stage_send_resp (req_ctx->req, req_ctx->op,
- status, op_errstr, rsp_dict);
-
-out:
- if (op_errstr && (strcmp (op_errstr, "")))
- GF_FREE (op_errstr);
-
- gf_log (this->name, GF_LOG_DEBUG, "Returning with %d", ret);
-
- if (rsp_dict)
- dict_unref (rsp_dict);
-
- return ret;
-}
-
-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);
-
- 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;
- default:
- ret = _gf_false;
- }
-
- return ret;
-}
-
-dict_t*
-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);
-
- if (glusterd_need_brick_op (op)) {
- op_ctx = glusterd_op_get_ctx ();
- GF_ASSERT (op_ctx);
- rsp_dict = dict_ref (op_ctx);
- } else {
- rsp_dict = dict_new ();
- }
-
- return rsp_dict;
-}
-
-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;
- int32_t status = 0;
- char *op_errstr = NULL;
- dict_t *dict = NULL;
- dict_t *rsp_dict = NULL;
- xlator_t *this = NULL;
- uuid_t *txn_id = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (ctx);
-
- req_ctx = ctx;
-
- dict = req_ctx->dict;
-
- rsp_dict = glusterd_op_init_commit_rsp_dict (req_ctx->op);
- if (NULL == rsp_dict)
- return -1;
-
-
- 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);
- }
-
- if (status)
- gf_log (this->name, GF_LOG_ERROR, "Commit of operation "
- "'Volume %s' failed: %d", gd_op_list[req_ctx->op],
- status);
-
- txn_id = GF_CALLOC (1, sizeof(uuid_t), gf_common_mt_uuid_t);
-
- if (txn_id)
- uuid_copy (*txn_id, event->txn_id);
- else {
- ret = -1;
- goto out;
- }
-
- ret = dict_set_bin (rsp_dict, "transaction_id",
- txn_id, sizeof(*txn_id));
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to set transaction id.");
- goto out;
- }
-
- ret = glusterd_op_commit_send_resp (req_ctx->req, req_ctx->op,
- status, op_errstr, rsp_dict);
-
-out:
- 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);
-
- return ret;
-}
-
-static int
-glusterd_op_ac_send_commit_failed (glusterd_op_sm_event_t *event, void *ctx)
-{
- int ret = 0;
- glusterd_req_ctx_t *req_ctx = NULL;
- dict_t *op_ctx = NULL;
-
- GF_ASSERT (ctx);
-
- req_ctx = ctx;
-
- op_ctx = glusterd_op_get_ctx ();
-
- ret = glusterd_op_commit_send_resp (req_ctx->req, req_ctx->op,
- opinfo.op_ret, opinfo.op_errstr,
- op_ctx);
-
- if (opinfo.op_errstr && (strcmp (opinfo.op_errstr, ""))) {
- GF_FREE (opinfo.op_errstr);
- opinfo.op_errstr = NULL;
- }
-
- gf_log (THIS->name, GF_LOG_DEBUG, "Returning with %d", ret);
- return ret;
-}
-
-static int
-glusterd_op_sm_transition_state (glusterd_op_info_t *opinfo,
- glusterd_op_sm_t *state,
- glusterd_op_sm_event_type_t event_type)
-{
- glusterd_conf_t *conf = NULL;
-
- GF_ASSERT (state);
- GF_ASSERT (opinfo);
-
- conf = THIS->private;
- GF_ASSERT (conf);
-
- (void) glusterd_sm_tr_log_transition_add (&conf->op_sm_log,
- opinfo->state.state,
- state[event_type].next_state,
- event_type);
-
- opinfo->state.state = state[event_type].next_state;
- return 0;
-}
-
-int32_t
-glusterd_op_stage_validate (glusterd_op_t op, dict_t *dict, char **op_errstr,
- dict_t *rsp_dict)
-{
- int ret = -1;
- xlator_t *this = THIS;
-
- switch (op) {
- case GD_OP_CREATE_VOLUME:
- ret = glusterd_op_stage_create_volume (dict, op_errstr,
- rsp_dict);
- break;
-
- case GD_OP_START_VOLUME:
- ret = glusterd_op_stage_start_volume (dict, op_errstr,
- rsp_dict);
- break;
-
- case GD_OP_STOP_VOLUME:
- ret = glusterd_op_stage_stop_volume (dict, op_errstr);
- break;
-
- case GD_OP_DELETE_VOLUME:
- ret = glusterd_op_stage_delete_volume (dict, op_errstr);
- break;
-
- case GD_OP_ADD_BRICK:
- ret = glusterd_op_stage_add_brick (dict, op_errstr,
- rsp_dict);
- break;
-
- case GD_OP_REPLACE_BRICK:
- ret = glusterd_op_stage_replace_brick (dict, op_errstr,
- rsp_dict);
- break;
-
- case GD_OP_SET_VOLUME:
- ret = glusterd_op_stage_set_volume (dict, op_errstr);
- break;
-
- case GD_OP_RESET_VOLUME:
- ret = glusterd_op_stage_reset_volume (dict, op_errstr);
- break;
-
- case GD_OP_REMOVE_BRICK:
- ret = glusterd_op_stage_remove_brick (dict, op_errstr);
- break;
-
- case GD_OP_LOG_ROTATE:
- ret = glusterd_op_stage_log_rotate (dict, op_errstr);
- break;
-
- case GD_OP_SYNC_VOLUME:
- ret = glusterd_op_stage_sync_volume (dict, op_errstr);
- break;
-
- case GD_OP_GSYNC_CREATE:
- ret = glusterd_op_stage_gsync_create (dict, op_errstr);
- break;
-
- case GD_OP_GSYNC_SET:
- ret = glusterd_op_stage_gsync_set (dict, op_errstr);
- break;
-
- case GD_OP_PROFILE_VOLUME:
- ret = glusterd_op_stage_stats_volume (dict, op_errstr);
- break;
-
- case GD_OP_QUOTA:
- ret = glusterd_op_stage_quota (dict, op_errstr,
- rsp_dict);
- 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;
-
- case GD_OP_COPY_FILE:
- ret = glusterd_op_stage_copy_file (dict, op_errstr);
- break;
-
- case GD_OP_SYS_EXEC:
- ret = glusterd_op_stage_sys_exec (dict, op_errstr);
- break;
-
- case GD_OP_BARRIER:
- ret = glusterd_op_stage_barrier (dict, op_errstr);
- break;
-
- default:
- gf_log (this->name, GF_LOG_ERROR, "Unknown op %s",
- gd_op_list[op]);
- }
-
- gf_log (this->name, GF_LOG_DEBUG, "OP = %d. Returning %d", op, ret);
- return ret;
-}
-
-
-int32_t
-glusterd_op_commit_perform (glusterd_op_t op, dict_t *dict, char **op_errstr,
- dict_t *rsp_dict)
-{
- int ret = -1;
- xlator_t *this = THIS;
-
- glusterd_op_commit_hook (op, dict, GD_COMMIT_HOOK_PRE);
- switch (op) {
- case GD_OP_CREATE_VOLUME:
- ret = glusterd_op_create_volume (dict, op_errstr);
- break;
-
- case GD_OP_START_VOLUME:
- ret = glusterd_op_start_volume (dict, op_errstr);
- break;
-
- case GD_OP_STOP_VOLUME:
- ret = glusterd_op_stop_volume (dict);
- break;
-
- case GD_OP_DELETE_VOLUME:
- ret = glusterd_op_delete_volume (dict);
- break;
-
- case GD_OP_ADD_BRICK:
- ret = glusterd_op_add_brick (dict, op_errstr);
- break;
-
- case GD_OP_REPLACE_BRICK:
- ret = glusterd_op_replace_brick (dict, rsp_dict);
- break;
-
- case GD_OP_SET_VOLUME:
- ret = glusterd_op_set_volume (dict);
- break;
-
- case GD_OP_RESET_VOLUME:
- ret = glusterd_op_reset_volume (dict, op_errstr);
- break;
-
- case GD_OP_REMOVE_BRICK:
- ret = glusterd_op_remove_brick (dict, op_errstr);
- break;
-
- case GD_OP_LOG_ROTATE:
- ret = glusterd_op_log_rotate (dict);
- break;
-
- case GD_OP_SYNC_VOLUME:
- ret = glusterd_op_sync_volume (dict, op_errstr, rsp_dict);
- break;
-
- case GD_OP_GSYNC_CREATE:
- ret = glusterd_op_gsync_create (dict, op_errstr,
- rsp_dict);
- break;
-
- case GD_OP_GSYNC_SET:
- ret = glusterd_op_gsync_set (dict, op_errstr, rsp_dict);
- break;
-
- case GD_OP_PROFILE_VOLUME:
- ret = glusterd_op_stats_volume (dict, op_errstr,
- rsp_dict);
- break;
-
- case GD_OP_QUOTA:
- ret = glusterd_op_quota (dict, op_errstr, rsp_dict);
- 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,
- rsp_dict);
- break;
-
- case GD_OP_COPY_FILE:
- ret = glusterd_op_copy_file (dict, op_errstr);
- break;
-
- case GD_OP_SYS_EXEC:
- ret = glusterd_op_sys_exec (dict, op_errstr, rsp_dict);
- break;
-
- case GD_OP_BARRIER:
- ret = glusterd_op_barrier (dict, op_errstr);
- break;
-
- default:
- gf_log (this->name, GF_LOG_ERROR, "Unknown op %s",
- gd_op_list[op]);
- break;
- }
-
- if (ret == 0)
- glusterd_op_commit_hook (op, dict, GD_COMMIT_HOOK_POST);
-
- gf_log (this->name, GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-
-
-static int
-glusterd_bricks_select_stop_volume (dict_t *dict, char **op_errstr,
- struct list_head *selected)
-{
- int ret = 0;
- int flags = 0;
- char *volname = NULL;
- glusterd_volinfo_t *volinfo = NULL;
- glusterd_brickinfo_t *brickinfo = NULL;
- glusterd_pending_node_t *pending_node = NULL;
-
- ret = glusterd_op_stop_volume_args_get (dict, &volname, &flags);
- if (ret)
- goto out;
-
- ret = glusterd_volinfo_find (volname, &volinfo);
- if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR, FMTSTR_CHECK_VOL_EXISTS,
- volname);
- gf_asprintf (op_errstr, FMTSTR_CHECK_VOL_EXISTS, volname);
- 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),
- gf_gld_mt_pending_node_t);
- if (!pending_node) {
- ret = -1;
- goto out;
- } else {
- pending_node->node = brickinfo;
- pending_node->type = GD_NODE_BRICK;
- list_add_tail (&pending_node->list, selected);
- pending_node = NULL;
- }
- }
- }
-
-out:
- return ret;
-}
-
-static int
-glusterd_bricks_select_remove_brick (dict_t *dict, char **op_errstr,
- struct list_head *selected)
-{
- int ret = -1;
- char *volname = NULL;
- glusterd_volinfo_t *volinfo = NULL;
- glusterd_brickinfo_t *brickinfo = NULL;
- char *brick = NULL;
- int32_t count = 0;
- 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);
-
- 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_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);
- ret = dict_get_str (dict, key, &brick);
- if (ret) {
- gf_log ("glusterd", GF_LOG_ERROR, "Unable to get brick");
- goto out;
- }
-
- ret = glusterd_volume_brickinfo_get_by_brick (brick, volinfo,
- &brickinfo);
- if (ret)
- goto out;
- if (glusterd_is_brick_started (brickinfo)) {
- 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 = brickinfo;
- pending_node->type = GD_NODE_BRICK;
- list_add_tail (&pending_node->list, selected);
- pending_node = NULL;
- }
- }
- i++;
- }
-
-out:
- return ret;
-}
-
-static int
-glusterd_bricks_select_profile_volume (dict_t *dict, char **op_errstr,
- struct list_head *selected)
-{
- int ret = -1;
- char *volname = NULL;
- char msg[2048] = {0,};
- glusterd_conf_t *priv = NULL;
- glusterd_volinfo_t *volinfo = NULL;
- xlator_t *this = NULL;
- int32_t stats_op = GF_CLI_STATS_NONE;
- glusterd_brickinfo_t *brickinfo = NULL;
- glusterd_pending_node_t *pending_node = NULL;
- char *brick = NULL;
-
-
-
- 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 exists",
- volname);
-
- *op_errstr = gf_strdup (msg);
- gf_log ("", GF_LOG_ERROR, "%s", msg);
- goto out;
- }
-
- ret = dict_get_int32 (dict, "op", &stats_op);
- if (ret) {
- gf_log ("glusterd", GF_LOG_ERROR, "volume profile op get failed");
- goto out;
- }
-
- switch (stats_op) {
- case GF_CLI_STATS_START:
- case GF_CLI_STATS_STOP:
- goto out;
- break;
- case GF_CLI_STATS_INFO:
- ret = dict_get_str_boolean (dict, "nfs", _gf_false);
- if (ret) {
- if (!glusterd_is_nodesvc_online ("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, selected);
- 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),
- gf_gld_mt_pending_node_t);
- if (!pending_node) {
- ret = -1;
- goto out;
- } else {
- pending_node->node = brickinfo;
- pending_node->type = GD_NODE_BRICK;
- list_add_tail (&pending_node->list,
- selected);
- pending_node = NULL;
- }
- }
- }
- break;
-
- case GF_CLI_STATS_TOP:
- ret = dict_get_str_boolean (dict, "nfs", _gf_false);
- if (ret) {
- if (!glusterd_is_nodesvc_online ("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, selected);
- 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);
- 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) {
- ret = -1;
- goto out;
- } else {
- pending_node->node = brickinfo;
- pending_node->type = GD_NODE_BRICK;
- list_add_tail (&pending_node->list,
- selected);
- pending_node = NULL;
- goto out;
- }
- }
- ret = 0;
- list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) {
- if (glusterd_is_brick_started (brickinfo)) {
- 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 = brickinfo;
- pending_node->type = GD_NODE_BRICK;
- list_add_tail (&pending_node->list,
- selected);
- pending_node = NULL;
- }
- }
- }
- break;
-
- default:
- GF_ASSERT (0);
- gf_log ("glusterd", GF_LOG_ERROR, "Invalid profile op: %d",
- stats_op);
- ret = -1;
- goto out;
- break;
- }
-
-
-out:
- gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
-
- return ret;
-}
-
-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
-get_replica_index_for_per_replica_cmd (glusterd_volinfo_t *volinfo,
- dict_t *dict) {
- int ret = 0;
- char *hostname = NULL;
- char *path = NULL;
- int index = 0;
- glusterd_brickinfo_t *brickinfo = NULL;
- int cmd_replica_index = -1;
- int replica_count = -1;
-
-
- if (!dict) {
- ret = -1;
- goto out;
- }
-
- ret = dict_get_str (dict, "per-replica-cmd-hostname", &hostname);
- if (ret)
- goto out;
- ret = dict_get_str (dict, "per-replica-cmd-path", &path);
- if (ret)
- goto out;
-
- 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 (!strcmp (brickinfo->path, path) &&
- !strcmp (brickinfo->hostname, hostname)) {
- cmd_replica_index = index/(replica_count);
- goto out;
- }
- index++;
- }
-
-
-out:
- if (ret)
- cmd_replica_index = -1;
-
- return cmd_replica_index;
-}
-
-int
-_select_rxlators_with_local_bricks (xlator_t *this, glusterd_volinfo_t *volinfo,
- dict_t *dict, cli_cmd_type type)
-{
- glusterd_brickinfo_t *brickinfo = NULL;
- glusterd_conf_t *priv = NULL;
- int index = 0;
- int rxlator_count = 0;
- int replica_count = 0;
- gf_boolean_t add = _gf_false;
- int ret = 0;
- int cmd_replica_index = -1;
-
- priv = this->private;
- replica_count = volinfo->replica_count;
-
- if (type == PER_REPLICA) {
-
- cmd_replica_index = get_replica_index_for_per_replica_cmd
- (volinfo, dict);
- if (cmd_replica_index == -1) {
- ret = -1;
- goto err;
- }
- }
-
- index = 1;
-
- list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) {
- if (uuid_is_null (brickinfo->uuid))
- (void)glusterd_resolve_brick (brickinfo);
-
- switch (type) {
- case ALL_REPLICA:
- if (!uuid_compare (MY_UUID, brickinfo->uuid))
- add = _gf_true;
- break;
- case PER_REPLICA:
- if (!uuid_compare (MY_UUID, brickinfo->uuid) &&
- ((index-1)/replica_count == cmd_replica_index))
-
- add = _gf_true;
- break;
- }
-
- 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++;
- }
-err:
- if (ret)
- rxlator_count = -1;
-
- 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_snap (dict_t *dict, char **op_errstr,
- struct list_head *selected)
-{
- int ret = -1;
- glusterd_conf_t *priv = NULL;
- xlator_t *this = NULL;
- glusterd_pending_node_t *pending_node = NULL;
- glusterd_volinfo_t *volinfo = NULL;
- char *volname = NULL;
- glusterd_brickinfo_t *brickinfo = NULL;
- int brick_index = -1;
-
- this = THIS;
- GF_ASSERT (this);
- priv = this->private;
- GF_ASSERT (priv);
-
- 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;
-
- 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;
- goto out;
- }
- pending_node->node = brickinfo;
- pending_node->type = GD_NODE_BRICK;
- pending_node->index = brick_index;
- list_add_tail (&pending_node->list,
- selected);
- pending_node = NULL;
- }
-
- ret = 0;
-
-out:
- gf_log (THIS->name, GF_LOG_DEBUG, "Returning ret %d", ret);
- return ret;
-}
-
-static int
-fill_shd_status_for_local_bricks (dict_t *dict, glusterd_volinfo_t *volinfo,
- cli_cmd_type type, dict_t *req_dict)
-{
- glusterd_brickinfo_t *brickinfo = NULL;
- char msg[1024] = {0,};
- char key[1024] = {0,};
- char value[1024] = {0,};
- int index = 0;
- int ret = 0;
- xlator_t *this = NULL;
- int cmd_replica_index = -1;
-
- this = THIS;
- snprintf (msg, sizeof (msg), "self-heal-daemon is not running on");
-
- if (type == PER_REPLICA) {
- cmd_replica_index = get_replica_index_for_per_replica_cmd
- (volinfo, req_dict);
- if (cmd_replica_index == -1) {
- gf_log (THIS->name, GF_LOG_ERROR, "Could not find the "
- "replica index for per replica type command");
- ret = -1;
- goto out;
- }
- }
-
- 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)) {
- index++;
- continue;
- }
-
- if (type == PER_REPLICA) {
- if (cmd_replica_index != (index/volinfo->replica_count)) {
- index++;
- continue;
- }
-
- }
- snprintf (key, sizeof (key), "%d-status",index);
- snprintf (value, sizeof (value), "%s %s",msg,
- uuid_utoa(MY_UUID));
- ret = dict_set_dynstr (dict, key, gf_strdup(value));
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Unable to"
- "set the dictionary for shd status msg");
- goto out;
- }
- snprintf (key, sizeof (key), "%d-shd-status",index);
- ret = dict_set_str (dict, key, "off");
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Unable to"
- " set dictionary for shd status msg");
- goto out;
- }
-
- index++;
- }
-
-out:
- return ret;
-
-}
-
-
-static int
-glusterd_bricks_select_heal_volume (dict_t *dict, char **op_errstr,
- struct list_head *selected,
- dict_t *rsp_dict)
-{
- 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_INDEX_SUMMARY:
- case GF_AFR_OP_STATISTICS_HEAL_COUNT:
- if (!glusterd_is_nodesvc_online ("glustershd")) {
- if (!rsp_dict) {
- gf_log (this->name, GF_LOG_ERROR, "Received "
- "empty ctx.");
- goto out;
- }
-
- ret = fill_shd_status_for_local_bricks (rsp_dict,
- volinfo,
- ALL_REPLICA,
- dict);
- if (ret)
- gf_log (this->name, GF_LOG_ERROR, "Unable to "
- "fill the shd status for the local "
- "bricks");
- goto out;
-
- }
- break;
- case GF_AFR_OP_STATISTICS_HEAL_COUNT_PER_REPLICA:
- if (!glusterd_is_nodesvc_online ("glustershd")) {
- if (!rsp_dict) {
- gf_log (this->name, GF_LOG_ERROR, "Received "
- "empty ctx.");
- goto out;
- }
- ret = fill_shd_status_for_local_bricks (rsp_dict,
- volinfo,
- PER_REPLICA,
- dict);
- if (ret)
- gf_log (this->name, GF_LOG_ERROR, "Unable to "
- "fill the shd status for the local"
- " bricks.");
- goto out;
-
- }
- break;
- default:
- break;
- }
-
-
- switch (heal_op) {
- case GF_AFR_OP_HEAL_FULL:
- rxlator_count = _select_rxlators_for_full_self_heal (this,
- volinfo,
- dict);
- break;
- case GF_AFR_OP_STATISTICS_HEAL_COUNT_PER_REPLICA:
- rxlator_count = _select_rxlators_with_local_bricks (this,
- volinfo,
- dict,
- PER_REPLICA);
- break;
- default:
- rxlator_count = _select_rxlators_with_local_bricks (this,
- volinfo,
- dict,
- ALL_REPLICA);
- break;
- }
- if (!rxlator_count)
- goto out;
- if (rxlator_count == -1){
- gf_log (this->name, GF_LOG_ERROR, "Could not determine the"
- "translator count");
- ret = -1;
- 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, selected);
- 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,
- struct list_head *selected)
-{
- 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,
- struct list_head *selected)
-{
- 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;
- glusterd_snapd_t *snapd = 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:
- case GF_CLI_STATUS_QUOTAD:
- case GF_CLI_STATUS_SNAPD:
- 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, selected);
-
- ret = 0;
- } else if ((cmd & GF_CLI_STATUS_NFS) != 0) {
- if (!glusterd_is_nodesvc_online ("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, selected);
-
- ret = 0;
- } else if ((cmd & GF_CLI_STATUS_SHD) != 0) {
- if (!glusterd_is_nodesvc_online ("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, selected);
-
- ret = 0;
- } else if ((cmd & GF_CLI_STATUS_QUOTAD) != 0) {
- if (!glusterd_is_nodesvc_online ("quotad")) {
- gf_log (this->name, GF_LOG_ERROR, "Quotad is not "
- "running");
- ret = -1;
- 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->quotad;
- pending_node->type = GD_NODE_QUOTAD;
- pending_node->index = 0;
- list_add_tail (&pending_node->list, selected);
-
- ret = 0;
- } else if ((cmd & GF_CLI_STATUS_SNAPD) != 0) {
- if (!glusterd_is_snapd_online (volinfo)) {
- gf_log (this->name, GF_LOG_ERROR, "snapd is not "
- "running");
- ret = -1;
- goto out;
- }
- pending_node = GF_CALLOC (1, sizeof (*pending_node),
- gf_gld_mt_pending_node_t);
- if (!pending_node) {
- gf_log (this->name, GF_LOG_ERROR, "failed to allocate "
- "memory for pending node");
- ret = -1;
- goto out;
- }
-
- pending_node->node = (void *)(&volinfo->snapd);
- pending_node->type = GD_NODE_SNAPD;
- pending_node->index = 0;
- list_add_tail (&pending_node->list, selected);
-
- 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, selected);
- pending_node = NULL;
- }
- }
-out:
- return ret;
-}
-
-/* Select the bricks to send the barrier request to.
- * This selects the bricks of the given volume which are present on this peer
- * and are running
- */
-static int
-glusterd_bricks_select_barrier (dict_t *dict, struct list_head *selected)
-{
- int ret = -1;
- char *volname = NULL;
- glusterd_volinfo_t *volinfo = NULL;
- glusterd_brickinfo_t *brickinfo = NULL;
- glusterd_pending_node_t *pending_node = NULL;
-
- GF_ASSERT (dict);
-
- ret = dict_get_str (dict, "volname", &volname);
- if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR, "Failed to get volname");
- goto out;
- }
-
- ret = glusterd_volinfo_find (volname, &volinfo);
- if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR, "Failed to find volume %s",
- volname);
- goto out;
- }
-
- list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) {
- 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;
- goto out;
- }
- pending_node->node = brickinfo;
- pending_node->type = GD_NODE_BRICK;
- list_add_tail (&pending_node->list, selected);
- pending_node = NULL;
- }
-
-out:
- gf_log(THIS->name, GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-
-static int
-glusterd_op_ac_send_brick_op (glusterd_op_sm_event_t *event, void *ctx)
-{
- int ret = 0;
- rpc_clnt_procedure_t *proc = NULL;
- glusterd_conf_t *priv = NULL;
- 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;
-
- if (ctx) {
- req_ctx = ctx;
- } else {
- req_ctx = GF_CALLOC (1, sizeof (*req_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,
- NULL);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, LOGSTR_BUILD_PAYLOAD,
- gd_op_list[op]);
- if (op_errstr == NULL)
- gf_asprintf (&op_errstr,
- OPERRSTR_BUILD_PAYLOAD);
- opinfo.op_errstr = op_errstr;
- goto out;
- }
- }
-
- proc = &priv->gfs_mgmt->proctable[GLUSTERD_BRICK_OP];
- if (proc->fn) {
- ret = proc->fn (NULL, this, req_ctx);
- if (ret)
- goto out;
- }
-
- if (!opinfo.pending_count && !opinfo.brick_pending_count) {
- glusterd_clear_pending_nodes (&opinfo.pending_bricks);
- ret = glusterd_op_sm_inject_event (GD_OP_EVENT_ALL_ACK,
- &event->txn_id, req_ctx);
- }
-
-out:
- gf_log (this->name, GF_LOG_DEBUG, "Returning with %d", ret);
-
- return ret;
-}
-
-
-static int
-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;
- char *op_errstr = NULL;
- glusterd_op_t op = GD_OP_NONE;
- gd_node_type type = GD_NODE_NONE;
- dict_t *op_ctx = NULL;
- glusterd_req_ctx_t *req_ctx = NULL;
- void *pending_entry = NULL;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (event);
- GF_ASSERT (ctx);
- ev_ctx = 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;
-
- ret = glusterd_remove_pending_entry (&opinfo.pending_bricks,
- pending_entry);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "unknown response received ");
- ret = -1;
- goto out;
- }
-
- if (opinfo.brick_pending_count > 0)
- opinfo.brick_pending_count--;
-
- glusterd_handle_node_rsp (req_ctx->dict, pending_entry, op, ev_ctx->rsp_dict,
- op_ctx, &op_errstr, type);
-
- if (opinfo.brick_pending_count > 0)
- goto out;
-
- ret = glusterd_op_sm_inject_event (GD_OP_EVENT_ALL_ACK, &event->txn_id,
- ev_ctx->commit_ctx);
-
-out:
- if (ev_ctx->rsp_dict)
- dict_unref (ev_ctx->rsp_dict);
- GF_FREE (ev_ctx);
- gf_log (this->name, GF_LOG_DEBUG, "Returning %d", ret);
-
- return ret;
-}
-
-int32_t
-glusterd_op_bricks_select (glusterd_op_t op, dict_t *dict, char **op_errstr,
- struct list_head *selected, dict_t *rsp_dict)
-{
- int ret = 0;
-
- GF_ASSERT (dict);
- GF_ASSERT (op_errstr);
- GF_ASSERT (op > GD_OP_NONE);
- GF_ASSERT (op < GD_OP_MAX);
-
- switch (op) {
- case GD_OP_STOP_VOLUME:
- ret = glusterd_bricks_select_stop_volume (dict, op_errstr,
- selected);
- break;
-
- case GD_OP_REMOVE_BRICK:
- ret = glusterd_bricks_select_remove_brick (dict, op_errstr,
- selected);
- break;
-
- case GD_OP_PROFILE_VOLUME:
- ret = glusterd_bricks_select_profile_volume (dict, op_errstr,
- selected);
- break;
-
- case GD_OP_HEAL_VOLUME:
- ret = glusterd_bricks_select_heal_volume (dict, op_errstr,
- selected, rsp_dict);
- break;
-
- case GD_OP_STATUS_VOLUME:
- ret = glusterd_bricks_select_status_volume (dict, op_errstr,
- selected);
- break;
-
- case GD_OP_DEFRAG_BRICK_VOLUME:
- ret = glusterd_bricks_select_rebalance_volume (dict, op_errstr,
- selected);
- break;
-
- case GD_OP_BARRIER:
- ret = glusterd_bricks_select_barrier (dict, selected);
- break;
- case GD_OP_SNAP:
- ret = glusterd_bricks_select_snap (dict, op_errstr, selected);
- break;
- default:
- break;
- }
-
- gf_log (THIS->name, GF_LOG_DEBUG, "Returning %d", ret);
-
- return ret;
-}
-
-glusterd_op_sm_t glusterd_op_state_default [] = {
- {GD_OP_STATE_DEFAULT, glusterd_op_ac_none}, //EVENT_NONE
- {GD_OP_STATE_LOCK_SENT, glusterd_op_ac_send_lock},//EVENT_START_LOCK
- {GD_OP_STATE_LOCKED, glusterd_op_ac_lock}, //EVENT_LOCK
- {GD_OP_STATE_DEFAULT, glusterd_op_ac_none}, //EVENT_RCVD_ACC
- {GD_OP_STATE_DEFAULT, glusterd_op_ac_none}, //EVENT_ALL_ACC
- {GD_OP_STATE_DEFAULT, glusterd_op_ac_none}, //EVENT_STAGE_ACC
- {GD_OP_STATE_DEFAULT, glusterd_op_ac_none}, //EVENT_COMMIT_ACC
- {GD_OP_STATE_DEFAULT, glusterd_op_ac_none}, //EVENT_RCVD_RJT
- {GD_OP_STATE_DEFAULT, glusterd_op_ac_none}, //EVENT_STAGE_OP
- {GD_OP_STATE_DEFAULT, glusterd_op_ac_none}, //EVENT_COMMIT_OP
- {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_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_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_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_RCVD_ACC
- {GD_OP_STATE_LOCKED, glusterd_op_ac_none}, //EVENT_ALL_ACC
- {GD_OP_STATE_LOCKED, glusterd_op_ac_none}, //EVENT_STAGE_ACC
- {GD_OP_STATE_LOCKED, glusterd_op_ac_none}, //EVENT_COMMIT_ACC
- {GD_OP_STATE_LOCKED, glusterd_op_ac_none}, //EVENT_RCVD_RJT
- {GD_OP_STATE_STAGED, glusterd_op_ac_stage_op}, //EVENT_STAGE_OP
- {GD_OP_STATE_LOCKED, glusterd_op_ac_none}, //EVENT_COMMIT_OP
- {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_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_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_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_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
- {GD_OP_STATE_STAGE_OP_FAILED, 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_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_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_RCVD_ACC
- {GD_OP_STATE_STAGED, glusterd_op_ac_none}, //EVENT_ALL_ACC
- {GD_OP_STATE_STAGED, glusterd_op_ac_none}, //EVENT_STAGE_ACC
- {GD_OP_STATE_STAGED, glusterd_op_ac_none}, //EVENT_COMMIT_ACC
- {GD_OP_STATE_STAGED, glusterd_op_ac_none}, //EVENT_RCVD_RJT
- {GD_OP_STATE_STAGED, glusterd_op_ac_none}, //EVENT_STAGE_OP
- {GD_OP_STATE_BRICK_COMMITTED, glusterd_op_ac_send_brick_op}, //EVENT_COMMIT_OP
- {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_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
- {GD_OP_STATE_BRICK_OP_SENT, glusterd_op_ac_none}, //EVENT_COMMIT_ACC
- {GD_OP_STATE_BRICK_OP_FAILED, glusterd_op_ac_brick_op_failed}, //EVENT_RCVD_RJT
- {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_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_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
- {GD_OP_STATE_BRICK_OP_FAILED, glusterd_op_ac_none}, //EVENT_COMMIT_ACC
- {GD_OP_STATE_BRICK_OP_FAILED, glusterd_op_ac_brick_op_failed}, //EVENT_RCVD_RJT
- {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_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_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
- {GD_OP_STATE_BRICK_COMMITTED, glusterd_op_ac_none}, //EVENT_COMMIT_ACC
- {GD_OP_STATE_BRICK_COMMIT_FAILED, glusterd_op_ac_brick_op_failed}, //EVENT_RCVD_RJT
- {GD_OP_STATE_BRICK_COMMITTED, glusterd_op_ac_none}, //EVENT_STAGE_OP
- {GD_OP_STATE_BRICK_COMMITTED, glusterd_op_ac_none}, //EVENT_COMMIT_OP
- {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_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
- {GD_OP_STATE_BRICK_COMMIT_FAILED, glusterd_op_ac_none}, //EVENT_COMMIT_ACC
- {GD_OP_STATE_BRICK_COMMIT_FAILED, glusterd_op_ac_brick_op_failed}, //EVENT_RCVD_RJT
- {GD_OP_STATE_BRICK_COMMIT_FAILED, glusterd_op_ac_none}, //EVENT_STAGE_OP
- {GD_OP_STATE_BRICK_COMMIT_FAILED, glusterd_op_ac_none}, //EVENT_COMMIT_OP
- {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_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
- {GD_OP_STATE_COMMIT_OP_FAILED, glusterd_op_ac_none}, //EVENT_COMMIT_ACC
- {GD_OP_STATE_COMMIT_OP_FAILED, glusterd_op_ac_commit_op_failed}, //EVENT_RCVD_RJT
- {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_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_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
- {GD_OP_STATE_UNLOCK_SENT, glusterd_op_ac_send_unlock}, //EVENT_COMMIT_ACC
- {GD_OP_STATE_COMMIT_OP_FAILED, glusterd_op_ac_commit_op_failed}, //EVENT_RCVD_RJT
- {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_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_RCVD_ACC
- {GD_OP_STATE_COMMITED, glusterd_op_ac_none}, //EVENT_ALL_ACC
- {GD_OP_STATE_COMMITED, glusterd_op_ac_none}, //EVENT_STAGE_ACC
- {GD_OP_STATE_COMMITED, glusterd_op_ac_none}, //EVENT_COMMIT_ACC
- {GD_OP_STATE_COMMITED, glusterd_op_ac_none}, //EVENT_RCVD_RJT
- {GD_OP_STATE_COMMITED, glusterd_op_ac_none}, //EVENT_STAGE_OP
- {GD_OP_STATE_COMMITED, glusterd_op_ac_none}, //EVENT_COMMIT_OP
- {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_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_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_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,
- glusterd_op_state_lock_sent,
- glusterd_op_state_locked,
- glusterd_op_state_stage_op_sent,
- glusterd_op_state_staged,
- glusterd_op_state_commit_op_sent,
- glusterd_op_state_committed,
- glusterd_op_state_unlock_sent,
- glusterd_op_state_stage_op_failed,
- glusterd_op_state_commit_op_failed,
- 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
-};
-
-int
-glusterd_op_sm_new_event (glusterd_op_sm_event_type_t event_type,
- glusterd_op_sm_event_t **new_event)
-{
- glusterd_op_sm_event_t *event = NULL;
-
- GF_ASSERT (new_event);
- GF_ASSERT (GD_OP_EVENT_NONE <= event_type &&
- GD_OP_EVENT_MAX > event_type);
-
- event = GF_CALLOC (1, sizeof (*event), gf_gld_mt_op_sm_event_t);
-
- if (!event)
- return -1;
-
- *new_event = event;
- event->event = event_type;
- INIT_LIST_HEAD (&event->list);
-
- return 0;
-}
-
-int
-glusterd_op_sm_inject_event (glusterd_op_sm_event_type_t event_type,
- uuid_t *txn_id, void *ctx)
-{
- int32_t ret = -1;
- glusterd_op_sm_event_t *event = NULL;
-
- GF_ASSERT (event_type < GD_OP_EVENT_MAX &&
- event_type >= GD_OP_EVENT_NONE);
-
- ret = glusterd_op_sm_new_event (event_type, &event);
-
- if (ret)
- goto out;
-
- event->ctx = ctx;
-
- if (txn_id)
- uuid_copy (event->txn_id, *txn_id);
-
- gf_log (THIS->name, GF_LOG_DEBUG, "Enqueue event: '%s'",
- glusterd_op_sm_event_name_get (event->event));
- list_add_tail (&event->list, &gd_op_sm_queue);
-
-out:
- return ret;
-}
-
-void
-glusterd_destroy_req_ctx (glusterd_req_ctx_t *ctx)
-{
- if (!ctx)
- return;
- if (ctx->dict)
- dict_unref (ctx->dict);
- GF_FREE (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)
- return;
-
- switch (event->event) {
- case GD_OP_EVENT_LOCK:
- case GD_OP_EVENT_UNLOCK:
- glusterd_destroy_lock_ctx (event->ctx);
- break;
- case GD_OP_EVENT_STAGE_OP:
- 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;
- }
-}
-
-int
-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;
- xlator_t *this = NULL;
- glusterd_op_info_t txn_op_info;
-
- this = THIS;
- GF_ASSERT (this);
-
- if ((lock_err = pthread_mutex_trylock (&gd_op_sm_lock))) {
- gf_log (this->name, GF_LOG_ERROR, "lock failed due to %s",
- strerror (lock_err));
- goto lock_failed;
- }
-
- while (!list_empty (&gd_op_sm_queue)) {
-
- list_for_each_entry_safe (event, tmp, &gd_op_sm_queue, list) {
-
- list_del_init (&event->list);
- event_type = event->event;
- gf_log (this->name, GF_LOG_DEBUG, "Dequeued event of "
- "type: '%s'",
- glusterd_op_sm_event_name_get(event_type));
-
- gf_log (this->name, GF_LOG_DEBUG, "transaction ID = %s",
- uuid_utoa (event->txn_id));
-
- ret = glusterd_get_txn_opinfo (&event->txn_id,
- &txn_op_info);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Unable to get transaction's opinfo");
- glusterd_destroy_op_event_ctx (event);
- GF_FREE (event);
- continue;
- } else
- opinfo = txn_op_info;
-
- state = glusterd_op_state_table[opinfo.state.state];
-
- GF_ASSERT (state);
-
- handler = state[event_type].handler;
- GF_ASSERT (handler);
-
- ret = handler (event, event->ctx);
-
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "handler returned: %d", ret);
- glusterd_destroy_op_event_ctx (event);
- GF_FREE (event);
- continue;
- }
-
- ret = glusterd_op_sm_transition_state (&opinfo, state,
- event_type);
-
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Unable to transition"
- "state from '%s' to '%s'",
- glusterd_op_sm_state_name_get(opinfo.state.state),
- glusterd_op_sm_state_name_get(state[event_type].next_state));
- (void ) pthread_mutex_unlock (&gd_op_sm_lock);
- return ret;
- }
-
- if ((state[event_type].next_state ==
- GD_OP_STATE_DEFAULT) &&
- (event_type == GD_OP_EVENT_UNLOCK)) {
- /* Clearing the transaction opinfo */
- ret = glusterd_clear_txn_opinfo(&event->txn_id);
- if (ret)
- gf_log (this->name, GF_LOG_ERROR,
- "Unable to clear "
- "transaction's opinfo");
- } else {
- ret = glusterd_set_txn_opinfo (&event->txn_id,
- &opinfo);
- if (ret)
- gf_log (this->name, GF_LOG_ERROR,
- "Unable to set "
- "transaction's opinfo");
- }
-
- glusterd_destroy_op_event_ctx (event);
- GF_FREE (event);
-
- }
- }
-
-
- (void ) pthread_mutex_unlock (&gd_op_sm_lock);
- ret = 0;
-
-lock_failed:
-
- return ret;
-}
-
-int32_t
-glusterd_op_set_op (glusterd_op_t op)
-{
-
- GF_ASSERT (op < GD_OP_MAX);
- GF_ASSERT (op > GD_OP_NONE);
-
- opinfo.op = op;
-
- return 0;
-
-}
-
-int32_t
-glusterd_op_get_op ()
-{
-
- return opinfo.op;
-
-}
-
-int32_t
-glusterd_op_set_req (rpcsvc_request_t *req)
-{
-
- GF_ASSERT (req);
- opinfo.req = req;
- return 0;
-}
-
-int32_t
-glusterd_op_clear_op (glusterd_op_t op)
-{
-
- opinfo.op = GD_OP_NONE;
-
- return 0;
-
-}
-
-int32_t
-glusterd_op_free_ctx (glusterd_op_t op, void *ctx)
-{
-
- if (ctx) {
- 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_ROTATE:
- case GD_OP_SYNC_VOLUME:
- case GD_OP_SET_VOLUME:
- case GD_OP_START_VOLUME:
- case GD_OP_RESET_VOLUME:
- 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;
- default:
- GF_ASSERT (0);
- break;
- }
- }
-
- glusterd_op_reset_ctx ();
- return 0;
-
-}
-
-void *
-glusterd_op_get_ctx ()
-{
-
- return opinfo.op_ctx;
-
-}
-
-int
-glusterd_op_sm_init ()
-{
- INIT_LIST_HEAD (&gd_op_sm_queue);
- pthread_mutex_init (&gd_op_sm_lock, NULL);
- return 0;
-}
diff --git a/xlators/mgmt/glusterd/src/glusterd-op-sm.h b/xlators/mgmt/glusterd/src/glusterd-op-sm.h
deleted file mode 100644
index 3786c9af291..00000000000
--- a/xlators/mgmt/glusterd/src/glusterd-op-sm.h
+++ /dev/null
@@ -1,317 +0,0 @@
-/*
- Copyright (c) 2006-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 _GLUSTERD_OP_SM_H_
-#define _GLUSTERD_OP_SM_H_
-
-#ifndef _CONFIG_H
-#define _CONFIG_H
-#include "config.h"
-#endif
-
-#ifndef GSYNC_CONF_TEMPLATE
-#define GSYNC_CONF_TEMPLATE GEOREP"/gsyncd_template.conf"
-#endif
-
-#include <pthread.h>
-#include "uuid.h"
-
-#include "glusterfs.h"
-#include "xlator.h"
-#include "logging.h"
-#include "call-stub.h"
-#include "fd.h"
-#include "byte-order.h"
-#include "glusterd.h"
-#include "protocol-common.h"
-
-#define GD_OP_PROTECTED (0x02)
-#define GD_OP_UNPROTECTED (0x04)
-
-typedef enum glusterd_op_sm_state_ {
- GD_OP_STATE_DEFAULT = 0,
- GD_OP_STATE_LOCK_SENT,
- GD_OP_STATE_LOCKED,
- GD_OP_STATE_STAGE_OP_SENT,
- GD_OP_STATE_STAGED,
- GD_OP_STATE_COMMIT_OP_SENT,
- GD_OP_STATE_COMMITED,
- GD_OP_STATE_UNLOCK_SENT,
- GD_OP_STATE_STAGE_OP_FAILED,
- GD_OP_STATE_COMMIT_OP_FAILED,
- GD_OP_STATE_BRICK_OP_SENT,
- 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;
-
-typedef enum glusterd_op_sm_event_type_ {
- GD_OP_EVENT_NONE = 0,
- GD_OP_EVENT_START_LOCK,
- GD_OP_EVENT_LOCK,
- GD_OP_EVENT_RCVD_ACC,
- GD_OP_EVENT_ALL_ACC,
- GD_OP_EVENT_STAGE_ACC,
- GD_OP_EVENT_COMMIT_ACC,
- GD_OP_EVENT_RCVD_RJT,
- GD_OP_EVENT_STAGE_OP,
- GD_OP_EVENT_COMMIT_OP,
- 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;
-
-
-struct glusterd_op_sm_event_ {
- struct list_head list;
- void *ctx;
- glusterd_op_sm_event_type_t event;
- uuid_t txn_id;
-};
-
-typedef struct glusterd_op_sm_event_ glusterd_op_sm_event_t;
-
-typedef int (*glusterd_op_sm_ac_fn) (glusterd_op_sm_event_t *, void *);
-
-typedef struct glusterd_op_sm_ {
- glusterd_op_sm_state_t next_state;
- glusterd_op_sm_ac_fn handler;
-} glusterd_op_sm_t;
-
-typedef struct glusterd_op_sm_state_info_ {
- glusterd_op_sm_state_t state;
- struct timeval time;
-} glusterd_op_sm_state_info_t;
-
-struct glusterd_op_info_ {
- glusterd_op_sm_state_info_t state;
- int32_t pending_count;
- int32_t brick_pending_count;
- int32_t op_count;
- glusterd_op_t op;
- struct list_head op_peers;
- void *op_ctx;
- rpcsvc_request_t *req;
- int32_t op_ret;
- int32_t op_errno;
- char *op_errstr;
- struct list_head pending_bricks;
- struct list_head *local_xaction_peers;
-};
-
-typedef struct glusterd_op_info_ glusterd_op_info_t;
-
-struct glusterd_op_log_filename_ctx_ {
- char volume_name[GD_VOLUME_NAME_MAX];
- char brick[GD_VOLUME_NAME_MAX];
- char path[PATH_MAX];
-};
-typedef struct glusterd_op_log_filename_ctx_ glusterd_op_log_filename_ctx_t;
-
-struct glusterd_op_lock_ctx_ {
- uuid_t uuid;
- dict_t *dict;
- rpcsvc_request_t *req;
-};
-
-typedef struct glusterd_op_lock_ctx_ glusterd_op_lock_ctx_t;
-
-struct glusterd_req_ctx_ {
- rpcsvc_request_t *req;
- u_char uuid[16];
- int op;
- dict_t *dict;
-};
-
-typedef struct glusterd_req_ctx_ glusterd_req_ctx_t;
-
-typedef struct glusterd_op_brick_rsp_ctx_ {
- int op_ret;
- char *op_errstr;
- dict_t *rsp_dict;
- glusterd_req_ctx_t *commit_ctx;
- glusterd_pending_node_t *pending_node;
-} glusterd_op_brick_rsp_ctx_t;
-
-typedef struct glusterd_pr_brick_rsp_conv_t {
- int count;
- 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_status_temp {
- dict_t *rsp_dict;
- glusterd_volinfo_t *volinfo;
- char *node;
-}glusterd_gsync_status_temp_t;
-
-typedef struct gsync_status_param {
- int is_active;
- glusterd_volinfo_t *volinfo;
-}gsync_status_param_t;
-
-typedef struct glusterd_txn_opinfo_object_ {
- glusterd_op_info_t opinfo;
-} glusterd_txn_opinfo_obj;
-
-typedef enum cli_cmd_type_ {
- PER_REPLICA,
- ALL_REPLICA,
- } cli_cmd_type;
-
-int
-glusterd_op_sm_new_event (glusterd_op_sm_event_type_t event_type,
- glusterd_op_sm_event_t **new_event);
-int
-glusterd_op_sm_inject_event (glusterd_op_sm_event_type_t event_type,
- uuid_t *txn_id, void *ctx);
-
-int
-glusterd_op_sm_init ();
-
-int
-glusterd_op_sm ();
-
-int32_t
-glusterd_op_set_ctx (void *ctx);
-
-int32_t
-glusterd_op_set_op (glusterd_op_t op);
-
-int
-glusterd_op_build_payload (dict_t **req, char **op_errstr, dict_t *op_ctx);
-
-int32_t
-glusterd_op_stage_validate (glusterd_op_t op, dict_t *req, char **op_errstr,
- dict_t *rsp_dict);
-
-int32_t
-glusterd_op_commit_perform (glusterd_op_t op, dict_t *req, char **op_errstr,
- dict_t* dict);
-
-int32_t
-glusterd_op_txn_begin (rpcsvc_request_t *req, glusterd_op_t op, void *ctx,
- char *err_str, size_t err_len);
-
-int32_t
-glusterd_op_txn_complete ();
-
-void *
-glusterd_op_get_ctx ();
-
-int32_t
-glusterd_op_set_req (rpcsvc_request_t *req);
-
-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);
-int32_t
-glusterd_op_get_op ();
-
-int32_t
-glusterd_op_clear_op ();
-
-int32_t
-glusterd_op_free_ctx (glusterd_op_t op, void *ctx);
-
-int
-glusterd_check_option_exists(char *optstring, char **completion);
-
-int
-set_xlator_option (dict_t *dict, char *key, char *value);
-
-void
-glusterd_do_replace_brick (void *data);
-
-char*
-glusterd_op_sm_state_name_get (int state);
-
-char*
-glusterd_op_sm_event_name_get (int event);
-int32_t
-glusterd_op_bricks_select (glusterd_op_t op, dict_t *dict, char **op_errstr,
- struct list_head *selected, dict_t *rsp_dict);
-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);
-
-dict_t*
-glusterd_op_init_commit_rsp_dict (glusterd_op_t op);
-
-void
-glusterd_op_modify_op_ctx (glusterd_op_t op, void *op_ctx);
-
-int32_t
-glusterd_volume_stats_read_perf (char *brick_path, int32_t blk_size,
- int32_t blk_count, double *throughput, double *time);
-int32_t
-glusterd_volume_stats_write_perf (char *brick_path, int32_t blk_size,
- int32_t blk_count, double *throughput, double *time);
-gf_boolean_t
-glusterd_is_volume_started (glusterd_volinfo_t *volinfo);
-int
-glusterd_start_bricks (glusterd_volinfo_t *volinfo);
-gf_boolean_t
-glusterd_are_all_volumes_stopped ();
-int
-glusterd_stop_bricks (glusterd_volinfo_t *volinfo);
-int
-gsync_status (char *master, char *slave, char *conf_path,
- int *status, gf_boolean_t *is_template_in_use);
-
-int
-glusterd_check_gsync_running (glusterd_volinfo_t *volinfo, gf_boolean_t *flag);
-
-int
-glusterd_defrag_volume_node_rsp (dict_t *req_dict, dict_t *rsp_dict,
- dict_t *op_ctx);
-#ifdef HAVE_BD_XLATOR
-int
-glusterd_is_valid_vg (glusterd_brickinfo_t *brick, int check_tag, char *msg);
-#endif
-
-int32_t
-glusterd_get_txn_opinfo (uuid_t *txn_id, glusterd_op_info_t *opinfo);
-
-int32_t
-glusterd_set_txn_opinfo (uuid_t *txn_id, glusterd_op_info_t *opinfo);
-
-int32_t
-glusterd_clear_txn_opinfo (uuid_t *txn_id);
-
-int32_t
-glusterd_generate_txn_id (dict_t *dict, uuid_t **txn_id);
-
-void
-glusterd_set_opinfo (char *errstr, int32_t op_errno, int32_t op_ret);
-#endif
diff --git a/xlators/mgmt/glusterd/src/glusterd-peer-utils.c b/xlators/mgmt/glusterd/src/glusterd-peer-utils.c
deleted file mode 100644
index be8ae76c77a..00000000000
--- a/xlators/mgmt/glusterd/src/glusterd-peer-utils.c
+++ /dev/null
@@ -1,902 +0,0 @@
-/*
- Copyright (c) 2014 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 "glusterd-peer-utils.h"
-#include "glusterd-store.h"
-#include "common-utils.h"
-
-int32_t
-glusterd_peerinfo_cleanup (glusterd_peerinfo_t *peerinfo)
-{
- GF_ASSERT (peerinfo);
- glusterd_peerctx_t *peerctx = NULL;
- gf_boolean_t quorum_action = _gf_false;
- glusterd_conf_t *priv = THIS->private;
-
- if (peerinfo->quorum_contrib != QUORUM_NONE)
- quorum_action = _gf_true;
- if (peerinfo->rpc) {
- peerctx = peerinfo->rpc->mydata;
- peerinfo->rpc->mydata = NULL;
- peerinfo->rpc = glusterd_rpc_clnt_unref (priv, peerinfo->rpc);
- peerinfo->rpc = NULL;
- if (peerctx) {
- GF_FREE (peerctx->errstr);
- GF_FREE (peerctx);
- }
- }
- glusterd_peerinfo_destroy (peerinfo);
-
- if (quorum_action)
- glusterd_do_quorum_action ();
- return 0;
-}
-
-int32_t
-glusterd_peerinfo_destroy (glusterd_peerinfo_t *peerinfo)
-{
- int32_t ret = -1;
- glusterd_peer_hostname_t *hostname = NULL;
- glusterd_peer_hostname_t *tmp = NULL;
-
- if (!peerinfo)
- goto out;
-
- list_del_init (&peerinfo->uuid_list);
-
- ret = glusterd_store_delete_peerinfo (peerinfo);
- if (ret) {
- gf_log ("glusterd", GF_LOG_ERROR, "Deleting peer info failed");
- }
-
- GF_FREE (peerinfo->hostname);
- peerinfo->hostname = NULL;
-
- list_for_each_entry_safe (hostname, tmp, &peerinfo->hostnames,
- hostname_list) {
- glusterd_peer_hostname_free (hostname);
- }
-
- glusterd_sm_tr_log_delete (&peerinfo->sm_log);
- GF_FREE (peerinfo);
- peerinfo = NULL;
-
- ret = 0;
-
-out:
- return ret;
-}
-
-/* glusterd_peerinfo_find_by_hostname searches for a peer which matches the
- * hostname @hoststr and if found returns the pointer to peerinfo object.
- * Returns NULL otherwise.
- *
- * It first attempts a quick search by string matching @hoststr. If that fails,
- * it'll attempt a more thorough match by resolving the addresses and matching
- * the resolved addrinfos.
- */
-glusterd_peerinfo_t *
-glusterd_peerinfo_find_by_hostname (const char *hoststr)
-{
- int ret = -1;
- struct addrinfo *addr = NULL;
- struct addrinfo *p = NULL;
- xlator_t *this = NULL;
- glusterd_peerinfo_t *peerinfo = NULL;
-
-
- this = THIS;
- GF_ASSERT (hoststr);
-
- peerinfo = NULL;
-
- peerinfo = gd_peerinfo_find_from_hostname (hoststr);
- if (peerinfo)
- return peerinfo;
-
- ret = getaddrinfo (hoststr, NULL, NULL, &addr);
- if (ret != 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "error in getaddrinfo: %s\n",
- gai_strerror(ret));
- goto out;
- }
-
- for (p = addr; p != NULL; p = p->ai_next) {
- peerinfo = gd_peerinfo_find_from_addrinfo (p);
- if (peerinfo) {
- freeaddrinfo (addr);
- return peerinfo;
- }
- }
-
-out:
- gf_log (this->name, GF_LOG_DEBUG, "Unable to find friend: %s", hoststr);
- if (addr)
- freeaddrinfo (addr);
- return NULL;
-}
-
-int
-glusterd_hostname_to_uuid (char *hostname, uuid_t uuid)
-{
- GF_ASSERT (hostname);
- GF_ASSERT (uuid);
-
- glusterd_peerinfo_t *peerinfo = NULL;
- glusterd_conf_t *priv = NULL;
- int ret = -1;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- priv = this->private;
- GF_ASSERT (priv);
-
- peerinfo = glusterd_peerinfo_find_by_hostname (hostname);
- if (peerinfo) {
- ret = 0;
- uuid_copy (uuid, peerinfo->uuid);
- } else {
- if (gf_is_local_addr (hostname)) {
- uuid_copy (uuid, MY_UUID);
- ret = 0;
- } else {
- ret = -1;
- }
- }
-
- gf_log (this->name, GF_LOG_DEBUG, "returning %d", ret);
- return ret;
-}
-
-/* glusterd_peerinfo_find_by_uuid searches for a peer which matches the
- * uuid @uuid and if found returns the pointer to peerinfo object.
- * Returns NULL otherwise.
- */
-glusterd_peerinfo_t *
-glusterd_peerinfo_find_by_uuid (uuid_t uuid)
-{
- glusterd_conf_t *priv = NULL;
- glusterd_peerinfo_t *entry = NULL;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
-
- priv = this->private;
-
- GF_ASSERT (priv);
-
- if (uuid_is_null (uuid))
- return NULL;
-
- list_for_each_entry (entry, &priv->peers, uuid_list) {
- if (!uuid_compare (entry->uuid, uuid)) {
-
- gf_log (this->name, GF_LOG_DEBUG,
- "Friend found... state: %s",
- glusterd_friend_sm_state_name_get (entry->state.state));
- return entry;
- }
- }
-
- gf_log (this->name, GF_LOG_DEBUG, "Friend with uuid: %s, not found",
- uuid_utoa (uuid));
- return NULL;
-}
-
-/* glusterd_peerinfo_find will search for a peer matching either @uuid or
- * @hostname and return a pointer to the peerinfo object
- * Returns NULL otherwise.
- */
-glusterd_peerinfo_t *
-glusterd_peerinfo_find (uuid_t uuid, const char *hostname)
-{
- glusterd_peerinfo_t *peerinfo = NULL;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
-
-
- if (uuid) {
- peerinfo = glusterd_peerinfo_find_by_uuid (uuid);
-
- if (peerinfo) {
- return peerinfo;
- } else {
- gf_log (this->name, GF_LOG_DEBUG,
- "Unable to find peer by uuid: %s",
- uuid_utoa (uuid));
- }
-
- }
-
- if (hostname) {
- peerinfo = glusterd_peerinfo_find_by_hostname (hostname);
-
- if (peerinfo) {
- return peerinfo;
- } else {
- gf_log (this->name, GF_LOG_DEBUG,
- "Unable to find hostname: %s", hostname);
- }
- }
- return NULL;
-}
-
-/* glusterd_peerinfo_new will create a new peerinfo object and set it's members
- * values using the passed parameters.
- * @hostname is added as the first entry in peerinfo->hostnames list and also
- * set to peerinfo->hostname.
- * It returns a pointer to peerinfo object if successfull and returns NULL
- * otherwise. The caller should take care of freeing the created peerinfo
- * object.
- */
-glusterd_peerinfo_t *
-glusterd_peerinfo_new (glusterd_friend_sm_state_t state, uuid_t *uuid,
- const char *hostname, int port)
-{
- glusterd_peerinfo_t *new_peer = NULL;
- int ret = -1;
-
- new_peer = GF_CALLOC (1, sizeof (*new_peer), gf_gld_mt_peerinfo_t);
- if (!new_peer)
- goto out;
-
- INIT_LIST_HEAD (&new_peer->uuid_list);
-
- new_peer->state.state = state;
-
- INIT_LIST_HEAD (&new_peer->hostnames);
- if (hostname) {
- ret = gd_add_address_to_peer (new_peer, hostname);
- if (ret)
- goto out;
- /* Also set it to peerinfo->hostname. Doing this as we use
- * peerinfo->hostname in a lot of places and is really hard to
- * get everything right
- */
- new_peer->hostname = gf_strdup (hostname);
- }
-
- if (uuid) {
- uuid_copy (new_peer->uuid, *uuid);
- }
-
- ret = glusterd_sm_tr_log_init (&new_peer->sm_log,
- glusterd_friend_sm_state_name_get,
- glusterd_friend_sm_event_name_get,
- GLUSTERD_TR_LOG_SIZE);
- if (ret)
- goto out;
-
- if (new_peer->state.state == GD_FRIEND_STATE_BEFRIENDED)
- new_peer->quorum_contrib = QUORUM_WAITING;
- new_peer->port = port;
-out:
- if (ret && new_peer) {
- glusterd_peerinfo_cleanup (new_peer);
- new_peer = NULL;
- }
- return new_peer;
-}
-
-/* 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;
-}
-
-/* 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;
-}
-
-char*
-gd_peer_uuid_str (glusterd_peerinfo_t *peerinfo)
-{
- if ((peerinfo == NULL) || uuid_is_null (peerinfo->uuid))
- return NULL;
-
- if (peerinfo->uuid_str[0] == '\0')
- uuid_utoa_r (peerinfo->uuid, peerinfo->uuid_str);
-
- return peerinfo->uuid_str;
-}
-
-gf_boolean_t
-glusterd_are_vol_all_peers_up (glusterd_volinfo_t *volinfo,
- struct list_head *peers,
- char **down_peerstr)
-{
- glusterd_peerinfo_t *peerinfo = NULL;
- glusterd_brickinfo_t *brickinfo = NULL;
- gf_boolean_t ret = _gf_false;
-
- list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) {
- if (!uuid_compare (brickinfo->uuid, MY_UUID))
- continue;
-
- list_for_each_entry (peerinfo, peers, uuid_list) {
- if (uuid_compare (peerinfo->uuid, brickinfo->uuid))
- continue;
-
- /*Found peer who owns the brick, return false
- * if peer is not connected or not friend */
- if (!(peerinfo->connected) ||
- (peerinfo->state.state !=
- GD_FRIEND_STATE_BEFRIENDED)) {
- *down_peerstr = gf_strdup (peerinfo->hostname);
- gf_log ("", GF_LOG_DEBUG, "Peer %s is down. ",
- peerinfo->hostname);
- goto out;
- }
- }
- }
-
- ret = _gf_true;
-out:
- gf_log ("glusterd", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-
-int32_t
-glusterd_peer_hostname_new (const char *hostname,
- glusterd_peer_hostname_t **name)
-{
- glusterd_peer_hostname_t *peer_hostname = NULL;
- int32_t ret = -1;
-
- GF_ASSERT (hostname);
- GF_ASSERT (name);
-
- peer_hostname = GF_CALLOC (1, sizeof (*peer_hostname),
- gf_gld_mt_peer_hostname_t);
-
- if (!peer_hostname)
- goto out;
-
- peer_hostname->hostname = gf_strdup (hostname);
- INIT_LIST_HEAD (&peer_hostname->hostname_list);
-
- *name = peer_hostname;
- ret = 0;
-
-out:
- gf_log ("glusterd", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-
-void
-glusterd_peer_hostname_free (glusterd_peer_hostname_t *name)
-{
- if (!name)
- return;
-
- list_del_init (&name->hostname_list);
-
- GF_FREE (name->hostname);
- name->hostname = NULL;
-
- GF_FREE (name);
-
- return;
-}
-
-gf_boolean_t
-gd_peer_has_address (glusterd_peerinfo_t *peerinfo, const char *address)
-{
- gf_boolean_t ret = _gf_false;
- glusterd_peer_hostname_t *hostname = NULL;
-
- GF_VALIDATE_OR_GOTO ("glusterd", (peerinfo != NULL), out);
- GF_VALIDATE_OR_GOTO ("glusterd", (address != NULL), out);
-
- list_for_each_entry (hostname, &peerinfo->hostnames, hostname_list) {
- if (strcmp (hostname->hostname, address) == 0) {
- ret = _gf_true;
- break;
- }
- }
-
-out:
- return ret;
-}
-
-int
-gd_add_address_to_peer (glusterd_peerinfo_t *peerinfo, const char *address)
-{
-
- int ret = -1;
- glusterd_peer_hostname_t *hostname = NULL;
-
- GF_VALIDATE_OR_GOTO ("glusterd", (peerinfo != NULL), out);
- GF_VALIDATE_OR_GOTO ("glusterd", (address != NULL), out);
-
- if (gd_peer_has_address (peerinfo, address)) {
- ret = 0;
- goto out;
- }
-
- ret = glusterd_peer_hostname_new (address, &hostname);
- if (ret)
- goto out;
-
- list_add_tail (&hostname->hostname_list, &peerinfo->hostnames);
-
- ret = 0;
-out:
- return ret;
-}
-
-/* gd_add_friend_to_dict() adds details of @friend into @dict with the given
- * @prefix. All the parameters are compulsary.
- *
- * The complete address list is added to the dict only if the cluster op-version
- * is >= GD_OP_VERSION_3_6_0
- */
-int
-gd_add_friend_to_dict (glusterd_peerinfo_t *friend, dict_t *dict,
- const char *prefix)
-{
- int ret = -1;
- xlator_t *this = NULL;
- glusterd_conf_t *conf = NULL;
- char key[100] = {0,};
- glusterd_peer_hostname_t *address = NULL;
- int count = 0;
-
- this = THIS;
- GF_VALIDATE_OR_GOTO ("glusterd", (this != NULL), out);
-
- conf = this->private;
- GF_VALIDATE_OR_GOTO (this->name, (conf != NULL), out);
-
- GF_VALIDATE_OR_GOTO (this->name, (friend != NULL), out);
- GF_VALIDATE_OR_GOTO (this->name, (dict != NULL), out);
- GF_VALIDATE_OR_GOTO (this->name, (prefix != NULL), out);
-
- snprintf (key, sizeof (key), "%s.uuid", prefix);
- ret = dict_set_dynstr_with_alloc (dict, key, uuid_utoa (friend->uuid));
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to set key %s in dict", key);
- goto out;
- }
-
- /* Setting the first hostname from the list with this key for backward
- * compatability
- */
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%s.hostname", prefix);
- address = list_entry (&friend->hostnames, glusterd_peer_hostname_t,
- hostname_list);
- if (!address) {
- ret = -1;
- gf_log (this->name, GF_LOG_ERROR, "Could not retrieve first "
- "address for peer");
- goto out;
- }
- ret = dict_set_dynstr_with_alloc (dict, key, address->hostname);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to set key %s in dict", key);
- goto out;
- }
-
- if (conf->op_version < GD_OP_VERSION_3_6_0) {
- ret = 0;
- goto out;
- }
-
- address = NULL;
- count = 0;
- list_for_each_entry (address, &friend->hostnames, hostname_list) {
- GF_VALIDATE_OR_GOTO (this->name, (address != NULL), out);
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%s.hostname%d", prefix, count);
- ret = dict_set_dynstr_with_alloc (dict, key, address->hostname);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to set key %s in dict", key);
- goto out;
- }
- count++;
- }
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%s.address-count", prefix);
- ret = dict_set_int32 (dict, key, count);
- if (ret)
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to set key %s in dict", key);
-
-out:
- gf_log (this ? this->name : "glusterd", GF_LOG_DEBUG, "Returning %d",
- ret);
- return ret;
-}
-
-/* gd_peerinfo_find_from_hostname iterates over all the addresses saved for each
- * peer and matches it to @hoststr.
- * Returns the matched peer if found else returns NULL
- */
-glusterd_peerinfo_t *
-gd_peerinfo_find_from_hostname (const char *hoststr)
-{
- xlator_t *this = NULL;
- glusterd_conf_t *priv = NULL;
- glusterd_peerinfo_t *peer = NULL;
- glusterd_peer_hostname_t *tmphost = NULL;
-
- this = THIS;
- GF_ASSERT (this != NULL);
- priv = this->private;
- GF_VALIDATE_OR_GOTO (this->name, (priv != NULL), out);
-
- GF_VALIDATE_OR_GOTO (this->name, (hoststr != NULL), out);
-
- list_for_each_entry (peer, &priv->peers, uuid_list) {
- list_for_each_entry (tmphost, &peer->hostnames,hostname_list) {
- if (!strncasecmp (tmphost->hostname, hoststr, 1024)) {
- gf_log (this->name, GF_LOG_DEBUG,
- "Friend %s found.. state: %d",
- tmphost->hostname, peer->state.state);
- return peer;
- }
- }
- }
-out:
- return NULL;
-}
-
-/* gd_peerinfo_find_from_addrinfo iterates over all the addresses saved for each
- * peer, resolves them and compares them to @addr.
- *
- *
- * NOTE: As getaddrinfo is a blocking call and is being performed multiple times
- * in this function, it could lead to the calling thread to be blocked for
- * significant amounts of time.
- *
- * Returns the matched peer if found else returns NULL
- */
-glusterd_peerinfo_t *
-gd_peerinfo_find_from_addrinfo (const struct addrinfo *addr)
-{
- xlator_t *this = NULL;
- glusterd_conf_t *conf = NULL;
- glusterd_peerinfo_t *peer = NULL;
- glusterd_peer_hostname_t *address = NULL;
- int ret = 0;
- struct addrinfo *paddr = NULL;
- struct addrinfo *tmp = NULL;
-
- this = THIS;
- GF_ASSERT (this != NULL);
- conf = this->private;
- GF_VALIDATE_OR_GOTO (this->name, (conf != NULL), out);
-
- GF_VALIDATE_OR_GOTO (this->name, (addr != NULL), out);
-
- list_for_each_entry (peer, &conf->peers, uuid_list) {
- list_for_each_entry (address, &peer->hostnames, hostname_list) {
- /* TODO: Cache the resolved addrinfos to improve
- * performance
- */
- ret = getaddrinfo (address->hostname, NULL, NULL,
- &paddr);
- if (ret) {
- /* Don't fail if getaddrinfo fails, continue
- * onto the next address
- */
- gf_log (this->name, GF_LOG_TRACE,
- "getaddrinfo for %s failed (%s)",
- address->hostname, gai_strerror (ret));
- ret = 0;
- continue;
- }
-
- for (tmp = paddr; tmp != NULL; tmp = tmp->ai_next) {
- if (gf_compare_sockaddr (addr->ai_addr,
- tmp->ai_addr)) {
- freeaddrinfo (paddr);
- return peer;
- }
- }
- }
- }
-out:
- return NULL;
-}
-
-/* gd_update_peerinfo_from_dict will update the hostnames for @peerinfo from
- * peer details with @prefix in @dict.
- * Returns 0 on sucess and -1 on failure.
- */
-int
-gd_update_peerinfo_from_dict (glusterd_peerinfo_t *peerinfo, dict_t *dict,
- const char *prefix)
-{
- int ret = -1;
- xlator_t *this = NULL;
- glusterd_conf_t *conf = NULL;
- char key[100] = {0,};
- char *hostname = NULL;
- int count = 0;
- int i = 0;
-
- this = THIS;
- GF_ASSERT (this != NULL);
-
- conf = this->private;
- GF_VALIDATE_OR_GOTO (this->name, (conf != NULL), out);
-
- GF_VALIDATE_OR_GOTO (this->name, (peerinfo != NULL), out);
- GF_VALIDATE_OR_GOTO (this->name, (dict != NULL), out);
- GF_VALIDATE_OR_GOTO (this->name, (prefix != NULL), out);
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%s.hostname", prefix);
- ret = dict_get_str (dict, key, &hostname);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Key %s not present in "
- "dictionary", key);
- goto out;
- }
- ret = gd_add_address_to_peer (peerinfo, hostname);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Could not add address to peer");
- goto out;
- }
- /* Also set peerinfo->hostname to the first address */
- if (peerinfo->hostname != NULL)
- GF_FREE (peerinfo->hostname);
- peerinfo->hostname = gf_strdup (hostname);
-
- if (conf->op_version < GD_OP_VERSION_3_6_0) {
- ret = 0;
- goto out;
- }
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%s.address-count", prefix);
- ret = dict_get_int32 (dict, key, &count);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Key %s not present in "
- "dictionary", key);
- goto out;
- }
- hostname = NULL;
- for (i = 0; i < count; i++) {
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%s.hostname%d",prefix, i);
- ret = dict_get_str (dict, key, &hostname);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Key %s not present "
- "in dictionary", key);
- goto out;
- }
- ret = gd_add_address_to_peer (peerinfo, hostname);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Could not add address to peer");
- goto out;
- }
-
- hostname = NULL;
- }
-
-out:
- gf_log (this->name, GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-
-/* gd_peerinfo_from_dict creates a peerinfo object from details of peer with
- * @prefix in @dict.
- * Returns a pointer to the created peerinfo object on success, and NULL on
- * failure.
- */
-glusterd_peerinfo_t *
-gd_peerinfo_from_dict (dict_t *dict, const char *prefix)
-{
- int ret = -1;
- xlator_t *this = NULL;
- glusterd_conf_t *conf = NULL;
- glusterd_peerinfo_t *new_peer = NULL;
- char key[100] = {0,};
- char *uuid_str = NULL;
-
- this = THIS;
- GF_VALIDATE_OR_GOTO ("glusterd", (this != NULL), out);
-
- conf = this->private;
- GF_VALIDATE_OR_GOTO (this->name, (conf != NULL), out);
-
- GF_VALIDATE_OR_GOTO (this->name, (dict != NULL), out);
- GF_VALIDATE_OR_GOTO (this->name, (prefix != NULL), out);
-
- new_peer = glusterd_peerinfo_new (GD_FRIEND_STATE_DEFAULT, NULL, NULL,
- 0);
- if (new_peer == NULL) {
- ret = -1;
- gf_log (this->name, GF_LOG_ERROR, "Could not create peerinfo "
- "object");
- goto out;
- }
-
- snprintf (key, sizeof (key), "%s.uuid", prefix);
- ret = dict_get_str (dict, key, &uuid_str);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Key %s not present in "
- "dictionary", key);
- goto out;
- }
- uuid_parse (uuid_str, new_peer->uuid);
-
- ret = gd_update_peerinfo_from_dict (new_peer, dict, prefix);
-
-out:
- if ((ret != 0) && (new_peer != NULL)) {
- glusterd_peerinfo_cleanup (new_peer);
- new_peer = NULL;
- }
-
- return new_peer;
-}
-
-int
-gd_add_peer_hostnames_to_dict (glusterd_peerinfo_t *peerinfo, dict_t *dict,
- const char *prefix)
-{
- int ret = -1;
- xlator_t *this = NULL;
- glusterd_conf_t *conf = NULL;
- char key[256] = {0,};
- glusterd_peer_hostname_t *addr = NULL;
- int count = 0;
-
- this = THIS;
- GF_ASSERT (this != NULL);
-
- conf = this->private;
- GF_VALIDATE_OR_GOTO (this->name, (conf != NULL), out);
-
- if (conf->op_version < GD_OP_VERSION_3_6_0) {
- ret = 0;
- goto out;
- }
-
- GF_VALIDATE_OR_GOTO (this->name, (peerinfo != NULL), out);
- GF_VALIDATE_OR_GOTO (this->name, (dict != NULL), out);
- GF_VALIDATE_OR_GOTO (this->name, (prefix != NULL), out);
-
- list_for_each_entry (addr, &peerinfo->hostnames, hostname_list) {
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%s.hostname%d", prefix, count);
- ret = dict_set_dynstr_with_alloc (dict, key, addr->hostname);
- if (ret)
- goto out;
- count++;
- }
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%s.hostname_count", prefix);
- ret = dict_set_int32 (dict, key, count);
-
-out:
- return ret;
-}
-
-int
-gd_add_peer_detail_to_dict (glusterd_peerinfo_t *peerinfo, dict_t *friends,
- int count)
-{
-
- int ret = -1;
- char key[256] = {0, };
- char *peer_uuid_str = NULL;
-
- GF_ASSERT (peerinfo);
- GF_ASSERT (friends);
-
- snprintf (key, sizeof (key), "friend%d.uuid", count);
- peer_uuid_str = gd_peer_uuid_str (peerinfo);
- ret = dict_set_str (friends, key, peer_uuid_str);
- if (ret)
- goto out;
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "friend%d.hostname", count);
- ret = dict_set_str (friends, key, peerinfo->hostname);
- if (ret)
- goto out;
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "friend%d.port", count);
- ret = dict_set_int32 (friends, key, peerinfo->port);
- if (ret)
- goto out;
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "friend%d.stateId", count);
- ret = dict_set_int32 (friends, key, peerinfo->state.state);
- if (ret)
- goto out;
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "friend%d.state", count);
- ret = dict_set_str (friends, key,
- glusterd_friend_sm_state_name_get(peerinfo->state.state));
- if (ret)
- goto out;
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "friend%d.connected", count);
- ret = dict_set_int32 (friends, key, (int32_t)peerinfo->connected);
- if (ret)
- goto out;
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "friend%d", count);
- ret = gd_add_peer_hostnames_to_dict (peerinfo, friends, key);
-
-out:
- return ret;
-}
diff --git a/xlators/mgmt/glusterd/src/glusterd-peer-utils.h b/xlators/mgmt/glusterd/src/glusterd-peer-utils.h
deleted file mode 100644
index 9877d861af7..00000000000
--- a/xlators/mgmt/glusterd/src/glusterd-peer-utils.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- Copyright (c) 2014 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 _GLUSTERD_PEER_UTILS_H
-#define _GLUSTERD_PEER_UTILS_H
-
-#include "glusterd.h"
-#include "glusterd-utils.h"
-
-int32_t
-glusterd_peerinfo_cleanup (glusterd_peerinfo_t *peerinfo);
-
-int32_t
-glusterd_peerinfo_destroy (glusterd_peerinfo_t *peerinfo);
-
-glusterd_peerinfo_t *
-glusterd_peerinfo_find_by_hostname (const char *hoststr);
-
-int
-glusterd_hostname_to_uuid (char *hostname, uuid_t uuid);
-
-glusterd_peerinfo_t *
-glusterd_peerinfo_find_by_uuid (uuid_t uuid);
-
-glusterd_peerinfo_t *
-glusterd_peerinfo_find (uuid_t uuid, const char *hostname);
-
-glusterd_peerinfo_t *
-glusterd_peerinfo_new (glusterd_friend_sm_state_t state, uuid_t *uuid,
- const char *hostname, int port);
-
-gf_boolean_t
-glusterd_chk_peers_connected_befriended (uuid_t skip_uuid);
-
-char *
-glusterd_uuid_to_hostname (uuid_t uuid);
-
-char*
-gd_peer_uuid_str (glusterd_peerinfo_t *peerinfo);
-
-gf_boolean_t
-glusterd_are_vol_all_peers_up (glusterd_volinfo_t *volinfo,
- struct list_head *peers, char **down_peerstr);
-
-int32_t
-glusterd_peer_hostname_new (const char *hostname,
- glusterd_peer_hostname_t **name);
-void
-glusterd_peer_hostname_free (glusterd_peer_hostname_t *name);
-
-gf_boolean_t
-gd_peer_has_address (glusterd_peerinfo_t *peerinfo, const char *address);
-
-int
-gd_add_address_to_peer (glusterd_peerinfo_t *peerinfo, const char *address);
-
-int
-gd_add_friend_to_dict (glusterd_peerinfo_t *friend, dict_t *dict,
- const char *prefix);
-
-glusterd_peerinfo_t *
-gd_peerinfo_find_from_hostname (const char *hoststr);
-
-glusterd_peerinfo_t *
-gd_peerinfo_find_from_addrinfo (const struct addrinfo *addr);
-
-int
-gd_update_peerinfo_from_dict (glusterd_peerinfo_t *peerinfo, dict_t *dict,
- const char *prefix);
-
-glusterd_peerinfo_t *
-gd_peerinfo_from_dict (dict_t *dict, const char *prefix);
-
-int
-gd_add_peer_hostnames_to_dict (glusterd_peerinfo_t *peerinfo, dict_t *dict,
- const char *prefix);
-int
-gd_add_peer_detail_to_dict (glusterd_peerinfo_t *peerinfo, dict_t *friends,
- int count);
-#endif /* _GLUSTERD_PEER_UTILS_H */
diff --git a/xlators/mgmt/glusterd/src/glusterd-pmap.c b/xlators/mgmt/glusterd/src/glusterd-pmap.c
deleted file mode 100644
index e4dacb80c4a..00000000000
--- a/xlators/mgmt/glusterd/src/glusterd-pmap.c
+++ /dev/null
@@ -1,500 +0,0 @@
-/*
- Copyright (c) 2010-2013 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 "xlator.h"
-#include "glusterfs.h"
-#include "compat-errno.h"
-
-#include "glusterd.h"
-#include "glusterd-utils.h"
-
-#include "portmap-xdr.h"
-#include "xdr-generic.h"
-#include "protocol-common.h"
-#include "rpcsvc.h"
-
-#include <sys/socket.h>
-#include <sys/types.h>
-#include <netinet/in.h>
-
-
-int
-pmap_port_isfree (int port)
-{
- struct sockaddr_in sin;
- int sock = -1;
- int ret = 0;
-
- memset (&sin, 0, sizeof (sin));
- sin.sin_family = PF_INET;
- sin.sin_port = hton16 (port);
-
- sock = socket (PF_INET, SOCK_STREAM, 0);
- if (sock == -1)
- return -1;
-
- ret = bind (sock, (struct sockaddr *)&sin, sizeof (sin));
- close (sock);
-
- return (ret == 0) ? 1 : 0;
-}
-
-
-static struct pmap_registry *
-pmap_registry_new (xlator_t *this)
-{
- struct pmap_registry *pmap = NULL;
- int i = 0;
-
- pmap = CALLOC (sizeof (*pmap), 1);
- if (!pmap)
- return NULL;
-
- for (i = 0; i < 65536; i++) {
- if (pmap_port_isfree (i))
- pmap->ports[i].type = GF_PMAP_PORT_FREE;
- else
- pmap->ports[i].type = GF_PMAP_PORT_FOREIGN;
- }
-
- pmap->base_port = pmap->last_alloc =
- ((glusterd_conf_t *)(this->private))->base_port;
-
- return pmap;
-}
-
-
-struct pmap_registry *
-pmap_registry_get (xlator_t *this)
-{
- glusterd_conf_t *priv = NULL;
- struct pmap_registry *pmap = NULL;
-
- priv = this->private;
-
- pmap = priv->pmap;
- if (!pmap) {
- pmap = pmap_registry_new (this);
- if (!pmap)
- return NULL;
- priv->pmap = pmap;
- }
-
- return pmap;
-}
-
-
-static char*
-nextword (char *str)
-{
- while (*str && !isspace (*str))
- str++;
- while (*str && isspace (*str))
- str++;
-
- return str;
-}
-
-int
-pmap_registry_search (xlator_t *this, const char *brickname,
- gf_pmap_port_type_t type)
-{
- struct pmap_registry *pmap = NULL;
- int p = 0;
- char *brck = NULL;
- char *nbrck = NULL;
-
- pmap = pmap_registry_get (this);
-
- for (p = pmap->base_port; p <= pmap->last_alloc; p++) {
- if (!pmap->ports[p].brickname || pmap->ports[p].type != type)
- continue;
-
- for (brck = pmap->ports[p].brickname;;) {
- nbrck = strtail (brck, brickname);
- if (nbrck && (!*nbrck || isspace (*nbrck)))
- return p;
- brck = nextword (brck);
- if (!*brck)
- break;
- }
- }
-
- return 0;
-}
-
-int
-pmap_registry_search_by_xprt (xlator_t *this, void *xprt,
- gf_pmap_port_type_t type)
-{
- struct pmap_registry *pmap = NULL;
- int p = 0;
- int port = 0;
-
- pmap = pmap_registry_get (this);
-
- for (p = pmap->base_port; p <= pmap->last_alloc; p++) {
- if (!pmap->ports[p].xprt)
- continue;
- if (pmap->ports[p].xprt == xprt &&
- pmap->ports[p].type == type) {
- port = p;
- break;
- }
- }
-
- return port;
-}
-
-
-char *
-pmap_registry_search_by_port (xlator_t *this, int port)
-{
- struct pmap_registry *pmap = NULL;
- char *brickname = NULL;
-
- if (port > 65535)
- goto out;
-
- pmap = pmap_registry_get (this);
-
- if (pmap->ports[port].type == GF_PMAP_PORT_BRICKSERVER)
- brickname = pmap->ports[port].brickname;
-
-out:
- return brickname;
-}
-
-
-int
-pmap_registry_alloc (xlator_t *this)
-{
- struct pmap_registry *pmap = NULL;
- int p = 0;
- int port = 0;
-
- pmap = pmap_registry_get (this);
-
- for (p = pmap->last_alloc; p < 65535; p++) {
- if (pmap->ports[p].type != GF_PMAP_PORT_FREE)
- continue;
-
- if (pmap_port_isfree (p)) {
- pmap->ports[p].type = GF_PMAP_PORT_LEASED;
- port = p;
- break;
- }
- }
-
- if (port)
- pmap->last_alloc = port;
-
- return port;
-}
-
-int
-pmap_registry_bind (xlator_t *this, int port, const char *brickname,
- gf_pmap_port_type_t type, void *xprt)
-{
- struct pmap_registry *pmap = NULL;
- int p = 0;
-
- pmap = pmap_registry_get (this);
-
- if (port > 65535)
- goto out;
-
- p = port;
- pmap->ports[p].type = type;
- free (pmap->ports[p].brickname);
- pmap->ports[p].brickname = strdup (brickname);
- pmap->ports[p].type = type;
- pmap->ports[p].xprt = xprt;
-
- gf_log ("pmap", GF_LOG_INFO, "adding brick %s on port %d",
- brickname, port);
-
- if (pmap->last_alloc < p)
- pmap->last_alloc = p;
-out:
- return 0;
-}
-
-int
-pmap_registry_remove (xlator_t *this, int port, const char *brickname,
- gf_pmap_port_type_t type, void *xprt)
-{
- struct pmap_registry *pmap = NULL;
- int p = 0;
- glusterd_conf_t *priv = NULL;
-
- priv = this->private;
- pmap = priv->pmap;
- if (!pmap)
- goto out;
-
- if (port) {
- if (port > 65535)
- goto out;
-
- p = port;
- goto remove;
- }
-
- if (brickname && strchr (brickname, '/')) {
- p = pmap_registry_search (this, brickname, type);
- if (p)
- goto remove;
- }
-
- if (xprt) {
- p = pmap_registry_search_by_xprt (this, xprt, type);
- if (p)
- goto remove;
- }
-
- goto out;
-remove:
- gf_log ("pmap", GF_LOG_INFO, "removing brick %s on port %d",
- pmap->ports[p].brickname, p);
-
- free (pmap->ports[p].brickname);
-
- pmap->ports[p].brickname = NULL;
- pmap->ports[p].xprt = NULL;
-
-out:
- return 0;
-}
-
-int
-__gluster_pmap_portbybrick (rpcsvc_request_t *req)
-{
- pmap_port_by_brick_req args = {0,};
- pmap_port_by_brick_rsp rsp = {0,};
- char *brick = NULL;
- int port = 0;
- int ret = -1;
-
- ret = xdr_to_generic (req->msg[0], &args,
- (xdrproc_t)xdr_pmap_port_by_brick_req);
- if (ret < 0) {
- req->rpc_err = GARBAGE_ARGS;
- goto fail;
- }
-
- brick = args.brick;
-
- port = pmap_registry_search (THIS, brick, GF_PMAP_PORT_BRICKSERVER);
-
- if (!port)
- rsp.op_ret = -1;
-
- rsp.port = port;
-
-fail:
- glusterd_submit_reply (req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_pmap_port_by_brick_rsp);
- free (args.brick);//malloced by xdr
-
- return 0;
-}
-
-
-int
-gluster_pmap_portbybrick (rpcsvc_request_t *req)
-{
- return glusterd_big_locked_handler (req, __gluster_pmap_portbybrick);
-}
-
-
-int
-__gluster_pmap_brickbyport (rpcsvc_request_t *req)
-{
- pmap_brick_by_port_req args = {0,};
- pmap_brick_by_port_rsp rsp = {0,};
- int ret = -1;
-
- ret = xdr_to_generic (req->msg[0], &args,
- (xdrproc_t)xdr_pmap_brick_by_port_req);
- if (ret < 0) {
- req->rpc_err = GARBAGE_ARGS;
- goto fail;
- }
-
- rsp.brick = pmap_registry_search_by_port (THIS, args.port);
- if (!rsp.brick) {
- rsp.op_ret = -1;
- rsp.brick = "";
- }
-fail:
-
- glusterd_submit_reply (req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_pmap_brick_by_port_rsp);
-
- return 0;
-}
-
-
-int
-gluster_pmap_brickbyport (rpcsvc_request_t *req)
-{
- return glusterd_big_locked_handler (req, __gluster_pmap_brickbyport);
-}
-
-
-static int
-glusterd_brick_update_signin (glusterd_brickinfo_t *brickinfo,
- gf_boolean_t value)
-{
- brickinfo->signed_in = value;
-
- return 0;
-}
-
-int
-__gluster_pmap_signup (rpcsvc_request_t *req)
-{
- pmap_signup_req args = {0,};
- pmap_signup_rsp rsp = {0,};
- int ret = -1;
-
-
- ret = xdr_to_generic (req->msg[0], &args,
- (xdrproc_t)xdr_pmap_signup_req);
- if (ret < 0) {
- req->rpc_err = GARBAGE_ARGS;
- goto fail;
- }
-
- rsp.op_ret = pmap_registry_bind (THIS, args.port, args.brick,
- GF_PMAP_PORT_BRICKSERVER, req->trans);
-
-fail:
- glusterd_submit_reply (req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_pmap_signup_rsp);
- free (args.brick);//malloced by xdr
-
- return 0;
-}
-
-int
-gluster_pmap_signup (rpcsvc_request_t *req)
-{
- return glusterd_big_locked_handler (req, __gluster_pmap_signup);
-}
-
-int
-__gluster_pmap_signin (rpcsvc_request_t *req)
-{
- pmap_signin_req args = {0,};
- pmap_signin_rsp rsp = {0,};
- glusterd_brickinfo_t *brickinfo = NULL;
- int ret = -1;
-
- ret = xdr_to_generic (req->msg[0], &args,
- (xdrproc_t)xdr_pmap_signin_req);
- if (ret < 0) {
- req->rpc_err = GARBAGE_ARGS;
- goto fail;
- }
-
- rsp.op_ret = pmap_registry_bind (THIS, args.port, args.brick,
- GF_PMAP_PORT_BRICKSERVER, req->trans);
-
- ret = glusterd_get_brickinfo (THIS, args.brick, args.port, _gf_true,
- &brickinfo);
-fail:
- glusterd_submit_reply (req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_pmap_signin_rsp);
- free (args.brick);//malloced by xdr
-
- if (!ret)
- glusterd_brick_update_signin (brickinfo, _gf_true);
-
- return 0;
-}
-
-
-int
-gluster_pmap_signin (rpcsvc_request_t *req)
-{
- return glusterd_big_locked_handler (req, __gluster_pmap_signin);
-}
-
-
-int
-__gluster_pmap_signout (rpcsvc_request_t *req)
-{
- pmap_signout_req args = {0,};
- pmap_signout_rsp rsp = {0,};
- int ret = -1;
- char brick_path[PATH_MAX] = {0,};
- glusterd_brickinfo_t *brickinfo = NULL;
-
- ret = xdr_to_generic (req->msg[0], &args,
- (xdrproc_t)xdr_pmap_signout_req);
- if (ret < 0) {
- //failed to decode msg;
- req->rpc_err = GARBAGE_ARGS;
- goto fail;
- }
-
- rsp.op_ret = pmap_registry_remove (THIS, args.port, args.brick,
- GF_PMAP_PORT_BRICKSERVER, req->trans);
-
- ret = glusterd_get_brickinfo (THIS, args.brick, args.port, _gf_true,
- &brickinfo);
- if (args.rdma_port) {
- snprintf(brick_path, PATH_MAX, "%s.rdma", args.brick);
- rsp.op_ret = pmap_registry_remove (THIS, args.rdma_port,
- brick_path, GF_PMAP_PORT_BRICKSERVER,
- req->trans);
- }
-
- if (!ret)
- glusterd_brick_update_signin (brickinfo, _gf_false);
-
-fail:
- glusterd_submit_reply (req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_pmap_signout_rsp);
- free (args.brick);//malloced by xdr
-
- return 0;
-}
-
-int
-gluster_pmap_signout (rpcsvc_request_t *req)
-{
- return glusterd_big_locked_handler (req, __gluster_pmap_signout);
-}
-
-rpcsvc_actor_t gluster_pmap_actors[GF_PMAP_MAXVALUE] = {
- [GF_PMAP_NULL] = {"NULL", GF_PMAP_NULL, NULL, NULL, 0, DRC_NA},
- [GF_PMAP_PORTBYBRICK] = {"PORTBYBRICK", GF_PMAP_PORTBYBRICK, gluster_pmap_portbybrick, NULL, 0, DRC_NA},
- [GF_PMAP_BRICKBYPORT] = {"BRICKBYPORT", GF_PMAP_BRICKBYPORT, gluster_pmap_brickbyport, NULL, 0, DRC_NA},
- [GF_PMAP_SIGNUP] = {"SIGNUP", GF_PMAP_SIGNUP, gluster_pmap_signup, NULL, 0, DRC_NA},
- [GF_PMAP_SIGNIN] = {"SIGNIN", GF_PMAP_SIGNIN, gluster_pmap_signin, NULL, 0, DRC_NA},
- [GF_PMAP_SIGNOUT] = {"SIGNOUT", GF_PMAP_SIGNOUT, gluster_pmap_signout, NULL, 0, DRC_NA},
-};
-
-
-struct rpcsvc_program gluster_pmap_prog = {
- .progname = "Gluster Portmap",
- .prognum = GLUSTER_PMAP_PROGRAM,
- .progver = GLUSTER_PMAP_VERSION,
- .actors = gluster_pmap_actors,
- .numactors = GF_PMAP_MAXVALUE,
-};
diff --git a/xlators/mgmt/glusterd/src/glusterd-pmap.h b/xlators/mgmt/glusterd/src/glusterd-pmap.h
deleted file mode 100644
index 6336ee998fd..00000000000
--- a/xlators/mgmt/glusterd/src/glusterd-pmap.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- Copyright (c) 2010-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 _GLUSTERD_PMAP_H_
-#define _GLUSTERD_PMAP_H_
-
-#ifndef _CONFIG_H
-#define _CONFIG_H
-#include "config.h"
-#endif
-
-#include <pthread.h>
-#include "uuid.h"
-
-#include "glusterfs.h"
-#include "xlator.h"
-#include "logging.h"
-#include "call-stub.h"
-#include "fd.h"
-#include "byte-order.h"
-#include "glusterd.h"
-#include "rpcsvc.h"
-
-
-#define GF_IANA_PRIV_PORTS_START 49152 /* RFC 6335 */
-
-struct pmap_port_status {
- gf_pmap_port_type_t type;
- char *brickname;
- void *xprt;
-};
-
-struct pmap_registry {
- int base_port;
- int last_alloc;
- struct pmap_port_status ports[65536];
-};
-
-int pmap_registry_alloc (xlator_t *this);
-int pmap_registry_bind (xlator_t *this, int port, const char *brickname,
- gf_pmap_port_type_t type, void *xprt);
-int pmap_registry_remove (xlator_t *this, int port, const char *brickname,
- gf_pmap_port_type_t type, void *xprt);
-int pmap_registry_search (xlator_t *this, const char *brickname,
- gf_pmap_port_type_t type);
-struct pmap_registry *pmap_registry_get (xlator_t *this);
-
-#endif
diff --git a/xlators/mgmt/glusterd/src/glusterd-quota.c b/xlators/mgmt/glusterd/src/glusterd-quota.c
deleted file mode 100644
index b578ef73ae7..00000000000
--- a/xlators/mgmt/glusterd/src/glusterd-quota.c
+++ /dev/null
@@ -1,1473 +0,0 @@
-/*
- Copyright (c) 2011-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 "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 "byte-order.h"
-#include "compat-errno.h"
-
-#include <sys/wait.h>
-#include <dlfcn.h>
-
-#ifndef _PATH_SETFATTR
-# ifdef GF_LINUX_HOST_OS
-# define _PATH_SETFATTR "/usr/bin/setfattr"
-# endif
-# ifdef __NetBSD__
-# define _PATH_SETFATTR "/usr/pkg/bin/setfattr"
-# endif
-#endif
-
-/* Any negative pid to make it special client */
-#define QUOTA_CRAWL_PID "-100"
-
-const char *gd_quota_op_list[GF_QUOTA_OPTION_TYPE_DEFAULT_SOFT_LIMIT+1] = {
- [GF_QUOTA_OPTION_TYPE_NONE] = "none",
- [GF_QUOTA_OPTION_TYPE_ENABLE] = "enable",
- [GF_QUOTA_OPTION_TYPE_DISABLE] = "disable",
- [GF_QUOTA_OPTION_TYPE_LIMIT_USAGE] = "limit-usage",
- [GF_QUOTA_OPTION_TYPE_REMOVE] = "remove",
- [GF_QUOTA_OPTION_TYPE_LIST] = "list",
- [GF_QUOTA_OPTION_TYPE_VERSION] = "version",
- [GF_QUOTA_OPTION_TYPE_ALERT_TIME] = "alert-time",
- [GF_QUOTA_OPTION_TYPE_SOFT_TIMEOUT] = "soft-timeout",
- [GF_QUOTA_OPTION_TYPE_HARD_TIMEOUT] = "hard-timeout",
- [GF_QUOTA_OPTION_TYPE_DEFAULT_SOFT_LIMIT] = "default-soft-limit",
-};
-
-int
-glusterd_store_quota_config (glusterd_volinfo_t *volinfo, char *path,
- char *gfid_str, int opcode, char **op_errstr);
-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 *volname = NULL;
- int32_t type = 0;
- char msg[2048] = {0,};
- xlator_t *this = NULL;
- glusterd_conf_t *conf = NULL;
-
- GF_ASSERT (req);
- this = THIS;
- GF_ASSERT (this);
- conf = this->private;
- GF_ASSERT (conf);
-
- ret = xdr_to_generic (req->msg[0], &cli_req, (xdrproc_t)xdr_gf_cli_req);
- if (ret < 0) {
- //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");
- snprintf (msg, sizeof (msg), "Unable to decode the "
- "command");
- goto out;
- } else {
- dict->extra_stdfree = cli_req.dict.dict_val;
- }
- }
-
- ret = dict_get_str (dict, "volname", &volname);
- if (ret) {
- snprintf (msg, sizeof (msg), "Unable to get volume name");
- gf_log (this->name, GF_LOG_ERROR, "Unable to get volume name, "
- "while handling quota command");
- goto out;
- }
-
- ret = dict_get_int32 (dict, "type", &type);
- if (ret) {
- snprintf (msg, sizeof (msg), "Unable to get type of command");
- gf_log (this->name, GF_LOG_ERROR, "Unable to get type of cmd, "
- "while handling quota command");
- goto out;
- }
-
- if ((conf->op_version == GD_OP_VERSION_MIN) &&
- (type > GF_QUOTA_OPTION_TYPE_VERSION)) {
- snprintf (msg, sizeof (msg), "Cannot execute command. The "
- "cluster is operating at version %d. Quota command %s "
- "is unavailable in this version", conf->op_version,
- gd_quota_op_list[type]);
- ret = -1;
- goto out;
- }
-
- ret = glusterd_op_begin_synctask (req, GD_OP_QUOTA, dict);
-
-out:
- if (ret) {
- if (msg[0] == '\0')
- snprintf (msg, sizeof (msg), "Operation failed");
- ret = glusterd_op_send_cli_response (cli_op, ret, 0, req,
- dict, msg);
- }
-
- return ret;
-}
-
-int
-glusterd_handle_quota (rpcsvc_request_t *req)
-{
- return glusterd_big_locked_handler (req, __glusterd_handle_quota);
-}
-
-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) {
- ret = -1;
- goto out;
- }
- ret = 0;
-out:
- return ret;
-}
-
-int32_t
-glusterd_quota_initiate_fs_crawl (glusterd_conf_t *priv, char *volname,
- int type)
-{
- 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,
- "--use-readdirp=no",
- "--client-pid", QUOTA_CRAWL_PID,
- "-l", DEFAULT_LOG_FILE_DIRECTORY"/quota-crawl.log",
- mountdir, NULL);
-
- synclock_unlock (&priv->big_lock);
- ret = runner_run_reuse (&runner);
- synclock_lock (&priv->big_lock);
- 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);
-
- if (type == GF_QUOTA_OPTION_TYPE_ENABLE)
- runner_add_args (&runner, "/usr/bin/find", ".",
- "-exec", "/usr/bin/stat",
- "{}", "\\", ";", NULL);
-
- else if (type == GF_QUOTA_OPTION_TYPE_DISABLE) {
-
-#if defined(GF_DARWIN_HOST_OS)
- runner_add_args (&runner, "/usr/bin/find", ".",
- "-exec", "/usr/bin/xattr", "-w",
- VIRTUAL_QUOTA_XATTR_CLEANUP_KEY, "1",
- "{}", "\\", ";", NULL);
-#elif defined(__FreeBSD__)
- runner_add_args (&runner, "/usr/bin/find", ".",
- "-exec", "/usr/sbin/setextattr",
- EXTATTR_NAMESPACE_USER,
- VIRTUAL_QUOTA_XATTR_CLEANUP_KEY, "1",
- "{}", "\\", ";", NULL);
-#else
- runner_add_args (&runner, "/usr/bin/find", ".",
- "-exec", _PATH_SETFATTR, "-n",
- VIRTUAL_QUOTA_XATTR_CLEANUP_KEY, "-v",
- "1", "{}", "\\", ";", NULL);
-#endif
-
- }
-
- if (runner_start (&runner) == -1)
- _exit (EXIT_FAILURE);
-
-#ifndef GF_LINUX_HOST_OS
- runner_end (&runner); /* blocks in waitpid */
-#endif
- gf_umount_lazy ("glusterd", mountdir, 1);
-
- _exit (EXIT_SUCCESS);
- }
- ret = (waitpid (pid, &status, 0) == pid &&
- WIFEXITED (status) && WEXITSTATUS (status) == EXIT_SUCCESS) ? 0 : -1;
-
-out:
- return ret;
-}
-
-int32_t
-glusterd_quota_get_default_soft_limit (glusterd_volinfo_t *volinfo,
- dict_t *rsp_dict)
-{
- int32_t ret = 0;
- xlator_t *this = NULL;
- glusterd_conf_t *conf = NULL;
- char *default_limit = NULL;
- char *val = NULL;
-
- if (rsp_dict == NULL)
- return -1;
-
- this = THIS;
- GF_ASSERT (this);
- conf = this->private;
- GF_ASSERT (conf);
-
- ret = glusterd_volinfo_get (volinfo, "features.default-soft-limit",
- &default_limit);
- if (default_limit)
- val = gf_strdup (default_limit);
- else
- val = gf_strdup ("80%");
-
- ret = dict_set_dynstr (rsp_dict, "default-soft-limit", val);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to set default "
- "soft-limit into dict");
- goto out;
- }
- ret = 0;
-
-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;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
-
- GF_VALIDATE_OR_GOTO (this->name, volinfo, out);
- GF_VALIDATE_OR_GOTO (this->name, crawl, out);
- GF_VALIDATE_OR_GOTO (this->name, op_errstr, out);
-
- if (glusterd_is_volume_started (volinfo) == 0) {
- *op_errstr = gf_strdup ("Volume is stopped, start volume "
- "to enable quota.");
- ret = -1;
- goto out;
- }
-
- ret = glusterd_check_if_quota_trans_enabled (volinfo);
- if (ret == 0) {
- *op_errstr = gf_strdup ("Quota is already enabled");
- ret = -1;
- goto out;
- }
-
- quota_status = gf_strdup ("on");
- if (!quota_status) {
- gf_log (this->name, GF_LOG_ERROR, "memory allocation failed");
- ret = -1;
- goto out;
- }
-
- ret = dict_set_dynstr (volinfo->dict, VKEY_FEATURES_QUOTA,
- quota_status);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "dict set failed");
- goto out;
- }
-
- *crawl = _gf_true;
-
- ret = glusterd_store_quota_config (volinfo, NULL, NULL,
- GF_QUOTA_OPTION_TYPE_ENABLE,
- op_errstr);
-
- ret = 0;
-out:
- if (ret && op_errstr && !*op_errstr)
- gf_asprintf (op_errstr, "Enabling quota on volume %s has been "
- "unsuccessful", volinfo->volname);
- return ret;
-}
-
-int32_t
-glusterd_quota_disable (glusterd_volinfo_t *volinfo, char **op_errstr,
- gf_boolean_t *crawl)
-{
- int32_t ret = -1;
- int i = 0;
- char *quota_status = NULL;
- char *value = NULL;
- xlator_t *this = NULL;
- glusterd_conf_t *conf = NULL;
- char *quota_options[] = {"features.soft-timeout",
- "features.hard-timeout",
- "features.alert-time",
- "features.default-soft-limit",
- "features.quota-deem-statfs",
- "features.quota-timeout", NULL};
-
- this = THIS;
- GF_ASSERT (this);
- conf = this->private;
- GF_ASSERT (conf);
-
- GF_VALIDATE_OR_GOTO (this->name, volinfo, out);
- GF_VALIDATE_OR_GOTO (this->name, 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 (this->name, GF_LOG_ERROR, "memory allocation failed");
- ret = -1;
- goto out;
- }
-
- ret = dict_set_dynstr (volinfo->dict, VKEY_FEATURES_QUOTA, quota_status);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "dict set failed");
- goto out;
- }
-
- for (i = 0; quota_options [i]; i++) {
- ret = glusterd_volinfo_get (volinfo, quota_options[i], &value);
- if (ret) {
- gf_log (this->name, GF_LOG_INFO, "failed to get option"
- " %s",
- quota_options[i]);
- } else {
- dict_del (volinfo->dict, quota_options[i]);
- }
- }
-
- //Remove aux mount of the volume on every node in the cluster
- ret = glusterd_remove_auxiliary_mount (volinfo->volname);
- if (ret)
- goto out;
-
- *crawl = _gf_true;
-
- (void) glusterd_clean_up_quota_store (volinfo);
-
- ret = 0;
-out:
- if (ret && op_errstr && !*op_errstr)
- gf_asprintf (op_errstr, "Disabling quota on volume %s has been "
- "unsuccessful", volinfo->volname);
- return ret;
-}
-
-
-static int
-glusterd_set_quota_limit (char *volname, char *path, char *hard_limit,
- char *soft_limit, char **op_errstr)
-{
- int ret = -1;
- xlator_t *this = NULL;
- char abspath[PATH_MAX] = {0,};
- glusterd_conf_t *priv = NULL;
- double soft_lim = 0;
-
- typedef struct quota_limits {
- int64_t hl;
- int64_t sl;
- } __attribute__ ((__packed__)) quota_limits_t;
-
- quota_limits_t existing_limit = {0,};
- quota_limits_t new_limit = {0,};
-
- this = THIS;
- GF_ASSERT (this);
- priv = this->private;
- GF_ASSERT (priv);
-
- GLUSTERD_GET_QUOTA_AUX_MOUNT_PATH (abspath, volname, path);
- ret = gf_lstat_dir (abspath, NULL);
- if (ret) {
- gf_asprintf (op_errstr, "Failed to find the directory %s. "
- "Reason : %s", abspath, strerror (errno));
- goto out;
- }
-
- if (!soft_limit) {
- ret = sys_lgetxattr (abspath,
- "trusted.glusterfs.quota.limit-set",
- (void *)&existing_limit,
- sizeof (existing_limit));
- if (ret < 0) {
- switch (errno) {
-#if defined(ENOATTR) && (ENOATTR != ENODATA)
- case ENODATA: /* FALLTHROUGH */
-#endif
- case ENOATTR:
- existing_limit.sl = -1;
- break;
- default:
- gf_asprintf (op_errstr, "Failed to get the xattr "
- "'trusted.glusterfs.quota.limit-set' from "
- "%s. Reason : %s", abspath,
- strerror (errno));
- goto out;
- }
- } else {
- existing_limit.hl = ntoh64 (existing_limit.hl);
- existing_limit.sl = ntoh64 (existing_limit.sl);
- }
- new_limit.sl = existing_limit.sl;
-
- } else {
- ret = gf_string2percent (soft_limit, &soft_lim);
- if (ret)
- goto out;
- new_limit.sl = soft_lim;
- }
-
- new_limit.sl = hton64 (new_limit.sl);
-
- ret = gf_string2bytesize_uint64 (hard_limit, (uint64_t*)&new_limit.hl);
- if (ret)
- goto out;
-
- new_limit.hl = hton64 (new_limit.hl);
-
- ret = sys_lsetxattr (abspath, "trusted.glusterfs.quota.limit-set",
- (char *)(void *)&new_limit, sizeof (new_limit), 0);
- if (ret == -1) {
- gf_asprintf (op_errstr, "setxattr of "
- "'trusted.glusterfs.quota.limit-set' failed on %s."
- " Reason : %s", abspath, strerror (errno));
- goto out;
- }
- ret = 0;
-
-out:
- return ret;
-}
-
-static int
-glusterd_update_quota_conf_version (glusterd_volinfo_t *volinfo)
-{
- volinfo->quota_conf_version++;
- return 0;
-}
-
-/*The function glusterd_find_gfid_match () does the following:
- * Given a buffer of gfids, the number of bytes read and the key gfid that needs
- * to be found, the function compares 16 bytes at a time from @buf against
- * @gfid.
- *
- * What happens when the match is found:
- * i. If the function was called as part of 'limit-usage' operation, the call
- * returns with write_byte_count = bytes_read
- *ii. If the function as called as part of 'quota remove' operation, @buf
- * is modified in memory such that the match is deleted from the buffer, and
- * also @write_byte_count is set to original buf size minus the sixteen bytes
- * that was deleted as part of 'remove'.
- *
- * What happens when the match is not found in the current buffer:
- * The function returns with write_byte_count = bytes_read, which means to say
- * that the caller of this function must write the entire buffer to the tmp file
- * and continue the search.
- */
-static gf_boolean_t
-glusterd_find_gfid_match (uuid_t gfid, unsigned char *buf, size_t bytes_read,
- int opcode, size_t *write_byte_count)
-{
- int gfid_index = 0;
- int shift_count = 0;
- unsigned char tmp_buf[17] = {0,};
-
- while (gfid_index != bytes_read) {
- memcpy ((void *)tmp_buf, (void *)&buf[gfid_index], 16);
- if (!uuid_compare (gfid, tmp_buf)) {
- if (opcode == GF_QUOTA_OPTION_TYPE_REMOVE) {
- shift_count = bytes_read - (gfid_index + 16);
- memmove ((void *)&buf[gfid_index],
- (void *)&buf[gfid_index+16],
- shift_count);
- *write_byte_count = bytes_read - 16;
- } else {
- *write_byte_count = bytes_read;
- }
- return _gf_true;
- } else {
- gfid_index+=16;
- }
- }
- if (gfid_index == bytes_read)
- *write_byte_count = bytes_read;
-
- return _gf_false;
-}
-
-/* The function glusterd_copy_to_tmp_file() reads the "remaining" bytes from
- * the source fd and writes them to destination fd, at the rate of 128K bytes
- * of read+write at a time.
- */
-
-static int
-glusterd_copy_to_tmp_file (int src_fd, int dst_fd)
-{
- int ret = 0;
- size_t entry_sz = 131072;
- ssize_t bytes_read = 0;
- unsigned char buf[131072] = {0,};
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
-
- while ((bytes_read = read (src_fd, (void *)&buf, entry_sz)) > 0) {
- if (bytes_read % 16 != 0) {
- gf_log (this->name, GF_LOG_ERROR, "quota.conf "
- "corrupted");
- ret = -1;
- goto out;
- }
- ret = write (dst_fd, (void *) buf, bytes_read);
- if (ret == -1) {
- gf_log (this->name, GF_LOG_ERROR,
- "write into quota.conf failed. Reason : %s",
- strerror (errno));
- goto out;
- }
- }
- ret = 0;
-
-out:
- return ret;
-}
-
-int
-glusterd_store_quota_config (glusterd_volinfo_t *volinfo, char *path,
- char *gfid_str, int opcode, char **op_errstr)
-{
- int ret = -1;
- int fd = -1;
- int conf_fd = -1;
- size_t entry_sz = 131072;
- ssize_t bytes_read = 0;
- size_t bytes_to_write = 0;
- unsigned char buf[131072] = {0,};
- uuid_t gfid = {0,};
- xlator_t *this = NULL;
- gf_boolean_t found = _gf_false;
- gf_boolean_t modified = _gf_false;
- gf_boolean_t is_file_empty = _gf_false;
- gf_boolean_t is_first_read = _gf_true;
- glusterd_conf_t *conf = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- conf = this->private;
- GF_ASSERT (conf);
-
- glusterd_store_create_quota_conf_sh_on_absence (volinfo);
-
- fd = gf_store_mkstemp (volinfo->quota_conf_shandle);
- if (fd < 0) {
- ret = -1;
- goto out;
- }
-
- conf_fd = open (volinfo->quota_conf_shandle->path, O_RDONLY);
- if (conf_fd == -1) {
- ret = -1;
- goto out;
- }
-
- ret = glusterd_store_quota_conf_skip_header (this, conf_fd);
- if (ret) {
- goto out;
- }
-
- ret = glusterd_store_quota_conf_stamp_header (this, fd);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to add header to tmp "
- "file.");
- goto out;
- }
-
- /* Just create empty quota.conf file if create */
- if (GF_QUOTA_OPTION_TYPE_ENABLE == opcode) {
- modified = _gf_true;
- goto out;
- }
-
- /* Check if gfid_str is given for opts other than ENABLE */
- if (!gfid_str) {
- ret = -1;
- goto out;
- }
- uuid_parse (gfid_str, gfid);
-
- for (;;) {
- bytes_read = read (conf_fd, (void*)&buf, entry_sz);
- if (bytes_read <= 0) {
- /*The flag @is_first_read is TRUE when the loop is
- * entered, and is set to false if the first read
- * reads non-zero bytes of data. The flag is used to
- * detect if quota.conf is an empty file, but for the
- * header. This is done to log appropriate error message
- * when 'quota remove' is attempted when there are no
- * limits set on the given volume.
- */
- if (is_first_read)
- is_file_empty = _gf_true;
- break;
- }
- if ((bytes_read % 16) != 0) {
- gf_log (this->name, GF_LOG_ERROR, "quota.conf "
- "corrupted");
- ret = -1;
- goto out;
- }
- found = glusterd_find_gfid_match (gfid, buf, bytes_read, opcode,
- &bytes_to_write);
-
- ret = write (fd, (void *) buf, bytes_to_write);
- if (ret == -1) {
- gf_log (this->name, GF_LOG_ERROR,
- "write into quota.conf failed. Reason : %s",
- strerror (errno));
- goto out;
- }
-
- /*If the match is found in this iteration, copy the rest of
- * quota.conf into quota.conf.tmp and break.
- * Else continue with the search.
- */
- if (found) {
- ret = glusterd_copy_to_tmp_file (conf_fd, fd);
- if (ret)
- goto out;
- break;
- }
- is_first_read = _gf_false;
- }
-
- switch (opcode) {
- case GF_QUOTA_OPTION_TYPE_LIMIT_USAGE:
- if (!found) {
- ret = write (fd, gfid, 16);
- if (ret == -1) {
- gf_log (this->name, GF_LOG_ERROR,
- "write into quota.conf failed. "
- "Reason : %s",
- strerror (errno));
- goto out;
- }
- modified = _gf_true;
- }
- break;
-
- case GF_QUOTA_OPTION_TYPE_REMOVE:
- if (is_file_empty) {
- gf_asprintf (op_errstr, "Cannot remove limit on"
- " %s. The quota configuration file"
- " for volume %s is empty.", path,
- volinfo->volname);
- ret = -1;
- goto out;
- } else {
- if (!found) {
- gf_asprintf (op_errstr, "Error. gfid %s"
- " for path %s not found in"
- " store", gfid_str, path);
- ret = -1;
- goto out;
- } else {
- modified = _gf_true;
- }
- }
- break;
-
- default:
- ret = 0;
- break;
- }
-
- if (modified)
- glusterd_update_quota_conf_version (volinfo);
-
- ret = 0;
-out:
- if (conf_fd != -1) {
- close (conf_fd);
- }
-
- if (ret && (fd > 0)) {
- gf_store_unlink_tmppath (volinfo->quota_conf_shandle);
- } else if (!ret) {
- ret = gf_store_rename_tmppath (volinfo->quota_conf_shandle);
- if (modified) {
- ret = glusterd_compute_cksum (volinfo, _gf_true);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to "
- "compute cksum for quota conf file");
- return ret;
- }
-
- ret = glusterd_store_save_quota_version_and_cksum
- (volinfo);
- if (ret)
- gf_log (this->name, GF_LOG_ERROR, "Failed to "
- "store quota version and cksum");
- }
- }
-
- return ret;
-}
-
-int32_t
-glusterd_quota_limit_usage (glusterd_volinfo_t *volinfo, dict_t *dict,
- int opcode, char **op_errstr)
-{
- int32_t ret = -1;
- char *path = NULL;
- char *hard_limit = NULL;
- char *soft_limit = NULL;
- char *gfid_str = NULL;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
-
- GF_VALIDATE_OR_GOTO (this->name, dict, out);
- GF_VALIDATE_OR_GOTO (this->name, volinfo, out);
- GF_VALIDATE_OR_GOTO (this->name, 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 = dict_get_str (dict, "path", &path);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Unable to fetch path");
- goto out;
- }
- ret = gf_canonicalize_path (path);
- if (ret)
- goto out;
-
- ret = dict_get_str (dict, "hard-limit", &hard_limit);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Unable to fetch hard limit");
- goto out;
- }
-
- if (dict_get (dict, "soft-limit")) {
- ret = dict_get_str (dict, "soft-limit", &soft_limit);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Unable to fetch "
- "soft limit");
- goto out;
- }
- }
-
- if (is_origin_glusterd (dict)) {
- ret = glusterd_set_quota_limit (volinfo->volname, path,
- hard_limit, soft_limit,
- op_errstr);
- if (ret)
- goto out;
- }
-
- ret = dict_get_str (dict, "gfid", &gfid_str);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to get gfid of path "
- "%s", path);
- goto out;
- }
-
- ret = glusterd_store_quota_config (volinfo, path, gfid_str, opcode,
- op_errstr);
- if (ret)
- goto out;
-
- ret = 0;
-out:
-
- if (ret && op_errstr && !*op_errstr)
- gf_asprintf (op_errstr, "Failed to set hard limit on path %s "
- "for volume %s", path, volinfo->volname);
- return ret;
-}
-
-static int
-glusterd_remove_quota_limit (char *volname, char *path, char **op_errstr)
-{
- int ret = -1;
- xlator_t *this = NULL;
- char abspath[PATH_MAX] = {0,};
- glusterd_conf_t *priv = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- priv = this->private;
- GF_ASSERT (priv);
-
- GLUSTERD_GET_QUOTA_AUX_MOUNT_PATH (abspath, volname, path);
- ret = gf_lstat_dir (abspath, NULL);
- if (ret) {
- gf_asprintf (op_errstr, "Failed to find the directory %s. "
- "Reason : %s", abspath, strerror (errno));
- goto out;
- }
-
- ret = sys_lremovexattr (abspath, "trusted.glusterfs.quota.limit-set");
- if (ret) {
- gf_asprintf (op_errstr, "removexattr failed on %s. Reason : %s",
- abspath, strerror (errno));
- goto out;
- }
- ret = 0;
-
-out:
- return ret;
-}
-
-int32_t
-glusterd_quota_remove_limits (glusterd_volinfo_t *volinfo, dict_t *dict,
- int opcode, char **op_errstr)
-{
- int32_t ret = -1;
- char *path = NULL;
- char *gfid_str = NULL;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
-
- GF_VALIDATE_OR_GOTO (this->name, dict, out);
- GF_VALIDATE_OR_GOTO (this->name, volinfo, out);
- GF_VALIDATE_OR_GOTO (this->name, 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 = dict_get_str (dict, "path", &path);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Unable to fetch path");
- goto out;
- }
-
- ret = gf_canonicalize_path (path);
- if (ret)
- goto out;
-
- if (is_origin_glusterd (dict)) {
- ret = glusterd_remove_quota_limit (volinfo->volname, path,
- op_errstr);
- if (ret)
- goto out;
- }
-
- ret = dict_get_str (dict, "gfid", &gfid_str);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to get gfid of path "
- "%s", path);
- goto out;
- }
-
- ret = glusterd_store_quota_config (volinfo, path, gfid_str, opcode,
- op_errstr);
- if (ret)
- goto out;
-
-
- ret = 0;
-
-out:
- return ret;
-}
-
-int
-glusterd_set_quota_option (glusterd_volinfo_t *volinfo, dict_t *dict,
- char *key, char **op_errstr)
-{
- int ret = 0;
- char *value = NULL;
- xlator_t *this = NULL;
- char *option = NULL;
-
- this = THIS;
- GF_ASSERT (this);
-
- ret = glusterd_check_if_quota_trans_enabled (volinfo);
- if (ret == -1) {
- gf_asprintf (op_errstr, "Cannot set %s. Quota on volume %s is "
- "disabled", key, volinfo->volname);
- return -1;
- }
-
- ret = dict_get_str (dict, "value", &value);
- if(ret) {
- gf_log (this->name, GF_LOG_ERROR, "Option value absent.");
- return -1;
- }
-
- option = gf_strdup (value);
- ret = dict_set_dynstr (volinfo->dict, key, option);
- if(ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to set option %s",
- key);
- return -1;
- }
-
- return 0;
-}
-
-static int
-glusterd_quotad_op (int opcode)
-{
- int ret = -1;
-
- switch (opcode) {
- case GF_QUOTA_OPTION_TYPE_ENABLE:
- case GF_QUOTA_OPTION_TYPE_DISABLE:
-
- if (glusterd_all_volumes_with_quota_stopped ())
- ret = glusterd_quotad_stop ();
- else
- ret = glusterd_check_generate_start_quotad_wait
- ();
- break;
-
- default:
- ret = 0;
- break;
- }
- return ret;
-}
-
-int
-glusterd_op_quota (dict_t *dict, char **op_errstr, dict_t *rsp_dict)
-{
- glusterd_volinfo_t *volinfo = NULL;
- int32_t ret = -1;
- char *volname = NULL;
- int type = -1;
- gf_boolean_t start_crawl = _gf_false;
- glusterd_conf_t *priv = NULL;
- xlator_t *this = NULL;
-
- GF_ASSERT (dict);
- GF_ASSERT (op_errstr);
-
- this = THIS;
- GF_ASSERT (this);
- priv = this->private;
- GF_ASSERT (priv);
-
- 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_asprintf (op_errstr, FMTSTR_CHECK_VOL_EXISTS, volname);
- goto out;
- }
-
- ret = dict_get_int32 (dict, "type", &type);
-
- if ((priv->op_version == GD_OP_VERSION_MIN) &&
- (type > GF_QUOTA_OPTION_TYPE_VERSION)) {
- gf_asprintf (op_errstr, "Volume quota failed. The cluster is "
- "operating at version %d. Quota command"
- " %s is unavailable in this version.",
- priv->op_version,
- gd_quota_op_list[type]);
- ret = -1;
- goto out;
- }
-
- switch (type) {
- case GF_QUOTA_OPTION_TYPE_ENABLE:
- ret = glusterd_quota_enable (volinfo, op_errstr,
- &start_crawl);
- if (ret < 0)
- goto out;
- break;
-
- case GF_QUOTA_OPTION_TYPE_DISABLE:
- ret = glusterd_quota_disable (volinfo, op_errstr,
- &start_crawl);
- if (ret < 0)
- goto out;
-
- break;
-
- case GF_QUOTA_OPTION_TYPE_LIMIT_USAGE:
- ret = glusterd_quota_limit_usage (volinfo, dict, type,
- op_errstr);
- goto out;
-
- case GF_QUOTA_OPTION_TYPE_REMOVE:
- ret = glusterd_quota_remove_limits (volinfo, dict, type,
- op_errstr);
- goto out;
-
- case GF_QUOTA_OPTION_TYPE_LIST:
- ret = glusterd_check_if_quota_trans_enabled (volinfo);
- if (ret == -1) {
- *op_errstr = gf_strdup ("Cannot list limits, "
- "quota is disabled");
- goto out;
- }
- ret = glusterd_quota_get_default_soft_limit (volinfo,
- rsp_dict);
- goto out;
-
- case GF_QUOTA_OPTION_TYPE_SOFT_TIMEOUT:
- ret = glusterd_set_quota_option (volinfo, dict,
- "features.soft-timeout",
- op_errstr);
- if (ret)
- goto out;
- break;
-
- case GF_QUOTA_OPTION_TYPE_HARD_TIMEOUT:
- ret = glusterd_set_quota_option (volinfo, dict,
- "features.hard-timeout",
- op_errstr);
- if (ret)
- goto out;
- break;
-
- case GF_QUOTA_OPTION_TYPE_ALERT_TIME:
- ret = glusterd_set_quota_option (volinfo, dict,
- "features.alert-time",
- op_errstr);
- if (ret)
- goto out;
- break;
-
- case GF_QUOTA_OPTION_TYPE_DEFAULT_SOFT_LIMIT:
- ret = glusterd_set_quota_option (volinfo, dict,
- "features.default-soft-limit",
- op_errstr);
- if (ret)
- goto out;
- break;
-
- default:
- gf_asprintf (op_errstr, "Quota command failed. Invalid "
- "opcode");
- ret = -1;
- goto out;
- }
-
- if (priv->op_version > GD_OP_VERSION_MIN) {
- ret = glusterd_quotad_op (type);
- if (ret)
- goto out;
- }
-
- ret = glusterd_create_volfiles_and_notify_services (volinfo);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Unable to re-create "
- "volfiles");
- ret = -1;
- goto out;
- }
-
- ret = glusterd_store_volinfo (volinfo, GLUSTERD_VOLINFO_VER_AC_INCREMENT);
- if (ret)
- goto out;
-
- if (GLUSTERD_STATUS_STARTED == volinfo->status) {
- if (priv->op_version == GD_OP_VERSION_MIN)
- ret = glusterd_check_generate_start_nfs ();
- }
-
- if (rsp_dict && start_crawl == _gf_true)
- glusterd_quota_initiate_fs_crawl (priv, volname, type);
-
- ret = 0;
-out:
- return ret;
-}
-
-/*
- * glusterd_get_gfid_from_brick() fetches the 'trusted.gfid' attribute of @path
- * from each brick in the backend and places the same in the rsp_dict with the
- * keys being gfid0, gfid1, gfid2 and so on. The absence of @path in the backend
- * is not treated as error.
- */
-static int
-glusterd_get_gfid_from_brick (dict_t *dict, glusterd_volinfo_t *volinfo,
- dict_t *rsp_dict, char **op_errstr)
-{
- int ret = -1;
- int count = 0;
- char *path = NULL;
- char backend_path[PATH_MAX] = {0,};
- xlator_t *this = NULL;
- glusterd_conf_t *priv = NULL;
- glusterd_brickinfo_t *brickinfo = NULL;
- char key[256] = {0,};
- char *gfid_str = NULL;
- uuid_t gfid;
-
- this = THIS;
- GF_ASSERT (this);
- priv = this->private;
- GF_ASSERT (priv);
-
- ret = dict_get_str (dict, "path", &path);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to get path");
- goto out;
- }
-
- list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) {
- ret = glusterd_resolve_brick (brickinfo);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, FMTSTR_RESOLVE_BRICK,
- brickinfo->hostname, brickinfo->path);
- goto out;
- }
-
- if (uuid_compare (brickinfo->uuid, MY_UUID))
- continue;
-
- if (brickinfo->vg[0])
- continue;
-
- snprintf (backend_path, sizeof (backend_path), "%s%s",
- brickinfo->path, path);
-
- ret = gf_lstat_dir (backend_path, NULL);
- if (ret) {
- gf_log (this->name, GF_LOG_INFO, "Failed to find "
- "directory %s. Reason : %s", backend_path,
- strerror (errno));
- ret = 0;
- continue;
- }
- ret = sys_lgetxattr (backend_path, GFID_XATTR_KEY, gfid, 16);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_INFO, "Failed to get "
- "extended attribute %s for directory %s. "
- "Reason : %s", GFID_XATTR_KEY, backend_path,
- strerror (errno));
- ret = 0;
- continue;
- }
- snprintf (key, sizeof (key), "gfid%d", count);
-
- gfid_str = gf_strdup (uuid_utoa (gfid));
- if (!gfid_str) {
- ret = -1;
- goto out;
- }
-
- ret = dict_set_dynstr (rsp_dict, key, gfid_str);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to place "
- "gfid of %s in dict", backend_path);
- GF_FREE (gfid_str);
- goto out;
- }
- count++;
- }
-
- ret = dict_set_int32 (rsp_dict, "count", count);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to set count");
- goto out;
- }
-
- ret = 0;
-out:
- return ret;
-}
-
-static int
-_glusterd_validate_quota_opts (dict_t *dict, int type, char **errstr)
-{
- int ret = -1;
- xlator_t *this = THIS;
- void *quota_xl = NULL;
- volume_opt_list_t opt_list = {{0},};
- volume_option_t *opt = NULL;
- char *key = NULL;
- char *value = NULL;
-
- GF_ASSERT (dict);
- GF_ASSERT (this);
-
- ret = xlator_volopt_dynload ("features/quota", &quota_xl, &opt_list);
- if (ret)
- goto out;
-
- switch (type) {
- case GF_QUOTA_OPTION_TYPE_SOFT_TIMEOUT:
- case GF_QUOTA_OPTION_TYPE_HARD_TIMEOUT:
- case GF_QUOTA_OPTION_TYPE_ALERT_TIME:
- case GF_QUOTA_OPTION_TYPE_DEFAULT_SOFT_LIMIT:
- key = (char *)gd_quota_op_list[type];
- break;
- default:
- ret = -1;
- goto out;
- }
-
- opt = xlator_volume_option_get_list (&opt_list, key);
- if (!opt) {
- ret = -1;
- gf_log (this->name, GF_LOG_ERROR, "Unknown option: %s", key);
- goto out;
- }
- ret = dict_get_str (dict, "value", &value);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Value not found for key %s",
- key);
- goto out;
- }
-
- ret = xlator_option_validate (this, key, value, opt, errstr);
-
-out:
- if (quota_xl) {
- dlclose (quota_xl);
- quota_xl = NULL;
- }
- return ret;
-}
-int
-glusterd_op_stage_quota (dict_t *dict, char **op_errstr, dict_t *rsp_dict)
-{
- int ret = 0;
- char *volname = NULL;
- gf_boolean_t exists = _gf_false;
- int type = 0;
- xlator_t *this = NULL;
- glusterd_conf_t *priv = NULL;
- glusterd_volinfo_t *volinfo = NULL;
- char *hard_limit_str = NULL;
- uint64_t hard_limit = 0;
-
- this = THIS;
- GF_ASSERT (this);
- priv = this->private;
- GF_ASSERT (priv);
-
- GF_ASSERT (dict);
- GF_ASSERT (op_errstr);
-
- ret = dict_get_str (dict, "volname", &volname);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Unable to get volume name");
- goto out;
- }
-
- exists = glusterd_check_volume_exists (volname);
- if (!exists) {
- gf_asprintf (op_errstr, FMTSTR_CHECK_VOL_EXISTS, volname);
- ret = -1;
- goto out;
- }
- ret = glusterd_volinfo_find (volname, &volinfo);
- if (ret) {
- gf_asprintf (op_errstr, FMTSTR_CHECK_VOL_EXISTS, volname);
- goto out;
- }
-
- if (!glusterd_is_volume_started (volinfo)) {
- *op_errstr = gf_strdup ("Volume is stopped, start volume "
- "before executing quota command.");
- ret = -1;
- goto out;
- }
-
- ret = dict_get_int32 (dict, "type", &type);
- if (ret) {
- *op_errstr = gf_strdup ("Volume quota failed, internal error, "
- "unable to get type of operation");
- goto out;
- }
-
- if ((!glusterd_is_volume_quota_enabled (volinfo)) &&
- (type != GF_QUOTA_OPTION_TYPE_ENABLE)) {
- *op_errstr = gf_strdup ("Quota is disabled, please enable "
- "quota");
- ret = -1;
- goto out;
- }
-
- if ((priv->op_version == GD_OP_VERSION_MIN) &&
- (type > GF_QUOTA_OPTION_TYPE_VERSION)) {
- gf_asprintf (op_errstr, "Volume quota failed. The cluster is "
- "operating at version %d. Quota command"
- " %s is unavailable in this version.",
- priv->op_version,
- gd_quota_op_list[type]);
- ret = -1;
- goto out;
- }
-
- if ((GF_QUOTA_OPTION_TYPE_ENABLE != type) &&
- (glusterd_check_if_quota_trans_enabled (volinfo) != 0)) {
- ret = -1;
- gf_asprintf (op_errstr, "Quota is not enabled on volume %s",
- volname);
- goto out;
- }
-
- switch (type) {
- case GF_QUOTA_OPTION_TYPE_ENABLE:
- case GF_QUOTA_OPTION_TYPE_LIST:
- /* Fuse mount req. only for enable & list-usage options*/
- if (is_origin_glusterd (dict) &&
- !glusterd_is_fuse_available ()) {
- *op_errstr = gf_strdup ("Fuse unavailable");
- ret = -1;
- goto out;
- }
- break;
-
- case GF_QUOTA_OPTION_TYPE_LIMIT_USAGE:
- ret = dict_get_str (dict, "hard-limit", &hard_limit_str);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Faild to get hard-limit from dict");
- goto out;
- }
- ret = gf_string2bytesize_uint64 (hard_limit_str, &hard_limit);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to convert hard-limit string to value");
- goto out;
- }
- if (hard_limit > UINT64_MAX) {
- ret = -1;
- ret = gf_asprintf (op_errstr, "Hard-limit %s is greater"
- " than %"PRId64"bytes. Please set a "
- "smaller limit.", hard_limit_str,
- INT64_MAX);
- gf_log (this->name, GF_LOG_ERROR, "hard-limit %s "
- "greater than INT64_MAX", hard_limit_str);
- goto out;
- }
- /*The break statement is missing here to allow intentional fall
- * through of code execution to the next switch case
- */
-
- case GF_QUOTA_OPTION_TYPE_REMOVE:
- ret = glusterd_get_gfid_from_brick (dict, volinfo, rsp_dict,
- op_errstr);
- if (ret)
- goto out;
- break;
-
- case GF_QUOTA_OPTION_TYPE_SOFT_TIMEOUT:
- case GF_QUOTA_OPTION_TYPE_HARD_TIMEOUT:
- case GF_QUOTA_OPTION_TYPE_ALERT_TIME:
- case GF_QUOTA_OPTION_TYPE_DEFAULT_SOFT_LIMIT:
- ret = _glusterd_validate_quota_opts (dict, type, op_errstr);
- if (ret)
- goto out;
- break;
-
- default:
- break;
- }
-
- ret = 0;
-
- out:
- if (ret && op_errstr && *op_errstr)
- gf_log (this->name, GF_LOG_ERROR, "%s", *op_errstr);
- gf_log (this->name, 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
deleted file mode 100644
index 1631290ad69..00000000000
--- a/xlators/mgmt/glusterd/src/glusterd-rebalance.c
+++ /dev/null
@@ -1,825 +0,0 @@
-/*
- Copyright (c) 2010-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 <inttypes.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include <sys/resource.h>
-#include <sys/statvfs.h>
-
-#include "globals.h"
-#include "compat.h"
-#include "protocol-common.h"
-#include "xlator.h"
-#include "logging.h"
-#include "timer.h"
-#include "glusterd-mem-types.h"
-#include "glusterd.h"
-#include "glusterd-sm.h"
-#include "glusterd-op-sm.h"
-#include "glusterd-utils.h"
-#include "glusterd-messages.h"
-#include "glusterd-store.h"
-#include "run.h"
-#include "glusterd-volgen.h"
-#include "glusterd-messages.h"
-
-#include "syscall.h"
-#include "cli1-xdr.h"
-#include "xdr-generic.h"
-
-int32_t
-glusterd_brick_op_cbk (struct rpc_req *req, struct iovec *iov,
- int count, void *myframe);
-int
-glusterd_defrag_start_validate (glusterd_volinfo_t *volinfo, char *op_errstr,
- size_t len, glusterd_op_t op)
-{
- int ret = -1;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
-
- /* Check only if operation is not remove-brick */
- if ((GD_OP_REMOVE_BRICK != op) &&
- !gd_is_remove_brick_committed (volinfo)) {
- gf_log (this->name, GF_LOG_DEBUG, "A remove-brick task on "
- "volume %s is not yet committed", volinfo->volname);
- snprintf (op_errstr, len, "A remove-brick task on volume %s is"
- " not yet committed. Either commit or stop the "
- "remove-brick task.", volinfo->volname);
- goto out;
- }
-
- if (glusterd_is_defrag_on (volinfo)) {
- gf_log (this->name, GF_LOG_DEBUG,
- "rebalance on volume %s already started",
- volinfo->volname);
- snprintf (op_errstr, len, "Rebalance on %s is already started",
- volinfo->volname);
- goto out;
- }
-
- if (glusterd_is_rb_started (volinfo) ||
- glusterd_is_rb_paused (volinfo)) {
- gf_log (this->name, GF_LOG_DEBUG,
- "Rebalance failed as replace brick is in progress on volume %s",
- volinfo->volname);
- snprintf (op_errstr, len, "Rebalance failed as replace brick is in progress on "
- "volume %s", volinfo->volname);
- goto out;
- }
- ret = 0;
-out:
- gf_log (this->name, GF_LOG_DEBUG, "Returning %d", ret);
- 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;
- xlator_t *this = NULL;
-
- this = THIS;
- if (!this)
- return 0;
-
- priv = this->private;
- if (!priv)
- return 0;
-
- volinfo = mydata;
- if (!volinfo)
- return 0;
-
- defrag = volinfo->rebal.defrag;
- if (!defrag)
- return 0;
-
- if ((event == RPC_CLNT_DISCONNECT) && defrag->connected)
- volinfo->rebal.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.name);
- break;
- }
-
- case RPC_CLNT_DISCONNECT:
- {
- if (!defrag->connected)
- return 0;
-
- LOCK (&defrag->lock);
- {
- defrag->connected = 0;
- }
- UNLOCK (&defrag->lock);
-
- if (!gf_is_service_running (pidfile, NULL)) {
- if (volinfo->rebal.defrag_status ==
- GF_DEFRAG_STATUS_STARTED) {
- volinfo->rebal.defrag_status =
- GF_DEFRAG_STATUS_FAILED;
- }
- }
-
- glusterd_store_perform_node_state_store (volinfo);
-
- if (defrag->rpc) {
- glusterd_rpc_clnt_unref (priv, defrag->rpc);
- defrag->rpc = NULL;
- }
- if (defrag->cbk_fn)
- defrag->cbk_fn (volinfo,
- volinfo->rebal.defrag_status);
-
- GF_FREE (defrag);
- gf_msg (this->name, GF_LOG_INFO, 0,
- GD_MSG_REBALANCE_DISCONNECTED,
- "Rebalance process for volume %s has disconnected.",
- volinfo->volname);
- break;
- }
- case RPC_CLNT_DESTROY:
- glusterd_volinfo_unref (volinfo);
- break;
- default:
- gf_log ("", GF_LOG_TRACE,
- "got some other RPC event %d", event);
- ret = 0;
- break;
- }
-
- return ret;
-}
-
-int32_t
-glusterd_defrag_notify (struct rpc_clnt *rpc, void *mydata,
- rpc_clnt_event_t event, void *data)
-{
- return glusterd_big_locked_notify (rpc, mydata, event,
- data, __glusterd_defrag_notify);
-}
-
-int
-glusterd_handle_defrag_start (glusterd_volinfo_t *volinfo, char *op_errstr,
- size_t len, int cmd, defrag_cbk_fn_t cbk,
- glusterd_op_t op)
-{
- int ret = -1;
- glusterd_defrag_info_t *defrag = NULL;
- runner_t runner = {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,};
- char volname[PATH_MAX] = {0,};
- char valgrind_logfile[PATH_MAX] = {0,};
-
- priv = THIS->private;
-
- GF_ASSERT (volinfo);
- GF_ASSERT (op_errstr);
-
- ret = glusterd_defrag_start_validate (volinfo, op_errstr, len, op);
- if (ret)
- goto out;
- if (!volinfo->rebal.defrag)
- volinfo->rebal.defrag =
- GF_CALLOC (1, sizeof (*volinfo->rebal.defrag),
- gf_gld_mt_defrag_info);
- if (!volinfo->rebal.defrag)
- goto out;
-
- defrag = volinfo->rebal.defrag;
-
- defrag->cmd = cmd;
-
- volinfo->rebal.defrag_cmd = cmd;
- volinfo->rebal.op = op;
-
- LOCK_INIT (&defrag->lock);
-
- volinfo->rebal.defrag_status = GF_DEFRAG_STATUS_STARTED;
-
- glusterd_volinfo_reset_defrag_stats (volinfo);
- 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);
- goto out;
- }
-
- GLUSTERD_GET_DEFRAG_SOCK_FILE (sockfile, volinfo);
- GLUSTERD_GET_DEFRAG_PID_FILE (pidfile, volinfo, priv);
- snprintf (logfile, PATH_MAX, "%s/%s-rebalance.log",
- DEFAULT_LOG_FILE_DIRECTORY, volinfo->volname);
- runinit (&runner);
-
- 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", "--track-origins=yes",
- NULL);
- runner_argprintf (&runner, "--log-file=%s", valgrind_logfile);
- }
-
- snprintf (volname, sizeof(volname), "rebalance/%s", volinfo->volname);
- runner_add_args (&runner, SBIN_DIR"/glusterfs",
- "-s", "localhost", "--volfile-id", 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",
- "--xlator-option", "*replicate*.readdir-failover=off",
- "--xlator-option", "*dht.readdir-optimize=on",
- 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_nowait (&runner);
- if (ret) {
- gf_log ("glusterd", GF_LOG_DEBUG, "rebalance command failed");
- goto out;
- }
-
- sleep (5);
-
- ret = glusterd_rebalance_rpc_create (volinfo, _gf_false);
-
- //FIXME: this cbk is passed as NULL in all occurrences. May be
- //we never needed it.
- 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,
- gf_boolean_t reconnect)
-{
- dict_t *options = NULL;
- char sockfile[PATH_MAX] = {0,};
- int ret = -1;
- glusterd_defrag_info_t *defrag = volinfo->rebal.defrag;
- glusterd_conf_t *priv = NULL;
- xlator_t *this = NULL;
- struct stat buf = {0,};
-
- this = THIS;
- GF_ASSERT (this);
- priv = this->private;
- GF_ASSERT (priv);
-
- //rebalance process is not started
- if (!defrag)
- goto out;
-
- //rpc obj for rebalance process already in place.
- if (defrag->rpc) {
- ret = 0;
- goto out;
- }
- GLUSTERD_GET_DEFRAG_SOCK_FILE (sockfile, volinfo);
- /* If reconnecting check if defrag sockfile exists in the new location
- * in /var/run/ , if it does not try the old location
- */
- if (reconnect) {
- ret = sys_stat (sockfile, &buf);
- /* TODO: Remove this once we don't need backward compatability
- * with the older path
- */
- if (ret && (errno == ENOENT)) {
- gf_log (this->name, GF_LOG_WARNING, "Rebalance sockfile "
- "%s does not exist. Trying old path.",
- sockfile);
- GLUSTERD_GET_DEFRAG_SOCK_FILE_OLD (sockfile, volinfo,
- priv);
- ret =sys_stat (sockfile, &buf);
- if (ret && (ENOENT == errno)) {
- gf_msg (this->name, GF_LOG_ERROR, 0,
- GD_MSG_REBAL_NO_SOCK_FILE, "Rebalance "
- "sockfile %s does not exist", sockfile);
- goto out;
- }
- }
- }
-
- /* Setting frame-timeout to 10mins (600seconds).
- * Unix domain sockets ensures that the connection is reliable. The
- * default timeout of 30mins used for unreliable network connections is
- * too long for unix domain socket connections.
- */
- ret = rpc_transport_unix_options_build (&options, sockfile, 600);
- if (ret) {
- gf_msg (THIS->name, GF_LOG_ERROR, 0, GD_MSG_UNIX_OP_BUILD_FAIL,
- "Unix options build failed");
- goto out;
- }
-
- glusterd_volinfo_ref (volinfo);
- ret = glusterd_rpc_create (&defrag->rpc, options,
- glusterd_defrag_notify, volinfo);
- if (ret) {
- gf_msg (THIS->name, GF_LOG_ERROR, 0, GD_MSG_RPC_CREATE_FAIL,
- "Glusterd RPC creation failed");
- goto out;
- }
- ret = 0;
-out:
- return ret;
-}
-
-int
-glusterd_rebalance_cmd_validate (int cmd, char *volname,
- glusterd_volinfo_t **volinfo,
- char *op_errstr, size_t len)
-{
- int ret = -1;
-
- if (glusterd_volinfo_find(volname, volinfo)) {
- gf_log ("glusterd", GF_LOG_ERROR, "Received rebalance on invalid"
- " volname %s", volname);
- snprintf (op_errstr, len, "Volume %s does not exist",
- 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"
- " volname %s", volname);
- snprintf (op_errstr, len, "Volume %s needs to "
- "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)
-{
- 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;
- char msg[2048] = {0,};
- xlator_t *this = NULL;
-
- GF_ASSERT (req);
- this = THIS;
- GF_ASSERT (this);
-
- priv = this->private;
- GF_ASSERT (priv);
-
- ret = xdr_to_generic (req->msg[0], &cli_req, (xdrproc_t)xdr_gf_cli_req);
- if (ret < 0) {
- //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");
- snprintf (msg, sizeof (msg), "Unable to decode the "
- "command");
- goto out;
- }
- }
-
- 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);
- goto out;
- }
-
- ret = dict_get_int32 (dict, "rebalance-command", (int32_t*)&cmd);
- if (ret) {
- snprintf (msg, sizeof (msg), "Failed to get command");
- gf_log (this->name, GF_LOG_ERROR, "%s", msg);
- goto out;
- }
-
- ret = dict_set_static_bin (dict, "node-uuid", MY_UUID, 16);
- 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, msg, sizeof (msg));
- } else
- ret = glusterd_op_begin (req, GD_OP_REBALANCE, dict,
- msg, sizeof (msg));
-
-out:
-
- glusterd_friend_sm ();
- glusterd_op_sm ();
-
- if (ret) {
- if (msg[0] == '\0')
- snprintf (msg, sizeof (msg), "Operation failed");
- ret = glusterd_op_send_cli_response (GD_OP_REBALANCE, ret, 0,
- req, dict, msg);
-
- }
-
- free (cli_req.dict.dict_val);//malloced by xdr
-
- return 0;
-}
-
-int
-glusterd_handle_defrag_volume (rpcsvc_request_t *req)
-{
- return glusterd_big_locked_handler (req, __glusterd_handle_defrag_volume);
-}
-
-
-int
-glusterd_op_stage_rebalance (dict_t *dict, char **op_errstr)
-{
- char *volname = NULL;
- char *cmd_str = NULL;
- int ret = 0;
- int32_t cmd = 0;
- char msg[2048] = {0};
- glusterd_volinfo_t *volinfo = NULL;
- char *task_id_str = NULL;
- dict_t *op_ctx = NULL;
- xlator_t *this = 0;
-
- this = THIS;
- GF_ASSERT (this);
-
- 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) {
- case GF_DEFRAG_CMD_START:
- case GF_DEFRAG_CMD_START_LAYOUT_FIX:
- case GF_DEFRAG_CMD_START_FORCE:
- if (is_origin_glusterd (dict)) {
- op_ctx = glusterd_op_get_ctx ();
- if (!op_ctx) {
- ret = -1;
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to get op_ctx");
- goto out;
- }
-
- ret = glusterd_generate_and_set_task_id
- (op_ctx, GF_REBALANCE_TID_KEY);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to generate task-id");
- goto out;
- }
- } else {
- ret = dict_get_str (dict, GF_REBALANCE_TID_KEY,
- &task_id_str);
- if (ret) {
- snprintf (msg, sizeof (msg),
- "Missing rebalance-id");
- gf_log (this->name, GF_LOG_WARNING, "%s", msg);
- ret = 0;
- }
- }
- ret = glusterd_defrag_start_validate (volinfo, msg,
- sizeof (msg),
- GD_OP_REBALANCE);
- if (ret) {
- gf_log (this->name, GF_LOG_DEBUG,
- "start validate failed");
- goto out;
- }
- break;
- case GF_DEFRAG_CMD_STATUS:
- case GF_DEFRAG_CMD_STOP:
- ret = dict_get_str (dict, "cmd-str", &cmd_str);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to get "
- "command string");
- ret = -1;
- goto out;
- }
- if ((strstr(cmd_str,"rebalance") != NULL) &&
- (volinfo->rebal.op != GD_OP_REBALANCE)){
- snprintf (msg,sizeof(msg),"Rebalance not started.");
- ret = -1;
- goto out;
- }
- if ((strstr(cmd_str,"remove-brick")!= NULL) &&
- (volinfo->rebal.op != GD_OP_REMOVE_BRICK)){
- snprintf (msg,sizeof(msg),"remove-brick not started.");
- ret = -1;
- goto out;
- }
- break;
- default:
- break;
- }
-
- ret = 0;
-out:
- if (ret && op_errstr && msg[0])
- *op_errstr = gf_strdup (msg);
-
- return ret;
-}
-
-
-int
-glusterd_op_rebalance (dict_t *dict, char **op_errstr, dict_t *rsp_dict)
-{
- 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;
- char *task_id_str = NULL;
- dict_t *ctx = NULL;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- priv = this->private;
-
- ret = dict_get_str (dict, "volname", &volname);
- if (ret) {
- gf_log (this->name, GF_LOG_DEBUG, "volname not given");
- goto out;
- }
-
- ret = dict_get_int32 (dict, "rebalance-command", &cmd);
- if (ret) {
- gf_log (this->name, GF_LOG_DEBUG, "command not given");
- goto out;
- }
-
-
- ret = glusterd_rebalance_cmd_validate (cmd, volname, &volinfo,
- msg, sizeof (msg));
- if (ret) {
- gf_log (this->name, GF_LOG_DEBUG, "cmd validate failed");
- goto out;
- }
-
- /* Set task-id, if available, in op_ctx dict for operations other than
- * start
- */
- if (cmd == GF_DEFRAG_CMD_STATUS || cmd == GF_DEFRAG_CMD_STOP) {
- if (!uuid_is_null (volinfo->rebal.rebalance_id)) {
- ctx = glusterd_op_get_ctx ();
- if (!ctx) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to get op_ctx");
- ret = -1;
- goto out;
- }
-
- if (GD_OP_REMOVE_BRICK == volinfo->rebal.op)
- ret = glusterd_copy_uuid_to_dict
- (volinfo->rebal.rebalance_id, ctx,
- GF_REMOVE_BRICK_TID_KEY);
- else
- ret = glusterd_copy_uuid_to_dict
- (volinfo->rebal.rebalance_id, ctx,
- GF_REBALANCE_TID_KEY);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to set task-id");
- goto out;
- }
- }
- }
-
- switch (cmd) {
- case GF_DEFRAG_CMD_START:
- case GF_DEFRAG_CMD_START_LAYOUT_FIX:
- case GF_DEFRAG_CMD_START_FORCE:
- /* Reset defrag status to 'NOT STARTED' whenever a
- * remove-brick/rebalance command is issued to remove
- * stale information from previous run.
- */
- volinfo->rebal.defrag_status = GF_DEFRAG_STATUS_NOT_STARTED;
-
- ret = dict_get_str (dict, GF_REBALANCE_TID_KEY, &task_id_str);
- if (ret) {
- gf_log (this->name, GF_LOG_DEBUG, "Missing rebalance "
- "id");
- ret = 0;
- } else {
- uuid_parse (task_id_str, volinfo->rebal.rebalance_id) ;
- volinfo->rebal.op = GD_OP_REBALANCE;
- }
- if (!gd_should_i_start_rebalance (volinfo))
- break;
- ret = glusterd_handle_defrag_start (volinfo, msg, sizeof (msg),
- cmd, NULL, GD_OP_REBALANCE);
- break;
- case GF_DEFRAG_CMD_STOP:
- /* Clear task-id only on explicitly stopping rebalance.
- * Also clear the stored operation, so it doesn't cause trouble
- * with future rebalance/remove-brick starts
- */
- uuid_clear (volinfo->rebal.rebalance_id);
- volinfo->rebal.op = GD_OP_NONE;
-
- /* 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;
- break;
-
- case GF_DEFRAG_CMD_STATUS:
- break;
- default:
- break;
- }
-
-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;
- char *volname_ptr = NULL;
- int32_t ret = -1;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (dict);
-
- ret = dict_get_str (dict, "volname", &volname);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to get volname");
- return ret;
- }
-
- volname_ptr = strstr (volname, "rebalance/");
- if (volname_ptr) {
- volname_ptr = strchr (volname_ptr, '/');
- if (!volname_ptr) {
- ret = -1;
- goto out;
- }
- volname = volname_ptr + 1;
- } else {
- gf_log (this->name, GF_LOG_ERROR,
- "volname recieved (%s) is not prefixed with rebalance.",
- volname);
- ret = -1;
- goto out;
- }
-
- ret = glusterd_volinfo_find (volname, &volinfo);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to get volinfo for %s"
- , volname);
- return ret;
- }
-
- ret = glusterd_defrag_volume_status_update (volinfo, dict);
-
- if (ret)
- gf_log (this->name, GF_LOG_ERROR, "Failed to update status");
-
-out:
- return ret;
-}
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 11e15c55f46..00000000000
--- a/xlators/mgmt/glusterd/src/glusterd-replace-brick.c
+++ /dev/null
@@ -1,2066 +0,0 @@
-/*
- Copyright (c) 2011-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 "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, \
- DEFAULT_VAR_RUN_DIRECTORY"/%s-"RB_CLIENT_MOUNTPOINT, \
- volinfo->volname);
-
-extern uuid_t global_txn_id;
-
-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;
- char msg[2048] = {0,};
- xlator_t *this = NULL;
-
- GF_ASSERT (req);
- this = THIS;
- GF_ASSERT (this);
-
- ret = xdr_to_generic (req->msg[0], &cli_req, (xdrproc_t)xdr_gf_cli_req);
- if (ret < 0) {
- //failed to decode msg;
- req->rpc_err = GARBAGE_ARGS;
- goto out;
- }
-
- gf_log (this->name, 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 (this->name, GF_LOG_ERROR,
- "failed to "
- "unserialize req-buffer to dictionary");
- snprintf (msg, sizeof (msg), "Unable to decode the "
- "command");
- goto out;
- }
- }
-
- ret = dict_get_str (dict, "volname", &volname);
- if (ret) {
- snprintf (msg, sizeof (msg), "Could not get volume name");
- gf_log (this->name, GF_LOG_ERROR, "%s", msg);
- goto out;
- }
-
- ret = dict_get_int32 (dict, "operation", &op);
- if (ret) {
- gf_log (this->name, GF_LOG_DEBUG,
- "dict_get on operation failed");
- snprintf (msg, sizeof (msg), "Could not get operation");
- goto out;
- }
-
- ret = dict_get_str (dict, "src-brick", &src_brick);
-
- if (ret) {
- snprintf (msg, sizeof (msg), "Failed to get src brick");
- gf_log (this->name, GF_LOG_ERROR, "%s", msg);
- 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) {
- snprintf (msg, sizeof (msg), "Failed to get dest brick");
- gf_log (this->name, GF_LOG_ERROR, "%s", msg);
- goto out;
- }
-
- (void) glusterd_get_replace_op_str (op, operation);
- gf_log (this->name, GF_LOG_DEBUG, "dst brick=%s", dst_brick);
- gf_log (this->name, GF_LOG_INFO, "Received replace brick %s request",
- operation);
-
- ret = glusterd_op_begin (req, GD_OP_REPLACE_BRICK, dict,
- msg, sizeof (msg));
-
-out:
- free (cli_req.dict.dict_val);//malloced by xdr
-
- glusterd_friend_sm ();
- glusterd_op_sm ();
-
- if (ret) {
- if (msg[0] == '\0')
- snprintf (msg, sizeof (msg), "Operation failed");
- ret = glusterd_op_send_cli_response (cli_op, ret, 0, req,
- dict, msg);
- }
-
- return ret;
-}
-
-int
-glusterd_handle_replace_brick (rpcsvc_request_t *req)
-{
- return glusterd_big_locked_handler (req,
- __glusterd_handle_replace_brick);
-}
-
-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->rep_brick.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;
- int32_t port = 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 pidfile[PATH_MAX] = {0};
- char *task_id_str = NULL;
- xlator_t *this = NULL;
- gf_boolean_t is_force = _gf_false;
-
- this = THIS;
- GF_ASSERT (this);
-
- priv = this->private;
- GF_ASSERT (priv);
-
- ret = dict_get_str (dict, "src-brick", &src_brick);
-
- if (ret) {
- gf_log (this->name, 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 (this->name, GF_LOG_ERROR, "Unable to get dest 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 (this->name, 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 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 (this->name, 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 (this->name, GF_LOG_WARNING, "Unable to get the status"
- " of active "GEOREP" session");
- if (is_run) {
- gf_log (this->name, 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 (this->name, GF_LOG_ERROR, "%s", msg);
- *op_errstr = gf_strdup (msg);
- ret = -1;
- goto out;
- }
-
- ctx = glusterd_op_get_ctx();
-
- switch (replace_op) {
- case GF_REPLACE_OP_START:
- if (glusterd_is_rb_started (volinfo)) {
- snprintf (msg, sizeof (msg), "Replace brick is already "
- "started for volume");
- gf_log (this->name, GF_LOG_ERROR, "%s", msg);
- *op_errstr = gf_strdup (msg);
- ret = -1;
- goto out;
- }
- if (is_origin_glusterd (dict)) {
- if (!ctx) {
- ret = -1;
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to get op_ctx");
- goto out;
- }
-
- ret = glusterd_generate_and_set_task_id
- (ctx, GF_REPLACE_BRICK_TID_KEY);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to generate task-id");
- goto out;
- }
-
- } else {
- ret = dict_get_str (dict, GF_REPLACE_BRICK_TID_KEY,
- &task_id_str);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING,
- "Missing replace-brick-id");
- ret = 0;
- }
- }
- is_force = dict_get_str_boolean (dict, "force", _gf_false);
-
- break;
-
- case GF_REPLACE_OP_PAUSE:
- if (glusterd_is_rb_paused (volinfo)) {
- gf_log (this->name, GF_LOG_ERROR, "Replace brick is "
- "already paused for volume ");
- ret = -1;
- goto out;
- } else if (!glusterd_is_rb_started(volinfo)) {
- gf_log (this->name, 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 (this->name, 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 (this->name, GF_LOG_ERROR, "Replace brick is not "
- "started for volume ");
- ret = -1;
- goto out;
- }
- break;
-
- case GF_REPLACE_OP_COMMIT_FORCE:
- is_force = _gf_true;
- 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;
- }
-
- if (ctx) {
- if (!glusterd_is_fuse_available ()) {
- gf_log (this->name, 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 (gf_is_local_addr (src_brickinfo->hostname)) {
- gf_log (this->name, 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_BRICK_PIDFILE (pidfile, volinfo, src_brickinfo,
- priv);
- if ((replace_op != GF_REPLACE_OP_COMMIT_FORCE) &&
- !gf_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 (this->name, GF_LOG_ERROR, "Memory allocation failed");
- goto out;
- }
- host = strtok_r (dup_dstbrick, ":", &savetok);
- path = strtok_r (NULL, ":", &savetok);
-
- if (!host || !path) {
- gf_log (this->name, 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, "%s", *op_errstr);
- goto out;
- }
-
- if (!glusterd_is_rb_ongoing (volinfo) &&
- (replace_op == GF_REPLACE_OP_START ||
- replace_op == GF_REPLACE_OP_COMMIT_FORCE)) {
-
- volinfo->rep_brick.src_brick = src_brickinfo;
- volinfo->rep_brick.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) &&
- gf_is_local_addr (host)) {
- ret = glusterd_validate_and_create_brickpath (dst_brickinfo,
- volinfo->volume_id,
- op_errstr, is_force);
- if (ret)
- goto out;
- }
-
- if (!gf_is_local_addr (host)) {
- peerinfo = glusterd_peerinfo_find (NULL, host);
- if (peerinfo == NULL) {
- ret = -1;
- 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;
- }
- } else if (priv->op_version >= GD_OP_VERSION_3_6_0) {
- /* A bricks mount dir is required only by snapshots which were
- * introduced in gluster-3.6.0
- */
- ret = glusterd_get_brick_mount_dir (dst_brickinfo->path,
- dst_brickinfo->hostname,
- dst_brickinfo->mount_dir);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to get brick mount_dir");
- goto out;
- }
-
- ret = dict_set_dynstr_with_alloc (rsp_dict, "brick1.mount_dir",
- dst_brickinfo->mount_dir);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to set brick1.mount_dir");
- goto out;
- }
-
- ret = dict_set_int32 (rsp_dict, "brick_count", 1);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to set local_brick_count");
- goto out;
- }
- }
-
- if (replace_op == GF_REPLACE_OP_START &&
- gf_is_local_addr (volinfo->rep_brick.dst_brick->hostname)) {
- port = pmap_registry_alloc (THIS);
- if (!port) {
- gf_log (THIS->name, GF_LOG_CRITICAL,
- "No free ports available");
- ret = -1;
- goto out;
- }
-
- ctx = glusterd_op_get_ctx();
- ret = dict_set_int32 ((ctx)?ctx:rsp_dict, "dst-brick-port",
- port);
- if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR, "Failed to set dst "
- "brick port");
- goto out;
- }
- volinfo->rep_brick.dst_brick->port = port;
- }
-
- ret = 0;
-
-out:
- GF_FREE (dup_dstbrick);
- gf_log (this->name, 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);
-
- dict_del (dict, "enable-pump");
-
-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,
- _gf_false);
- 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,
- _gf_false);
- 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 = brickinfo->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_nowait (&runner);
- if (ret) {
- pmap_registry_remove (THIS, 0, brickinfo->path,
- GF_PMAP_PORT_BRICKSERVER, NULL);
- 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;
-
-
-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;
- }
- sys_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));
-
- GF_FREE (ttype);
-
- ret = 0;
-
-out:
- if (file)
- fclose (file);
-
- 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 = sys_creat (filename, S_IRUSR | S_IWUSR);
- if (fd < 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "%s", strerror (errno));
- goto out;
- }
- sys_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);
-
- ret = 0;
-
-out:
- if (file)
- fclose (file);
-
- 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_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;
- char mntpt[PATH_MAX] = {0,};
-
- 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;
- }
-
- GLUSTERD_GET_RB_MNTPT (mntpt, sizeof (mntpt), volinfo);
- ret = gf_umount_lazy (this->name, mntpt, 1);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING,
- "Lazy unmount failed on maintenance client");
- } else {
- gf_log (this->name, GF_LOG_DEBUG,
- "Successfully unmounted maintenance client");
- }
-
- snprintf (volfile, PATH_MAX, "%s/vols/%s/%s", priv->workdir,
- volinfo->volname, RB_CLIENTVOL_FILENAME);
-
- ret = unlink (volfile);
- if (ret) {
- gf_log ("", GF_LOG_DEBUG, "unlink of %s failed, reason: %s",
- volfile, strerror (errno));
- 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_str[8192] = {0,};
- char *status_reply = NULL;
- char *tmp = NULL;
- char *save_ptr = NULL;
- char filename[PATH_MAX] = {0,};
- char *current_file = NULL;
- uint64_t files = 0;
- int status = 0;
- 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_str);
- 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;
- }
-
- /* Split status reply into different parts */
- tmp = strtok_r (status_str, ":", &save_ptr);
- if (!tmp) {
- ret = -1;
- gf_log (THIS->name, GF_LOG_ERROR,
- "Couldn't tokenize status string");
- goto out;
- }
- sscanf (tmp, "status=%d", &status);
- ret = dict_set_int32 (ctx, "status", status);
- if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR, "Couldn't "
- "set rb status in context");
- goto out;
- }
-
- tmp = NULL;
- tmp = strtok_r (NULL, ":", &save_ptr);
- if (!tmp) {
- ret = -1;
- gf_log (THIS->name, GF_LOG_ERROR,
- "Couldn't tokenize status string");
- goto out;
- }
- sscanf (tmp, "no_of_files=%"SCNu64, &files);
- ret = dict_set_uint64 (ctx, "files", files);
- if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR, "Couldn't "
- "set rb files in context");
- goto out;
- }
-
- if (status == 0) {
- tmp = NULL;
- tmp = strtok_r (NULL, ":", &save_ptr);
- if (!tmp) {
- ret = -1;
- gf_log (THIS->name, GF_LOG_ERROR,
- "Couldn't tokenize status "
- "string");
- goto out;
- }
- sscanf (tmp, "current_file=%s", filename);
- current_file = gf_strdup (filename);
- ret = dict_set_dynstr (ctx, "current_file",
- current_file);
- if (ret) {
- GF_FREE (current_file);
- gf_log (THIS->name, GF_LOG_ERROR,
- "Couldn't set rb current file "
- "in context");
- goto out;
- }
- }
- if (status) {
- ret = gf_asprintf (&status_reply,
- "Number of files migrated = %"
- PRIu64"\tMigration complete",
- files);
- } else {
- ret = gf_asprintf (&status_reply,
- "Number of files migrated = %"
- PRIu64"\tCurrent file = %s",
- files, filename);
- }
- if (ret == -1) {
- gf_log (THIS->name, GF_LOG_ERROR,
- "Failed to create status_reply string");
- goto out;
- }
- 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_volinfo_t *volinfo,
- 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;
- char brickname[PATH_MAX] = {0,};
-
- this = THIS;
-
- dict_ret = dict_get_int32 (req_dict, "src-brick-port", &src_port);
- if (src_port)
- src_brickinfo->port = src_port;
-
- if (gf_is_local_addr (src_brickinfo->hostname)) {
- gf_log ("", GF_LOG_INFO,
- "adding src-brick port no");
-
- if (volinfo->transport_type == GF_TRANSPORT_RDMA) {
- snprintf (brickname, sizeof(brickname), "%s.rdma",
- src_brickinfo->path);
- } else
- snprintf (brickname, sizeof(brickname), "%s",
- src_brickinfo->path);
-
- src_brickinfo->port = pmap_registry_search (this,
- brickname, 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;
-
- dict_ret = dict_get_int32 (req_dict, "dst-brick-port", &dst_port);
- if (!dict_ret)
- dst_brickinfo->port = dst_port;
-
-
- if (gf_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,
- dict_t *dict)
-{
- char *brick_mount_dir = NULL;
- glusterd_brickinfo_t *old_brickinfo = NULL;
- glusterd_brickinfo_t *new_brickinfo = NULL;
- int32_t ret = -1;
- xlator_t *this = NULL;
- glusterd_conf_t *conf = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (dict);
- GF_ASSERT (volinfo);
-
- conf = this->private;
- GF_ASSERT (conf);
-
- ret = glusterd_brickinfo_new_from_brick (new_brick,
- &new_brickinfo);
- if (ret)
- goto out;
-
- ret = glusterd_resolve_brick (new_brickinfo);
-
- if (ret)
- goto out;
-
- ret = glusterd_volume_brickinfo_get_by_brick (old_brick,
- volinfo, &old_brickinfo);
- if (ret)
- goto out;
-
- strncpy (new_brickinfo->brick_id, old_brickinfo->brick_id,
- sizeof (new_brickinfo->brick_id));
-
- /* A bricks mount dir is required only by snapshots which were
- * introduced in gluster-3.6.0
- */
- if (conf->op_version >= GD_OP_VERSION_3_6_0) {
- ret = dict_get_str (dict, "brick1.mount_dir", &brick_mount_dir);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "brick1.mount_dir not present");
- goto out;
- }
- strncpy (new_brickinfo->mount_dir, brick_mount_dir,
- sizeof(new_brickinfo->mount_dir));
- }
-
- 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, _gf_false);
- 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;
- char *task_id_str = 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 (this->name, 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 (this->name, 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 (this->name, 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 (this->name, 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 (this->name, GF_LOG_DEBUG,
- "Unable to get src-brickinfo");
- goto out;
- }
-
-
- ret = glusterd_get_rb_dst_brickinfo (volinfo, &dst_brickinfo);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Unable to get "
- "replace brick destination brickinfo");
- goto out;
- }
-
- ret = glusterd_resolve_brick (dst_brickinfo);
- if (ret) {
- gf_log (this->name, GF_LOG_DEBUG,
- "Unable to resolve dst-brickinfo");
- goto out;
- }
-
- ret = rb_update_srcbrick_port (volinfo, src_brickinfo, rsp_dict,
- dict, replace_op);
- if (ret)
- goto out;
-
- if ((GF_REPLACE_OP_START != replace_op)) {
-
- /* Set task-id, if available, in op_ctx dict for operations
- * other than start
- */
- if (is_origin_glusterd (dict)) {
- ctx = glusterd_op_get_ctx();
- if (!ctx) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to "
- "get op_ctx");
- ret = -1;
- goto out;
- }
- if (!uuid_is_null (volinfo->rep_brick.rb_id)) {
- ret = glusterd_copy_uuid_to_dict
- (volinfo->rep_brick.rb_id, ctx,
- GF_REPLACE_BRICK_TID_KEY);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to set "
- "replace-brick-id");
- goto out;
- }
- }
- }
- }
- ret = rb_update_dstbrick_port (dst_brickinfo, rsp_dict,
- dict, replace_op);
- if (ret)
- goto out;
-
- switch (replace_op) {
- case GF_REPLACE_OP_START:
- {
- ret = dict_get_str (dict, GF_REPLACE_BRICK_TID_KEY, &task_id_str);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Missing replace-brick-id");
- ret = 0;
- } else {
- uuid_parse (task_id_str, volinfo->rep_brick.rb_id);
- }
-
- if (gf_is_local_addr (dst_brickinfo->hostname)) {
- gf_log (this->name, 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 (this->name, GF_LOG_DEBUG,
- "Failed to spawn destination "
- "brick");
- goto out;
- }
- } else {
- gf_log (this->name, GF_LOG_ERROR,
- "Replace brick is already started=> no "
- "need to restart dst brick ");
- }
- }
-
-
- if (gf_is_local_addr (src_brickinfo->hostname)) {
- ret = rb_src_brick_restart (volinfo, src_brickinfo,
- 1);
- if (ret) {
- gf_log (this->name, GF_LOG_DEBUG,
- "Could not restart src-brick");
- goto out;
- }
- }
-
- if (gf_is_local_addr (dst_brickinfo->hostname)) {
- gf_log (this->name, 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 (this->name, GF_LOG_ERROR,
- "Commit operation failed");
- goto out;
- }
- }
- }
- /* fall through */
- case GF_REPLACE_OP_COMMIT_FORCE:
- {
- if (gf_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, dict);
- 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->rebal.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->rep_brick.dst_brick);
- volinfo->rep_brick.src_brick = NULL;
- volinfo->rep_brick.dst_brick = NULL;
- uuid_clear (volinfo->rep_brick.rb_id);
- }
- break;
-
- case GF_REPLACE_OP_PAUSE:
- {
- gf_log (this->name, 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 (this->name, 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;
- }
- }
-
- if (gf_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 (gf_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->rep_brick.dst_brick);
- volinfo->rep_brick.src_brick = NULL;
- volinfo->rep_brick.dst_brick = NULL;
- }
- break;
-
- case GF_REPLACE_OP_STATUS:
- {
- gf_log (this->name, 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;
- int32_t ret = 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;
- uuid_t *txn_id = NULL;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- priv = this->private;
- GF_ASSERT (priv);
- GF_ASSERT (data);
-
- txn_id = &priv->global_txn_id;
- dict = data;
-
- 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_bin (dict, "transaction_id", (void **)&txn_id);
- gf_log (this->name, GF_LOG_DEBUG, "transaction ID = %s",
- uuid_utoa (*txn_id));
-
- 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,
- txn_id, NULL);
- else
- ret = glusterd_op_sm_inject_event (GD_OP_EVENT_COMMIT_ACC,
- txn_id, NULL);
-
- synclock_lock (&priv->big_lock);
- {
- glusterd_op_sm ();
- }
- synclock_unlock (&priv->big_lock);
-}
diff --git a/xlators/mgmt/glusterd/src/glusterd-rpc-ops.c b/xlators/mgmt/glusterd/src/glusterd-rpc-ops.c
deleted file mode 100644
index ec2d850094a..00000000000
--- a/xlators/mgmt/glusterd/src/glusterd-rpc-ops.c
+++ /dev/null
@@ -1,2172 +0,0 @@
-/*
- Copyright (c) 2010-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 "rpc-clnt.h"
-#include "glusterd1-xdr.h"
-#include "cli1-xdr.h"
-
-#include "xdr-generic.h"
-
-#include "compat-errno.h"
-#include "glusterd-op-sm.h"
-#include "glusterd-sm.h"
-#include "glusterd.h"
-#include "protocol-common.h"
-#include "glusterd-utils.h"
-#include "common-utils.h"
-#include "glusterd-messages.h"
-#include <sys/uio.h>
-
-
-#define SERVER_PATH_MAX (16 * 1024)
-
-
-extern glusterd_op_info_t opinfo;
-extern uuid_t global_txn_id;
-
-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;
- 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,};
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- conf = this->private;
-
- GF_ASSERT (conf);
-
- ctx = op_ctx;
-
- switch (op) {
- case GD_OP_REMOVE_BRICK:
- {
- if (ctx)
- ret = dict_get_str (ctx, "errstr", &errstr);
- break;
- }
- case GD_OP_RESET_VOLUME:
- {
- if (op_ret && !op_errstr)
- errstr = "Error while resetting options";
- break;
- }
- case GD_OP_REBALANCE:
- case GD_OP_DEFRAG_BRICK_VOLUME:
- {
- if (ctx) {
- ret = dict_get_int32 (ctx, "status", &status);
- if (ret) {
- gf_log (this->name, GF_LOG_TRACE,
- "failed to get status");
- }
- }
- break;
- }
- case GD_OP_GSYNC_CREATE:
- case GD_OP_GSYNC_SET:
- {
- 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 */
-
- }
- break;
-
- }
- case GD_OP_PROFILE_VOLUME:
- {
- 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");
- }
- }
- break;
- }
- case GD_OP_START_BRICK:
- case GD_OP_STOP_BRICK:
- {
- gf_log (this->name, GF_LOG_DEBUG, "op '%s' not supported",
- gd_op_list[op]);
- break;
- }
- case GD_OP_NONE:
- case GD_OP_MAX:
- {
- gf_log (this->name, GF_LOG_ERROR, "invalid operation");
- 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:
- case GD_OP_QUOTA:
- case GD_OP_SNAP:
- case GD_OP_BARRIER:
- {
- /*nothing specific to be done*/
- break;
- }
- case GD_OP_COPY_FILE:
- {
- if (ctx)
- ret = dict_get_str (ctx, "errstr", &errstr);
- break;
- }
- case GD_OP_SYS_EXEC:
- {
- if (ctx) {
- ret = dict_get_str (ctx, "errstr", &errstr);
- ret = dict_set_str (ctx, "glusterd_workdir",
- conf->workdir);
- }
- break;
- }
- }
-
- rsp.op_ret = op_ret;
- rsp.op_errno = errno;
- if (errstr)
- rsp.op_errstr = errstr;
- else if (op_errstr)
- rsp.op_errstr = op_errstr;
-
- if (!rsp.op_errstr)
- rsp.op_errstr = "";
-
- 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");
- else
- free_ptr = rsp.dict.dict_val;
- }
-
- /* needed by 'rebalance status' */
- if (status)
- rsp.op_errno = status;
-
- cli_rsp = &rsp;
- xdrproc = (xdrproc_t) xdr_gf_cli_rsp;
-
- glusterd_to_cli (req, cli_rsp, NULL, 0, NULL,
- xdrproc, ctx);
- ret = 0;
-
- GF_FREE (free_ptr);
- gf_log (this->name, GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-
-int
-glusterd_big_locked_cbk (struct rpc_req *req, struct iovec *iov,
- int count, void *myframe, fop_cbk_fn_t fn)
-{
- glusterd_conf_t *priv = THIS->private;
- int ret = -1;
-
- synclock_lock (&priv->big_lock);
- ret = fn (req, iov, count, myframe);
- synclock_unlock (&priv->big_lock);
-
- return ret;
-}
-
-int
-__glusterd_probe_cbk (struct rpc_req *req, struct iovec *iov,
- int count, void *myframe)
-{
- gd1_mgmt_probe_rsp rsp = {{0},};
- int ret = 0;
- glusterd_peerinfo_t *peerinfo = NULL;
- glusterd_friend_sm_event_t *event = NULL;
- glusterd_probe_ctx_t *ctx = NULL;
- xlator_t *this = NULL;
- glusterd_conf_t *conf = NULL;
-
- if (-1 == req->rpc_status) {
- goto out;
- }
-
- this = THIS;
- GF_ASSERT (this != NULL);
- conf = this->private;
- GF_VALIDATE_OR_GOTO (this->name, (conf != NULL), out);
-
- ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gd1_mgmt_probe_rsp);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR, "error");
- //rsp.op_ret = -1;
- //rsp.op_errno = EINVAL;
- goto out;
- }
-
- gf_log (this->name, GF_LOG_INFO,
- "Received probe resp from uuid: %s, host: %s",
- uuid_utoa (rsp.uuid), rsp.hostname);
- if (rsp.op_ret != 0) {
- ctx = ((call_frame_t *)myframe)->local;
- ((call_frame_t *)myframe)->local = NULL;
-
- GF_ASSERT (ctx);
-
- if (ctx->req) {
- glusterd_xfer_cli_probe_resp (ctx->req, rsp.op_ret,
- rsp.op_errno,
- rsp.op_errstr,
- ctx->hostname, ctx->port,
- ctx->dict);
- }
-
- glusterd_destroy_probe_ctx (ctx);
- (void) glusterd_friend_remove (rsp.uuid, rsp.hostname);
- ret = rsp.op_ret;
- goto out;
- }
-
- peerinfo = glusterd_peerinfo_find (rsp.uuid, rsp.hostname);
- if (peerinfo == NULL) {
- GF_ASSERT (0);
- }
-
- /*
- * In the case of a fresh probe rsp.uuid and peerinfo.uuid will not
- * match, as peerinfo->uuid will be NULL.
- *
- * In the case of a peer probe being done to add a new network to a
- * peer, rsp.uuid will match an existing peerinfo.uuid. If we have this
- * stage it means that the current address/hostname being used isn't
- * present in the found peerinfo. If it were, we would have found out
- * earlier in the probe process and wouldn't even reach till here. So,
- * we need to add the new hostname to the peer.
- *
- * This addition should only be done for cluster op-version >=
- * GD_OP_VERSION_3_6_0 as address lists are only supported from then on.
- * Also, this update should only be done when an explicit CLI probe
- * command was used to begin the probe process.
- */
- if ((conf->op_version >= GD_OP_VERSION_3_6_0) &&
- (uuid_compare (rsp.uuid, peerinfo->uuid) == 0)) {
- ctx = ((call_frame_t *)myframe)->local;
- /* Presence of ctx->req implies this probe was started by a cli
- * probe command
- */
- if (ctx->req == NULL)
- goto cont;
-
- gf_log (this->name, GF_LOG_DEBUG, "Adding address '%s' to "
- "existing peer %s", rsp.hostname, uuid_utoa (rsp.uuid));
-
- ret = glusterd_friend_remove (NULL, rsp.hostname);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Could not remove "
- "stale peerinfo with name %s", rsp.hostname);
- goto reply;
- }
-
- ret = gd_add_address_to_peer (peerinfo, rsp.hostname);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Couldn't add hostname to peer list");
- goto reply;
- }
-
- /* Injecting LOCAL_ACC to send update */
- ret = glusterd_friend_sm_new_event (GD_FRIEND_EVENT_LOCAL_ACC,
- &event);
- if (!ret) {
- event->peerinfo = peerinfo;
- ret = glusterd_friend_sm_inject_event (event);
- }
- rsp.op_errno = GF_PROBE_FRIEND;
-
-reply:
- ctx = ((call_frame_t *)myframe)->local;
- ((call_frame_t *)myframe)->local = NULL;
-
- GF_ASSERT (ctx);
-
- if (ctx->req) {
- glusterd_xfer_cli_probe_resp (ctx->req, ret,
- rsp.op_errno,
- rsp.op_errstr,
- ctx->hostname, ctx->port,
- ctx->dict);
- }
-
- glusterd_destroy_probe_ctx (ctx);
-
- goto out;
-
- } else 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,
- ctx->dict);
- }
-
- glusterd_destroy_probe_ctx (ctx);
- (void) glusterd_friend_remove (NULL, rsp.hostname);
- ret = rsp.op_ret;
- goto out;
- }
-cont:
- uuid_copy (peerinfo->uuid, rsp.uuid);
-
- ret = glusterd_friend_sm_new_event
- (GD_FRIEND_EVENT_INIT_FRIEND_REQ, &event);
-
- if (ret) {
- gf_log ("glusterd", GF_LOG_ERROR,
- "Unable to get event");
- goto out;
- }
-
- event->peerinfo = peerinfo;
- event->ctx = ((call_frame_t *)myframe)->local;
- ((call_frame_t *)myframe)->local = NULL;
- ret = glusterd_friend_sm_inject_event (event);
-
-
- if (!ret) {
- glusterd_friend_sm ();
- glusterd_op_sm ();
- }
-
- gf_log ("glusterd", GF_LOG_INFO, "Received resp to probe req");
-
-out:
- free (rsp.hostname);//malloced by xdr
- GLUSTERD_STACK_DESTROY (((call_frame_t *)myframe));
- return ret;
-}
-
-int
-glusterd_probe_cbk (struct rpc_req *req, struct iovec *iov,
- int count, void *myframe)
-{
- return glusterd_big_locked_cbk (req, iov, count, myframe,
- __glusterd_probe_cbk);
-}
-
-
-int
-__glusterd_friend_add_cbk (struct rpc_req * req, struct iovec *iov,
- int count, void *myframe)
-{
- gd1_mgmt_friend_rsp rsp = {{0},};
- int ret = -1;
- glusterd_friend_sm_event_t *event = NULL;
- glusterd_friend_sm_event_type_t event_type = GD_FRIEND_EVENT_NONE;
- glusterd_peerinfo_t *peerinfo = NULL;
- int32_t op_ret = -1;
- int32_t op_errno = -1;
- glusterd_probe_ctx_t *ctx = NULL;
- glusterd_friend_update_ctx_t *ev_ctx = NULL;
-
- 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);
- if (ret < 0) {
- gf_log ("", GF_LOG_ERROR, "error");
- rsp.op_ret = -1;
- rsp.op_errno = EINVAL;
- goto out;
- }
-
- op_ret = rsp.op_ret;
- op_errno = rsp.op_errno;
-
- gf_log ("glusterd", GF_LOG_INFO,
- "Received %s from uuid: %s, host: %s, port: %d",
- (op_ret)?"RJT":"ACC", uuid_utoa (rsp.uuid), rsp.hostname, rsp.port);
-
- peerinfo = glusterd_peerinfo_find (rsp.uuid, rsp.hostname);
- if (peerinfo == NULL) {
- ret = -1;
- gf_log ("", GF_LOG_ERROR, "received friend add response from"
- " unknown peer uuid: %s", uuid_utoa (rsp.uuid));
- goto out;
- }
-
- if (op_ret)
- event_type = GD_FRIEND_EVENT_RCVD_RJT;
- else
- event_type = GD_FRIEND_EVENT_RCVD_ACC;
-
- ret = glusterd_friend_sm_new_event (event_type, &event);
-
- if (ret) {
- gf_log ("glusterd", GF_LOG_ERROR,
- "Unable to get event");
- goto out;
- }
- event->peerinfo = peerinfo;
- ev_ctx = GF_CALLOC (1, sizeof (*ev_ctx),
- gf_gld_mt_friend_update_ctx_t);
- if (!ev_ctx) {
- ret = -1;
- goto out;
- }
-
- uuid_copy (ev_ctx->uuid, rsp.uuid);
- ev_ctx->hostname = gf_strdup (rsp.hostname);
-
- event->ctx = ev_ctx;
- ret = glusterd_friend_sm_inject_event (event);
-
- if (ret)
- goto out;
-
-out:
- ctx = ((call_frame_t *)myframe)->local;
- ((call_frame_t *)myframe)->local = NULL;
-
- GF_ASSERT (ctx);
-
- if (ctx->req)//reverse probe doesn't have req
- ret = glusterd_xfer_cli_probe_resp (ctx->req, op_ret, op_errno,
- NULL, ctx->hostname,
- ctx->port, ctx->dict);
- if (!ret) {
- glusterd_friend_sm ();
- glusterd_op_sm ();
- }
- if (ctx)
- glusterd_destroy_probe_ctx (ctx);
- 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,
- int count, void *myframe)
-{
- return glusterd_big_locked_cbk (req, iov, count, myframe,
- __glusterd_friend_add_cbk);
-}
-
-int
-__glusterd_friend_remove_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;
- glusterd_peerinfo_t *peerinfo = NULL;
- 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);
-
- ctx = ((call_frame_t *)myframe)->local;
- ((call_frame_t *)myframe)->local = NULL;
- GF_ASSERT (ctx);
-
- 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);
- if (ret < 0) {
- gf_log ("", GF_LOG_ERROR, "error");
- rsp.op_ret = -1;
- rsp.op_errno = EINVAL;
- goto respond;
- }
-
- op_ret = rsp.op_ret;
- op_errno = rsp.op_errno;
-
- gf_log ("glusterd", GF_LOG_INFO,
- "Received %s from uuid: %s, host: %s, port: %d",
- (op_ret)?"RJT":"ACC", uuid_utoa (rsp.uuid), rsp.hostname, rsp.port);
-
-inject:
- peerinfo = glusterd_peerinfo_find (rsp.uuid, ctx->hostname);
- if (peerinfo == NULL) {
- //can happen as part of rpc clnt connection cleanup
- //when the frame timeout happens after 30 minutes
- ret = -1;
- goto respond;
- }
-
- event_type = GD_FRIEND_EVENT_REMOVE_FRIEND;
-
- ret = glusterd_friend_sm_new_event (event_type, &event);
-
- if (ret) {
- gf_log ("glusterd", GF_LOG_ERROR,
- "Unable to get event");
- goto respond;
- }
- event->peerinfo = peerinfo;
-
- ret = glusterd_friend_sm_inject_event (event);
-
- 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.
- */
- op_ret = 0;
-
-
-respond:
- ret = glusterd_xfer_cli_deprobe_resp (ctx->req, op_ret, op_errno, NULL,
- ctx->hostname, ctx->dict);
- if (!ret && move_sm_now) {
- glusterd_friend_sm ();
- glusterd_op_sm ();
- }
-
- if (ctx) {
- glusterd_broadcast_friend_delete (ctx->hostname, NULL);
- glusterd_destroy_probe_ctx (ctx);
- }
-
- 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,
- int count, void *myframe)
-{
- return glusterd_big_locked_cbk (req, iov, count, myframe,
- __glusterd_friend_remove_cbk);
-}
-
-int32_t
-__glusterd_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;
-
- GF_ASSERT (req);
- this = THIS;
-
- if (-1 == req->rpc_status) {
- gf_log (this->name, GF_LOG_ERROR, "RPC Error");
- goto out;
- }
-
- ret = xdr_to_generic (*iov, &rsp,
- (xdrproc_t)xdr_gd1_mgmt_friend_update_rsp);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to serialize friend"
- " update repsonse");
- goto out;
- }
-
- ret = 0;
-out:
- gf_log (this->name, GF_LOG_INFO, "Received %s from uuid: %s",
- (ret)?"RJT":"ACC", uuid_utoa (rsp.uuid));
-
- GLUSTERD_STACK_DESTROY (((call_frame_t *)myframe));
- return ret;
-}
-
-int
-glusterd_friend_update_cbk (struct rpc_req *req, struct iovec *iov,
- int count, void *myframe)
-{
- return glusterd_big_locked_cbk (req, iov, count, myframe,
- __glusterd_friend_update_cbk);
-}
-
-int32_t
-__glusterd_cluster_lock_cbk (struct rpc_req *req, struct iovec *iov,
- int count, void *myframe)
-{
- gd1_mgmt_cluster_lock_rsp rsp = {{0},};
- int ret = -1;
- int32_t op_ret = -1;
- glusterd_op_sm_event_type_t event_type = GD_OP_EVENT_NONE;
- glusterd_peerinfo_t *peerinfo = NULL;
- xlator_t *this = NULL;
- uuid_t *txn_id = NULL;
- glusterd_conf_t *priv = NULL;
- char *err_str = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- priv = this->private;
- GF_ASSERT (priv);
- GF_ASSERT (req);
-
- txn_id = &priv->global_txn_id;
-
- if (-1 == req->rpc_status) {
- gf_log (this->name, GF_LOG_ERROR, "Lock response is not "
- "received from one of the peer");
- err_str = "Lock response is not received from one of the peer";
- glusterd_set_opinfo (err_str, ENETRESET, -1);
- event_type = GD_OP_EVENT_RCVD_RJT;
- goto out;
- }
-
- ret = xdr_to_generic (*iov, &rsp,
- (xdrproc_t)xdr_gd1_mgmt_cluster_lock_rsp);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to decode "
- "cluster lock response received from peer");
- err_str = "Failed to decode cluster lock response received from"
- " peer";
- glusterd_set_opinfo (err_str, EINVAL, -1);
- event_type = GD_OP_EVENT_RCVD_RJT;
- goto out;
- }
-
- op_ret = rsp.op_ret;
-
- gf_log (this->name, (op_ret) ? GF_LOG_ERROR : GF_LOG_DEBUG,
- "Received lock %s from uuid: %s", (op_ret) ? "RJT" : "ACC",
- uuid_utoa (rsp.uuid));
-
- peerinfo = glusterd_peerinfo_find (rsp.uuid, NULL);
- if (peerinfo == NULL) {
- gf_log (this->name, GF_LOG_CRITICAL,
- "cluster lock response received from unknown peer: %s."
- "Ignoring response", uuid_utoa (rsp.uuid));
- err_str = "cluster lock response received from unknown peer";
- goto out;
-
- }
-
- if (op_ret) {
- event_type = GD_OP_EVENT_RCVD_RJT;
- opinfo.op_ret = op_ret;
- opinfo.op_errstr = gf_strdup ("Another transaction could be in "
- "progress. Please try again after"
- " sometime.");
- } else {
- event_type = GD_OP_EVENT_RCVD_ACC;
- }
-
-out:
- ret = glusterd_op_sm_inject_event (event_type, txn_id, NULL);
-
- if (!ret) {
- glusterd_friend_sm ();
- glusterd_op_sm ();
- }
-
- GLUSTERD_STACK_DESTROY (((call_frame_t *)myframe));
- return ret;
-}
-
-int32_t
-glusterd_cluster_lock_cbk (struct rpc_req *req, struct iovec *iov,
- int count, void *myframe)
-{
- return glusterd_big_locked_cbk (req, iov, count, myframe,
- __glusterd_cluster_lock_cbk);
-}
-
-void
-glusterd_set_opinfo (char *errstr, int32_t op_errno, int32_t op_ret)
-{
- opinfo.op_errstr = gf_strdup (errstr);
- opinfo.op_errno = op_errno;
- opinfo.op_ret = op_ret;
-}
-
-static int32_t
-glusterd_mgmt_v3_lock_peers_cbk_fn (struct rpc_req *req, struct iovec *iov,
- int count, void *myframe)
-{
- gd1_mgmt_v3_lock_rsp rsp = {{0},};
- int ret = -1;
- int32_t op_ret = -1;
- glusterd_op_sm_event_type_t event_type = GD_OP_EVENT_NONE;
- glusterd_peerinfo_t *peerinfo = NULL;
- xlator_t *this = NULL;
- call_frame_t *frame = NULL;
- uuid_t *txn_id = NULL;
- char *err_str = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (req);
-
- frame = myframe;
- txn_id = frame->cookie;
- frame->cookie = NULL;
-
- if (-1 == req->rpc_status) {
- gf_log (this->name, GF_LOG_ERROR, "Lock response is not "
- "received from one of the peer");
- err_str = "Lock response is not received from one of the peer";
- glusterd_set_opinfo (err_str, ENETRESET, -1);
- event_type = GD_OP_EVENT_RCVD_RJT;
- goto out;
- }
-
- ret = xdr_to_generic (*iov, &rsp,
- (xdrproc_t)xdr_gd1_mgmt_v3_lock_rsp);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to decode "
- "mgmt_v3 lock response received from peer");
- err_str = "Failed to decode mgmt_v3 lock response received from"
- " peer";
- glusterd_set_opinfo (err_str, EINVAL, -1);
- event_type = GD_OP_EVENT_RCVD_RJT;
- goto out;
- }
-
- op_ret = rsp.op_ret;
-
- txn_id = &rsp.txn_id;
-
- gf_log (this->name, (op_ret) ? GF_LOG_ERROR : GF_LOG_DEBUG,
- "Received mgmt_v3 lock %s from uuid: %s",
- (op_ret) ? "RJT" : "ACC", uuid_utoa (rsp.uuid));
-
- peerinfo = glusterd_peerinfo_find (rsp.uuid, NULL);
- if (peerinfo == NULL) {
- gf_log (this->name, GF_LOG_CRITICAL,
- "mgmt_v3 lock response received "
- "from unknown peer: %s. Ignoring response",
- uuid_utoa (rsp.uuid));
- goto out;
- }
-
- if (op_ret) {
- event_type = GD_OP_EVENT_RCVD_RJT;
- opinfo.op_ret = op_ret;
- opinfo.op_errstr = gf_strdup ("Another transaction could be in "
- "progress. Please try again after"
- " sometime.");
- } else {
- event_type = GD_OP_EVENT_RCVD_ACC;
- }
-
-out:
- ret = glusterd_op_sm_inject_event (event_type, txn_id, NULL);
- if (!ret) {
- glusterd_friend_sm ();
- glusterd_op_sm ();
- }
-
- GF_FREE (frame->cookie);
- GLUSTERD_STACK_DESTROY (frame);
- return ret;
-}
-
-int32_t
-glusterd_mgmt_v3_lock_peers_cbk (struct rpc_req *req, struct iovec *iov,
- int count, void *myframe)
-{
- return glusterd_big_locked_cbk (req, iov, count, myframe,
- glusterd_mgmt_v3_lock_peers_cbk_fn);
-}
-
-static int32_t
-glusterd_mgmt_v3_unlock_peers_cbk_fn (struct rpc_req *req, struct iovec *iov,
- int count, void *myframe)
-{
- gd1_mgmt_v3_unlock_rsp rsp = {{0},};
- int ret = -1;
- int32_t op_ret = -1;
- glusterd_op_sm_event_type_t event_type = GD_OP_EVENT_NONE;
- glusterd_peerinfo_t *peerinfo = NULL;
- xlator_t *this = NULL;
- call_frame_t *frame = NULL;
- uuid_t *txn_id = NULL;
- char *err_str = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (req);
-
- frame = myframe;
- txn_id = frame->cookie;
- frame->cookie = NULL;
-
- if (-1 == req->rpc_status) {
- err_str = "Unlock response not received from one of the peer.";
- gf_msg (this->name, GF_LOG_ERROR, 0,
- GD_MSG_CLUSTER_UNLOCK_FAILED,
- "UnLock response is not received from one of the peer");
- glusterd_set_opinfo (err_str, 0, 0);
- event_type = GD_OP_EVENT_RCVD_RJT;
- goto out;
- }
-
- ret = xdr_to_generic (*iov, &rsp,
- (xdrproc_t)xdr_gd1_mgmt_v3_unlock_rsp);
- if (ret < 0) {
- gf_msg (this->name, GF_LOG_ERROR, 0,
- GD_MSG_CLUSTER_UNLOCK_FAILED,
- "Failed to decode mgmt_v3 unlock response received from"
- "peer");
- err_str = "Failed to decode mgmt_v3 unlock response received "
- "from peer";
- glusterd_set_opinfo (err_str, 0, 0);
- event_type = GD_OP_EVENT_RCVD_RJT;
- goto out;
- }
-
- op_ret = rsp.op_ret;
-
- txn_id = &rsp.txn_id;
-
- gf_log (this->name, (op_ret) ? GF_LOG_ERROR : GF_LOG_DEBUG,
- "Received mgmt_v3 unlock %s from uuid: %s",
- (op_ret) ? "RJT" : "ACC",
- uuid_utoa (rsp.uuid));
-
- peerinfo = glusterd_peerinfo_find (rsp.uuid, NULL);
- if (peerinfo == NULL) {
- gf_msg (this->name, GF_LOG_CRITICAL, 0,
- GD_MSG_CLUSTER_UNLOCK_FAILED,
- "mgmt_v3 unlock response received "
- "from unknown peer: %s. Ignoring response",
- uuid_utoa (rsp.uuid));
- goto out;
- }
-
- if (op_ret) {
- event_type = GD_OP_EVENT_RCVD_RJT;
- opinfo.op_ret = op_ret;
- opinfo.op_errstr = gf_strdup ("Another transaction could be in "
- "progress. Please try again after"
- " sometime.");
- } else {
- event_type = GD_OP_EVENT_RCVD_ACC;
- }
-
-out:
- ret = glusterd_op_sm_inject_event (event_type, txn_id, NULL);
-
- if (!ret) {
- glusterd_friend_sm ();
- glusterd_op_sm ();
- }
-
- GF_FREE (frame->cookie);
- GLUSTERD_STACK_DESTROY (frame);
- return ret;
-}
-
-int32_t
-glusterd_mgmt_v3_unlock_peers_cbk (struct rpc_req *req, struct iovec *iov,
- int count, void *myframe)
-{
- return glusterd_big_locked_cbk (req, iov, count, myframe,
- glusterd_mgmt_v3_unlock_peers_cbk_fn);
-}
-
-int32_t
-__glusterd_cluster_unlock_cbk (struct rpc_req *req, struct iovec *iov,
- int count, void *myframe)
-{
- gd1_mgmt_cluster_lock_rsp rsp = {{0},};
- int ret = -1;
- int32_t op_ret = -1;
- glusterd_op_sm_event_type_t event_type = GD_OP_EVENT_NONE;
- glusterd_peerinfo_t *peerinfo = NULL;
- xlator_t *this = NULL;
- uuid_t *txn_id = NULL;
- glusterd_conf_t *priv = NULL;
- char *err_str = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- priv = this->private;
- GF_ASSERT (priv);
- GF_ASSERT (req);
-
- txn_id = &priv->global_txn_id;
-
- if (-1 == req->rpc_status) {
- err_str = "Unlock response not received from one of the peer.";
- gf_msg (this->name, GF_LOG_ERROR, 0,
- GD_MSG_CLUSTER_UNLOCK_FAILED,
- "UnLock response is not received from one of the peer");
- glusterd_set_opinfo (err_str, 0, 0);
- event_type = GD_OP_EVENT_RCVD_RJT;
- goto out;
- }
-
- ret = xdr_to_generic (*iov, &rsp,
- (xdrproc_t)xdr_gd1_mgmt_cluster_unlock_rsp);
- if (ret < 0) {
- gf_msg (this->name, GF_LOG_ERROR, 0,
- GD_MSG_CLUSTER_UNLOCK_FAILED,
- "Failed to decode unlock response received from peer");
- err_str = "Failed to decode cluster unlock response received "
- "from peer";
- glusterd_set_opinfo (err_str, 0, 0);
- event_type = GD_OP_EVENT_RCVD_RJT;
- goto out;
- }
-
- op_ret = rsp.op_ret;
-
- gf_log (this->name, (op_ret) ? GF_LOG_ERROR : GF_LOG_DEBUG,
- "Received unlock %s from uuid: %s",
- (op_ret)?"RJT":"ACC", uuid_utoa (rsp.uuid));
-
- peerinfo = glusterd_peerinfo_find (rsp.uuid, NULL);
- if (peerinfo == NULL) {
- gf_msg (this->name, GF_LOG_CRITICAL, 0,
- GD_MSG_CLUSTER_UNLOCK_FAILED,
- "Unlock response received from unknown peer %s",
- uuid_utoa (rsp.uuid));
- goto out;
- }
-
- if (op_ret) {
- event_type = GD_OP_EVENT_RCVD_RJT;
- opinfo.op_ret = op_ret;
- } else {
- event_type = GD_OP_EVENT_RCVD_ACC;
- }
-
-out:
- ret = glusterd_op_sm_inject_event (event_type, txn_id, NULL);
-
- if (!ret) {
- glusterd_friend_sm ();
- glusterd_op_sm ();
- }
-
- GLUSTERD_STACK_DESTROY (((call_frame_t *)myframe));
- return ret;
-}
-
-int32_t
-glusterd_cluster_unlock_cbk (struct rpc_req *req, struct iovec *iov,
- int count, void *myframe)
-{
- return glusterd_big_locked_cbk (req, iov, count, myframe,
- __glusterd_cluster_unlock_cbk);
-}
-
-int32_t
-__glusterd_stage_op_cbk (struct rpc_req *req, struct iovec *iov,
- int count, void *myframe)
-{
- gd1_mgmt_stage_op_rsp rsp = {{0},};
- int ret = -1;
- int32_t op_ret = -1;
- glusterd_op_sm_event_type_t event_type = GD_OP_EVENT_NONE;
- glusterd_peerinfo_t *peerinfo = NULL;
- dict_t *dict = NULL;
- char err_str[2048] = {0};
- char *peer_str = NULL;
- xlator_t *this = NULL;
- glusterd_conf_t *priv = NULL;
- uuid_t *txn_id = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (req);
- priv = this->private;
- GF_ASSERT (priv);
-
- txn_id = &priv->global_txn_id;
-
- 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");
- goto out;
- }
-
- ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gd1_mgmt_stage_op_rsp);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to decode stage "
- "response received from peer");
- rsp.op_ret = -1;
- rsp.op_errno = EINVAL;
- /* use standard allocation because to keep uniformity
- in freeing it */
- rsp.op_errstr = strdup ("Failed to decode stage response "
- "received from peer.");
- goto out;
- }
-
- if (rsp.dict.dict_len) {
- /* Unserialize the dictionary */
- dict = dict_new ();
-
- ret = dict_unserialize (rsp.dict.dict_val,
- rsp.dict.dict_len,
- &dict);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "failed to "
- "unserialize rsp-buffer to dictionary");
- event_type = GD_OP_EVENT_RCVD_RJT;
- goto out;
- } else {
- dict->extra_stdfree = rsp.dict.dict_val;
- }
- }
-
-out:
- op_ret = rsp.op_ret;
-
- gf_log (this->name, (op_ret) ? GF_LOG_ERROR : GF_LOG_DEBUG,
- "Received stage %s from uuid: %s",
- (op_ret) ? "RJT" : "ACC", uuid_utoa (rsp.uuid));
-
- ret = dict_get_bin (dict, "transaction_id", (void **)&txn_id);
- gf_log (this->name, GF_LOG_DEBUG, "transaction ID = %s",
- uuid_utoa (*txn_id));
-
- peerinfo = glusterd_peerinfo_find (rsp.uuid, NULL);
- if (peerinfo == NULL) {
- gf_log (this->name, GF_LOG_CRITICAL, "Stage response received "
- "from unknown peer: %s. Ignoring response.",
- uuid_utoa (rsp.uuid));
- }
-
- if (op_ret) {
- event_type = GD_OP_EVENT_RCVD_RJT;
- opinfo.op_ret = op_ret;
- if (strcmp ("", rsp.op_errstr)) {
- opinfo.op_errstr = gf_strdup (rsp.op_errstr);
- } else {
- if (peerinfo)
- peer_str = peerinfo->hostname;
- else
- peer_str = uuid_utoa (rsp.uuid);
- snprintf (err_str, sizeof (err_str),
- OPERRSTR_STAGE_FAIL, peer_str);
- opinfo.op_errstr = gf_strdup (err_str);
- }
- if (!opinfo.op_errstr)
- ret = -1;
- } else {
- event_type = GD_OP_EVENT_RCVD_ACC;
- }
-
- switch (rsp.op) {
- case GD_OP_REPLACE_BRICK:
- glusterd_rb_use_rsp_dict (NULL, dict);
- break;
- }
-
- ret = glusterd_op_sm_inject_event (event_type, txn_id, NULL);
-
- if (!ret) {
- glusterd_friend_sm ();
- glusterd_op_sm ();
- }
-
- 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
- }
- GLUSTERD_STACK_DESTROY (((call_frame_t *)myframe));
- return ret;
-}
-
-int32_t
-glusterd_stage_op_cbk (struct rpc_req *req, struct iovec *iov,
- int count, void *myframe)
-{
- return glusterd_big_locked_cbk (req, iov, count, myframe,
- __glusterd_stage_op_cbk);
-}
-
-int32_t
-__glusterd_commit_op_cbk (struct rpc_req *req, struct iovec *iov,
- int count, void *myframe)
-{
- gd1_mgmt_commit_op_rsp rsp = {{0},};
- int ret = -1;
- int32_t op_ret = -1;
- glusterd_op_sm_event_type_t event_type = GD_OP_EVENT_NONE;
- glusterd_peerinfo_t *peerinfo = NULL;
- dict_t *dict = NULL;
- char err_str[2048] = {0};
- char *peer_str = NULL;
- xlator_t *this = NULL;
- glusterd_conf_t *priv = NULL;
- uuid_t *txn_id = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (req);
- priv = this->private;
- GF_ASSERT (priv);
-
- txn_id = &priv->global_txn_id;
-
- 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");
- event_type = GD_OP_EVENT_RCVD_RJT;
- goto out;
- }
-
- ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gd1_mgmt_commit_op_rsp);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to decode commit "
- "response received from peer");
- rsp.op_ret = -1;
- rsp.op_errno = EINVAL;
- /* use standard allocation because to keep uniformity
- in freeing it */
- rsp.op_errstr = strdup ("Failed to decode commit response "
- "received from peer.");
- event_type = GD_OP_EVENT_RCVD_RJT;
- goto out;
- }
-
- if (rsp.dict.dict_len) {
- /* Unserialize the dictionary */
- dict = dict_new ();
-
- ret = dict_unserialize (rsp.dict.dict_val,
- rsp.dict.dict_len,
- &dict);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "failed to "
- "unserialize rsp-buffer to dictionary");
- event_type = GD_OP_EVENT_RCVD_RJT;
- goto out;
- } else {
- dict->extra_stdfree = rsp.dict.dict_val;
- }
- }
-
- op_ret = rsp.op_ret;
-
- gf_log (this->name, (op_ret) ? GF_LOG_ERROR : GF_LOG_DEBUG,
- "Received commit %s from uuid: %s",
- (op_ret)?"RJT":"ACC", uuid_utoa (rsp.uuid));
-
- ret = dict_get_bin (dict, "transaction_id", (void **)&txn_id);
- gf_log (this->name, GF_LOG_DEBUG, "transaction ID = %s",
- uuid_utoa (*txn_id));
-
- peerinfo = glusterd_peerinfo_find (rsp.uuid, NULL);
- if (peerinfo == NULL) {
- gf_log (this->name, GF_LOG_CRITICAL, "Commit response for "
- "'Volume %s' received from unknown peer: %s",
- gd_op_list[opinfo.op], uuid_utoa (rsp.uuid));
- }
-
- if (op_ret) {
- event_type = GD_OP_EVENT_RCVD_RJT;
- opinfo.op_ret = op_ret;
- if (strcmp ("", rsp.op_errstr)) {
- opinfo.op_errstr = gf_strdup(rsp.op_errstr);
- } else {
- if (peerinfo)
- peer_str = peerinfo->hostname;
- else
- peer_str = uuid_utoa (rsp.uuid);
- snprintf (err_str, sizeof (err_str),
- OPERRSTR_COMMIT_FAIL, peer_str);
- opinfo.op_errstr = gf_strdup (err_str);
- }
- if (!opinfo.op_errstr) {
- ret = -1;
- goto out;
- }
- } else {
- event_type = GD_OP_EVENT_RCVD_ACC;
- switch (rsp.op) {
- case GD_OP_REPLACE_BRICK:
- ret = glusterd_rb_use_rsp_dict (NULL, dict);
- if (ret)
- goto out;
- break;
-
- case GD_OP_SYNC_VOLUME:
- ret = glusterd_sync_use_rsp_dict (NULL, dict);
- if (ret)
- goto out;
- break;
-
- case GD_OP_PROFILE_VOLUME:
- ret = glusterd_profile_volume_use_rsp_dict (NULL, dict);
- if (ret)
- goto out;
- break;
-
- case GD_OP_GSYNC_SET:
- ret = glusterd_gsync_use_rsp_dict (NULL, dict, rsp.op_errstr);
- if (ret)
- goto out;
- break;
-
- case GD_OP_STATUS_VOLUME:
- ret = glusterd_volume_status_copy_to_op_ctx_dict (NULL, dict);
- if (ret)
- goto out;
- break;
-
- case GD_OP_REBALANCE:
- case GD_OP_DEFRAG_BRICK_VOLUME:
- ret = glusterd_volume_rebalance_use_rsp_dict (NULL, dict);
- if (ret)
- goto out;
- break;
-
- case GD_OP_HEAL_VOLUME:
- ret = glusterd_volume_heal_use_rsp_dict (NULL, dict);
- if (ret)
- goto out;
-
- break;
-
- default:
- break;
- }
- }
-
-out:
- ret = glusterd_op_sm_inject_event (event_type, txn_id, NULL);
-
- if (!ret) {
- glusterd_friend_sm ();
- glusterd_op_sm ();
- }
-
- if (dict)
- dict_unref (dict);
- free (rsp.op_errstr); //malloced by xdr
- GLUSTERD_STACK_DESTROY (((call_frame_t *)myframe));
- return ret;
-}
-
-int32_t
-glusterd_commit_op_cbk (struct rpc_req *req, struct iovec *iov,
- int count, void *myframe)
-{
- return glusterd_big_locked_cbk (req, iov, count, myframe,
- __glusterd_commit_op_cbk);
-}
-
-int32_t
-glusterd_rpc_probe (call_frame_t *frame, xlator_t *this,
- void *data)
-{
- gd1_mgmt_probe_req req = {{0},};
- int ret = 0;
- int port = 0;
- char *hostname = NULL;
- glusterd_peerinfo_t *peerinfo = NULL;
- glusterd_conf_t *priv = NULL;
- dict_t *dict = NULL;
-
- if (!frame || !this || !data) {
- ret = -1;
- goto out;
- }
-
- dict = data;
- priv = this->private;
-
- GF_ASSERT (priv);
- ret = dict_get_str (dict, "hostname", &hostname);
- if (ret)
- goto out;
- ret = dict_get_int32 (dict, "port", &port);
- if (ret)
- port = GF_DEFAULT_BASE_PORT;
-
- ret = dict_get_ptr (dict, "peerinfo", VOID (&peerinfo));
- if (ret)
- goto out;
-
- uuid_copy (req.uuid, MY_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);
-
-out:
- 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)
-{
- 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;
- dict_t *peer_data = NULL;
-
-
- if (!frame || !this || !data) {
- ret = -1;
- goto out;
- }
-
- event = data;
- priv = this->private;
-
- GF_ASSERT (priv);
-
- peerinfo = event->peerinfo;
-
- ret = glusterd_add_volumes_to_export_dict (&peer_data);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Unable to add list of volumes "
- "in the peer_data dict for handshake");
- goto out;
- }
-
- if (priv->op_version >= GD_OP_VERSION_3_6_0) {
- ret = glusterd_add_missed_snaps_to_export_dict (peer_data);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Unable to add list of missed snapshots "
- "in the peer_data dict for handshake");
- goto out;
- }
-
- ret = glusterd_add_snapshots_to_export_dict (peer_data);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Unable to add list of snapshots "
- "in the peer_data dict for handshake");
- goto out;
- }
- }
-
- uuid_copy (req.uuid, MY_UUID);
- req.hostname = peerinfo->hostname;
- req.port = peerinfo->port;
-
- ret = dict_allocate_and_serialize (peer_data, &req.vols.vols_val,
- &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);
-
-
-out:
- GF_FREE (req.vols.vols_val);
-
- if (peer_data)
- dict_unref (peer_data);
-
- gf_log ("glusterd", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-
-int32_t
-glusterd_rpc_friend_remove (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;
-
- if (!frame || !this || !data) {
- ret = -1;
- goto out;
- }
-
- event = data;
- priv = this->private;
-
- GF_ASSERT (priv);
-
- peerinfo = event->peerinfo;
-
- uuid_copy (req.uuid, MY_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);
-
-out:
- gf_log ("glusterd", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-
-
-int32_t
-glusterd_rpc_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;
- call_frame_t *dummy_frame = NULL;
- glusterd_peerinfo_t *peerinfo = NULL;
-
- priv = this->private;
- GF_ASSERT (priv);
-
- friends = data;
- if (!friends)
- goto out;
-
- ret = dict_get_ptr (friends, "peerinfo", VOID(&peerinfo));
- if (ret)
- goto out;
-
- ret = dict_allocate_and_serialize (friends, &req.friends.friends_val,
- &req.friends.friends_len);
- if (ret)
- goto out;
-
- uuid_copy (req.uuid, MY_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);
-
-out:
- 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,
- void *data)
-{
- gd1_mgmt_cluster_lock_req req = {{0},};
- int ret = -1;
- glusterd_peerinfo_t *peerinfo = NULL;
- glusterd_conf_t *priv = NULL;
- call_frame_t *dummy_frame = NULL;
-
- if (!this)
- goto out;
-
- peerinfo = data;
-
- priv = this->private;
- GF_ASSERT (priv);
-
- glusterd_get_uuid (&req.uuid);
-
- 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_CLUSTER_LOCK,
- NULL,
- this, glusterd_cluster_lock_cbk,
- (xdrproc_t)xdr_gd1_mgmt_cluster_lock_req);
-out:
- gf_log (this->name, GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-
-int32_t
-glusterd_mgmt_v3_lock_peers (call_frame_t *frame, xlator_t *this,
- void *data)
-{
- gd1_mgmt_v3_lock_req req = {{0},};
- int ret = -1;
- glusterd_peerinfo_t *peerinfo = NULL;
- glusterd_conf_t *priv = NULL;
- dict_t *dict = NULL;
- uuid_t *txn_id = NULL;
-
- if (!this)
- goto out;
-
- dict = data;
-
- priv = this->private;
- GF_ASSERT (priv);
-
- ret = dict_get_ptr (dict, "peerinfo", VOID (&peerinfo));
- if (ret)
- goto out;
-
- //peerinfo should not be in payload
- dict_del (dict, "peerinfo");
-
- glusterd_get_uuid (&req.uuid);
-
- ret = dict_allocate_and_serialize (dict, &req.dict.dict_val,
- &req.dict.dict_len);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to serialize dict "
- "to request buffer");
- goto out;
- }
-
- /* Sending valid transaction ID to peers */
- ret = dict_get_bin (dict, "transaction_id",
- (void **)&txn_id);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to get transaction id.");
- goto out;
- } else {
- gf_log (this->name, GF_LOG_DEBUG,
- "Transaction_id = %s", uuid_utoa (*txn_id));
- uuid_copy (req.txn_id, *txn_id);
- }
-
- if (!frame)
- frame = create_frame (this, this->ctx->pool);
-
- if (!frame) {
- ret = -1;
- goto out;
- }
- frame->cookie = GF_CALLOC (1, sizeof(uuid_t), gf_common_mt_uuid_t);
- if (!frame->cookie) {
- ret = -1;
- goto out;
- }
- uuid_copy (frame->cookie, req.txn_id);
-
- ret = glusterd_submit_request (peerinfo->rpc, &req, frame,
- peerinfo->mgmt_v3,
- GLUSTERD_MGMT_V3_LOCK, NULL,
- this, glusterd_mgmt_v3_lock_peers_cbk,
- (xdrproc_t)xdr_gd1_mgmt_v3_lock_req);
-out:
- gf_log (this->name, GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-
-int32_t
-glusterd_mgmt_v3_unlock_peers (call_frame_t *frame, xlator_t *this,
- void *data)
-{
- gd1_mgmt_v3_unlock_req req = {{0},};
- int ret = -1;
- glusterd_peerinfo_t *peerinfo = NULL;
- glusterd_conf_t *priv = NULL;
- dict_t *dict = NULL;
- uuid_t *txn_id = NULL;
-
- if (!this)
- goto out;
-
- dict = data;
-
- priv = this->private;
- GF_ASSERT (priv);
-
- ret = dict_get_ptr (dict, "peerinfo", VOID (&peerinfo));
- if (ret)
- goto out;
-
- //peerinfo should not be in payload
- dict_del (dict, "peerinfo");
-
- glusterd_get_uuid (&req.uuid);
-
- ret = dict_allocate_and_serialize (dict, &req.dict.dict_val,
- &req.dict.dict_len);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to serialize dict "
- "to request buffer");
- goto out;
- }
-
- /* Sending valid transaction ID to peers */
- ret = dict_get_bin (dict, "transaction_id",
- (void **)&txn_id);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to get transaction id.");
- goto out;
- } else {
- gf_log (this->name, GF_LOG_DEBUG,
- "Transaction_id = %s", uuid_utoa (*txn_id));
- uuid_copy (req.txn_id, *txn_id);
- }
-
- if (!frame)
- frame = create_frame (this, this->ctx->pool);
-
- if (!frame) {
- ret = -1;
- goto out;
- }
- frame->cookie = GF_CALLOC (1, sizeof(uuid_t), gf_common_mt_uuid_t);
- if (!frame->cookie) {
- ret = -1;
- goto out;
- }
- uuid_copy (frame->cookie, req.txn_id);
-
- ret = glusterd_submit_request (peerinfo->rpc, &req, frame,
- peerinfo->mgmt_v3,
- GLUSTERD_MGMT_V3_UNLOCK, NULL,
- this, glusterd_mgmt_v3_unlock_peers_cbk,
- (xdrproc_t)
- xdr_gd1_mgmt_v3_unlock_req);
-out:
- gf_log (this->name, GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-
-int32_t
-glusterd_cluster_unlock (call_frame_t *frame, xlator_t *this,
- void *data)
-{
- gd1_mgmt_cluster_lock_req req = {{0},};
- int ret = -1;
- glusterd_peerinfo_t *peerinfo = NULL;
- glusterd_conf_t *priv = NULL;
- call_frame_t *dummy_frame = NULL;
-
- if (!this ) {
- ret = -1;
- goto out;
- }
- peerinfo = data;
- priv = this->private;
- GF_ASSERT (priv);
-
- glusterd_get_uuid (&req.uuid);
-
- 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_CLUSTER_UNLOCK,
- NULL,
- this, glusterd_cluster_unlock_cbk,
- (xdrproc_t)xdr_gd1_mgmt_cluster_unlock_req);
-out:
- gf_log (this->name, GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-
-int32_t
-glusterd_stage_op (call_frame_t *frame, xlator_t *this,
- void *data)
-{
- gd1_mgmt_stage_op_req req = {{0,},};
- int ret = -1;
- glusterd_peerinfo_t *peerinfo = NULL;
- glusterd_conf_t *priv = NULL;
- call_frame_t *dummy_frame = NULL;
- dict_t *dict = NULL;
- gf_boolean_t is_alloc = _gf_true;
-
- if (!this) {
- goto out;
- }
-
- dict = data;
-
- priv = this->private;
- GF_ASSERT (priv);
-
- ret = dict_get_ptr (dict, "peerinfo", VOID (&peerinfo));
- if (ret)
- goto out;
-
- //peerinfo should not be in payload
- dict_del (dict, "peerinfo");
-
- 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) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to serialize dict "
- "to request buffer");
- 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,
- NULL,
- this, glusterd_stage_op_cbk,
- (xdrproc_t)xdr_gd1_mgmt_stage_op_req);
-
-out:
- if ((_gf_true == is_alloc) && req.buf.buf_val)
- GF_FREE (req.buf.buf_val);
-
- gf_log (this->name, GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-
-int32_t
-glusterd_commit_op (call_frame_t *frame, xlator_t *this,
- void *data)
-{
- gd1_mgmt_commit_op_req req = {{0,},};
- int ret = -1;
- glusterd_peerinfo_t *peerinfo = NULL;
- glusterd_conf_t *priv = NULL;
- call_frame_t *dummy_frame = NULL;
- dict_t *dict = NULL;
- gf_boolean_t is_alloc = _gf_true;
-
- if (!this) {
- goto out;
- }
-
- dict = data;
- priv = this->private;
- GF_ASSERT (priv);
-
- ret = dict_get_ptr (dict, "peerinfo", VOID (&peerinfo));
- if (ret)
- goto out;
-
- //peerinfo should not be in payload
- dict_del (dict, "peerinfo");
-
- 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) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to serialize dict to "
- "request buffer");
- 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,
- NULL,
- this, glusterd_commit_op_cbk,
- (xdrproc_t)xdr_gd1_mgmt_commit_op_req);
-
-out:
- if ((_gf_true == is_alloc) && req.buf.buf_val)
- GF_FREE (req.buf.buf_val);
-
- gf_log (this->name, GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-
-int32_t
-__glusterd_brick_op_cbk (struct rpc_req *req, struct iovec *iov,
- int count, void *myframe)
-{
- gd1_mgmt_brick_op_rsp rsp = {0};
- int ret = -1;
- int32_t op_ret = -1;
- 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;
- dict_t *dict = NULL;
- int index = 0;
- glusterd_req_ctx_t *req_ctx = NULL;
- glusterd_pending_node_t *node = NULL;
- xlator_t *this = NULL;
- uuid_t *txn_id = NULL;
- glusterd_conf_t *priv = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- priv = this->private;
- GF_ASSERT (priv);
- GF_ASSERT (req);
-
- txn_id = &priv->global_txn_id;
- 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");
- event_type = GD_OP_EVENT_RCVD_RJT;
- goto out;
- }
-
- ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gd1_mgmt_brick_op_rsp);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to decode brick op "
- "response received");
- rsp.op_ret = -1;
- rsp.op_errno = EINVAL;
- rsp.op_errstr = strdup ("Unable to decode brick op response");
- event_type = GD_OP_EVENT_RCVD_RJT;
- goto out;
- }
-
- if (rsp.output.output_len) {
- /* Unserialize the dictionary */
- dict = dict_new ();
-
- ret = dict_unserialize (rsp.output.output_val,
- rsp.output.output_len,
- &dict);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to "
- "unserialize rsp-buffer to dictionary");
- event_type = GD_OP_EVENT_RCVD_RJT;
- goto out;
- } else {
- dict->extra_stdfree = rsp.output.output_val;
- }
- }
-
- 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:
-
- if (req_ctx && req_ctx->dict) {
- ret = dict_get_bin (req_ctx->dict, "transaction_id",
- (void **)&txn_id);
- gf_log (this->name, GF_LOG_DEBUG,
- "transaction ID = %s", uuid_utoa (*txn_id));
- }
-
- ev_ctx = GF_CALLOC (1, sizeof (*ev_ctx), gf_gld_mt_brick_rsp_ctx_t);
- GF_ASSERT (ev_ctx);
- if (op_ret) {
- event_type = GD_OP_EVENT_RCVD_RJT;
- ev_ctx->op_ret = op_ret;
- ev_ctx->op_errstr = gf_strdup(rsp.op_errstr);
- } else {
- event_type = GD_OP_EVENT_RCVD_ACC;
- }
- ev_ctx->pending_node = frame->cookie;
- ev_ctx->rsp_dict = dict;
- ev_ctx->commit_ctx = frame->local;
- ret = glusterd_op_sm_inject_event (event_type, txn_id, ev_ctx);
- if (!ret) {
- glusterd_friend_sm ();
- glusterd_op_sm ();
- }
-
- if (ret && dict)
- dict_unref (dict);
- free (rsp.op_errstr); //malloced by xdr
- GLUSTERD_STACK_DESTROY (frame);
- return ret;
-}
-
-int32_t
-glusterd_brick_op_cbk (struct rpc_req *req, struct iovec *iov,
- int count, void *myframe)
-{
- return glusterd_big_locked_cbk (req, iov, count, myframe,
- __glusterd_brick_op_cbk);
-}
-
-int32_t
-glusterd_brick_op (call_frame_t *frame, xlator_t *this,
- void *data)
-{
-
- gd1_mgmt_brick_op_req *req = NULL;
- int ret = 0;
- glusterd_conf_t *priv = NULL;
- 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;
- uuid_t *txn_id = NULL;
-
- if (!this) {
- ret = -1;
- goto out;
- }
- priv = this->private;
- GF_ASSERT (priv);
-
- txn_id = &priv->global_txn_id;
-
- req_ctx = data;
- GF_ASSERT (req_ctx);
- INIT_LIST_HEAD (&opinfo.pending_bricks);
-
- ret = dict_get_bin (req_ctx->dict, "transaction_id", (void **)&txn_id);
- gf_log (this->name, GF_LOG_DEBUG, "transaction ID = %s",
- uuid_utoa (*txn_id));
-
- ret = glusterd_op_bricks_select (req_ctx->op, req_ctx->dict, &op_errstr,
- &opinfo.pending_bricks, NULL);
-
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to select bricks "
- "while performing brick op during 'Volume %s'",
- gd_op_list[opinfo.op]);
- opinfo.op_errstr = op_errstr;
- goto out;
- }
-
- list_for_each_entry (pending_node, &opinfo.pending_bricks, list) {
- dummy_frame = create_frame (this, this->ctx->pool);
- if (!dummy_frame)
- continue;
-
- if ((pending_node->type == GD_NODE_NFS) ||
- (pending_node->type == GD_NODE_QUOTAD) ||
- (pending_node->type == GD_NODE_SNAPD) ||
- ((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);
-
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to "
- "build brick op payload during "
- "'Volume %s'", gd_op_list[req_ctx->op]);
- 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,
- req->op, NULL,
- this, glusterd_brick_op_cbk,
- (xdrproc_t)xdr_gd1_mgmt_brick_op_req);
- if (req) {
- GF_FREE (req->input.input_val);
- GF_FREE (req);
- req = NULL;
- }
- if (!ret)
- pending_bricks++;
- }
-
- gf_log (this->name, GF_LOG_DEBUG, "Sent brick op req for operation "
- "'Volume %s' to %d bricks", gd_op_list[req_ctx->op],
- pending_bricks);
- opinfo.brick_pending_count = pending_bricks;
-
-out:
- if (ret) {
- glusterd_op_sm_inject_event (GD_OP_EVENT_RCVD_RJT,
- txn_id, data);
- opinfo.op_ret = ret;
- }
- gf_log (this->name, 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_procedure gd_mgmt_v3_actors[GLUSTERD_MGMT_V3_MAXVALUE] = {
- [GLUSTERD_MGMT_V3_NULL] = {"NULL", NULL },
- [GLUSTERD_MGMT_V3_LOCK] = {"MGMT_V3_LOCK", glusterd_mgmt_v3_lock_peers},
- [GLUSTERD_MGMT_V3_UNLOCK] = {"MGMT_V3_UNLOCK", glusterd_mgmt_v3_unlock_peers},
-};
-
-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,
-};
-
-struct rpc_clnt_program gd_mgmt_v3_prog = {
- .progname = "glusterd mgmt v3",
- .prognum = GD_MGMT_PROGRAM,
- .progver = GD_MGMT_V3_VERSION,
- .proctable = gd_mgmt_v3_actors,
- .numproc = GLUSTERD_MGMT_V3_MAXVALUE,
-};
diff --git a/xlators/mgmt/glusterd/src/glusterd-sm.c b/xlators/mgmt/glusterd/src/glusterd-sm.c
deleted file mode 100644
index 6b30361e3d5..00000000000
--- a/xlators/mgmt/glusterd/src/glusterd-sm.c
+++ /dev/null
@@ -1,1156 +0,0 @@
-/*
- Copyright (c) 2006-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 <time.h>
-#include <sys/uio.h>
-#include <sys/resource.h>
-
-#include <libgen.h>
-#include "uuid.h"
-
-#include "fnmatch.h"
-#include "xlator.h"
-#include "protocol-common.h"
-#include "glusterd.h"
-#include "call-stub.h"
-#include "defaults.h"
-#include "list.h"
-#include "glusterd-messages.h"
-#include "dict.h"
-#include "compat.h"
-#include "compat-errno.h"
-#include "statedump.h"
-#include "glusterd-sm.h"
-#include "glusterd-op-sm.h"
-#include "glusterd-utils.h"
-#include "glusterd-store.h"
-
-static struct list_head gd_friend_sm_queue;
-
-static char *glusterd_friend_sm_state_names[] = {
- "Establishing Connection",
- "Probe Sent to Peer",
- "Probe Received from Peer",
- "Peer in Cluster",
- "Accepted peer request",
- "Sent and Received peer request",
- "Peer Rejected",
- "Peer detach in progress",
- "Probe Received from peer",
- "Connected to Peer",
- "Peer is connected and Accepted",
- "Invalid State"
-};
-
-static char *glusterd_friend_sm_event_names[] = {
- "GD_FRIEND_EVENT_NONE",
- "GD_FRIEND_EVENT_PROBE",
- "GD_FRIEND_EVENT_INIT_FRIEND_REQ",
- "GD_FRIEND_EVENT_RCVD_ACC",
- "GD_FRIEND_EVENT_LOCAL_ACC",
- "GD_FRIEND_EVENT_RCVD_RJT",
- "GD_FRIEND_EVENT_LOCAL_RJT",
- "GD_FRIEND_EVENT_RCVD_FRIEND_REQ",
- "GD_FRIEND_EVENT_INIT_REMOVE_FRIEND",
- "GD_FRIEND_EVENT_RCVD_REMOVE_FRIEND",
- "GD_FRIEND_EVENT_REMOVE_FRIEND",
- "GD_FRIEND_EVENT_CONNECTED",
- "GD_FRIEND_EVENT_MAX"
-};
-
-char*
-glusterd_friend_sm_state_name_get (int state)
-{
- if (state < 0 || state >= GD_FRIEND_STATE_MAX)
- return glusterd_friend_sm_state_names[GD_FRIEND_STATE_MAX];
- return glusterd_friend_sm_state_names[state];
-}
-
-char*
-glusterd_friend_sm_event_name_get (int event)
-{
- if (event < 0 || event >= GD_FRIEND_EVENT_MAX)
- return glusterd_friend_sm_event_names[GD_FRIEND_EVENT_MAX];
- return glusterd_friend_sm_event_names[event];
-}
-
-void
-glusterd_destroy_probe_ctx (glusterd_probe_ctx_t *ctx)
-{
- if (!ctx)
- return;
-
- GF_FREE (ctx->hostname);
- GF_FREE (ctx);
-}
-
-void
-glusterd_destroy_friend_req_ctx (glusterd_friend_req_ctx_t *ctx)
-{
- if (!ctx)
- return;
-
- if (ctx->vols)
- dict_unref (ctx->vols);
- GF_FREE (ctx->hostname);
- GF_FREE (ctx);
-}
-
-void
-glusterd_destroy_friend_update_ctx (glusterd_friend_update_ctx_t *ctx)
-{
- if (!ctx)
- return;
- GF_FREE (ctx->hostname);
- GF_FREE (ctx);
-}
-
-int
-glusterd_broadcast_friend_delete (char *hostname, uuid_t uuid)
-{
- int ret = 0;
- rpc_clnt_procedure_t *proc = NULL;
- xlator_t *this = NULL;
- glusterd_friend_update_ctx_t ctx = {{0},};
- glusterd_peerinfo_t *peerinfo = NULL;
- glusterd_conf_t *priv = NULL;
- dict_t *friends = NULL;
- char key[100] = {0,};
- int32_t count = 0;
-
- this = THIS;
- priv = this->private;
-
- GF_ASSERT (priv);
-
- ctx.hostname = hostname;
- ctx.op = GD_FRIEND_UPDATE_DEL;
-
- friends = dict_new ();
- if (!friends)
- goto out;
-
- snprintf (key, sizeof (key), "op");
- ret = dict_set_int32 (friends, key, ctx.op);
- if (ret)
- goto out;
-
- snprintf (key, sizeof (key), "hostname");
- ret = dict_set_str (friends, key, hostname);
- if (ret)
- goto out;
-
- ret = dict_set_int32 (friends, "count", count);
- if (ret)
- goto out;
-
- list_for_each_entry (peerinfo, &priv->peers, uuid_list) {
- if (!peerinfo->connected || !peerinfo->peer)
- continue;
-
- ret = dict_set_static_ptr (friends, "peerinfo", peerinfo);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "failed to set peerinfo");
- goto out;
- }
-
- proc = &peerinfo->peer->proctable[GLUSTERD_FRIEND_UPDATE];
- if (proc->fn) {
- ret = proc->fn (NULL, this, friends);
- }
- }
-
- gf_log ("", GF_LOG_DEBUG, "Returning with %d", ret);
-
-out:
- if (friends)
- dict_unref (friends);
-
- return ret;
-}
-
-
-static int
-glusterd_ac_none (glusterd_friend_sm_event_t *event, void *ctx)
-{
- int ret = 0;
-
- gf_log ("", GF_LOG_DEBUG, "Returning with %d", ret);
-
- return ret;
-}
-
-static int
-glusterd_ac_error (glusterd_friend_sm_event_t *event, void *ctx)
-{
- int ret = 0;
-
- gf_log ("", GF_LOG_ERROR, "Received event %d ", event->event);
-
- return ret;
-}
-
-static int
-glusterd_ac_reverse_probe_begin (glusterd_friend_sm_event_t *event, void *ctx)
-{
- int ret = 0;
- glusterd_peerinfo_t *peerinfo = NULL;
- glusterd_friend_sm_event_t *new_event = NULL;
- glusterd_probe_ctx_t *new_ev_ctx = NULL;
-
- GF_ASSERT (event);
- GF_ASSERT (ctx);
-
- peerinfo = event->peerinfo;
- ret = glusterd_friend_sm_new_event
- (GD_FRIEND_EVENT_PROBE, &new_event);
-
- if (ret) {
- gf_log ("glusterd", GF_LOG_ERROR, "Unable to get new new_event");
- ret = -1;
- goto out;
- }
-
- new_ev_ctx = GF_CALLOC (1, sizeof(*new_ev_ctx), gf_gld_mt_probe_ctx_t);
-
- if (!new_ev_ctx) {
- ret = -1;
- goto out;
- }
-
- new_ev_ctx->hostname = gf_strdup (peerinfo->hostname);
- new_ev_ctx->port = peerinfo->port;
- new_ev_ctx->req = NULL;
-
- new_event->peerinfo = peerinfo;
- new_event->ctx = new_ev_ctx;
-
- ret = glusterd_friend_sm_inject_event (new_event);
-
- if (ret) {
- gf_log ("glusterd", GF_LOG_ERROR, "Unable to inject new_event %d, "
- "ret = %d", new_event->event, ret);
- }
-
-out:
- if (ret) {
- GF_FREE (new_event);
- if (new_ev_ctx)
- GF_FREE (new_ev_ctx->hostname);
- GF_FREE (new_ev_ctx);
- }
- gf_log ("", GF_LOG_DEBUG, "returning with %d", ret);
- return ret;
-}
-
-static int
-glusterd_ac_friend_add (glusterd_friend_sm_event_t *event, void *ctx)
-{
- int ret = 0;
- glusterd_peerinfo_t *peerinfo = NULL;
- rpc_clnt_procedure_t *proc = NULL;
- call_frame_t *frame = NULL;
- glusterd_conf_t *conf = NULL;
- xlator_t *this = NULL;
-
- GF_ASSERT (event);
- peerinfo = event->peerinfo;
-
- this = THIS;
- conf = this->private;
-
- GF_ASSERT (conf);
-
- if (!peerinfo->peer)
- goto out;
- proc = &peerinfo->peer->proctable[GLUSTERD_FRIEND_ADD];
- if (proc->fn) {
- frame = create_frame (this, this->ctx->pool);
- if (!frame) {
- goto out;
- }
- frame->local = ctx;
- ret = proc->fn (frame, this, event);
- }
-
-out:
- gf_log ("", GF_LOG_DEBUG, "Returning with %d", ret);
-
- return ret;
-}
-
-static int
-glusterd_ac_friend_probe (glusterd_friend_sm_event_t *event, void *ctx)
-{
- int ret = -1;
- rpc_clnt_procedure_t *proc = NULL;
- call_frame_t *frame = NULL;
- glusterd_conf_t *conf = NULL;
- xlator_t *this = NULL;
- glusterd_probe_ctx_t *probe_ctx = NULL;
- glusterd_peerinfo_t *peerinfo = NULL;
- dict_t *dict = NULL;
-
- GF_ASSERT (ctx);
-
- probe_ctx = ctx;
-
- this = THIS;
-
- GF_ASSERT (this);
-
- conf = this->private;
-
- GF_ASSERT (conf);
-
- peerinfo = glusterd_peerinfo_find (NULL, probe_ctx->hostname);
- if (peerinfo == NULL) {
- //We should not reach this state ideally
- GF_ASSERT (0);
- goto out;
- }
-
- if (!peerinfo->peer)
- goto out;
- proc = &peerinfo->peer->proctable[GLUSTERD_PROBE_QUERY];
- if (proc->fn) {
- frame = create_frame (this, this->ctx->pool);
- if (!frame) {
- goto out;
- }
- frame->local = ctx;
- dict = dict_new ();
- if (!dict)
- goto out;
- ret = dict_set_str (dict, "hostname", probe_ctx->hostname);
- if (ret)
- goto out;
-
- ret = dict_set_int32 (dict, "port", probe_ctx->port);
- if (ret)
- goto out;
-
- ret = dict_set_static_ptr (dict, "peerinfo", peerinfo);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "failed to set peerinfo");
- goto out;
- }
-
- ret = proc->fn (frame, this, dict);
- if (ret)
- goto out;
-
- }
-
-
-out:
- if (dict)
- dict_unref (dict);
- gf_log ("", GF_LOG_DEBUG, "Returning with %d", ret);
-
- return ret;
-}
-
-static int
-glusterd_ac_send_friend_remove_req (glusterd_friend_sm_event_t *event,
- void *data)
-{
- int ret = 0;
- glusterd_peerinfo_t *peerinfo = NULL;
- rpc_clnt_procedure_t *proc = NULL;
- call_frame_t *frame = NULL;
- glusterd_conf_t *conf = NULL;
- xlator_t *this = NULL;
- glusterd_friend_sm_event_type_t event_type = GD_FRIEND_EVENT_NONE;
- glusterd_probe_ctx_t *ctx = NULL;
- glusterd_friend_sm_event_t *new_event = NULL;
-
- GF_ASSERT (event);
- peerinfo = event->peerinfo;
-
- this = THIS;
- conf = this->private;
-
- GF_ASSERT (conf);
-
- ctx = event->ctx;
-
- if (!peerinfo->connected) {
- event_type = GD_FRIEND_EVENT_REMOVE_FRIEND;
-
- ret = glusterd_friend_sm_new_event (event_type, &new_event);
-
- if (!ret) {
- new_event->peerinfo = peerinfo;
- ret = glusterd_friend_sm_inject_event (new_event);
- } else {
- gf_log ("glusterd", GF_LOG_ERROR,
- "Unable to get event");
- }
-
- if (ctx)
- ret = glusterd_xfer_cli_deprobe_resp (ctx->req, ret, 0,
- NULL,
- ctx->hostname,
- ctx->dict);
- glusterd_friend_sm ();
- glusterd_op_sm ();
-
- if (ctx) {
- glusterd_broadcast_friend_delete (ctx->hostname, NULL);
- glusterd_destroy_probe_ctx (ctx);
- }
- goto out;
- }
-
- if (!peerinfo->peer)
- goto out;
- proc = &peerinfo->peer->proctable[GLUSTERD_FRIEND_REMOVE];
- if (proc->fn) {
- frame = create_frame (this, this->ctx->pool);
- if (!frame) {
- goto out;
- }
- frame->local = data;
- ret = proc->fn (frame, this, event);
- }
-
-out:
- gf_log ("", GF_LOG_DEBUG, "Returning with %d", ret);
-
- 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,};
- int32_t count = 0;
-
- GF_ASSERT (event);
- cur_peerinfo = event->peerinfo;
-
- this = THIS;
- priv = this->private;
-
- GF_ASSERT (priv);
-
- ev_ctx.op = GD_FRIEND_UPDATE_ADD;
-
- friends = dict_new ();
- if (!friends)
- goto out;
-
- snprintf (key, sizeof (key), "op");
- ret = dict_set_int32 (friends, key, ev_ctx.op);
- if (ret)
- goto out;
-
- list_for_each_entry (peerinfo, &priv->peers, uuid_list) {
- if (!glusterd_should_update_peer (peerinfo, cur_peerinfo))
- continue;
-
- count++;
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "friend%d", count);
- ret = gd_add_friend_to_dict (peerinfo, friends, key);
- if (ret)
- goto out;
- }
-
- ret = dict_set_int32 (friends, "count", count);
- if (ret)
- 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))
- continue;
-
- ret = dict_set_static_ptr (friends, "peerinfo", peerinfo);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "failed to set peerinfo");
- goto out;
- }
-
- proc = &peerinfo->peer->proctable[GLUSTERD_FRIEND_UPDATE];
- if (proc->fn) {
- ret = proc->fn (NULL, this, friends);
- }
- }
-
- gf_log ("", GF_LOG_DEBUG, "Returning with %d", ret);
-
-out:
- if (friends)
- dict_unref (friends);
-
- return ret;
-}
-
-/* Clean up stale volumes on the peer being detached. The volumes which have
- * bricks on other peers are stale with respect to the detached peer.
- */
-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) {
- /* The peer detach checks make sure that, at this point in the
- * detach process, there are only volumes contained completely
- * within or completely outside the detached peer.
- * The only stale volumes at this point are the ones
- * completely outside the peer and can be safely deleted.
- */
- 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,
- void *ctx)
-{
- int ret = 0;
- glusterd_peerinfo_t *peerinfo = NULL;
- glusterd_friend_req_ctx_t *ev_ctx = NULL;
- glusterd_friend_sm_event_t *new_event = NULL;
- glusterd_conf_t *priv = NULL;
-
- GF_ASSERT (ctx);
- ev_ctx = ctx;
- peerinfo = event->peerinfo;
- GF_ASSERT (peerinfo);
-
- priv = THIS->private;
- GF_ASSERT (priv);
-
- ret = glusterd_xfer_friend_remove_resp (ev_ctx->req, ev_ctx->hostname,
- ev_ctx->port);
-
- list_for_each_entry (peerinfo, &priv->peers, uuid_list) {
-
- ret = glusterd_friend_sm_new_event (GD_FRIEND_EVENT_REMOVE_FRIEND,
- &new_event);
- if (ret)
- goto out;
-
- new_event->peerinfo = peerinfo;
-
- ret = glusterd_friend_sm_inject_event (new_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);
-
- return ret;
-}
-
-static int
-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_msg (THIS->name, GF_LOG_WARNING, 0, GD_MSG_VOL_CLEANUP_FAIL,
- "Volumes cleanup failed");
-
- ret = glusterd_peerinfo_cleanup (event->peerinfo);
- if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR, "Cleanup returned: %d", ret);
- }
-
- return 0;
-}
-
-/*static int
-glusterd_ac_none (void *ctx)
-{
- int ret = 0;
-
- gf_log ("", GF_LOG_DEBUG, "Returning with %d", ret);
-
- return ret;
-}*/
-
-static int
-glusterd_ac_handle_friend_add_req (glusterd_friend_sm_event_t *event, void *ctx)
-{
- int ret = 0;
- uuid_t uuid;
- glusterd_peerinfo_t *peerinfo = NULL;
- glusterd_friend_req_ctx_t *ev_ctx = NULL;
- glusterd_friend_update_ctx_t *new_ev_ctx = NULL;
- glusterd_friend_sm_event_t *new_event = NULL;
- glusterd_friend_sm_event_type_t event_type = GD_FRIEND_EVENT_NONE;
- glusterd_conf_t *conf = NULL;
- int status = 0;
- int32_t op_ret = -1;
- int32_t op_errno = 0;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (ctx);
- ev_ctx = ctx;
- uuid_copy (uuid, ev_ctx->uuid);
- peerinfo = event->peerinfo;
- GF_ASSERT (peerinfo);
- uuid_copy (peerinfo->uuid, ev_ctx->uuid);
-
- conf = this->private;
- GF_ASSERT (conf);
-
- //Build comparison logic here.
- ret = glusterd_compare_friend_data (ev_ctx->vols, &status,
- peerinfo->hostname);
- if (ret)
- goto out;
-
- if (GLUSTERD_VOL_COMP_RJT != status) {
- event_type = GD_FRIEND_EVENT_LOCAL_ACC;
- op_ret = 0;
- } else {
- event_type = GD_FRIEND_EVENT_LOCAL_RJT;
- op_errno = GF_PROBE_VOLUME_CONFLICT;
- op_ret = -1;
- }
-
- /* Compare missed_snapshot list with the peer *
- * if volume comparison is successful */
- if ((op_ret == 0) &&
- (conf->op_version >= GD_OP_VERSION_3_6_0)) {
- ret = glusterd_import_friend_missed_snap_list (ev_ctx->vols);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to import peer's "
- "missed_snaps_list.");
- event_type = GD_FRIEND_EVENT_LOCAL_RJT;
- op_errno = GF_PROBE_MISSED_SNAP_CONFLICT;
- op_ret = -1;
- }
-
- ret = glusterd_compare_friend_snapshots (ev_ctx->vols,
- peerinfo);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Conflict in comparing peer's snapshots");
- event_type = GD_FRIEND_EVENT_LOCAL_RJT;
- op_errno = GF_PROBE_SNAP_CONFLICT;
- op_ret = -1;
- }
- }
-
- ret = glusterd_friend_sm_new_event (event_type, &new_event);
-
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Out of Memory");
- }
-
- new_event->peerinfo = peerinfo;
-
- new_ev_ctx = GF_CALLOC (1, sizeof (*new_ev_ctx),
- gf_gld_mt_friend_update_ctx_t);
- if (!new_ev_ctx) {
- ret = -1;
- goto out;
- }
-
- uuid_copy (new_ev_ctx->uuid, ev_ctx->uuid);
- new_ev_ctx->hostname = gf_strdup (ev_ctx->hostname);
- new_ev_ctx->op = GD_FRIEND_UPDATE_ADD;
-
- new_event->ctx = new_ev_ctx;
-
- glusterd_friend_sm_inject_event (new_event);
-
- ret = glusterd_xfer_friend_add_resp (ev_ctx->req, ev_ctx->hostname,
- peerinfo->hostname, ev_ctx->port,
- op_ret, op_errno);
-
-out:
- gf_log ("", GF_LOG_DEBUG, "Returning with %d", ret);
-
- return ret;
-}
-
-static int
-glusterd_friend_sm_transition_state (glusterd_peerinfo_t *peerinfo,
- glusterd_sm_t *state,
- glusterd_friend_sm_event_type_t event_type)
-{
-
- GF_ASSERT (state);
- GF_ASSERT (peerinfo);
-
- (void) glusterd_sm_tr_log_transition_add (&peerinfo->sm_log,
- peerinfo->state.state,
- state[event_type].next_state,
- event_type);
-
- peerinfo->state.state = state[event_type].next_state;
- return 0;
-}
-
-
-glusterd_sm_t glusterd_state_default [] = {
- {GD_FRIEND_STATE_DEFAULT, glusterd_ac_none},
- {GD_FRIEND_STATE_DEFAULT, glusterd_ac_friend_probe},//EV_PROBE
- {GD_FRIEND_STATE_REQ_SENT, glusterd_ac_friend_add}, //EV_INIT_FRIEND_REQ
- {GD_FRIEND_STATE_DEFAULT, glusterd_ac_none}, //EVENT_RCVD_ACC
- {GD_FRIEND_STATE_DEFAULT, glusterd_ac_none}, //EVENT_RCVD_LOCAL_ACC
- {GD_FRIEND_STATE_DEFAULT, glusterd_ac_none}, //EVENT_RCVD_RJT
- {GD_FRIEND_STATE_DEFAULT, glusterd_ac_none}, //EVENT_RCVD_LOCAL_RJT
- {GD_FRIEND_STATE_REQ_RCVD, glusterd_ac_handle_friend_add_req}, //EVENT_RCV_FRIEND_REQ
- {GD_FRIEND_STATE_DEFAULT, glusterd_ac_send_friend_remove_req}, //EV_INIT_REMOVE_FRIEND
- {GD_FRIEND_STATE_DEFAULT, glusterd_ac_none}, //EVENT_RCVD_REMOVE_FRIEND
- {GD_FRIEND_STATE_DEFAULT, glusterd_ac_friend_remove}, //EVENT_REMOVE_FRIEND
- {GD_FRIEND_STATE_DEFAULT, glusterd_ac_friend_probe}, //EVENT_CONNECTED
- {GD_FRIEND_STATE_DEFAULT, glusterd_ac_none}, //EVENT_MAX
-};
-
-glusterd_sm_t glusterd_state_probe_rcvd [] = {
- {GD_FRIEND_STATE_PROBE_RCVD, glusterd_ac_none},
- {GD_FRIEND_STATE_PROBE_RCVD, glusterd_ac_none}, //EV_PROBE
- {GD_FRIEND_STATE_PROBE_RCVD, glusterd_ac_none}, //EV_INIT_FRIEND_REQ
- {GD_FRIEND_STATE_PROBE_RCVD, glusterd_ac_none}, //EVENT_RCVD_ACC
- {GD_FRIEND_STATE_PROBE_RCVD, glusterd_ac_none}, //EVENT_RCVD_LOCAL_ACC
- {GD_FRIEND_STATE_PROBE_RCVD, glusterd_ac_none}, //EVENT_RCVD_RJT
- {GD_FRIEND_STATE_PROBE_RCVD, glusterd_ac_none}, //EVENT_RCVD_LOCAL_RJT
- {GD_FRIEND_STATE_REQ_RCVD, glusterd_ac_handle_friend_add_req}, //EVENT_RCV_FRIEND_REQ
- {GD_FRIEND_STATE_DEFAULT, glusterd_ac_send_friend_remove_req}, //EV_INIT_REMOVE_FRIEND
- {GD_FRIEND_STATE_DEFAULT, glusterd_ac_none}, //EVENT_RCVD_REMOVE_FRIEND
- {GD_FRIEND_STATE_DEFAULT, glusterd_ac_friend_remove}, //EVENT_REMOVE_FRIEND
- {GD_FRIEND_STATE_CONNECTED_RCVD, glusterd_ac_none}, //EVENT_CONNECTED
- {GD_FRIEND_STATE_DEFAULT, glusterd_ac_none}, //EVENT_MAX
-};
-
-glusterd_sm_t glusterd_state_connected_rcvd [] = {
- {GD_FRIEND_STATE_CONNECTED_RCVD, glusterd_ac_none},
- {GD_FRIEND_STATE_CONNECTED_RCVD, glusterd_ac_none}, //EV_PROBE
- {GD_FRIEND_STATE_CONNECTED_RCVD, glusterd_ac_none}, //EV_INIT_FRIEND_REQ
- {GD_FRIEND_STATE_CONNECTED_RCVD, glusterd_ac_none}, //EVENT_RCVD_ACC
- {GD_FRIEND_STATE_CONNECTED_ACCEPTED, glusterd_ac_reverse_probe_begin}, //EVENT_RCVD_LOCAL_ACC
- {GD_FRIEND_STATE_CONNECTED_RCVD, glusterd_ac_none}, //EVENT_RCVD_RJT
- {GD_FRIEND_STATE_REJECTED, glusterd_ac_none}, //EVENT_RCVD_LOCAL_RJT
- {GD_FRIEND_STATE_CONNECTED_RCVD, glusterd_ac_handle_friend_add_req}, //EVENT_RCV_FRIEND_REQ
- {GD_FRIEND_STATE_DEFAULT, glusterd_ac_send_friend_remove_req}, //EV_INIT_REMOVE_FRIEND
- {GD_FRIEND_STATE_DEFAULT, glusterd_ac_none}, //EVENT_RCVD_REMOVE_FRIEND
- {GD_FRIEND_STATE_DEFAULT, glusterd_ac_friend_remove}, //EVENT_REMOVE_FRIEND
- {GD_FRIEND_STATE_CONNECTED_RCVD, glusterd_ac_none}, //EVENT_CONNECTED
- {GD_FRIEND_STATE_CONNECTED_RCVD, glusterd_ac_none}, //EVENT_MAX
-};
-
-glusterd_sm_t glusterd_state_connected_accepted [] = {
- {GD_FRIEND_STATE_CONNECTED_ACCEPTED, glusterd_ac_none},
- {GD_FRIEND_STATE_CONNECTED_ACCEPTED, glusterd_ac_friend_probe}, //EV_PROBE
- {GD_FRIEND_STATE_REQ_SENT_RCVD, glusterd_ac_friend_add}, //EV_INIT_FRIEND_REQ
- {GD_FRIEND_STATE_CONNECTED_ACCEPTED, glusterd_ac_none}, //EVENT_RCVD_ACC
- {GD_FRIEND_STATE_CONNECTED_ACCEPTED, glusterd_ac_none}, //EVENT_RCVD_LOCAL_ACC
- {GD_FRIEND_STATE_CONNECTED_ACCEPTED, glusterd_ac_none}, //EVENT_RCVD_RJT
- {GD_FRIEND_STATE_CONNECTED_ACCEPTED, glusterd_ac_none}, //EVENT_RCVD_LOCAL_RJT
- {GD_FRIEND_STATE_CONNECTED_ACCEPTED, glusterd_ac_none}, //EVENT_RCV_FRIEND_REQ
- {GD_FRIEND_STATE_DEFAULT, glusterd_ac_send_friend_remove_req}, //EV_INIT_REMOVE_FRIEND
- {GD_FRIEND_STATE_DEFAULT, glusterd_ac_none}, //EVENT_RCVD_REMOVE_FRIEND
- {GD_FRIEND_STATE_DEFAULT, glusterd_ac_friend_remove}, //EVENT_REMOVE_FRIEND
- {GD_FRIEND_STATE_CONNECTED_ACCEPTED, glusterd_ac_none}, //EVENT_CONNECTED
- {GD_FRIEND_STATE_CONNECTED_ACCEPTED, glusterd_ac_none}, //EVENT_MAX
-};
-
-glusterd_sm_t glusterd_state_req_sent [] = {
- {GD_FRIEND_STATE_REQ_SENT, glusterd_ac_none}, //EVENT_NONE,
- {GD_FRIEND_STATE_REQ_SENT, glusterd_ac_none}, //EVENT_PROBE,
- {GD_FRIEND_STATE_REQ_SENT, glusterd_ac_none}, //EVENT_INIT_FRIEND_REQ,
- {GD_FRIEND_STATE_REQ_ACCEPTED, glusterd_ac_none}, //EVENT_RCVD_ACC
- {GD_FRIEND_STATE_REQ_SENT, glusterd_ac_none}, //EVENT_RCVD_LOCAL_ACC
- {GD_FRIEND_STATE_REJECTED, glusterd_ac_none}, //EVENT_RCVD_RJT
- {GD_FRIEND_STATE_REQ_SENT, glusterd_ac_none}, //EVENT_RCVD_LOCAL_RJT
- {GD_FRIEND_STATE_REQ_SENT_RCVD, glusterd_ac_handle_friend_add_req}, //EVENT_RCV_FRIEND_REQ
- {GD_FRIEND_STATE_UNFRIEND_SENT, glusterd_ac_send_friend_remove_req}, //EVENT_INIT_REMOVE_FRIEND,
- {GD_FRIEND_STATE_REQ_SENT, glusterd_ac_none}, //EVENT_RCVD_REMOVE_FRIEND
- {GD_FRIEND_STATE_DEFAULT, glusterd_ac_friend_remove}, //EVENT_REMOVE_FRIEND
- {GD_FRIEND_STATE_REQ_SENT, glusterd_ac_none},//EVENT_CONNECTED
- {GD_FRIEND_STATE_REQ_SENT, glusterd_ac_none},//EVENT_MAX
-};
-
-glusterd_sm_t glusterd_state_req_rcvd [] = {
- {GD_FRIEND_STATE_REQ_RCVD, glusterd_ac_none}, //EVENT_NONE,
- {GD_FRIEND_STATE_REQ_RCVD, glusterd_ac_none}, //EVENT_PROBE,
- {GD_FRIEND_STATE_REQ_SENT_RCVD, glusterd_ac_none}, //EVENT_INIT_FRIEND_REQ,
- {GD_FRIEND_STATE_REQ_RCVD, glusterd_ac_none}, //EVENT_RCVD_ACC
- {GD_FRIEND_STATE_REQ_ACCEPTED, glusterd_ac_none}, //EVENT_RCVD_LOCAL_ACC
- {GD_FRIEND_STATE_REQ_RCVD, glusterd_ac_none}, //EVENT_RCVD_RJT
- {GD_FRIEND_STATE_REJECTED, glusterd_ac_none}, //EVENT_RCVD_LOCAL_RJT
- {GD_FRIEND_STATE_REQ_RCVD, glusterd_ac_none}, //EVENT_RCV_FRIEND_REQ
- {GD_FRIEND_STATE_DEFAULT, glusterd_ac_send_friend_remove_req}, //EVENT_INIT_REMOVE_FRIEND,
- {GD_FRIEND_STATE_DEFAULT, glusterd_ac_handle_friend_remove_req}, //EVENT_RCVD_REMOVE_FRIEND
- {GD_FRIEND_STATE_DEFAULT, glusterd_ac_friend_remove}, //EVENT_REMOVE_FRIEND
- {GD_FRIEND_STATE_CONNECTED_RCVD, glusterd_ac_none},//EVENT_CONNECTED
- {GD_FRIEND_STATE_REQ_RCVD, glusterd_ac_none},//EVENT_MAX
-};
-
-glusterd_sm_t glusterd_state_befriended [] = {
- {GD_FRIEND_STATE_BEFRIENDED, glusterd_ac_none}, //EVENT_NONE,
- {GD_FRIEND_STATE_BEFRIENDED, glusterd_ac_none}, //EVENT_PROBE,
- {GD_FRIEND_STATE_BEFRIENDED, glusterd_ac_none}, //EVENT_INIT_FRIEND_REQ,
- {GD_FRIEND_STATE_BEFRIENDED, glusterd_ac_none}, //EVENT_RCVD_ACC
- {GD_FRIEND_STATE_BEFRIENDED, glusterd_ac_send_friend_update}, //EVENT_RCVD_LOCAL_ACC
- {GD_FRIEND_STATE_REJECTED, glusterd_ac_none}, //EVENT_RCVD_RJT
- {GD_FRIEND_STATE_REJECTED, glusterd_ac_none}, //EVENT_RCVD_LOCAL_RJT
- {GD_FRIEND_STATE_BEFRIENDED, glusterd_ac_handle_friend_add_req}, //EVENT_RCV_FRIEND_REQ
- {GD_FRIEND_STATE_UNFRIEND_SENT, glusterd_ac_send_friend_remove_req}, //EVENT_INIT_REMOVE_FRIEND,
- {GD_FRIEND_STATE_DEFAULT, glusterd_ac_handle_friend_remove_req}, //EVENT_RCVD_REMOVE_FRIEND
- {GD_FRIEND_STATE_DEFAULT, glusterd_ac_friend_remove}, //EVENT_REMOVE_FRIEND
- {GD_FRIEND_STATE_BEFRIENDED, glusterd_ac_friend_add},//EVENT_CONNECTED
- {GD_FRIEND_STATE_BEFRIENDED, glusterd_ac_none},//EVENT_MAX
-};
-
-glusterd_sm_t glusterd_state_req_sent_rcvd [] = {
- {GD_FRIEND_STATE_REQ_SENT_RCVD, glusterd_ac_none}, //EVENT_NONE,
- {GD_FRIEND_STATE_REQ_SENT_RCVD, glusterd_ac_none}, //EVENT_PROBE,
- {GD_FRIEND_STATE_REQ_SENT_RCVD, glusterd_ac_none}, //EVENT_INIT_FRIEND_REQ,
- {GD_FRIEND_STATE_BEFRIENDED, glusterd_ac_send_friend_update}, //EVENT_RCVD_ACC
- {GD_FRIEND_STATE_REQ_SENT_RCVD, glusterd_ac_none}, //EVENT_RCVD_LOCAL_ACC
- {GD_FRIEND_STATE_REJECTED, glusterd_ac_none}, //EVENT_RCVD_RJT
- {GD_FRIEND_STATE_REQ_SENT_RCVD, glusterd_ac_none}, //EVENT_RCVD_LOCAL_RJT
- {GD_FRIEND_STATE_REQ_SENT_RCVD, glusterd_ac_none}, //EVENT_RCV_FRIEND_REQ
- {GD_FRIEND_STATE_UNFRIEND_SENT, glusterd_ac_send_friend_remove_req}, //EVENT_INIT_REMOVE_FRIEND,
- {GD_FRIEND_STATE_DEFAULT, glusterd_ac_handle_friend_remove_req}, //EVENT_RCVD_REMOVE_FRIEND
- {GD_FRIEND_STATE_DEFAULT, glusterd_ac_friend_remove}, //EVENT_REMOVE_FRIEND
- {GD_FRIEND_STATE_REQ_SENT_RCVD, glusterd_ac_none},//EVENT_CONNECTED
- {GD_FRIEND_STATE_REQ_SENT_RCVD, glusterd_ac_none},//EVENT_MAX
-};
-
-glusterd_sm_t glusterd_state_rejected [] = {
- {GD_FRIEND_STATE_REJECTED, glusterd_ac_none}, //EVENT_NONE,
- {GD_FRIEND_STATE_REJECTED, glusterd_ac_friend_probe}, //EVENT_PROBE,
- {GD_FRIEND_STATE_REQ_SENT, glusterd_ac_friend_add}, //EVENT_INIT_FRIEND_REQ,
- {GD_FRIEND_STATE_BEFRIENDED, glusterd_ac_none}, //EVENT_RCVD_ACC
- {GD_FRIEND_STATE_BEFRIENDED, glusterd_ac_none}, //EVENT_RCVD_LOCAL_ACC
- {GD_FRIEND_STATE_REJECTED, glusterd_ac_none}, //EVENT_RCVD_RJT
- {GD_FRIEND_STATE_REJECTED, glusterd_ac_none}, //EVENT_RCVD_LOCAL_RJT
- {GD_FRIEND_STATE_REQ_RCVD, glusterd_ac_handle_friend_add_req}, //EVENT_RCV_FRIEND_REQ
- {GD_FRIEND_STATE_DEFAULT, glusterd_ac_send_friend_remove_req}, //EVENT_INIT_REMOVE_FRIEND
- {GD_FRIEND_STATE_DEFAULT, glusterd_ac_handle_friend_remove_req}, //EVENT_RCVD_REMOVE_FRIEND
- {GD_FRIEND_STATE_DEFAULT, glusterd_ac_friend_remove}, //EVENT_REMOVE_FRIEND
- {GD_FRIEND_STATE_REJECTED, glusterd_ac_friend_add},//EVENT_CONNECTED
- {GD_FRIEND_STATE_REQ_RCVD, glusterd_ac_none},//EVENT_MAX
-};
-
-glusterd_sm_t glusterd_state_req_accepted [] = {
- {GD_FRIEND_STATE_REQ_ACCEPTED, glusterd_ac_none}, //EVENT_NONE,
- {GD_FRIEND_STATE_REQ_ACCEPTED, glusterd_ac_none}, //EVENT_PROBE,
- {GD_FRIEND_STATE_REQ_ACCEPTED, glusterd_ac_none}, //EVENT_INIT_FRIEND_REQ,
- {GD_FRIEND_STATE_BEFRIENDED, glusterd_ac_send_friend_update}, //EVENT_RCVD_ACC
- {GD_FRIEND_STATE_BEFRIENDED, glusterd_ac_send_friend_update}, //EVENT_RCVD_LOCAL_ACC
- {GD_FRIEND_STATE_REJECTED, glusterd_ac_none}, //EVENT_RCVD_RJT
- {GD_FRIEND_STATE_REJECTED, glusterd_ac_none}, //EVENT_RCVD_LOCAL_RJT
- {GD_FRIEND_STATE_REQ_ACCEPTED, glusterd_ac_handle_friend_add_req}, //EVENT_RCV_FRIEND_REQ
- {GD_FRIEND_STATE_REQ_ACCEPTED, glusterd_ac_send_friend_remove_req}, //EVENT_INIT_REMOVE_FRIEND
- {GD_FRIEND_STATE_DEFAULT, glusterd_ac_handle_friend_remove_req}, //EVENT_RCVD_REMOVE_FRIEND
- {GD_FRIEND_STATE_DEFAULT, glusterd_ac_friend_remove}, //EVENT_REMOVE_FRIEND
- {GD_FRIEND_STATE_CONNECTED_ACCEPTED, glusterd_ac_reverse_probe_begin},//EVENT_CONNECTED
- {GD_FRIEND_STATE_REQ_SENT, glusterd_ac_none},//EVENT_MAX
-};
-
-glusterd_sm_t glusterd_state_unfriend_sent [] = {
- {GD_FRIEND_STATE_UNFRIEND_SENT, glusterd_ac_none}, //EVENT_NONE,
- {GD_FRIEND_STATE_UNFRIEND_SENT, glusterd_ac_error}, //EVENT_PROBE,
- {GD_FRIEND_STATE_UNFRIEND_SENT, glusterd_ac_none}, //EVENT_INIT_FRIEND_REQ,
- {GD_FRIEND_STATE_UNFRIEND_SENT, glusterd_ac_none}, //EVENT_RCVD_ACC
- {GD_FRIEND_STATE_UNFRIEND_SENT, glusterd_ac_none}, //EVENT_RCVD_LOCAL_ACC
- {GD_FRIEND_STATE_UNFRIEND_SENT, glusterd_ac_error}, //EVENT_RCVD_RJT
- {GD_FRIEND_STATE_UNFRIEND_SENT, glusterd_ac_error}, //EVENT_RCVD_LOCAL_RJT
- {GD_FRIEND_STATE_UNFRIEND_SENT, glusterd_ac_error}, //EVENT_RCV_FRIEND_REQ
- {GD_FRIEND_STATE_UNFRIEND_SENT, glusterd_ac_none}, //EVENT_INIT_REMOVE_FRIEND
- {GD_FRIEND_STATE_UNFRIEND_SENT, glusterd_ac_none}, //EVENT_RCVD_REMOVE_FRIEND
- {GD_FRIEND_STATE_DEFAULT, glusterd_ac_friend_remove}, //EVENT_REMOVE_FRIEND
- {GD_FRIEND_STATE_UNFRIEND_SENT, glusterd_ac_none},//EVENT_CONNECTED
- {GD_FRIEND_STATE_UNFRIEND_SENT, glusterd_ac_none},//EVENT_MAX
-};
-
-glusterd_sm_t *glusterd_friend_state_table [] = {
- glusterd_state_default,
- glusterd_state_req_sent,
- glusterd_state_req_rcvd,
- glusterd_state_befriended,
- glusterd_state_req_accepted,
- glusterd_state_req_sent_rcvd,
- glusterd_state_rejected,
- glusterd_state_unfriend_sent,
- glusterd_state_probe_rcvd,
- glusterd_state_connected_rcvd,
- glusterd_state_connected_accepted
-};
-
-int
-glusterd_friend_sm_new_event (glusterd_friend_sm_event_type_t event_type,
- glusterd_friend_sm_event_t **new_event)
-{
- glusterd_friend_sm_event_t *event = NULL;
-
- GF_ASSERT (new_event);
- GF_ASSERT (GD_FRIEND_EVENT_NONE <= event_type &&
- GD_FRIEND_EVENT_MAX > event_type);
-
- event = GF_CALLOC (1, sizeof (*event), gf_gld_mt_friend_sm_event_t);
-
- if (!event)
- return -1;
-
- *new_event = event;
- event->event = event_type;
- INIT_LIST_HEAD (&event->list);
-
- return 0;
-}
-
-int
-glusterd_friend_sm_inject_event (glusterd_friend_sm_event_t *event)
-{
- GF_ASSERT (event);
- gf_log ("glusterd", GF_LOG_DEBUG, "Enqueue event: '%s'",
- glusterd_friend_sm_event_name_get (event->event));
- list_add_tail (&event->list, &gd_friend_sm_queue);
-
- return 0;
-}
-
-void
-glusterd_destroy_friend_event_context (glusterd_friend_sm_event_t *event)
-{
- if (!event)
- return;
-
- switch (event->event) {
- case GD_FRIEND_EVENT_RCVD_FRIEND_REQ:
- case GD_FRIEND_EVENT_RCVD_REMOVE_FRIEND:
- glusterd_destroy_friend_req_ctx (event->ctx);
- break;
- case GD_FRIEND_EVENT_LOCAL_ACC:
- case GD_FRIEND_EVENT_LOCAL_RJT:
- case GD_FRIEND_EVENT_RCVD_ACC:
- case GD_FRIEND_EVENT_RCVD_RJT:
- glusterd_destroy_friend_update_ctx (event->ctx);
- break;
- default:
- break;
- }
-}
-
-gf_boolean_t
-gd_does_peer_affect_quorum (glusterd_friend_sm_state_t old_state,
- glusterd_friend_sm_event_type_t event_type,
- glusterd_peerinfo_t *peerinfo)
-{
- gf_boolean_t affects = _gf_false;
-
- //When glusterd comes up with friends in BEFRIENDED state in store,
- //wait until compare-data happens.
- if ((old_state == GD_FRIEND_STATE_BEFRIENDED) &&
- (event_type != GD_FRIEND_EVENT_RCVD_ACC) &&
- (event_type != GD_FRIEND_EVENT_LOCAL_ACC))
- goto out;
- if ((peerinfo->state.state == GD_FRIEND_STATE_BEFRIENDED)
- && peerinfo->connected) {
- affects = _gf_true;
- }
-out:
- return affects;
-}
-
-int
-glusterd_friend_sm ()
-{
- glusterd_friend_sm_event_t *event = NULL;
- glusterd_friend_sm_event_t *tmp = NULL;
- int ret = -1;
- glusterd_friend_sm_ac_fn handler = NULL;
- glusterd_sm_t *state = NULL;
- glusterd_peerinfo_t *peerinfo = NULL;
- glusterd_friend_sm_event_type_t event_type = 0;
- gf_boolean_t is_await_conn = _gf_false;
- gf_boolean_t quorum_action = _gf_false;
- glusterd_friend_sm_state_t old_state = GD_FRIEND_STATE_DEFAULT;
- xlator_t *this = NULL;
- glusterd_conf_t *priv = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- priv = this->private;
- GF_ASSERT (priv);
-
- while (!list_empty (&gd_friend_sm_queue)) {
- list_for_each_entry_safe (event, tmp, &gd_friend_sm_queue, list) {
-
- list_del_init (&event->list);
- event_type = event->event;
- peerinfo = event->peerinfo;
- if (!peerinfo) {
- gf_log ("glusterd", GF_LOG_CRITICAL, "Received"
- " event %s with empty peer info",
- glusterd_friend_sm_event_name_get (event_type));
-
- GF_FREE (event);
- continue;
- }
- gf_log ("", GF_LOG_DEBUG, "Dequeued event of type: '%s'",
- glusterd_friend_sm_event_name_get (event_type));
-
-
- old_state = peerinfo->state.state;
- state = glusterd_friend_state_table[peerinfo->state.state];
-
- GF_ASSERT (state);
-
- handler = state[event_type].handler;
- GF_ASSERT (handler);
-
- ret = handler (event, event->ctx);
- if (ret == GLUSTERD_CONNECTION_AWAITED) {
- is_await_conn = _gf_true;
- ret = 0;
- }
-
- if (ret) {
- gf_log ("glusterd", GF_LOG_ERROR, "handler returned: "
- "%d", ret);
- glusterd_destroy_friend_event_context (event);
- GF_FREE (event);
- continue;
- }
-
- if ((GD_FRIEND_EVENT_REMOVE_FRIEND == event_type) ||
- (GD_FRIEND_EVENT_INIT_REMOVE_FRIEND == event_type)){
- glusterd_destroy_friend_event_context (event);
- GF_FREE (event);
- continue;
- }
-
- ret = glusterd_friend_sm_transition_state (peerinfo,
- state, event_type);
-
- if (ret) {
- gf_log ("glusterd", GF_LOG_ERROR, "Unable to transition"
- " state from '%s' to '%s' for event '%s'",
- glusterd_friend_sm_state_name_get(peerinfo->state.state),
- glusterd_friend_sm_state_name_get(state[event_type].next_state),
- glusterd_friend_sm_event_name_get(event_type));
- goto out;
- }
-
- if (gd_does_peer_affect_quorum (old_state, event_type,
- peerinfo)) {
- peerinfo->quorum_contrib = QUORUM_UP;
- if (peerinfo->quorum_action) {
- peerinfo->quorum_action = _gf_false;
- quorum_action = _gf_true;
- }
- }
-
- ret = glusterd_store_peerinfo (peerinfo);
-
- glusterd_destroy_friend_event_context (event);
- GF_FREE (event);
- if (is_await_conn)
- break;
- }
- if (is_await_conn)
- break;
- }
-
- ret = 0;
-out:
- if (quorum_action) {
- /* When glusterd is restarted, it needs to wait until the 'friends' view
- * of the volumes settle, before it starts any of the internal daemons.
- *
- * Every friend that was part of the cluster, would send its
- * cluster-view, 'our' way. For every friend, who belongs to
- * a partition which has a different cluster-view from our
- * partition, we may update our cluster-view. For subsequent
- * friends from that partition would agree with us, if the first
- * friend wasn't rejected. For every first friend, whom we agreed with,
- * we would need to start internal daemons/bricks belonging to the
- * new volumes.
- * glusterd_spawn_daemons calls functions that are idempotent. ie,
- * the functions spawn process(es) only if they are not started yet.
- *
- * */
- synclock_unlock (&priv->big_lock);
- glusterd_launch_synctask (glusterd_spawn_daemons, NULL);
- synclock_lock (&priv->big_lock);
- glusterd_do_quorum_action ();
- }
- return ret;
-}
-
-
-int
-glusterd_friend_sm_init ()
-{
- INIT_LIST_HEAD (&gd_friend_sm_queue);
- return 0;
-}
diff --git a/xlators/mgmt/glusterd/src/glusterd-sm.h b/xlators/mgmt/glusterd/src/glusterd-sm.h
deleted file mode 100644
index fb873f75601..00000000000
--- a/xlators/mgmt/glusterd/src/glusterd-sm.h
+++ /dev/null
@@ -1,217 +0,0 @@
-/*
- Copyright (c) 2006-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 _GLUSTERD_SM_H_
-#define _GLUSTERD_SM_H_
-
-#ifndef _CONFIG_H
-#define _CONFIG_H
-#include "config.h"
-#endif
-
-#include <pthread.h>
-#include "uuid.h"
-
-#include "rpc-clnt.h"
-#include "glusterfs.h"
-#include "xlator.h"
-#include "logging.h"
-#include "call-stub.h"
-#include "fd.h"
-#include "byte-order.h"
-//#include "glusterd.h"
-#include "rpcsvc.h"
-#include "store.h"
-
-typedef enum gd_quorum_contribution_ {
- QUORUM_NONE,
- QUORUM_WAITING,
- QUORUM_DOWN,
- QUORUM_UP
-} gd_quorum_contrib_t;
-
-typedef enum glusterd_friend_sm_state_ {
- GD_FRIEND_STATE_DEFAULT = 0,
- GD_FRIEND_STATE_REQ_SENT,
- GD_FRIEND_STATE_REQ_RCVD,
- GD_FRIEND_STATE_BEFRIENDED,
- GD_FRIEND_STATE_REQ_ACCEPTED,
- GD_FRIEND_STATE_REQ_SENT_RCVD,
- GD_FRIEND_STATE_REJECTED,
- GD_FRIEND_STATE_UNFRIEND_SENT,
- GD_FRIEND_STATE_PROBE_RCVD,
- GD_FRIEND_STATE_CONNECTED_RCVD,
- GD_FRIEND_STATE_CONNECTED_ACCEPTED,
- GD_FRIEND_STATE_MAX
-} glusterd_friend_sm_state_t;
-
-typedef struct glusterd_peer_state_info_ {
- glusterd_friend_sm_state_t state;
- struct timeval transition_time;
-}glusterd_peer_state_info_t;
-
-typedef struct glusterd_peer_hostname_ {
- char *hostname;
- struct list_head hostname_list;
-} glusterd_peer_hostname_t;
-
-typedef struct glusterd_sm_transition_ {
- int old_state;
- int event;
- int new_state;
- time_t time;
-} glusterd_sm_transition_t;
-
-typedef struct glusterd_sm_tr_log_ {
- glusterd_sm_transition_t *transitions;
- size_t current;
- size_t size;
- size_t count;
- char* (*state_name_get) (int);
- char* (*event_name_get) (int);
-} glusterd_sm_tr_log_t;
-
-struct glusterd_peerinfo_ {
- uuid_t uuid;
- char uuid_str[50]; /* Retrieve this using
- * gd_peer_uuid_str ()
- */
- glusterd_peer_state_info_t state;
- char *hostname;
- struct list_head hostnames;
- int port;
- struct list_head uuid_list;
- struct list_head op_peers_list;
- struct rpc_clnt *rpc;
- rpc_clnt_prog_t *mgmt;
- rpc_clnt_prog_t *peer;
- rpc_clnt_prog_t *mgmt_v3;
- int connected;
- gf_store_handle_t *shandle;
- glusterd_sm_tr_log_t sm_log;
- gf_boolean_t quorum_action;
- gd_quorum_contrib_t quorum_contrib;
- gf_boolean_t locked;
- gf_boolean_t detaching;
-};
-
-typedef struct glusterd_peerinfo_ glusterd_peerinfo_t;
-
-typedef struct glusterd_local_peers_ {
- glusterd_peerinfo_t *peerinfo;
- struct list_head op_peers_list;
-} glusterd_local_peers_t;
-
-typedef enum glusterd_ev_gen_mode_ {
- GD_MODE_OFF,
- GD_MODE_ON,
- GD_MODE_SWITCH_ON
-} glusterd_ev_gen_mode_t;
-
-typedef struct glusterd_peer_ctx_args_ {
- rpcsvc_request_t *req;
- glusterd_ev_gen_mode_t mode;
- dict_t *dict;
-} glusterd_peerctx_args_t;
-
-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_ {
- GD_FRIEND_EVENT_NONE = 0,
- GD_FRIEND_EVENT_PROBE,
- GD_FRIEND_EVENT_INIT_FRIEND_REQ,
- GD_FRIEND_EVENT_RCVD_ACC,
- GD_FRIEND_EVENT_LOCAL_ACC,
- GD_FRIEND_EVENT_RCVD_RJT,
- GD_FRIEND_EVENT_LOCAL_RJT,
- GD_FRIEND_EVENT_RCVD_FRIEND_REQ,
- GD_FRIEND_EVENT_INIT_REMOVE_FRIEND,
- GD_FRIEND_EVENT_RCVD_REMOVE_FRIEND,
- GD_FRIEND_EVENT_REMOVE_FRIEND,
- GD_FRIEND_EVENT_CONNECTED,
- GD_FRIEND_EVENT_MAX
-} glusterd_friend_sm_event_type_t;
-
-
-typedef enum glusterd_friend_update_op_ {
- GD_FRIEND_UPDATE_NONE = 0,
- GD_FRIEND_UPDATE_ADD,
- GD_FRIEND_UPDATE_DEL,
-} glusterd_friend_update_op_t;
-
-
-struct glusterd_friend_sm_event_ {
- struct list_head list;
- glusterd_peerinfo_t *peerinfo;
- void *ctx;
- glusterd_friend_sm_event_type_t event;
-};
-
-typedef struct glusterd_friend_sm_event_ glusterd_friend_sm_event_t;
-
-typedef int (*glusterd_friend_sm_ac_fn) (glusterd_friend_sm_event_t *, void *);
-
-typedef struct glusterd_sm_ {
- glusterd_friend_sm_state_t next_state;
- glusterd_friend_sm_ac_fn handler;
-} glusterd_sm_t;
-
-typedef struct glusterd_friend_req_ctx_ {
- uuid_t uuid;
- char *hostname;
- rpcsvc_request_t *req;
- int port;
- dict_t *vols;
-} glusterd_friend_req_ctx_t;
-
-typedef struct glusterd_friend_update_ctx_ {
- uuid_t uuid;
- char *hostname;
- int op;
-} glusterd_friend_update_ctx_t;
-
-typedef struct glusterd_probe_ctx_ {
- char *hostname;
- rpcsvc_request_t *req;
- int port;
- dict_t *dict;
-} glusterd_probe_ctx_t;
-int
-glusterd_friend_sm_new_event (glusterd_friend_sm_event_type_t event_type,
- glusterd_friend_sm_event_t **new_event);
-int
-glusterd_friend_sm_inject_event (glusterd_friend_sm_event_t *event);
-
-int
-glusterd_friend_sm_init ();
-
-int
-glusterd_friend_sm ();
-
-void
-glusterd_destroy_probe_ctx (glusterd_probe_ctx_t *ctx);
-
-void
-glusterd_destroy_friend_req_ctx (glusterd_friend_req_ctx_t *ctx);
-
-char*
-glusterd_friend_sm_state_name_get (int state);
-
-char*
-glusterd_friend_sm_event_name_get (int event);
-
-int
-glusterd_broadcast_friend_delete (char *hostname, uuid_t uuid);
-void
-glusterd_destroy_friend_update_ctx (glusterd_friend_update_ctx_t *ctx);
-#endif
diff --git a/xlators/mgmt/glusterd/src/glusterd-snapshot.c b/xlators/mgmt/glusterd/src/glusterd-snapshot.c
deleted file mode 100644
index f4f7fbfe674..00000000000
--- a/xlators/mgmt/glusterd/src/glusterd-snapshot.c
+++ /dev/null
@@ -1,8371 +0,0 @@
-/*
- Copyright (c) 2013-2014 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 <inttypes.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include <sys/resource.h>
-#include <sys/statvfs.h>
-#include <sys/mount.h>
-#include <signal.h>
-
-#if defined(GF_LINUX_HOST_OS)
-#include <mntent.h>
-#else
-#include "mntent_compat.h"
-#endif
-
-#ifdef __NetBSD__
-#define umount2(dir, flags) unmount(dir, ((flags) != 0) ? MNT_FORCE : 0)
-#endif
-
-#if defined(GF_DARWIN_HOST_OS) || defined(__FreeBSD__)
-#include <sys/param.h>
-#include <sys/mount.h>
-#define umount2(dir, flags) unmount(dir, ((flags) != 0) ? MNT_FORCE : 0)
-#endif
-
-#include <regex.h>
-
-#include "globals.h"
-#include "compat.h"
-#include "protocol-common.h"
-#include "xlator.h"
-#include "logging.h"
-#include "timer.h"
-#include "glusterd-mem-types.h"
-#include "glusterd.h"
-#include "glusterd-sm.h"
-#include "glusterd-op-sm.h"
-#include "glusterd-utils.h"
-#include "glusterd-store.h"
-#include "run.h"
-#include "glusterd-volgen.h"
-#include "glusterd-mgmt.h"
-#include "glusterd-syncop.h"
-
-#include "glusterfs3.h"
-
-#include "syscall.h"
-#include "cli1-xdr.h"
-#include "xdr-generic.h"
-
-#include "lvm-defaults.h"
-
-char snap_mount_folder[PATH_MAX];
-struct snap_create_args_ {
- xlator_t *this;
- dict_t *dict;
- dict_t *rsp_dict;
- glusterd_volinfo_t *snap_vol;
- glusterd_brickinfo_t *brickinfo;
- struct syncargs *args;
- int32_t volcount;
- int32_t brickcount;
- int32_t brickorder;
-};
-typedef struct snap_create_args_ snap_create_args_t;
-
-/* This function is called to get the device path of the snap lvm. Usually
- if /dev/mapper/<group-name>-<lvm-name> is the device for the lvm,
- then the snap device will be /dev/<group-name>/<snapname>.
- This function takes care of building the path for the snap device.
-*/
-char *
-glusterd_build_snap_device_path (char *device, char *snapname,
- int32_t brickcount)
-{
- char snap[PATH_MAX] = "";
- char msg[1024] = "";
- char volgroup[PATH_MAX] = "";
- char *snap_device = NULL;
- xlator_t *this = NULL;
- runner_t runner = {0,};
- char *ptr = NULL;
- int ret = -1;
-
- this = THIS;
- GF_ASSERT (this);
- if (!device) {
- gf_log (this->name, GF_LOG_ERROR, "device is NULL");
- goto out;
- }
- if (!snapname) {
- gf_log (this->name, GF_LOG_ERROR, "snapname is NULL");
- goto out;
- }
-
- runinit (&runner);
- runner_add_args (&runner, "/sbin/lvs", "--noheadings", "-o", "vg_name",
- device, NULL);
- runner_redir (&runner, STDOUT_FILENO, RUN_PIPE);
- snprintf (msg, sizeof (msg), "Get volume group for device %s", device);
- runner_log (&runner, this->name, GF_LOG_DEBUG, msg);
- ret = runner_start (&runner);
- if (ret == -1) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to get volume group "
- "for device %s", device);
- runner_end (&runner);
- goto out;
- }
- ptr = fgets(volgroup, sizeof(volgroup),
- runner_chio (&runner, STDOUT_FILENO));
- if (!ptr || !strlen(volgroup)) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to get volume group "
- "for snap %s", snapname);
- runner_end (&runner);
- ret = -1;
- goto out;
- }
- runner_end (&runner);
-
- snprintf (snap, sizeof(snap), "/dev/%s/%s_%d", gf_trim(volgroup),
- snapname, brickcount);
- snap_device = gf_strdup (snap);
- if (!snap_device) {
- gf_log (this->name, GF_LOG_WARNING, "Cannot copy the "
- "snapshot device name for snapname: %s", snapname);
- }
-
-out:
- return snap_device;
-}
-
-/* Look for disconnected peers, for missed snap creates or deletes */
-static int32_t
-glusterd_find_missed_snap (dict_t *rsp_dict, glusterd_volinfo_t *vol,
- struct list_head *peers, int32_t op)
-{
- int32_t brick_count = -1;
- int32_t ret = -1;
- xlator_t *this = NULL;
- glusterd_peerinfo_t *peerinfo = NULL;
- glusterd_brickinfo_t *brickinfo = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (rsp_dict);
- GF_ASSERT (peers);
- GF_ASSERT (vol);
-
- brick_count = 0;
- list_for_each_entry (brickinfo, &vol->bricks, brick_list) {
- if (!uuid_compare (brickinfo->uuid, MY_UUID)) {
- /* If the brick belongs to the same node */
- brick_count++;
- continue;
- }
-
- list_for_each_entry (peerinfo, peers, uuid_list) {
- if (uuid_compare (peerinfo->uuid, brickinfo->uuid)) {
- /* If the brick doesnt belong to this peer */
- continue;
- }
-
- /* Found peer who owns the brick, *
- * if peer is not connected or not *
- * friend add it to missed snap list */
- if (!(peerinfo->connected) ||
- (peerinfo->state.state !=
- GD_FRIEND_STATE_BEFRIENDED)) {
- ret = glusterd_add_missed_snaps_to_dict
- (rsp_dict,
- vol, brickinfo,
- brick_count + 1,
- op);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to add missed snapshot "
- "info for %s:%s in the "
- "rsp_dict", brickinfo->hostname,
- brickinfo->path);
- goto out;
- }
- }
- }
- brick_count++;
- }
-
- ret = 0;
-out:
- gf_log (this->name, GF_LOG_TRACE, "Returning %d", ret);
- return ret;
-}
-
-int
-snap_max_limits_display_commit (dict_t *rsp_dict, char *volname,
- char *op_errstr, int len)
-{
- char err_str[PATH_MAX] = "";
- char buf[PATH_MAX] = "";
- glusterd_conf_t *conf = NULL;
- glusterd_volinfo_t *volinfo = NULL;
- int ret = -1;
- uint64_t active_hard_limit = 0;
- uint64_t snap_max_limit = 0;
- uint64_t soft_limit_value = -1;
- uint64_t count = 0;
- xlator_t *this = NULL;
- uint64_t opt_hard_max = GLUSTERD_SNAPS_MAX_HARD_LIMIT;
- uint64_t opt_soft_max = GLUSTERD_SNAPS_DEF_SOFT_LIMIT_PERCENT;
- char *auto_delete = "disable";
- char *snap_activate = "disable";
-
- this = THIS;
-
- GF_ASSERT (this);
- GF_ASSERT (rsp_dict);
- GF_ASSERT (op_errstr);
-
- conf = this->private;
-
- GF_ASSERT (conf);
-
-
- /* config values snap-max-hard-limit and snap-max-soft-limit are
- * optional and hence we are not erroring out if values are not
- * present
- */
- gd_get_snap_conf_values_if_present (conf->opts, &opt_hard_max,
- &opt_soft_max);
-
- if (!volname) {
- /* For system limit */
- list_for_each_entry (volinfo, &conf->volumes, vol_list) {
- if (volinfo->is_snap_volume == _gf_true)
- continue;
-
- snap_max_limit = volinfo->snap_max_hard_limit;
- if (snap_max_limit > opt_hard_max)
- active_hard_limit = opt_hard_max;
- else
- active_hard_limit = snap_max_limit;
-
- soft_limit_value = (opt_soft_max *
- active_hard_limit) / 100;
-
- snprintf (buf, sizeof(buf), "volume%"PRId64"-volname",
- count);
- ret = dict_set_str (rsp_dict, buf, volinfo->volname);
- if (ret) {
- snprintf (err_str, PATH_MAX,
- "Failed to set %s", buf);
- goto out;
- }
-
- snprintf (buf, sizeof(buf),
- "volume%"PRId64"-snap-max-hard-limit", count);
- ret = dict_set_uint64 (rsp_dict, buf, snap_max_limit);
- if (ret) {
- snprintf (err_str, PATH_MAX,
- "Failed to set %s", buf);
- goto out;
- }
-
- snprintf (buf, sizeof(buf),
- "volume%"PRId64"-active-hard-limit", count);
- ret = dict_set_uint64 (rsp_dict, buf,
- active_hard_limit);
- if (ret) {
- snprintf (err_str, PATH_MAX,
- "Failed to set %s", buf);
- goto out;
- }
-
- snprintf (buf, sizeof(buf),
- "volume%"PRId64"-snap-max-soft-limit", count);
- ret = dict_set_uint64 (rsp_dict, buf, soft_limit_value);
- if (ret) {
- snprintf (err_str, PATH_MAX,
- "Failed to set %s", buf);
- goto out;
- }
- count++;
- }
-
- ret = dict_set_uint64 (rsp_dict, "voldisplaycount", count);
- if (ret) {
- snprintf (err_str, PATH_MAX,
- "Failed to set voldisplaycount");
- goto out;
- }
- } else {
- /* For one volume */
- ret = glusterd_volinfo_find (volname, &volinfo);
- if (ret) {
- snprintf (err_str, PATH_MAX, "Volume (%s) does not "
- "exist", volname);
- goto out;
- }
-
- snap_max_limit = volinfo->snap_max_hard_limit;
- if (snap_max_limit > opt_hard_max)
- active_hard_limit = opt_hard_max;
- else
- active_hard_limit = snap_max_limit;
-
- soft_limit_value = (opt_soft_max *
- active_hard_limit) / 100;
-
- snprintf (buf, sizeof(buf), "volume%"PRId64"-volname", count);
- ret = dict_set_str (rsp_dict, buf, volinfo->volname);
- if (ret) {
- snprintf (err_str, PATH_MAX,
- "Failed to set %s", buf);
- goto out;
- }
-
- snprintf (buf, sizeof(buf),
- "volume%"PRId64"-snap-max-hard-limit", count);
- ret = dict_set_uint64 (rsp_dict, buf, snap_max_limit);
- if (ret) {
- snprintf (err_str, PATH_MAX,
- "Failed to set %s", buf);
- goto out;
- }
-
- snprintf (buf, sizeof(buf),
- "volume%"PRId64"-active-hard-limit", count);
- ret = dict_set_uint64 (rsp_dict, buf, active_hard_limit);
- if (ret) {
- snprintf (err_str, PATH_MAX,
- "Failed to set %s", buf);
- goto out;
- }
-
- snprintf (buf, sizeof(buf),
- "volume%"PRId64"-snap-max-soft-limit", count);
- ret = dict_set_uint64 (rsp_dict, buf, soft_limit_value);
- if (ret) {
- snprintf (err_str, PATH_MAX,
- "Failed to set %s", buf);
- goto out;
- }
-
- count++;
-
- ret = dict_set_uint64 (rsp_dict, "voldisplaycount", count);
- if (ret) {
- snprintf (err_str, PATH_MAX,
- "Failed to set voldisplaycount");
- goto out;
- }
-
- }
-
- ret = dict_set_uint64 (rsp_dict,
- GLUSTERD_STORE_KEY_SNAP_MAX_HARD_LIMIT,
- opt_hard_max);
- if (ret) {
- snprintf (err_str, PATH_MAX,
- "Failed to set %s in reponse dictionary",
- GLUSTERD_STORE_KEY_SNAP_MAX_HARD_LIMIT);
- goto out;
- }
-
- ret = dict_set_uint64 (rsp_dict,
- GLUSTERD_STORE_KEY_SNAP_MAX_SOFT_LIMIT,
- opt_soft_max);
- if (ret) {
- snprintf (err_str, PATH_MAX,
- "Failed to set %s in response dictionary",
- GLUSTERD_STORE_KEY_SNAP_MAX_SOFT_LIMIT);
- goto out;
- }
-
- /* "auto-delete" might not be set by user explicitly,
- * in that case it's better to consider the default value.
- * Hence not erroring out if Key is not found.
- */
- ret = dict_get_str (conf->opts, GLUSTERD_STORE_KEY_SNAP_AUTO_DELETE,
- &auto_delete);
-
- ret = dict_set_dynstr_with_alloc (rsp_dict,
- GLUSTERD_STORE_KEY_SNAP_AUTO_DELETE,
- auto_delete);
- if (ret) {
- snprintf (err_str, PATH_MAX,
- "Failed to set %s in response dictionary",
- GLUSTERD_STORE_KEY_SNAP_AUTO_DELETE);
- goto out;
- }
-
- /* "snap-activate-on-create" might not be set by user explicitly,
- * in that case it's better to consider the default value.
- * Hence not erroring out if Key is not found.
- */
- ret = dict_get_str (conf->opts, GLUSTERD_STORE_KEY_SNAP_ACTIVATE,
- &snap_activate);
-
- ret = dict_set_dynstr_with_alloc (rsp_dict,
- GLUSTERD_STORE_KEY_SNAP_ACTIVATE,
- snap_activate);
- if (ret) {
- snprintf (err_str, PATH_MAX,
- "Failed to set %s in response dictionary",
- GLUSTERD_STORE_KEY_SNAP_ACTIVATE);
- goto out;
- }
-
- ret = 0;
-out:
- if (ret) {
- strncpy (op_errstr, err_str, len);
- gf_log (this->name, GF_LOG_ERROR, "%s", err_str);
- }
- return ret;
-}
-
-
-/* Third argument of scandir(used in glusterd_copy_geo_rep_session_files)
- * is filter function. As we dont want "." and ".." files present in the
- * directory, we are excliding these 2 files.
- * "file_select" function here does the job of filtering.
- */
-int
-file_select (const struct dirent *entry)
-{
- if (entry == NULL)
- return (FALSE);
-
- if ((strcmp(entry->d_name, ".") == 0) ||
- (strcmp(entry->d_name, "..") == 0))
- return (FALSE);
- else
- return (TRUE);
-}
-
-int32_t
-glusterd_copy_geo_rep_session_files (char *session,
- glusterd_volinfo_t *snap_vol)
-{
- int32_t ret = -1;
- char snap_session_dir[PATH_MAX] = "";
- char georep_session_dir[PATH_MAX] = "";
- regex_t *reg_exp = NULL;
- int file_count = -1;
- struct dirent **files = {0,};
- xlator_t *this = NULL;
- int i = 0;
- char src_path[PATH_MAX] = "";
- char dest_path[PATH_MAX] = "";
- glusterd_conf_t *priv = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- priv = this->private;
- GF_ASSERT (priv);
-
- GF_ASSERT (session);
- GF_ASSERT (snap_vol);
-
- ret = snprintf (georep_session_dir, sizeof (georep_session_dir),
- "%s/%s/%s", priv->workdir, GEOREP,
- session);
- if (ret < 0) { /* Negative value is an error */
- goto out;
- }
-
- ret = snprintf (snap_session_dir, sizeof (snap_session_dir),
- "%s/%s/%s/%s/%s", priv->workdir,
- GLUSTERD_VOL_SNAP_DIR_PREFIX,
- snap_vol->snapshot->snapname, GEOREP, session);
- if (ret < 0) { /* Negative value is an error */
- goto out;
- }
-
- ret = mkdir_p (snap_session_dir, 0777, _gf_true);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Creating directory %s failed", snap_session_dir);
- goto out;
- }
-
- /* TODO : good to have - Allocate in stack instead of heap */
- reg_exp = GF_CALLOC (1, sizeof (regex_t), gf_common_mt_regex_t);
- if (!reg_exp) {
- ret = -1;
- gf_log (this->name, GF_LOG_ERROR, "Failed to allocate "
- "memory for regular expression");
- goto out;
- }
-
- ret = regcomp (reg_exp, "(.*status$)|(.*conf$)\0", REG_EXTENDED);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to "
- "compile the regular expression");
- goto out;
- }
-
- /* If there are no files in a particular session then fail it*/
- file_count = scandir (georep_session_dir, &files, file_select,
- alphasort);
- if (file_count <= 0) {
- ret = -1;
- gf_log (this->name, GF_LOG_ERROR, "Session files not present "
- "in %s", georep_session_dir);
- goto out;
- }
-
- /* Now compare the file name with regular expression to see if
- * there is a match
- */
- for (i = 0 ; i < file_count; i++) {
- if (regexec (reg_exp, files[i]->d_name, 0, NULL, 0))
- continue;
-
- ret = snprintf (src_path, sizeof (src_path), "%s/%s",
- georep_session_dir, files[i]->d_name);
- if (ret < 0) {
- goto out;
- }
-
- ret = snprintf (dest_path , sizeof (dest_path), "%s/%s",
- snap_session_dir, files[i]->d_name);
- if (ret < 0) {
- goto out;
- }
-
- ret = glusterd_copy_file (src_path, dest_path);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Could not "
- "copy file %s of session %s",
- files[i]->d_name, session);
- goto out;
- }
- }
-out:
- if (reg_exp)
- GF_FREE (reg_exp);
-
- return ret;
-}
-
-/* This function will take backup of the volume store
- * of the to-be restored volume. This will help us to
- * revert the operation if it fails.
- *
- * @param volinfo volinfo of the origin volume
- *
- * @return 0 on success and -1 on failure
- */
-int
-glusterd_snapshot_backup_vol (glusterd_volinfo_t *volinfo)
-{
- char pathname[PATH_MAX] = {0,};
- int ret = -1;
- int op_ret = 0;
- char delete_path[PATH_MAX] = {0,};
- char trashdir[PATH_MAX] = {0,};
- glusterd_conf_t *priv = NULL;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- priv = this->private;
- GF_ASSERT (priv);
- GF_ASSERT (volinfo);
-
- GLUSTERD_GET_VOLUME_DIR (pathname, volinfo, priv);
-
- snprintf (delete_path, sizeof (delete_path),
- "%s/"GLUSTERD_TRASH"/vols-%s.deleted", priv->workdir,
- volinfo->volname);
-
- snprintf (trashdir, sizeof (trashdir), "%s/"GLUSTERD_TRASH,
- priv->workdir);
-
- /* Create trash folder if it is not there */
- ret = mkdir (trashdir, 0777);
- if (ret && errno != EEXIST) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to create trash "
- "directory, reason : %s", strerror (errno));
- ret = -1;
- goto out;
- }
-
- /* Move the origin volume volder to the backup location */
- ret = rename (pathname, delete_path);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to rename snap "
- "directory %s to %s", pathname, delete_path);
- goto out;
- }
-
- /* Re-create an empty origin volume folder so that restore can
- * happen. */
- ret = mkdir (pathname, 0777);
- if (ret && errno != EEXIST) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to create origin "
- "volume directory (%s), reason : %s",
- pathname, strerror (errno));
- ret = -1;
- goto out;
- }
-
- ret = 0;
-out:
- /* Save the actual return value */
- op_ret = ret;
- if (ret) {
- /* Revert the changes in case of failure */
- ret = rmdir (pathname);
- if (ret) {
- gf_log (this->name, GF_LOG_DEBUG,
- "Failed to rmdir: %s,err: %s",
- pathname, strerror (errno));
- }
-
- ret = rename (delete_path, pathname);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to rename directory %s to %s",
- delete_path, pathname);
- }
-
- ret = rmdir (trashdir);
- if (ret) {
- gf_log (this->name, GF_LOG_DEBUG,
- "Failed to rmdir: %s, Reason: %s",
- trashdir, strerror (errno));
- }
- }
-
- gf_log (this->name, GF_LOG_TRACE, "Returning %d", op_ret);
-
- return op_ret;
-}
-
-int32_t
-glusterd_copy_geo_rep_files (glusterd_volinfo_t *origin_vol,
- glusterd_volinfo_t *snap_vol, dict_t *rsp_dict)
-{
- int32_t ret = -1;
- int i = 0;
- xlator_t *this = NULL;
- char key[PATH_MAX] = "";
- char session[PATH_MAX] = "";
- char slave[PATH_MAX] = "";
- char snapgeo_dir[PATH_MAX] = "";
- glusterd_conf_t *priv = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- priv = this->private;
- GF_ASSERT (priv);
-
- GF_ASSERT (origin_vol);
- GF_ASSERT (snap_vol);
- GF_ASSERT (rsp_dict);
-
- /* This condition is not satisfied if the volume
- * is slave volume.
- */
- if (!origin_vol->gsync_slaves) {
- ret = 0;
- goto out;
- }
-
- GLUSTERD_GET_SNAP_GEO_REP_DIR(snapgeo_dir, snap_vol->snapshot, priv);
-
- ret = mkdir (snapgeo_dir, 0777);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Creating directory %s failed", snapgeo_dir);
- goto out;
- }
-
- for (i = 1 ; i <= origin_vol->gsync_slaves->count ; i++) {
- ret = snprintf (key, sizeof (key), "slave%d", i);
- if (ret < 0) /* Negative value is an error */
- goto out;
-
- ret = glusterd_get_geo_rep_session (key, origin_vol->volname,
- origin_vol->gsync_slaves,
- session, slave);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to get geo-rep session");
- goto out;
- }
-
- ret = glusterd_copy_geo_rep_session_files (session, snap_vol);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to copy files"
- " related to session %s", session);
- goto out;
- }
- }
-
-out:
- return ret;
-}
-
-/* This function will restore a snapshot volumes
- *
- * @param dict dictionary containing snapshot restore request
- * @param op_errstr In case of any failure error message will be returned
- * in this variable
- * @return Negative value on Failure and 0 in success
- */
-int
-glusterd_snapshot_restore (dict_t *dict, char **op_errstr, dict_t *rsp_dict)
-{
- int ret = -1;
- int32_t volcount = -1;
- char *snapname = NULL;
- xlator_t *this = NULL;
- glusterd_volinfo_t *snap_volinfo = NULL;
- glusterd_volinfo_t *tmp = NULL;
- glusterd_volinfo_t *parent_volinfo = NULL;
- glusterd_snap_t *snap = NULL;
- glusterd_conf_t *priv = NULL;
-
- this = THIS;
-
- GF_ASSERT (this);
- GF_ASSERT (dict);
- GF_ASSERT (op_errstr);
- GF_ASSERT (rsp_dict);
-
- priv = this->private;
- GF_ASSERT (priv);
-
- ret = dict_get_str (dict, "snapname", &snapname);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to get "
- "snap name");
- goto out;
- }
-
- snap = glusterd_find_snap_by_name (snapname);
- if (NULL == snap) {
- ret = gf_asprintf (op_errstr, "Snapshot (%s) does not exist",
- snapname);
- if (ret < 0) {
- goto out;
- }
- gf_log (this->name, GF_LOG_ERROR, "%s", *op_errstr);
- ret = -1;
- goto out;
- }
-
- volcount = 0;
- list_for_each_entry_safe (snap_volinfo, tmp, &snap->volumes, vol_list) {
- volcount++;
- ret = glusterd_volinfo_find (snap_volinfo->parent_volname,
- &parent_volinfo);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Could not get volinfo of %s",
- snap_volinfo->parent_volname);
- goto out;
- }
-
- ret = dict_set_dynstr_with_alloc (rsp_dict, "snapuuid",
- uuid_utoa (snap->snap_id));
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to set snap "
- "uuid in response dictionary for %s snapshot",
- snap->snapname);
- goto out;
- }
-
-
- ret = dict_set_dynstr_with_alloc (rsp_dict, "volname",
- snap_volinfo->parent_volname);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to set snap "
- "uuid in response dictionary for %s snapshot",
- snap->snapname);
- goto out;
- }
-
- ret = dict_set_dynstr_with_alloc (rsp_dict, "volid",
- uuid_utoa (parent_volinfo->volume_id));
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to set snap "
- "uuid in response dictionary for %s snapshot",
- snap->snapname);
- goto out;
- }
-
- /* Take backup of the volinfo folder */
- ret = glusterd_snapshot_backup_vol (parent_volinfo);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to backup "
- "volume backend files for %s volume",
- parent_volinfo->volname);
- goto out;
- }
-
- if (is_origin_glusterd (dict) == _gf_true) {
- /* From origin glusterd check if *
- * any peers with snap bricks is down */
- ret = glusterd_find_missed_snap
- (rsp_dict, snap_volinfo,
- &priv->peers,
- GF_SNAP_OPTION_TYPE_RESTORE);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to find missed snap restores");
- goto out;
- }
- }
-
- ret = gd_restore_snap_volume (dict, rsp_dict, parent_volinfo,
- snap_volinfo, volcount);
- if (ret) {
- /* No need to update op_errstr because it is assumed
- * that the called function will do that in case of
- * failure.
- */
- gf_log (this->name, GF_LOG_ERROR, "Failed to restore "
- "snap for %s", snapname);
- goto out;
- }
- }
-
- ret = 0;
-
- /* TODO: Need to check if we need to delete the snap after the
- * operation is successful or not. Also need to persist the state
- * of restore operation in the store.
- */
-out:
- return ret;
-}
-
-/* This function is called before actual restore is taken place. This function
- * will validate whether the snapshot volumes are ready to be restored or not.
- *
- * @param dict dictionary containing snapshot restore request
- * @param op_errstr In case of any failure error message will be returned
- * in this variable
- * @param rsp_dict response dictionary
- * @return Negative value on Failure and 0 in success
- */
-int32_t
-glusterd_snapshot_restore_prevalidate (dict_t *dict, char **op_errstr,
- dict_t *rsp_dict)
-{
- int ret = -1;
- int32_t i = 0;
- int32_t volcount = 0;
- int32_t brick_count = 0;
- gf_boolean_t snap_restored = _gf_false;
- char key[PATH_MAX] = {0, };
- char *volname = NULL;
- char *snapname = NULL;
- glusterd_volinfo_t *volinfo = NULL;
- glusterd_brickinfo_t *brickinfo = NULL;
- glusterd_snap_t *snap = NULL;
- xlator_t *this = NULL;
-
- this = THIS;
-
- GF_ASSERT (this);
- GF_ASSERT (dict);
- GF_ASSERT (op_errstr);
- GF_ASSERT (rsp_dict);
-
- ret = dict_get_str (dict, "snapname", &snapname);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to get "
- "snap name");
- goto out;
- }
-
- snap = glusterd_find_snap_by_name (snapname);
- if (NULL == snap) {
- ret = gf_asprintf (op_errstr, "Snapshot (%s) does not exist",
- snapname);
- if (ret < 0) {
- goto out;
- }
- gf_log (this->name, GF_LOG_ERROR, "%s", *op_errstr);
- ret = -1;
- goto out;
- }
-
- snap_restored = snap->snap_restored;
-
- if (snap_restored) {
- ret = gf_asprintf (op_errstr, "Snapshot (%s) is already "
- "restored", snapname);
- if (ret < 0) {
- goto out;
- }
- gf_log (this->name, GF_LOG_ERROR, "%s", *op_errstr);
- ret = -1;
- goto out;
- }
-
- ret = dict_set_str (rsp_dict, "snapname", snapname);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to set "
- "snap name(%s)", snapname);
- goto out;
- }
-
- ret = dict_get_int32 (dict, "volcount", &volcount);
-
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to get volume count");
- goto out;
- }
-
- /* Snapshot restore will only work if all the volumes,
- that are part of the snapshot, are stopped. */
- for (i = 1; i <= volcount; ++i) {
- snprintf (key, sizeof (key), "volname%d", i);
- ret = dict_get_str (dict, key, &volname);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to "
- "get volume name");
- goto out;
- }
-
- ret = glusterd_volinfo_find (volname, &volinfo);
- if (ret) {
- ret = gf_asprintf (op_errstr, "Volume (%s) "
- "does not exist", volname);
- if (ret < 0) {
- goto out;
- }
- gf_log (this->name, GF_LOG_ERROR, "%s", *op_errstr);
- ret = -1;
- goto out;
- }
-
- if (glusterd_is_volume_started (volinfo)) {
- ret = gf_asprintf (op_errstr, "Volume (%s) has been "
- "started. Volume needs to be stopped before restoring "
- "a snapshot.", volname);
- if (ret < 0) {
- goto out;
- }
- gf_log (this->name, GF_LOG_ERROR, "%s", *op_errstr);
- ret = -1;
- goto out;
- }
- }
-
- /* Get brickinfo for snap_volumes */
- volcount = 0;
- list_for_each_entry (volinfo, &snap->volumes, vol_list) {
- volcount++;
- brick_count = 0;
- list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) {
- brick_count++;
- if (uuid_compare (brickinfo->uuid, MY_UUID))
- continue;
-
- snprintf (key, sizeof (key), "snap%d.brick%d.path",
- volcount, brick_count);
- ret = dict_set_str (rsp_dict, key, brickinfo->path);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to set %s", key);
- goto out;
- }
-
- snprintf (key, sizeof (key),
- "snap%d.brick%d.snap_status",
- volcount, brick_count);
- ret = dict_set_int32 (rsp_dict, key,
- brickinfo->snap_status);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to set %s", key);
- goto out;
- }
-
- snprintf (key, sizeof (key),
- "snap%d.brick%d.device_path",
- volcount, brick_count);
- ret = dict_set_str (rsp_dict, key,
- brickinfo->device_path);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to set %s", key);
- goto out;
- }
-
- snprintf (key, sizeof (key),
- "snap%d.brick%d.fs_type",
- volcount, brick_count);
- ret = dict_set_str (rsp_dict, key,
- brickinfo->fstype);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to set %s", key);
- goto out;
- }
-
- snprintf (key, sizeof (key),
- "snap%d.brick%d.mnt_opts",
- volcount, brick_count);
- ret = dict_set_str (rsp_dict, key,
- brickinfo->mnt_opts);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to set %s", key);
- goto out;
- }
- }
-
- snprintf (key, sizeof (key), "snap%d.brick_count", volcount);
- ret = dict_set_int32 (rsp_dict, key, brick_count);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to set %s", key);
- goto out;
- }
- }
-
- ret = dict_set_int32 (rsp_dict, "volcount", volcount);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to set %s", key);
- goto out;
- }
-
-out:
- return ret;
-}
-
-int
-snap_max_hard_limits_validate (dict_t *dict, char *volname,
- uint64_t value, char **op_errstr)
-{
- char err_str[PATH_MAX] = "";
- glusterd_conf_t *conf = NULL;
- glusterd_volinfo_t *volinfo = NULL;
- int ret = -1;
- uint64_t max_limit = GLUSTERD_SNAPS_MAX_HARD_LIMIT;
- xlator_t *this = NULL;
- uint64_t opt_hard_max = GLUSTERD_SNAPS_MAX_HARD_LIMIT;
-
- this = THIS;
-
- GF_ASSERT (this);
- GF_ASSERT (dict);
- GF_ASSERT (op_errstr);
-
- conf = this->private;
-
- GF_ASSERT (conf);
-
- if (volname) {
- ret = glusterd_volinfo_find (volname, &volinfo);
- if (!ret) {
- if (volinfo->is_snap_volume) {
- ret = -1;
- snprintf (err_str, PATH_MAX,
- "%s is a snap volume. Configuring "
- "snap-max-hard-limit for a snap "
- "volume is prohibited.", volname);
- goto out;
- }
- }
- }
-
- /* "snap-max-hard-limit" might not be set by user explicitly,
- * in that case it's better to use the default value.
- * Hence not erroring out if Key is not found.
- */
- ret = dict_get_uint64 (conf->opts,
- GLUSTERD_STORE_KEY_SNAP_MAX_HARD_LIMIT,
- &opt_hard_max);
- if (ret) {
- ret = 0;
- gf_log (this->name, GF_LOG_DEBUG, "%s is not present in "
- "opts dictionary",
- GLUSTERD_STORE_KEY_SNAP_MAX_HARD_LIMIT);
- }
-
- /* volume snap-max-hard-limit cannot exceed system snap-max-hard-limit.
- * Hence during prevalidate following checks are made to ensure the
- * snap-max-hard-limit set on one particular volume does not
- * exceed snap-max-hard-limit set globally (system limit).
- */
- if (value && volname) {
- max_limit = opt_hard_max;
- }
-
- if ((value < 0) || (value > max_limit)) {
- ret = -1;
- snprintf (err_str, PATH_MAX, "Invalid snap-max-hard-limit "
- "%"PRIu64 ". Expected range 1 - %"PRIu64,
- value, max_limit);
- goto out;
- }
-
- ret = 0;
-out:
- if (ret) {
- *op_errstr = gf_strdup (err_str);
- gf_log (this->name, GF_LOG_ERROR, "%s", err_str);
- }
- return ret;
-}
-
-int
-glusterd_snapshot_config_prevalidate (dict_t *dict, char **op_errstr)
-{
- char *volname = NULL;
- glusterd_volinfo_t *volinfo = NULL;
- xlator_t *this = NULL;
- int ret = -1;
- int config_command = 0;
- char err_str[PATH_MAX] = {0,};
- glusterd_conf_t *conf = NULL;
- uint64_t hard_limit = 0;
- uint64_t soft_limit = 0;
- gf_loglevel_t loglevel = GF_LOG_ERROR;
- uint64_t max_limit = GLUSTERD_SNAPS_MAX_HARD_LIMIT;
- int32_t cur_auto_delete = 0;
- int32_t req_auto_delete = 0;
- int32_t cur_snap_activate = 0;
- int32_t req_snap_activate = 0;
-
- this = THIS;
-
- GF_ASSERT (this);
- GF_ASSERT (dict);
- GF_ASSERT (op_errstr);
-
- conf = this->private;
-
- GF_ASSERT (conf);
-
- ret = dict_get_int32 (dict, "config-command", &config_command);
- if (ret) {
- snprintf (err_str, sizeof (err_str),
- "failed to get config-command type");
- goto out;
- }
-
- if (config_command != GF_SNAP_CONFIG_TYPE_SET) {
- ret = 0;
- goto out;
- }
-
- ret = dict_get_str (dict, "volname", &volname);
- if (volname) {
- ret = glusterd_volinfo_find (volname, &volinfo);
- if (ret) {
- snprintf (err_str, sizeof (err_str),
- "Volume (%s) does not exist.", volname);
- goto out;
- }
- }
-
- /* config values snap-max-hard-limit and snap-max-soft-limit are
- * optional and hence we are not erroring out if values are not
- * present
- */
- gd_get_snap_conf_values_if_present (dict, &hard_limit, &soft_limit);
-
- if (hard_limit) {
- /* Validations for snap-max-hard-limits */
- ret = snap_max_hard_limits_validate (dict, volname,
- hard_limit, op_errstr);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "snap-max-hard-limit validation failed.");
- goto out;
- }
- }
-
- if (soft_limit) {
- max_limit = GLUSTERD_SNAPS_MAX_SOFT_LIMIT_PERCENT;
- if ((soft_limit < 0) || (soft_limit > max_limit)) {
- ret = -1;
- snprintf (err_str, PATH_MAX, "Invalid "
- "snap-max-soft-limit ""%"
- PRIu64 ". Expected range 1 - %"PRIu64,
- soft_limit, max_limit);
- goto out;
- }
- }
-
- if (hard_limit || soft_limit) {
- ret = 0;
- goto out;
- }
-
- if (dict_get(dict, GLUSTERD_STORE_KEY_SNAP_AUTO_DELETE)) {
- req_auto_delete = dict_get_str_boolean (dict,
- GLUSTERD_STORE_KEY_SNAP_AUTO_DELETE,
- _gf_false);
- if (req_auto_delete < 0) {
- ret = -1;
- snprintf (err_str, sizeof (err_str), "Please enter a "
- "valid boolean value for auto-delete");
- goto out;
- }
-
- /* Ignoring the error as the auto-delete is optional and
- might not be present in the options dictionary.*/
- cur_auto_delete = dict_get_str_boolean (conf->opts,
- GLUSTERD_STORE_KEY_SNAP_AUTO_DELETE,
- _gf_false);
-
- if (cur_auto_delete == req_auto_delete) {
- ret = -1;
- if (cur_auto_delete == _gf_true)
- snprintf (err_str, sizeof (err_str),
- "auto-delete is already enabled");
- else
- snprintf (err_str, sizeof (err_str),
- "auto-delete is already disabled");
- goto out;
- }
- } else if (dict_get(dict, GLUSTERD_STORE_KEY_SNAP_ACTIVATE)) {
- req_snap_activate = dict_get_str_boolean (dict,
- GLUSTERD_STORE_KEY_SNAP_ACTIVATE,
- _gf_false);
- if (req_snap_activate < 0) {
- ret = -1;
- snprintf (err_str, sizeof (err_str), "Please enter a "
- "valid boolean value for activate-on-create");
- goto out;
- }
-
- /* Ignoring the error as the activate-on-create is optional and
- might not be present in the options dictionary.*/
- cur_snap_activate = dict_get_str_boolean (conf->opts,
- GLUSTERD_STORE_KEY_SNAP_ACTIVATE,
- _gf_false);
-
- if (cur_snap_activate == req_snap_activate) {
- ret = -1;
- if (cur_snap_activate == _gf_true)
- snprintf (err_str, sizeof (err_str),
- "activate-on-create is already enabled");
- else
- snprintf (err_str, sizeof (err_str),
- "activate-on-create is already disabled");
- goto out;
- }
- } else {
- ret = -1;
- snprintf (err_str, sizeof (err_str), "Invalid option");
- goto out;
- }
-
- ret = 0;
-out:
-
- if (ret && err_str[0] != '\0') {
- gf_log (this->name, loglevel, "%s", err_str);
- *op_errstr = gf_strdup (err_str);
- }
-
- return ret;
-}
-
-/* This function will be called from RPC handler routine.
- * This function is responsible for getting the requested
- * snapshot config into the dictionary.
- *
- * @param req RPC request object. Required for sending a response back.
- * @param op glusterd operation. Required for sending a response back.
- * @param dict pointer to dictionary which will contain both
- * request and response key-pair values.
- * @return -1 on error and 0 on success
- */
-int
-glusterd_handle_snapshot_config (rpcsvc_request_t *req, glusterd_op_t op,
- dict_t *dict, char *err_str, size_t len)
-{
- int32_t ret = -1;
- char *volname = NULL;
- xlator_t *this = NULL;
- int config_command = 0;
-
- this = THIS;
- GF_ASSERT (this);
-
- GF_VALIDATE_OR_GOTO (this->name, req, out);
- GF_VALIDATE_OR_GOTO (this->name, dict, out);
-
- /* TODO : Type of lock to be taken when we are setting
- * limits system wide
- */
- ret = dict_get_int32 (dict, "config-command", &config_command);
- if (ret) {
- snprintf (err_str, len,
- "Failed to get config-command type");
- goto out;
- }
-
- ret = dict_get_str (dict, "volname", &volname);
-
- switch (config_command) {
- case GF_SNAP_CONFIG_TYPE_SET:
- if (!volname) {
- ret = dict_set_int32 (dict, "hold_vol_locks",
- _gf_false);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Unable to set hold_vol_locks value "
- "as _gf_false");
- goto out;
- }
-
- }
- ret = glusterd_mgmt_v3_initiate_all_phases (req, op, dict);
- break;
- case GF_SNAP_CONFIG_DISPLAY:
- /* Reading data from local node only */
- ret = snap_max_limits_display_commit (dict, volname,
- err_str, len);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "snap-max-limit "
- "display commit failed.");
- goto out;
- }
-
- /* If everything is successful then send the response
- * back to cli
- */
- ret = glusterd_op_send_cli_response (op, 0, 0, req, dict,
- err_str);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to send cli "
- "response");
- goto out;
- }
-
- break;
- default:
- gf_log (this->name, GF_LOG_ERROR, "Unknown config type");
- ret = -1;
- break;
- }
-out:
- return ret;
-}
-int
-glusterd_snap_create_pre_val_use_rsp_dict (dict_t *dst, dict_t *src)
-{
- char *snap_brick_dir = NULL;
- char *snap_device = NULL;
- char key[PATH_MAX] = "";
- char *value = "";
- char snapbrckcnt[PATH_MAX] = "";
- char snapbrckord[PATH_MAX] = "";
- int ret = -1;
- int64_t i = -1;
- int64_t j = -1;
- int64_t volume_count = 0;
- int64_t brick_count = 0;
- int64_t brick_order = 0;
- xlator_t *this = NULL;
- int32_t brick_online = 0;
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (dst);
- GF_ASSERT (src);
-
- ret = dict_get_int64 (src, "volcount", &volume_count);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "failed to "
- "get the volume count");
- goto out;
- }
-
- for (i = 0; i < volume_count; i++) {
- memset (snapbrckcnt, '\0', sizeof(snapbrckcnt));
- ret = snprintf (snapbrckcnt, sizeof(snapbrckcnt) - 1,
- "vol%"PRId64"_brickcount", i+1);
- ret = dict_get_int64 (src, snapbrckcnt, &brick_count);
- if (ret) {
- gf_log (this->name, GF_LOG_TRACE,
- "No bricks for this volume in this dict");
- continue;
- }
-
- for (j = 0; j < brick_count; j++) {
- /* Fetching data from source dict */
- snprintf (key, sizeof(key) - 1,
- "vol%"PRId64".brickdir%"PRId64, i+1, j);
- ret = dict_get_ptr (src, key,
- (void **)&snap_brick_dir);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING,
- "Unable to fetch %s", key);
- continue;
- }
-
- /* Fetching brick order from source dict */
- snprintf (snapbrckord, sizeof(snapbrckord) - 1,
- "vol%"PRId64".brick%"PRId64".order", i+1, j);
- ret = dict_get_int64 (src, snapbrckord, &brick_order);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to get brick order");
- goto out;
- }
-
- snprintf (key, sizeof(key) - 1,
- "vol%"PRId64".brickdir%"PRId64, i+1,
- brick_order);
- ret = dict_set_dynstr_with_alloc (dst, key,
- snap_brick_dir);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to set %s", key);
- goto out;
- }
-
- snprintf (key, sizeof(key) - 1,
- "vol%"PRId64".fstype%"PRId64, i+1, j);
- ret = dict_get_str (src, key, &value);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING,
- "Unable to fetch %s", key);
- continue;
- }
-
- snprintf (key, sizeof(key) - 1,
- "vol%"PRId64".fstype%"PRId64, i+1,
- brick_order);
- ret = dict_set_dynstr_with_alloc (dst, key, value);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to set %s", key);
- goto out;
- }
-
- snprintf (key, sizeof(key) - 1,
- "vol%"PRId64".mnt_opts%"PRId64, i+1, j);
- ret = dict_get_str (src, key, &value);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING,
- "Unable to fetch %s", key);
- continue;
- }
-
- snprintf (key, sizeof(key) - 1,
- "vol%"PRId64".mnt_opts%"PRId64, i+1,
- brick_order);
- ret = dict_set_dynstr_with_alloc (dst, key, value);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to set %s", key);
- goto out;
- }
-
- snprintf (key, sizeof(key) - 1,
- "vol%"PRId64".brick_snapdevice%"PRId64,
- i+1, j);
- ret = dict_get_ptr (src, key,
- (void **)&snap_device);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Unable to fetch snap_device");
- goto out;
- }
-
- snprintf (key, sizeof(key) - 1,
- "vol%"PRId64".brick_snapdevice%"PRId64,
- i+1, brick_order);
- ret = dict_set_dynstr_with_alloc (dst, key,
- snap_device);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to set %s", key);
- goto out;
- }
-
- snprintf (key, sizeof (key),
- "vol%"PRId64".brick%"PRId64".status", i+1, brick_order);
- ret = dict_get_int32 (src, key, &brick_online);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "failed to "
- "get the brick status");
- goto out;
- }
-
- ret = dict_set_int32 (dst, key, brick_online);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "failed to "
- "set the brick status");
- goto out;
- }
- brick_online = 0;
- }
- }
- ret = 0;
-out:
-
- gf_log (this->name, GF_LOG_TRACE, "Returning %d", ret);
- return ret;
-}
-
-/* Aggregate brickinfo's of the snap volumes to be restored from */
-int32_t
-glusterd_snap_restore_use_rsp_dict (dict_t *dst, dict_t *src)
-{
- char key[PATH_MAX] = "";
- char *strvalue = NULL;
- int32_t value = -1;
- int32_t i = -1;
- int32_t j = -1;
- int32_t vol_count = -1;
- int32_t brickcount = -1;
- int32_t ret = -1;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
-
- if (!dst || !src) {
- gf_log (this->name, GF_LOG_ERROR, "Source or Destination "
- "dict is empty.");
- goto out;
- }
-
- ret = dict_get_int32 (src, "volcount", &vol_count);
- if (ret) {
- gf_log (this->name, GF_LOG_DEBUG, "No volumes");
- ret = 0;
- goto out;
- }
-
- for (i = 1; i <= vol_count; i++) {
- snprintf (key, sizeof (key), "snap%d.brick_count", i);
- ret = dict_get_int32 (src, key, &brickcount);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to get %s", key);
- goto out;
- }
-
- for (j = 1; j <= brickcount; j++) {
- snprintf (key, sizeof (key), "snap%d.brick%d.path",
- i, j);
- ret = dict_get_str (src, key, &strvalue);
- if (ret) {
- /* The brickinfo will be present in
- * another rsp_dict */
- gf_log (this->name, GF_LOG_DEBUG,
- "%s not present", key);
- ret = 0;
- continue;
- }
- ret = dict_set_dynstr_with_alloc (dst, key, strvalue);
- if (ret) {
- gf_log (this->name, GF_LOG_DEBUG,
- "Failed to set %s", key);
- goto out;
- }
-
- snprintf (key, sizeof (key),
- "snap%d.brick%d.snap_status", i, j);
- ret = dict_get_int32 (src, key, &value);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to get %s", key);
- goto out;
- }
- ret = dict_set_int32 (dst, key, value);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to set %s", key);
- goto out;
- }
-
- snprintf (key, sizeof (key),
- "snap%d.brick%d.device_path", i, j);
- ret = dict_get_str (src, key, &strvalue);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to get %s", key);
- goto out;
- }
- ret = dict_set_dynstr_with_alloc (dst, key, strvalue);
- if (ret) {
- gf_log (this->name, GF_LOG_DEBUG,
- "Failed to set %s", key);
- goto out;
- }
-
- snprintf (key, sizeof (key),
- "snap%d.brick%d.fs_type", i, j);
- ret = dict_get_str (src, key, &strvalue);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to get %s", key);
- goto out;
- }
- ret = dict_set_dynstr_with_alloc (dst, key, strvalue);
- if (ret) {
- gf_log (this->name, GF_LOG_DEBUG,
- "Failed to set %s", key);
- goto out;
- }
-
- snprintf (key, sizeof (key),
- "snap%d.brick%d.mnt_opts", i, j);
- ret = dict_get_str (src, key, &strvalue);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to get %s", key);
- goto out;
- }
- ret = dict_set_dynstr_with_alloc (dst, key, strvalue);
- if (ret) {
- gf_log (this->name, GF_LOG_DEBUG,
- "Failed to set %s", key);
- goto out;
- }
- }
- }
-
-out:
- gf_log (this->name, GF_LOG_TRACE, "Returning %d", ret);
- return ret;
-}
-
-int
-glusterd_snap_pre_validate_use_rsp_dict (dict_t *dst, dict_t *src)
-{
- int ret = -1;
- int32_t snap_command = 0;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
-
- if (!dst || !src) {
- gf_log (this->name, GF_LOG_ERROR, "Source or Destination "
- "dict is empty.");
- goto out;
- }
-
- ret = dict_get_int32 (dst, "type", &snap_command);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "unable to get the type of "
- "the snapshot command");
- goto out;
- }
-
- switch (snap_command) {
- case GF_SNAP_OPTION_TYPE_CREATE:
- ret = glusterd_snap_create_pre_val_use_rsp_dict (dst, src);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Unable to use "
- "rsp dict");
- goto out;
- }
- break;
- case GF_SNAP_OPTION_TYPE_RESTORE:
- ret = glusterd_snap_restore_use_rsp_dict (dst, src);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Unable to use "
- "rsp dict");
- goto out;
- }
- break;
- default:
- break;
- }
-
- ret = 0;
-out:
- gf_log (this->name, GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-
-int
-glusterd_add_brick_status_to_dict (dict_t *dict, glusterd_volinfo_t *volinfo,
- glusterd_brickinfo_t *brickinfo,
- char *key_prefix)
-{
- char pidfile[PATH_MAX] = {0, };
- int32_t brick_online = 0;
- pid_t pid = 0;
- xlator_t *this = NULL;
- glusterd_conf_t *conf = NULL;
- int ret = -1;
-
- GF_ASSERT (dict);
- GF_ASSERT (volinfo);
- GF_ASSERT (brickinfo);
-
- this = THIS;
- GF_ASSERT (this);
- conf = this->private;
- GF_ASSERT (conf);
-
- if (!key_prefix) {
- gf_log (this->name, GF_LOG_ERROR, "key prefix is NULL");
- goto out;
- }
-
- GLUSTERD_GET_BRICK_PIDFILE (pidfile, volinfo, brickinfo, conf);
-
- brick_online = gf_is_service_running (pidfile, &pid);
-
- ret = dict_set_int32 (dict, key_prefix, brick_online);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to set %s", key_prefix);
- goto out;
- }
- brick_online = 0;
-
- ret = 0;
-
-out:
- return ret;
-}
-
-/* This function will check whether the given device
- * is a thinly provisioned LV or not.
- *
- * @param device LV device path
- *
- * @return _gf_true if LV is thin else _gf_false
- */
-gf_boolean_t
-glusterd_is_thinp_brick (char *device)
-{
- int ret = -1;
- char msg [1024] = "";
- char pool_name [PATH_MAX] = "";
- char *ptr = NULL;
- xlator_t *this = NULL;
- runner_t runner = {0,};
- gf_boolean_t is_thin = _gf_false;
-
- this = THIS;
-
- GF_VALIDATE_OR_GOTO ("glusterd", this, out);
- GF_VALIDATE_OR_GOTO (this->name, device, out);
-
- snprintf (msg, sizeof (msg), "Get thin pool name for device %s",
- device);
-
- runinit (&runner);
-
- runner_add_args (&runner, "/sbin/lvs", "--noheadings", "-o", "pool_lv",
- device, NULL);
- runner_redir (&runner, STDOUT_FILENO, RUN_PIPE);
- runner_log (&runner, this->name, GF_LOG_DEBUG, msg);
-
- ret = runner_start (&runner);
- if (ret == -1) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to get thin pool "
- "name for device %s", device);
- runner_end (&runner);
- goto out;
- }
-
- ptr = fgets(pool_name, sizeof(pool_name),
- runner_chio (&runner, STDOUT_FILENO));
- if (!ptr || !strlen(pool_name)) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to get pool name "
- "for device %s", device);
- runner_end (&runner);
- ret = -1;
- goto out;
- }
-
- runner_end (&runner);
-
- /* Trim all the whitespaces. */
- ptr = gf_trim (pool_name);
-
- /* If the LV has thin pool associated with this
- * then it is a thinly provisioned LV else it is
- * regular LV */
- if (0 != ptr [0]) {
- is_thin = _gf_true;
- }
-
-out:
- return is_thin;
-}
-
-int
-glusterd_snapshot_create_prevalidate (dict_t *dict, char **op_errstr,
- dict_t *rsp_dict)
-{
- char *volname = NULL;
- char *snapname = NULL;
- char *device = NULL;
- char key[PATH_MAX] = "";
- char snap_volname[64] = "";
- char err_str[PATH_MAX] = "";
- int ret = -1;
- int64_t i = 0;
- int64_t volcount = 0;
- int64_t brick_count = 0;
- int64_t brick_order = 0;
- glusterd_brickinfo_t *brickinfo = NULL;
- glusterd_volinfo_t *volinfo = NULL;
- xlator_t *this = NULL;
- uuid_t *snap_volid = NULL;
- gf_loglevel_t loglevel = GF_LOG_ERROR;
- glusterd_conf_t *conf = NULL;
- int64_t effective_max_limit = 0;
- int flags = 0;
- uint64_t opt_hard_max = GLUSTERD_SNAPS_MAX_HARD_LIMIT;
-
- this = THIS;
- GF_ASSERT (op_errstr);
- conf = this->private;
- GF_ASSERT (conf);
-
- ret = dict_get_int64 (dict, "volcount", &volcount);
- if (ret) {
- snprintf (err_str, sizeof (err_str), "Failed to "
- "get the volume count");
- goto out;
- }
- if (volcount <= 0) {
- snprintf (err_str, sizeof (err_str),
- "Invalid volume count %"PRId64" supplied", volcount);
- ret = -1;
- goto out;
- }
-
- ret = dict_get_str (dict, "snapname", &snapname);
- if (ret) {
- snprintf (err_str, sizeof (err_str), "Failed to get snapname");
- goto out;
- }
-
- ret = dict_get_int32 (dict, "flags", &flags);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Unable to get flags");
- goto out;
- }
-
- if (glusterd_find_snap_by_name (snapname)) {
- ret = -1;
- snprintf (err_str, sizeof (err_str), "Snapshot %s already "
- "exists", snapname);
- goto out;
- }
-
- for (i = 1; i <= volcount; i++) {
- snprintf (key, sizeof (key), "volname%"PRId64, i);
- ret = dict_get_str (dict, key, &volname);
- if (ret) {
- snprintf (err_str, sizeof (err_str),
- "failed to get volume name");
- goto out;
- }
- ret = glusterd_volinfo_find (volname, &volinfo);
- if (ret) {
- snprintf (err_str, sizeof (err_str),
- "Volume (%s) does not exist ", volname);
- goto out;
- }
-
- ret = -1;
- if (!glusterd_is_volume_started (volinfo)) {
- snprintf (err_str, sizeof (err_str), "volume %s is "
- "not started", volinfo->volname);
- loglevel = GF_LOG_WARNING;
- goto out;
- }
-
- if (glusterd_is_defrag_on (volinfo)) {
- snprintf (err_str, sizeof (err_str),
- "rebalance process is running for the "
- "volume %s", volname);
- loglevel = GF_LOG_WARNING;
- goto out;
- }
-
- if (gd_vol_is_geo_rep_active (volinfo)) {
- snprintf (err_str, sizeof (err_str),
- "geo-replication session is running for "
- "the volume %s. Session needs to be "
- "stopped before taking a snapshot.",
- volname);
- loglevel = GF_LOG_WARNING;
- goto out;
- }
-
- if (volinfo->is_snap_volume == _gf_true) {
- snprintf (err_str, sizeof (err_str),
- "Volume %s is a snap volume", volname);
- loglevel = GF_LOG_WARNING;
- goto out;
- }
-
- /* "snap-max-hard-limit" might not be set by user explicitly,
- * in that case it's better to consider the default value.
- * Hence not erroring out if Key is not found.
- */
- ret = dict_get_uint64 (conf->opts,
- GLUSTERD_STORE_KEY_SNAP_MAX_HARD_LIMIT,
- &opt_hard_max);
- if (ret) {
- ret = 0;
- gf_log (this->name, GF_LOG_DEBUG, "%s is not present "
- "in opts dictionary",
- GLUSTERD_STORE_KEY_SNAP_MAX_HARD_LIMIT);
- }
-
- if (volinfo->snap_max_hard_limit < opt_hard_max)
- effective_max_limit = volinfo->snap_max_hard_limit;
- else
- effective_max_limit = opt_hard_max;
-
- if (volinfo->snap_count >= effective_max_limit) {
- ret = -1;
- snprintf (err_str, sizeof (err_str),
- "The number of existing snaps has reached "
- "the effective maximum limit of %"PRIu64", "
- "for the volume (%s). Please delete few "
- "snapshots before taking further snapshots.",
- effective_max_limit, volname);
- loglevel = GF_LOG_WARNING;
- goto out;
- }
-
- snprintf (key, sizeof(key) - 1, "vol%"PRId64"_volid", i);
- ret = dict_get_bin (dict, key, (void **)&snap_volid);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Unable to fetch snap_volid");
- goto out;
- }
-
- /* snap volume uuid is used as lvm snapshot name.
- This will avoid restrictions on snapshot names
- provided by user */
- GLUSTERD_GET_UUID_NOHYPHEN (snap_volname, *snap_volid);
-
- brick_count = 0;
- brick_order = 0;
- /* Adding snap bricks mount paths to the dict */
- list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) {
- if (uuid_compare (brickinfo->uuid, MY_UUID)) {
- brick_order++;
- continue;
- }
-
- if (!glusterd_is_brick_started (brickinfo)) {
- if(flags & GF_CLI_FLAG_OP_FORCE) {
- gf_log (this->name, GF_LOG_WARNING,
- "brick %s:%s is not started",
- brickinfo->hostname,
- brickinfo->path);
- brick_order++;
- brick_count++;
- continue;
- }
-
- snprintf (err_str, sizeof (err_str),
- "brick %s:%s is not started. "
- "Please start the stopped brick "
- "and then issue snapshot create "
- "command or use [force] option in "
- "snapshot create to override this "
- "behavior.", brickinfo->hostname,
- brickinfo->path);
- ret = -1;
- goto out;
- }
-
- device = glusterd_get_brick_mount_device
- (brickinfo->path);
- if (!device) {
- snprintf (err_str, sizeof (err_str),
- "getting device name for the brick "
- "%s:%s failed", brickinfo->hostname,
- brickinfo->path);
- ret = -1;
- goto out;
- }
-
- if (!glusterd_is_thinp_brick (device)) {
- snprintf (err_str, sizeof (err_str),
- "Snapshot is supported only for "
- "thin provisioned LV. Ensure that "
- "all bricks of %s are thinly "
- "provisioned LV.", volinfo->volname);
- ret = -1;
- goto out;
- }
-
- device = glusterd_build_snap_device_path (device,
- snap_volname,
- brick_count);
- if (!device) {
- snprintf (err_str, sizeof (err_str),
- "cannot copy the snapshot device "
- "name (volname: %s, snapname: %s)",
- volinfo->volname, snapname);
- loglevel = GF_LOG_WARNING;
- ret = -1;
- goto out;
- }
-
- snprintf (key, sizeof(key),
- "vol%"PRId64".brick_snapdevice%"PRId64, i,
- brick_count);
- ret = dict_set_dynstr (rsp_dict, key, device);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to set %s", key);
- GF_FREE (device);
- goto out;
- }
- device = NULL;
-
- ret = glusterd_update_mntopts (brickinfo->path,
- brickinfo);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to "
- "update mount options for %s brick",
- brickinfo->path);
- }
-
- snprintf (key, sizeof(key), "vol%"PRId64".fstype%"
- PRId64, i, brick_count);
- ret = dict_set_dynstr_with_alloc (rsp_dict, key,
- brickinfo->fstype);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to set %s", key);
- goto out;
- }
-
- snprintf (key, sizeof(key), "vol%"PRId64".mnt_opts%"
- PRId64, i, brick_count);
- ret = dict_set_dynstr_with_alloc (rsp_dict, key,
- brickinfo->mnt_opts);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to set %s", key);
- goto out;
- }
-
- snprintf (key, sizeof(key), "vol%"PRId64".brickdir%"PRId64, i,
- brick_count);
- ret = dict_set_dynstr_with_alloc (rsp_dict, key,
- brickinfo->mount_dir);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to set %s", key);
- goto out;
- }
-
- snprintf (key, sizeof(key) - 1, "vol%"PRId64".brick%"PRId64".order",
- i, brick_count);
- ret = dict_set_int64 (rsp_dict, key, brick_order);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to set %s", key);
- goto out;
- }
-
- snprintf (key, sizeof (key), "vol%"PRId64".brick%"PRId64".status",
- i, brick_order);
-
- ret = glusterd_add_brick_status_to_dict (rsp_dict,
- volinfo,
- brickinfo,
- key);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "failed to "
- "add brick status to dict");
- goto out;
- }
-
- brick_count++;
- brick_order++;
- }
-
- snprintf (key, sizeof(key) - 1, "vol%"PRId64"_brickcount", i);
- ret = dict_set_int64 (rsp_dict, key, brick_count);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to set %s",
- key);
- goto out;
- }
- }
-
- ret = dict_set_int64 (rsp_dict, "volcount", volcount);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to set volcount");
- goto out;
- }
-
- ret = 0;
-out:
- if (device)
- GF_FREE (device);
-
- if (ret && err_str[0] != '\0') {
- gf_log (this->name, loglevel, "%s", err_str);
- *op_errstr = gf_strdup (err_str);
- }
-
- gf_log (this->name, GF_LOG_TRACE, "Returning %d", ret);
- return ret;
-}
-
-glusterd_snap_t*
-glusterd_new_snap_object()
-{
- glusterd_snap_t *snap = NULL;
-
- snap = GF_CALLOC (1, sizeof (*snap), gf_gld_mt_snap_t);
-
- if (snap) {
- if (LOCK_INIT (&snap->lock)) {
- gf_log (THIS->name, GF_LOG_ERROR, "Failed initiating"
- " snap lock");
- GF_FREE (snap);
- return NULL;
- }
-
- INIT_LIST_HEAD (&snap->snap_list);
- INIT_LIST_HEAD (&snap->volumes);
- snap->snapname[0] = 0;
- snap->snap_status = GD_SNAP_STATUS_INIT;
- }
-
- return snap;
-
-};
-
-/* Function glusterd_list_add_snapvol adds the volinfo object (snapshot volume)
- to the snapshot object list and to the parent volume list */
-int32_t
-glusterd_list_add_snapvol (glusterd_volinfo_t *origin_vol,
- glusterd_volinfo_t *snap_vol)
-{
- int ret = -1;
- glusterd_snap_t *snap = NULL;
-
- GF_VALIDATE_OR_GOTO ("glusterd", origin_vol, out);
- GF_VALIDATE_OR_GOTO ("glusterd", snap_vol, out);
-
- snap = snap_vol->snapshot;
- GF_ASSERT (snap);
-
- list_add_tail (&snap_vol->vol_list, &snap->volumes);
- LOCK (&origin_vol->lock);
- {
- list_add_order (&snap_vol->snapvol_list,
- &origin_vol->snap_volumes,
- glusterd_compare_snap_vol_time);
- origin_vol->snap_count++;
- }
- UNLOCK (&origin_vol->lock);
-
- gf_log (THIS->name, GF_LOG_DEBUG, "Snapshot %s added to the list",
- snap->snapname);
- ret = 0;
- out:
- return ret;
-}
-
-glusterd_snap_t*
-glusterd_find_snap_by_name (char *snapname)
-{
- glusterd_snap_t *snap = NULL;
- glusterd_conf_t *priv = NULL;
-
- priv = THIS->private;
- GF_ASSERT (priv);
- GF_ASSERT (snapname);
-
- list_for_each_entry (snap, &priv->snapshots, snap_list) {
- if (!strcmp (snap->snapname, snapname)) {
- gf_log (THIS->name, GF_LOG_DEBUG, "Found "
- "snap %s (%s)", snap->snapname,
- uuid_utoa (snap->snap_id));
- goto out;
- }
- }
- snap = NULL;
-out:
- return snap;
-}
-
-glusterd_snap_t*
-glusterd_find_snap_by_id (uuid_t snap_id)
-{
- glusterd_snap_t *snap = NULL;
- glusterd_conf_t *priv = NULL;
-
- priv = THIS->private;
- GF_ASSERT (priv);
-
- if (uuid_is_null(snap_id))
- goto out;
-
- list_for_each_entry (snap, &priv->snapshots, snap_list) {
- if (!uuid_compare (snap->snap_id, snap_id)) {
- gf_log (THIS->name, GF_LOG_DEBUG, "Found "
- "snap %s (%s)", snap->snapname,
- uuid_utoa (snap->snap_id));
- goto out;
- }
- }
- snap = NULL;
-out:
- return snap;
-}
-
-int
-glusterd_do_lvm_snapshot_remove (glusterd_volinfo_t *snap_vol,
- glusterd_brickinfo_t *brickinfo,
- const char *mount_pt, const char *snap_device)
-{
- int ret = -1;
- xlator_t *this = NULL;
- glusterd_conf_t *priv = NULL;
- runner_t runner = {0,};
- char msg[1024] = {0, };
- char pidfile[PATH_MAX] = {0, };
- pid_t pid = -1;
- int retry_count = 0;
- char *mnt_pt = NULL;
- struct mntent *entry = NULL;
- gf_boolean_t unmount = _gf_true;
-
- this = THIS;
- GF_ASSERT (this);
- priv = this->private;
- GF_ASSERT (priv);
-
- if (!brickinfo) {
- gf_log (this->name, GF_LOG_ERROR, "brickinfo NULL");
- goto out;
- }
- GF_ASSERT (snap_vol);
- GF_ASSERT (mount_pt);
- GF_ASSERT (snap_device);
-
- GLUSTERD_GET_BRICK_PIDFILE (pidfile, snap_vol, brickinfo, priv);
- if (gf_is_service_running (pidfile, &pid)) {
- ret = kill (pid, SIGKILL);
- if (ret && errno != ESRCH) {
- gf_log (this->name, GF_LOG_ERROR, "Unable to kill pid "
- "%d reason : %s", pid, strerror(errno));
- goto out;
- }
- }
-
- /* Check if the brick is mounted and then try unmounting the brick */
- ret = glusterd_get_brick_root (brickinfo->path, &mnt_pt);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING, "Getting the root "
- "of the brick for volume %s (snap %s) failed. "
- "Removing lv (%s).", snap_vol->volname,
- snap_vol->snapshot->snapname, snap_device);
- /* The brick path is already unmounted. Remove the lv only *
- * Need not fail the operation */
- ret = 0;
- unmount = _gf_false;
- }
-
- if ((unmount == _gf_true) && (strcmp (mnt_pt, mount_pt))) {
- gf_log (this->name, GF_LOG_WARNING,
- "Lvm is not mounted for brick %s:%s. "
- "Removing lv (%s).", brickinfo->hostname,
- brickinfo->path, snap_device);
- /* The brick path is already unmounted. Remove the lv only *
- * Need not fail the operation */
- unmount = _gf_false;
- }
-
- /* umount cannot be done when the brick process is still in the process
- of shutdown, so give three re-tries */
- while ((unmount == _gf_true) && (retry_count < 3)) {
- retry_count++;
- /*umount2 system call doesn't cleanup mtab entry after un-mount.
- So use external umount command*/
- ret = glusterd_umount(mount_pt);
- if (!ret)
- break;
-
- gf_log (this->name, GF_LOG_DEBUG, "umount failed for "
- "path %s (brick: %s): %s. Retry(%d)", mount_pt,
- brickinfo->path, strerror (errno), retry_count);
-
- sleep (1);
- }
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "umount failed for "
- "path %s (brick: %s): %s.", mount_pt,
- brickinfo->path, strerror (errno));
- goto out;
- }
-
- runinit (&runner);
- snprintf (msg, sizeof(msg), "remove snapshot of the brick %s:%s, "
- "device: %s", brickinfo->hostname, brickinfo->path,
- snap_device);
- runner_add_args (&runner, LVM_REMOVE, "-f", snap_device, NULL);
- runner_log (&runner, "", GF_LOG_DEBUG, msg);
-
- ret = runner_run (&runner);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "removing snapshot of the "
- "brick (%s:%s) of device %s failed",
- brickinfo->hostname, brickinfo->path, snap_device);
- goto out;
- }
-
-out:
- return ret;
-}
-
-int32_t
-glusterd_lvm_snapshot_remove (dict_t *rsp_dict, glusterd_volinfo_t *snap_vol)
-{
- struct mntent save_entry = {0,};
- int32_t brick_count = -1;
- int32_t ret = -1;
- int32_t err = 0;
- glusterd_brickinfo_t *brickinfo = NULL;
- xlator_t *this = NULL;
- char buff[PATH_MAX] = "";
- char brick_dir[PATH_MAX] = "";
- char *tmp = NULL;
- char *brick_mount_path = NULL;
- gf_boolean_t is_brick_dir_present = _gf_false;
- struct stat stbuf = {0,};
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (snap_vol);
-
- if ((snap_vol->is_snap_volume == _gf_false) &&
- (uuid_is_null (snap_vol->restored_from_snap))) {
- gf_log (this->name, GF_LOG_DEBUG,
- "Not a snap volume, or a restored snap volume.");
- ret = 0;
- goto out;
- }
-
- brick_count = -1;
- list_for_each_entry (brickinfo, &snap_vol->bricks, brick_list) {
- brick_count++;
- if (uuid_compare (brickinfo->uuid, MY_UUID)) {
- gf_log (this->name, GF_LOG_DEBUG,
- "%s:%s belongs to a different node",
- brickinfo->hostname, brickinfo->path);
- continue;
- }
-
- /* Fetch the brick mount path from the brickinfo->path */
- ret = glusterd_find_brick_mount_path (brickinfo->path,
- brick_count + 1,
- &brick_mount_path);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to find brick_mount_path for %s",
- brickinfo->path);
- ret = 0;
- continue;
- }
-
- ret = lstat (brick_mount_path, &stbuf);
- if (ret) {
- gf_log (this->name, GF_LOG_DEBUG,
- "Brick %s:%s already deleted.",
- brickinfo->hostname, brickinfo->path);
- ret = 0;
- continue;
- }
-
- if (brickinfo->snap_status == -1) {
- gf_log (this->name, GF_LOG_INFO,
- "snapshot was pending. lvm not present "
- "for brick %s:%s of the snap %s.",
- brickinfo->hostname, brickinfo->path,
- snap_vol->snapshot->snapname);
-
- if (rsp_dict &&
- (snap_vol->is_snap_volume == _gf_true)) {
- /* Adding missed delete to the dict */
- ret = glusterd_add_missed_snaps_to_dict
- (rsp_dict,
- snap_vol,
- brickinfo,
- brick_count + 1,
- GF_SNAP_OPTION_TYPE_DELETE);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to add missed snapshot "
- "info for %s:%s in the "
- "rsp_dict", brickinfo->hostname,
- brickinfo->path);
- goto out;
- }
- }
-
- continue;
- }
-
- /* Check if the brick has a LV associated with it */
- if (!brickinfo->device_path) {
- gf_log (this->name, GF_LOG_DEBUG,
- "Brick (%s:%s) does not have a LV "
- "associated with it. Removing the brick path",
- brickinfo->hostname, brickinfo->path);
- goto remove_brick_path;
- }
-
- /* Verify if the device path exists or not */
- ret = stat (brickinfo->device_path, &stbuf);
- if (ret) {
- gf_log (this->name, GF_LOG_DEBUG,
- "LV (%s) for brick (%s:%s) not present. "
- "Removing the brick path",
- brickinfo->device_path,
- brickinfo->hostname, brickinfo->path);
- /* Making ret = 0 as absence of device path should *
- * not fail the remove operation */
- ret = 0;
- goto remove_brick_path;
- }
-
- ret = glusterd_do_lvm_snapshot_remove (snap_vol, brickinfo,
- brick_mount_path,
- brickinfo->device_path);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to "
- "remove the snapshot %s (%s)",
- brickinfo->path, brickinfo->device_path);
- err = -1; /* We need to record this failure */
- }
-
-remove_brick_path:
- /* After removing the brick dir fetch the parent path
- * i.e /var/run/gluster/snaps/<snap-vol-id>/
- */
- if (is_brick_dir_present == _gf_false) {
- /* Need to fetch brick_dir to be removed from
- * brickinfo->path, as in a restored volume,
- * snap_vol won't have the non-hyphenated snap_vol_id
- */
- tmp = strstr (brick_mount_path, "brick");
- if (!tmp) {
- gf_log (this->name, GF_LOG_ERROR,
- "Invalid brick %s", brickinfo->path);
- GF_FREE (brick_mount_path);
- brick_mount_path = NULL;
- continue;
- }
-
- strncpy (brick_dir, brick_mount_path,
- (size_t) (tmp - brick_mount_path));
-
- /* Peers not hosting bricks will have _gf_false */
- is_brick_dir_present = _gf_true;
- }
-
- GF_FREE (brick_mount_path);
- brick_mount_path = NULL;
- }
-
- if (is_brick_dir_present == _gf_true) {
- ret = glusterd_recursive_rmdir (brick_dir);
- if (ret) {
- if (errno == ENOTEMPTY) {
- /* Will occur when multiple glusterds
- * are running in the same node
- */
- gf_log (this->name, GF_LOG_WARNING,
- "Failed to rmdir: %s, err: %s. "
- "More than one glusterd running "
- "on this node.",
- brick_dir, strerror (errno));
- ret = 0;
- goto out;
- } else
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to rmdir: %s, err: %s",
- brick_dir, strerror (errno));
- goto out;
- }
- }
-
- ret = 0;
-out:
- if (err) {
- ret = err;
- }
- GF_FREE (brick_mount_path);
- gf_log (this->name, GF_LOG_TRACE, "Returning %d", ret);
- return ret;
-}
-
-
-int32_t
-glusterd_snap_volume_remove (dict_t *rsp_dict,
- glusterd_volinfo_t *snap_vol,
- gf_boolean_t remove_lvm,
- gf_boolean_t force)
-{
- int ret = -1;
- int save_ret = 0;
- glusterd_brickinfo_t *brickinfo = NULL;
- glusterd_volinfo_t *origin_vol = NULL;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (rsp_dict);
- GF_ASSERT (snap_vol);
-
- if (!snap_vol) {
- gf_log(this->name, GF_LOG_WARNING, "snap_vol in NULL");
- ret = -1;
- goto out;
- }
-
- list_for_each_entry (brickinfo, &snap_vol->bricks, brick_list) {
- if (uuid_compare (brickinfo->uuid, MY_UUID))
- continue;
-
- ret = glusterd_brick_stop (snap_vol, brickinfo, _gf_false);
- if (ret) {
- gf_log(this->name, GF_LOG_WARNING, "Failed to stop "
- "brick for volume %s", snap_vol->volname);
- save_ret = ret;
-
- /* Don't clean up the snap on error when
- force flag is disabled */
- if (!force)
- goto out;
- }
- }
-
- /* Only remove the backend lvm when required */
- if (remove_lvm) {
- ret = glusterd_lvm_snapshot_remove (rsp_dict, snap_vol);
- if (ret) {
- gf_log(this->name, GF_LOG_WARNING, "Failed to remove "
- "lvm snapshot volume %s", snap_vol->volname);
- save_ret = ret;
- if (!force)
- goto out;
- }
- }
-
- ret = glusterd_store_delete_volume (snap_vol);
- if (ret) {
- gf_log(this->name, GF_LOG_WARNING, "Failed to remove volume %s "
- "from store", snap_vol->volname);
- save_ret = ret;
- if (!force)
- goto out;
- }
-
- if (!list_empty(&snap_vol->snapvol_list)) {
- ret = glusterd_volinfo_find (snap_vol->parent_volname,
- &origin_vol);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to get "
- "parent volinfo %s for volume %s",
- snap_vol->parent_volname, snap_vol->volname);
- save_ret = ret;
- if (!force)
- goto out;
- }
- origin_vol->snap_count--;
- }
-
- ret = glusterd_volinfo_delete (snap_vol);
- if (ret) {
- gf_log(this->name, GF_LOG_WARNING, "Failed to remove volinfo "
- "%s ", snap_vol->volname);
- save_ret = ret;
- if (!force)
- goto out;
- }
-
- if (save_ret)
- ret = save_ret;
-out:
- gf_log (this->name, GF_LOG_TRACE, "returning %d", ret);
- return ret;
-}
-
-int32_t
-glusterd_snapobject_delete (glusterd_snap_t *snap)
-{
- if (snap == NULL) {
- gf_log(THIS->name, GF_LOG_WARNING, "snap is NULL");
- return -1;
- }
-
- list_del_init (&snap->snap_list);
- list_del_init (&snap->volumes);
- if (LOCK_DESTROY(&snap->lock))
- gf_log (THIS->name, GF_LOG_WARNING, "Failed destroying lock"
- "of snap %s", snap->snapname);
-
- GF_FREE (snap->description);
- GF_FREE (snap);
-
- return 0;
-}
-
-int32_t
-glusterd_snap_remove (dict_t *rsp_dict,
- glusterd_snap_t *snap,
- gf_boolean_t remove_lvm,
- gf_boolean_t force)
-{
- int ret = -1;
- int save_ret = 0;
- glusterd_volinfo_t *snap_vol = NULL;
- glusterd_volinfo_t *tmp = NULL;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (rsp_dict);
- GF_ASSERT (snap);
-
- if (!snap) {
- gf_log(this->name, GF_LOG_WARNING, "snap is NULL");
- ret = -1;
- goto out;
- }
-
- list_for_each_entry_safe (snap_vol, tmp, &snap->volumes, vol_list) {
- ret = glusterd_snap_volume_remove (rsp_dict, snap_vol,
- remove_lvm, force);
- if (ret && !force) {
- /* Don't clean up the snap on error when
- force flag is disabled */
- gf_log(this->name, GF_LOG_WARNING, "Failed to remove "
- "volinfo %s for snap %s", snap_vol->volname,
- snap->snapname);
- save_ret = ret;
- goto out;
- }
- }
-
- ret = glusterd_store_delete_snap (snap);
- if (ret) {
- gf_log(this->name, GF_LOG_WARNING, "Failed to remove snap %s "
- "from store", snap->snapname);
- save_ret = ret;
- if (!force)
- goto out;
- }
-
- ret = glusterd_snapobject_delete (snap);
- if (ret)
- gf_log (this->name, GF_LOG_WARNING, "Failed to delete "
- "snap object %s", snap->snapname);
-
- if (save_ret)
- ret = save_ret;
-out:
- gf_log (THIS->name, GF_LOG_TRACE, "returning %d", ret);
- return ret;
-}
-
-static int
-glusterd_snapshot_get_snapvol_detail (dict_t *dict,
- glusterd_volinfo_t *snap_vol,
- char *keyprefix, int detail)
-{
- int ret = -1;
- int snap_limit = 0;
- char key[PATH_MAX] = {0,};
- char *value = NULL;
- glusterd_volinfo_t *origin_vol = NULL;
- glusterd_conf_t *conf = NULL;
- xlator_t *this = NULL;
- uint64_t opt_hard_max = GLUSTERD_SNAPS_MAX_HARD_LIMIT;
-
- this = THIS;
- conf = this->private;
- GF_ASSERT (conf);
-
- GF_ASSERT (dict);
- GF_ASSERT (snap_vol);
- GF_ASSERT (keyprefix);
-
- /* Volume Name */
- value = gf_strdup (snap_vol->volname);
- if (!value)
- goto out;
-
- snprintf (key, sizeof (key), "%s.volname", keyprefix);
- ret = dict_set_dynstr (dict, key, value);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to set "
- "volume name in dictionary: %s", key);
- goto out;
- }
-
- /* Volume ID */
- value = gf_strdup (uuid_utoa (snap_vol->volume_id));
- if (NULL == value) {
- ret = -1;
- goto out;
- }
-
- snprintf (key, sizeof (key), "%s.vol-id", keyprefix);
- ret = dict_set_dynstr (dict, key, value);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to set "
- "volume id in dictionary: %s", key);
- goto out;
- }
- value = NULL;
-
- /* volume status */
- snprintf (key, sizeof (key), "%s.vol-status", keyprefix);
- switch (snap_vol->status) {
- case GLUSTERD_STATUS_STARTED:
- ret = dict_set_str (dict, key, "Started");
- break;
- case GLUSTERD_STATUS_STOPPED:
- ret = dict_set_str (dict, key, "Stopped");
- break;
- case GD_SNAP_STATUS_NONE:
- ret = dict_set_str (dict, key, "None");
- break;
- default:
- gf_log (this->name, GF_LOG_ERROR, "Invalid volume status");
- ret = -1;
- goto out;
- }
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to set volume status"
- " in dictionary: %s", key);
- goto out;
- }
-
-
- ret = glusterd_volinfo_find (snap_vol->parent_volname, &origin_vol);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "failed to get the parent "
- "volinfo for the volume %s", snap_vol->volname);
- goto out;
- }
-
- /* "snap-max-hard-limit" might not be set by user explicitly,
- * in that case it's better to consider the default value.
- * Hence not erroring out if Key is not found.
- */
- ret = dict_get_uint64 (conf->opts,
- GLUSTERD_STORE_KEY_SNAP_MAX_HARD_LIMIT,
- &opt_hard_max);
- if (ret) {
- ret = 0;
- gf_log (this->name, GF_LOG_DEBUG, "%s is not present in "
- "opts dictionary",
- GLUSTERD_STORE_KEY_SNAP_MAX_HARD_LIMIT);
- }
-
- if (opt_hard_max < origin_vol->snap_max_hard_limit) {
- snap_limit = opt_hard_max;
- gf_log(this->name, GF_LOG_DEBUG, "system snap-max-hard-limit is"
- " lesser than volume snap-max-hard-limit, "
- "snap-max-hard-limit value is set to %d", snap_limit);
- } else {
- snap_limit = origin_vol->snap_max_hard_limit;
- gf_log(this->name, GF_LOG_DEBUG, "volume snap-max-hard-limit is"
- " lesser than system snap-max-hard-limit, "
- "snap-max-hard-limit value is set to %d", snap_limit);
- }
-
- snprintf (key, sizeof (key), "%s.snaps-available", keyprefix);
- if (snap_limit > origin_vol->snap_count)
- ret = dict_set_int32 (dict, key,
- snap_limit - origin_vol->snap_count);
- else
- ret = dict_set_int32 (dict, key, 0);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to set available snaps");
- goto out;
- }
-
- snprintf (key, sizeof (key), "%s.snapcount", keyprefix);
- ret = dict_set_int32 (dict, key, origin_vol->snap_count);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Could not save snapcount");
- goto out;
- }
-
- if (!detail)
- goto out;
-
- /* Parent volume name */
- value = gf_strdup (snap_vol->parent_volname);
- if (!value)
- goto out;
-
- snprintf (key, sizeof (key), "%s.origin-volname", keyprefix);
- ret = dict_set_dynstr (dict, key, value);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to set parent "
- "volume name in dictionary: %s", key);
- goto out;
- }
- value = NULL;
-
- ret = 0;
-out:
- if (value)
- GF_FREE (value);
-
- return ret;
-}
-
-static int
-glusterd_snapshot_get_snap_detail (dict_t *dict, glusterd_snap_t *snap,
- char *keyprefix, glusterd_volinfo_t *volinfo)
-{
- int ret = -1;
- int volcount = 0;
- char key[PATH_MAX] = {0,};
- char *value = NULL;
- char *timestr = NULL;
- struct tm *tmptr = NULL;
- glusterd_volinfo_t *snap_vol = NULL;
- glusterd_volinfo_t *tmp_vol = NULL;
- xlator_t *this = NULL;
-
- this = THIS;
-
- GF_ASSERT (dict);
- GF_ASSERT (snap);
- GF_ASSERT (keyprefix);
-
- /* Snap Name */
- value = gf_strdup (snap->snapname);
- if (!value)
- goto out;
-
- snprintf (key, sizeof (key), "%s.snapname", keyprefix);
- ret = dict_set_dynstr (dict, key, value);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to set "
- "snap name in dictionary");
- goto out;
- }
-
- /* Snap ID */
- value = gf_strdup (uuid_utoa (snap->snap_id));
- if (NULL == value) {
- ret = -1;
- goto out;
- }
-
- snprintf (key, sizeof (key), "%s.snap-id", keyprefix);
- ret = dict_set_dynstr (dict, key, value);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to set "
- "snap id in dictionary");
- goto out;
- }
- value = NULL;
-
- tmptr = localtime (&(snap->time_stamp));
- if (NULL == tmptr) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to convert "
- "time_t to *tm");
- ret = -1;
- goto out;
- }
-
- timestr = GF_CALLOC (1, PATH_MAX, gf_gld_mt_char);
- if (NULL == timestr) {
- ret = -1;
- goto out;
- }
-
- ret = strftime (timestr, PATH_MAX, "%Y-%m-%d %H:%M:%S", tmptr);
- if (0 == ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to convert time_t "
- "to string");
- ret = -1;
- goto out;
- }
-
- snprintf (key, sizeof (key), "%s.snap-time", keyprefix);
- ret = dict_set_dynstr (dict, key, timestr);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to set "
- "snap time stamp in dictionary");
- goto out;
- }
- timestr = NULL;
-
- /* If snap description is provided then add that into dictionary */
- if (NULL != snap->description) {
- value = gf_strdup (snap->description);
- if (NULL == value) {
- ret = -1;
- goto out;
- }
-
- snprintf (key, sizeof (key), "%s.snap-desc", keyprefix);
- ret = dict_set_dynstr (dict, key, value);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to set "
- "snap description in dictionary");
- goto out;
- }
- value = NULL;
- }
-
- snprintf (key, sizeof (key), "%s.snap-status", keyprefix);
- switch (snap->snap_status) {
- case GD_SNAP_STATUS_INIT:
- ret = dict_set_str (dict, key, "Init");
- break;
- case GD_SNAP_STATUS_IN_USE:
- ret = dict_set_str (dict, key, "In-use");
- break;
- case GD_SNAP_STATUS_DECOMMISSION:
- ret = dict_set_str (dict, key, "Decommisioned");
- break;
- case GD_SNAP_STATUS_RESTORED:
- ret = dict_set_str (dict, key, "Restored");
- break;
- case GD_SNAP_STATUS_NONE:
- ret = dict_set_str (dict, key, "None");
- break;
- default:
- gf_log (this->name, GF_LOG_ERROR, "Invalid snap status");
- ret = -1;
- goto out;
- }
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to set snap status "
- "in dictionary");
- goto out;
- }
-
- if (volinfo) {
- volcount = 1;
- snprintf (key, sizeof (key), "%s.vol%d", keyprefix, volcount);
- ret = glusterd_snapshot_get_snapvol_detail (dict,
- volinfo, key, 0);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to "
- "get volume detail %s for snap %s",
- snap_vol->volname, snap->snapname);
- goto out;
- }
- goto done;
- }
-
- list_for_each_entry_safe (snap_vol, tmp_vol, &snap->volumes, vol_list) {
- volcount++;
- snprintf (key, sizeof (key), "%s.vol%d", keyprefix, volcount);
- ret = glusterd_snapshot_get_snapvol_detail (dict,
- snap_vol, key, 1);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to "
- "get volume detail %s for snap %s",
- snap_vol->volname, snap->snapname);
- goto out;
- }
- }
-
-done:
- snprintf (key, sizeof (key), "%s.vol-count", keyprefix);
- ret = dict_set_int32 (dict, key, volcount);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to set %s",
- key);
- goto out;
- }
-
- ret = 0;
-out:
- if (value)
- GF_FREE (value);
-
- if (timestr)
- GF_FREE(timestr);
-
- return ret;
-}
-
-static int
-glusterd_snapshot_get_all_snap_info (dict_t *dict)
-{
- int ret = -1;
- int snapcount = 0;
- char key[PATH_MAX] = {0,};
- glusterd_snap_t *snap = NULL;
- glusterd_snap_t *tmp_snap = NULL;
- glusterd_conf_t *priv = NULL;
- xlator_t *this = NULL;
-
- this = THIS;
- priv = this->private;
- GF_ASSERT (priv);
-
- /* General parameter validation */
- GF_ASSERT (dict);
-
- list_for_each_entry_safe (snap, tmp_snap, &priv->snapshots, snap_list) {
- snapcount++;
- snprintf (key, sizeof (key), "snap%d", snapcount);
- ret = glusterd_snapshot_get_snap_detail (dict, snap, key, NULL);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to get "
- "snapdetail for snap %s", snap->snapname);
- goto out;
- }
- }
-
- ret = dict_set_int32 (dict, "snapcount", snapcount);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to set snapcount");
- goto out;
- }
-
- ret = 0;
-out:
- return ret;
-}
-
-int
-glusterd_snapshot_get_info_by_volume (dict_t *dict, char *volname,
- char *err_str, size_t len)
-{
- int ret = -1;
- int snapcount = 0;
- int snap_limit = 0;
- char *value = NULL;
- char key[PATH_MAX] = "";
- glusterd_volinfo_t *volinfo = NULL;
- glusterd_volinfo_t *snap_vol = NULL;
- glusterd_volinfo_t *tmp_vol = NULL;
- glusterd_conf_t *conf = NULL;
- xlator_t *this = NULL;
- uint64_t opt_hard_max = GLUSTERD_SNAPS_MAX_HARD_LIMIT;
-
- this = THIS;
- conf = this->private;
- GF_ASSERT (conf);
-
- GF_ASSERT (dict);
- GF_ASSERT (volname);
-
- ret = glusterd_volinfo_find (volname, &volinfo);
- if (ret) {
- snprintf (err_str, len, "Volume (%s) does not exist", volname);
- gf_log (this->name, GF_LOG_ERROR, "%s", err_str);
- goto out;
- }
-
- /* "snap-max-hard-limit" might not be set by user explicitly,
- * in that case it's better to consider the default value.
- * Hence not erroring out if Key is not found.
- */
- ret = dict_get_uint64 (conf->opts,
- GLUSTERD_STORE_KEY_SNAP_MAX_HARD_LIMIT,
- &opt_hard_max);
- if (ret) {
- ret = 0;
- gf_log (this->name, GF_LOG_DEBUG, "%s is not present in "
- "opts dictionary",
- GLUSTERD_STORE_KEY_SNAP_MAX_HARD_LIMIT);
- }
-
- if (opt_hard_max < volinfo->snap_max_hard_limit) {
- snap_limit = opt_hard_max;
- gf_log(this->name, GF_LOG_DEBUG, "system snap-max-hard-limit is"
- " lesser than volume snap-max-hard-limit, "
- "snap-max-hard-limit value is set to %d", snap_limit);
- } else {
- snap_limit = volinfo->snap_max_hard_limit;
- gf_log(this->name, GF_LOG_DEBUG, "volume snap-max-hard-limit is"
- " lesser than system snap-max-hard-limit, "
- "snap-max-hard-limit value is set to %d", snap_limit);
- }
-
- if (snap_limit > volinfo->snap_count)
- ret = dict_set_int32 (dict, "snaps-available",
- snap_limit - volinfo->snap_count);
- else
- ret = dict_set_int32 (dict, "snaps-available", 0);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to set available snaps");
- goto out;
- }
-
- /* Origin volume name */
- value = gf_strdup (volinfo->volname);
- if (!value)
- goto out;
-
- ret = dict_set_dynstr (dict, "origin-volname", value);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to set parent "
- "volume name in dictionary: %s", key);
- goto out;
- }
- value = NULL;
-
- list_for_each_entry_safe (snap_vol, tmp_vol, &volinfo->snap_volumes,
- snapvol_list) {
- snapcount++;
- snprintf (key, sizeof (key), "snap%d", snapcount);
- ret = glusterd_snapshot_get_snap_detail (dict,
- snap_vol->snapshot,
- key, snap_vol);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to get "
- "snapdetail for snap %s",
- snap_vol->snapshot->snapname);
- goto out;
- }
- }
- ret = dict_set_int32 (dict, "snapcount", snapcount);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to set snapcount");
- goto out;
- }
-
- ret = 0;
-out:
- if (value)
- GF_FREE (value);
-
- return ret;
-}
-
-/* This function will be called from RPC handler routine.
- * This function is responsible for getting the requested
- * snapshot info into the dictionary.
- *
- * @param req RPC request object. Required for sending a response back.
- * @param op glusterd operation. Required for sending a response back.
- * @param dict pointer to dictionary which will contain both
- * request and response key-pair values.
- * @return -1 on error and 0 on success
- */
-int
-glusterd_handle_snapshot_info (rpcsvc_request_t *req, glusterd_op_t op,
- dict_t *dict, char *err_str, size_t len)
-{
- int ret = -1;
- int8_t snap_driven = 1;
- char *volname = NULL;
- char *snapname = NULL;
- glusterd_snap_t *snap = NULL;
- xlator_t *this = NULL;
- int32_t cmd = GF_SNAP_INFO_TYPE_ALL;
-
- this = THIS;
- GF_ASSERT (this);
-
- GF_VALIDATE_OR_GOTO (this->name, req, out);
- GF_VALIDATE_OR_GOTO (this->name, dict, out);
-
-
- ret = dict_get_int32 (dict, "cmd", &cmd);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to get type "
- "of snapshot info");
- goto out;
- }
-
- switch (cmd) {
- case GF_SNAP_INFO_TYPE_ALL:
- {
- ret = glusterd_snapshot_get_all_snap_info (dict);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to get info of all snaps");
- goto out;
- }
- break;
- }
-
- case GF_SNAP_INFO_TYPE_SNAP:
- {
- ret = dict_get_str (dict, "snapname", &snapname);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to get snap name");
- goto out;
- }
-
- ret = dict_set_int32 (dict, "snapcount", 1);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to set snapcount");
- goto out;
- }
-
- snap = glusterd_find_snap_by_name (snapname);
- if (!snap) {
- snprintf (err_str, len,
- "Snapshot (%s) does not exist",
- snapname);
- gf_log (this->name, GF_LOG_ERROR,
- "%s", err_str);
- ret = -1;
- goto out;
- }
- ret = glusterd_snapshot_get_snap_detail (dict, snap,
- "snap1", NULL);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to get snap detail of snap "
- "%s", snap->snapname);
- goto out;
- }
- break;
- }
-
- case GF_SNAP_INFO_TYPE_VOL:
- {
- ret = dict_get_str (dict, "volname", &volname);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to get volname");
- goto out;
- }
- ret = glusterd_snapshot_get_info_by_volume (dict,
- volname, err_str, len);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to get volume info of volume "
- "%s", volname);
- goto out;
- }
- snap_driven = 0;
- break;
- }
- }
-
- ret = dict_set_int8 (dict, "snap-driven", snap_driven);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to set snap-driven");
- goto out;
- }
-
- /* If everything is successful then send the response back to cli.
- * In case of failure the caller of this function will take care
- of the response */
- ret = glusterd_op_send_cli_response (op, 0, 0, req, dict, err_str);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to send cli "
- "response");
- goto out;
- }
-
- ret = 0;
-
-out:
- return ret;
-}
-
-/* This function sets all the snapshot names in the dictionary */
-int
-glusterd_snapshot_get_all_snapnames (dict_t *dict)
-{
- int ret = -1;
- int snapcount = 0;
- char *snapname = NULL;
- char key[PATH_MAX] = {0,};
- glusterd_snap_t *snap = NULL;
- glusterd_snap_t *tmp_snap = NULL;
- glusterd_conf_t *priv = NULL;
- xlator_t *this = NULL;
-
- this = THIS;
- priv = this->private;
- GF_ASSERT (priv);
- GF_ASSERT (dict);
-
- list_for_each_entry_safe (snap, tmp_snap, &priv->snapshots, snap_list) {
- snapcount++;
- snapname = gf_strdup (snap->snapname);
- if (!snapname) {
- gf_log (this->name, GF_LOG_ERROR, "strdup failed");
- ret = -1;
- goto out;
- }
- snprintf (key, sizeof (key), "snapname%d", snapcount);
- ret = dict_set_dynstr (dict, key, snapname);
- if (ret) {
- GF_FREE (snapname);
- gf_log (this->name, GF_LOG_ERROR, "Failed to set %s",
- key);
- goto out;
- }
- }
-
- ret = dict_set_int32 (dict, "snapcount", snapcount);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to set snapcount");
- goto out;
- }
-
- ret = 0;
-out:
-
- return ret;
-}
-
-/* This function sets all the snapshot names
- under a given volume in the dictionary */
-int
-glusterd_snapshot_get_vol_snapnames (dict_t *dict, glusterd_volinfo_t *volinfo)
-{
- int ret = -1;
- int snapcount = 0;
- char *snapname = NULL;
- char key[PATH_MAX] = {0,};
- glusterd_volinfo_t *snap_vol = NULL;
- glusterd_volinfo_t *tmp_vol = NULL;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (dict);
- GF_ASSERT (volinfo);
-
- list_for_each_entry_safe (snap_vol, tmp_vol,
- &volinfo->snap_volumes, snapvol_list) {
- snapcount++;
- snprintf (key, sizeof (key), "snapname%d", snapcount);
-
- ret = dict_set_dynstr_with_alloc (dict, key,
- snap_vol->snapshot->snapname);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to "
- "set %s", key);
- GF_FREE (snapname);
- goto out;
- }
- }
-
- ret = dict_set_int32 (dict, "snapcount", snapcount);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to set snapcount");
- goto out;
- }
-
- ret = 0;
-out:
-
- return ret;
-}
-
-int
-glusterd_handle_snapshot_list (rpcsvc_request_t *req, glusterd_op_t op,
- dict_t *dict, char *err_str, size_t len)
-{
- int ret = -1;
- char *volname = NULL;
- glusterd_volinfo_t *volinfo = NULL;
- xlator_t *this = NULL;
-
- this = THIS;
-
- GF_VALIDATE_OR_GOTO (this->name, req, out);
- GF_VALIDATE_OR_GOTO (this->name, dict, out);
-
- /* Ignore error for getting volname as it is optional */
- ret = dict_get_str (dict, "volname", &volname);
-
- if (NULL == volname) {
- ret = glusterd_snapshot_get_all_snapnames (dict);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to get snapshot list");
- goto out;
- }
- } else {
- ret = glusterd_volinfo_find (volname, &volinfo);
- if (ret) {
- snprintf (err_str, len,
- "Volume (%s) does not exist", volname);
- gf_log (this->name, GF_LOG_ERROR,
- "%s", err_str);
- goto out;
- }
-
- ret = glusterd_snapshot_get_vol_snapnames (dict, volinfo);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to get snapshot list for volume %s",
- volname);
- goto out;
- }
- }
-
- /* If everything is successful then send the response back to cli.
- In case of failure the caller of this function will take of response.*/
- ret = glusterd_op_send_cli_response (op, 0, 0, req, dict, err_str);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to send cli "
- "response");
- goto out;
- }
-
- ret = 0;
-
-out:
- return ret;
-}
-
-/* This is a snapshot create handler function. This function will be
- * executed in the originator node. This function is responsible for
- * calling mgmt_v3 framework to do the actual snap creation on all the bricks
- *
- * @param req RPC request object
- * @param op gluster operation
- * @param dict dictionary containing snapshot restore request
- * @param err_str In case of an err this string should be populated
- * @param len length of err_str buffer
- *
- * @return Negative value on Failure and 0 in success
- */
-int
-glusterd_handle_snapshot_create (rpcsvc_request_t *req, glusterd_op_t op,
- dict_t *dict, char *err_str, size_t len)
-{
- int ret = -1;
- char *volname = NULL;
- char *snapname = NULL;
- int64_t volcount = 0;
- xlator_t *this = NULL;
- char key[PATH_MAX] = "";
- char *username = NULL;
- char *password = NULL;
- uuid_t *uuid_ptr = NULL;
- uuid_t tmp_uuid = {0};
- int i = 0;
- char snap_volname[GD_VOLUME_NAME_MAX] = {0, };
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (req);
- GF_ASSERT (dict);
- GF_ASSERT (err_str);
-
- ret = dict_get_int64 (dict, "volcount", &volcount);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "failed to "
- "get the volume count");
- goto out;
- }
- if (volcount <= 0) {
- gf_log (this->name, GF_LOG_ERROR, "Invalid volume count %"PRId64
- " supplied", volcount);
- ret = -1;
- goto out;
- }
-
- ret = dict_get_str (dict, "snapname", &snapname);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "failed to get the snapname");
- goto out;
- }
-
- if (strlen(snapname) >= GLUSTERD_MAX_SNAP_NAME) {
- snprintf (err_str, len, "snapname cannot exceed 255 "
- "characters");
- gf_log (this->name, GF_LOG_ERROR, "%s", err_str);
- ret = -1;
- goto out;
- }
-
- uuid_ptr = GF_CALLOC (1, sizeof(uuid_t), gf_common_mt_uuid_t);
- if (!uuid_ptr) {
- gf_log (this->name, GF_LOG_ERROR, "Out Of Memory");
- ret = -1;
- goto out;
- }
-
- uuid_generate (*uuid_ptr);
- ret = dict_set_bin (dict, "snap-id", uuid_ptr, sizeof(uuid_t));
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Unable to set snap-id");
- GF_FREE (uuid_ptr);
- goto out;
- }
- uuid_ptr = NULL;
-
- ret = dict_set_int64 (dict, "snap-time", (int64_t)time(NULL));
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Unable to set snap-time");
- goto out;
- }
-
- for (i = 1; i <= volcount; i++) {
- snprintf (key, sizeof (key), "volname%d", i);
- ret = dict_get_str (dict, key, &volname);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to get volume name");
- goto out;
- }
-
- /* generate internal username and password for the snap*/
- uuid_generate (tmp_uuid);
- username = gf_strdup (uuid_utoa (tmp_uuid));
- snprintf (key, sizeof(key), "volume%d_username", i);
- ret = dict_set_dynstr (dict, key, username);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to set snap "
- "username for volume %s", volname);
- GF_FREE (username);
- goto out;
- }
-
- uuid_generate (tmp_uuid);
- password = gf_strdup (uuid_utoa (tmp_uuid));
- snprintf (key, sizeof(key), "volume%d_password", i);
- ret = dict_set_dynstr (dict, key, password);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to set snap "
- "password for volume %s", volname);
- GF_FREE (password);
- goto out;
- }
-
- uuid_ptr = GF_CALLOC (1, sizeof(uuid_t), gf_common_mt_uuid_t);
- if (!uuid_ptr) {
- gf_log (this->name, GF_LOG_ERROR, "Out Of Memory");
- ret = -1;
- goto out;
- }
-
- snprintf (key, sizeof(key) - 1, "vol%d_volid", i);
- uuid_generate (*uuid_ptr);
- ret = dict_set_bin (dict, key, uuid_ptr, sizeof(uuid_t));
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Unable to set snap_volid");
- GF_FREE (uuid_ptr);
- goto out;
- }
- GLUSTERD_GET_UUID_NOHYPHEN (snap_volname, *uuid_ptr);
- snprintf (key, sizeof (key), "snap-volname%d", i);
- ret = dict_set_dynstr_with_alloc (dict, key, snap_volname);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Unable to set snap volname");
- GF_FREE (uuid_ptr);
- goto out;
- }
- }
-
- ret = glusterd_mgmt_v3_initiate_snap_phases (req, op, dict);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to initiate snap "
- "phases");
- }
-
-out:
- return ret;
-}
-
-/* This is a snapshot status handler function. This function will be
- * executed in a originator node. This function is responsible for
- * calling mgmt v3 framework to get the actual snapshot status from
- * all the bricks
- *
- * @param req RPC request object
- * @param op gluster operation
- * @param dict dictionary containing snapshot status request
- * @param err_str In case of an err this string should be populated
- * @param len length of err_str buffer
- *
- * return : 0 in case of success.
- * -1 in case of failure.
- *
- */
-int
-glusterd_handle_snapshot_status (rpcsvc_request_t *req, glusterd_op_t op,
- dict_t *dict, char *err_str, size_t len)
-{
- int ret = -1;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
-
- GF_ASSERT (req);
- GF_ASSERT (dict);
- GF_ASSERT (err_str);
-
-
- ret = glusterd_mgmt_v3_initiate_snap_phases (req, op, dict);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to initiate "
- "snap phases");
- goto out;
- }
-
- ret = 0;
-out:
- return ret;
-}
-
-
-/* This is a snapshot restore handler function. This function will be
- * executed in the originator node. This function is responsible for
- * calling mgmt_v3 framework to do the actual restore on all the bricks
- *
- * @param req RPC request object
- * @param op gluster operation
- * @param dict dictionary containing snapshot restore request
- * @param err_str In case of an err this string should be populated
- * @param len length of err_str buffer
- *
- * @return Negative value on Failure and 0 in success
- */
-int
-glusterd_handle_snapshot_restore (rpcsvc_request_t *req, glusterd_op_t op,
- dict_t *dict, char *err_str, size_t len)
-{
- int ret = -1;
- char *snapname = NULL;
- char *buf = NULL;
- glusterd_conf_t *conf = NULL;
- xlator_t *this = NULL;
- glusterd_snap_t *snap = NULL;
- glusterd_volinfo_t *snap_volinfo = NULL;
- int32_t i = 0;
- char key[PATH_MAX] = "";
-
- this = THIS;
- GF_ASSERT (this);
- conf = this->private;
-
- GF_ASSERT (conf);
- GF_ASSERT (req);
- GF_ASSERT (dict);
- GF_ASSERT (err_str);
-
- ret = dict_get_str (dict, "snapname", &snapname);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to "
- "get snapname");
- goto out;
- }
-
- snap = glusterd_find_snap_by_name (snapname);
- if (!snap) {
- snprintf (err_str, len, "Snapshot (%s) does not exist",
- snapname);
- gf_log (this->name, GF_LOG_ERROR, "%s", err_str);
- ret = -1;
- goto out;
- }
-
- list_for_each_entry (snap_volinfo, &snap->volumes, vol_list) {
- i++;
- snprintf (key, sizeof (key), "volname%d", i);
- buf = gf_strdup (snap_volinfo->parent_volname);
- if (!buf) {
- ret = -1;
- goto out;
- }
- ret = dict_set_dynstr (dict, key, buf);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Could not set "
- "parent volume name %s in the dict",
- snap_volinfo->parent_volname);
- GF_FREE (buf);
- goto out;
- }
- buf = NULL;
- }
-
- ret = dict_set_int32 (dict, "volcount", i);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Could not save volume count");
- goto out;
- }
-
- ret = glusterd_mgmt_v3_initiate_snap_phases (req, op, dict);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to initiate snap "
- "phases");
- goto out;
- }
-
- ret = 0;
-
-out:
- return ret;
-}
-
-glusterd_snap_t*
-glusterd_create_snap_object (dict_t *dict, dict_t *rsp_dict)
-{
- char *snapname = NULL;
- uuid_t *snap_id = NULL;
- char *description = NULL;
- glusterd_snap_t *snap = NULL;
- xlator_t *this = NULL;
- glusterd_conf_t *priv = NULL;
- int ret = -1;
- int64_t time_stamp = 0;
-
- this = THIS;
- priv = this->private;
-
- GF_ASSERT (dict);
- GF_ASSERT (rsp_dict);
-
- /* Fetch snapname, description, id and time from dict */
- ret = dict_get_str (dict, "snapname", &snapname);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Unable to fetch snapname");
- goto out;
- }
-
- /* Ignore ret value for description*/
- ret = dict_get_str (dict, "description", &description);
-
- ret = dict_get_bin (dict, "snap-id", (void **)&snap_id);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Unable to fetch snap_id");
- goto out;
- }
-
- ret = dict_get_int64 (dict, "snap-time", &time_stamp);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Unable to fetch snap-time");
- goto out;
- }
- if (time_stamp <= 0) {
- ret = -1;
- gf_log (this->name, GF_LOG_ERROR, "Invalid time-stamp: %"PRId64,
- time_stamp);
- goto out;
- }
-
- list_for_each_entry (snap, &priv->snapshots, snap_list) {
- if (!strcmp (snap->snapname, snapname) ||
- !uuid_compare (snap->snap_id, *snap_id)) {
- gf_log (THIS->name, GF_LOG_ERROR,
- "Found duplicate snap %s (%s)",
- snap->snapname, uuid_utoa (snap->snap_id));
- ret = -1;
- break;
- }
- }
- if (ret) {
- snap = NULL;
- goto out;
- }
-
- snap = glusterd_new_snap_object ();
- if (!snap) {
- gf_log (this->name, GF_LOG_ERROR, "Could not create "
- "the snap object for snap %s", snapname);
- goto out;
- }
-
- strcpy (snap->snapname, snapname);
- uuid_copy (snap->snap_id, *snap_id);
- snap->time_stamp = (time_t)time_stamp;
- /* Set the status as GD_SNAP_STATUS_INIT and once the backend snapshot
- is taken and snap is really ready to use, set the status to
- GD_SNAP_STATUS_IN_USE. This helps in identifying the incomplete
- snapshots and cleaning them up.
- */
- snap->snap_status = GD_SNAP_STATUS_INIT;
- if (description) {
- snap->description = gf_strdup (description);
- if (snap->description == NULL) {
- gf_log (this->name, GF_LOG_ERROR,
- "Saving the Snapshot Description Failed");
- ret = -1;
- goto out;
- }
- }
-
- ret = glusterd_store_snap (snap);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING, "Could not store snap"
- "object %s", snap->snapname);
- goto out;
- }
-
- list_add_order (&snap->snap_list, &priv->snapshots,
- glusterd_compare_snap_time);
-
- gf_log (this->name, GF_LOG_TRACE, "Snapshot %s added to the list",
- snap->snapname);
-
- ret = 0;
-
-out:
- if (ret) {
- if (snap)
- glusterd_snap_remove (rsp_dict, snap,
- _gf_true, _gf_true);
- snap = NULL;
- }
-
- return snap;
-}
-
-/* Added missed_snap_entry to rsp_dict */
-int32_t
-glusterd_add_missed_snaps_to_dict (dict_t *rsp_dict,
- glusterd_volinfo_t *snap_vol,
- glusterd_brickinfo_t *brickinfo,
- int32_t brick_number, int32_t op)
-{
- char *snap_uuid = NULL;
- char missed_snap_entry[PATH_MAX] = "";
- char name_buf[PATH_MAX] = "";
- int32_t missed_snap_count = -1;
- int32_t ret = -1;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (rsp_dict);
- GF_ASSERT (snap_vol);
- GF_ASSERT (brickinfo);
-
- snap_uuid = gf_strdup (uuid_utoa (snap_vol->snapshot->snap_id));
- if (!snap_uuid) {
- ret = -1;
- goto out;
- }
-
- snprintf (missed_snap_entry, sizeof(missed_snap_entry),
- "%s:%s=%s:%d:%s:%d:%d", uuid_utoa(brickinfo->uuid),
- snap_uuid, snap_vol->volname, brick_number, brickinfo->path,
- op, GD_MISSED_SNAP_PENDING);
-
- /* Fetch the missed_snap_count from the dict */
- ret = dict_get_int32 (rsp_dict, "missed_snap_count",
- &missed_snap_count);
- if (ret) {
- /* Initialize the missed_snap_count for the first time */
- missed_snap_count = 0;
- }
-
- /* Setting the missed_snap_entry in the rsp_dict */
- snprintf (name_buf, sizeof(name_buf), "missed_snaps_%d",
- missed_snap_count);
- ret = dict_set_dynstr_with_alloc (rsp_dict, name_buf,
- missed_snap_entry);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to set missed_snap_entry (%s) "
- "in the rsp_dict.", missed_snap_entry);
- goto out;
- }
- missed_snap_count++;
-
- /* Setting the new missed_snap_count in the dict */
- ret = dict_set_int32 (rsp_dict, "missed_snap_count",
- missed_snap_count);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to set missed_snap_count for %s "
- "in the rsp_dict.", missed_snap_entry);
- goto out;
- }
-
-out:
- if (snap_uuid)
- GF_FREE (snap_uuid);
-
- gf_log (this->name, GF_LOG_TRACE, "Returning %d", ret);
- return ret;
-}
-
-/* This function actually calls the command (or the API) for taking the
- snapshot of the backend brick filesystem. If this is successful,
- then call the glusterd_snap_create function to create the snap object
- for glusterd
-*/
-int32_t
-glusterd_take_lvm_snapshot (glusterd_brickinfo_t *brickinfo,
- char *origin_brick_path)
-{
- char msg[NAME_MAX] = "";
- char buf[PATH_MAX] = "";
- char *ptr = NULL;
- char *origin_device = NULL;
- int ret = -1;
- gf_boolean_t match = _gf_false;
- runner_t runner = {0,};
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (brickinfo);
- GF_ASSERT (origin_brick_path);
-
- origin_device = glusterd_get_brick_mount_device (origin_brick_path);
- if (!origin_device) {
- gf_log (this->name, GF_LOG_ERROR, "getting device name for "
- "the brick %s failed", origin_brick_path);
- goto out;
- }
-
- /* Figuring out if setactivationskip flag is supported or not */
- runinit (&runner);
- snprintf (msg, sizeof (msg), "running lvcreate help");
- runner_add_args (&runner, LVM_CREATE, "--help", NULL);
- runner_log (&runner, "", GF_LOG_DEBUG, msg);
- runner_redir (&runner, STDOUT_FILENO, RUN_PIPE);
- ret = runner_start (&runner);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to run lvcreate help");
- runner_end (&runner);
- goto out;
- }
-
- /* Looking for setactivationskip in lvcreate --help */
- do {
- ptr = fgets(buf, sizeof(buf),
- runner_chio (&runner, STDOUT_FILENO));
- if (ptr) {
- if (strstr(buf, "setactivationskip")) {
- match = _gf_true;
- break;
- }
- }
- } while (ptr != NULL);
- runner_end (&runner);
-
- /* Taking the actual snapshot */
- runinit (&runner);
- snprintf (msg, sizeof (msg), "taking snapshot of the brick %s",
- origin_brick_path);
- if (match == _gf_true)
- runner_add_args (&runner, LVM_CREATE, "-s", origin_device,
- "--setactivationskip", "n", "--name",
- brickinfo->device_path, NULL);
- else
- runner_add_args (&runner, LVM_CREATE, "-s", origin_device,
- "--name", brickinfo->device_path, NULL);
- runner_log (&runner, this->name, GF_LOG_DEBUG, msg);
- ret = runner_run (&runner);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "taking snapshot of the "
- "brick (%s) of device %s failed",
- origin_brick_path, origin_device);
- }
-
-out:
- return ret;
-}
-
-int32_t
-glusterd_snap_brick_create (glusterd_volinfo_t *snap_volinfo,
- glusterd_brickinfo_t *brickinfo,
- int32_t brick_count)
-{
- int32_t ret = -1;
- xlator_t *this = NULL;
- glusterd_conf_t *priv = NULL;
- char snap_brick_mount_path[PATH_MAX] = "";
- struct stat statbuf = {0, };
-
- this = THIS;
- priv = this->private;
-
- GF_ASSERT (snap_volinfo);
- GF_ASSERT (brickinfo);
-
- snprintf (snap_brick_mount_path, sizeof (snap_brick_mount_path),
- "%s/%s/brick%d", snap_mount_folder, snap_volinfo->volname,
- brick_count + 1);
-
- ret = mkdir_p (snap_brick_mount_path, 0777, _gf_true);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "creating the brick directory"
- " %s for the snapshot %s(device: %s) failed",
- snap_brick_mount_path, snap_volinfo->volname,
- brickinfo->device_path);
- goto out;
- }
- /* mount the snap logical device on the directory inside
- /run/gluster/snaps/<snapname>/@snap_brick_mount_path
- Way to mount the snap brick via mount api is this.
- ret = mount (device, snap_brick_mount_path, entry->mnt_type,
- MS_MGC_VAL, "nouuid");
- But for now, mounting using runner apis.
- */
- ret = glusterd_mount_lvm_snapshot (brickinfo, snap_brick_mount_path);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to mount lvm snapshot.");
- goto out;
- }
-
- ret = stat (brickinfo->path, &statbuf);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING, "stat of the brick %s"
- "(brick mount: %s) failed (%s)", brickinfo->path,
- snap_brick_mount_path, strerror (errno));
- goto out;
- }
- ret = sys_lsetxattr (brickinfo->path,
- GF_XATTR_VOL_ID_KEY,
- snap_volinfo->volume_id, 16,
- XATTR_REPLACE);
- if (ret == -1) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to set "
- "extended attribute %s on %s. Reason: "
- "%s, snap: %s", GF_XATTR_VOL_ID_KEY,
- brickinfo->path, strerror (errno),
- snap_volinfo->volname);
- goto out;
- }
-
-out:
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING, "unmounting the snap brick"
- " mount %s", snap_brick_mount_path);
- /*umount2 system call doesn't cleanup mtab entry after un-mount.
- So use external umount command*/
- glusterd_umount (snap_brick_mount_path);
- }
-
- gf_log (this->name, GF_LOG_TRACE, "Returning %d", ret);
- return ret;
-}
-
-static int32_t
-glusterd_add_brick_to_snap_volume (dict_t *dict, dict_t *rsp_dict,
- glusterd_volinfo_t *snap_vol,
- glusterd_brickinfo_t *original_brickinfo,
- int64_t volcount, int32_t brick_count)
-{
- char key[PATH_MAX] = "";
- char *value = NULL;
- char *snap_brick_dir = NULL;
- char snap_brick_path[PATH_MAX] = "";
- char *snap_device = NULL;
- glusterd_brickinfo_t *snap_brickinfo = NULL;
- gf_boolean_t add_missed_snap = _gf_false;
- int32_t ret = -1;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (dict);
- GF_ASSERT (rsp_dict);
- GF_ASSERT (snap_vol);
- GF_ASSERT (original_brickinfo);
-
- snprintf (key, sizeof(key), "vol%"PRId64".origin_brickpath%d",
- volcount, brick_count);
- ret = dict_set_dynstr_with_alloc (dict, key, original_brickinfo->path);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to set %s", key);
- goto out;
- }
-
- ret = glusterd_brickinfo_new (&snap_brickinfo);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "initializing the brick for the snap "
- "volume failed (snapname: %s)",
- snap_vol->snapshot->snapname);
- goto out;
- }
-
- snprintf (key, sizeof(key) - 1, "vol%"PRId64".fstype%d", volcount,
- brick_count);
- ret = dict_get_str (dict, key, &value);
- if (!ret) {
- /* Update the fstype in original brickinfo as well */
- strcpy (original_brickinfo->fstype, value);
- strcpy (snap_brickinfo->fstype, value);
- } else {
- if (is_origin_glusterd (dict) == _gf_true)
- add_missed_snap = _gf_true;
- }
-
- snprintf (key, sizeof(key) - 1, "vol%"PRId64".mnt_opts%d", volcount,
- brick_count);
- ret = dict_get_str (dict, key, &value);
- if (!ret) {
- /* Update the mnt_opts in original brickinfo as well */
- strcpy (original_brickinfo->mnt_opts, value);
- strcpy (snap_brickinfo->mnt_opts, value);
- } else {
- if (is_origin_glusterd (dict) == _gf_true)
- add_missed_snap = _gf_true;
- }
-
- snprintf (key, sizeof(key) - 1, "vol%"PRId64".brickdir%d", volcount,
- brick_count);
- ret = dict_get_str (dict, key, &snap_brick_dir);
- if (ret) {
- /* Using original brickinfo here because it will be a
- * pending snapshot and storing the original brickinfo
- * will help in mapping while recreating the missed snapshot
- */
- gf_log (this->name, GF_LOG_WARNING, "Unable to fetch "
- "snap mount path(%s). Adding to missed_snap_list", key);
- snap_brickinfo->snap_status = -1;
-
- snap_brick_dir = original_brickinfo->mount_dir;
-
- /* In origiator node add snaps missed
- * from different nodes to the dict
- */
- if (is_origin_glusterd (dict) == _gf_true)
- add_missed_snap = _gf_true;
- }
-
- if ((snap_brickinfo->snap_status != -1) &&
- (!uuid_compare (original_brickinfo->uuid, MY_UUID)) &&
- (!glusterd_is_brick_started (original_brickinfo))) {
- /* In case if the brick goes down after prevalidate. */
- gf_log (this->name, GF_LOG_WARNING, "brick %s:%s is not"
- " started (snap: %s)",
- original_brickinfo->hostname,
- original_brickinfo->path,
- snap_vol->snapshot->snapname);
-
- snap_brickinfo->snap_status = -1;
- add_missed_snap = _gf_true;
- }
-
- if (add_missed_snap) {
- ret = glusterd_add_missed_snaps_to_dict (rsp_dict,
- snap_vol,
- original_brickinfo,
- brick_count + 1,
- GF_SNAP_OPTION_TYPE_CREATE);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to add missed"
- " snapshot info for %s:%s in the rsp_dict",
- original_brickinfo->hostname,
- original_brickinfo->path);
- goto out;
- }
- }
-
- /* Create brick-path in the format /var/run/gluster/snaps/ *
- * <snap-uuid>/<original-brick#>/snap-brick-dir *
- */
- snprintf (snap_brick_path, sizeof(snap_brick_path),
- "%s/%s/brick%d%s", snap_mount_folder,
- snap_vol->volname, brick_count+1,
- snap_brick_dir);
-
- snprintf (key, sizeof(key), "vol%"PRId64".brick_snapdevice%d",
- volcount, brick_count);
- ret = dict_get_str (dict, key, &snap_device);
- if (ret) {
- /* If the device name is empty, so will be the brick path
- * Hence the missed snap has already been added above
- */
- gf_log (this->name, GF_LOG_ERROR, "Unable to fetch "
- "snap device (%s). Leaving empty", key);
- } else
- strcpy (snap_brickinfo->device_path, snap_device);
-
- ret = gf_canonicalize_path (snap_brick_path);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to canonicalize path");
- goto out;
- }
-
- strcpy (snap_brickinfo->hostname, original_brickinfo->hostname);
- strcpy (snap_brickinfo->path, snap_brick_path);
- strcpy (snap_brickinfo->mount_dir, original_brickinfo->mount_dir);
- uuid_copy (snap_brickinfo->uuid, original_brickinfo->uuid);
- /* AFR changelog names are based on brick_id and hence the snap
- * volume's bricks must retain the same ID */
- strcpy (snap_brickinfo->brick_id, original_brickinfo->brick_id);
- list_add_tail (&snap_brickinfo->brick_list, &snap_vol->bricks);
-
-out:
- if (ret && snap_brickinfo)
- GF_FREE (snap_brickinfo);
-
- gf_log (this->name, GF_LOG_TRACE, "Returning %d", ret);
- return ret;
-}
-
-/* This function will update the file-system label of the
- * backend snapshot brick.
- *
- * @param brickinfo brickinfo of the snap volume
- *
- * @return 0 on success and -1 on failure
- */
-int
-glusterd_update_fs_label (glusterd_brickinfo_t *brickinfo)
-{
- int32_t ret = -1;
- char msg [PATH_MAX] = "";
- char label [NAME_MAX] = "";
- uuid_t uuid = {0,};
- runner_t runner = {0,};
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (brickinfo);
-
- /* Generate a new UUID */
- uuid_generate (uuid);
-
- GLUSTERD_GET_UUID_NOHYPHEN (label, uuid);
-
- runinit (&runner);
-
- /* Call the file-system specific tools to update the file-system
- * label. Currently we are only supporting xfs and ext2/ext3/ext4
- * file-system.
- */
- if (0 == strcmp (brickinfo->fstype, "xfs")) {
- /* XFS label is of size 12. Therefore we should truncate the
- * label to 12 bytes*/
- label [12] = '\0';
- snprintf (msg, sizeof (msg), "Changing filesystem label of "
- "%s brick to %s", brickinfo->path, label);
- /* Run the run xfs_admin tool to change the label
- * of the file-system */
- runner_add_args (&runner, "xfs_admin", "-L", label,
- brickinfo->device_path, NULL);
- } else if (0 == strcmp (brickinfo->fstype, "ext4") ||
- 0 == strcmp (brickinfo->fstype, "ext3") ||
- 0 == strcmp (brickinfo->fstype, "ext2")) {
- /* Ext2/Ext3/Ext4 label is of size 16. Therefore we should
- * truncate the label to 16 bytes*/
- label [16] = '\0';
- snprintf (msg, sizeof (msg), "Changing filesystem label of "
- "%s brick to %s", brickinfo->path, label);
- /* For ext2/ext3/ext4 run tune2fs to change the
- * file-system label */
- runner_add_args (&runner, "tune2fs", "-L", label,
- brickinfo->device_path, NULL);
- } else {
- gf_log (this->name, GF_LOG_WARNING, "Changing file-system "
- "label of %s file-system is not supported as of now",
- brickinfo->fstype);
- runner_end (&runner);
- ret = -1;
- goto out;
- }
-
- runner_log (&runner, this->name, GF_LOG_DEBUG, msg);
- ret = runner_run (&runner);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to change "
- "filesystem label of %s brick to %s",
- brickinfo->path, label);
- goto out;
- }
-
- ret = 0;
-out:
- return ret;
-}
-
-static int32_t
-glusterd_take_brick_snapshot (dict_t *dict, glusterd_volinfo_t *snap_vol,
- glusterd_brickinfo_t *brickinfo,
- int32_t volcount, int32_t brick_count)
-{
- char *origin_brick_path = NULL;
- char key[PATH_MAX] = "";
- int32_t ret = -1;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (dict);
- GF_ASSERT (snap_vol);
- GF_ASSERT (brickinfo);
-
- if (strlen(brickinfo->device_path) == 0) {
- gf_log (this->name, GF_LOG_ERROR, "Device path is empty "
- "brick %s:%s", brickinfo->hostname, brickinfo->path);
- ret = -1;
- goto out;
- }
-
- snprintf (key, sizeof(key) - 1, "vol%d.origin_brickpath%d", volcount,
- brick_count);
- ret = dict_get_str (dict, key, &origin_brick_path);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING, "Unable to fetch "
- "brick path (%s)", key);
- goto out;
- }
-
- ret = glusterd_take_lvm_snapshot (brickinfo, origin_brick_path);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to take snapshot of "
- "brick %s:%s", brickinfo->hostname, origin_brick_path);
- goto out;
- }
-
- /* After the snapshot both the origin brick (LVM brick) and
- * the snapshot brick will have the same file-system label. This
- * will cause lot of problems at mount time. Therefore we must
- * generate a new label for the snapshot brick
- */
- ret = glusterd_update_fs_label (brickinfo);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to update "
- "file-system label for %s brick", brickinfo->path);
- /* Failing to update label should not cause snapshot failure.
- * Currently label is updated only for XFS and ext2/ext3/ext4
- * file-system.
- */
- }
-
- /* create the complete brick here */
- ret = glusterd_snap_brick_create (snap_vol, brickinfo, brick_count);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "not able to"
- " create the brick for the snap %s"
- ", volume %s", snap_vol->snapshot->snapname,
- snap_vol->volname);
- goto out;
- }
-
-out:
- gf_log (this->name, GF_LOG_TRACE, "Returning %d", ret);
- return ret;
-}
-
-glusterd_volinfo_t *
-glusterd_do_snap_vol (glusterd_volinfo_t *origin_vol, glusterd_snap_t *snap,
- dict_t *dict, dict_t *rsp_dict, int64_t volcount)
-{
- char key[PATH_MAX] = "";
- char *username = NULL;
- char *password = NULL;
- glusterd_brickinfo_t *brickinfo = NULL;
- glusterd_conf_t *priv = NULL;
- glusterd_volinfo_t *snap_vol = NULL;
- uuid_t *snap_volid = NULL;
- int32_t ret = -1;
- int32_t brick_count = 0;
- xlator_t *this = NULL;
- int64_t brick_order = 0;
-
- this = THIS;
- GF_ASSERT (this);
-
- priv = this->private;
- GF_ASSERT (priv);
- GF_ASSERT (dict);
- GF_ASSERT (origin_vol);
- GF_ASSERT (rsp_dict);
-
- /* fetch username, password and vol_id from dict*/
- snprintf (key, sizeof(key), "volume%"PRId64"_username", volcount);
- ret = dict_get_str (dict, key, &username);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to get %s for "
- "snap %s", key, snap->snapname);
- goto out;
- }
-
- snprintf (key, sizeof(key), "volume%"PRId64"_password", volcount);
- ret = dict_get_str (dict, key, &password);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to get %s for "
- "snap %s", key, snap->snapname);
- goto out;
- }
-
- snprintf (key, sizeof(key) - 1, "vol%"PRId64"_volid", volcount);
- ret = dict_get_bin (dict, key, (void **)&snap_volid);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Unable to fetch snap_volid");
- goto out;
- }
-
- /* We are not setting the username and password here as
- * we need to set the user name and password passed in
- * the dictionary
- */
- ret = glusterd_volinfo_dup (origin_vol, &snap_vol, _gf_false);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to duplicate volinfo "
- "for the snapshot %s", snap->snapname);
- goto out;
- }
-
- /* uuid is used as lvm snapshot name.
- This will avoid restrictions on snapshot names provided by user */
- GLUSTERD_GET_UUID_NOHYPHEN (snap_vol->volname, *snap_volid);
- uuid_copy (snap_vol->volume_id, *snap_volid);
- snap_vol->is_snap_volume = _gf_true;
- strcpy (snap_vol->parent_volname, origin_vol->volname);
- snap_vol->snapshot = snap;
-
- glusterd_auth_set_username (snap_vol, username);
- glusterd_auth_set_password (snap_vol, password);
-
- /* TODO : Sync before taking a snapshot */
- /* Copy the status and config files of geo-replication before
- * taking a snapshot. During restore operation these files needs
- * to be copied back in /var/lib/glusterd/georeplication/
- */
- ret = glusterd_copy_geo_rep_files (origin_vol, snap_vol, rsp_dict);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to copy geo-rep "
- "config and status files for volume %s",
- origin_vol->volname);
- goto out;
- }
-
- /* Adding snap brickinfos to the snap volinfo */
- brick_count = 0;
- list_for_each_entry (brickinfo, &origin_vol->bricks, brick_list) {
- ret = glusterd_add_brick_to_snap_volume (dict, rsp_dict,
- snap_vol, brickinfo,
- volcount, brick_count);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to add the snap brick for "
- "%s:%s to the snap volume",
- brickinfo->hostname, brickinfo->path);
- goto out;
- }
-
- brick_count++;
- }
-
-
- /* During snapshot creation if I/O is in progress,
- * then barrier value is enabled. Hence during snapshot create
- * and in-turn snapshot restore the barrier value is set to enable.
- * Because of this further I/O on the mount point fails.
- * Hence remove the barrier key from newly created snap volinfo
- * before storing and generating the brick volfiles. Also update
- * the snap vol's version after removing the barrier key.
- */
- dict_del (snap_vol->dict, "features.barrier");
- gd_update_volume_op_versions (snap_vol);
-
- ret = glusterd_store_volinfo (snap_vol,
- GLUSTERD_VOLINFO_VER_AC_INCREMENT);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to store snapshot "
- "volinfo (%s) for snap %s", snap_vol->volname,
- snap->snapname);
- goto out;
- }
-
- ret = glusterd_copy_quota_files (origin_vol, snap_vol);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to copy quota "
- "config and cksum for volume %s", origin_vol->volname);
- goto out;
- }
-
- ret = generate_brick_volfiles (snap_vol);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "generating the brick "
- "volfiles for the snap %s (volume: %s) failed",
- snap->snapname, origin_vol->volname);
- goto out;
- }
-
- ret = generate_client_volfiles (snap_vol, GF_CLIENT_TRUSTED);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "generating the trusted "
- "client volfiles for the snap %s (volume: %s) failed",
- snap->snapname, origin_vol->volname);
- goto out;
- }
-
- ret = generate_client_volfiles (snap_vol, GF_CLIENT_OTHER);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "generating the client "
- "volfiles for the snap %s (volume: %s) failed",
- snap->snapname, origin_vol->volname);
- goto out;
- }
-
- ret = glusterd_list_add_snapvol (origin_vol, snap_vol);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "could not add the snap "
- "volume %s to the list", snap_vol->volname);
- goto out;
- }
-
-out:
- if (ret) {
- if (snap_vol)
- glusterd_snap_volume_remove (rsp_dict, snap_vol,
- _gf_true, _gf_true);
- snap_vol = NULL;
- }
-
- return snap_vol;
-}
-
-/*This is the prevalidate function for both activate and deactive of snap
- * For Activate operation pass is_op_activate as _gf_true
- * For Deactivate operation pass is_op_activate as _gf_false
- * */
-int
-glusterd_snapshot_activate_deactivate_prevalidate (dict_t *dict,
- char **op_errstr, dict_t *rsp_dict, gf_boolean_t is_op_activate)
-{
- int32_t ret = -1;
- char *snapname = NULL;
- xlator_t *this = NULL;
- glusterd_snap_t *snap = NULL;
- glusterd_volinfo_t *snap_volinfo = NULL;
- char err_str[PATH_MAX] = "";
- gf_loglevel_t loglevel = GF_LOG_ERROR;
- glusterd_volume_status volume_status = GLUSTERD_STATUS_STOPPED;
- int flags = 0;
-
- this = THIS;
-
- if (!dict || !op_errstr) {
- gf_log (this->name, GF_LOG_ERROR, "input parameters NULL");
- goto out;
- }
-
- ret = dict_get_str (dict, "snapname", &snapname);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Getting the snap name "
- "failed");
- goto out;
- }
-
- snap = glusterd_find_snap_by_name (snapname);
- if (!snap) {
- snprintf (err_str, sizeof (err_str), "Snapshot (%s) does not "
- "exist.", snapname);
- ret = -1;
- goto out;
- }
-
- /*If its activation of snap then fetch the flags*/
- if (is_op_activate) {
- ret = dict_get_int32 (dict, "flags", &flags);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Unable to get flags");
- goto out;
- }
- }
-
- /* TODO : As of now there is only volume in snapshot.
- * Change this when multiple volume snapshot is introduced
- */
- snap_volinfo = list_entry (snap->volumes.next, glusterd_volinfo_t,
- vol_list);
- if (!snap_volinfo) {
- gf_log (this->name, GF_LOG_ERROR,
- "Unable to fetch snap_volinfo");
- ret = -1;
- goto out;
- }
-
- /*TODO: When multiple snapvolume are involved a cummulative
- * logic is required to tell whether is snapshot is
- * started/partially started/stopped*/
- if (is_op_activate) {
- volume_status = GLUSTERD_STATUS_STARTED;
- }
-
- if (snap_volinfo->status == volume_status) {
- if (is_op_activate) {
- /* if flag is to GF_CLI_FLAG_OP_FORCE
- * try to start the snap volume, even
- * if the volume_status is GLUSTERD_STATUS_STARTED.
- * By doing so we try to bring
- * back the brick processes that are down*/
- if (!(flags & GF_CLI_FLAG_OP_FORCE)) {
- snprintf (err_str, sizeof (err_str),
- "Snapshot %s is already activated.",
- snapname);
- ret = -1;
- }
- } else {
- snprintf (err_str, sizeof (err_str),
- "Snapshot %s is already deactivated.", snapname);
- ret = -1;
- }
- goto out;
- }
- ret = 0;
-out:
-
- if (ret && err_str[0] != '\0') {
- gf_log (this->name, loglevel, "%s", err_str);
- *op_errstr = gf_strdup (err_str);
- }
-
- return ret;
-}
-
-int32_t
-glusterd_handle_snapshot_delete_vol (dict_t *dict, char *err_str, int len)
-{
- int32_t ret = -1;
- int32_t i = 0;
- glusterd_volinfo_t *snap_volinfo = NULL;
- glusterd_volinfo_t *volinfo = NULL;
- glusterd_volinfo_t *temp_volinfo = NULL;
- char key[PATH_MAX] = "";
- xlator_t *this = NULL;
- char *volname = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (dict);
-
- ret = dict_get_str (dict, "volname", &volname);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to get "
- "volume name");
- goto out;
- }
-
- ret = glusterd_volinfo_find (volname, &volinfo);
- if (ret) {
- snprintf (err_str, len, "Volume (%s) does not exist", volname);
- gf_log (this->name, GF_LOG_ERROR, "Failed to get volinfo of "
- "volume %s", volname);
- goto out;
- }
-
- ret = glusterd_snapshot_get_vol_snapnames (dict, volinfo);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to get snapshot list for volume %s", volname);
- goto out;
- }
-
- ret = 0;
-out:
- return ret;
-}
-
-int32_t
-glusterd_handle_snapshot_delete_all (dict_t *dict)
-{
- int32_t ret = -1;
- int32_t i = 0;
- char key[PATH_MAX] = "";
- glusterd_conf_t *priv = NULL;
- glusterd_snap_t *snap = NULL;
- glusterd_snap_t *tmp_snap = NULL;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- priv = this->private;
- GF_ASSERT (priv);
-
- GF_ASSERT (dict);
-
- list_for_each_entry_safe (snap, tmp_snap, &priv->snapshots, snap_list) {
- /* indexing from 1 to n, to keep it uniform with other code
- * paths
- */
- i++;
- ret = snprintf (key, sizeof (key), "snapname%d", i);
- if (ret < 0) {
- goto out;
- }
-
- ret = dict_set_dynstr_with_alloc (dict, key, snap->snapname);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Could not save "
- "snap name");
- goto out;
- }
- }
-
- ret = dict_set_int32 (dict, "snapcount", i);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Could not save snapcount");
- goto out;
- }
-
- ret = 0;
-
-out:
- return ret;
-}
-
-int32_t
-glusterd_handle_snapshot_delete_type_snap (rpcsvc_request_t *req,
- glusterd_op_t op,
- dict_t *dict, char *err_str,
- size_t len)
-{
- int32_t ret = -1;
- int64_t volcount = 0;
- char *snapname = NULL;
- char *volname = NULL;
- char key[PATH_MAX] = "";
- glusterd_snap_t *snap = NULL;
- glusterd_volinfo_t *snap_vol = NULL;
- glusterd_volinfo_t *tmp = NULL;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
-
- GF_ASSERT (req);
- GF_ASSERT (dict);
- GF_ASSERT (err_str);
-
- ret = dict_get_str (dict, "snapname", &snapname);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to get snapname");
- goto out;
- }
-
- snap = glusterd_find_snap_by_name (snapname);
- if (!snap) {
- snprintf (err_str, len, "Snapshot (%s) does not exist",
- snapname);
- gf_log (this->name, GF_LOG_ERROR,
- "%s", err_str);
- ret = -1;
- goto out;
- }
-
- /* Set volnames in the dict to get mgmt_v3 lock */
- list_for_each_entry_safe (snap_vol, tmp, &snap->volumes, vol_list) {
- volcount++;
- volname = gf_strdup (snap_vol->parent_volname);
- if (!volname) {
- ret = -1;
- gf_log (this->name, GF_LOG_ERROR, "strdup failed");
- goto out;
- }
-
- snprintf (key, sizeof (key), "volname%"PRId64, volcount);
- ret = dict_set_dynstr (dict, key, volname);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to set "
- "volume name in dictionary");
- GF_FREE (volname);
- goto out;
- }
- volname = NULL;
- }
- ret = dict_set_int64 (dict, "volcount", volcount);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to set volcount");
- goto out;
- }
-
- ret = glusterd_mgmt_v3_initiate_snap_phases (req, op, dict);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to initiate snap "
- "phases");
- goto out;
- }
-
- ret = 0;
-
-out :
- return ret;
-}
-
-/* This is a snapshot remove handler function. This function will be
- * executed in the originator node. This function is responsible for
- * calling mgmt v3 framework to do the actual remove on all the bricks
- *
- * @param req RPC request object
- * @param op gluster operation
- * @param dict dictionary containing snapshot remove request
- * @param err_str In case of an err this string should be populated
- * @param len length of err_str buffer
- *
- * @return Negative value on Failure and 0 in success
- */
-int
-glusterd_handle_snapshot_delete (rpcsvc_request_t *req, glusterd_op_t op,
- dict_t *dict, char *err_str, size_t len)
-{
- int ret = -1;
- xlator_t *this = NULL;
- int32_t delete_cmd = -1;
-
- this = THIS;
-
- GF_ASSERT (this);
-
- GF_ASSERT (req);
- GF_ASSERT (dict);
- GF_ASSERT (err_str);
-
- ret = dict_get_int32 (dict, "delete-cmd", &delete_cmd);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to get delete-cmd");
- goto out;
- }
-
- switch (delete_cmd) {
- case GF_SNAP_DELETE_TYPE_SNAP:
- ret = glusterd_handle_snapshot_delete_type_snap (req, op, dict,
- err_str, len);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to handle "
- "snapshot delete for type SNAP");
- goto out;
- }
- break;
-
- case GF_SNAP_DELETE_TYPE_ALL:
- ret = glusterd_handle_snapshot_delete_all (dict);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to handle "
- "snapshot delete for type ALL");
- goto out;
- }
- break;
-
- case GF_SNAP_DELETE_TYPE_VOL:
- ret = glusterd_handle_snapshot_delete_vol (dict, err_str, len);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to handle "
- "snapshot delete for type VOL");
- goto out;
- }
- break;
-
- default:
- gf_log (this->name, GF_LOG_ERROR, "Wrong snapshot delete type");
- break;
- }
-
- if ( ret == 0 && (delete_cmd == GF_SNAP_DELETE_TYPE_ALL ||
- delete_cmd == GF_SNAP_DELETE_TYPE_VOL)) {
- ret = glusterd_op_send_cli_response (op, 0, 0, req, dict,
- err_str);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to send cli "
- "response");
- goto out;
- }
- }
- ret = 0;
-out:
- return ret;
-}
-
-int
-glusterd_snapshot_remove_prevalidate (dict_t *dict, char **op_errstr,
- dict_t *rsp_dict)
-{
- int32_t ret = -1;
- char *snapname = NULL;
- xlator_t *this = NULL;
- glusterd_snap_t *snap = NULL;
-
- this = THIS;
-
- if (!dict || !op_errstr) {
- gf_log (this->name, GF_LOG_ERROR, "input parameters NULL");
- goto out;
- }
-
- ret = dict_get_str (dict, "snapname", &snapname);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Getting the snap name "
- "failed");
- goto out;
- }
-
- snap = glusterd_find_snap_by_name (snapname);
- if (!snap) {
- gf_log (this->name, GF_LOG_ERROR,
- "Snapshot (%s) does not exist", snapname);
- ret = -1;
- goto out;
- }
-
- ret = dict_set_dynstr_with_alloc (dict, "snapuuid",
- uuid_utoa (snap->snap_id));
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to set snap "
- "uuid in response dictionary for %s snapshot",
- snap->snapname);
- goto out;
- }
-
- ret = 0;
-out:
- return ret;
-}
-
-int
-glusterd_snapshot_status_prevalidate (dict_t *dict, char **op_errstr,
- dict_t *rsp_dict)
-{
- int ret = -1;
- char *snapname = NULL;
- glusterd_conf_t *conf = NULL;
- xlator_t *this = NULL;
- int32_t cmd = -1;
- glusterd_volinfo_t *volinfo = NULL;
- char *volname = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- conf = this->private;
-
- GF_ASSERT (conf);
- GF_ASSERT (op_errstr);
- if (!dict) {
- gf_log (this->name, GF_LOG_ERROR, "Input dict is NULL");
- goto out;
- }
-
- ret = dict_get_int32 (dict, "status-cmd", &cmd);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Could not fetch status cmd");
- goto out;
- }
-
- switch (cmd) {
- case GF_SNAP_STATUS_TYPE_ALL:
- {
- break;
- }
- case GF_SNAP_STATUS_TYPE_SNAP:
- {
- ret = dict_get_str (dict, "snapname", &snapname);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Could not fetch snapname");
- goto out;
- }
-
- if (!glusterd_find_snap_by_name (snapname)) {
- ret = gf_asprintf (op_errstr, "Snapshot (%s) "
- "does not exist", snapname);
- if (ret < 0) {
- goto out;
- }
- ret = -1;
- gf_log (this->name, GF_LOG_ERROR,
- "Snapshot (%s) does not exist",
- snapname);
- goto out;
- }
- break;
- }
- case GF_SNAP_STATUS_TYPE_VOL:
- {
- ret = dict_get_str (dict, "volname", &volname);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Could not fetch volname");
- goto out;
- }
-
- ret = glusterd_volinfo_find (volname, &volinfo);
- if (ret) {
- ret = gf_asprintf (op_errstr, "Volume (%s) "
- "does not exist", volname);
- if (ret < 0) {
- goto out;
- }
- ret = -1;
- gf_log (this->name, GF_LOG_ERROR, "Volume "
- "%s not present", volname);
- goto out;
- }
- break;
-
- }
- default:
- {
- gf_log (this->name, GF_LOG_ERROR, "Invalid command");
- break;
- }
- }
- ret = 0;
-
-out:
- return ret;
-}
-
-int32_t
-glusterd_snapshot_activate_commit (dict_t *dict, char **op_errstr,
- dict_t *rsp_dict)
-{
- int32_t ret = -1;
- char *snapname = NULL;
- glusterd_snap_t *snap = NULL;
- glusterd_volinfo_t *snap_volinfo = NULL;
- xlator_t *this = NULL;
- int flags = 0;
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (dict);
- GF_ASSERT (rsp_dict);
- GF_ASSERT (op_errstr);
-
- if (!dict || !op_errstr) {
- gf_log (this->name, GF_LOG_ERROR, "input parameters NULL");
- goto out;
- }
-
- ret = dict_get_str (dict, "snapname", &snapname);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Getting the snap name "
- "failed");
- goto out;
- }
-
- ret = dict_get_int32 (dict, "flags", &flags);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Unable to get flags");
- goto out;
- }
-
- snap = glusterd_find_snap_by_name (snapname);
- if (!snap) {
- gf_log (this->name, GF_LOG_ERROR,
- "Snapshot (%s) does not exist", snapname);
- ret = -1;
- goto out;
- }
-
- /* TODO : As of now there is only volume in snapshot.
- * Change this when multiple volume snapshot is introduced
- */
- snap_volinfo = list_entry (snap->volumes.next, glusterd_volinfo_t,
- vol_list);
- if (!snap_volinfo) {
- gf_log (this->name, GF_LOG_ERROR,
- "Unable to fetch snap_volinfo");
- ret = -1;
- goto out;
- }
-
- ret = glusterd_start_volume (snap_volinfo, flags, _gf_true);
-
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to activate snap volume %s of the snap %s",
- snap_volinfo->volname, snap->snapname);
- goto out;
- }
-
- ret = dict_set_dynstr_with_alloc (rsp_dict, "snapuuid",
- uuid_utoa (snap->snap_id));
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to set snap "
- "uuid in response dictionary for %s snapshot",
- snap->snapname);
- goto out;
- }
-
- ret = 0;
-out:
- return ret;
-}
-
-int32_t
-glusterd_snapshot_deactivate_commit (dict_t *dict, char **op_errstr,
- dict_t *rsp_dict)
-{
- int32_t ret = -1;
- char *snapname = NULL;
- glusterd_snap_t *snap = NULL;
- glusterd_volinfo_t *snap_volinfo = NULL;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (dict);
- GF_ASSERT (rsp_dict);
- GF_ASSERT (op_errstr);
-
- if (!dict || !op_errstr) {
- gf_log (this->name, GF_LOG_ERROR, "input parameters NULL");
- goto out;
- }
-
- ret = dict_get_str (dict, "snapname", &snapname);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Getting the snap name "
- "failed");
- goto out;
- }
-
- snap = glusterd_find_snap_by_name (snapname);
- if (!snap) {
- gf_log (this->name, GF_LOG_ERROR,
- "Snapshot (%s) does not exist", snapname);
- ret = -1;
- goto out;
- }
-
- /* TODO : As of now there is only volume in snapshot.
- * Change this when multiple volume snapshot is introduced
- */
- snap_volinfo = list_entry (snap->volumes.next, glusterd_volinfo_t,
- vol_list);
- if (!snap_volinfo) {
- gf_log (this->name, GF_LOG_ERROR,
- "Unable to fetch snap_volinfo");
- ret = -1;
- goto out;
- }
-
- ret = glusterd_stop_volume (snap_volinfo);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to deactivate"
- "snap %s", snapname);
- goto out;
- }
-
- ret = dict_set_dynstr_with_alloc (rsp_dict, "snapuuid",
- uuid_utoa (snap->snap_id));
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to set snap "
- "uuid in response dictionary for %s snapshot",
- snap->snapname);
- goto out;
- }
-
- ret = 0;
-out:
- return ret;
-}
-
-int32_t
-glusterd_snapshot_remove_commit (dict_t *dict, char **op_errstr,
- dict_t *rsp_dict)
-{
- int32_t ret = -1;
- char *snapname = NULL;
- char *dup_snapname = NULL;
- glusterd_snap_t *snap = NULL;
- glusterd_conf_t *priv = NULL;
- glusterd_volinfo_t *snap_volinfo = NULL;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (dict);
- GF_ASSERT (rsp_dict);
- GF_ASSERT (op_errstr);
-
- priv = this->private;
- GF_ASSERT (priv);
-
- if (!dict || !op_errstr) {
- gf_log (this->name, GF_LOG_ERROR, "input parameters NULL");
- goto out;
- }
-
- ret = dict_get_str (dict, "snapname", &snapname);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Getting the snap name "
- "failed");
- goto out;
- }
-
- snap = glusterd_find_snap_by_name (snapname);
- if (!snap) {
- gf_log (this->name, GF_LOG_ERROR,
- "Snapshot (%s) does not exist", snapname);
- ret = -1;
- goto out;
- }
-
- ret = dict_set_dynstr_with_alloc (rsp_dict, "snapuuid",
- uuid_utoa (snap->snap_id));
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to set snap uuid in "
- "response dictionary for %s snapshot",
- snap->snapname);
- goto out;
- }
-
- /* Save the snap status as GD_SNAP_STATUS_DECOMMISSION so
- * that if the node goes down the snap would be removed
- */
- snap->snap_status = GD_SNAP_STATUS_DECOMMISSION;
- ret = glusterd_store_snap (snap);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to "
- "store snap object %s", snap->snapname);
- goto out;
- } else
- gf_log (this->name, GF_LOG_INFO, "Successfully marked "
- "snap %s for decommission.", snap->snapname);
-
- if (is_origin_glusterd (dict) == _gf_true) {
- /* TODO : As of now there is only volume in snapshot.
- * Change this when multiple volume snapshot is introduced
- */
- snap_volinfo = list_entry (snap->volumes.next,
- glusterd_volinfo_t,
- vol_list);
- if (!snap_volinfo) {
- gf_log (this->name, GF_LOG_ERROR,
- "Unable to fetch snap_volinfo");
- ret = -1;
- goto out;
- }
-
- /* From origin glusterd check if *
- * any peers with snap bricks is down */
- ret = glusterd_find_missed_snap (rsp_dict, snap_volinfo,
- &priv->peers,
- GF_SNAP_OPTION_TYPE_DELETE);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to find missed snap deletes");
- goto out;
- }
- }
-
- ret = glusterd_snap_remove (rsp_dict, snap, _gf_true, _gf_false);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to remove snap %s",
- snapname);
- goto out;
- }
-
- dup_snapname = gf_strdup (snapname);
- if (!dup_snapname) {
- gf_log (this->name, GF_LOG_ERROR, "Strdup failed");
- ret = -1;
- goto out;
- }
-
- ret = dict_set_dynstr (rsp_dict, "snapname", dup_snapname);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to set the snapname");
- GF_FREE (dup_snapname);
- goto out;
- }
-
- ret = 0;
-out:
- return ret;
-}
-
-int32_t
-glusterd_do_snap_cleanup (dict_t *dict, char **op_errstr, dict_t *rsp_dict)
-{
- int32_t ret = -1;
- char *name = NULL;
- xlator_t *this = NULL;
- glusterd_conf_t *conf = NULL;
- glusterd_volinfo_t *volinfo = NULL;
- glusterd_snap_t *snap = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- conf = this->private;
- GF_ASSERT (conf);
-
- if (!dict || !op_errstr) {
- gf_log (this->name, GF_LOG_ERROR, "input parameters NULL");
- goto out;
- }
-
- ret = dict_get_str (dict, "snapname", &name);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "getting the snap "
- "name failed (volume: %s)", volinfo->volname);
- goto out;
- }
-
- /*
- If the snapname is not found that means the failure happened at
- staging, or in commit, before the snap object is created, in which
- case there is nothing to cleanup. So set ret to 0.
- */
- snap = glusterd_find_snap_by_name (name);
- if (!snap) {
- gf_log (this->name, GF_LOG_INFO, "Snapshot (%s) does not exist",
- name);
- ret = 0;
- goto out;
- }
-
- ret = glusterd_snap_remove (rsp_dict, snap, _gf_true, _gf_true);
- if (ret) {
- /* Ignore failure as this is a cleanup of half cooked
- snapshot */
- gf_log (this->name, GF_LOG_DEBUG, "removing the snap %s failed",
- name);
- ret = 0;
- }
-
- name = NULL;
-
- ret = 0;
-
-out:
-
- return ret;
-}
-
-/* In case of a successful, delete or create operation, during post_validate *
- * look for missed snap operations and update the missed snap lists */
-int32_t
-glusterd_snapshot_update_snaps_post_validate (dict_t *dict, char **op_errstr,
- dict_t *rsp_dict)
-{
- int32_t ret = -1;
- int32_t missed_snap_count = -1;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (dict);
- GF_ASSERT (rsp_dict);
- GF_ASSERT (op_errstr);
-
- ret = dict_get_int32 (dict, "missed_snap_count",
- &missed_snap_count);
- if (ret) {
- gf_log (this->name, GF_LOG_DEBUG, "No missed snaps");
- ret = 0;
- goto out;
- }
-
- ret = glusterd_add_missed_snaps_to_list (dict, missed_snap_count);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to add missed snaps to list");
- goto out;
- }
-
- ret = glusterd_store_update_missed_snaps ();
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to update missed_snaps_list");
- goto out;
- }
-
-out:
- gf_log (this->name, GF_LOG_TRACE, "Returning %d", ret);
- return ret;
-}
-
-int
-glusterd_take_brick_snapshot_task (void *opaque)
-{
- int ret = 0;
- snap_create_args_t *snap_args = NULL;
- char key[PATH_MAX] = "";
-
- GF_ASSERT (opaque);
-
- snap_args = (snap_create_args_t*) opaque;
- THIS = snap_args->this;
-
- ret = glusterd_take_brick_snapshot (snap_args->dict,
- snap_args->snap_vol,
- snap_args->brickinfo,
- snap_args->volcount,
- snap_args->brickorder);
-
- if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR, "Failed to "
- "take backend snapshot for brick "
- "%s:%s volume(%s)", snap_args->brickinfo->hostname,
- snap_args->brickinfo->path, snap_args->snap_vol->volname);
- }
-
- snprintf (key, sizeof (key), "snap-vol%d.brick%d.status",
- snap_args->volcount, snap_args->brickorder);
- if (dict_set_int32 (snap_args->rsp_dict, key, (ret)?0:1)) {
- gf_log (THIS->name, GF_LOG_ERROR, "failed to "
- "add %s to dict", key);
- ret = -1;
- goto out;
- }
-
-out:
- return ret;
-}
-
-int32_t
-glusterd_take_brick_snapshot_cbk (int ret, call_frame_t *frame, void *opaque)
-{
- snap_create_args_t *snap_args = NULL;
- struct syncargs *args = NULL;
-
- GF_ASSERT (opaque);
-
- snap_args = (snap_create_args_t*) opaque;
- args = snap_args->args;
-
- if (ret)
- args->op_ret = ret;
-
- GF_FREE (opaque);
- synctask_barrier_wake(args);
- return 0;
-}
-
-int32_t
-glusterd_schedule_brick_snapshot (dict_t *dict, dict_t *rsp_dict,
- glusterd_snap_t *snap)
-{
- int ret = -1;
- int32_t volcount = 0;
- int32_t brickcount = 0;
- int32_t brickorder = 0;
- int32_t taskcount = 0;
- char key[PATH_MAX] = "";
- xlator_t *this = NULL;
- glusterd_volinfo_t *snap_vol = NULL;
- glusterd_brickinfo_t *brickinfo = NULL;
- struct syncargs args = {0};
- snap_create_args_t *snap_args = NULL;
-
- this = THIS;
- GF_ASSERT(this);
- GF_ASSERT(dict);
- GF_ASSERT(snap);
-
- synctask_barrier_init ((&args));
- list_for_each_entry (snap_vol, &snap->volumes, vol_list) {
- volcount++;
- brickcount = 0;
- brickorder = 0;
- list_for_each_entry (brickinfo, &snap_vol->bricks, brick_list) {
- snprintf (key, sizeof(key) - 1,
- "snap-vol%d.brick%d.order", volcount,
- brickcount);
- ret = dict_set_int32 (rsp_dict, key, brickorder);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to set %s", key);
- goto out;
- }
-
- if ((uuid_compare (brickinfo->uuid, MY_UUID)) ||
- (brickinfo->snap_status == -1)) {
- if (!uuid_compare (brickinfo->uuid, MY_UUID)) {
- brickcount++;
- snprintf (key, sizeof (key),
- "snap-vol%d.brick%d.status",
- volcount, brickorder);
- ret = dict_set_int32 (rsp_dict, key, 0);
- if (ret) {
- gf_log (this->name,
- GF_LOG_ERROR,
- "failed to add %s to "
- "dict", key);
- goto out;
- }
- }
- brickorder++;
- continue;
- }
-
- snap_args = GF_CALLOC (1, sizeof (*snap_args),
- gf_gld_mt_snap_create_args_t);
- if (!snap_args) {
- ret = -1;
- goto out;
- }
-
-
- snap_args->this = this;
- snap_args->dict = dict;
- snap_args->rsp_dict = rsp_dict;
- snap_args->snap_vol = snap_vol;
- snap_args->brickinfo = brickinfo;
- snap_args->volcount = volcount;
- snap_args->brickcount = brickcount;
- snap_args->brickorder = brickorder;
- snap_args->args = &args;
-
- ret = synctask_new (this->ctx->env,
- glusterd_take_brick_snapshot_task,
- glusterd_take_brick_snapshot_cbk,
- NULL, snap_args);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to "
- "spawn task for snapshot create");
- GF_FREE (snap_args);
- goto out;
- }
- taskcount++;
- brickcount++;
- brickorder++;
- }
-
- snprintf (key, sizeof (key), "snap-vol%d_brickcount", volcount);
- ret = dict_set_int64 (rsp_dict, key, brickcount);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "failed to "
- "add %s to dict", key);
- goto out;
- }
- }
- synctask_barrier_wait ((&args), taskcount);
- taskcount = 0;
-
- if (args.op_ret)
- gf_log (this->name, GF_LOG_ERROR, "Failed to create snapshot");
-
- ret = args.op_ret;
-out:
- if (ret && taskcount)
- synctask_barrier_wait ((&args), taskcount);
-
- return ret;
-}
-
-int32_t
-glusterd_snapshot_create_commit (dict_t *dict, char **op_errstr,
- dict_t *rsp_dict)
-{
- int ret = -1;
- int64_t i = 0;
- int64_t volcount = 0;
- int32_t snap_activate = 0;
- char *snapname = NULL;
- char *volname = NULL;
- char *tmp_name = NULL;
- char key[PATH_MAX] = "";
- xlator_t *this = NULL;
- glusterd_snap_t *snap = NULL;
- glusterd_volinfo_t *origin_vol = NULL;
- glusterd_volinfo_t *snap_vol = NULL;
- glusterd_brickinfo_t *brickinfo = NULL;
- glusterd_conf_t *priv = NULL;
-
- this = THIS;
- GF_ASSERT(this);
- GF_ASSERT(dict);
- GF_ASSERT(op_errstr);
- GF_ASSERT(rsp_dict);
- priv = this->private;
- GF_ASSERT(priv);
-
- ret = dict_get_int64 (dict, "volcount", &volcount);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "failed to "
- "get the volume count");
- goto out;
- }
-
- ret = dict_get_str (dict, "snapname", &snapname);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Unable to fetch snapname");
- goto out;
- }
- tmp_name = gf_strdup (snapname);
- if (!tmp_name) {
- gf_log (this->name, GF_LOG_ERROR, "Out of memory");
- ret = -1;
- goto out;
- }
-
- ret = dict_set_dynstr (rsp_dict, "snapname", tmp_name);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Unable to set snapname in rsp_dict");
- GF_FREE (tmp_name);
- goto out;
- }
- tmp_name = NULL;
-
- snap = glusterd_create_snap_object (dict, rsp_dict);
- if (!snap) {
- gf_log (this->name, GF_LOG_ERROR, "creating the"
- "snap object %s failed", snapname);
- ret = -1;
- goto out;
- }
-
- for (i = 1; i <= volcount; i++) {
- snprintf (key, sizeof (key), "volname%"PRId64, i);
- ret = dict_get_str (dict, key, &volname);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "failed to get volume name");
- goto out;
- }
-
- ret = glusterd_volinfo_find (volname, &origin_vol);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "failed to get the volinfo for "
- "the volume %s", volname);
- goto out;
- }
-
- if (is_origin_glusterd (dict)) {
- ret = glusterd_is_snap_soft_limit_reached (origin_vol,
- rsp_dict);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to "
- "check soft limit exceeded or not, "
- "for volume %s ", origin_vol->volname);
- goto out;
- }
- }
-
- snap_vol = glusterd_do_snap_vol (origin_vol, snap, dict,
- rsp_dict, i);
- if (!snap_vol) {
- ret = -1;
- gf_log (this->name, GF_LOG_WARNING, "taking the "
- "snapshot of the volume %s failed", volname);
- goto out;
- }
- }
- ret = dict_set_int64 (rsp_dict, "volcount", volcount);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to set volcount");
- goto out;
- }
-
- ret = glusterd_schedule_brick_snapshot (dict, rsp_dict, snap);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to take backend "
- "snapshot %s", snap->snapname);
- goto out;
- }
-
- ret = dict_set_dynstr_with_alloc (rsp_dict, "snapuuid",
- uuid_utoa (snap->snap_id));
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to set snap "
- "uuid in response dictionary for %s snapshot",
- snap->snapname);
- goto out;
- }
-
- snap_activate = dict_get_str_boolean (priv->opts,
- GLUSTERD_STORE_KEY_SNAP_ACTIVATE,
- _gf_false);
- if (!snap_activate) {
- list_for_each_entry (snap_vol, &snap->volumes, vol_list) {
- snap_vol->status = GLUSTERD_STATUS_STOPPED;
- ret = glusterd_store_volinfo (snap_vol,
- GLUSTERD_VOLINFO_VER_AC_INCREMENT);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to store snap volinfo %s",
- snap_vol->volname);
- goto out;
- }
- }
-
- goto out;
- }
-
- list_for_each_entry (snap_vol, &snap->volumes, vol_list) {
- list_for_each_entry (brickinfo, &snap_vol->bricks, brick_list) {
- ret = glusterd_brick_start (snap_vol, brickinfo,
- _gf_false);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING, "starting "
- "the brick %s:%s for the snap %s "
- "(volume: %s) failed",
- brickinfo->hostname, brickinfo->path,
- snap_vol->snapshot->snapname,
- snap_vol->volname);
- goto out;
- }
- }
-
- snap_vol->status = GLUSTERD_STATUS_STARTED;
- ret = glusterd_store_volinfo (snap_vol,
- GLUSTERD_VOLINFO_VER_AC_INCREMENT);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to store "
- "snap volinfo %s", snap_vol->volname);
- goto out;
- }
- }
-
- ret = 0;
-
-out:
- if (ret) {
- if (snap)
- glusterd_snap_remove (rsp_dict, snap,
- _gf_true, _gf_true);
- snap = NULL;
- }
-
- gf_log (this->name, GF_LOG_TRACE, "Returning %d", ret);
- return ret;
-}
-
-int
-snap_max_hard_limit_set_commit (dict_t *dict, uint64_t value,
- char *volname, char **op_errstr)
-{
- char err_str[PATH_MAX] = "";
- glusterd_conf_t *conf = NULL;
- glusterd_volinfo_t *volinfo = NULL;
- int ret = -1;
- xlator_t *this = NULL;
- char *next_version = NULL;
-
- this = THIS;
-
- GF_ASSERT (this);
- GF_ASSERT (dict);
- GF_ASSERT (op_errstr);
-
- conf = this->private;
-
- GF_ASSERT (conf);
-
- /* TODO: Initiate auto deletion when there is a limit change */
- if (!volname) {
- /* For system limit */
- ret = dict_set_uint64 (conf->opts,
- GLUSTERD_STORE_KEY_SNAP_MAX_HARD_LIMIT,
- value);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to store "
- "%s in the options",
- GLUSTERD_STORE_KEY_SNAP_MAX_HARD_LIMIT);
- goto out;
- }
-
-
- ret = glusterd_get_next_global_opt_version_str (conf->opts,
- &next_version);
- if (ret)
- goto out;
-
- ret = dict_set_str (conf->opts, GLUSTERD_GLOBAL_OPT_VERSION,
- next_version);
- if (ret)
- goto out;
-
- ret = glusterd_store_options (this, conf->opts);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to store "
- "options");
- goto out;
- }
- } else {
- /* For one volume */
- ret = glusterd_volinfo_find (volname, &volinfo);
- if (ret) {
- snprintf (err_str, PATH_MAX, "Failed to get the"
- " volinfo for volume %s", volname);
- goto out;
- }
-
- volinfo->snap_max_hard_limit = value;
-
- ret = glusterd_store_volinfo (volinfo,
- GLUSTERD_VOLINFO_VER_AC_INCREMENT);
- if (ret) {
- snprintf (err_str, PATH_MAX, "Failed to store "
- "snap-max-hard-limit for volume %s", volname);
- goto out;
- }
- }
-
- ret = 0;
-out:
- if (ret) {
- *op_errstr = gf_strdup (err_str);
- gf_log (this->name, GF_LOG_ERROR, "%s", err_str);
- }
- return ret;
-}
-
-int
-glusterd_snapshot_config_commit (dict_t *dict, char **op_errstr,
- dict_t *rsp_dict)
-{
- char *volname = NULL;
- xlator_t *this = NULL;
- int ret = -1;
- char err_str[PATH_MAX] = {0,};
- glusterd_conf_t *conf = NULL;
- int config_command = 0;
- uint64_t hard_limit = 0;
- uint64_t soft_limit = 0;
- char *next_version = NULL;
- char *auto_delete = NULL;
- char *snap_activate = NULL;
- gf_boolean_t system_conf = _gf_false;
-
- this = THIS;
-
- GF_ASSERT (this);
- GF_ASSERT (dict);
- GF_ASSERT (op_errstr);
-
- conf = this->private;
-
- GF_ASSERT (conf);
-
- ret = dict_get_int32 (dict, "config-command", &config_command);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "failed to get config-command type");
- goto out;
- }
- if (config_command != GF_SNAP_CONFIG_TYPE_SET) {
- ret = 0;
- goto out;
- }
-
- ret = dict_get_str (dict, "volname", &volname);
-
- /* config values snap-max-hard-limit and snap-max-soft-limit are
- * optional and hence we are not erroring out if values are not
- * present
- */
- gd_get_snap_conf_values_if_present (dict, &hard_limit,
- &soft_limit);
-
- if (hard_limit) {
- /* Commit ops for snap-max-hard-limit */
- ret = snap_max_hard_limit_set_commit (dict, hard_limit, volname,
- op_errstr);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "snap-max-hard-limit set commit failed.");
- goto out;
- }
- }
-
- if (soft_limit) {
- /* For system limit */
- system_conf = _gf_true;
- ret = dict_set_uint64 (conf->opts,
- GLUSTERD_STORE_KEY_SNAP_MAX_SOFT_LIMIT,
- soft_limit);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to save %s in the dictionary",
- GLUSTERD_STORE_KEY_SNAP_MAX_SOFT_LIMIT);
- goto out;
- }
- }
-
- if (hard_limit || soft_limit) {
- ret = 0;
- goto done;
- }
-
- if (!dict_get_str(dict,
- GLUSTERD_STORE_KEY_SNAP_AUTO_DELETE,
- &auto_delete)) {
- system_conf = _gf_true;
- ret = dict_set_dynstr_with_alloc (conf->opts,
- GLUSTERD_STORE_KEY_SNAP_AUTO_DELETE,
- auto_delete);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Could not "
- "save auto-delete value in conf->opts");
- goto out;
- }
- } else if (!dict_get_str(dict,
- GLUSTERD_STORE_KEY_SNAP_ACTIVATE,
- &snap_activate)) {
- system_conf = _gf_true;
- ret = dict_set_dynstr_with_alloc (conf->opts,
- GLUSTERD_STORE_KEY_SNAP_ACTIVATE,
- snap_activate);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Could not save "
- "snap-activate-on-create value in conf->opts");
- goto out;
- }
- } else {
- ret = -1;
- gf_log (this->name, GF_LOG_ERROR, "Invalid option");
- goto out;
- }
-
-done:
- if (system_conf) {
- ret = glusterd_get_next_global_opt_version_str (conf->opts,
- &next_version);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to get next global opt-version");
- goto out;
- }
-
- ret = dict_set_str (conf->opts, GLUSTERD_GLOBAL_OPT_VERSION,
- next_version);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to set next global opt-version");
- goto out;
- }
-
- ret = glusterd_store_options (this, conf->opts);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to store options");
- goto out;
- }
- }
-
-out:
- gf_log (this->name, GF_LOG_TRACE, "Returning %d", ret);
- return ret;
-}
-
-int
-glusterd_get_brick_lvm_details (dict_t *rsp_dict,
- glusterd_brickinfo_t *brickinfo, char *volname,
- char *device, char *key_prefix)
-{
-
- int ret = -1;
- glusterd_conf_t *priv = NULL;
- runner_t runner = {0,};
- xlator_t *this = NULL;
- char msg[PATH_MAX] = "";
- char buf[PATH_MAX] = "";
- char *ptr = NULL;
- char *token = NULL;
- char key[PATH_MAX] = "";
- char *value = NULL;
-
- GF_ASSERT (rsp_dict);
- GF_ASSERT (brickinfo);
- GF_ASSERT (volname);
- this = THIS;
- GF_ASSERT (this);
- priv = this->private;
- GF_ASSERT (priv);
-
- device = glusterd_get_brick_mount_device (brickinfo->path);
- if (!device) {
- gf_log (this->name, GF_LOG_ERROR, "Getting device name for "
- "the brick %s:%s failed", brickinfo->hostname,
- brickinfo->path);
- goto out;
- }
- runinit (&runner);
- snprintf (msg, sizeof (msg), "running lvs command, "
- "for getting snap status");
- /* Using lvs command fetch the Volume Group name,
- * Percentage of data filled and Logical Volume size
- *
- * "-o" argument is used to get the desired information,
- * example : "lvs /dev/VolGroup/thin_vol -o vgname,lv_size",
- * will get us Volume Group name and Logical Volume size.
- *
- * Here separator used is ":",
- * for the above given command with separator ":",
- * The output will be "vgname:lvsize"
- */
- runner_add_args (&runner, LVS, device, "--noheading", "-o",
- "vg_name,data_percent,lv_size",
- "--separator", ":", NULL);
- runner_redir (&runner, STDOUT_FILENO, RUN_PIPE);
- runner_log (&runner, "", GF_LOG_DEBUG, msg);
- ret = runner_start (&runner);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Could not perform lvs action");
- goto end;
- }
- do {
- ptr = fgets (buf, sizeof (buf),
- runner_chio (&runner, STDOUT_FILENO));
-
- if (ptr == NULL)
- break;
- token = strtok (buf, ":");
- if (token != NULL) {
- while (token && token[0] == ' ')
- token++;
- if (!token) {
- ret = -1;
- gf_log (this->name, GF_LOG_ERROR,
- "Invalid vg entry");
- goto end;
- }
- value = gf_strdup (token);
- if (!value) {
- ret = -1;
- goto end;
- }
- ret = snprintf (key, sizeof (key), "%s.vgname",
- key_prefix);
- if (ret < 0) {
- goto end;
- }
-
- ret = dict_set_dynstr (rsp_dict, key, value);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Could not save vgname ");
- goto end;
- }
- }
-
- token = strtok (NULL, ":");
- if (token != NULL) {
- value = gf_strdup (token);
- if (!value) {
- ret = -1;
- goto end;
- }
- ret = snprintf (key, sizeof (key), "%s.data",
- key_prefix);
- if (ret < 0) {
- goto end;
- }
-
- ret = dict_set_dynstr (rsp_dict, key, value);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Could not save data percent ");
- goto end;
- }
- }
- token = strtok (NULL, ":");
- if (token != NULL) {
- value = gf_strdup (token);
- if (!value) {
- ret = -1;
- goto end;
- }
- ret = snprintf (key, sizeof (key), "%s.lvsize",
- key_prefix);
- if (ret < 0) {
- goto end;
- }
-
- ret = dict_set_dynstr (rsp_dict, key, value);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Could not save meta data percent ");
- goto end;
- }
- }
-
- } while (ptr != NULL);
-
- ret = 0;
-
-end:
- runner_end (&runner);
-
-out:
- if (ret && value) {
- GF_FREE (value);
- }
-
- return ret;
-}
-
-int
-glusterd_get_single_brick_status (char **op_errstr, dict_t *rsp_dict,
- char *keyprefix, int index,
- glusterd_volinfo_t *snap_volinfo,
- glusterd_brickinfo_t *brickinfo)
-{
- int ret = -1;
- xlator_t *this = NULL;
- glusterd_conf_t *priv = NULL;
- char key[PATH_MAX] = "";
- char *device = NULL;
- char *value = NULL;
- char brick_path[PATH_MAX] = "";
- char pidfile[PATH_MAX] = "";
- pid_t pid = -1;
-
- this = THIS;
- GF_ASSERT (this);
- priv = this->private;
- GF_ASSERT (priv);
-
- GF_ASSERT (op_errstr);
- GF_ASSERT (rsp_dict);
- GF_ASSERT (keyprefix);
- GF_ASSERT (snap_volinfo);
- GF_ASSERT (brickinfo);
-
- ret = snprintf (key, sizeof (key), "%s.brick%d.path", keyprefix,
- index);
- if (ret < 0) {
- goto out;
- }
-
- ret = snprintf (brick_path, sizeof (brick_path),
- "%s:%s", brickinfo->hostname, brickinfo->path);
- if (ret < 0) {
- goto out;
- }
-
- value = gf_strdup (brick_path);
- if (!value) {
- ret = -1;
- goto out;
- }
-
- ret = dict_set_dynstr (rsp_dict, key, value);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Unable to store "
- "brick_path %s", brickinfo->path);
- goto out;
- }
-
- if (brickinfo->snap_status == -1) {
- /* Setting vgname as "Pending Snapshot" */
- value = gf_strdup ("Pending Snapshot");
- if (!value) {
- ret = -1;
- goto out;
- }
-
- snprintf (key, sizeof (key), "%s.brick%d.vgname",
- keyprefix, index);
- ret = dict_set_dynstr (rsp_dict, key, value);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Could not save vgname ");
- goto out;
- }
-
- ret = 0;
- goto out;
- }
- value = NULL;
-
- ret = snprintf (key, sizeof (key), "%s.brick%d.status",
- keyprefix, index);
- if (ret < 0) {
- goto out;
- }
-
- if (brickinfo->status == GF_BRICK_STOPPED) {
- value = gf_strdup ("No");
- if (!value) {
- ret = -1;
- goto out;
- }
- ret = dict_set_str (rsp_dict, key, value);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Could not save brick status");
- goto out;
- }
- value = NULL;
- } else {
- value = gf_strdup ("Yes");
- if (!value) {
- ret = -1;
- goto out;
- }
- ret = dict_set_str (rsp_dict, key, value);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Could not save brick status");
- goto out;
- }
- value = NULL;
-
- GLUSTERD_GET_BRICK_PIDFILE (pidfile, snap_volinfo,
- brickinfo, priv);
- ret = gf_is_service_running (pidfile, &pid);
-
- ret = snprintf (key, sizeof (key), "%s.brick%d.pid",
- keyprefix, index);
- if (ret < 0) {
- goto out;
- }
-
- ret = dict_set_int32 (rsp_dict, key, pid);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Could not save pid %d", pid);
- goto out;
- }
- }
-
- ret = snprintf (key, sizeof (key), "%s.brick%d",
- keyprefix, index);
- if (ret < 0) {
- goto out;
- }
-
- ret = glusterd_get_brick_lvm_details (rsp_dict, brickinfo,
- snap_volinfo->volname,
- device, key);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to get "
- "brick LVM details");
- goto out;
- }
-out:
- if (ret && value) {
- GF_FREE (value);
- }
-
- return ret;
-}
-
-int
-glusterd_get_single_snap_status (char **op_errstr, dict_t *rsp_dict,
- char *keyprefix, glusterd_snap_t *snap)
-{
- int ret = -1;
- xlator_t *this = NULL;
- char key[PATH_MAX] = "";
- char brickkey[PATH_MAX] = "";
- glusterd_volinfo_t *snap_volinfo = NULL;
- glusterd_volinfo_t *tmp_volinfo = NULL;
- glusterd_brickinfo_t *brickinfo = NULL;
- int volcount = 0;
- int brickcount = 0;
-
- this = THIS;
- GF_ASSERT (this);
-
- GF_ASSERT (op_errstr);
- GF_ASSERT (rsp_dict);
- GF_ASSERT (keyprefix);
- GF_ASSERT (snap);
-
- list_for_each_entry_safe (snap_volinfo, tmp_volinfo, &snap->volumes,
- vol_list) {
- ret = snprintf (key, sizeof (key), "%s.vol%d", keyprefix,
- volcount);
- if (ret < 0) {
- goto out;
- }
- list_for_each_entry (brickinfo, &snap_volinfo->bricks,
- brick_list) {
- if (!glusterd_is_local_brick (this, snap_volinfo,
- brickinfo)) {
- brickcount++;
- continue;
- }
-
- ret = glusterd_get_single_brick_status (op_errstr,
- rsp_dict, key, brickcount,
- snap_volinfo, brickinfo);
-
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Getting "
- "single snap status failed");
- goto out;
- }
- brickcount++;
- }
- ret = snprintf (brickkey, sizeof (brickkey), "%s.brickcount",
- key);
- if (ret < 0) {
- goto out;
- }
-
- ret = dict_set_int32 (rsp_dict, brickkey, brickcount);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Could not save brick count");
- goto out;
- }
- volcount++;
- }
-
- ret = snprintf (key, sizeof (key), "%s.volcount", keyprefix);
- if (ret < 0) {
- goto out;
- }
-
- ret = dict_set_int32 (rsp_dict, key, volcount);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Could not save volcount");
- goto out;
- }
-
-out:
-
- return ret;
-}
-
-int
-glusterd_get_each_snap_object_status (char **op_errstr, dict_t *rsp_dict,
- glusterd_snap_t *snap, char *keyprefix)
-{
- int ret = -1;
- char key[PATH_MAX] = "";
- char *temp = NULL;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (op_errstr);
- GF_ASSERT (rsp_dict);
- GF_ASSERT (snap);
- GF_ASSERT (keyprefix);
-
- /* TODO : Get all the snap volume info present in snap object,
- * as of now, There will be only one snapvolinfo per snap object
- */
- ret = snprintf (key, sizeof (key), "%s.snapname", keyprefix);
- if (ret < 0) {
- goto out;
- }
-
- temp = gf_strdup (snap->snapname);
- if (temp == NULL) {
- ret = -1;
- goto out;
- }
- ret = dict_set_dynstr (rsp_dict, key, temp);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Could not save "
- "snap name");
- goto out;
- }
-
- temp = NULL;
-
- ret = snprintf (key, sizeof (key), "%s.uuid", keyprefix);
- if (ret < 0) {
- goto out;
- }
-
- temp = gf_strdup (uuid_utoa (snap->snap_id));
- if (temp == NULL) {
- ret = -1;
- goto out;
- }
-
- ret = dict_set_dynstr (rsp_dict, key, temp);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Could not save "
- "snap UUID");
- goto out;
- }
-
- temp = NULL;
-
- ret = glusterd_get_single_snap_status (op_errstr, rsp_dict, keyprefix,
- snap);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Could not get single snap status");
- goto out;
- }
-
- ret = snprintf (key, sizeof (key), "%s.volcount", keyprefix);
- if (ret < 0) {
- goto out;
- }
-
- ret = dict_set_int32 (rsp_dict, key, 1);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Could not save volcount");
- goto out;
- }
-out:
- if (ret && temp)
- GF_FREE (temp);
-
- return ret;
-}
-
-int
-glusterd_get_snap_status_of_volume (char **op_errstr, dict_t *rsp_dict,
- char *volname, char *keyprefix) {
- int ret = -1;
- glusterd_volinfo_t *snap_volinfo = NULL;
- glusterd_volinfo_t *temp_volinfo = NULL;
- glusterd_volinfo_t *volinfo = NULL;
- char key[PATH_MAX] = "";
- xlator_t *this = NULL;
- glusterd_conf_t *priv = NULL;
- int i = 0;
-
- this = THIS;
- GF_ASSERT (this);
- priv = this->private;
- GF_ASSERT (priv);
-
- GF_ASSERT (op_errstr);
- GF_ASSERT (rsp_dict);
- GF_ASSERT (volname);
- GF_ASSERT (keyprefix);
-
- ret = glusterd_volinfo_find (volname, &volinfo);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to get volinfo of "
- "volume %s", volname);
- goto out;
- }
-
- list_for_each_entry_safe (snap_volinfo, temp_volinfo,
- &volinfo->snap_volumes, snapvol_list) {
- ret = snprintf (key, sizeof (key),
- "status.snap%d.snapname", i);
- if (ret < 0) {
- goto out;
- }
-
- ret = dict_set_dynstr_with_alloc (rsp_dict, key,
- snap_volinfo->snapshot->snapname);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Could not save "
- "snap name");
- goto out;
- }
-
- i++;
- }
-
- ret = dict_set_int32 (rsp_dict, "status.snapcount", i);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to save snapcount");
- ret = -1;
- goto out;
- }
-out:
- return ret;
-}
-
-int
-glusterd_get_all_snapshot_status (dict_t *dict, char **op_errstr,
- dict_t *rsp_dict)
-{
- int32_t i = 0;
- int ret = -1;
- char key[PATH_MAX] = "";
- glusterd_conf_t *priv = NULL;
- glusterd_snap_t *snap = NULL;
- glusterd_snap_t *tmp_snap = NULL;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- priv = this->private;
- GF_ASSERT (priv);
-
- GF_ASSERT (dict);
- GF_ASSERT (op_errstr);
-
- list_for_each_entry_safe (snap, tmp_snap,
- &priv->snapshots, snap_list) {
- ret = snprintf (key, sizeof (key),
- "status.snap%d.snapname", i);
- if (ret < 0) {
- goto out;
- }
-
- ret = dict_set_dynstr_with_alloc (rsp_dict, key,
- snap->snapname);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Could not save "
- "snap name");
- goto out;
- }
-
- i++;
- }
-
- ret = dict_set_int32 (rsp_dict, "status.snapcount", i);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Could not save snapcount");
- goto out;
- }
-
- ret = 0;
-out :
- return ret;
-}
-
-
-int
-glusterd_snapshot_status_commit (dict_t *dict, char **op_errstr,
- dict_t *rsp_dict)
-{
- xlator_t *this = NULL;
- int ret = -1;
- glusterd_conf_t *conf = NULL;
- char *get_buffer = NULL;
- int32_t cmd = -1;
- char *snapname = NULL;
- glusterd_snap_t *snap = NULL;
- char *volname = NULL;
-
- this = THIS;
-
- GF_ASSERT (this);
- GF_ASSERT (dict);
- GF_ASSERT (op_errstr);
-
- conf = this->private;
-
- GF_ASSERT (conf);
- ret = dict_get_int32 (dict, "status-cmd", &cmd);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to get status cmd type");
- goto out;
- }
-
- ret = dict_set_int32 (rsp_dict, "status-cmd", cmd);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Could not save status cmd in rsp dictionary");
- goto out;
- }
- switch (cmd) {
- case GF_SNAP_STATUS_TYPE_ALL:
- {
- ret = glusterd_get_all_snapshot_status (dict, op_errstr,
- rsp_dict);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Unable to "
- "get snapshot status");
- goto out;
- }
- break;
- }
- case GF_SNAP_STATUS_TYPE_SNAP:
- {
-
- ret = dict_get_str (dict, "snapname", &snapname);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Unable to "
- "get snap name");
- goto out;
- }
-
- snap = glusterd_find_snap_by_name (snapname);
- if (!snap) {
- ret = gf_asprintf (op_errstr, "Snapshot (%s) "
- "does not exist", snapname);
- if (ret < 0) {
- goto out;
- }
- ret = -1;
- gf_log (this->name, GF_LOG_ERROR, "Unable to "
- "get snap volinfo");
- goto out;
- }
- ret = glusterd_get_each_snap_object_status (op_errstr,
- rsp_dict, snap, "status.snap0");
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Unable to "
- "get status of snap %s", get_buffer);
- goto out;
- }
-
- ret = dict_set_int32 (rsp_dict, "status.snapcount", 1);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Unable to "
- "set snapcount to 1");
- goto out;
- }
- break;
- }
- case GF_SNAP_STATUS_TYPE_VOL:
- {
- 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_get_snap_status_of_volume (op_errstr,
- rsp_dict, volname, "status.vol0");
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Function :"
- " glusterd_get_snap_status_of_volume "
- "failed");
- goto out;
- }
- }
- }
- ret = 0;
-
-out:
- return ret;
-}
-
-int32_t
-glusterd_handle_snap_limit (dict_t *dict, dict_t *rsp_dict)
-{
- int32_t ret = -1;
- xlator_t *this = NULL;
- glusterd_conf_t *priv = NULL;
- uint64_t effective_max_limit = 0;
- int64_t volcount = 0;
- int64_t i = 0;
- char *volname = NULL;
- char key[PATH_MAX] = {0, };
- glusterd_volinfo_t *volinfo = NULL;
- uint64_t limit = 0;
- int64_t count = 0;
- glusterd_snap_t *snap = NULL;
- glusterd_volinfo_t *tmp_volinfo = NULL;
- glusterd_volinfo_t *other_volinfo = NULL;
- uint64_t opt_max_hard = GLUSTERD_SNAPS_MAX_HARD_LIMIT;
- uint64_t opt_max_soft = GLUSTERD_SNAPS_DEF_SOFT_LIMIT_PERCENT;
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (dict);
- GF_ASSERT (rsp_dict);
-
- priv = this->private;
- GF_ASSERT (priv);
-
- ret = dict_get_int64 (dict, "volcount", &volcount);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "failed to get the volcount");
- goto out;
- }
-
- for (i = 1; i <= volcount; i++) {
- snprintf (key, sizeof (key), "volname%ld", i);
- ret = dict_get_str (dict, key, &volname);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "failed to get the "
- "volname");
- goto out;
- }
-
- ret = glusterd_volinfo_find (volname, &volinfo);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "volinfo for %s "
- "not found", volname);
- goto out;
- }
-
- /* config values snap-max-hard-limit and snap-max-soft-limit are
- * optional and hence we are not erroring out if values are not
- * present
- */
- gd_get_snap_conf_values_if_present (priv->opts, &opt_max_hard,
- &opt_max_soft);
-
- /* The minimum of the 2 limits i.e system wide limit and
- volume wide limit will be considered
- */
- if (volinfo->snap_max_hard_limit < opt_max_hard)
- effective_max_limit = volinfo->snap_max_hard_limit;
- else
- effective_max_limit = opt_max_hard;
-
- limit = (opt_max_soft * effective_max_limit)/100;
-
- count = volinfo->snap_count - limit;
- if (count <= 0)
- goto out;
-
- tmp_volinfo = list_entry (volinfo->snap_volumes.next,
- glusterd_volinfo_t, snapvol_list);
- snap = tmp_volinfo->snapshot;
- GF_ASSERT (snap);
-
- LOCK (&snap->lock);
- {
- snap->snap_status = GD_SNAP_STATUS_DECOMMISSION;
- ret = glusterd_store_snap (snap);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "could "
- "not store snap object %s",
- snap->snapname);
- goto unlock;
- }
-
- ret = glusterd_snap_remove (rsp_dict, snap,
- _gf_true, _gf_true);
- if (ret)
- gf_log (this->name, GF_LOG_WARNING,
- "failed to remove snap %s",
- snap->snapname);
- }
- unlock: UNLOCK (&snap->lock);
- }
-
-out:
- return ret;
-}
-
-int32_t
-glusterd_snapshot_create_postvalidate (dict_t *dict, int32_t op_ret,
- char **op_errstr, dict_t *rsp_dict)
-{
- xlator_t *this = NULL;
- glusterd_conf_t *priv = NULL;
- int ret = -1;
- int32_t cleanup = 0;
- glusterd_snap_t *snap = NULL;
- char *snapname = NULL;
- char *auto_delete = NULL;
-
- this = THIS;
-
- GF_ASSERT (this);
- GF_ASSERT (dict);
- GF_ASSERT (rsp_dict);
-
- priv = this->private;
- GF_ASSERT (priv);
-
- if (op_ret) {
- ret = dict_get_int32 (dict, "cleanup", &cleanup);
- if (!ret && cleanup) {
- ret = glusterd_do_snap_cleanup (dict, op_errstr,
- rsp_dict);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING, "cleanup "
- "operation failed");
- goto out;
- }
- }
- /* Irrespective of status of cleanup its better
- * to return from this function. As the functions
- * following this block is not required to be
- * executed in case of failure scenario.
- */
- ret = 0;
- goto out;
- }
-
- ret = dict_get_str (dict, "snapname", &snapname);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Unable to fetch "
- "snapname");
- goto out;
- }
-
- snap = glusterd_find_snap_by_name (snapname);
- if (!snap) {
- gf_log (this->name, GF_LOG_ERROR, "unable to find snap "
- "%s", snapname);
- goto out;
- }
-
- snap->snap_status = GD_SNAP_STATUS_IN_USE;
- ret = glusterd_store_snap (snap);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING, "Could not store snap"
- "object %s", snap->snapname);
- goto out;
- }
-
- ret = glusterd_snapshot_update_snaps_post_validate (dict,
- op_errstr,
- rsp_dict);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to "
- "create snapshot");
- goto out;
- }
-
- /* "auto-delete" might not be set by user explicitly,
- * in that case it's better to consider the default value.
- * Hence not erroring out if Key is not found.
- */
- ret = dict_get_str_boolean (priv->opts,
- GLUSTERD_STORE_KEY_SNAP_AUTO_DELETE,
- _gf_false);
- if ( _gf_true == ret ) {
- //ignore the errors of autodelete
- ret = glusterd_handle_snap_limit (dict, rsp_dict);
- }
- ret = 0;
-out:
- return ret;
-}
-
-int32_t
-glusterd_snapshot (dict_t *dict, char **op_errstr, dict_t *rsp_dict)
-{
-
- xlator_t *this = NULL;
- glusterd_conf_t *priv = NULL;
- int32_t snap_command = 0;
- char *snap_name = NULL;
- char temp[PATH_MAX] = "";
- int ret = -1;
-
- this = THIS;
-
- GF_ASSERT (this);
- GF_ASSERT (dict);
- GF_ASSERT (rsp_dict);
-
- priv = this->private;
- GF_ASSERT (priv);
-
- ret = dict_get_int32 (dict, "type", &snap_command);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "unable to get the type of "
- "the snapshot command");
- goto out;
- }
-
- switch (snap_command) {
- case (GF_SNAP_OPTION_TYPE_CREATE):
- ret = glusterd_snapshot_create_commit (dict, op_errstr,
- rsp_dict);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to "
- "create snapshot");
- goto out;
- }
- break;
-
- case GF_SNAP_OPTION_TYPE_CONFIG:
- ret = glusterd_snapshot_config_commit (dict, op_errstr,
- rsp_dict);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "snapshot config failed");
- goto out;
- }
- break;
-
- case GF_SNAP_OPTION_TYPE_DELETE:
- ret = glusterd_snapshot_remove_commit (dict, op_errstr,
- rsp_dict);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to "
- "delete snapshot");
- if (*op_errstr) {
- /* If error string is already set
- * then goto out */
- goto out;
- }
-
- ret = dict_get_str (dict, "snapname", &snap_name);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to get snapname");
- snap_name = "NA";
- }
-
- snprintf (temp, sizeof (temp), "Snapshot %s might "
- "not be in an usable state.", snap_name);
-
- *op_errstr = gf_strdup (temp);
- ret = -1;
- goto out;
- }
- break;
-
- case GF_SNAP_OPTION_TYPE_RESTORE:
- ret = glusterd_snapshot_restore (dict, op_errstr,
- rsp_dict);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING, "Failed to "
- "restore snapshot");
- goto out;
- }
-
- break;
- case GF_SNAP_OPTION_TYPE_ACTIVATE:
- ret = glusterd_snapshot_activate_commit (dict, op_errstr,
- rsp_dict);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING, "Failed to "
- "activate snapshot");
- goto out;
- }
-
- break;
-
- case GF_SNAP_OPTION_TYPE_DEACTIVATE:
- ret = glusterd_snapshot_deactivate_commit (dict, op_errstr,
- rsp_dict);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING, "Failed to "
- "deactivate snapshot");
- goto out;
- }
-
- break;
-
- case GF_SNAP_OPTION_TYPE_STATUS:
- ret = glusterd_snapshot_status_commit (dict, op_errstr,
- rsp_dict);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to "
- "show snapshot status");
- goto out;
- }
- break;
-
-
- default:
- gf_log (this->name, GF_LOG_WARNING, "invalid snap command");
- goto out;
- break;
- }
-
- ret = 0;
-
-out:
- return ret;
-}
-
-int
-glusterd_snapshot_brickop (dict_t *dict, char **op_errstr, dict_t *rsp_dict)
-{
- int ret = -1;
- int64_t vol_count = 0;
- int64_t count = 1;
- char key[1024] = {0,};
- char *volname = NULL;
- int32_t snap_command = 0;
- xlator_t *this = NULL;
- char *op_type = NULL;
-
- this = THIS;
-
- GF_ASSERT (this);
- GF_ASSERT (dict);
- GF_ASSERT (rsp_dict);
-
- ret = dict_get_int32 (dict, "type", &snap_command);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "unable to get the type of "
- "the snapshot command");
- goto out;
- }
-
- switch (snap_command) {
- case GF_SNAP_OPTION_TYPE_CREATE:
-
- /* op_type with tell us whether its pre-commit operation
- * or post-commit
- */
- ret = dict_get_str (dict, "operation-type", &op_type);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to fetch "
- "operation type");
- goto out;
- }
-
- if (strcmp (op_type, "pre") == 0) {
- /* BRICK OP PHASE for enabling barrier, Enable barrier
- * if its a pre-commit operation
- */
- ret = glusterd_set_barrier_value (dict, "enable");
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to "
- "set barrier value as enable in dict");
- goto out;
- }
- } else if (strcmp (op_type, "post") == 0) {
- /* BRICK OP PHASE for disabling barrier, Disable barrier
- * if its a post-commit operation
- */
- ret = glusterd_set_barrier_value (dict, "disable");
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to "
- "set barrier value as disable in "
- "dict");
- goto out;
- }
- } else {
- ret = -1;
- gf_log (this->name, GF_LOG_ERROR, "Invalid op_type");
- goto out;
- }
-
- ret = dict_get_int64 (dict, "volcount", &vol_count);
- if (ret)
- goto out;
- while (count <= vol_count) {
- snprintf (key, 1024, "volname%"PRId64, count);
- ret = dict_get_str (dict, key, &volname);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Unable to get volname");
- goto out;
- }
- ret = dict_set_str (dict, "volname", volname);
- if (ret)
- goto out;
-
- ret = gd_brick_op_phase (GD_OP_SNAP, NULL, dict,
- op_errstr);
- if (ret)
- goto out;
- volname = NULL;
- count++;
- }
-
- dict_del (dict, "volname");
- ret = 0;
- break;
- case GF_SNAP_OPTION_TYPE_DELETE:
- break;
- default:
- break;
- }
-
-out:
- return ret;
-}
-
-int
-glusterd_snapshot_prevalidate (dict_t *dict, char **op_errstr,
- dict_t *rsp_dict)
-{
- int snap_command = 0;
- xlator_t *this = NULL;
- int ret = -1;
-
- this = THIS;
-
- GF_ASSERT (this);
- GF_ASSERT (dict);
- GF_ASSERT (rsp_dict);
-
- ret = dict_get_int32 (dict, "type", &snap_command);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "unable to get the type of "
- "the snapshot command");
- goto out;
- }
-
- switch (snap_command) {
- case (GF_SNAP_OPTION_TYPE_CREATE):
- ret = glusterd_snapshot_create_prevalidate (dict, op_errstr,
- rsp_dict);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING, "Snapshot create "
- "pre-validation failed");
- goto out;
- }
- break;
-
- case (GF_SNAP_OPTION_TYPE_CONFIG):
- ret = glusterd_snapshot_config_prevalidate (dict, op_errstr);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING, "Snapshot config "
- "pre-validation failed");
- goto out;
- }
- break;
-
- case GF_SNAP_OPTION_TYPE_RESTORE:
- ret = glusterd_snapshot_restore_prevalidate (dict, op_errstr,
- rsp_dict);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING, "Snapshot restore "
- "validation failed");
- goto out;
- }
- break;
-
- case GF_SNAP_OPTION_TYPE_ACTIVATE:
- ret = glusterd_snapshot_activate_deactivate_prevalidate (dict,
- op_errstr, rsp_dict, _gf_true);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING, "Snapshot activate "
- "validation failed");
- goto out;
- }
- break;
- case GF_SNAP_OPTION_TYPE_DEACTIVATE:
- ret = glusterd_snapshot_activate_deactivate_prevalidate (dict,
- op_errstr, rsp_dict, _gf_false);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING,
- "Snapshot deactivate validation failed");
- goto out;
- }
- break;
- case GF_SNAP_OPTION_TYPE_DELETE:
- ret = glusterd_snapshot_remove_prevalidate (dict, op_errstr,
- rsp_dict);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING, "Snapshot remove "
- "validation failed");
- goto out;
- }
- break;
-
- case GF_SNAP_OPTION_TYPE_STATUS:
- ret = glusterd_snapshot_status_prevalidate (dict, op_errstr,
- rsp_dict);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING, "Snapshot status "
- "validation failed");
- goto out;
- }
- break;
-
- default:
- gf_log (this->name, GF_LOG_WARNING, "invalid snap command");
- goto out;
- }
-
- ret = 0;
-out:
- return ret;
-}
-
-/* This function is called if snapshot restore operation
- * is successful. It will cleanup the backup files created
- * during the restore operation.
- *
- * @param rsp_dict Response dictionary
- * @param volinfo volinfo of the volume which is being restored
- * @param snap snap object
- *
- * @return 0 on success or -1 on failure
- */
-int
-glusterd_snapshot_restore_cleanup (dict_t *rsp_dict,
- glusterd_volinfo_t *volinfo,
- glusterd_snap_t *snap)
-{
- int ret = -1;
- char delete_path[PATH_MAX] = {0,};
- xlator_t *this = NULL;
- glusterd_conf_t *priv = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- priv = this->private;
-
- GF_ASSERT (rsp_dict);
- GF_ASSERT (volinfo);
- GF_ASSERT (snap);
-
- /* If the volinfo is already restored then we should delete
- * the backend LVMs */
- if (!uuid_is_null (volinfo->restored_from_snap)) {
- ret = glusterd_lvm_snapshot_remove (rsp_dict, volinfo);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to remove "
- "LVM backend");
- goto out;
- }
- }
-
- snprintf (delete_path, sizeof (delete_path),
- "%s/"GLUSTERD_TRASH"/vols-%s.deleted", priv->workdir,
- volinfo->volname);
-
- /* Restore is successful therefore delete the original volume's
- * volinfo.
- */
- ret = glusterd_volinfo_delete (volinfo);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to delete volinfo");
- goto out;
- }
-
- /* Now delete the snap entry. */
- ret = glusterd_snap_remove (rsp_dict, snap, _gf_false, _gf_true);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING, "Failed to delete "
- "snap %s", snap->snapname);
- goto out;
- }
-
- /* Delete the backup copy of volume folder */
- ret = glusterd_recursive_rmdir (delete_path);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to remove "
- "backup dir (%s)", delete_path);
- goto out;
- }
-
- ret = 0;
-out:
- return ret;
-}
-
-/* This function is called when the snapshot restore operation failed
- * for some reasons. In such case we revert the restore operation.
- *
- * @param volinfo volinfo of the origin volume
- * @param restore_from_store Boolean variable which tells whether to
- * restore the origin from store or not.
- *
- * @return 0 on success and -1 on failure
- */
-int
-glusterd_snapshot_revert_partial_restored_vol (glusterd_volinfo_t *volinfo,
- gf_boolean_t restore_from_store)
-{
- int ret = 0;
- char pathname [PATH_MAX] = {0,};
- char trash_path[PATH_MAX] = {0,};
- glusterd_volinfo_t *reverted_vol = NULL;
- glusterd_conf_t *priv = NULL;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- priv = this->private;
- GF_ASSERT (priv);
- GF_ASSERT (volinfo);
-
- GLUSTERD_GET_VOLUME_DIR (pathname, volinfo, priv);
-
- snprintf (trash_path, sizeof (trash_path),
- "%s/"GLUSTERD_TRASH"/vols-%s.deleted", priv->workdir,
- volinfo->volname);
-
- /* Since snapshot restore failed we cannot rely on the volume
- * data stored under vols folder. Therefore delete the origin
- * volume's backend folder.*/
- ret = glusterd_recursive_rmdir (pathname);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to remove "
- "%s directory", pathname);
- goto out;
- }
-
- /* Now move the backup copy of the vols to its original
- * location.*/
- ret = rename (trash_path, pathname);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to rename folder "
- "from %s to %s", trash_path, pathname);
- goto out;
- }
-
- /* Skip the volinfo retrieval from the store if restore_from_store
- * is not true. */
- if (!restore_from_store) {
- ret = 0;
- goto out;
- }
-
- /* Retrieve the volume from the store */
- reverted_vol = glusterd_store_retrieve_volume (volinfo->volname, NULL);
- if (NULL == reverted_vol) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to load restored "
- "%s volume", volinfo->volname);
- goto out;
- }
-
- /* Since we retrieved the volinfo from store now we don't
- * want the older volinfo. Therefore delete the older volinfo */
- ret = glusterd_volinfo_delete (volinfo);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to delete volinfo");
- goto out;
- }
-
- ret = 0;
-out:
- return ret;
-}
-
-/* This function is called when glusterd is started and we need
- * to revert a failed snapshot restore.
- *
- * @param snap snapshot object of the restored snap
- *
- * @return 0 on success and -1 on failure
- */
-int
-glusterd_snapshot_revert_restore_from_snap (glusterd_snap_t *snap)
-{
- int ret = -1;
- char volname [PATH_MAX] = {0,};
- glusterd_volinfo_t *snap_volinfo = NULL;
- glusterd_volinfo_t *volinfo = NULL;
- xlator_t *this = NULL;
-
- this = THIS;
-
- GF_ASSERT (this);
- GF_ASSERT (snap);
-
- /* TODO : As of now there is only one volume in snapshot.
- * Change this when multiple volume snapshot is introduced
- */
- snap_volinfo = list_entry (snap->volumes.next, glusterd_volinfo_t,
- vol_list);
-
- strcpy (volname, snap_volinfo->parent_volname);
-
- ret = glusterd_volinfo_find (volname, &volinfo);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Could not get volinfo of "
- "%s", snap_volinfo->parent_volname);
- goto out;
- }
-
- ret = glusterd_snapshot_revert_partial_restored_vol (volinfo, _gf_true);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to revert snapshot "
- "restore operation for %s volume", volname);
- goto out;
- }
-out:
- return ret;
-}
-
-/* This function is called from post-validation. Based on the op_ret
- * it will take a decision on whether to revert the operation or
- * perform cleanup.
- *
- * @param dict dictionary object
- * @param op_ret return value of the restore operation
- * @param op_errstr error string
- * @param rsp_dict Response dictionary
- *
- * @return 0 on success and -1 on failure
- */
-int
-glusterd_snapshot_restore_postop (dict_t *dict, int32_t op_ret,
- char **op_errstr, dict_t *rsp_dict)
-{
- int ret = -1;
- char *name = NULL;
- char *volname = NULL;
- int cleanup = 0;
- glusterd_snap_t *snap = NULL;
- glusterd_volinfo_t *volinfo = NULL;
- xlator_t *this = NULL;
-
- this = THIS;
-
- GF_ASSERT (this);
- GF_ASSERT (dict);
- GF_ASSERT (rsp_dict);
-
- ret = dict_get_str (dict, "snapname", &name);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "getting the snap "
- "name failed (volume: %s)", volinfo->volname);
- goto out;
- }
-
- snap = glusterd_find_snap_by_name (name);
- if (!snap) {
- gf_log (this->name, GF_LOG_ERROR,
- "Snapshot (%s) does not exist", name);
- ret = -1;
- goto out;
- }
-
- /* TODO: fix this when multiple volume support will come */
- ret = dict_get_str (dict, "volname1", &volname);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "failed to get volume name");
- goto out;
- }
-
- ret = glusterd_volinfo_find (volname, &volinfo);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Volume (%s) does not exist ", volname);
- goto out;
- }
-
- ret = dict_get_str (dict, "snapname", &name);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "getting the snap "
- "name failed (volume: %s)", volinfo->volname);
- goto out;
- }
-
- snap = glusterd_find_snap_by_name (name);
- if (!snap) {
- gf_log (this->name, GF_LOG_ERROR, "snap %s is not found", name);
- ret = -1;
- goto out;
- }
-
- /* On success perform the cleanup operation */
- if (0 == op_ret) {
- ret = glusterd_snapshot_restore_cleanup (rsp_dict, volinfo,
- snap);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to perform "
- "snapshot restore cleanup for %s volume",
- volname);
- goto out;
- }
- } else { /* On failure revert snapshot restore */
- ret = dict_get_int32 (dict, "cleanup", &cleanup);
- /* Perform cleanup only when required */
- if (ret || (0 == cleanup)) {
- ret = 0;
- goto out;
- }
-
- ret = glusterd_snapshot_revert_partial_restored_vol (volinfo,
- _gf_false);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to revert "
- "restore operation for %s volume", volname);
- goto out;
- }
- }
-
- ret = 0;
-out:
- return ret;
-}
-
-int
-glusterd_snapshot_postvalidate (dict_t *dict, int32_t op_ret, char **op_errstr,
- dict_t *rsp_dict)
-{
- int snap_command = 0;
- xlator_t *this = NULL;
- int ret = -1;
-
- this = THIS;
-
- GF_ASSERT (this);
- GF_ASSERT (dict);
- GF_ASSERT (rsp_dict);
-
- ret = dict_get_int32 (dict, "type", &snap_command);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "unable to get the type of "
- "the snapshot command");
- goto out;
- }
-
- switch (snap_command) {
- case GF_SNAP_OPTION_TYPE_CREATE:
- ret = glusterd_snapshot_create_postvalidate (dict, op_ret,
- op_errstr,
- rsp_dict);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING, "Snapshot create "
- "post-validation failed");
- goto out;
- }
- glusterd_fetchsnap_notify (this);
- break;
- case GF_SNAP_OPTION_TYPE_DELETE:
- if (op_ret) {
- gf_log (this->name, GF_LOG_DEBUG,
- "op_ret = %d. Not performing delete "
- "post_validate", op_ret);
- ret = 0;
- goto out;
- }
- ret = glusterd_snapshot_update_snaps_post_validate (dict,
- op_errstr,
- rsp_dict);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to "
- "update missed snaps list");
- goto out;
- }
- glusterd_fetchsnap_notify (this);
- break;
- case GF_SNAP_OPTION_TYPE_RESTORE:
- ret = glusterd_snapshot_update_snaps_post_validate (dict,
- op_errstr,
- rsp_dict);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to "
- "update missed snaps list");
- goto out;
- }
-
- ret = glusterd_snapshot_restore_postop (dict, op_ret,
- op_errstr, rsp_dict);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to "
- "perform snapshot restore post-op");
- goto out;
- }
- glusterd_fetchsnap_notify (this);
- break;
- case GF_SNAP_OPTION_TYPE_ACTIVATE:
- case GF_SNAP_OPTION_TYPE_DEACTIVATE:
- glusterd_fetchsnap_notify (this);
- break;
- case GF_SNAP_OPTION_TYPE_STATUS:
- case GF_SNAP_OPTION_TYPE_CONFIG:
- case GF_SNAP_OPTION_TYPE_INFO:
- case GF_SNAP_OPTION_TYPE_LIST:
- /*Nothing to be done. But want to
- * avoid the default case warning*/
- ret = 0;
- break;
- default:
- gf_log (this->name, GF_LOG_WARNING, "invalid snap command");
- goto out;
- }
-
- ret = 0;
-out:
- return ret;
-}
-
-/*
- Verify availability of lvm commands
-*/
-
-static gf_boolean_t
-glusterd_is_lvm_cmd_available (char *lvm_cmd)
-{
- int32_t ret = 0;
- struct stat buf = {0,};
-
- if (!lvm_cmd)
- return _gf_false;
-
- ret = stat (lvm_cmd, &buf);
- if (ret != 0) {
- gf_log (THIS->name, GF_LOG_ERROR,
- "stat fails on %s, exiting. (errno = %d (%s))",
- lvm_cmd, errno, strerror(errno));
- return _gf_false;
- }
-
- if ((!ret) && (!S_ISREG(buf.st_mode))) {
- gf_log (THIS->name, GF_LOG_CRITICAL,
- "Provided command %s is not a regular file,"
- "exiting", lvm_cmd);
- return _gf_false;
- }
-
- if ((!ret) && (!(buf.st_mode & S_IXUSR))) {
- gf_log (THIS->name, GF_LOG_CRITICAL,
- "Provided command %s has no exec permissions,"
- "exiting", lvm_cmd);
- return _gf_false;
- }
-
- return _gf_true;
-}
-
-int
-glusterd_handle_snapshot_fn (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_SNAP;
- int type = 0;
- glusterd_conf_t *conf = NULL;
- char *host_uuid = NULL;
- char err_str[2048] = {0,};
- xlator_t *this = NULL;
-
- GF_ASSERT (req);
-
- this = THIS;
- GF_ASSERT (this);
- conf = this->private;
- GF_ASSERT (conf);
-
- ret = xdr_to_generic (req->msg[0], &cli_req,
- (xdrproc_t)xdr_gf_cli_req);
- if (ret < 0) {
- 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 req-buffer to dictionary");
- snprintf (err_str, sizeof (err_str), "Unable to decode "
- "the command");
- goto out;
- }
-
- dict->extra_stdfree = cli_req.dict.dict_val;
-
- host_uuid = gf_strdup (uuid_utoa(MY_UUID));
- if (host_uuid == NULL) {
- snprintf (err_str, sizeof (err_str), "Failed to get "
- "the uuid of local glusterd");
- ret = -1;
- goto out;
- }
- ret = dict_set_dynstr (dict, "host-uuid", host_uuid);
- if (ret) {
- GF_FREE (host_uuid);
- goto out;
- }
-
-
- } else {
- gf_log (this->name, GF_LOG_ERROR, "request dict length is %d",
- cli_req.dict.dict_len);
- goto out;
- }
-
- if (conf->op_version < GD_OP_VERSION_3_6_0) {
- snprintf (err_str, sizeof (err_str), "Cluster operating version"
- " is lesser than the supported version "
- "for a snapshot");
- gf_log (this->name, GF_LOG_ERROR, "%s (%d < %d)", err_str,
- conf->op_version, GD_OP_VERSION_3_6_0);
- ret = -1;
- goto out;
- }
-
- ret = dict_get_int32 (dict, "type", &type);
- if (ret < 0) {
- snprintf (err_str, sizeof (err_str), "Command type not found");
- gf_log (this->name, GF_LOG_ERROR, "%s", err_str);
- goto out;
- }
-
- if (!glusterd_is_lvm_cmd_available (LVM_CREATE)) {
- snprintf (err_str, sizeof (err_str), "LVM commands not found,"
- " snapshot functionality is disabled");
- gf_log (this->name, GF_LOG_ERROR, "%s", err_str);
- ret = -1;
- goto out;
- }
-
- switch (type) {
- case GF_SNAP_OPTION_TYPE_CREATE:
- ret = glusterd_handle_snapshot_create (req, cli_op, dict,
- err_str, sizeof (err_str));
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING, "Snapshot create "
- "failed: %s", err_str);
- }
- break;
- case GF_SNAP_OPTION_TYPE_RESTORE:
- ret = glusterd_handle_snapshot_restore (req, cli_op, dict,
- err_str, sizeof (err_str));
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING, "Snapshot restore "
- "failed: %s", err_str);
- }
-
- break;
- case GF_SNAP_OPTION_TYPE_INFO:
- ret = glusterd_handle_snapshot_info (req, cli_op, dict,
- err_str, sizeof (err_str));
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING, "Snapshot info "
- "failed");
- }
- break;
- case GF_SNAP_OPTION_TYPE_LIST:
- ret = glusterd_handle_snapshot_list (req, cli_op, dict,
- err_str, sizeof (err_str));
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING, "Snapshot list "
- "failed");
- }
- break;
- case GF_SNAP_OPTION_TYPE_CONFIG:
- ret = glusterd_handle_snapshot_config (req, cli_op, dict,
- err_str, sizeof (err_str));
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING, "snapshot config "
- "failed");
- }
- break;
- case GF_SNAP_OPTION_TYPE_DELETE:
- ret = glusterd_handle_snapshot_delete (req, cli_op, dict,
- err_str,
- sizeof (err_str));
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING, "Snapshot delete "
- "failed: %s", err_str);
- }
- break;
- case GF_SNAP_OPTION_TYPE_ACTIVATE:
- ret = glusterd_mgmt_v3_initiate_snap_phases (req, cli_op,
- dict);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING,
- "Snapshot activate failed: %s", err_str);
- }
- break;
- case GF_SNAP_OPTION_TYPE_DEACTIVATE:
- ret = glusterd_mgmt_v3_initiate_snap_phases (req, cli_op,
- dict);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING,
- "Snapshot deactivate failed: %s", err_str);
- }
- break;
- case GF_SNAP_OPTION_TYPE_STATUS:
- ret = glusterd_handle_snapshot_status (req, cli_op, dict,
- err_str,
- sizeof (err_str));
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING, "Snapshot status "
- "failed: %s", err_str);
- }
- break;
- default:
- gf_log (this->name, GF_LOG_ERROR, "Unkown snapshot request "
- "type (%d)", type);
- ret = -1; /* Failure */
- }
-
-out:
- if (ret) {
- if (err_str[0] == '\0')
- snprintf (err_str, sizeof (err_str),
- "Operation failed");
- ret = glusterd_op_send_cli_response (cli_op, ret, 0, req,
- dict, err_str);
- }
-
- return ret;
-}
-
-int
-glusterd_handle_snapshot (rpcsvc_request_t *req)
-{
- return glusterd_big_locked_handler (req, glusterd_handle_snapshot_fn);
-}
-
-static inline void
-glusterd_free_snap_op (glusterd_snap_op_t *snap_op)
-{
- if (snap_op) {
- if (snap_op->brick_path)
- GF_FREE (snap_op->brick_path);
-
- GF_FREE (snap_op);
- }
-}
-
-static inline void
-glusterd_free_missed_snapinfo (glusterd_missed_snap_info *missed_snapinfo)
-{
- glusterd_snap_op_t *snap_opinfo = NULL;
- glusterd_snap_op_t *tmp = NULL;
-
- if (missed_snapinfo) {
- list_for_each_entry_safe (snap_opinfo, tmp,
- &missed_snapinfo->snap_ops,
- snap_ops_list) {
- glusterd_free_snap_op (snap_opinfo);
- snap_opinfo = NULL;
- }
-
- if (missed_snapinfo->node_uuid)
- GF_FREE (missed_snapinfo->node_uuid);
-
- if (missed_snapinfo->snap_uuid)
- GF_FREE (missed_snapinfo->snap_uuid);
-
- GF_FREE (missed_snapinfo);
- }
-}
-
-/* Look for duplicates and accordingly update the list */
-int32_t
-glusterd_update_missed_snap_entry (glusterd_missed_snap_info *missed_snapinfo,
- glusterd_snap_op_t *missed_snap_op)
-{
- int32_t ret = -1;
- glusterd_snap_op_t *snap_opinfo = NULL;
- gf_boolean_t match = _gf_false;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT(this);
- GF_ASSERT(missed_snapinfo);
- GF_ASSERT(missed_snap_op);
-
- list_for_each_entry (snap_opinfo, &missed_snapinfo->snap_ops,
- snap_ops_list) {
- /* If the entry is not for the same snap_vol_id
- * then continue
- */
- if (strcmp (snap_opinfo->snap_vol_id,
- missed_snap_op->snap_vol_id))
- continue;
-
- if ((!strcmp (snap_opinfo->brick_path,
- missed_snap_op->brick_path)) &&
- (snap_opinfo->op == missed_snap_op->op)) {
- /* If two entries have conflicting status
- * GD_MISSED_SNAP_DONE takes precedence
- */
- if ((snap_opinfo->status == GD_MISSED_SNAP_PENDING) &&
- (missed_snap_op->status == GD_MISSED_SNAP_DONE)) {
- snap_opinfo->status = GD_MISSED_SNAP_DONE;
- gf_log (this->name, GF_LOG_INFO,
- "Updating missed snap status "
- "for %s:%s=%s:%d:%s:%d as DONE",
- missed_snapinfo->node_uuid,
- missed_snapinfo->snap_uuid,
- snap_opinfo->snap_vol_id,
- snap_opinfo->brick_num,
- snap_opinfo->brick_path,
- snap_opinfo->op);
- ret = 0;
- glusterd_free_snap_op (missed_snap_op);
- goto out;
- }
- match = _gf_true;
- break;
- } else if ((snap_opinfo->brick_num ==
- missed_snap_op->brick_num) &&
- (snap_opinfo->op == GF_SNAP_OPTION_TYPE_CREATE) &&
- ((missed_snap_op->op ==
- GF_SNAP_OPTION_TYPE_DELETE) ||
- (missed_snap_op->op ==
- GF_SNAP_OPTION_TYPE_RESTORE))) {
- /* Optimizing create and delete entries for the same
- * brick and same node
- */
- gf_log (this->name, GF_LOG_INFO,
- "Updating missed snap status "
- "for %s:%s=%s:%d:%s:%d as DONE",
- missed_snapinfo->node_uuid,
- missed_snapinfo->snap_uuid,
- snap_opinfo->snap_vol_id,
- snap_opinfo->brick_num,
- snap_opinfo->brick_path,
- snap_opinfo->op);
- snap_opinfo->status = GD_MISSED_SNAP_DONE;
- ret = 0;
- glusterd_free_snap_op (missed_snap_op);
- goto out;
- }
- }
-
- if (match == _gf_true) {
- gf_log (this->name, GF_LOG_INFO,
- "Duplicate entry. Not updating");
- glusterd_free_snap_op (missed_snap_op);
- } else {
- list_add_tail (&missed_snap_op->snap_ops_list,
- &missed_snapinfo->snap_ops);
- }
-
- ret = 0;
-out:
- gf_log (this->name, GF_LOG_TRACE, "Returning %d", ret);
- return ret;
-}
-
-/* Add new missed snap entry to the missed_snaps list. */
-int32_t
-glusterd_add_new_entry_to_list (char *missed_info, char *snap_vol_id,
- int32_t brick_num, char *brick_path,
- int32_t snap_op, int32_t snap_status)
-{
- char *buf = NULL;
- char *save_ptr = NULL;
- char node_snap_info[PATH_MAX] = "";
- int32_t ret = -1;
- glusterd_missed_snap_info *missed_snapinfo = NULL;
- glusterd_snap_op_t *missed_snap_op = NULL;
- glusterd_conf_t *priv = NULL;
- gf_boolean_t match = _gf_false;
- gf_boolean_t free_missed_snap_info = _gf_false;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT(this);
- GF_ASSERT(missed_info);
- GF_ASSERT(snap_vol_id);
- GF_ASSERT(brick_path);
-
- priv = this->private;
- GF_ASSERT (priv);
-
- /* Create the snap_op object consisting of the *
- * snap id and the op */
- ret = glusterd_missed_snap_op_new (&missed_snap_op);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to create new missed snap object.");
- ret = -1;
- goto out;
- }
-
- missed_snap_op->snap_vol_id = gf_strdup(snap_vol_id);
- if (!missed_snap_op->snap_vol_id) {
- ret = -1;
- goto out;
- }
- missed_snap_op->brick_path = gf_strdup(brick_path);
- if (!missed_snap_op->brick_path) {
- ret = -1;
- goto out;
- }
- missed_snap_op->brick_num = brick_num;
- missed_snap_op->op = snap_op;
- missed_snap_op->status = snap_status;
-
- /* Look for other entries for the same node and same snap */
- list_for_each_entry (missed_snapinfo, &priv->missed_snaps_list,
- missed_snaps) {
- snprintf (node_snap_info, sizeof(node_snap_info),
- "%s:%s", missed_snapinfo->node_uuid,
- missed_snapinfo->snap_uuid);
- if (!strcmp (node_snap_info, missed_info)) {
- /* Found missed snapshot info for *
- * the same node and same snap */
- match = _gf_true;
- break;
- }
- }
-
- if (match == _gf_false) {
- /* First snap op missed for the brick */
- ret = glusterd_missed_snapinfo_new (&missed_snapinfo);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to create missed snapinfo");
- goto out;
- }
- free_missed_snap_info = _gf_true;
- buf = strtok_r (missed_info, ":", &save_ptr);
- if (!buf) {
- ret = -1;
- goto out;
- }
- missed_snapinfo->node_uuid = gf_strdup(buf);
- if (!missed_snapinfo->node_uuid) {
- ret = -1;
- goto out;
- }
-
- buf = strtok_r (NULL, ":", &save_ptr);
- if (!buf) {
- ret = -1;
- goto out;
- }
- missed_snapinfo->snap_uuid = gf_strdup(buf);
- if (!missed_snapinfo->snap_uuid) {
- ret = -1;
- goto out;
- }
-
- list_add_tail (&missed_snap_op->snap_ops_list,
- &missed_snapinfo->snap_ops);
- list_add_tail (&missed_snapinfo->missed_snaps,
- &priv->missed_snaps_list);
-
- ret = 0;
- goto out;
- } else {
- ret = glusterd_update_missed_snap_entry (missed_snapinfo,
- missed_snap_op);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to update existing missed snap entry.");
- goto out;
- }
- }
-
-out:
- if (ret) {
- glusterd_free_snap_op (missed_snap_op);
-
- if (missed_snapinfo &&
- (free_missed_snap_info == _gf_true))
- glusterd_free_missed_snapinfo (missed_snapinfo);
- }
-
- gf_log (this->name, GF_LOG_TRACE, "Returning %d", ret);
- return ret;
-}
-
-/* Add missing snap entries to the in-memory conf->missed_snap_list */
-int32_t
-glusterd_add_missed_snaps_to_list (dict_t *dict, int32_t missed_snap_count)
-{
- char *buf = NULL;
- char *tmp = NULL;
- char *save_ptr = NULL;
- char *nodeid = NULL;
- char *snap_uuid = NULL;
- char *snap_vol_id = NULL;
- char *brick_path = NULL;
- char missed_info[PATH_MAX] = "";
- char name_buf[PATH_MAX] = "";
- int32_t i = -1;
- int32_t ret = -1;
- int32_t brick_num = -1;
- int32_t snap_op = -1;
- int32_t snap_status = -1;
- glusterd_conf_t *priv = NULL;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT(this);
- GF_ASSERT(dict);
-
- priv = this->private;
- GF_ASSERT (priv);
-
- /* We can update the missed_snaps_list without acquiring *
- * any additional locks as big lock will be held. */
- for (i = 0; i < missed_snap_count; i++) {
- snprintf (name_buf, sizeof(name_buf), "missed_snaps_%d",
- i);
- ret = dict_get_str (dict, name_buf, &buf);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Unable to fetch %s", name_buf);
- goto out;
- }
-
- gf_log (this->name, GF_LOG_DEBUG, "missed_snap_entry = %s",
- buf);
-
- /* Need to make a duplicate string coz the same dictionary *
- * is resent to the non-originator nodes */
- tmp = gf_strdup (buf);
- if (!tmp) {
- ret = -1;
- goto out;
- }
-
- /* Fetch the node-id, snap-id, brick_num,
- * brick_path, snap_op and snap status
- */
- nodeid = strtok_r (tmp, ":", &save_ptr);
- snap_uuid = strtok_r (NULL, "=", &save_ptr);
- snap_vol_id = strtok_r (NULL, ":", &save_ptr);
- brick_num = atoi(strtok_r (NULL, ":", &save_ptr));
- brick_path = strtok_r (NULL, ":", &save_ptr);
- snap_op = atoi(strtok_r (NULL, ":", &save_ptr));
- snap_status = atoi(strtok_r (NULL, ":", &save_ptr));
-
- if (!nodeid || !snap_uuid || !brick_path ||
- !snap_vol_id || brick_num < 1 || snap_op < 1 ||
- snap_status < 1) {
- gf_log (this->name, GF_LOG_ERROR,
- "Invalid missed_snap_entry");
- ret = -1;
- goto out;
- }
-
- snprintf (missed_info, sizeof(missed_info), "%s:%s",
- nodeid, snap_uuid);
-
- ret = glusterd_add_new_entry_to_list (missed_info,
- snap_vol_id,
- brick_num,
- brick_path,
- snap_op,
- snap_status);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to store missed snaps_list");
- goto out;
- }
-
- GF_FREE (tmp);
- tmp = NULL;
- }
-
- ret = 0;
-out:
- if (tmp)
- GF_FREE (tmp);
-
- gf_log (this->name, GF_LOG_TRACE, "Returning %d", ret);
- return ret;
-}
-
-/* This function will restore origin volume to it's snap.
- * The restore operation will simply replace the Gluster origin
- * volume with the snap volume.
- * TODO: Multi-volume delete to be done.
- * Cleanup in case of restore failure is pending.
- *
- * @param orig_vol volinfo of origin volume
- * @param snap_vol volinfo of snapshot volume
- *
- * @return 0 on success and negative value on error
- */
-int
-gd_restore_snap_volume (dict_t *dict, dict_t *rsp_dict,
- glusterd_volinfo_t *orig_vol,
- glusterd_volinfo_t *snap_vol,
- int32_t volcount)
-{
- int ret = -1;
- glusterd_volinfo_t *new_volinfo = NULL;
- glusterd_snap_t *snap = NULL;
- xlator_t *this = NULL;
- glusterd_conf_t *conf = NULL;
- glusterd_volinfo_t *temp_volinfo = NULL;
- glusterd_volinfo_t *voliter = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (dict);
- GF_ASSERT (rsp_dict);
- conf = this->private;
- GF_ASSERT (conf);
-
- GF_VALIDATE_OR_GOTO (this->name, orig_vol, out);
- GF_VALIDATE_OR_GOTO (this->name, snap_vol, out);
- snap = snap_vol->snapshot;
- GF_VALIDATE_OR_GOTO (this->name, snap, out);
-
- /* Set the status to under restore so that if the
- * the node goes down during restore and comes back
- * the state of the volume can be reverted correctly
- */
- snap->snap_status = GD_SNAP_STATUS_UNDER_RESTORE;
-
- /* We need to save this in disk so that if node goes
- * down the status is in updated state.
- */
- ret = glusterd_store_snap (snap);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Could not store snap "
- "object for %s snap of %s volume", snap_vol->volname,
- snap_vol->parent_volname);
- goto out;
- }
-
- /* Snap volume must be stoped before performing the
- * restore operation.
- */
- ret = glusterd_stop_volume (snap_vol);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to stop "
- "snap volume");
- goto out;
- }
-
- /* Create a new volinfo for the restored volume */
- ret = glusterd_volinfo_dup (snap_vol, &new_volinfo, _gf_true);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to create volinfo");
- goto out;
- }
-
- /* Following entries need to be derived from origin volume. */
- strcpy (new_volinfo->volname, orig_vol->volname);
- uuid_copy (new_volinfo->volume_id, orig_vol->volume_id);
- new_volinfo->snap_count = orig_vol->snap_count;
- new_volinfo->snap_max_hard_limit = orig_vol->snap_max_hard_limit;
- uuid_copy (new_volinfo->restored_from_snap,
- snap_vol->snapshot->snap_id);
-
- /* Bump the version of the restored volume, so that nodes *
- * which are done can sync during handshake */
- new_volinfo->version = orig_vol->version;
-
- list_for_each_entry_safe (voliter, temp_volinfo,
- &orig_vol->snap_volumes, snapvol_list) {
- list_add_tail (&voliter->snapvol_list,
- &new_volinfo->snap_volumes);
- }
- /* Copy the snap vol info to the new_volinfo.*/
- ret = glusterd_snap_volinfo_restore (dict, rsp_dict, new_volinfo,
- snap_vol, volcount);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to restore snap");
- goto out;
- }
-
- ret = glusterd_restore_geo_rep_files (snap_vol);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to restore "
- "geo-rep files for snap %s",
- snap_vol->snapshot->snapname);
- goto out;
- }
-
- ret = glusterd_copy_quota_files (snap_vol, orig_vol);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to restore "
- "quota files for snap %s",
- snap_vol->snapshot->snapname);
- goto out;
- }
-
- /* New volinfo always shows the status as created. Therefore
- * set the status to the original volume's status. */
- glusterd_set_volume_status (new_volinfo, orig_vol->status);
-
- list_add_tail (&new_volinfo->vol_list, &conf->volumes);
-
- ret = glusterd_store_volinfo (new_volinfo,
- GLUSTERD_VOLINFO_VER_AC_INCREMENT);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to store volinfo");
- goto out;
- }
-
- ret = 0;
-out:
- if (ret && NULL != new_volinfo) {
- /* In case of any failure we should free new_volinfo. Doing
- * this will also remove the entry we added in conf->volumes
- * if it was added there.
- */
- (void)glusterd_volinfo_delete (new_volinfo);
- }
-
- return ret;
-}
-
-
-
-int
-glusterd_snapshot_get_volnames_uuids (dict_t *dict,
- char *volname,
- gf_getsnap_name_uuid_rsp *snap_info_rsp)
-{
- int ret = -1;
- int snapcount = 0;
- char key[PATH_MAX] = {0,};
- glusterd_volinfo_t *snap_vol = NULL;
- glusterd_volinfo_t *volinfo = NULL;
- glusterd_volinfo_t *tmp_vol = NULL;
- xlator_t *this = NULL;
- int op_errno = 0;
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (volname);
- GF_VALIDATE_OR_GOTO_WITH_ERROR (this->name, dict, out,
- op_errno, EINVAL);
- GF_VALIDATE_OR_GOTO_WITH_ERROR (this->name, volname, out,
- op_errno, EINVAL);
- GF_VALIDATE_OR_GOTO_WITH_ERROR (this->name, snap_info_rsp, out,
- op_errno, EINVAL);
-
- ret = glusterd_volinfo_find (volname, &volinfo);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to get volinfo of volume %s",
- volname);
- op_errno = EINVAL;
- goto out;
- }
-
- list_for_each_entry_safe (snap_vol, tmp_vol, &volinfo->snap_volumes,
- snapvol_list) {
-
- if (GLUSTERD_STATUS_STARTED != snap_vol->status)
- continue;
-
- snapcount++;
-
- /* Set Snap Name */
- snprintf (key, sizeof (key), "snapname.%d", snapcount);
- ret = dict_set_dynstr_with_alloc (dict, key,
- snap_vol->snapshot->snapname);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to set "
- "snap name in dictionary");
- goto out;
- }
-
- /* Set Snap ID */
- snprintf (key, sizeof (key), "snap-id.%d", snapcount);
- ret = dict_set_dynstr_with_alloc (dict, key,
- uuid_utoa(snap_vol->snapshot->snap_id));
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to set "
- "snap id in dictionary");
- goto out;
- }
-
- /* Snap Volname which is used to activate the snap vol */
- snprintf (key, sizeof (key), "snap-volname.%d", snapcount);
- ret = dict_set_dynstr_with_alloc (dict, key, snap_vol->volname);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to set "
- "snap id in dictionary");
- goto out;
- }
- }
-
- ret = dict_set_int32 (dict, "snap-count", snapcount);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to set snapcount");
- op_errno = -ret;
- goto out;
- }
-
- ret = dict_allocate_and_serialize (dict, &snap_info_rsp->dict.dict_val,
- &snap_info_rsp->dict.dict_len);
- if (ret) {
- op_errno = -ret;
- ret = -1;
- goto out;
- }
-
- ret = 0;
-
-out:
- snap_info_rsp->op_ret = ret;
- snap_info_rsp->op_errno = op_errno;
- snap_info_rsp->op_errstr = "";
-
- return ret;
-}
diff --git a/xlators/mgmt/glusterd/src/glusterd-store.c b/xlators/mgmt/glusterd/src/glusterd-store.c
deleted file mode 100644
index 1f31d196af2..00000000000
--- a/xlators/mgmt/glusterd/src/glusterd-store.c
+++ /dev/null
@@ -1,4429 +0,0 @@
-/*
- Copyright (c) 2007-2013 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 "glusterd-op-sm.h"
-#include <inttypes.h>
-
-
-#include "globals.h"
-#include "glusterfs.h"
-#include "compat.h"
-#include "dict.h"
-#include "protocol-common.h"
-#include "xlator.h"
-#include "logging.h"
-#include "timer.h"
-#include "defaults.h"
-#include "compat.h"
-#include "compat-errno.h"
-#include "statedump.h"
-#include "glusterd-mem-types.h"
-#include "glusterd.h"
-#include "glusterd-sm.h"
-#include "glusterd-op-sm.h"
-#include "glusterd-utils.h"
-#include "glusterd-hooks.h"
-#include "store.h"
-#include "glusterd-store.h"
-
-#include "rpc-clnt.h"
-#include "common-utils.h"
-
-#include <sys/resource.h>
-#include <inttypes.h>
-#include <dirent.h>
-
-#if defined(GF_LINUX_HOST_OS)
-#include <mntent.h>
-#else
-#include "mntent_compat.h"
-#endif
-
-void
-glusterd_replace_slash_with_hyphen (char *str)
-{
- char *ptr = NULL;
-
- ptr = strchr (str, '/');
-
- while (ptr) {
- *ptr = '-';
- ptr = strchr (str, '/');
- }
-}
-
-int32_t
-glusterd_store_create_brick_dir (glusterd_volinfo_t *volinfo)
-{
- int32_t ret = -1;
- char brickdirpath[PATH_MAX] = {0,};
- glusterd_conf_t *priv = NULL;
-
- GF_ASSERT (volinfo);
-
- priv = THIS->private;
- GF_ASSERT (priv);
-
- GLUSTERD_GET_BRICK_DIR (brickdirpath, volinfo, priv);
- ret = gf_store_mkdir (brickdirpath);
-
- return ret;
-}
-
-static void
-glusterd_store_key_vol_brick_set (glusterd_brickinfo_t *brickinfo,
- char *key_vol_brick, size_t len)
-{
- GF_ASSERT (brickinfo);
- GF_ASSERT (key_vol_brick);
- GF_ASSERT (len >= PATH_MAX);
-
- snprintf (key_vol_brick, len, "%s", brickinfo->path);
- glusterd_replace_slash_with_hyphen (key_vol_brick);
-}
-
-static void
-glusterd_store_brickinfofname_set (glusterd_brickinfo_t *brickinfo,
- char *brickfname, size_t len)
-{
- char key_vol_brick[PATH_MAX] = {0};
-
- GF_ASSERT (brickfname);
- GF_ASSERT (brickinfo);
- GF_ASSERT (len >= PATH_MAX);
-
- glusterd_store_key_vol_brick_set (brickinfo, key_vol_brick,
- sizeof (key_vol_brick));
- snprintf (brickfname, len, "%s:%s", brickinfo->hostname, key_vol_brick);
-}
-
-static void
-glusterd_store_brickinfopath_set (glusterd_volinfo_t *volinfo,
- glusterd_brickinfo_t *brickinfo,
- char *brickpath, size_t len)
-{
- char brickfname[PATH_MAX] = {0};
- char brickdirpath[PATH_MAX] = {0,};
- glusterd_conf_t *priv = NULL;
-
- GF_ASSERT (brickpath);
- GF_ASSERT (brickinfo);
- GF_ASSERT (len >= PATH_MAX);
-
- priv = THIS->private;
- GF_ASSERT (priv);
-
- GLUSTERD_GET_BRICK_DIR (brickdirpath, volinfo, priv);
- glusterd_store_brickinfofname_set (brickinfo, brickfname,
- sizeof (brickfname));
- snprintf (brickpath, len, "%s/%s", brickdirpath, brickfname);
-}
-
-static void
-glusterd_store_snapd_path_set (glusterd_volinfo_t *volinfo,
- char *snapd_path, size_t len)
-{
- char volpath[PATH_MAX] = {0, };
- glusterd_conf_t *priv = NULL;
-
- GF_ASSERT (volinfo);
- GF_ASSERT (len >= PATH_MAX);
-
- priv = THIS->private;
- GF_ASSERT (priv);
-
- GLUSTERD_GET_VOLUME_DIR (volpath, volinfo, priv);
-
- snprintf (snapd_path, len, "%s/snapd.info", volpath);
-}
-
-gf_boolean_t
-glusterd_store_is_valid_brickpath (char *volname, char *brick)
-{
- glusterd_brickinfo_t *brickinfo = NULL;
- glusterd_volinfo_t *volinfo = NULL;
- int32_t ret = 0;
- size_t volname_len = strlen (volname);
- xlator_t *this = NULL;
- int bpath_len = 0;
- const char delim[2] = "/";
- char *sub_dir = NULL;
- char *saveptr = NULL;
- char *brickpath_ptr = NULL;
-
- this = THIS;
- GF_ASSERT (this);
-
- ret = glusterd_brickinfo_new_from_brick (brick, &brickinfo);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING, "Failed to create brick "
- "info for brick %s", brick);
- ret = 0;
- goto out;
- }
- ret = glusterd_volinfo_new (&volinfo);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING, "Failed to create volinfo");
- ret = 0;
- goto out;
- }
- if (volname_len >= sizeof (volinfo->volname)) {
- gf_log (this->name, GF_LOG_WARNING, "volume name too long");
- ret = 0;
- goto out;
- }
- memcpy (volinfo->volname, volname, volname_len+1);
-
- /* Check whether brickpath is less than PATH_MAX */
- ret = 1;
- bpath_len = strlen (brickinfo->path);
-
- if (brickinfo->path[bpath_len - 1] != '/') {
- if (strlen (brickinfo->path) >= PATH_MAX) {
- ret = 0;
- goto out;
- }
- } else {
- /* Path has a trailing "/" which should not be considered in
- * length check validation
- */
- if (strlen (brickinfo->path) >= PATH_MAX + 1) {
- ret = 0;
- goto out;
- }
- }
-
- /* The following validation checks whether each sub directories in the
- * brick path meets the POSIX max length validation
- */
-
- brickpath_ptr = brickinfo->path;
- sub_dir = strtok_r (brickpath_ptr, delim, &saveptr);
-
- while (sub_dir != NULL) {
- if (strlen(sub_dir) >= _POSIX_PATH_MAX) {
- ret = 0;
- goto out;
- }
- sub_dir = strtok_r (NULL, delim, &saveptr);
- }
-
-out:
- if (brickinfo)
- glusterd_brickinfo_delete (brickinfo);
- if (volinfo)
- glusterd_volinfo_unref (volinfo);
-
- return ret;
-}
-
-int32_t
-glusterd_store_volinfo_brick_fname_write (int vol_fd,
- glusterd_brickinfo_t *brickinfo,
- int32_t brick_count)
-{
- char key[PATH_MAX] = {0,};
- char brickfname[PATH_MAX] = {0,};
- int32_t ret = -1;
-
- snprintf (key, sizeof (key), "%s-%d", GLUSTERD_STORE_KEY_VOL_BRICK,
- brick_count);
- glusterd_store_brickinfofname_set (brickinfo, brickfname,
- sizeof (brickfname));
- ret = gf_store_save_value (vol_fd, key, brickfname);
- if (ret)
- goto out;
-
-out:
- return ret;
-}
-
-int32_t
-glusterd_store_create_brick_shandle_on_absence (glusterd_volinfo_t *volinfo,
- glusterd_brickinfo_t *brickinfo)
-{
- char brickpath[PATH_MAX] = {0,};
- int32_t ret = 0;
-
- GF_ASSERT (volinfo);
- GF_ASSERT (brickinfo);
-
- glusterd_store_brickinfopath_set (volinfo, brickinfo, brickpath,
- sizeof (brickpath));
- ret = gf_store_handle_create_on_absence (&brickinfo->shandle,
- brickpath);
- return ret;
-}
-
-int32_t
-glusterd_store_create_snapd_shandle_on_absence (glusterd_volinfo_t *volinfo)
-{
- char snapd_path[PATH_MAX] = {0,};
- int32_t ret = 0;
-
- GF_ASSERT (volinfo);
-
- glusterd_store_snapd_path_set (volinfo, snapd_path,
- sizeof (snapd_path));
- ret = gf_store_handle_create_on_absence (&volinfo->snapd.handle,
- snapd_path);
- return ret;
-}
-
-/* Store the bricks snapshot details only if required
- *
- * The snapshot details will be stored only if the cluster op-version is
- * greater than or equal to 4
- */
-int
-gd_store_brick_snap_details_write (int fd, glusterd_brickinfo_t *brickinfo)
-{
- int ret = -1;
- xlator_t *this = NULL;
- glusterd_conf_t *conf = NULL;
- char value[256] = {0,};
-
- this = THIS;
- GF_ASSERT (this != NULL);
- conf = this->private;
- GF_VALIDATE_OR_GOTO (this->name, (conf != NULL), out);
-
- GF_VALIDATE_OR_GOTO (this->name, (fd > 0), out);
- GF_VALIDATE_OR_GOTO (this->name, (brickinfo != NULL), out);
-
- if (conf->op_version < GD_OP_VERSION_3_6_0) {
- ret = 0;
- goto out;
- }
-
- if (strlen(brickinfo->device_path) > 0) {
- snprintf (value, sizeof(value), "%s", brickinfo->device_path);
- ret = gf_store_save_value (fd,
- GLUSTERD_STORE_KEY_BRICK_DEVICE_PATH, value);
- if (ret)
- goto out;
- }
-
- if (strlen(brickinfo->mount_dir) > 0) {
- memset (value, 0, sizeof (value));
- snprintf (value, sizeof(value), "%s", brickinfo->mount_dir);
- ret = gf_store_save_value (fd,
- GLUSTERD_STORE_KEY_BRICK_MOUNT_DIR, value);
- if (ret)
- goto out;
- }
-
- if (strlen (brickinfo->fstype) > 0) {
- snprintf (value, sizeof (value), "%s", brickinfo->fstype);
- ret = gf_store_save_value (fd,
- GLUSTERD_STORE_KEY_BRICK_FSTYPE, value);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to save "
- "brick fs type of brick %s", brickinfo->path);
- goto out;
- }
- }
-
- if (strlen (brickinfo->mnt_opts) > 0) {
- snprintf (value, sizeof (value), "%s", brickinfo->mnt_opts);
- ret = gf_store_save_value (fd,
- GLUSTERD_STORE_KEY_BRICK_MNTOPTS, value);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to save "
- "brick mnt opts of brick %s", brickinfo->path);
- goto out;
- }
- }
-
- memset (value, 0, sizeof (value));
- snprintf (value, sizeof(value), "%d", brickinfo->snap_status);
- ret = gf_store_save_value (fd, GLUSTERD_STORE_KEY_BRICK_SNAP_STATUS,
- value);
-
-out:
- return ret;
-}
-
-int32_t
-glusterd_store_brickinfo_write (int fd, glusterd_brickinfo_t *brickinfo)
-{
- char value[256] = {0,};
- int32_t ret = 0;
-
- GF_ASSERT (brickinfo);
- GF_ASSERT (fd > 0);
-
- ret = gf_store_save_value (fd, GLUSTERD_STORE_KEY_BRICK_HOSTNAME,
- brickinfo->hostname);
- if (ret)
- goto out;
-
- ret = gf_store_save_value (fd, GLUSTERD_STORE_KEY_BRICK_PATH,
- brickinfo->path);
- if (ret)
- goto out;
-
- snprintf (value, sizeof(value), "%d", brickinfo->port);
- ret = gf_store_save_value (fd, GLUSTERD_STORE_KEY_BRICK_PORT, value);
-
- snprintf (value, sizeof(value), "%d", brickinfo->rdma_port);
- ret = gf_store_save_value (fd, GLUSTERD_STORE_KEY_BRICK_RDMA_PORT,
- value);
-
- snprintf (value, sizeof(value), "%d", brickinfo->decommissioned);
- ret = gf_store_save_value (fd, GLUSTERD_STORE_KEY_BRICK_DECOMMISSIONED,
- value);
- if (ret)
- goto out;
-
- ret = gf_store_save_value (fd, GLUSTERD_STORE_KEY_BRICK_ID,
- brickinfo->brick_id);
- if (ret)
- goto out;
-
- ret = gd_store_brick_snap_details_write (fd, brickinfo);
- if (ret)
- goto out;
-
- if (!brickinfo->vg[0])
- goto out;
-
- ret = gf_store_save_value (fd, GLUSTERD_STORE_KEY_BRICK_VGNAME,
- brickinfo->vg);
-out:
- gf_log (THIS->name, GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-
-int32_t
-glusterd_store_snapd_write (int fd, glusterd_volinfo_t *volinfo)
-{
- char value[256] = {0,};
- int32_t ret = 0;
- xlator_t *this = NULL;
-
- GF_ASSERT (volinfo);
- GF_ASSERT (fd > 0);
-
- this = THIS;
- GF_ASSERT (this);
-
- snprintf (value, sizeof(value), "%d", volinfo->snapd.port);
- ret = gf_store_save_value (fd, GLUSTERD_STORE_KEY_SNAPD_PORT, value);
- if (ret)
- gf_log (this->name, GF_LOG_ERROR, "failed to store the snapd "
- "port of volume %s", volinfo->volname);
-
-
- gf_log (this->name, GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-
-int32_t
-glusterd_store_perform_brick_store (glusterd_brickinfo_t *brickinfo)
-{
- int fd = -1;
- int32_t ret = -1;
- GF_ASSERT (brickinfo);
-
- fd = gf_store_mkstemp (brickinfo->shandle);
- if (fd <= 0) {
- ret = -1;
- goto out;
- }
-
- ret = glusterd_store_brickinfo_write (fd, brickinfo);
- if (ret)
- goto out;
-
-out:
- if (ret && (fd > 0))
- gf_store_unlink_tmppath (brickinfo->shandle);
- gf_log (THIS->name, GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-
-int32_t
-glusterd_store_perform_snapd_store (glusterd_volinfo_t *volinfo)
-{
- int fd = -1;
- int32_t ret = -1;
- xlator_t *this = NULL;
-
- GF_ASSERT (volinfo);
-
- this = THIS;
- GF_ASSERT (this);
-
- fd = gf_store_mkstemp (volinfo->snapd.handle);
- if (fd <= 0) {
- gf_log (this->name, GF_LOG_ERROR, "failed to create the "
- "temporary file for the snapd store handle of volume "
- "%s", volinfo->volname);
- goto out;
- }
-
- ret = glusterd_store_snapd_write (fd, volinfo);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "failed to write snapd port "
- "info to store handle (volume: %s", volinfo->volname);
- goto out;
- }
-
- ret = gf_store_rename_tmppath (volinfo->snapd.handle);
-
-out:
- if (ret && (fd > 0))
- gf_store_unlink_tmppath (volinfo->snapd.handle);
- gf_log (THIS->name, GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-
-int32_t
-glusterd_store_brickinfo (glusterd_volinfo_t *volinfo,
- glusterd_brickinfo_t *brickinfo, int32_t brick_count,
- int vol_fd)
-{
- int32_t ret = -1;
-
- GF_ASSERT (volinfo);
- GF_ASSERT (brickinfo);
-
- ret = glusterd_store_volinfo_brick_fname_write (vol_fd, brickinfo,
- brick_count);
- if (ret)
- goto out;
-
- ret = glusterd_store_create_brick_dir (volinfo);
- if (ret)
- goto out;
-
- ret = glusterd_store_create_brick_shandle_on_absence (volinfo,
- brickinfo);
- if (ret)
- goto out;
-
- ret = glusterd_store_perform_brick_store (brickinfo);
-out:
- gf_log (THIS->name, GF_LOG_DEBUG, "Returning with %d", ret);
- return ret;
-}
-
-int32_t
-glusterd_store_snapd_info (glusterd_volinfo_t *volinfo)
-{
- int32_t ret = -1;
- xlator_t *this = NULL;
-
- GF_ASSERT (volinfo);
-
- this = THIS;
- GF_ASSERT (this);
-
- ret = glusterd_store_create_snapd_shandle_on_absence (volinfo);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "failed to create store "
- "handle for snapd (volume: %s)", volinfo->volname);
- goto out;
- }
-
- ret = glusterd_store_perform_snapd_store (volinfo);
- if (ret)
- gf_log (this->name, GF_LOG_ERROR, "failed to store snapd info "
- "of the volume %s", volinfo->volname);
-
-out:
- if (ret)
- gf_store_unlink_tmppath (volinfo->snapd.handle);
-
- gf_log (this->name, GF_LOG_DEBUG, "Returning with %d", ret);
- return ret;
-}
-
-int32_t
-glusterd_store_delete_brick (glusterd_brickinfo_t *brickinfo, char *delete_path)
-{
- int32_t ret = -1;
- glusterd_conf_t *priv = NULL;
- char brickpath[PATH_MAX] = {0,};
- char *ptr = NULL;
- char *tmppath = NULL;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (brickinfo);
-
- priv = this->private;
- GF_ASSERT (priv);
-
- tmppath = gf_strdup (brickinfo->path);
-
- ptr = strchr (tmppath, '/');
-
- while (ptr) {
- *ptr = '-';
- ptr = strchr (tmppath, '/');
- }
-
- snprintf (brickpath, sizeof (brickpath),
- "%s/"GLUSTERD_BRICK_INFO_DIR"/%s:%s", delete_path,
- brickinfo->hostname, tmppath);
-
- GF_FREE (tmppath);
-
- ret = unlink (brickpath);
-
- if ((ret < 0) && (errno != ENOENT)) {
- gf_log (this->name, GF_LOG_DEBUG, "Unlink failed on %s, "
- "reason: %s", brickpath, strerror(errno));
- ret = -1;
- goto out;
- } else {
- ret = 0;
- }
-
-out:
- if (brickinfo->shandle) {
- gf_store_handle_destroy (brickinfo->shandle);
- brickinfo->shandle = NULL;
- }
- gf_log (this->name, GF_LOG_DEBUG, "Returning with %d", ret);
- return ret;
-}
-
-int32_t
-glusterd_store_remove_bricks (glusterd_volinfo_t *volinfo, char *delete_path)
-{
- int32_t ret = 0;
- glusterd_brickinfo_t *tmp = NULL;
- glusterd_conf_t *priv = NULL;
- char brickdir [PATH_MAX] = {0,};
- DIR *dir = NULL;
- struct dirent *entry = NULL;
- char path[PATH_MAX] = {0,};
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
-
- GF_ASSERT (volinfo);
-
- list_for_each_entry (tmp, &volinfo->bricks, brick_list) {
- ret = glusterd_store_delete_brick (tmp, delete_path);
- if (ret)
- goto out;
- }
-
- priv = this->private;
- GF_ASSERT (priv);
-
- snprintf (brickdir, sizeof (brickdir), "%s/%s", delete_path,
- GLUSTERD_BRICK_INFO_DIR);
-
- dir = opendir (brickdir);
-
- glusterd_for_each_entry (entry, dir);
-
- while (entry) {
- snprintf (path, sizeof (path), "%s/%s",
- brickdir, entry->d_name);
- ret = unlink (path);
- if (ret && errno != ENOENT) {
- gf_log (this->name, GF_LOG_DEBUG, "Unable to unlink %s, "
- "reason: %s", path, strerror(errno));
- }
- glusterd_for_each_entry (entry, dir);
- }
-
- closedir (dir);
-
- ret = rmdir (brickdir);
-
-out:
- gf_log (this->name, GF_LOG_DEBUG, "Returning with %d", ret);
- return ret;
-}
-
-static int
-_storeslaves (dict_t *this, char *key, data_t *value, void *data)
-{
- int32_t ret = 0;
- gf_store_handle_t *shandle = NULL;
- xlator_t *xl = NULL;
-
- xl = THIS;
- GF_ASSERT (xl);
-
- shandle = (gf_store_handle_t*)data;
-
- GF_ASSERT (shandle);
- GF_ASSERT (shandle->fd > 0);
- GF_ASSERT (shandle->path);
- GF_ASSERT (key);
- GF_ASSERT (value && value->data);
-
- if ((!shandle) || (shandle->fd <= 0) || (!shandle->path))
- return -1;
-
- if (!key)
- return -1;
- if (!value || !value->data)
- return -1;
-
- gf_log (xl->name, GF_LOG_DEBUG, "Storing in volinfo:key= %s, val=%s",
- key, value->data);
-
- ret = gf_store_save_value (shandle->fd, key, (char*)value->data);
- if (ret) {
- gf_log (xl->name, GF_LOG_ERROR, "Unable to write into store"
- " handle for path: %s", shandle->path);
- return -1;
- }
- return 0;
-}
-
-
-int _storeopts (dict_t *this, char *key, data_t *value, void *data)
-{
- int32_t ret = 0;
- int32_t exists = 0;
- gf_store_handle_t *shandle = NULL;
- xlator_t *xl = NULL;
-
- xl = THIS;
- GF_ASSERT (xl);
-
- shandle = (gf_store_handle_t*)data;
-
- GF_ASSERT (shandle);
- GF_ASSERT (shandle->fd > 0);
- GF_ASSERT (shandle->path);
- GF_ASSERT (key);
- GF_ASSERT (value && value->data);
-
- if ((!shandle) || (shandle->fd <= 0) || (!shandle->path))
- return -1;
-
- if (!key)
- return -1;
- if (!value || !value->data)
- return -1;
-
- if (is_key_glusterd_hooks_friendly (key)) {
- exists = 1;
-
- } else {
- exists = glusterd_check_option_exists (key, NULL);
- }
-
- if (1 == exists) {
- gf_log (xl->name, GF_LOG_DEBUG, "Storing in volinfo:key= %s, "
- "val=%s", key, value->data);
-
- } else {
- gf_log (xl->name, GF_LOG_DEBUG, "Discarding:key= %s, val=%s",
- key, value->data);
- return 0;
- }
-
- ret = gf_store_save_value (shandle->fd, key, (char*)value->data);
- if (ret) {
- gf_log (xl->name, GF_LOG_ERROR, "Unable to write into store"
- " handle for path: %s", shandle->path);
- return -1;
- }
- return 0;
-}
-
-/* Store the volumes snapshot details only if required
- *
- * The snapshot details will be stored only if the cluster op-version is
- * greater than or equal to 4
- */
-int
-glusterd_volume_write_snap_details (int fd, glusterd_volinfo_t *volinfo)
-{
- int ret = -1;
- xlator_t *this = NULL;
- glusterd_conf_t *conf = NULL;
- char buf[PATH_MAX] = {0,};
-
- this = THIS;
- GF_ASSERT (this != NULL);
- conf = this->private;
- GF_VALIDATE_OR_GOTO (this->name, (conf != NULL), out);
-
- GF_VALIDATE_OR_GOTO (this->name, (fd > 0), out);
- GF_VALIDATE_OR_GOTO (this->name, (volinfo != NULL), out);
-
- if (conf->op_version < GD_OP_VERSION_3_6_0) {
- ret = 0;
- goto out;
- }
-
- snprintf (buf, sizeof (buf), "%s", volinfo->parent_volname);
- ret = gf_store_save_value (fd, GLUSTERD_STORE_KEY_PARENT_VOLNAME, buf);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to store "
- GLUSTERD_STORE_KEY_PARENT_VOLNAME);
- goto out;
- }
-
- ret = gf_store_save_value (fd, GLUSTERD_STORE_KEY_VOL_RESTORED_SNAP,
- uuid_utoa (volinfo->restored_from_snap));
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Unable to write restored_from_snap");
- goto out;
- }
-
- memset (buf, 0, sizeof (buf));
- snprintf (buf, sizeof (buf), "%"PRIu64, volinfo->snap_max_hard_limit);
- ret = gf_store_save_value (fd, GLUSTERD_STORE_KEY_SNAP_MAX_HARD_LIMIT,
- buf);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Unable to write snap-max-hard-limit");
- goto out;
- }
-
- ret = glusterd_store_snapd_info (volinfo);
- if (ret)
- gf_log (this->name, GF_LOG_ERROR, "snapd info store failed "
- "volume: %s", volinfo->volname);
-
-out:
- if (ret)
- gf_log (this->name, GF_LOG_ERROR, "Failed to write snap details"
- " for volume %s", volinfo->volname);
- return ret;
-}
-int32_t
-glusterd_volume_exclude_options_write (int fd, glusterd_volinfo_t *volinfo)
-{
- char *str = NULL;
- char buf[PATH_MAX] = "";
- int32_t ret = -1;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (fd > 0);
- GF_ASSERT (volinfo);
-
- snprintf (buf, sizeof (buf), "%d", volinfo->type);
- ret = gf_store_save_value (fd, GLUSTERD_STORE_KEY_VOL_TYPE, buf);
- if (ret)
- goto out;
-
- snprintf (buf, sizeof (buf), "%d", volinfo->brick_count);
- ret = gf_store_save_value (fd, GLUSTERD_STORE_KEY_VOL_COUNT, buf);
- if (ret)
- goto out;
-
- snprintf (buf, sizeof (buf), "%d", volinfo->status);
- ret = gf_store_save_value (fd, GLUSTERD_STORE_KEY_VOL_STATUS, buf);
- if (ret)
- goto out;
-
- snprintf (buf, sizeof (buf), "%d", volinfo->sub_count);
- ret = gf_store_save_value (fd, GLUSTERD_STORE_KEY_VOL_SUB_COUNT, buf);
- if (ret)
- goto out;
-
- snprintf (buf, sizeof (buf), "%d", volinfo->stripe_count);
- ret = gf_store_save_value (fd, GLUSTERD_STORE_KEY_VOL_STRIPE_CNT, buf);
- if (ret)
- goto out;
-
- snprintf (buf, sizeof (buf), "%d", volinfo->replica_count);
- ret = gf_store_save_value (fd, GLUSTERD_STORE_KEY_VOL_REPLICA_CNT,
- buf);
- if (ret)
- goto out;
-
- snprintf (buf, sizeof (buf), "%d", volinfo->disperse_count);
- ret = gf_store_save_value (fd, GLUSTERD_STORE_KEY_VOL_DISPERSE_CNT,
- buf);
- if (ret)
- goto out;
-
- snprintf (buf, sizeof (buf), "%d", volinfo->redundancy_count);
- ret = gf_store_save_value (fd, GLUSTERD_STORE_KEY_VOL_REDUNDANCY_CNT,
- buf);
- if (ret)
- goto out;
-
- snprintf (buf, sizeof (buf), "%d", volinfo->version);
- ret = gf_store_save_value (fd, GLUSTERD_STORE_KEY_VOL_VERSION, buf);
- if (ret)
- goto out;
-
- snprintf (buf, sizeof (buf), "%d", volinfo->transport_type);
- ret = gf_store_save_value (fd, GLUSTERD_STORE_KEY_VOL_TRANSPORT, buf);
- if (ret)
- goto out;
-
- ret = gf_store_save_value (fd, GLUSTERD_STORE_KEY_VOL_ID,
- uuid_utoa (volinfo->volume_id));
- if (ret)
- goto out;
-
- str = glusterd_auth_get_username (volinfo);
- if (str) {
- ret = gf_store_save_value (fd, GLUSTERD_STORE_KEY_USERNAME,
- str);
- if (ret)
- goto out;
- }
-
- str = glusterd_auth_get_password (volinfo);
- if (str) {
- ret = gf_store_save_value (fd, GLUSTERD_STORE_KEY_PASSWORD,
- str);
- if (ret)
- goto out;
- }
-
- snprintf (buf, sizeof (buf), "%d", volinfo->op_version);
- ret = gf_store_save_value (fd, GLUSTERD_STORE_KEY_VOL_OP_VERSION, buf);
- if (ret)
- goto out;
-
- snprintf (buf, sizeof (buf), "%d", volinfo->client_op_version);
- ret = gf_store_save_value (fd, GLUSTERD_STORE_KEY_VOL_CLIENT_OP_VERSION,
- buf);
- if (ret)
- goto out;
- if (volinfo->caps) {
- snprintf (buf, sizeof (buf), "%d", volinfo->caps);
- ret = gf_store_save_value (fd, GLUSTERD_STORE_KEY_VOL_CAPS,
- buf);
- if (ret)
- goto out;
- }
-
- ret = glusterd_volume_write_snap_details (fd, volinfo);
-
-out:
- if (ret)
- gf_log (this->name, GF_LOG_ERROR, "Unable to write volume "
- "values for %s", volinfo->volname);
- return ret;
-}
-
-static void
-glusterd_store_voldirpath_set (glusterd_volinfo_t *volinfo, char *voldirpath,
- size_t len)
-{
- glusterd_conf_t *priv = NULL;
-
- GF_ASSERT (volinfo);
- priv = THIS->private;
- GF_ASSERT (priv);
-
- GLUSTERD_GET_VOLUME_DIR (voldirpath, volinfo, priv);
-}
-
-static int32_t
-glusterd_store_create_volume_dir (glusterd_volinfo_t *volinfo)
-{
- int32_t ret = -1;
- char voldirpath[PATH_MAX] = {0,};
-
- GF_ASSERT (volinfo);
-
- glusterd_store_voldirpath_set (volinfo, voldirpath,
- sizeof (voldirpath));
- ret = gf_store_mkdir (voldirpath);
-
- gf_log (THIS->name, GF_LOG_DEBUG, "Returning with %d", ret);
- return ret;
-}
-
-int32_t
-glusterd_store_create_snap_dir (glusterd_snap_t *snap)
-{
- int32_t ret = -1;
- char snapdirpath[PATH_MAX] = {0,};
- glusterd_conf_t *priv = NULL;
-
- priv = THIS->private;
- GF_ASSERT (priv);
- GF_ASSERT (snap);
-
- GLUSTERD_GET_SNAP_DIR (snapdirpath, snap, priv);
-
- ret = mkdir_p (snapdirpath, 0755, _gf_true);
- if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR, "Failed to create snaps dir "
- "%s", snapdirpath);
- }
- return ret;
-}
-
-int32_t
-glusterd_store_volinfo_write (int fd, glusterd_volinfo_t *volinfo)
-{
- int32_t ret = -1;
- gf_store_handle_t *shandle = NULL;
- GF_ASSERT (fd > 0);
- GF_ASSERT (volinfo);
- GF_ASSERT (volinfo->shandle);
-
- shandle = volinfo->shandle;
- ret = glusterd_volume_exclude_options_write (fd, volinfo);
- if (ret)
- goto out;
-
- shandle->fd = fd;
- dict_foreach (volinfo->dict, _storeopts, shandle);
-
- dict_foreach (volinfo->gsync_slaves, _storeslaves, shandle);
- shandle->fd = 0;
-out:
- gf_log (THIS->name, GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-
-int32_t
-glusterd_store_snapinfo_write (glusterd_snap_t *snap)
-{
- int32_t ret = -1;
- int fd = 0;
- char buf[PATH_MAX] = "";
-
- GF_ASSERT (snap);
-
- fd = gf_store_mkstemp (snap->shandle);
- if (fd <= 0)
- goto out;
-
- ret = gf_store_save_value (fd, GLUSTERD_STORE_KEY_SNAP_ID,
- uuid_utoa (snap->snap_id));
- if (ret)
- goto out;
-
- snprintf (buf, sizeof (buf), "%d", snap->snap_status);
- ret = gf_store_save_value (fd, GLUSTERD_STORE_KEY_SNAP_STATUS, buf);
- if (ret)
- goto out;
-
- snprintf (buf, sizeof (buf), "%d", snap->snap_restored);
- ret = gf_store_save_value (fd, GLUSTERD_STORE_KEY_SNAP_RESTORED, buf);
- if (ret)
- goto out;
-
- if (snap->description) {
- ret = gf_store_save_value (fd, GLUSTERD_STORE_KEY_SNAP_DESC,
- snap->description);
- if (ret)
- goto out;
- }
-
- snprintf (buf, sizeof (buf), "%ld", snap->time_stamp);
- ret = gf_store_save_value (fd, GLUSTERD_STORE_KEY_SNAP_TIMESTAMP, buf);
-
-out:
- gf_log (THIS->name, GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-
-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);
-
- 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);
-}
-
-static void
-glusterd_store_quota_conf_path_set (glusterd_volinfo_t *volinfo,
- char *quota_conf_path, size_t len)
-{
- char voldirpath[PATH_MAX] = {0,};
- GF_ASSERT (volinfo);
- GF_ASSERT (quota_conf_path);
- GF_ASSERT (len <= PATH_MAX);
-
- glusterd_store_voldirpath_set (volinfo, voldirpath,
- sizeof (voldirpath));
- snprintf (quota_conf_path, len, "%s/%s", voldirpath,
- GLUSTERD_VOLUME_QUOTA_CONFIG);
-}
-
-static void
-glusterd_store_missed_snaps_list_path_set (char *missed_snaps_list,
- size_t len)
-{
- glusterd_conf_t *priv = NULL;
-
- priv = THIS->private;
- GF_ASSERT (priv);
- GF_ASSERT (missed_snaps_list);
- GF_ASSERT (len <= PATH_MAX);
-
- snprintf (missed_snaps_list, len, "%s/snaps/"
- GLUSTERD_MISSED_SNAPS_LIST_FILE, priv->workdir);
-}
-
-static void
-glusterd_store_snapfpath_set (glusterd_snap_t *snap, char *snap_fpath,
- size_t len)
-{
- glusterd_conf_t *priv = NULL;
- priv = THIS->private;
- GF_ASSERT (priv);
- GF_ASSERT (snap);
- GF_ASSERT (snap_fpath);
- GF_ASSERT (len <= PATH_MAX);
-
- snprintf (snap_fpath, len, "%s/snaps/%s/%s", priv->workdir,
- snap->snapname, GLUSTERD_SNAP_INFO_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 = gf_store_handle_create_on_absence (&volinfo->rb_shandle,
- rbstatepath);
- return ret;
-}
-
-int32_t
-glusterd_store_create_vol_shandle_on_absence (glusterd_volinfo_t *volinfo)
-{
- char volfpath[PATH_MAX] = {0};
- int32_t ret = 0;
-
- GF_ASSERT (volinfo);
-
- glusterd_store_volfpath_set (volinfo, volfpath, sizeof (volfpath));
- ret = gf_store_handle_create_on_absence (&volinfo->shandle, volfpath);
- return ret;
-}
-
-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 =
- gf_store_handle_create_on_absence (&volinfo->node_state_shandle,
- node_state_path);
-
- return ret;
-}
-
-int32_t
-glusterd_store_create_quota_conf_sh_on_absence (glusterd_volinfo_t *volinfo)
-{
- char quota_conf_path[PATH_MAX] = {0};
- int32_t ret = 0;
-
- GF_ASSERT (volinfo);
-
- glusterd_store_quota_conf_path_set (volinfo, quota_conf_path,
- sizeof (quota_conf_path));
- ret =
- gf_store_handle_create_on_absence (&volinfo->quota_conf_shandle,
- quota_conf_path);
-
- return ret;
-}
-
-static int32_t
-glusterd_store_create_missed_snaps_list_shandle_on_absence ()
-{
- char missed_snaps_list[PATH_MAX] = "";
- int32_t ret = -1;
- glusterd_conf_t *priv = NULL;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
-
- priv = this->private;
- GF_ASSERT (priv);
-
- glusterd_store_missed_snaps_list_path_set (missed_snaps_list,
- sizeof(missed_snaps_list));
-
- ret = gf_store_handle_create_on_absence
- (&priv->missed_snaps_list_shandle,
- missed_snaps_list);
- return ret;
-}
-
-int32_t
-glusterd_store_create_snap_shandle_on_absence (glusterd_snap_t *snap)
-{
- char snapfpath[PATH_MAX] = {0};
- int32_t ret = 0;
-
- GF_ASSERT (snap);
-
- glusterd_store_snapfpath_set (snap, snapfpath, sizeof (snapfpath));
- ret = gf_store_handle_create_on_absence (&snap->shandle, snapfpath);
- return ret;
-}
-
-int32_t
-glusterd_store_brickinfos (glusterd_volinfo_t *volinfo, int vol_fd)
-{
- int32_t ret = 0;
- glusterd_brickinfo_t *brickinfo = NULL;
- int32_t brick_count = 0;
-
- GF_ASSERT (volinfo);
-
- list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) {
- ret = glusterd_store_brickinfo (volinfo, brickinfo,
- brick_count, vol_fd);
- if (ret)
- goto out;
- brick_count++;
- }
-out:
- gf_log (THIS->name, GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-
-int32_t
-glusterd_store_rbstate_write (int fd, glusterd_volinfo_t *volinfo)
-{
- int ret = -1;
- int port = 0;
- char buf[PATH_MAX] = {0, };
-
- GF_ASSERT (fd > 0);
- GF_ASSERT (volinfo);
-
- snprintf (buf, sizeof (buf), "%d", volinfo->rep_brick.rb_status);
- ret = gf_store_save_value (fd, GLUSTERD_STORE_KEY_RB_STATUS, buf);
- if (ret)
- goto out;
-
- if (volinfo->rep_brick.rb_status > GF_RB_STATUS_NONE) {
-
- snprintf (buf, sizeof (buf), "%s:%s",
- volinfo->rep_brick.src_brick->hostname,
- volinfo->rep_brick.src_brick->path);
- ret = gf_store_save_value (fd, GLUSTERD_STORE_KEY_RB_SRC_BRICK,
- buf);
- if (ret)
- goto out;
-
- snprintf (buf, sizeof (buf), "%s:%s",
- volinfo->rep_brick.dst_brick->hostname,
- volinfo->rep_brick.dst_brick->path);
- ret = gf_store_save_value (fd, GLUSTERD_STORE_KEY_RB_DST_BRICK,
- buf);
- if (ret)
- goto out;
-
- switch (volinfo->transport_type) {
- case GF_TRANSPORT_RDMA:
- port = volinfo->rep_brick.dst_brick->rdma_port;
- break;
-
- case GF_TRANSPORT_TCP:
- case GF_TRANSPORT_BOTH_TCP_RDMA:
- port = volinfo->rep_brick.dst_brick->port;
- break;
- }
-
- snprintf (buf, sizeof (buf), "%d", port);
- ret = gf_store_save_value (fd, GLUSTERD_STORE_KEY_RB_DST_PORT,
- buf);
- if (ret)
- goto out;
- uuid_unparse (volinfo->rep_brick.rb_id, buf);
- ret = gf_store_save_value (fd, GF_REPLACE_BRICK_TID_KEY, buf);
- }
-
- ret = 0;
-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 = gf_store_mkstemp (volinfo->rb_shandle);
- if (fd <= 0) {
- ret = -1;
- goto out;
- }
-
- ret = glusterd_store_rbstate_write (fd, volinfo);
- if (ret)
- goto out;
-
- ret = gf_store_rename_tmppath (volinfo->rb_shandle);
- if (ret)
- goto out;
-
-out:
- if (ret && (fd > 0))
- gf_store_unlink_tmppath (volinfo->rb_shandle);
- gf_log (THIS->name, GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-
-int
-_gd_store_rebalance_dict (dict_t *dict, char *key, data_t *value, void *data)
-{
- int ret = -1;
- int fd = 0;
-
- fd = *(int *)data;
-
- ret = gf_store_save_value (fd, key, value->data);
-
- 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->rebal.defrag_cmd == GF_DEFRAG_CMD_STATUS) {
- ret = 0;
- goto out;
- }
-
- snprintf (buf, sizeof (buf), "%d", volinfo->rebal.defrag_cmd);
- ret = gf_store_save_value (fd, GLUSTERD_STORE_KEY_VOL_DEFRAG, buf);
- if (ret)
- goto out;
-
- snprintf (buf, sizeof (buf), "%d", volinfo->rebal.defrag_status);
- ret = gf_store_save_value (fd, GLUSTERD_STORE_KEY_VOL_DEFRAG_STATUS,
- buf);
- if (ret)
- goto out;
-
-
- snprintf (buf, sizeof (buf), "%d", volinfo->rebal.op);
- ret = gf_store_save_value (fd, GLUSTERD_STORE_KEY_DEFRAG_OP, buf);
- if (ret)
- goto out;
-
- uuid_unparse (volinfo->rebal.rebalance_id, buf);
- ret = gf_store_save_value (fd, GF_REBALANCE_TID_KEY, buf);
- if (ret)
- goto out;
-
- if (volinfo->rebal.dict) {
- dict_foreach (volinfo->rebal.dict, _gd_store_rebalance_dict,
- &fd);
- }
-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 = gf_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 = gf_store_rename_tmppath (volinfo->node_state_shandle);
- if (ret)
- goto out;
-
-out:
- if (ret && (fd > 0))
- gf_store_unlink_tmppath (volinfo->node_state_shandle);
- gf_log (THIS->name, GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-
-int32_t
-glusterd_store_perform_volume_store (glusterd_volinfo_t *volinfo)
-{
- int fd = -1;
- int32_t ret = -1;
- GF_ASSERT (volinfo);
-
- fd = gf_store_mkstemp (volinfo->shandle);
- if (fd <= 0) {
- ret = -1;
- goto out;
- }
-
- ret = glusterd_store_volinfo_write (fd, volinfo);
- if (ret)
- goto out;
-
- ret = glusterd_store_brickinfos (volinfo, fd);
- if (ret)
- goto out;
-
-out:
- if (ret && (fd > 0))
- gf_store_unlink_tmppath (volinfo->shandle);
- gf_log (THIS->name, GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-
-void
-glusterd_perform_volinfo_version_action (glusterd_volinfo_t *volinfo,
- glusterd_volinfo_ver_ac_t ac)
-{
- GF_ASSERT (volinfo);
-
- switch (ac) {
- case GLUSTERD_VOLINFO_VER_AC_NONE:
- break;
- 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) {
- gf_store_unlink_tmppath (brickinfo->shandle);
- }
-}
-
-void
-glusterd_store_volume_cleanup_tmp (glusterd_volinfo_t *volinfo)
-{
- GF_ASSERT (volinfo);
-
- glusterd_store_bricks_cleanup_tmp (volinfo);
-
- gf_store_unlink_tmppath (volinfo->shandle);
-
- gf_store_unlink_tmppath (volinfo->rb_shandle);
-
- gf_store_unlink_tmppath (volinfo->node_state_shandle);
-
- gf_store_unlink_tmppath (volinfo->snapd.handle);
-}
-
-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 = gf_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 = gf_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_snap_atomic_update (glusterd_snap_t *snap)
-{
- int ret = -1;
- GF_ASSERT (snap);
-
- ret = gf_store_rename_tmppath (snap->shandle);
- 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_snap (glusterd_snap_t *snap)
-{
- int32_t ret = -1;
-
- GF_ASSERT (snap);
-
- ret = glusterd_store_create_snap_dir (snap);
- if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR, "Failed to create snap dir");
- goto out;
- }
-
- ret = glusterd_store_create_snap_shandle_on_absence (snap);
- if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR, "Failed to create snap info "
- "file");
- goto out;
- }
-
- ret = glusterd_store_snapinfo_write (snap);
- if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR, "Failed to write snap info");
- goto out;
- }
-
- ret = glusterd_store_snap_atomic_update (snap);
- if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR,"Failed to do automic update");
- goto out;
- }
-
-out:
- if (ret && snap->shandle)
- gf_store_unlink_tmppath (snap->shandle);
-
- gf_log (THIS->name, GF_LOG_TRACE, "Returning %d", ret);
- return ret;
-}
-
-int32_t
-glusterd_store_volinfo (glusterd_volinfo_t *volinfo, glusterd_volinfo_ver_ac_t ac)
-{
- int32_t ret = -1;
-
- GF_ASSERT (volinfo);
-
- glusterd_perform_volinfo_version_action (volinfo, ac);
- ret = glusterd_store_create_volume_dir (volinfo);
- if (ret)
- goto out;
-
- ret = glusterd_store_create_vol_shandle_on_absence (volinfo);
- 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_compute_cksum (volinfo, _gf_false);
- if (ret)
- goto out;
-
-out:
- if (ret)
- glusterd_store_volume_cleanup_tmp (volinfo);
-
- gf_log (THIS->name, GF_LOG_DEBUG, "Returning %d", ret);
-
- return ret;
-}
-
-int32_t
-glusterd_store_delete_volume (glusterd_volinfo_t *volinfo)
-{
- char pathname[PATH_MAX] = {0,};
- int32_t ret = 0;
- glusterd_conf_t *priv = NULL;
- char delete_path[PATH_MAX] = {0,};
- char trashdir[PATH_MAX] = {0,};
- xlator_t *this = NULL;
- gf_boolean_t rename_fail = _gf_false;
-
- this = THIS;
- GF_ASSERT (this);
-
- GF_ASSERT (volinfo);
- priv = this->private;
-
- GF_ASSERT (priv);
-
- GLUSTERD_GET_VOLUME_DIR (pathname, volinfo, priv);
-
- snprintf (delete_path, sizeof (delete_path),
- "%s/"GLUSTERD_TRASH"/%s.deleted", priv->workdir,
- uuid_utoa (volinfo->volume_id));
-
- snprintf (trashdir, sizeof (trashdir), "%s/"GLUSTERD_TRASH,
- priv->workdir);
-
- ret = mkdir (trashdir, 0777);
- if (ret && errno != EEXIST) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to create trash "
- "directory, reason : %s", strerror (errno));
- ret = -1;
- goto out;
- }
-
- ret = rename (pathname, delete_path);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to rename volume "
- "directory for volume %s", volinfo->volname);
- rename_fail = _gf_true;
- goto out;
- }
-
- ret = glusterd_recursive_rmdir (trashdir);
- if (ret) {
- gf_log (this->name, GF_LOG_DEBUG, "Failed to rmdir: %s, Reason:"
- " %s", trashdir, strerror (errno));
- }
-
-out:
- if (volinfo->shandle) {
- gf_store_handle_destroy (volinfo->shandle);
- volinfo->shandle = NULL;
- }
- ret = (rename_fail == _gf_true) ? -1: 0;
-
- gf_log (this->name, GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-
-/*TODO: cleanup the duplicate code and implement a generic function for
- * deleting snap/volume depending on the parameter flag */
-int32_t
-glusterd_store_delete_snap (glusterd_snap_t *snap)
-{
- char pathname[PATH_MAX] = {0,};
- int32_t ret = 0;
- glusterd_conf_t *priv = NULL;
- DIR *dir = NULL;
- struct dirent *entry = NULL;
- char path[PATH_MAX] = {0,};
- char delete_path[PATH_MAX] = {0,};
- char trashdir[PATH_MAX] = {0,};
- struct stat st = {0, };
- xlator_t *this = NULL;
- gf_boolean_t rename_fail = _gf_false;
-
- this = THIS;
- priv = this->private;
- GF_ASSERT (priv);
-
- GF_ASSERT (snap);
- GLUSTERD_GET_SNAP_DIR (pathname, snap, priv);
-
- snprintf (delete_path, sizeof (delete_path),
- "%s/"GLUSTERD_TRASH"/snap-%s.deleted", priv->workdir,
- uuid_utoa (snap->snap_id));
-
- snprintf (trashdir, sizeof (trashdir), "%s/"GLUSTERD_TRASH,
- priv->workdir);
-
- ret = mkdir (trashdir, 0777);
- if (ret && errno != EEXIST) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to create trash "
- "directory, reason : %s", strerror (errno));
- ret = -1;
- goto out;
- }
-
- ret = rename (pathname, delete_path);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to rename snap "
- "directory %s to %s", pathname, delete_path);
- rename_fail = _gf_true;
- goto out;
- }
-
- dir = opendir (delete_path);
- if (!dir) {
- gf_log (this->name, GF_LOG_DEBUG, "Failed to open directory %s."
- " Reason : %s", delete_path, strerror (errno));
- ret = 0;
- goto out;
- }
-
- glusterd_for_each_entry (entry, dir);
- while (entry) {
- snprintf (path, PATH_MAX, "%s/%s", delete_path, entry->d_name);
- ret = stat (path, &st);
- if (ret == -1) {
- gf_log (this->name, GF_LOG_DEBUG, "Failed to stat "
- "entry %s : %s", path, strerror (errno));
- goto stat_failed;
- }
-
- if (S_ISDIR (st.st_mode))
- ret = rmdir (path);
- else
- ret = unlink (path);
-
- if (ret) {
- gf_log (this->name, GF_LOG_DEBUG, " Failed to remove "
- "%s. Reason : %s", path, strerror (errno));
- }
-
- gf_log (this->name, GF_LOG_DEBUG, "%s %s",
- ret ? "Failed to remove":"Removed",
- entry->d_name);
-stat_failed:
- memset (path, 0, sizeof(path));
- glusterd_for_each_entry (entry, dir);
- }
-
- ret = closedir (dir);
- if (ret) {
- gf_log (this->name, GF_LOG_DEBUG, "Failed to close dir %s. "
- "Reason : %s",delete_path, strerror (errno));
- }
-
- ret = rmdir (delete_path);
- if (ret) {
- gf_log (this->name, GF_LOG_DEBUG, "Failed to rmdir: %s,err: %s",
- delete_path, strerror (errno));
- }
- ret = rmdir (trashdir);
- if (ret) {
- gf_log (this->name, GF_LOG_DEBUG, "Failed to rmdir: %s, Reason:"
- " %s", trashdir, strerror (errno));
- }
-
-out:
- if (snap->shandle) {
- gf_store_handle_destroy (snap->shandle);
- snap->shandle = NULL;
- }
- ret = (rename_fail == _gf_true) ? -1: 0;
-
- gf_log (this->name, GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-
-int
-glusterd_store_global_info (xlator_t *this)
-{
- int ret = -1;
- glusterd_conf_t *conf = NULL;
- char op_version_str[15] = {0,};
- char path[PATH_MAX] = {0,};
- gf_store_handle_t *handle = NULL;
- char *uuid_str = NULL;
- char buf[256] = {0, };
-
- conf = this->private;
-
- uuid_str = gf_strdup (uuid_utoa (MY_UUID));
- if (!uuid_str)
- goto out;
-
- if (!conf->handle) {
- snprintf (path, PATH_MAX, "%s/%s", conf->workdir,
- GLUSTERD_INFO_FILE);
- ret = gf_store_handle_new (path, &handle);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Unable to get store handle");
- goto out;
- }
-
- conf->handle = handle;
- } else
- handle = conf->handle;
-
- /* These options need to be available for all 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 = gf_store_mkstemp (handle);
- if (handle->fd <= 0) {
- ret = -1;
- goto out;
- }
-
- ret = gf_store_save_value (handle->fd, GLUSTERD_STORE_UUID_KEY,
- uuid_str);
- if (ret) {
- gf_log (this->name, GF_LOG_CRITICAL,
- "Storing uuid failed ret = %d", ret);
- goto out;
- }
-
- snprintf (op_version_str, 15, "%d", conf->op_version);
- ret = gf_store_save_value (handle->fd, GD_OP_VERSION_KEY,
- op_version_str);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Storing op-version failed ret = %d", ret);
- goto out;
- }
-
- ret = gf_store_rename_tmppath (handle);
-out:
- if (handle) {
- if (ret && (handle->fd > 0))
- gf_store_unlink_tmppath (handle);
-
- if (handle->fd > 0) {
- handle->fd = 0;
- }
- }
-
- if (uuid_str)
- GF_FREE (uuid_str);
-
- if (ret)
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to store glusterd global-info");
-
- return ret;
-}
-
-int
-glusterd_retrieve_op_version (xlator_t *this, int *op_version)
-{
- char *op_version_str = NULL;
- glusterd_conf_t *priv = NULL;
- int ret = -1;
- int tmp_version = 0;
- char *tmp = NULL;
- char path[PATH_MAX] = {0,};
- gf_store_handle_t *handle = NULL;
-
- priv = this->private;
-
- if (!priv->handle) {
- snprintf (path, PATH_MAX, "%s/%s", priv->workdir,
- GLUSTERD_INFO_FILE);
- ret = gf_store_handle_retrieve (path, &handle);
-
- if (ret) {
- gf_log ("", GF_LOG_DEBUG, "Unable to get store "
- "handle!");
- goto out;
- }
-
- priv->handle = handle;
- }
-
- ret = gf_store_retrieve_value (priv->handle, GD_OP_VERSION_KEY,
- &op_version_str);
- if (ret) {
- gf_log (this->name, GF_LOG_DEBUG,
- "No previous op_version present");
- goto out;
- }
-
- tmp_version = strtol (op_version_str, &tmp, 10);
- if ((tmp_version <= 0) || (tmp && strlen (tmp) > 1)) {
- gf_log (this->name, GF_LOG_WARNING, "invalid version number");
- goto out;
- }
-
- *op_version = tmp_version;
-
- ret = 0;
-out:
- if (op_version_str)
- GF_FREE (op_version_str);
-
- return ret;
-}
-
-int
-glusterd_retrieve_sys_snap_max_limit (xlator_t *this, uint64_t *limit,
- char *key)
-{
- char *limit_str = NULL;
- glusterd_conf_t *priv = NULL;
- int ret = -1;
- uint64_t tmp_limit = 0;
- char *tmp = NULL;
- char path[PATH_MAX] = {0,};
- gf_store_handle_t *handle = NULL;
-
- GF_ASSERT (this);
- priv = this->private;
-
- GF_ASSERT (priv);
- GF_ASSERT (limit);
- GF_ASSERT (key);
-
- if (!priv->handle) {
- snprintf (path, PATH_MAX, "%s/%s", priv->workdir,
- GLUSTERD_INFO_FILE);
- ret = gf_store_handle_retrieve (path, &handle);
-
- if (ret) {
- gf_log ("", GF_LOG_DEBUG, "Unable to get store "
- "handle!");
- goto out;
- }
-
- priv->handle = handle;
- }
-
- ret = gf_store_retrieve_value (priv->handle,
- key,
- &limit_str);
- if (ret) {
- gf_log (this->name, GF_LOG_DEBUG,
- "No previous %s present", key);
- goto out;
- }
-
- tmp_limit = strtoul (limit_str, &tmp, 10);
- if ((tmp_limit <= 0) || (tmp && strlen (tmp) > 1)) {
- gf_log (this->name, GF_LOG_WARNING, "invalid version number");
- goto out;
- }
-
- *limit = tmp_limit;
-
- ret = 0;
-out:
- if (limit_str)
- GF_FREE (limit_str);
-
- return ret;
-}
-static int
-glusterd_restore_op_version (xlator_t *this)
-{
- glusterd_conf_t *conf = NULL;
- int ret = 0;
- int op_version = 0;
-
- conf = this->private;
-
- ret = glusterd_retrieve_op_version (this, &op_version);
- if (!ret) {
- if ((op_version < GD_OP_VERSION_MIN) ||
- (op_version > GD_OP_VERSION_MAX)) {
- gf_log (this->name, GF_LOG_ERROR,
- "wrong op-version (%d) retrieved", op_version);
- ret = -1;
- goto out;
- }
- conf->op_version = op_version;
- gf_log ("glusterd", GF_LOG_INFO,
- "retrieved op-version: %d", conf->op_version);
- goto out;
- }
-
- /* op-version can be missing from the store file in 2 cases,
- * 1. This is a new install of glusterfs
- * 2. This is an upgrade of glusterfs from a version without op-version
- * to a version with op-version (eg. 3.3 -> 3.4)
- *
- * Detection of a new install or an upgrade from an older install can be
- * done by checking for the presence of the its peer-id in the store
- * file. If peer-id is present, the installation is an upgrade else, it
- * is a new install.
- *
- * For case 1, set op-version to GD_OP_VERSION_MAX.
- * For case 2, set op-version to GD_OP_VERSION_MIN.
- */
- ret = glusterd_retrieve_uuid();
- if (ret) {
- gf_log (this->name, GF_LOG_INFO, "Detected new install. Setting"
- " op-version to maximum : %d", GD_OP_VERSION_MAX);
- conf->op_version = GD_OP_VERSION_MAX;
- } else {
- gf_log (this->name, GF_LOG_INFO, "Upgrade detected. Setting"
- " op-version to minimum : %d", GD_OP_VERSION_MIN);
- conf->op_version = GD_OP_VERSION_MIN;
- }
- ret = 0;
-out:
- return ret;
-}
-
-int32_t
-glusterd_retrieve_uuid ()
-{
- char *uuid_str = NULL;
- int32_t ret = -1;
- gf_store_handle_t *handle = NULL;
- glusterd_conf_t *priv = NULL;
- char path[PATH_MAX] = {0,};
-
- priv = THIS->private;
-
- if (!priv->handle) {
- snprintf (path, PATH_MAX, "%s/%s", priv->workdir,
- GLUSTERD_INFO_FILE);
- ret = gf_store_handle_retrieve (path, &handle);
-
- if (ret) {
- gf_log ("", GF_LOG_DEBUG, "Unable to get store"
- "handle!");
- goto out;
- }
-
- priv->handle = handle;
- }
-
- ret = gf_store_retrieve_value (priv->handle, GLUSTERD_STORE_UUID_KEY,
- &uuid_str);
-
- if (ret) {
- gf_log ("", GF_LOG_DEBUG, "No previous uuid is present");
- goto out;
- }
-
- uuid_parse (uuid_str, priv->uuid);
-
-out:
- GF_FREE (uuid_str);
- gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-
-int
-glusterd_store_retrieve_snapd (glusterd_volinfo_t *volinfo)
-{
- int ret = -1;
- int exists = 0;
- char *key = NULL;
- char *value = NULL;
- char volpath[PATH_MAX] = {0,};
- char path[PATH_MAX] = {0,};
- xlator_t *this = NULL;
- glusterd_conf_t *conf = NULL;
- gf_store_iter_t *iter = NULL;
- gf_store_op_errno_t op_errno = GD_STORE_SUCCESS;
-
- this = THIS;
- GF_ASSERT (this);
- conf = THIS->private;
- GF_ASSERT (volinfo);
-
- if (conf->op_version < GD_OP_VERSION_3_6_0) {
- ret = 0;
- goto out;
- }
-
- /*
- * This is needed for upgrade situations. Say a volume is created with
- * older version of glusterfs and upgraded to a glusterfs version equal
- * to or greater than GD_OP_VERSION_3_6_0. The older glusterd would not
- * have created the snapd.info file related to snapshot daemon for user
- * serviceable snapshots. So as part of upgrade when the new glusterd
- * starts, as part of restore (restoring the volume to be precise), it
- * tries to snapd related info from snapd.info file. But since there was
- * no such file till now, the restore operation fails. Thus, to prevent
- * it from happening check whether user serviceable snapshots features
- * is enabled before restoring snapd. If its disbaled, then simply
- * exit by returning success (without even checking for the snapd.info).
- */
-
- if (!dict_get_str_boolean (volinfo->dict, "features.uss", _gf_false)) {
- ret = 0;
- goto out;
- }
-
- GLUSTERD_GET_VOLUME_DIR(volpath, volinfo, conf);
-
- snprintf (path, sizeof (path), "%s/%s", volpath,
- GLUSTERD_VOLUME_SNAPD_INFO_FILE);
-
- ret = gf_store_handle_retrieve (path, &volinfo->snapd.handle);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "volinfo handle is NULL");
- goto out;
- }
-
- ret = gf_store_iter_new (volinfo->snapd.handle, &iter);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to get new store "
- "iter");
- goto out;
- }
-
- ret = gf_store_iter_get_next (iter, &key, &value, &op_errno);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to get next store "
- "iter");
- goto out;
- }
-
- while (!ret) {
- if (!strncmp (key, GLUSTERD_STORE_KEY_SNAPD_PORT,
- strlen (GLUSTERD_STORE_KEY_SNAPD_PORT))) {
- volinfo->snapd.port = atoi (value);
- }
-
- ret = gf_store_iter_get_next (iter, &key, &value,
- &op_errno);
- }
-
- if (op_errno != GD_STORE_EOF)
- goto out;
-
- ret = gf_store_iter_destroy (iter);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to destroy store "
- "iter");
- goto out;
- }
-
- ret = 0;
-
-out:
- return ret;
-}
-
-int32_t
-glusterd_store_retrieve_bricks (glusterd_volinfo_t *volinfo)
-{
- int32_t ret = 0;
- glusterd_brickinfo_t *brickinfo = NULL;
- gf_store_iter_t *iter = NULL;
- char *key = NULL;
- char *value = NULL;
- char brickdir[PATH_MAX] = {0,};
- char path[PATH_MAX] = {0,};
- glusterd_conf_t *priv = NULL;
- int32_t brick_count = 0;
- char tmpkey[4096] = {0,};
- gf_store_iter_t *tmpiter = NULL;
- char *tmpvalue = NULL;
- struct pmap_registry *pmap = NULL;
- int brickid = 0;
- gf_store_op_errno_t op_errno = GD_STORE_SUCCESS;
-
- GF_ASSERT (volinfo);
- GF_ASSERT (volinfo->volname);
-
- priv = THIS->private;
-
- GLUSTERD_GET_BRICK_DIR (brickdir, volinfo, priv);
-
- ret = gf_store_iter_new (volinfo->shandle, &tmpiter);
-
- if (ret)
- goto out;
-
- while (brick_count < volinfo->brick_count) {
- ret = glusterd_brickinfo_new (&brickinfo);
-
- if (ret)
- goto out;
- snprintf (tmpkey, sizeof (tmpkey), "%s-%d",
- GLUSTERD_STORE_KEY_VOL_BRICK,brick_count);
- ret = gf_store_iter_get_matching (tmpiter, tmpkey, &tmpvalue);
- snprintf (path, sizeof (path), "%s/%s", brickdir, tmpvalue);
-
- GF_FREE (tmpvalue);
-
- tmpvalue = NULL;
-
- ret = gf_store_handle_retrieve (path, &brickinfo->shandle);
-
- if (ret)
- goto out;
-
- ret = gf_store_iter_new (brickinfo->shandle, &iter);
-
- if (ret)
- goto out;
-
- ret = gf_store_iter_get_next (iter, &key, &value, &op_errno);
- if (ret) {
- gf_log ("glusterd", GF_LOG_ERROR, "Unable to iterate "
- "the store for brick: %s, reason: %s", path,
- gf_store_strerror (op_errno));
- goto out;
- }
- while (!ret) {
- if (!strncmp (key, GLUSTERD_STORE_KEY_BRICK_HOSTNAME,
- strlen (GLUSTERD_STORE_KEY_BRICK_HOSTNAME))) {
- strncpy (brickinfo->hostname, value, 1024);
- } else if (!strncmp (key, GLUSTERD_STORE_KEY_BRICK_PATH,
- strlen (GLUSTERD_STORE_KEY_BRICK_PATH))) {
- strncpy (brickinfo->path, value,
- sizeof (brickinfo->path));
- } else if (!strncmp (key, GLUSTERD_STORE_KEY_BRICK_PORT,
- strlen (GLUSTERD_STORE_KEY_BRICK_PORT))) {
- gf_string2int (value, &brickinfo->port);
-
- if (brickinfo->port < priv->base_port) {
- /* 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 < priv->base_port) {
- /* 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);
- } else if (!strncmp (key, GLUSTERD_STORE_KEY_BRICK_DEVICE_PATH,
- strlen (GLUSTERD_STORE_KEY_BRICK_DEVICE_PATH))) {
- strncpy (brickinfo->device_path, value,
- sizeof (brickinfo->device_path));
- } else if (!strncmp (key, GLUSTERD_STORE_KEY_BRICK_MOUNT_DIR,
- strlen (GLUSTERD_STORE_KEY_BRICK_MOUNT_DIR))) {
- strncpy (brickinfo->mount_dir, value,
- sizeof (brickinfo->mount_dir));
- } else if (!strncmp (key, GLUSTERD_STORE_KEY_BRICK_SNAP_STATUS,
- strlen (GLUSTERD_STORE_KEY_BRICK_SNAP_STATUS))) {
- gf_string2int (value, &brickinfo->snap_status);
- } else if (!strncmp (key, GLUSTERD_STORE_KEY_BRICK_FSTYPE,
- strlen (GLUSTERD_STORE_KEY_BRICK_FSTYPE))) {
- strncpy (brickinfo->fstype, value,
- sizeof (brickinfo->fstype));
- } else if (!strncmp (key, GLUSTERD_STORE_KEY_BRICK_MNTOPTS,
- strlen (GLUSTERD_STORE_KEY_BRICK_MNTOPTS))) {
- strncpy (brickinfo->mnt_opts, value,
- sizeof (brickinfo->mnt_opts));
- } else if (!strncmp (key,
- GLUSTERD_STORE_KEY_BRICK_VGNAME,
- strlen (GLUSTERD_STORE_KEY_BRICK_VGNAME))) {
- strncpy (brickinfo->vg, value,
- sizeof (brickinfo->vg));
- } else if (!strcmp(key, GLUSTERD_STORE_KEY_BRICK_ID)) {
- strncpy (brickinfo->brick_id, value,
- sizeof (brickinfo->brick_id));
- } else {
- gf_log ("", GF_LOG_ERROR, "Unknown key: %s",
- key);
- }
-
- GF_FREE (key);
- GF_FREE (value);
- key = NULL;
- value = NULL;
-
- ret = gf_store_iter_get_next (iter, &key, &value,
- &op_errno);
- }
-
- if (op_errno != GD_STORE_EOF) {
- gf_log ("", GF_LOG_ERROR, "Error parsing brickinfo: "
- "op_errno=%d", op_errno);
- goto out;
- }
- ret = gf_store_iter_destroy (iter);
-
- if (ret)
- goto out;
-
- if (brickinfo->brick_id[0] == '\0') {
- /* This is an old volume upgraded to op_version 4 */
- GLUSTERD_ASSIGN_BRICKID_TO_BRICKINFO (brickinfo, volinfo,
- brickid++);
- }
-
- list_add_tail (&brickinfo->brick_list, &volinfo->bricks);
- brick_count++;
- }
-
- ret = gf_store_iter_destroy (tmpiter);
- if (ret)
- goto out;
-out:
- gf_log ("", GF_LOG_DEBUG, "Returning with %d", ret);
-
- return ret;
-}
-
-
-int32_t
-glusterd_store_retrieve_rbstate (glusterd_volinfo_t *volinfo)
-{
- int32_t ret = -1;
- gf_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,};
- gf_store_op_errno_t op_errno = GD_STORE_SUCCESS;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- priv = this->private;
- GF_ASSERT (priv);
- GF_ASSERT (volinfo);
-
- GLUSTERD_GET_VOLUME_DIR(volpath, volinfo, priv);
- snprintf (path, sizeof (path), "%s/%s", volpath,
- GLUSTERD_VOLUME_RBSTATE_FILE);
-
- ret = gf_store_handle_retrieve (path, &volinfo->rb_shandle);
-
- if (ret)
- goto out;
-
- ret = gf_store_iter_new (volinfo->rb_shandle, &iter);
-
- if (ret)
- goto out;
-
- ret = gf_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->rep_brick.rb_status = atoi (value);
- }
-
- if (volinfo->rep_brick.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->rep_brick.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->rep_brick.dst_brick);
- if (ret)
- goto out;
- } else if (!strncmp (key, GLUSTERD_STORE_KEY_RB_DST_PORT,
- strlen (GLUSTERD_STORE_KEY_RB_DST_PORT))) {
- switch (volinfo->transport_type) {
- case GF_TRANSPORT_RDMA:
- volinfo->rep_brick.dst_brick->rdma_port =
- atoi (value);
- break;
-
- case GF_TRANSPORT_TCP:
- case GF_TRANSPORT_BOTH_TCP_RDMA:
- volinfo->rep_brick.dst_brick->port =
- atoi (value);
- break;
- }
- } else if (!strncmp (key, GF_REPLACE_BRICK_TID_KEY,
- strlen (GF_REPLACE_BRICK_TID_KEY))) {
- uuid_parse (value,
- volinfo->rep_brick.rb_id);
- }
- }
-
- GF_FREE (key);
- GF_FREE (value);
- key = NULL;
- value = NULL;
-
- ret = gf_store_iter_get_next (iter, &key, &value, &op_errno);
- }
-
- if (op_errno != GD_STORE_EOF)
- goto out;
-
- ret = gf_store_iter_destroy (iter);
-
- if (ret)
- goto out;
-
-out:
- gf_log (this->name, GF_LOG_TRACE, "Returning with %d", ret);
-
- return ret;
-}
-
-int32_t
-glusterd_store_retrieve_node_state (glusterd_volinfo_t *volinfo)
-{
- int32_t ret = -1;
- gf_store_iter_t *iter = NULL;
- char *key = NULL;
- char *value = NULL;
- char *dup_value = NULL;
- char volpath[PATH_MAX] = {0,};
- glusterd_conf_t *priv = NULL;
- char path[PATH_MAX] = {0,};
- gf_store_op_errno_t op_errno = GD_STORE_SUCCESS;
- dict_t *tmp_dict = NULL;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- priv = this->private;
- GF_ASSERT (priv);
- GF_ASSERT (volinfo);
-
- GLUSTERD_GET_VOLUME_DIR(volpath, volinfo, priv);
- snprintf (path, sizeof (path), "%s/%s", volpath,
- GLUSTERD_NODE_STATE_FILE);
-
- ret = gf_store_handle_retrieve (path, &volinfo->node_state_shandle);
- if (ret)
- goto out;
-
- ret = gf_store_iter_new (volinfo->node_state_shandle, &iter);
-
- if (ret)
- goto out;
-
- ret = gf_store_iter_get_next (iter, &key, &value, &op_errno);
- if (ret)
- goto out;
-
- while (ret == 0) {
- if (!strncmp (key, GLUSTERD_STORE_KEY_VOL_DEFRAG,
- strlen (GLUSTERD_STORE_KEY_VOL_DEFRAG))) {
- volinfo->rebal.defrag_cmd = atoi (value);
- } else if (!strncmp (key, GLUSTERD_STORE_KEY_VOL_DEFRAG_STATUS,
- strlen (GLUSTERD_STORE_KEY_VOL_DEFRAG_STATUS))) {
- volinfo->rebal.defrag_status = atoi (value);
- } else if (!strncmp (key, GF_REBALANCE_TID_KEY,
- strlen (GF_REBALANCE_TID_KEY))) {
- uuid_parse (value, volinfo->rebal.rebalance_id);
- } else if (!strncmp (key, GLUSTERD_STORE_KEY_DEFRAG_OP,
- strlen (GLUSTERD_STORE_KEY_DEFRAG_OP))) {
- volinfo->rebal.op = atoi (value);
- } else {
- if (!tmp_dict) {
- tmp_dict = dict_new ();
- if (!tmp_dict) {
- ret = -1;
- goto out;
- }
- }
- dup_value = gf_strdup (value);
- if (!dup_value) {
- ret = -1;
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to strdup value string");
- goto out;
- }
- ret = dict_set_str (tmp_dict, key, dup_value);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Error setting data in rebal "
- "dict.");
- goto out;
- }
- dup_value = NULL;
- }
-
- GF_FREE (key);
- GF_FREE (value);
- key = NULL;
- value = NULL;
-
- ret = gf_store_iter_get_next (iter, &key, &value, &op_errno);
- }
- if (tmp_dict)
- volinfo->rebal.dict = dict_ref (tmp_dict);
-
- if (op_errno != GD_STORE_EOF) {
- ret = -1;
- goto out;
- }
-
- ret = gf_store_iter_destroy (iter);
-
- if (ret)
- goto out;
-
-out:
- if (dup_value)
- GF_FREE (dup_value);
- if (ret && volinfo->rebal.dict)
- dict_unref (volinfo->rebal.dict);
- if (tmp_dict)
- dict_unref (tmp_dict);
-
- gf_log (this->name, GF_LOG_TRACE, "Returning with %d", ret);
-
- return ret;
-}
-
-
-int
-glusterd_store_update_volinfo (glusterd_volinfo_t *volinfo)
-{
- int ret = -1;
- int exists = 0;
- char *key = NULL;
- char *value = NULL;
- char volpath[PATH_MAX] = {0,};
- char path[PATH_MAX] = {0,};
- xlator_t *this = NULL;
- glusterd_conf_t *conf = NULL;
- gf_store_iter_t *iter = NULL;
- gf_store_op_errno_t op_errno = GD_STORE_SUCCESS;
-
- this = THIS;
- GF_ASSERT (this);
- conf = THIS->private;
- GF_ASSERT (volinfo);
-
- GLUSTERD_GET_VOLUME_DIR(volpath, volinfo, conf);
-
- snprintf (path, sizeof (path), "%s/%s", volpath,
- GLUSTERD_VOLUME_INFO_FILE);
-
- ret = gf_store_handle_retrieve (path, &volinfo->shandle);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "volinfo handle is NULL");
- goto out;
- }
-
- ret = gf_store_iter_new (volinfo->shandle, &iter);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to get new store "
- "iter");
- goto out;
- }
-
- ret = gf_store_iter_get_next (iter, &key, &value, &op_errno);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to get next store "
- "iter");
- goto out;
- }
-
- while (!ret) {
- gf_log ("", GF_LOG_DEBUG, "key = %s value = %s", key, value);
- if (!strncmp (key, GLUSTERD_STORE_KEY_VOL_TYPE,
- 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))) {
- volinfo->brick_count = atoi (value);
- } else if (!strncmp (key, 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))) {
- volinfo->version = atoi (value);
- } else if (!strncmp (key, 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))) {
- 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_DISPERSE_CNT,
- strlen (GLUSTERD_STORE_KEY_VOL_DISPERSE_CNT))) {
- volinfo->disperse_count = atoi (value);
- } else if (!strncmp (key, GLUSTERD_STORE_KEY_VOL_REDUNDANCY_CNT,
- strlen (GLUSTERD_STORE_KEY_VOL_REDUNDANCY_CNT))) {
- volinfo->redundancy_count = atoi (value);
- } else if (!strncmp (key, GLUSTERD_STORE_KEY_VOL_TRANSPORT,
- strlen (GLUSTERD_STORE_KEY_VOL_TRANSPORT))) {
- volinfo->transport_type = atoi (value);
- } else if (!strncmp (key, 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));
- if (ret) {
- gf_log ("",GF_LOG_ERROR, "Error in "
- "dict_set_str");
- goto out;
- }
- gf_log ("", GF_LOG_DEBUG, "Parsed as "GEOREP" "
- " slave:key=%s,value:%s", key, value);
-
- } else if (!strncmp (key, GLUSTERD_STORE_KEY_VOL_OP_VERSION,
- strlen (GLUSTERD_STORE_KEY_VOL_OP_VERSION))) {
- volinfo->op_version = atoi (value);
- } else if (!strncmp (key, GLUSTERD_STORE_KEY_VOL_CLIENT_OP_VERSION,
- strlen (GLUSTERD_STORE_KEY_VOL_CLIENT_OP_VERSION))) {
- volinfo->client_op_version = atoi (value);
- } else if (!strncmp (key, GLUSTERD_STORE_KEY_VOL_CAPS,
- strlen (GLUSTERD_STORE_KEY_VOL_CAPS))) {
- volinfo->caps = atoi (value);
- } else if (!strncmp (key, GLUSTERD_STORE_KEY_SNAP_MAX_HARD_LIMIT,
- strlen (GLUSTERD_STORE_KEY_SNAP_MAX_HARD_LIMIT))) {
- volinfo->snap_max_hard_limit = (uint64_t) atoll (value);
- } else if (!strncmp (key, GLUSTERD_STORE_KEY_VOL_RESTORED_SNAP,
- strlen (GLUSTERD_STORE_KEY_VOL_RESTORED_SNAP))) {
- ret = uuid_parse (value, volinfo->restored_from_snap);
- if (ret)
- gf_log (this->name, GF_LOG_WARNING,
- "failed to parse restored snap's uuid");
- } else if (!strncmp (key, GLUSTERD_STORE_KEY_PARENT_VOLNAME,
- strlen (GLUSTERD_STORE_KEY_PARENT_VOLNAME))) {
- strncpy (volinfo->parent_volname, value,
- sizeof(volinfo->parent_volname) - 1);
- } else {
-
- if (is_key_glusterd_hooks_friendly (key)) {
- exists = 1;
-
- } else {
- exists = glusterd_check_option_exists (key,
- NULL);
- }
-
- switch (exists) {
- case -1:
- ret = -1;
- goto out;
-
- case 0:
- /*Ignore GLUSTERD_STORE_KEY_VOL_BRICK since
- glusterd_store_retrieve_bricks gets it later*/
- if (!strstr (key, GLUSTERD_STORE_KEY_VOL_BRICK))
- gf_log ("", GF_LOG_WARNING,
- "Unknown key: %s", key);
- break;
-
- case 1:
- /*The following strcmp check is to ensure that
- * glusterd does not restore the quota limits
- * into volinfo->dict post upgradation from 3.3
- * to 3.4 as the same limits will now be stored
- * in xattrs on the respective directories.
- */
- if (!strcmp (key, "features.limit-usage"))
- break;
- ret = dict_set_str(volinfo->dict, key,
- gf_strdup (value));
- if (ret) {
- gf_log ("",GF_LOG_ERROR, "Error in "
- "dict_set_str");
- goto out;
- }
- gf_log ("", GF_LOG_DEBUG, "Parsed as Volume-"
- "set:key=%s,value:%s", key, value);
- break;
- }
- }
-
- GF_FREE (key);
- GF_FREE (value);
- key = NULL;
- value = NULL;
-
- ret = gf_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;
-
- case GF_CLUSTER_TYPE_DISPERSE:
- GF_ASSERT (volinfo->disperse_count > 0);
- GF_ASSERT (volinfo->redundancy_count > 0);
- break;
-
- default:
- GF_ASSERT (0);
- break;
- }
-
- volinfo->dist_leaf_count = glusterd_get_dist_leaf_count (volinfo);
-
- volinfo->subvol_count = (volinfo->brick_count /
- volinfo->dist_leaf_count);
-
- /* Only calculate volume op-versions if they are not found */
- if (!volinfo->op_version && !volinfo->client_op_version)
- gd_update_volume_op_versions (volinfo);
- }
-
- if (op_errno != GD_STORE_EOF)
- goto out;
-
- ret = gf_store_iter_destroy (iter);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to destroy store "
- "iter");
- goto out;
- }
-
- ret = 0;
-out:
- return ret;
-}
-
-glusterd_volinfo_t*
-glusterd_store_retrieve_volume (char *volname, glusterd_snap_t *snap)
-{
- int32_t ret = -1;
- glusterd_volinfo_t *volinfo = NULL;
- glusterd_volinfo_t *origin_volinfo = NULL;
- glusterd_conf_t *priv = NULL;
- xlator_t *this = NULL;
-
-
- this = THIS;
- GF_ASSERT (this);
- priv = this->private;
- GF_ASSERT (priv);
- GF_ASSERT (volname);
-
- ret = glusterd_volinfo_new (&volinfo);
- if (ret)
- goto out;
-
- strncpy (volinfo->volname, volname, GD_VOLUME_NAME_MAX);
- volinfo->snapshot = snap;
- if (snap)
- volinfo->is_snap_volume = _gf_true;
-
- ret = glusterd_store_update_volinfo (volinfo);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to update volinfo "
- "for %s volume", volname);
- goto out;
- }
-
- ret = glusterd_store_retrieve_bricks (volinfo);
- if (ret)
- goto out;
-
- ret = glusterd_store_retrieve_snapd (volinfo);
- if (ret)
- goto out;
-
- ret = glusterd_compute_cksum (volinfo, _gf_false);
- if (ret)
- goto out;
-
- ret = glusterd_store_retrieve_quota_version (volinfo);
- if (ret)
- goto out;
-
- ret = glusterd_store_create_quota_conf_sh_on_absence (volinfo);
- if (ret)
- goto out;
-
- ret = glusterd_compute_cksum (volinfo, _gf_true);
- if (ret)
- goto out;
-
- ret = glusterd_store_save_quota_version_and_cksum (volinfo);
- if (ret)
- goto out;
-
-
- if (!snap) {
- list_add_order (&volinfo->vol_list, &priv->volumes,
- glusterd_compare_volume_name);
- } else {
- ret = glusterd_volinfo_find (volinfo->parent_volname,
- &origin_volinfo);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Parent volinfo "
- "not found for %s volume", volname);
- goto out;
- }
- glusterd_list_add_snapvol (origin_volinfo, volinfo);
- }
-
-out:
- if (ret) {
- if (volinfo)
- glusterd_volinfo_delete (volinfo);
- volinfo = NULL;
- }
-
- gf_log (this->name, GF_LOG_TRACE, "Returning with %d", ret);
-
- return volinfo;
-}
-
-static inline void
-glusterd_store_set_options_path (glusterd_conf_t *conf, char *path, size_t len)
-{
- snprintf (path, len, "%s/options", conf->workdir);
-}
-
-int
-_store_global_opts (dict_t *this, char *key, data_t *value, void *data)
-{
- gf_store_handle_t *shandle = data;
-
- gf_store_save_value (shandle->fd, key, (char*)value->data);
- return 0;
-}
-
-int32_t
-glusterd_store_options (xlator_t *this, dict_t *opts)
-{
- gf_store_handle_t *shandle = NULL;
- glusterd_conf_t *conf = NULL;
- char path[PATH_MAX] = {0};
- int fd = -1;
- int32_t ret = -1;
-
- conf = this->private;
- glusterd_store_set_options_path (conf, path, sizeof (path));
-
- ret = gf_store_handle_new (path, &shandle);
- if (ret)
- goto out;
-
- fd = gf_store_mkstemp (shandle);
- if (fd <= 0) {
- ret = -1;
- goto out;
- }
-
- shandle->fd = fd;
- dict_foreach (opts, _store_global_opts, shandle);
- shandle->fd = 0;
- ret = gf_store_rename_tmppath (shandle);
- if (ret)
- goto out;
-out:
- if ((ret < 0) && (fd > 0))
- gf_store_unlink_tmppath (shandle);
- gf_store_handle_destroy (shandle);
- return ret;
-}
-
-int32_t
-glusterd_store_retrieve_options (xlator_t *this)
-{
- char path[PATH_MAX] = {0};
- glusterd_conf_t *conf = NULL;
- gf_store_handle_t *shandle = NULL;
- gf_store_iter_t *iter = NULL;
- char *key = NULL;
- char *value = NULL;
- gf_store_op_errno_t op_errno = 0;
- int ret = -1;
-
- conf = this->private;
- glusterd_store_set_options_path (conf, path, sizeof (path));
-
- ret = gf_store_handle_retrieve (path, &shandle);
- if (ret)
- goto out;
-
- ret = gf_store_iter_new (shandle, &iter);
- if (ret)
- goto out;
-
- ret = gf_store_iter_get_next (iter, &key, &value, &op_errno);
- while (!ret) {
- ret = dict_set_dynstr (conf->opts, key, value);
- if (ret) {
- GF_FREE (key);
- GF_FREE (value);
- goto out;
- }
- GF_FREE (key);
- key = NULL;
- value = NULL;
-
- ret = gf_store_iter_get_next (iter, &key, &value, &op_errno);
- }
- if (op_errno != GD_STORE_EOF)
- goto out;
- ret = 0;
-out:
- gf_store_iter_destroy (iter);
- gf_store_handle_destroy (shandle);
- return ret;
-}
-
-int32_t
-glusterd_store_retrieve_volumes (xlator_t *this, glusterd_snap_t *snap)
-{
- int32_t ret = -1;
- char path[PATH_MAX] = {0,};
- glusterd_conf_t *priv = NULL;
- DIR *dir = NULL;
- struct dirent *entry = NULL;
- glusterd_volinfo_t *volinfo = NULL;
-
- GF_ASSERT (this);
- priv = this->private;
-
- GF_ASSERT (priv);
-
- if (snap)
- snprintf (path, PATH_MAX, "%s/snaps/%s", priv->workdir,
- snap->snapname);
- else
- snprintf (path, PATH_MAX, "%s/%s", priv->workdir,
- GLUSTERD_VOLUME_DIR_PREFIX);
-
- dir = opendir (path);
-
- if (!dir) {
- gf_log ("", GF_LOG_ERROR, "Unable to open dir %s", path);
- goto out;
- }
-
- glusterd_for_each_entry (entry, dir);
-
- while (entry) {
- if (snap && ((!strcmp (entry->d_name, "geo-replication")) ||
- (!strcmp (entry->d_name, "info"))))
- goto next;
-
- volinfo = glusterd_store_retrieve_volume (entry->d_name, snap);
- if (!volinfo) {
- gf_log ("", GF_LOG_ERROR, "Unable to restore "
- "volume: %s", entry->d_name);
- ret = -1;
- goto out;
- }
-
- ret = glusterd_store_retrieve_rbstate (volinfo);
- if (ret) {
- /* Backward compatibility */
- gf_log ("", GF_LOG_INFO, "Creating a new rbstate "
- "for volume: %s.", entry->d_name);
- ret = glusterd_store_create_rbstate_shandle_on_absence (volinfo);
- ret = glusterd_store_perform_rbstate_store (volinfo);
- }
-
- ret = glusterd_store_retrieve_node_state (volinfo);
- if (ret) {
- /* Backward compatibility */
- gf_log ("", GF_LOG_INFO, "Creating a new node_state "
- "for volume: %s.", entry->d_name);
- glusterd_store_create_nodestate_sh_on_absence (volinfo);
- ret = glusterd_store_perform_node_state_store (volinfo);
-
- }
-next:
- glusterd_for_each_entry (entry, dir);
- }
-
- ret = 0;
-
-out:
- if (dir)
- closedir (dir);
- gf_log ("", GF_LOG_DEBUG, "Returning with %d", ret);
-
- return ret;
-}
-
-/* Figure out the brick mount path, from the brick path */
-int32_t
-glusterd_find_brick_mount_path (char *brick_path, int32_t brick_count,
- char **brick_mount_path)
-{
- char brick_num[PATH_MAX] = "";
- char *ptr = NULL;
- int32_t ret = -1;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (brick_path);
- GF_ASSERT (brick_mount_path);
-
- *brick_mount_path = gf_strdup (brick_path);
- if (!*brick_mount_path) {
- ret = -1;
- goto out;
- }
-
- snprintf (brick_num, sizeof(brick_num), "brick%d", brick_count);
-
- /* Finding the pointer to the end of
- * /var/run/gluster/snaps/<snap-uuid>
- */
- ptr = strstr (*brick_mount_path, brick_num);
- if (!ptr) {
- /* Snapshot bricks must have brick num as part
- * of the brickpath
- */
- gf_log (this->name, GF_LOG_ERROR,
- "Invalid brick path(%s)", brick_path);
- ret = -1;
- goto out;
- }
-
- /* Moving the pointer to the end of
- * /var/run/gluster/snaps/<snap-uuid>/<brick_num>
- * and assigning '\0' to it.
- */
- ptr += strlen(brick_num);
- *ptr = '\0';
-
- ret = 0;
-out:
- if (ret && *brick_mount_path) {
- GF_FREE (*brick_mount_path);
- *brick_mount_path = NULL;
- }
- gf_log (this->name, GF_LOG_TRACE, "Returning with %d", ret);
- return ret;
-}
-
-/* Check if brick_mount_path is already mounted. If not, mount the device_path
- * at the brick_mount_path
- */
-int32_t
-glusterd_mount_brick_paths (char *brick_mount_path,
- glusterd_brickinfo_t *brickinfo)
-{
- int32_t ret = -1;
- runner_t runner = {0, };
- char buff [PATH_MAX] = {0, };
- struct mntent save_entry = {0, };
- struct mntent *entry = NULL;
- xlator_t *this = NULL;
- glusterd_conf_t *priv = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (brick_mount_path);
- GF_ASSERT (brickinfo);
-
- priv = this->private;
- GF_ASSERT (priv);
-
- /* Check if the brick_mount_path is already mounted */
- entry = glusterd_get_mnt_entry_info (brick_mount_path, buff,
- sizeof (buff), &save_entry);
- if (entry) {
- gf_log (this->name, GF_LOG_INFO,
- "brick_mount_path (%s) already mounted.",
- brick_mount_path);
- ret = 0;
- goto out;
- }
-
- /* TODO RHEL 6.5 has the logical volumes inactive by default
- * on reboot. Hence activating the logical vol. Check behaviour
- * on other systems
- */
- /* Activate the snapshot */
- runinit (&runner);
- runner_add_args (&runner, "lvchange", "-ay", brickinfo->device_path,
- NULL);
- ret = runner_run (&runner);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to activate %s. Error: %s",
- brickinfo->device_path, strerror(errno));
- goto out;
- } else
- gf_log (this->name, GF_LOG_DEBUG,
- "Activating %s successful", brickinfo->device_path);
-
- /* Mount the snapshot */
- ret = glusterd_mount_lvm_snapshot (brickinfo, brick_mount_path);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to mount lvm snapshot.");
- goto out;
- }
-
-out:
- gf_log (this->name, GF_LOG_TRACE, "Returning with %d", ret);
- return ret;
-}
-
-static int32_t
-glusterd_recreate_vol_brick_mounts (xlator_t *this,
- glusterd_volinfo_t *volinfo)
-{
- char *brick_mount_path = NULL;
- glusterd_brickinfo_t *brickinfo = NULL;
- int32_t ret = -1;
- int32_t brick_count = -1;
- struct stat st_buf = {0, };
-
- GF_ASSERT (this);
- GF_ASSERT (volinfo);
-
- brick_count = 0;
- list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) {
- brick_count++;
- /* If the brick is not of this node, or its
- * snapshot is pending, or the brick is not
- * a snapshotted brick, we continue
- */
- if ((uuid_compare (brickinfo->uuid, MY_UUID)) ||
- (brickinfo->snap_status == -1) ||
- (strlen(brickinfo->device_path) == 0))
- continue;
-
- /* Fetch the brick mount path from the brickinfo->path */
- ret = glusterd_find_brick_mount_path (brickinfo->path,
- brick_count,
- &brick_mount_path);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to find brick_mount_path for %s",
- brickinfo->path);
- goto out;
- }
-
- /* Check if the brickinfo path is present.
- * If not create the brick_mount_path */
- ret = lstat (brickinfo->path, &st_buf);
- if (ret) {
- if (errno == ENOENT) {
- ret = mkdir_p (brick_mount_path, 0777,
- _gf_true);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to create %s. "
- "Error: %s", brick_mount_path,
- strerror (errno));
- goto out;
- }
- } else {
- gf_log (this->name, GF_LOG_ERROR,
- "Brick Path(%s) not valid. "
- "Error: %s", brickinfo->path,
- strerror(errno));
- goto out;
- }
- }
-
- /* Check if brick_mount_path is already mounted.
- * If not, mount the device_path at the brick_mount_path */
- ret = glusterd_mount_brick_paths (brick_mount_path, brickinfo);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to mount brick_mount_path");
- }
-
- if (brick_mount_path) {
- GF_FREE (brick_mount_path);
- brick_mount_path = NULL;
- }
- }
-
- ret = 0;
-out:
- if (ret && brick_mount_path)
- GF_FREE (brick_mount_path);
-
- gf_log (this->name, GF_LOG_TRACE, "Returning with %d", ret);
- return ret;
-}
-
-int32_t
-glusterd_resolve_snap_bricks (xlator_t *this, glusterd_snap_t *snap)
-{
- int32_t ret = -1;
- glusterd_volinfo_t *volinfo = NULL;
- glusterd_brickinfo_t *brickinfo = NULL;
-
- GF_ASSERT (this);
- GF_VALIDATE_OR_GOTO (this->name, snap, out);
-
- list_for_each_entry (volinfo, &snap->volumes, vol_list) {
- list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) {
- ret = glusterd_resolve_brick (brickinfo);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "resolve brick failed in restore");
- goto out;
- }
- }
- }
-
- ret = 0;
-
-out:
- gf_log (this->name, GF_LOG_TRACE, "Returning with %d", ret);
-
- return ret;
-}
-
-int
-glusterd_store_update_snap (glusterd_snap_t *snap)
-{
- int ret = -1;
- char *key = NULL;
- char *value = NULL;
- char snappath[PATH_MAX] = {0,};
- char path[PATH_MAX] = {0,};
- xlator_t *this = NULL;
- glusterd_conf_t *conf = NULL;
- gf_store_iter_t *iter = NULL;
- gf_store_op_errno_t op_errno = GD_STORE_SUCCESS;
-
- this = THIS;
- conf = this->private;
- GF_ASSERT (snap);
-
- GLUSTERD_GET_SNAP_DIR (snappath, snap, conf);
-
- snprintf (path, sizeof (path), "%s/%s", snappath,
- GLUSTERD_SNAP_INFO_FILE);
-
- ret = gf_store_handle_retrieve (path, &snap->shandle);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "snap handle is NULL");
- goto out;
- }
-
- ret = gf_store_iter_new (snap->shandle, &iter);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to get new store "
- "iter");
- goto out;
- }
-
- ret = gf_store_iter_get_next (iter, &key, &value, &op_errno);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to get next store "
- "iter");
- goto out;
- }
-
- while (!ret) {
- gf_log (this->name, GF_LOG_DEBUG, "key = %s value = %s",
- key, value);
-
- if (!strncmp (key, GLUSTERD_STORE_KEY_SNAP_ID,
- strlen (GLUSTERD_STORE_KEY_SNAP_ID))) {
- ret = uuid_parse (value, snap->snap_id);
- if (ret)
- gf_log (this->name, GF_LOG_WARNING,
- "Failed to parse uuid");
- } else if (!strncmp (key, GLUSTERD_STORE_KEY_SNAP_RESTORED,
- strlen (GLUSTERD_STORE_KEY_SNAP_RESTORED))) {
- snap->snap_restored = atoi (value);
- } else if (!strncmp (key, GLUSTERD_STORE_KEY_SNAP_STATUS,
- strlen (GLUSTERD_STORE_KEY_SNAP_STATUS))) {
- snap->snap_status = atoi (value);
- } else if (!strncmp (key, GLUSTERD_STORE_KEY_SNAP_DESC,
- strlen (GLUSTERD_STORE_KEY_SNAP_DESC))) {
- snap->description = gf_strdup (value);
- } else if (!strncmp (key, GLUSTERD_STORE_KEY_SNAP_TIMESTAMP,
- strlen (GLUSTERD_STORE_KEY_SNAP_TIMESTAMP))) {
- snap->time_stamp = atoi (value);
- }
-
- GF_FREE (key);
- GF_FREE (value);
- key = NULL;
- value = NULL;
-
- ret = gf_store_iter_get_next (iter, &key, &value, &op_errno);
- }
-
- if (op_errno != GD_STORE_EOF)
- goto out;
-
- ret = gf_store_iter_destroy (iter);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to destroy store "
- "iter");
- }
-
-out:
- return ret;
-}
-
-int32_t
-glusterd_store_retrieve_snap (char *snapname)
-{
- int32_t ret = -1;
- glusterd_snap_t *snap = NULL;
- glusterd_conf_t *priv = NULL;
- xlator_t *this = NULL;
-
- this = THIS;
- priv = this->private;
- GF_ASSERT (priv);
- GF_ASSERT (snapname);
-
- snap = glusterd_new_snap_object ();
- if (!snap) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to create "
- " snap object");
- goto out;
- }
-
- strncpy (snap->snapname, snapname, strlen(snapname));
- ret = glusterd_store_update_snap (snap);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to update snapshot "
- "for %s snap", snapname);
- goto out;
- }
-
- ret = glusterd_store_retrieve_volumes (this, snap);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to retrieve "
- "snap volumes for snap %s", snapname);
- goto out;
- }
-
- /* TODO: list_add_order can do 'N-square' comparisions and
- is not efficient. Find a better solution to store the snap
- in order */
- list_add_order (&snap->snap_list, &priv->snapshots,
- glusterd_compare_snap_time);
-
-out:
- gf_log (this->name, GF_LOG_TRACE, "Returning with %d", ret);
- return ret;
-}
-
-/* Read the missed_snap_list and update the in-memory structs */
-int32_t
-glusterd_store_retrieve_missed_snaps_list (xlator_t *this)
-{
- char buf[PATH_MAX] = "";
- char path[PATH_MAX] = "";
- char *snap_vol_id = NULL;
- char *missed_node_info = NULL;
- char *brick_path = NULL;
- char *value = NULL;
- char *save_ptr = NULL;
- FILE *fp = NULL;
- int32_t brick_num = -1;
- int32_t snap_op = -1;
- int32_t snap_status = -1;
- int32_t ret = -1;
- glusterd_conf_t *priv = NULL;
- gf_store_op_errno_t store_errno = GD_STORE_SUCCESS;
-
- GF_ASSERT (this);
- priv = this->private;
- GF_ASSERT (priv);
-
- /* Get the path of the missed_snap_list */
- glusterd_store_missed_snaps_list_path_set (path, sizeof(path));
-
- fp = fopen (path, "r");
- if (!fp) {
- /* If errno is ENOENT then there are no missed snaps yet */
- if (errno != ENOENT) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to open %s. "
- "Error: %s", path, strerror(errno));
- } else {
- gf_log (this->name, GF_LOG_INFO,
- "No missed snaps list.");
- ret = 0;
- }
- goto out;
- }
-
- do {
- ret = gf_store_read_and_tokenize (fp, buf,
- &missed_node_info, &value,
- &store_errno);
- if (ret) {
- if (store_errno == GD_STORE_EOF) {
- gf_log (this->name,
- GF_LOG_DEBUG,
- "EOF for missed_snap_list");
- ret = 0;
- break;
- }
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to fetch data from "
- "missed_snaps_list. Error: %s",
- gf_store_strerror (store_errno));
- goto out;
- }
-
- /* Fetch the brick_num, brick_path, snap_op and snap status */
- snap_vol_id = strtok_r (value, ":", &save_ptr);
- brick_num = atoi(strtok_r (NULL, ":", &save_ptr));
- brick_path = strtok_r (NULL, ":", &save_ptr);
- snap_op = atoi(strtok_r (NULL, ":", &save_ptr));
- snap_status = atoi(strtok_r (NULL, ":", &save_ptr));
-
- if (!missed_node_info || !brick_path || !snap_vol_id ||
- brick_num < 1 || snap_op < 1 ||
- snap_status < 1) {
- gf_log (this->name, GF_LOG_ERROR,
- "Invalid missed_snap_entry");
- ret = -1;
- goto out;
- }
-
- ret = glusterd_add_new_entry_to_list (missed_node_info,
- snap_vol_id,
- brick_num,
- brick_path,
- snap_op,
- snap_status);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to store missed snaps_list");
- goto out;
- }
-
- } while (store_errno == GD_STORE_SUCCESS);
-
- ret = 0;
-out:
- gf_log (this->name, GF_LOG_TRACE, "Returning with %d", ret);
- return ret;
-}
-
-int32_t
-glusterd_store_retrieve_snaps (xlator_t *this)
-{
- 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;
-
- GF_ASSERT (priv);
-
- snprintf (path, PATH_MAX, "%s/snaps", priv->workdir);
-
- dir = opendir (path);
-
- if (!dir) {
- /* If snaps dir doesn't exists ignore the error for
- backward compatibility */
- if (errno != ENOENT) {
- ret = -1;
- gf_log ("", GF_LOG_ERROR, "Unable to open dir %s", path);
- }
- goto out;
- }
-
- glusterd_for_each_entry (entry, dir);
-
- while (entry) {
- if (strcmp (entry->d_name, GLUSTERD_MISSED_SNAPS_LIST_FILE)) {
- ret = glusterd_store_retrieve_snap (entry->d_name);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Unable to restore snapshot: %s",
- entry->d_name);
- goto out;
- }
- }
- glusterd_for_each_entry (entry, dir);
- }
-
- /* Retrieve missed_snaps_list */
- ret = glusterd_store_retrieve_missed_snaps_list (this);
- if (ret) {
- gf_log (this->name, GF_LOG_DEBUG,
- "Failed to retrieve missed_snaps_list");
- goto out;
- }
-
-out:
- if (dir)
- closedir (dir);
- gf_log ("", GF_LOG_DEBUG, "Returning with %d", ret);
-
- return ret;
-}
-
-/* Writes all the contents of conf->missed_snap_list */
-int32_t
-glusterd_store_write_missed_snapinfo (int32_t fd)
-{
- char key[PATH_MAX] = "";
- char value[PATH_MAX] = "";
- int32_t ret = -1;
- glusterd_conf_t *priv = NULL;
- glusterd_missed_snap_info *missed_snapinfo = NULL;
- glusterd_snap_op_t *snap_opinfo = NULL;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT(this);
-
- priv = this->private;
- GF_ASSERT (priv);
-
- /* Write the missed_snap_entry */
- list_for_each_entry (missed_snapinfo, &priv->missed_snaps_list,
- missed_snaps) {
- list_for_each_entry (snap_opinfo,
- &missed_snapinfo->snap_ops,
- snap_ops_list) {
- snprintf (key, sizeof(key), "%s:%s",
- missed_snapinfo->node_uuid,
- missed_snapinfo->snap_uuid);
- snprintf (value, sizeof(value), "%s:%d:%s:%d:%d",
- snap_opinfo->snap_vol_id,
- snap_opinfo->brick_num,
- snap_opinfo->brick_path,
- snap_opinfo->op, snap_opinfo->status);
- ret = gf_store_save_value (fd, key, value);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to write missed snapinfo");
- goto out;
- }
- }
- }
-
- ret = 0;
-out:
- gf_log (this->name, GF_LOG_TRACE, "Returning %d", ret);
- return ret;
-}
-
-/* Adds the missed snap entries to the in-memory conf->missed_snap_list *
- * and writes them to disk */
-int32_t
-glusterd_store_update_missed_snaps ()
-{
- int32_t fd = -1;
- int32_t ret = -1;
- glusterd_conf_t *priv = NULL;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT(this);
-
- priv = this->private;
- GF_ASSERT (priv);
-
- ret = glusterd_store_create_missed_snaps_list_shandle_on_absence ();
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Unable to obtain "
- "missed_snaps_list store handle.");
- goto out;
- }
-
- fd = gf_store_mkstemp (priv->missed_snaps_list_shandle);
- if (fd <= 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to create tmp file");
- ret = -1;
- goto out;
- }
-
- ret = glusterd_store_write_missed_snapinfo (fd);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to write missed snaps to disk");
- goto out;
- }
-
- ret = gf_store_rename_tmppath (priv->missed_snaps_list_shandle);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to rename the tmp file");
- goto out;
- }
-out:
- if (ret && (fd > 0)) {
- ret = gf_store_unlink_tmppath (priv->missed_snaps_list_shandle);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to unlink the tmp file");
- }
- ret = -1;
- }
-
- gf_log (this->name, GF_LOG_TRACE, "Returning %d", ret);
- return ret;
-}
-
-int32_t
-glusterd_store_delete_peerinfo (glusterd_peerinfo_t *peerinfo)
-{
- int32_t ret = -1;
- glusterd_conf_t *priv = NULL;
- char peerdir[PATH_MAX] = {0,};
- char filepath[PATH_MAX] = {0,};
- char hostname_path[PATH_MAX] = {0,};
-
-
- if (!peerinfo) {
- ret = 0;
- goto out;
- }
-
- priv = THIS->private;
-
- snprintf (peerdir, PATH_MAX, "%s/peers", priv->workdir);
-
-
- if (uuid_is_null (peerinfo->uuid)) {
-
- if (peerinfo->hostname) {
- snprintf (filepath, PATH_MAX, "%s/%s", peerdir,
- peerinfo->hostname);
- } else {
- ret = 0;
- goto out;
- }
- } else {
-
- snprintf (filepath, PATH_MAX, "%s/%s", peerdir,
- uuid_utoa (peerinfo->uuid));
- snprintf (hostname_path, PATH_MAX, "%s/%s",
- peerdir, peerinfo->hostname);
-
- ret = unlink (hostname_path);
-
- if (!ret)
- goto out;
- }
-
- ret = unlink (filepath);
- if (ret && (errno == ENOENT))
- ret = 0;
-
-out:
- if (peerinfo->shandle) {
- gf_store_handle_destroy (peerinfo->shandle);
- peerinfo->shandle = NULL;
- }
- gf_log ("", GF_LOG_DEBUG, "Returning with %d", ret);
-
- return ret;
-}
-
-void
-glusterd_store_peerinfo_dirpath_set (char *path, size_t len)
-{
- glusterd_conf_t *priv = NULL;
- GF_ASSERT (path);
- GF_ASSERT (len >= PATH_MAX);
-
- priv = THIS->private;
- snprintf (path, len, "%s/peers", priv->workdir);
-}
-
-int32_t
-glusterd_store_create_peer_dir ()
-{
- int32_t ret = 0;
- char path[PATH_MAX];
-
- glusterd_store_peerinfo_dirpath_set (path, sizeof (path));
- ret = gf_store_mkdir (path);
-
- gf_log ("", GF_LOG_DEBUG, "Returning with %d", ret);
- return ret;
-}
-
-static void
-glusterd_store_uuid_peerpath_set (glusterd_peerinfo_t *peerinfo, char *peerfpath,
- size_t len)
-{
- char peerdir[PATH_MAX];
- char str[50] = {0};
-
- GF_ASSERT (peerinfo);
- GF_ASSERT (peerfpath);
- GF_ASSERT (len >= PATH_MAX);
-
- glusterd_store_peerinfo_dirpath_set (peerdir, sizeof (peerdir));
- uuid_unparse (peerinfo->uuid, str);
- snprintf (peerfpath, len, "%s/%s", peerdir, str);
-}
-
-static void
-glusterd_store_hostname_peerpath_set (glusterd_peerinfo_t *peerinfo,
- char *peerfpath, size_t len)
-{
- char peerdir[PATH_MAX];
-
- GF_ASSERT (peerinfo);
- GF_ASSERT (peerfpath);
- GF_ASSERT (len >= PATH_MAX);
-
- glusterd_store_peerinfo_dirpath_set (peerdir, sizeof (peerdir));
- snprintf (peerfpath, len, "%s/%s", peerdir, peerinfo->hostname);
-}
-
-int32_t
-glusterd_store_peerinfo_hostname_shandle_create (glusterd_peerinfo_t *peerinfo)
-{
- char peerfpath[PATH_MAX];
- int32_t ret = -1;
-
- glusterd_store_hostname_peerpath_set (peerinfo, peerfpath,
- sizeof (peerfpath));
- ret = gf_store_handle_create_on_absence (&peerinfo->shandle,
- peerfpath);
- return ret;
-}
-
-int32_t
-glusterd_store_peerinfo_uuid_shandle_create (glusterd_peerinfo_t *peerinfo)
-{
- char peerfpath[PATH_MAX];
- int32_t ret = -1;
-
- glusterd_store_uuid_peerpath_set (peerinfo, peerfpath,
- sizeof (peerfpath));
- ret = gf_store_handle_create_on_absence (&peerinfo->shandle,
- peerfpath);
- return ret;
-}
-
-int32_t
-glusterd_peerinfo_hostname_shandle_check_destroy (glusterd_peerinfo_t *peerinfo)
-{
- char peerfpath[PATH_MAX];
- int32_t ret = -1;
- struct stat stbuf = {0,};
-
- glusterd_store_hostname_peerpath_set (peerinfo, peerfpath,
- sizeof (peerfpath));
- ret = stat (peerfpath, &stbuf);
- if (!ret) {
- if (peerinfo->shandle)
- gf_store_handle_destroy (peerinfo->shandle);
- peerinfo->shandle = NULL;
- ret = unlink (peerfpath);
- }
- return ret;
-}
-
-int32_t
-glusterd_store_create_peer_shandle (glusterd_peerinfo_t *peerinfo)
-{
- int32_t ret = 0;
-
- GF_ASSERT (peerinfo);
-
- if (uuid_is_null (peerinfo->uuid)) {
- ret = glusterd_store_peerinfo_hostname_shandle_create (peerinfo);
- } else {
- ret = glusterd_peerinfo_hostname_shandle_check_destroy (peerinfo);
- ret = glusterd_store_peerinfo_uuid_shandle_create (peerinfo);
- }
- return ret;
-}
-
-int32_t
-glusterd_store_peer_write (int fd, glusterd_peerinfo_t *peerinfo)
-{
- char buf[50] = {0};
- int32_t ret = 0;
- int32_t i = 1;
- glusterd_peer_hostname_t *hostname = NULL;
- char *key = NULL;
-
- ret = gf_store_save_value (fd, GLUSTERD_STORE_KEY_PEER_UUID,
- uuid_utoa (peerinfo->uuid));
- if (ret)
- goto out;
-
- snprintf (buf, sizeof (buf), "%d", peerinfo->state.state);
- ret = gf_store_save_value (fd, GLUSTERD_STORE_KEY_PEER_STATE, buf);
- if (ret)
- goto out;
-
- list_for_each_entry (hostname, &peerinfo->hostnames, hostname_list) {
- ret = gf_asprintf (&key, GLUSTERD_STORE_KEY_PEER_HOSTNAME"%d",
- i);
- if (ret < 0)
- goto out;
- ret = gf_store_save_value (fd, key, hostname->hostname);
- if (ret)
- goto out;
- GF_FREE (key);
- key = NULL;
- i++;
- }
-
-out:
- gf_log ("", GF_LOG_DEBUG, "Returning with %d", ret);
- return ret;
-}
-
-int32_t
-glusterd_store_perform_peer_store (glusterd_peerinfo_t *peerinfo)
-{
- int fd = -1;
- int32_t ret = -1;
-
- GF_ASSERT (peerinfo);
-
- fd = gf_store_mkstemp (peerinfo->shandle);
- if (fd <= 0) {
- ret = -1;
- goto out;
- }
-
- ret = glusterd_store_peer_write (fd, peerinfo);
- if (ret)
- goto out;
-
- ret = gf_store_rename_tmppath (peerinfo->shandle);
-out:
- if (ret && (fd > 0))
- gf_store_unlink_tmppath (peerinfo->shandle);
- gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-
-int32_t
-glusterd_store_peerinfo (glusterd_peerinfo_t *peerinfo)
-{
- int32_t ret = -1;
-
- GF_ASSERT (peerinfo);
-
- ret = glusterd_store_create_peer_dir ();
- if (ret)
- goto out;
-
- ret = glusterd_store_create_peer_shandle (peerinfo);
- if (ret)
- goto out;
-
- ret = glusterd_store_perform_peer_store (peerinfo);
-out:
- gf_log ("", GF_LOG_DEBUG, "Returning with %d", ret);
- return ret;
-}
-
-int32_t
-glusterd_store_retrieve_peers (xlator_t *this)
-{
- int32_t ret = 0;
- glusterd_conf_t *priv = NULL;
- DIR *dir = NULL;
- struct dirent *entry = NULL;
- char path[PATH_MAX] = {0,};
- glusterd_peerinfo_t *peerinfo = NULL;
- char *hostname = NULL;
- gf_store_handle_t *shandle = NULL;
- char filepath[PATH_MAX] = {0,};
- gf_store_iter_t *iter = NULL;
- char *key = NULL;
- char *value = NULL;
- glusterd_peerctx_args_t args = {0};
- gf_store_op_errno_t op_errno = GD_STORE_SUCCESS;
- glusterd_peer_hostname_t *address = NULL;
-
- GF_ASSERT (this);
- priv = this->private;
-
- GF_ASSERT (priv);
-
- snprintf (path, PATH_MAX, "%s/%s", priv->workdir,
- GLUSTERD_PEER_DIR_PREFIX);
-
- dir = opendir (path);
-
- if (!dir) {
- gf_log ("", GF_LOG_ERROR, "Unable to open dir %s", path);
- ret = -1;
- goto out;
- }
-
- glusterd_for_each_entry (entry, dir);
-
- while (entry) {
- snprintf (filepath, PATH_MAX, "%s/%s", path, entry->d_name);
- ret = gf_store_handle_retrieve (filepath, &shandle);
- if (ret)
- goto out;
-
- ret = gf_store_iter_new (shandle, &iter);
- if (ret)
- goto out;
-
- ret = gf_store_iter_get_next (iter, &key, &value, &op_errno);
- if (ret)
- goto out;
-
- /* Create an empty peerinfo object before reading in the
- * details
- */
- peerinfo = glusterd_peerinfo_new (GD_FRIEND_STATE_DEFAULT, NULL,
- NULL, 0);
- if (peerinfo == NULL) {
- ret = -1;
- goto out;
- }
-
- while (!ret) {
-
- if (!strncmp (GLUSTERD_STORE_KEY_PEER_UUID, key,
- strlen (GLUSTERD_STORE_KEY_PEER_UUID))) {
- if (value)
- uuid_parse (value, peerinfo->uuid);
- } else if (!strncmp (GLUSTERD_STORE_KEY_PEER_STATE,
- key,
- strlen (GLUSTERD_STORE_KEY_PEER_STATE))) {
- peerinfo->state.state = atoi (value);
- } else if (!strncmp (GLUSTERD_STORE_KEY_PEER_HOSTNAME,
- key,
- strlen (GLUSTERD_STORE_KEY_PEER_HOSTNAME))) {
- ret = gd_add_address_to_peer (peerinfo, value);
- } else {
- gf_log ("", GF_LOG_ERROR, "Unknown key: %s",
- key);
- }
-
- GF_FREE (key);
- GF_FREE (value);
- key = NULL;
- value = NULL;
-
- ret = gf_store_iter_get_next (iter, &key, &value,
- &op_errno);
- }
- if (op_errno != GD_STORE_EOF) {
- GF_FREE(hostname);
- goto out;
- }
-
- (void) gf_store_iter_destroy (iter);
-
- /* Set first hostname from peerinfo->hostnames to
- * peerinfo->hostname
- */
- address = list_entry (peerinfo->hostnames.next,
- glusterd_peer_hostname_t, hostname_list);
- if (!address) {
- ret = -1;
- goto out;
- }
- peerinfo->hostname = gf_strdup (address->hostname);
-
- ret = glusterd_friend_add_from_peerinfo (peerinfo, 1, NULL);
- if (ret)
- goto out;
-
- peerinfo->shandle = shandle;
- peerinfo = NULL;
- glusterd_for_each_entry (entry, dir);
- }
-
- args.mode = GD_MODE_ON;
- list_for_each_entry (peerinfo, &priv->peers, uuid_list) {
- ret = glusterd_friend_rpc_create (this, peerinfo, &args);
- if (ret)
- goto out;
- }
- peerinfo = NULL;
-
-out:
- if (peerinfo)
- glusterd_peerinfo_cleanup (peerinfo);
-
- if (dir)
- closedir (dir);
- gf_log ("", GF_LOG_DEBUG, "Returning with %d", ret);
-
- return ret;
-}
-
-/* Bricks for snap volumes are hosted at /var/run/gluster/snaps
- * When a volume is restored, it points to the bricks of the snap
- * volume it was restored from. Hence on a node restart these
- * paths need to be recreated and re-mounted
- */
-int32_t
-glusterd_recreate_all_snap_brick_mounts (xlator_t *this)
-{
- int32_t ret = 0;
- glusterd_conf_t *priv = NULL;
- glusterd_volinfo_t *volinfo = NULL;
- glusterd_snap_t *snap = NULL;
-
- GF_ASSERT (this);
- priv = this->private;
- GF_ASSERT (priv);
-
- /* Recreate bricks of volumes restored from snaps */
- list_for_each_entry (volinfo, &priv->volumes, vol_list) {
- /* If the volume is not a restored volume then continue */
- if (uuid_is_null (volinfo->restored_from_snap))
- continue;
-
- ret = glusterd_recreate_vol_brick_mounts (this, volinfo);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to recreate brick mounts "
- "for %s", volinfo->volname);
- goto out;
- }
- }
-
- /* Recreate bricks of snapshot volumes */
- list_for_each_entry (snap, &priv->snapshots, snap_list) {
- list_for_each_entry (volinfo, &snap->volumes, vol_list) {
- ret = glusterd_recreate_vol_brick_mounts (this,
- volinfo);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to recreate brick mounts "
- "for %s", snap->snapname);
- goto out;
- }
- }
- }
-
-out:
- gf_log (this->name, GF_LOG_TRACE, "Returning with %d", ret);
- return ret;
-}
-
-/* When the snapshot command from cli is received, the on disk and
- * in memory structures for the snapshot are created (with the status)
- * being marked as GD_SNAP_STATUS_INIT. Once the backend snapshot is
- * taken, the status is changed to GD_SNAP_STATUS_IN_USE. If glusterd
- * dies after taking the backend snapshot, but before updating the
- * status, then when glusterd comes up, it should treat that snapshot
- * as a failed snapshot and clean it up.
- *
- * Restore operation starts by setting the status to
- * GD_SNAP_STATUS_RESTORED. If the server goes down before changing
- * the status the status back we need to revert the partial snapshot
- * taken.
- */
-int32_t
-glusterd_snap_cleanup (xlator_t *this)
-{
- dict_t *dict = NULL;
- int32_t ret = 0;
- glusterd_conf_t *priv = NULL;
- glusterd_snap_t *snap = NULL;
- glusterd_snap_t *tmp_snap = NULL;
-
- GF_ASSERT (this);
- priv = this->private;
- GF_ASSERT (priv);
-
- dict = dict_new();
- if (!dict) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to create dict");
- ret = -1;
- goto out;
- }
-
- list_for_each_entry_safe (snap, tmp_snap, &priv->snapshots, snap_list) {
- if (snap->snap_status == GD_SNAP_STATUS_RESTORED) {
- ret = glusterd_snapshot_revert_restore_from_snap (snap);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING, "Failed to "
- "revert partially restored snapshot "
- "(%s)", snap->snapname);
- goto out;
- }
- } else if (snap->snap_status != GD_SNAP_STATUS_IN_USE) {
- ret = glusterd_snap_remove (dict, snap,
- _gf_true, _gf_true);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to remove the snapshot %s",
- snap->snapname);
- goto out;
- }
- }
- }
-out:
- if (dict)
- dict_unref (dict);
-
- gf_log (this->name, GF_LOG_TRACE, "Returning with %d", ret);
- return ret;
-}
-
-int32_t
-glusterd_resolve_all_bricks (xlator_t *this)
-{
- int32_t ret = 0;
- glusterd_conf_t *priv = NULL;
- glusterd_volinfo_t *volinfo = NULL;
- glusterd_brickinfo_t *brickinfo = NULL;
- glusterd_snap_t *snap = NULL;
-
- GF_ASSERT (this);
- priv = this->private;
-
- GF_ASSERT (priv);
-
- /* Resolve bricks of volumes */
- list_for_each_entry (volinfo, &priv->volumes, vol_list) {
- list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) {
- ret = glusterd_resolve_brick (brickinfo);
- if (ret) {
- gf_log ("glusterd", GF_LOG_ERROR,
- "resolve brick failed in restore");
- goto out;
- }
- }
- }
-
- /* Resolve bricks of snapshot volumes */
- list_for_each_entry (snap, &priv->snapshots, snap_list) {
- ret = glusterd_resolve_snap_bricks (this, snap);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "resolving the snap bricks"
- " failed for snap: %s",
- snap->snapname);
- goto out;
- }
- }
-
-out:
- gf_log (this->name, GF_LOG_TRACE, "Returning with %d", ret);
- return ret;
-}
-
-int32_t
-glusterd_restore ()
-{
- int32_t ret = -1;
- xlator_t *this = NULL;
-
- this = THIS;
-
- ret = glusterd_restore_op_version (this);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to restore op_version");
- goto out;
- }
-
- ret = glusterd_store_retrieve_volumes (this, NULL);
- if (ret)
- goto out;
-
- ret = glusterd_store_retrieve_peers (this);
- if (ret)
- goto out;
-
- /* While retrieving snapshots, if the snapshot status
- is not GD_SNAP_STATUS_IN_USE, then the snapshot is
- cleaned up. To do that, the snap volume has to be
- stopped by stopping snapshot volume's bricks. And for
- that the snapshot bricks should be resolved. But without
- retrieving the peers, resolving bricks will fail. So
- do retrieving of snapshots after retrieving peers.
- */
- ret = glusterd_store_retrieve_snaps (this);
- if (ret)
- goto out;
-
- ret = glusterd_resolve_all_bricks (this);
- if (ret)
- goto out;
-
- ret = glusterd_snap_cleanup (this);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to perform "
- "a cleanup of the snapshots");
- goto out;
- }
-
- ret = glusterd_recreate_all_snap_brick_mounts (this);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to recreate "
- "all snap brick mounts");
- goto out;
- }
-
-out:
- gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-
-int
-glusterd_store_retrieve_quota_version (glusterd_volinfo_t *volinfo)
-{
- int ret = -1;
- uint32_t version = 0;
- char cksum_path[PATH_MAX] = {0,};
- char path[PATH_MAX] = {0,};
- char *version_str = NULL;
- char *tmp = NULL;
- xlator_t *this = NULL;
- glusterd_conf_t *conf = NULL;
- gf_store_handle_t *handle = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- conf = this->private;
- GF_ASSERT (conf);
-
- GLUSTERD_GET_VOLUME_DIR (path, volinfo, conf);
- snprintf (cksum_path, sizeof (cksum_path), "%s/%s", path,
- GLUSTERD_VOL_QUOTA_CKSUM_FILE);
-
- ret = gf_store_handle_new (cksum_path, &handle);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Unable to get store handle "
- "for %s", cksum_path);
- goto out;
- }
-
- ret = gf_store_retrieve_value (handle, "version", &version_str);
- if (ret) {
- gf_log (this->name, GF_LOG_DEBUG, "Version absent");
- ret = 0;
- goto out;
- }
-
- version = strtoul (version_str, &tmp, 10);
- if ((errno == ERANGE) || (errno == EINVAL)) {
- gf_log (this->name, GF_LOG_DEBUG, "Invalid version number");
- goto out;
- }
- volinfo->quota_conf_version = version;
- ret = 0;
-
-out:
- if (version_str)
- GF_FREE (version_str);
- gf_store_handle_destroy (handle);
- return ret;
-}
-
-int
-glusterd_store_save_quota_version_and_cksum (glusterd_volinfo_t *volinfo)
-{
- gf_store_handle_t *shandle = NULL;
- glusterd_conf_t *conf = NULL;
- xlator_t *this = NULL;
- char path[PATH_MAX] = {0};
- char cksum_path[PATH_MAX] = {0,};
- char buf[256] = {0};
- int fd = -1;
- int32_t ret = -1;
-
- this = THIS;
- conf = this->private;
-
- GLUSTERD_GET_VOLUME_DIR (path, volinfo, conf);
- snprintf (cksum_path, sizeof (cksum_path), "%s/%s", path,
- GLUSTERD_VOL_QUOTA_CKSUM_FILE);
-
- ret = gf_store_handle_new (cksum_path, &shandle);
- if (ret)
- goto out;
-
- fd = gf_store_mkstemp (shandle);
- if (fd <= 0) {
- ret = -1;
- goto out;
- }
-
- snprintf (buf, sizeof (buf)-1, "%u", volinfo->quota_conf_cksum);
- ret = gf_store_save_value (fd, "cksum", buf);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to store cksum");
- goto out;
- }
-
- memset (buf, 0, sizeof (buf));
- snprintf (buf, sizeof (buf)-1, "%u", volinfo->quota_conf_version);
- ret = gf_store_save_value (fd, "version", buf);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to store version");
- goto out;
- }
-
- ret = gf_store_rename_tmppath (shandle);
- if (ret)
- goto out;
-
-out:
- if ((ret < 0) && (fd > 0))
- gf_store_unlink_tmppath (shandle);
- gf_store_handle_destroy (shandle);
- return ret;
-}
diff --git a/xlators/mgmt/glusterd/src/glusterd-store.h b/xlators/mgmt/glusterd/src/glusterd-store.h
deleted file mode 100644
index 99bbb39683a..00000000000
--- a/xlators/mgmt/glusterd/src/glusterd-store.h
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
- Copyright (c) 2006-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 _GLUSTERD_HA_H_
-#define _GLUSTERD_HA_H_
-
-#ifndef _CONFIG_H
-#define _CONFIG_H
-#include "config.h"
-#endif
-
-#include <pthread.h>
-#include "uuid.h"
-
-#include "glusterfs.h"
-#include "xlator.h"
-#include "run.h"
-#include "logging.h"
-#include "call-stub.h"
-#include "fd.h"
-#include "byte-order.h"
-#include "glusterd.h"
-#include "rpcsvc.h"
-
-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;
-
-
-#define GLUSTERD_STORE_UUID_KEY "UUID"
-
-#define GLUSTERD_STORE_KEY_VOL_TYPE "type"
-#define GLUSTERD_STORE_KEY_VOL_COUNT "count"
-#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_DISPERSE_CNT "disperse_count"
-#define GLUSTERD_STORE_KEY_VOL_REDUNDANCY_CNT "redundancy_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_VOL_RESTORED_SNAP "restored_from_snap"
-#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_RB_DST_PORT "rb_port"
-#define GLUSTERD_STORE_KEY_VOL_DEFRAG "rebalance_status"
-#define GLUSTERD_STORE_KEY_VOL_DEFRAG_STATUS "status"
-#define GLUSTERD_STORE_KEY_DEFRAG_OP "rebalance_op"
-#define GLUSTERD_STORE_KEY_USERNAME "username"
-#define GLUSTERD_STORE_KEY_PASSWORD "password"
-#define GLUSTERD_STORE_KEY_PARENT_VOLNAME "parent_volname"
-#define GLUSTERD_STORE_KEY_VOL_OP_VERSION "op-version"
-#define GLUSTERD_STORE_KEY_VOL_CLIENT_OP_VERSION "client-op-version"
-
-#define GLUSTERD_STORE_KEY_SNAP_NAME "name"
-#define GLUSTERD_STORE_KEY_SNAP_ID "snap-id"
-#define GLUSTERD_STORE_KEY_SNAP_DESC "desc"
-#define GLUSTERD_STORE_KEY_SNAP_TIMESTAMP "time-stamp"
-#define GLUSTERD_STORE_KEY_SNAP_STATUS "status"
-#define GLUSTERD_STORE_KEY_SNAP_RESTORED "snap-restored"
-#define GLUSTERD_STORE_KEY_SNAP_MAX_HARD_LIMIT "snap-max-hard-limit"
-#define GLUSTERD_STORE_KEY_SNAP_AUTO_DELETE "auto-delete"
-#define GLUSTERD_STORE_KEY_SNAP_MAX_SOFT_LIMIT "snap-max-soft-limit"
-#define GLUSTERD_STORE_KEY_SNAPD_PORT "snapd-port"
-#define GLUSTERD_STORE_KEY_SNAP_ACTIVATE "snap-activate-on-create"
-
-#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_BRICK_VGNAME "vg"
-#define GLUSTERD_STORE_KEY_BRICK_DEVICE_PATH "device_path"
-#define GLUSTERD_STORE_KEY_BRICK_MOUNT_DIR "mount_dir"
-#define GLUSTERD_STORE_KEY_BRICK_SNAP_STATUS "snap-status"
-#define GLUSTERD_STORE_KEY_BRICK_FSTYPE "fs-type"
-#define GLUSTERD_STORE_KEY_BRICK_MNTOPTS "mnt-opts"
-#define GLUSTERD_STORE_KEY_BRICK_ID "brick-id"
-
-#define GLUSTERD_STORE_KEY_PEER_UUID "uuid"
-#define GLUSTERD_STORE_KEY_PEER_HOSTNAME "hostname"
-#define GLUSTERD_STORE_KEY_PEER_STATE "state"
-
-#define GLUSTERD_STORE_KEY_VOL_CAPS "caps"
-
-#define glusterd_for_each_entry(entry, dir) \
- do {\
- entry = NULL;\
- if (dir) {\
- entry = readdir (dir);\
- while (entry && (!strcmp (entry->d_name, ".") ||\
- !fnmatch ("*.tmp", entry->d_name, 0) ||\
- !strcmp (entry->d_name, ".."))) {\
- entry = readdir (dir);\
- }\
- }\
- } while (0); \
-
-
-int32_t
-glusterd_store_volinfo (glusterd_volinfo_t *volinfo, glusterd_volinfo_ver_ac_t ac);
-
-int32_t
-glusterd_store_delete_volume (glusterd_volinfo_t *volinfo);
-
-int32_t
-glusterd_store_delete_snap (glusterd_snap_t *snap);
-
-int32_t
-glusterd_retrieve_uuid ();
-
-int32_t
-glusterd_store_peerinfo (glusterd_peerinfo_t *peerinfo);
-
-int32_t
-glusterd_store_delete_peerinfo (glusterd_peerinfo_t *peerinfo);
-
-int32_t
-glusterd_store_delete_brick (glusterd_brickinfo_t *brickinfo,
- char *delete_path);
-
-int32_t
-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);
-
-int
-glusterd_retrieve_op_version (xlator_t *this, int *op_version);
-
-int
-glusterd_store_global_info (xlator_t *this);
-
-int32_t
-glusterd_store_retrieve_options (xlator_t *this);
-
-int32_t
-glusterd_store_retrieve_bricks (glusterd_volinfo_t *volinfo);
-
-int32_t
-glusterd_store_options (xlator_t *this, dict_t *opts);
-
-void
-glusterd_replace_slash_with_hyphen (char *str);
-
-int32_t
-glusterd_store_perform_volume_store (glusterd_volinfo_t *volinfo);
-
-int32_t
-glusterd_store_create_quota_conf_sh_on_absence (glusterd_volinfo_t *volinfo);
-
-int
-glusterd_store_retrieve_quota_version (glusterd_volinfo_t *volinfo);
-
-int
-glusterd_store_save_quota_version_and_cksum (glusterd_volinfo_t *volinfo);
-
-int32_t
-glusterd_store_snap (glusterd_snap_t *snap);
-
-int32_t
-glusterd_store_update_missed_snaps ();
-
-glusterd_volinfo_t*
-glusterd_store_retrieve_volume (char *volname, glusterd_snap_t *snap);
-#endif
diff --git a/xlators/mgmt/glusterd/src/glusterd-syncop.c b/xlators/mgmt/glusterd/src/glusterd-syncop.c
deleted file mode 100644
index 7a4b02d1f7a..00000000000
--- a/xlators/mgmt/glusterd/src/glusterd-syncop.c
+++ /dev/null
@@ -1,1729 +0,0 @@
-/*
- Copyright (c) 2012-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.
-*/
-/* rpc related syncops */
-#include "rpc-clnt.h"
-#include "protocol-common.h"
-#include "xdr-generic.h"
-#include "glusterd1-xdr.h"
-#include "glusterd-syncop.h"
-#include "glusterd-mgmt.h"
-
-#include "glusterd.h"
-#include "glusterd-op-sm.h"
-#include "glusterd-utils.h"
-#include "glusterd-locks.h"
-
-extern glusterd_op_info_t opinfo;
-
-void
-gd_synctask_barrier_wait (struct syncargs *args, int count)
-{
- glusterd_conf_t *conf = THIS->private;
-
- synclock_unlock (&conf->big_lock);
- synctask_barrier_wait (args, count);
- synclock_lock (&conf->big_lock);
-
- syncbarrier_destroy (&args->barrier);
-}
-
-static void
-gd_collate_errors (struct syncargs *args, int op_ret, int op_errno,
- char *op_errstr, int op_code,
- glusterd_peerinfo_t *peerinfo, u_char *uuid)
-{
- char err_str[PATH_MAX] = "Please check log file for details.";
- char op_err[PATH_MAX] = "";
- int len = -1;
- char *peer_str = NULL;
-
- if (op_ret) {
- args->op_ret = op_ret;
- args->op_errno = op_errno;
-
- if (peerinfo)
- peer_str = peerinfo->hostname;
- else
- peer_str = uuid_utoa (uuid);
-
- if (op_errstr && strcmp (op_errstr, "")) {
- len = snprintf (err_str, sizeof(err_str) - 1,
- "Error: %s", op_errstr);
- err_str[len] = '\0';
- }
-
- switch (op_code){
- case GLUSTERD_MGMT_CLUSTER_LOCK :
- {
- len = snprintf (op_err, sizeof(op_err) - 1,
- "Locking failed on %s. %s",
- peer_str, err_str);
- break;
- }
- case GLUSTERD_MGMT_CLUSTER_UNLOCK :
- {
- len = snprintf (op_err, sizeof(op_err) - 1,
- "Unlocking failed on %s. %s",
- peer_str, err_str);
- break;
- }
- case GLUSTERD_MGMT_STAGE_OP :
- {
- len = snprintf (op_err, sizeof(op_err) - 1,
- "Staging failed on %s. %s",
- peer_str, err_str);
- break;
- }
- case GLUSTERD_MGMT_COMMIT_OP :
- {
- len = snprintf (op_err, sizeof(op_err) - 1,
- "Commit failed on %s. %s",
- peer_str, err_str);
- break;
- }
- }
- op_err[len] = '\0';
-
- if (args->errstr) {
- len = snprintf (err_str, sizeof(err_str) - 1,
- "%s\n%s", args->errstr,
- op_err);
- GF_FREE (args->errstr);
- args->errstr = NULL;
- } else
- len = snprintf (err_str, sizeof(err_str) - 1,
- "%s", op_err);
- err_str[len] = '\0';
-
- gf_log ("", GF_LOG_ERROR, "%s", op_err);
- args->errstr = gf_strdup (err_str);
- }
-
- return;
-}
-
-void
-gd_syncargs_init (struct syncargs *args, dict_t *op_ctx)
-{
- args->dict = op_ctx;
- pthread_mutex_init (&args->lock_dict, NULL);
-}
-
-static void
-gd_stage_op_req_free (gd1_mgmt_stage_op_req *req)
-{
- if (!req)
- return;
-
- GF_FREE (req->buf.buf_val);
- GF_FREE (req);
-}
-
-static void
-gd_commit_op_req_free (gd1_mgmt_commit_op_req *req)
-{
- if (!req)
- return;
-
- GF_FREE (req->buf.buf_val);
- GF_FREE (req);
-}
-
-static void
-gd_brick_op_req_free (gd1_mgmt_brick_op_req *req)
-{
- if (!req)
- return;
-
- if (strcmp (req->name, "") != 0)
- GF_FREE (req->name);
- GF_FREE (req->input.input_val);
- GF_FREE (req);
-}
-
-int
-gd_syncop_submit_request (struct rpc_clnt *rpc, void *req, void *local,
- 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 = local;
- frame->cookie = 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;
-extern struct rpc_clnt_program gd_brick_prog;
-extern struct rpc_clnt_program gd_mgmt_v3_prog;
-
-int
-glusterd_syncop_aggr_rsp_dict (glusterd_op_t op, dict_t *aggr, dict_t *rsp)
-{
- int ret = 0;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
-
- switch (op) {
- case GD_OP_CREATE_VOLUME:
- case GD_OP_ADD_BRICK:
- case GD_OP_START_VOLUME:
- ret = glusterd_aggr_brick_mount_dirs (aggr, rsp);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to "
- "aggregate brick mount dirs");
- goto out;
- }
- break;
-
- case GD_OP_REPLACE_BRICK:
- ret = glusterd_rb_use_rsp_dict (aggr, rsp);
- if (ret)
- goto out;
- break;
-
- case GD_OP_SYNC_VOLUME:
- ret = glusterd_sync_use_rsp_dict (aggr, rsp);
- if (ret)
- goto out;
- break;
-
- case GD_OP_PROFILE_VOLUME:
- ret = glusterd_profile_volume_use_rsp_dict (aggr, rsp);
- if (ret)
- goto out;
- break;
-
- case GD_OP_GSYNC_CREATE:
- break;
-
- case GD_OP_GSYNC_SET:
- ret = glusterd_gsync_use_rsp_dict (aggr, rsp, NULL);
- if (ret)
- goto out;
- break;
-
- case GD_OP_STATUS_VOLUME:
- ret = glusterd_volume_status_copy_to_op_ctx_dict (aggr, rsp);
- if (ret)
- goto out;
- break;
-
- case GD_OP_REBALANCE:
- case GD_OP_DEFRAG_BRICK_VOLUME:
- ret = glusterd_volume_rebalance_use_rsp_dict (aggr, rsp);
- if (ret)
- goto out;
- break;
-
- case GD_OP_HEAL_VOLUME:
- ret = glusterd_volume_heal_use_rsp_dict (aggr, rsp);
- if (ret)
- goto out;
-
- break;
-
- case GD_OP_CLEARLOCKS_VOLUME:
- ret = glusterd_use_rsp_dict (aggr, rsp);
- if (ret)
- goto out;
- break;
-
- case GD_OP_QUOTA:
- ret = glusterd_volume_quota_copy_to_op_ctx_dict (aggr, rsp);
- if (ret)
- goto out;
- break;
-
- case GD_OP_SYS_EXEC:
- ret = glusterd_sys_exec_output_rsp_dict (aggr, rsp);
- if (ret)
- goto out;
- break;
-
- case GD_OP_SNAP:
- ret = glusterd_snap_use_rsp_dict (aggr, rsp);
- if (ret)
- goto out;
- break;
-
- default:
- break;
- }
-out:
- return ret;
-}
-
-int32_t
-gd_syncop_mgmt_v3_lock_cbk_fn (struct rpc_req *req, struct iovec *iov,
- int count, void *myframe)
-{
- int ret = -1;
- struct syncargs *args = NULL;
- glusterd_peerinfo_t *peerinfo = NULL;
- gd1_mgmt_v3_lock_rsp rsp = {{0},};
- call_frame_t *frame = NULL;
- int op_ret = -1;
- int op_errno = -1;
-
- GF_ASSERT(req);
- GF_ASSERT(iov);
- GF_ASSERT(myframe);
-
- frame = myframe;
- args = frame->local;
- peerinfo = frame->cookie;
- frame->local = NULL;
- frame->cookie = NULL;
-
- if (-1 == req->rpc_status) {
- op_errno = ENOTCONN;
- goto out;
- }
-
- ret = xdr_to_generic (*iov, &rsp,
- (xdrproc_t)xdr_gd1_mgmt_v3_lock_rsp);
- if (ret < 0)
- goto out;
-
- uuid_copy (args->uuid, rsp.uuid);
-
- op_ret = rsp.op_ret;
- op_errno = rsp.op_errno;
-out:
- gd_mgmt_v3_collate_errors (args, op_ret, op_errno, NULL,
- GLUSTERD_MGMT_V3_LOCK,
- peerinfo, rsp.uuid);
- STACK_DESTROY (frame->root);
- synctask_barrier_wake(args);
- return 0;
-}
-
-int32_t
-gd_syncop_mgmt_v3_lock_cbk (struct rpc_req *req, struct iovec *iov,
- int count, void *myframe)
-{
- return glusterd_big_locked_cbk (req, iov, count, myframe,
- gd_syncop_mgmt_v3_lock_cbk_fn);
-}
-
-int
-gd_syncop_mgmt_v3_lock (glusterd_op_t op, dict_t *op_ctx,
- glusterd_peerinfo_t *peerinfo,
- struct syncargs *args, uuid_t my_uuid,
- uuid_t recv_uuid, uuid_t txn_id)
-{
- int ret = -1;
- gd1_mgmt_v3_lock_req req = {{0},};
- glusterd_conf_t *conf = THIS->private;
-
- GF_ASSERT(op_ctx);
- GF_ASSERT(peerinfo);
- GF_ASSERT(args);
-
- ret = dict_allocate_and_serialize (op_ctx,
- &req.dict.dict_val,
- &req.dict.dict_len);
- if (ret)
- goto out;
-
- uuid_copy (req.uuid, my_uuid);
- uuid_copy (req.txn_id, txn_id);
- req.op = op;
- synclock_unlock (&conf->big_lock);
- ret = gd_syncop_submit_request (peerinfo->rpc, &req, args, peerinfo,
- &gd_mgmt_v3_prog,
- GLUSTERD_MGMT_V3_LOCK,
- gd_syncop_mgmt_v3_lock_cbk,
- (xdrproc_t)
- xdr_gd1_mgmt_v3_lock_req);
- synclock_lock (&conf->big_lock);
-out:
- gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-
-int32_t
-gd_syncop_mgmt_v3_unlock_cbk_fn (struct rpc_req *req, struct iovec *iov,
- int count, void *myframe)
-{
- int ret = -1;
- struct syncargs *args = NULL;
- glusterd_peerinfo_t *peerinfo = NULL;
- gd1_mgmt_v3_unlock_rsp rsp = {{0},};
- call_frame_t *frame = NULL;
- int op_ret = -1;
- int op_errno = -1;
-
- GF_ASSERT(req);
- GF_ASSERT(iov);
- GF_ASSERT(myframe);
-
- frame = myframe;
- args = frame->local;
- peerinfo = frame->cookie;
- frame->local = NULL;
- frame->cookie = NULL;
-
- if (-1 == req->rpc_status) {
- op_errno = ENOTCONN;
- goto out;
- }
-
- ret = xdr_to_generic (*iov, &rsp,
- (xdrproc_t)xdr_gd1_mgmt_v3_unlock_rsp);
- if (ret < 0)
- goto out;
-
- uuid_copy (args->uuid, rsp.uuid);
-
- /* Set peer as locked, so we unlock only the locked peers */
- if (rsp.op_ret == 0)
- peerinfo->locked = _gf_true;
- op_ret = rsp.op_ret;
- op_errno = rsp.op_errno;
-out:
- gd_mgmt_v3_collate_errors (args, op_ret, op_errno, NULL,
- GLUSTERD_MGMT_V3_UNLOCK,
- peerinfo, rsp.uuid);
- STACK_DESTROY (frame->root);
- synctask_barrier_wake(args);
- return 0;
-}
-
-int32_t
-gd_syncop_mgmt_v3_unlock_cbk (struct rpc_req *req, struct iovec *iov,
- int count, void *myframe)
-{
- return glusterd_big_locked_cbk (req, iov, count, myframe,
- gd_syncop_mgmt_v3_unlock_cbk_fn);
-}
-
-int
-gd_syncop_mgmt_v3_unlock (dict_t *op_ctx, glusterd_peerinfo_t *peerinfo,
- struct syncargs *args, uuid_t my_uuid,
- uuid_t recv_uuid, uuid_t txn_id)
-{
- int ret = -1;
- gd1_mgmt_v3_unlock_req req = {{0},};
- glusterd_conf_t *conf = THIS->private;
-
- GF_ASSERT(op_ctx);
- GF_ASSERT(peerinfo);
- GF_ASSERT(args);
-
- ret = dict_allocate_and_serialize (op_ctx,
- &req.dict.dict_val,
- &req.dict.dict_len);
- if (ret)
- goto out;
-
- uuid_copy (req.uuid, my_uuid);
- uuid_copy (req.txn_id, txn_id);
- synclock_unlock (&conf->big_lock);
- ret = gd_syncop_submit_request (peerinfo->rpc, &req, args, peerinfo,
- &gd_mgmt_v3_prog,
- GLUSTERD_MGMT_V3_UNLOCK,
- gd_syncop_mgmt_v3_unlock_cbk,
- (xdrproc_t)
- xdr_gd1_mgmt_v3_unlock_req);
- synclock_lock (&conf->big_lock);
-out:
- gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-
-int32_t
-_gd_syncop_mgmt_lock_cbk (struct rpc_req *req, struct iovec *iov,
- int count, void *myframe)
-{
- int ret = -1;
- struct syncargs *args = NULL;
- glusterd_peerinfo_t *peerinfo = NULL;
- gd1_mgmt_cluster_lock_rsp rsp = {{0},};
- call_frame_t *frame = NULL;
- int op_ret = -1;
- int op_errno = -1;
-
- frame = myframe;
- args = frame->local;
- peerinfo = frame->cookie;
- frame->local = NULL;
- frame->cookie = NULL;
-
- if (-1 == req->rpc_status) {
- op_errno = ENOTCONN;
- goto out;
- }
-
- ret = xdr_to_generic (*iov, &rsp,
- (xdrproc_t)xdr_gd1_mgmt_cluster_lock_rsp);
- if (ret < 0)
- goto out;
-
- uuid_copy (args->uuid, rsp.uuid);
-
- /* Set peer as locked, so we unlock only the locked peers */
- if (rsp.op_ret == 0)
- peerinfo->locked = _gf_true;
- op_ret = rsp.op_ret;
- op_errno = rsp.op_errno;
-out:
- gd_collate_errors (args, op_ret, op_errno, NULL,
- GLUSTERD_MGMT_CLUSTER_LOCK, peerinfo, rsp.uuid);
- STACK_DESTROY (frame->root);
- synctask_barrier_wake(args);
- return 0;
-}
-
-int32_t
-gd_syncop_mgmt_lock_cbk (struct rpc_req *req, struct iovec *iov, int count,
- void *myframe)
-{
- return glusterd_big_locked_cbk (req, iov, count, myframe,
- _gd_syncop_mgmt_lock_cbk);
-}
-
-int
-gd_syncop_mgmt_lock (glusterd_peerinfo_t *peerinfo, struct syncargs *args,
- uuid_t my_uuid, uuid_t recv_uuid)
-{
- int ret = -1;
- gd1_mgmt_cluster_lock_req req = {{0},};
- glusterd_conf_t *conf = THIS->private;
-
- uuid_copy (req.uuid, my_uuid);
- synclock_unlock (&conf->big_lock);
- ret = gd_syncop_submit_request (peerinfo->rpc, &req, args, peerinfo,
- &gd_mgmt_prog,
- GLUSTERD_MGMT_CLUSTER_LOCK,
- gd_syncop_mgmt_lock_cbk,
- (xdrproc_t) xdr_gd1_mgmt_cluster_lock_req);
- synclock_lock (&conf->big_lock);
- return ret;
-}
-
-int32_t
-_gd_syncop_mgmt_unlock_cbk (struct rpc_req *req, struct iovec *iov,
- int count, void *myframe)
-{
- int ret = -1;
- struct syncargs *args = NULL;
- glusterd_peerinfo_t *peerinfo = NULL;
- gd1_mgmt_cluster_unlock_rsp rsp = {{0},};
- call_frame_t *frame = NULL;
- int op_ret = -1;
- int op_errno = -1;
-
- frame = myframe;
- args = frame->local;
- peerinfo = frame->cookie;
- frame->local = NULL;
-
- if (-1 == req->rpc_status) {
- op_errno = ENOTCONN;
- goto out;
- }
-
- ret = xdr_to_generic (*iov, &rsp,
- (xdrproc_t)xdr_gd1_mgmt_cluster_unlock_rsp);
- if (ret < 0)
- goto out;
-
- uuid_copy (args->uuid, rsp.uuid);
-
- peerinfo->locked = _gf_false;
- op_ret = rsp.op_ret;
- op_errno = rsp.op_errno;
-out:
- gd_collate_errors (args, op_ret, op_errno, NULL,
- GLUSTERD_MGMT_CLUSTER_UNLOCK, peerinfo, rsp.uuid);
- STACK_DESTROY (frame->root);
- synctask_barrier_wake(args);
- return 0;
-}
-
-int32_t
-gd_syncop_mgmt_unlock_cbk (struct rpc_req *req, struct iovec *iov,
- int count, void *myframe)
-{
- return glusterd_big_locked_cbk (req, iov, count, myframe,
- _gd_syncop_mgmt_unlock_cbk);
-}
-
-
-int
-gd_syncop_mgmt_unlock (glusterd_peerinfo_t *peerinfo, struct syncargs *args,
- uuid_t my_uuid, uuid_t recv_uuid)
-{
- int ret = -1;
- gd1_mgmt_cluster_unlock_req req = {{0},};
- glusterd_conf_t *conf = THIS->private;
-
- uuid_copy (req.uuid, my_uuid);
- synclock_unlock (&conf->big_lock);
- ret = gd_syncop_submit_request (peerinfo->rpc, &req, args, peerinfo,
- &gd_mgmt_prog,
- GLUSTERD_MGMT_CLUSTER_UNLOCK,
- gd_syncop_mgmt_unlock_cbk,
- (xdrproc_t) xdr_gd1_mgmt_cluster_lock_req);
- synclock_lock (&conf->big_lock);
- return ret;
-}
-
-int32_t
-_gd_syncop_stage_op_cbk (struct rpc_req *req, struct iovec *iov,
- int count, void *myframe)
-{
- int ret = -1;
- gd1_mgmt_stage_op_rsp rsp = {{0},};
- struct syncargs *args = NULL;
- xlator_t *this = NULL;
- dict_t *rsp_dict = NULL;
- call_frame_t *frame = NULL;
- glusterd_peerinfo_t *peerinfo = NULL;
- int op_ret = -1;
- int op_errno = -1;
-
- this = THIS;
- frame = myframe;
- args = frame->local;
- frame->local = NULL;
-
- if (-1 == req->rpc_status) {
- 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 */
- rsp_dict = dict_new ();
-
- ret = dict_unserialize (rsp.dict.dict_val,
- rsp.dict.dict_len,
- &rsp_dict);
- if (ret < 0) {
- GF_FREE (rsp.dict.dict_val);
- goto out;
- } else {
- rsp_dict->extra_stdfree = rsp.dict.dict_val;
- }
- }
-
- peerinfo = glusterd_peerinfo_find (rsp.uuid, NULL);
- if (peerinfo == NULL) {
- ret = -1;
- gf_log (this->name, GF_LOG_CRITICAL, "Staging response "
- "for 'Volume %s' received from unknown "
- "peer: %s", gd_op_list[rsp.op],
- uuid_utoa (rsp.uuid));
- goto out;
- }
-
- uuid_copy (args->uuid, rsp.uuid);
- if (rsp.op == GD_OP_REPLACE_BRICK || rsp.op == GD_OP_QUOTA ||
- rsp.op == GD_OP_CREATE_VOLUME || rsp.op == GD_OP_ADD_BRICK ||
- rsp.op == GD_OP_START_VOLUME) {
- pthread_mutex_lock (&args->lock_dict);
- {
- ret = glusterd_syncop_aggr_rsp_dict (rsp.op, args->dict,
- rsp_dict);
- if (ret)
- gf_log (this->name, GF_LOG_ERROR, "%s",
- "Failed to aggregate response from "
- " node/brick");
- }
- pthread_mutex_unlock (&args->lock_dict);
- }
-
- op_ret = rsp.op_ret;
- op_errno = rsp.op_errno;
-
-out:
- gd_collate_errors (args, op_ret, op_errno, rsp.op_errstr,
- GLUSTERD_MGMT_STAGE_OP, peerinfo, rsp.uuid);
-
- if (rsp_dict)
- dict_unref (rsp_dict);
-
- STACK_DESTROY (frame->root);
- synctask_barrier_wake(args);
- return 0;
-}
-
-int32_t
-gd_syncop_stage_op_cbk (struct rpc_req *req, struct iovec *iov,
- int count, void *myframe)
-{
- return glusterd_big_locked_cbk (req, iov, count, myframe,
- _gd_syncop_stage_op_cbk);
-}
-
-
-int
-gd_syncop_mgmt_stage_op (struct rpc_clnt *rpc, struct syncargs *args,
- uuid_t my_uuid, uuid_t recv_uuid, int op,
- dict_t *dict_out, dict_t *op_ctx)
-{
- gd1_mgmt_stage_op_req *req = NULL;
- glusterd_conf_t *conf = THIS->private;
- int ret = -1;
-
- req = GF_CALLOC (1, sizeof (*req), gf_gld_mt_mop_stage_req_t);
- if (!req)
- goto out;
-
- uuid_copy (req->uuid, my_uuid);
- req->op = op;
-
- ret = dict_allocate_and_serialize (dict_out,
- &req->buf.buf_val, &req->buf.buf_len);
- if (ret)
- goto out;
-
- synclock_unlock (&conf->big_lock);
- ret = gd_syncop_submit_request (rpc, req, args, NULL, &gd_mgmt_prog,
- GLUSTERD_MGMT_STAGE_OP,
- gd_syncop_stage_op_cbk,
- (xdrproc_t) xdr_gd1_mgmt_stage_op_req);
- synclock_lock (&conf->big_lock);
-out:
- gd_stage_op_req_free (req);
- return ret;
-
-}
-
-int32_t
-_gd_syncop_brick_op_cbk (struct rpc_req *req, struct iovec *iov,
- int count, void *myframe)
-{
- struct syncargs *args = NULL;
- gd1_mgmt_brick_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_brick_op_rsp);
- if (ret < 0)
- goto out;
-
- if (rsp.output.output_len) {
- args->dict = dict_new ();
- if (!args->dict) {
- ret = -1;
- args->op_errno = ENOMEM;
- goto out;
- }
-
- ret = dict_unserialize (rsp.output.output_val,
- rsp.output.output_len,
- &args->dict);
- if (ret < 0)
- goto out;
- }
-
- args->op_ret = rsp.op_ret;
- args->op_errno = rsp.op_errno;
- args->errstr = gf_strdup (rsp.op_errstr);
-
-out:
- if ((rsp.op_errstr) && (strcmp (rsp.op_errstr, "") != 0))
- free (rsp.op_errstr);
- free (rsp.output.output_val);
-
- STACK_DESTROY (frame->root);
- __wake (args);
-
- return 0;
-}
-
-int32_t
-gd_syncop_brick_op_cbk (struct rpc_req *req, struct iovec *iov,
- int count, void *myframe)
-{
- return glusterd_big_locked_cbk (req, iov, count, myframe,
- _gd_syncop_brick_op_cbk);
-}
-
-int
-gd_syncop_mgmt_brick_op (struct rpc_clnt *rpc, glusterd_pending_node_t *pnode,
- int op, dict_t *dict_out, dict_t *op_ctx,
- char **errstr)
-{
- struct syncargs args = {0, };
- gd1_mgmt_brick_op_req *req = NULL;
- int ret = 0;
- xlator_t *this = NULL;
-
- this = THIS;
- args.op_ret = -1;
- args.op_errno = ENOTCONN;
-
- if ((pnode->type == GD_NODE_NFS) ||
- (pnode->type == GD_NODE_QUOTAD) ||
- ((pnode->type == GD_NODE_SHD) && (op == GD_OP_STATUS_VOLUME))) {
- ret = glusterd_node_op_build_payload
- (op, &req, dict_out);
-
- } else {
- ret = glusterd_brick_op_build_payload
- (op, pnode->node, &req, dict_out);
-
- }
-
- if (ret)
- goto out;
-
- GD_SYNCOP (rpc, (&args), NULL, gd_syncop_brick_op_cbk, req,
- &gd_brick_prog, req->op, xdr_gd1_mgmt_brick_op_req);
-
- if (args.errstr) {
- if ((strlen(args.errstr) > 0) && errstr)
- *errstr = args.errstr;
- else
- GF_FREE (args.errstr);
- }
-
- if (GD_OP_STATUS_VOLUME == op) {
- ret = dict_set_int32 (args.dict, "index", pnode->index);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Error setting index on brick status"
- " rsp dict");
- args.op_ret = -1;
- goto out;
- }
- }
- if (args.op_ret == 0)
- glusterd_handle_node_rsp (dict_out, pnode->node, op,
- args.dict, op_ctx, errstr,
- pnode->type);
-
-out:
- errno = args.op_errno;
- if (args.dict)
- dict_unref (args.dict);
- gd_brick_op_req_free (req);
- return args.op_ret;
-
-}
-
-int32_t
-_gd_syncop_commit_op_cbk (struct rpc_req *req, struct iovec *iov,
- int count, void *myframe)
-{
- int ret = -1;
- gd1_mgmt_commit_op_rsp rsp = {{0},};
- struct syncargs *args = NULL;
- xlator_t *this = NULL;
- dict_t *rsp_dict = NULL;
- call_frame_t *frame = NULL;
- glusterd_peerinfo_t *peerinfo = NULL;
- int op_ret = -1;
- int op_errno = -1;
- int type = GF_QUOTA_OPTION_TYPE_NONE;
-
- this = THIS;
- frame = myframe;
- args = frame->local;
- frame->local = NULL;
-
- if (-1 == req->rpc_status) {
- 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 */
- rsp_dict = dict_new ();
-
- ret = dict_unserialize (rsp.dict.dict_val,
- rsp.dict.dict_len,
- &rsp_dict);
- if (ret < 0) {
- GF_FREE (rsp.dict.dict_val);
- goto out;
- } else {
- rsp_dict->extra_stdfree = rsp.dict.dict_val;
- }
- }
-
- peerinfo = glusterd_peerinfo_find (rsp.uuid, NULL);
- if (peerinfo == NULL) {
- ret = -1;
- gf_log (this->name, GF_LOG_CRITICAL, "Commit response "
- "for 'Volume %s' received from unknown "
- "peer: %s", gd_op_list[rsp.op],
- uuid_utoa (rsp.uuid));
- goto out;
- }
-
- uuid_copy (args->uuid, rsp.uuid);
- if (rsp.op == GD_OP_QUOTA) {
- ret = dict_get_int32 (args->dict, "type", &type);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to get "
- "opcode");
- goto out;
- }
- }
-
- if ((rsp.op != GD_OP_QUOTA) || (type == GF_QUOTA_OPTION_TYPE_LIST)) {
- pthread_mutex_lock (&args->lock_dict);
- {
- ret = glusterd_syncop_aggr_rsp_dict (rsp.op, args->dict,
- rsp_dict);
- if (ret)
- gf_log (this->name, GF_LOG_ERROR, "%s",
- "Failed to aggregate response from "
- " node/brick");
- }
- pthread_mutex_unlock (&args->lock_dict);
- }
-
- op_ret = rsp.op_ret;
- op_errno = rsp.op_errno;
-
-out:
- gd_collate_errors (args, op_ret, op_errno, rsp.op_errstr,
- GLUSTERD_MGMT_COMMIT_OP, peerinfo, rsp.uuid);
- if (rsp_dict)
- dict_unref (rsp_dict);
-
- STACK_DESTROY (frame->root);
- synctask_barrier_wake(args);
-
- return 0;
-}
-
-int32_t
-gd_syncop_commit_op_cbk (struct rpc_req *req, struct iovec *iov,
- int count, void *myframe)
-{
- return glusterd_big_locked_cbk (req, iov, count, myframe,
- _gd_syncop_commit_op_cbk);
-}
-
-
-int
-gd_syncop_mgmt_commit_op (struct rpc_clnt *rpc, struct syncargs *args,
- uuid_t my_uuid, uuid_t recv_uuid,
- int op, dict_t *dict_out, dict_t *op_ctx)
-{
- glusterd_conf_t *conf = THIS->private;
- gd1_mgmt_commit_op_req *req = NULL;
- int ret = -1;
-
- req = GF_CALLOC (1, sizeof (*req), gf_gld_mt_mop_commit_req_t);
- if (!req)
- goto out;
-
- uuid_copy (req->uuid, my_uuid);
- req->op = op;
-
- ret = dict_allocate_and_serialize (dict_out,
- &req->buf.buf_val, &req->buf.buf_len);
- if (ret)
- goto out;
-
- synclock_unlock (&conf->big_lock);
- ret = gd_syncop_submit_request (rpc, req, args, NULL, &gd_mgmt_prog,
- GLUSTERD_MGMT_COMMIT_OP ,
- gd_syncop_commit_op_cbk,
- (xdrproc_t) xdr_gd1_mgmt_commit_op_req);
- synclock_lock (&conf->big_lock);
-out:
- gd_commit_op_req_free (req);
- return ret;
-}
-
-
-int
-gd_build_peers_list (struct list_head *peers, struct list_head *xact_peers,
- glusterd_op_t op)
-{
- glusterd_peerinfo_t *peerinfo = NULL;
- int npeers = 0;
-
- GF_ASSERT (peers);
- GF_ASSERT (xact_peers);
-
- list_for_each_entry (peerinfo, peers, uuid_list) {
- if (!peerinfo->connected)
- continue;
- if (op != GD_OP_SYNC_VOLUME &&
- peerinfo->state.state != GD_FRIEND_STATE_BEFRIENDED)
- continue;
-
- list_add_tail (&peerinfo->op_peers_list, xact_peers);
- npeers++;
- }
- return npeers;
-}
-
-int
-gd_build_local_xaction_peers_list (struct list_head *peers,
- struct list_head *xact_peers,
- glusterd_op_t op)
-{
- glusterd_peerinfo_t *peerinfo = NULL;
- glusterd_local_peers_t *local_peers = NULL;
- int npeers = 0;
-
- GF_ASSERT (peers);
- GF_ASSERT (xact_peers);
-
- list_for_each_entry (peerinfo, peers, uuid_list) {
- if (!peerinfo->connected)
- continue;
- if (op != GD_OP_SYNC_VOLUME &&
- peerinfo->state.state != GD_FRIEND_STATE_BEFRIENDED)
- continue;
-
- local_peers = GF_CALLOC (1, sizeof (*local_peers),
- gf_gld_mt_local_peers_t);
- if (!local_peers) {
- return -1;
- }
- INIT_LIST_HEAD (&local_peers->op_peers_list);
- local_peers->peerinfo = peerinfo;
- list_add_tail (&local_peers->op_peers_list, xact_peers);
- npeers++;
- }
- return npeers;
-}
-
-int
-gd_lock_op_phase (glusterd_conf_t *conf, glusterd_op_t op, dict_t *op_ctx,
- char **op_errstr, int npeers, uuid_t txn_id,
- struct list_head *peers, gf_boolean_t cluster_lock)
-{
- int ret = -1;
- int peer_cnt = 0;
- uuid_t peer_uuid = {0};
- xlator_t *this = NULL;
- glusterd_peerinfo_t *peerinfo = NULL;
- struct syncargs args = {0};
-
- if (!npeers) {
- ret = 0;
- goto out;
- }
-
- this = THIS;
- synctask_barrier_init((&args));
- peer_cnt = 0;
- list_for_each_local_xaction_peers (peerinfo, peers) {
- if (cluster_lock) {
- /* Reset lock status */
- peerinfo->locked = _gf_false;
- gd_syncop_mgmt_lock (peerinfo, &args,
- MY_UUID, peer_uuid);
- } else
- gd_syncop_mgmt_v3_lock (op, op_ctx, peerinfo, &args,
- MY_UUID, peer_uuid, txn_id);
- peer_cnt++;
- }
- gd_synctask_barrier_wait((&args), peer_cnt);
-
- if (args.op_ret) {
- if (args.errstr)
- *op_errstr = gf_strdup (args.errstr);
- else {
- ret = gf_asprintf (op_errstr, "Another transaction "
- "could be in progress. Please try "
- "again after sometime.");
- if (ret == -1)
- *op_errstr = NULL;
-
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to acquire lock");
-
- }
- }
-
- ret = args.op_ret;
-
- gf_log (this->name, GF_LOG_DEBUG, "Sent lock op req for 'Volume %s' "
- "to %d peers. Returning %d", gd_op_list[op], peer_cnt, ret);
-out:
- return ret;
-}
-
-int
-gd_stage_op_phase (struct list_head *peers, glusterd_op_t op, dict_t *op_ctx,
- dict_t *req_dict, char **op_errstr, int npeers)
-{
- int ret = -1;
- int peer_cnt = 0;
- dict_t *rsp_dict = NULL;
- char *hostname = NULL;
- xlator_t *this = NULL;
- glusterd_peerinfo_t *peerinfo = NULL;
- uuid_t tmp_uuid = {0};
- char *errstr = NULL;
- struct syncargs args = {0};
- dict_t *aggr_dict = NULL;
-
- this = THIS;
- rsp_dict = dict_new ();
- if (!rsp_dict)
- goto out;
-
- if ((op == GD_OP_CREATE_VOLUME) || (op == GD_OP_ADD_BRICK) ||
- (op == GD_OP_START_VOLUME))
- aggr_dict = req_dict;
- else
- aggr_dict = op_ctx;
-
- ret = glusterd_op_stage_validate (op, req_dict, op_errstr, rsp_dict);
- if (ret) {
- hostname = "localhost";
- goto stage_done;
- }
-
- if ((op == GD_OP_REPLACE_BRICK || op == GD_OP_QUOTA ||
- op == GD_OP_CREATE_VOLUME || op == GD_OP_ADD_BRICK ||
- op == GD_OP_START_VOLUME)) {
- ret = glusterd_syncop_aggr_rsp_dict (op, aggr_dict, rsp_dict);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "%s",
- "Failed to aggregate response from node/brick");
- goto out;
- }
- }
- dict_unref (rsp_dict);
- rsp_dict = NULL;
-
-stage_done:
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, LOGSTR_STAGE_FAIL,
- gd_op_list[op], hostname, (*op_errstr) ? ":" : " ",
- (*op_errstr) ? *op_errstr : " ");
- if (*op_errstr == NULL)
- gf_asprintf (op_errstr, OPERRSTR_STAGE_FAIL, hostname);
- goto out;
- }
-
- if (!npeers) {
- ret = 0;
- goto out;
- }
-
- gd_syncargs_init (&args, aggr_dict);
- synctask_barrier_init((&args));
- peer_cnt = 0;
-
- list_for_each_local_xaction_peers (peerinfo, peers) {
- ret = gd_syncop_mgmt_stage_op (peerinfo->rpc, &args,
- MY_UUID, tmp_uuid,
- op, req_dict, op_ctx);
- peer_cnt++;
- }
-
- gf_log (this->name, GF_LOG_DEBUG, "Sent stage op req for 'Volume %s' "
- "to %d peers", gd_op_list[op], peer_cnt);
-
- gd_synctask_barrier_wait((&args), peer_cnt);
-
- if (args.errstr)
- *op_errstr = gf_strdup (args.errstr);
- else if (dict_get_str (aggr_dict, "errstr", &errstr) == 0)
- *op_errstr = gf_strdup (errstr);
-
- ret = args.op_ret;
-
-out:
- if ((ret == 0) && (op == GD_OP_QUOTA)) {
- ret = glusterd_validate_and_set_gfid (op_ctx, req_dict,
- op_errstr);
- if (ret)
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to validate and set gfid");
- }
-
- if (rsp_dict)
- dict_unref (rsp_dict);
- return ret;
-}
-
-int
-gd_commit_op_phase (struct list_head *peers, glusterd_op_t op, dict_t *op_ctx,
- dict_t *req_dict, char **op_errstr, int npeers)
-{
- dict_t *rsp_dict = NULL;
- int peer_cnt = -1;
- int ret = -1;
- char *hostname = NULL;
- glusterd_peerinfo_t *peerinfo = NULL;
- xlator_t *this = NULL;
- uuid_t tmp_uuid = {0};
- char *errstr = NULL;
- struct syncargs args = {0};
- int type = GF_QUOTA_OPTION_TYPE_NONE;
-
- this = THIS;
- rsp_dict = dict_new ();
- if (!rsp_dict) {
- ret = -1;
- goto out;
- }
-
- ret = glusterd_op_commit_perform (op, req_dict, op_errstr, rsp_dict);
- if (ret) {
- hostname = "localhost";
- goto commit_done;
- }
-
- if (op == GD_OP_QUOTA) {
- ret = dict_get_int32 (op_ctx, "type", &type);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to get "
- "opcode");
- goto out;
- }
- }
-
- if (((op == GD_OP_QUOTA) && (type == GF_QUOTA_OPTION_TYPE_LIST)) ||
- ((op != GD_OP_SYNC_VOLUME) && (op != GD_OP_QUOTA))) {
-
- ret = glusterd_syncop_aggr_rsp_dict (op, op_ctx,
- rsp_dict);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "%s", "Failed to aggregate "
- "response from node/brick");
- goto out;
- }
- }
-
- dict_unref (rsp_dict);
- rsp_dict = NULL;
-
-commit_done:
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, LOGSTR_COMMIT_FAIL,
- gd_op_list[op], hostname, (*op_errstr) ? ":" : " ",
- (*op_errstr) ? *op_errstr : " ");
- if (*op_errstr == NULL)
- gf_asprintf (op_errstr, OPERRSTR_COMMIT_FAIL,
- hostname);
- goto out;
- }
-
- if (!npeers) {
- ret = 0;
- goto out;
- }
-
- gd_syncargs_init (&args, op_ctx);
- synctask_barrier_init((&args));
- peer_cnt = 0;
-
- list_for_each_local_xaction_peers (peerinfo, peers) {
- ret = gd_syncop_mgmt_commit_op (peerinfo->rpc, &args,
- MY_UUID, tmp_uuid,
- op, req_dict, op_ctx);
- peer_cnt++;
- }
- gd_synctask_barrier_wait((&args), peer_cnt);
- ret = args.op_ret;
- if (args.errstr)
- *op_errstr = gf_strdup (args.errstr);
- else if (dict_get_str (op_ctx, "errstr", &errstr) == 0)
- *op_errstr = gf_strdup (errstr);
-
- gf_log (this->name, GF_LOG_DEBUG, "Sent commit op req for 'Volume %s' "
- "to %d peers", gd_op_list[op], peer_cnt);
-out:
- if (!ret)
- glusterd_op_modify_op_ctx (op, op_ctx);
-
- if (rsp_dict)
- dict_unref (rsp_dict);
-
- GF_FREE (args.errstr);
- args.errstr = NULL;
-
- return ret;
-}
-
-int
-gd_unlock_op_phase (glusterd_conf_t *conf, glusterd_op_t op, int *op_ret,
- rpcsvc_request_t *req, dict_t *op_ctx, char *op_errstr,
- int npeers, char *volname, gf_boolean_t is_acquired,
- uuid_t txn_id, struct list_head *peers,
- gf_boolean_t cluster_lock)
-{
- glusterd_peerinfo_t *peerinfo = NULL;
- uuid_t tmp_uuid = {0};
- int peer_cnt = 0;
- int ret = -1;
- xlator_t *this = NULL;
- struct syncargs args = {0};
-
- this = THIS;
- GF_ASSERT (this);
-
- if (!npeers) {
- ret = 0;
- goto out;
- }
-
- /* If the lock has not been held during this
- * transaction, do not send unlock requests */
- if (!is_acquired) {
- ret = 0;
- goto out;
- }
-
- synctask_barrier_init((&args));
- peer_cnt = 0;
-
- if (cluster_lock) {
- list_for_each_local_xaction_peers (peerinfo, peers) {
- /* Only unlock peers that were locked */
- if (peerinfo->locked) {
- gd_syncop_mgmt_unlock (peerinfo, &args,
- MY_UUID, tmp_uuid);
- peer_cnt++;
- }
- }
- } else {
- if (volname) {
- list_for_each_local_xaction_peers (peerinfo, peers) {
- gd_syncop_mgmt_v3_unlock (op_ctx, peerinfo,
- &args, MY_UUID,
- tmp_uuid, txn_id);
- peer_cnt++;
- }
- }
- }
- gd_synctask_barrier_wait((&args), peer_cnt);
-
- ret = args.op_ret;
-
- gf_log (this->name, GF_LOG_DEBUG, "Sent unlock op req for 'Volume %s' "
- "to %d peers. Returning %d", gd_op_list[op], peer_cnt, ret);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to unlock "
- "on some peer(s)");
- }
-
-out:
- /* If unlock failed, and op_ret was previously set
- * priority is given to the op_ret. If op_ret was
- * not set, and unlock failed, then set op_ret */
- if (!*op_ret)
- *op_ret = ret;
-
- if (is_acquired) {
- /* Based on the op-version,
- * we release the cluster or mgmt_v3 lock
- * and clear the op */
-
- glusterd_op_clear_op (op);
- if (cluster_lock)
- glusterd_unlock (MY_UUID);
- else {
- if (volname) {
- ret = glusterd_mgmt_v3_unlock (volname, MY_UUID,
- "vol");
- if (ret)
- gf_log (this->name, GF_LOG_ERROR,
- "Unable to release lock for %s",
- volname);
- }
- }
- }
-
- if (!*op_ret)
- *op_ret = ret;
-
- /*
- * If there are any quorum events while the OP is in progress, process
- * them.
- */
- if (conf->pending_quorum_action)
- glusterd_do_quorum_action ();
-
- return 0;
-}
-
-int
-gd_get_brick_count (struct list_head *bricks)
-{
- glusterd_pending_node_t *pending_node = NULL;
- int npeers = 0;
- list_for_each_entry (pending_node, bricks, list) {
- npeers++;
- }
- return npeers;
-}
-
-int
-gd_brick_op_phase (glusterd_op_t op, dict_t *op_ctx, dict_t *req_dict,
- char **op_errstr)
-{
- glusterd_pending_node_t *pending_node = NULL;
- struct list_head selected = {0,};
- xlator_t *this = NULL;
- int brick_count = 0;
- int ret = -1;
- rpc_clnt_t *rpc = NULL;
- dict_t *rsp_dict = NULL;
- glusterd_conf_t *conf = NULL;
-
- this = THIS;
- conf = this->private;
- rsp_dict = dict_new ();
- if (!rsp_dict) {
- ret = -1;
- goto out;
- }
-
- INIT_LIST_HEAD (&selected);
- ret = glusterd_op_bricks_select (op, req_dict, op_errstr, &selected,
- rsp_dict);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "%s",
- (*op_errstr)? *op_errstr: "Brick op failed. Check "
- "glusterd log file for more details.");
- goto out;
- }
-
- if (op == GD_OP_HEAL_VOLUME) {
- ret = glusterd_syncop_aggr_rsp_dict (op, op_ctx, rsp_dict);
- if (ret)
- goto out;
- }
- dict_unref (rsp_dict);
- rsp_dict = NULL;
-
- brick_count = 0;
- list_for_each_entry (pending_node, &selected, list) {
- rpc = glusterd_pending_node_get_rpc (pending_node);
- if (!rpc) {
- if (pending_node->type == GD_NODE_REBALANCE) {
- ret = 0;
- glusterd_defrag_volume_node_rsp (req_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 = gd_syncop_mgmt_brick_op (rpc, pending_node, op, req_dict,
- op_ctx, op_errstr);
- if (ret)
- goto out;
-
- brick_count++;
- }
-
- ret = 0;
-out:
- if (rsp_dict)
- dict_unref (rsp_dict);
- gf_log (this->name, GF_LOG_DEBUG, "Sent op req to %d bricks",
- brick_count);
- return ret;
-}
-
-void
-gd_sync_task_begin (dict_t *op_ctx, rpcsvc_request_t * req)
-{
- int ret = -1;
- int op_ret = -1;
- int npeers = 0;
- dict_t *req_dict = NULL;
- glusterd_conf_t *conf = NULL;
- glusterd_op_t op = 0;
- int32_t tmp_op = 0;
- char *op_errstr = NULL;
- char *tmp = NULL;
- char *volname = NULL;
- xlator_t *this = NULL;
- gf_boolean_t is_acquired = _gf_false;
- uuid_t *txn_id = NULL;
- struct list_head xaction_peers = {0,};
- glusterd_op_info_t txn_opinfo = {{0},};
- gf_boolean_t cluster_lock = _gf_false;
-
- this = THIS;
- GF_ASSERT (this);
- conf = this->private;
- GF_ASSERT (conf);
-
- INIT_LIST_HEAD (&xaction_peers);
-
- ret = dict_get_int32 (op_ctx, GD_SYNC_OPCODE_KEY, &tmp_op);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to get volume "
- "operation");
- goto out;
- }
- op = tmp_op;
-
- /* Generate a transaction-id for this operation and
- * save it in the dict */
- ret = glusterd_generate_txn_id (op_ctx, &txn_id);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to generate transaction id");
- goto out;
- }
-
- /* Save opinfo for this transaction with the transaction id */
- glusterd_txn_opinfo_init (&txn_opinfo, NULL, &op, NULL, NULL);
- ret = glusterd_set_txn_opinfo (txn_id, &txn_opinfo);
- if (ret)
- gf_log (this->name, GF_LOG_ERROR,
- "Unable to set transaction's opinfo");
-
- gf_log (this->name, GF_LOG_DEBUG,
- "Transaction ID : %s", uuid_utoa (*txn_id));
-
- opinfo = txn_opinfo;
-
- /* Save the MY_UUID as the originator_uuid */
- ret = glusterd_set_originator_uuid (op_ctx);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to set originator_uuid.");
- goto out;
- }
-
- if (conf->op_version < GD_OP_VERSION_3_6_0)
- cluster_lock = _gf_true;
-
- /* Based on the op_version, acquire a cluster or mgmt_v3 lock */
- if (cluster_lock) {
- ret = glusterd_lock (MY_UUID);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Unable to acquire lock");
- gf_asprintf (&op_errstr,
- "Another transaction is in progress. "
- "Please try again after sometime.");
- goto out;
- }
- } else {
-
- /* If no volname is given as a part of the command, locks will
- * not be held */
- ret = dict_get_str (op_ctx, "volname", &tmp);
- if (ret) {
- gf_log ("", GF_LOG_DEBUG, "Failed to get volume "
- "name");
- goto local_locking_done;
- } else {
- /* Use a copy of volname, as cli response will be
- * sent before the unlock, and the volname in the
- * dict, might be removed */
- volname = gf_strdup (tmp);
- if (!volname)
- goto out;
- }
-
- ret = glusterd_mgmt_v3_lock (volname, MY_UUID, "vol");
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Unable to acquire lock for %s", volname);
- gf_asprintf (&op_errstr,
- "Another transaction is in progress "
- "for %s. Please try again after sometime.",
- volname);
- goto out;
- }
- }
-
- is_acquired = _gf_true;
-
-local_locking_done:
-
- /* Maintain xaction_peers on per transaction basis */
- npeers = gd_build_local_xaction_peers_list (&conf->peers,
- &xaction_peers, op);
- if (npeers == -1) {
- gf_log (this->name, GF_LOG_ERROR, "building local peers list "
- "failed");
- goto out;
- }
-
- /* If no volname is given as a part of the command, locks will
- * not be held */
- if (volname || cluster_lock) {
- ret = gd_lock_op_phase (conf, op, op_ctx, &op_errstr,
- npeers, *txn_id, &xaction_peers,
- cluster_lock);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Locking Peers Failed.");
- goto out;
- }
- }
-
- ret = glusterd_op_build_payload (&req_dict, &op_errstr, op_ctx);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, LOGSTR_BUILD_PAYLOAD,
- gd_op_list[op]);
- if (op_errstr == NULL)
- gf_asprintf (&op_errstr, OPERRSTR_BUILD_PAYLOAD);
- goto out;
- }
-
- ret = gd_stage_op_phase (&xaction_peers, op, op_ctx, req_dict,
- &op_errstr, npeers);
- if (ret)
- goto out;
-
- ret = gd_brick_op_phase (op, op_ctx, req_dict, &op_errstr);
- if (ret)
- goto out;
-
- ret = gd_commit_op_phase (&xaction_peers, op, op_ctx, req_dict,
- &op_errstr, npeers);
- if (ret)
- goto out;
-
- ret = 0;
-out:
- op_ret = ret;
- if (txn_id) {
- (void) gd_unlock_op_phase (conf, op, &op_ret, req,
- op_ctx, op_errstr,
- npeers, volname,
- is_acquired, *txn_id,
- &xaction_peers, cluster_lock);
-
- /* Clearing the transaction opinfo */
- ret = glusterd_clear_txn_opinfo (txn_id);
- if (ret)
- gf_log (this->name, GF_LOG_ERROR,
- "Unable to clear transaction's "
- "opinfo for transaction ID : %s",
- uuid_utoa (*txn_id));
- }
-
- glusterd_op_send_cli_response (op, op_ret, 0, req, op_ctx, op_errstr);
-
- gd_cleanup_local_xaction_peers_list (&xaction_peers);
-
- if (volname)
- GF_FREE (volname);
-
- if (req_dict)
- dict_unref (req_dict);
-
- if (op_errstr) {
- GF_FREE (op_errstr);
- op_errstr = NULL;
- }
-
- return;
-}
-
-int32_t
-glusterd_op_begin_synctask (rpcsvc_request_t *req, glusterd_op_t op,
- void *dict)
-{
- int ret = 0;
-
- 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;
- }
-
- gd_sync_task_begin (dict, req);
- ret = 0;
-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 cdc65a3e931..00000000000
--- a/xlators/mgmt/glusterd/src/glusterd-syncop.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- Copyright (c) 2012-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 __RPC_SYNCOP_H
-#define __RPC_SYNCOP_H
-
-#include "syncop.h"
-#include "glusterd-sm.h"
-#include "glusterd.h"
-
-#define GD_SYNC_OPCODE_KEY "sync-mgmt-operation"
-
-/* gd_syncop_* */
-#define GD_SYNCOP(rpc, stb, cookie, cbk, req, prog, procnum, xdrproc) do { \
- int ret = 0; \
- struct synctask *task = NULL; \
- glusterd_conf_t *conf= THIS->private; \
- \
- task = synctask_get (); \
- stb->task = task; \
- \
- /*This is to ensure that the brick_op_cbk is able to \
- * take the big lock*/ \
- synclock_unlock (&conf->big_lock); \
- ret = gd_syncop_submit_request (rpc, req, stb, cookie, \
- prog, procnum, cbk, \
- (xdrproc_t)xdrproc); \
- if (!ret) \
- synctask_yield (stb->task); \
- synclock_lock (&conf->big_lock); \
- } while (0)
-
-int gd_syncop_submit_request (struct rpc_clnt *rpc, void *req, void *local,
- void *cookie, rpc_clnt_prog_t *prog, int procnum,
- fop_cbk_fn_t cbkfn, xdrproc_t xdrproc);
-int gd_syncop_mgmt_lock (glusterd_peerinfo_t *peerinfo, struct syncargs *arg,
- uuid_t my_uuid, uuid_t recv_uuid);
-int gd_syncop_mgmt_unlock (glusterd_peerinfo_t *peerinfo, struct syncargs *arg,
- uuid_t my_uuid, uuid_t recv_uuid);
-int gd_syncop_mgmt_stage_op (struct rpc_clnt *rpc, struct syncargs *arg,
- uuid_t my_uuid, uuid_t recv_uuid, int op,
- dict_t *dict_out, dict_t *op_ctx);
-int gd_syncop_mgmt_commit_op (struct rpc_clnt *rpc, struct syncargs *arg,
- uuid_t my_uuid, uuid_t recv_uuid, int op,
- dict_t *dict_out, dict_t *op_ctx);
-
-void
-gd_synctask_barrier_wait (struct syncargs *args, int count);
-
-int
-gd_build_peers_list (struct list_head *peers, struct list_head *xact_peers,
- glusterd_op_t op);
-
-int
-gd_build_local_xaction_peers_list (struct list_head *peers,
- struct list_head *xact_peers,
- glusterd_op_t op);
-
-int
-gd_brick_op_phase (glusterd_op_t op, dict_t *op_ctx, dict_t *req_dict,
- char **op_errstr);
-
-int
-glusterd_syncop_aggr_rsp_dict (glusterd_op_t op, dict_t *aggr, dict_t *rsp);
-
-void
-gd_syncargs_init (struct syncargs *args, dict_t *op_ctx);
-#endif /* __RPC_SYNCOP_H */
diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.c b/xlators/mgmt/glusterd/src/glusterd-utils.c
deleted file mode 100644
index 6275ae9a761..00000000000
--- a/xlators/mgmt/glusterd/src/glusterd-utils.c
+++ /dev/null
@@ -1,13832 +0,0 @@
-/*
- Copyright (c) 2006-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 <inttypes.h>
-
-#if defined(GF_LINUX_HOST_OS)
-#include <mntent.h>
-#else
-#include "mntent_compat.h"
-#endif
-
-#include "globals.h"
-#include "glusterfs.h"
-#include "compat.h"
-#include "dict.h"
-#include "xlator.h"
-#include "logging.h"
-#include "glusterd-messages.h"
-#include "timer.h"
-#include "defaults.h"
-#include "compat.h"
-#include "syncop.h"
-#include "run.h"
-#include "compat-errno.h"
-#include "statedump.h"
-#include "syscall.h"
-#include "glusterd-mem-types.h"
-#include "glusterd.h"
-#include "glusterd-op-sm.h"
-#include "glusterd-sm.h"
-#include "glusterd-utils.h"
-#include "glusterd-store.h"
-#include "glusterd-volgen.h"
-#include "glusterd-pmap.h"
-#include "glusterfs-acl.h"
-#include "glusterd-syncop.h"
-#include "glusterd-locks.h"
-#include "glusterd-messages.h"
-
-#include "xdr-generic.h"
-#include <sys/resource.h>
-#include <inttypes.h>
-#include <signal.h>
-#include <sys/types.h>
-#include <sys/ioctl.h>
-#include <sys/socket.h>
-#include <rpc/pmap_clnt.h>
-#include <unistd.h>
-#include <fnmatch.h>
-#include <sys/statvfs.h>
-#include <ifaddrs.h>
-#ifdef HAVE_BD_XLATOR
-#include <lvm2app.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 CEILING_POS(X) (((X)-(int)(X)) > 0 ? (int)((X)+1) : (int)(X))
-
-static glusterd_lock_t lock;
-
-
-int32_t
-glusterd_get_lock_owner (uuid_t *uuid)
-{
- uuid_copy (*uuid, lock.owner) ;
- return 0;
-}
-
-static int32_t
-glusterd_set_lock_owner (uuid_t owner)
-{
- uuid_copy (lock.owner, owner);
- //TODO: set timestamp
- return 0;
-}
-
-static int32_t
-glusterd_unset_lock_owner (uuid_t owner)
-{
- uuid_clear (lock.owner);
- //TODO: set timestamp
- return 0;
-}
-
-gf_boolean_t
-glusterd_is_fuse_available ()
-{
-
- int fd = 0;
-
-#ifdef __NetBSD__
- fd = open ("/dev/puffs", O_RDWR);
-#else
- fd = open ("/dev/fuse", O_RDWR);
-#endif
-
- if (fd > -1 && !close (fd))
- return _gf_true;
- else
- return _gf_false;
-}
-
-int32_t
-glusterd_lock (uuid_t uuid)
-{
-
- uuid_t owner;
- char new_owner_str[50];
- char owner_str[50];
- int ret = -1;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
-
- GF_ASSERT (uuid);
-
- glusterd_get_lock_owner (&owner);
-
- if (!uuid_is_null (owner)) {
- gf_log (this->name, GF_LOG_ERROR, "Unable to get lock"
- " for uuid: %s, lock held by: %s",
- uuid_utoa_r (uuid, new_owner_str),
- uuid_utoa_r (owner, owner_str));
- goto out;
- }
-
- ret = glusterd_set_lock_owner (uuid);
-
- if (!ret) {
- gf_log (this->name, GF_LOG_DEBUG, "Cluster lock held by"
- " %s", uuid_utoa (uuid));
- }
-
-out:
- return ret;
-}
-
-
-int32_t
-glusterd_unlock (uuid_t uuid)
-{
- uuid_t owner;
- char new_owner_str[50];
- char owner_str[50];
- int32_t ret = -1;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
-
- GF_ASSERT (uuid);
-
- glusterd_get_lock_owner (&owner);
-
- if (uuid_is_null (owner)) {
- gf_log (this->name, GF_LOG_ERROR, "Cluster lock not held!");
- goto out;
- }
-
- ret = uuid_compare (uuid, owner);
-
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Cluster lock held by %s ,"
- "unlock req from %s!", uuid_utoa_r (owner ,owner_str)
- , uuid_utoa_r (uuid, new_owner_str));
- goto out;
- }
-
- ret = glusterd_unset_lock_owner (uuid);
-
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Unable to clear cluster "
- "lock");
- goto out;
- }
-
- ret = 0;
-
-out:
- return ret;
-}
-
-
-int
-glusterd_get_uuid (uuid_t *uuid)
-{
- glusterd_conf_t *priv = NULL;
-
- priv = THIS->private;
-
- GF_ASSERT (priv);
-
- uuid_copy (*uuid, MY_UUID);
-
- return 0;
-}
-
-int
-glusterd_submit_request_unlocked (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)
-{
- char new_iobref = 0;
- int ret = -1;
- int count = 0;
- ssize_t req_size = 0;
- struct iobuf *iobuf = NULL;
- struct iovec iov = {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;
- };
-
- if (!iobref) {
- iobref = iobref_new ();
- if (!iobref) {
- goto out;
- }
-
- new_iobref = 1;
- }
-
- 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;
- }
-
- /* Send the msg */
- ret = rpc_clnt_submit (rpc, prog, procnum, cbkfn,
- &iov, count,
- NULL, 0, iobref, frame, NULL, 0, NULL, 0, NULL);
-out:
- if (new_iobref) {
- iobref_unref (iobref);
- }
-
- iobuf_unref (iobuf);
-
- return ret;
-}
-
-
-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)
-{
- glusterd_conf_t *priv = THIS->private;
- int ret = -1;
-
- synclock_unlock (&priv->big_lock);
- {
- ret = glusterd_submit_request_unlocked (rpc, req, frame, prog,
- procnum, iobref, this,
- cbkfn, xdrproc);
- }
- synclock_lock (&priv->big_lock);
-
- return ret;
-}
-
-
-struct iobuf *
-glusterd_serialize_reply (rpcsvc_request_t *req, void *arg,
- struct iovec *outmsg, xdrproc_t xdrproc)
-{
- 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);
- if (!iob) {
- gf_log ("", 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) {
- gf_log ("", GF_LOG_ERROR, "Failed to encode message");
- goto ret;
- }
-
- outmsg->iov_len = retlen;
-ret:
- if (retlen == -1) {
- iobuf_unref (iob);
- iob = NULL;
- }
-
- return iob;
-}
-
-int
-glusterd_submit_reply (rpcsvc_request_t *req, void *arg,
- struct iovec *payload, int payloadcount,
- struct iobref *iobref, xdrproc_t xdrproc)
-{
- struct iobuf *iob = NULL;
- int ret = -1;
- struct iovec rsp = {0,};
- char new_iobref = 0;
-
- if (!req) {
- GF_ASSERT (req);
- goto out;
- }
-
- if (!iobref) {
- iobref = iobref_new ();
- if (!iobref) {
- gf_log ("", GF_LOG_ERROR, "out of memory");
- goto out;
- }
-
- new_iobref = 1;
- }
-
- iob = glusterd_serialize_reply (req, arg, &rsp, xdrproc);
- if (!iob) {
- gf_log ("", GF_LOG_ERROR, "Failed to serialize reply");
- } else {
- iobref_add (iobref, iob);
- }
-
- ret = rpcsvc_submit_generic (req, &rsp, 1, payload, payloadcount,
- 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.
- */
- if (ret == -1) {
- gf_log ("", GF_LOG_ERROR, "Reply submission failed");
- goto out;
- }
-
- ret = 0;
-out:
-
- if (new_iobref) {
- iobref_unref (iobref);
- }
-
- if (iob)
- iobuf_unref (iob);
- return ret;
-}
-
-gf_boolean_t
-glusterd_check_volume_exists (char *volname)
-{
- char pathname[1024] = {0,};
- struct stat stbuf = {0,};
- int32_t ret = -1;
- glusterd_conf_t *priv = NULL;
-
- priv = THIS->private;
-
- snprintf (pathname, 1024, "%s/vols/%s", priv->workdir,
- volname);
-
- ret = stat (pathname, &stbuf);
-
- if (ret) {
- gf_log (THIS->name, GF_LOG_DEBUG, "Volume %s does not exist."
- "stat failed with errno : %d on path: %s",
- volname, errno, pathname);
- return _gf_false;
- }
-
- return _gf_true;
-}
-
-glusterd_volinfo_t *
-glusterd_volinfo_unref (glusterd_volinfo_t *volinfo)
-{
- int refcnt = -1;
-
- pthread_mutex_lock (&volinfo->reflock);
- {
- refcnt = --volinfo->refcnt;
- }
- pthread_mutex_unlock (&volinfo->reflock);
-
- if (!refcnt) {
- glusterd_volinfo_delete (volinfo);
- return NULL;
- }
-
- return volinfo;
-}
-
-glusterd_volinfo_t *
-glusterd_volinfo_ref (glusterd_volinfo_t *volinfo)
-{
- pthread_mutex_lock (&volinfo->reflock);
- {
- ++volinfo->refcnt;
- }
- pthread_mutex_unlock (&volinfo->reflock);
-
- return volinfo;
-}
-
-int32_t
-glusterd_volinfo_new (glusterd_volinfo_t **volinfo)
-{
- glusterd_volinfo_t *new_volinfo = NULL;
- int32_t ret = -1;
-
- GF_ASSERT (volinfo);
-
- new_volinfo = GF_CALLOC (1, sizeof(*new_volinfo),
- gf_gld_mt_glusterd_volinfo_t);
-
- if (!new_volinfo)
- goto out;
-
- LOCK_INIT (&new_volinfo->lock);
- INIT_LIST_HEAD (&new_volinfo->vol_list);
- INIT_LIST_HEAD (&new_volinfo->snapvol_list);
- INIT_LIST_HEAD (&new_volinfo->bricks);
- INIT_LIST_HEAD (&new_volinfo->snap_volumes);
-
- new_volinfo->dict = dict_new ();
- if (!new_volinfo->dict) {
- GF_FREE (new_volinfo);
-
- goto out;
- }
-
- new_volinfo->gsync_slaves = dict_new ();
- if (!new_volinfo->gsync_slaves) {
- dict_unref (new_volinfo->dict);
- GF_FREE (new_volinfo);
- goto out;
- }
-
- new_volinfo->gsync_active_slaves = dict_new ();
- if (!new_volinfo->gsync_active_slaves) {
- dict_unref (new_volinfo->dict);
- dict_unref (new_volinfo->gsync_slaves);
- GF_FREE (new_volinfo);
- goto out;
- }
-
- snprintf (new_volinfo->parent_volname, GD_VOLUME_NAME_MAX, "N/A");
-
- new_volinfo->snap_max_hard_limit = GLUSTERD_SNAPS_MAX_HARD_LIMIT;
-
- new_volinfo->xl = THIS;
-
- pthread_mutex_init (&new_volinfo->reflock, NULL);
- *volinfo = glusterd_volinfo_ref (new_volinfo);
-
- ret = 0;
-
-out:
- gf_log (THIS->name, GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-
-/* This function will create a new volinfo and then
- * dup the entries from volinfo to the new_volinfo.
- *
- * @param volinfo volinfo which will be duplicated
- * @param dup_volinfo new volinfo which will be created
- * @param set_userauth if this true then auth info is also set
- *
- * @return 0 on success else -1
- */
-int32_t
-glusterd_volinfo_dup (glusterd_volinfo_t *volinfo,
- glusterd_volinfo_t **dup_volinfo,
- gf_boolean_t set_userauth)
-{
- int32_t ret = -1;
- xlator_t *this = NULL;
- glusterd_volinfo_t *new_volinfo = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- GF_VALIDATE_OR_GOTO (this->name, volinfo, out);
- GF_VALIDATE_OR_GOTO (this->name, dup_volinfo, out);
-
- ret = glusterd_volinfo_new (&new_volinfo);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "not able to create the "
- "duplicate volinfo for the volume %s",
- volinfo->volname);
- goto out;
- }
-
- new_volinfo->type = volinfo->type;
- new_volinfo->replica_count = volinfo->replica_count;
- new_volinfo->stripe_count = volinfo->stripe_count;
- new_volinfo->disperse_count = volinfo->disperse_count;
- new_volinfo->redundancy_count = volinfo->redundancy_count;
- new_volinfo->dist_leaf_count = volinfo->dist_leaf_count;
- new_volinfo->sub_count = volinfo->sub_count;
- new_volinfo->transport_type = volinfo->transport_type;
- new_volinfo->brick_count = volinfo->brick_count;
-
- dict_copy (volinfo->dict, new_volinfo->dict);
- dict_copy (volinfo->gsync_slaves, new_volinfo->gsync_slaves);
- dict_copy (volinfo->gsync_active_slaves,
- new_volinfo->gsync_active_slaves);
- gd_update_volume_op_versions (new_volinfo);
-
- if (set_userauth) {
- glusterd_auth_set_username (new_volinfo,
- volinfo->auth.username);
- glusterd_auth_set_password (new_volinfo,
- volinfo->auth.password);
- }
-
- *dup_volinfo = new_volinfo;
- ret = 0;
-out:
- if (ret && (NULL != new_volinfo)) {
- (void) glusterd_volinfo_delete (new_volinfo);
- }
- return ret;
-}
-
-/* This function will duplicate brickinfo
- *
- * @param brickinfo Source brickinfo
- * @param dup_brickinfo Destination brickinfo
- *
- * @return 0 on success else -1
- */
-int32_t
-glusterd_brickinfo_dup (glusterd_brickinfo_t *brickinfo,
- glusterd_brickinfo_t *dup_brickinfo)
-{
- int32_t ret = -1;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
-
- GF_VALIDATE_OR_GOTO (this->name, brickinfo, out);
- GF_VALIDATE_OR_GOTO (this->name, dup_brickinfo, out);
-
- strcpy (dup_brickinfo->hostname, brickinfo->hostname);
- strcpy (dup_brickinfo->path, brickinfo->path);
- strcpy (dup_brickinfo->device_path, brickinfo->device_path);
- strcpy (dup_brickinfo->fstype, brickinfo->fstype);
- strcpy (dup_brickinfo->mnt_opts, brickinfo->mnt_opts);
- ret = gf_canonicalize_path (dup_brickinfo->path);
- if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR, "Failed to canonicalize "
- "brick path");
- goto out;
- }
- uuid_copy (dup_brickinfo->uuid, brickinfo->uuid);
-
- dup_brickinfo->port = brickinfo->port;
- dup_brickinfo->rdma_port = brickinfo->rdma_port;
- if (NULL != brickinfo->logfile) {
- dup_brickinfo->logfile = gf_strdup (brickinfo->logfile);
- if (NULL == dup_brickinfo->logfile) {
- ret = -1;
- goto out;
- }
- }
- strcpy (dup_brickinfo->brick_id, brickinfo->brick_id);
- strcpy (dup_brickinfo->mount_dir, brickinfo->mount_dir);
- dup_brickinfo->status = brickinfo->status;
- dup_brickinfo->snap_status = brickinfo->snap_status;
-out:
- return ret;
-}
-/*
- * gd_vol_is_geo_rep_active:
- * This function checks for any running geo-rep session for
- * the volume given.
- *
- * Return Value:
- * _gf_true : If any running geo-rep session.
- * _gf_false: If no running geo-rep session.
- */
-
-gf_boolean_t
-gd_vol_is_geo_rep_active (glusterd_volinfo_t *volinfo)
-{
- gf_boolean_t active = _gf_false;
-
- GF_ASSERT (volinfo);
-
- if (volinfo->gsync_active_slaves &&
- volinfo->gsync_active_slaves->count > 0)
- active = _gf_true;
-
- return active;
-}
-
-/*
- * glusterd_snap_geo_rep_restore:
- * This function restores the atime and mtime of marker.tstamp
- * if present from snapped marker.tstamp file.
- */
-static int
-glusterd_snap_geo_rep_restore (glusterd_volinfo_t *snap_volinfo,
- glusterd_volinfo_t *new_volinfo)
-{
- char vol_tstamp_file[PATH_MAX] = {0,};
- char snap_tstamp_file[PATH_MAX] = {0,};
- glusterd_conf_t *priv = NULL;
- xlator_t *this = NULL;
- int geo_rep_indexing_on = 0;
- int ret = 0;
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (snap_volinfo);
- GF_ASSERT (new_volinfo);
-
- priv = this->private;
- GF_ASSERT (priv);
-
- /* Check if geo-rep indexing is enabled, if yes, we need restore
- * back the mtime of 'marker.tstamp' file.
- */
- geo_rep_indexing_on = glusterd_volinfo_get_boolean (new_volinfo,
- VKEY_MARKER_XTIME);
- if (geo_rep_indexing_on == -1) {
- gf_log (this->name, GF_LOG_DEBUG, "Failed"
- " to check whether geo-rep-indexing enabled or not");
- ret = 0;
- goto out;
- }
-
- if (geo_rep_indexing_on == 1) {
- GLUSTERD_GET_VOLUME_DIR (vol_tstamp_file, new_volinfo, priv);
- strncat (vol_tstamp_file, "/marker.tstamp",
- PATH_MAX - strlen(vol_tstamp_file) - 1);
- GLUSTERD_GET_VOLUME_DIR (snap_tstamp_file, snap_volinfo, priv);
- strncat (snap_tstamp_file, "/marker.tstamp",
- PATH_MAX - strlen(snap_tstamp_file) - 1);
- ret = gf_set_timestamp (snap_tstamp_file, vol_tstamp_file);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Unable to set atime and mtime of %s as of %s",
- vol_tstamp_file, snap_tstamp_file);
- goto out;
- }
- }
-
-out:
- return ret;
-}
-
-/* This function will copy snap volinfo to the new
- * passed volinfo and regenerate backend store files
- * for the restored snap.
- *
- * @param new_volinfo new volinfo
- * @param snap_volinfo volinfo of snap volume
- *
- * @return 0 on success and -1 on failure
- *
- * TODO: Duplicate all members of volinfo, e.g. geo-rep sync slaves
- */
-int32_t
-glusterd_snap_volinfo_restore (dict_t *dict, dict_t *rsp_dict,
- glusterd_volinfo_t *new_volinfo,
- glusterd_volinfo_t *snap_volinfo,
- int32_t volcount)
-{
- char *value = NULL;
- char key[PATH_MAX] = "";
- int32_t brick_count = -1;
- int32_t ret = -1;
- xlator_t *this = NULL;
- glusterd_brickinfo_t *brickinfo = NULL;
- glusterd_brickinfo_t *new_brickinfo = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (dict);
- GF_ASSERT (rsp_dict);
-
- GF_VALIDATE_OR_GOTO (this->name, new_volinfo, out);
- GF_VALIDATE_OR_GOTO (this->name, snap_volinfo, out);
-
- brick_count = 0;
- list_for_each_entry (brickinfo, &snap_volinfo->bricks, brick_list) {
- brick_count++;
- ret = glusterd_brickinfo_new (&new_brickinfo);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to create "
- "new brickinfo");
- goto out;
- }
-
- /* Duplicate brickinfo */
- ret = glusterd_brickinfo_dup (brickinfo, new_brickinfo);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to dup "
- "brickinfo");
- goto out;
- }
-
- /* Fetch values if present in dict These values won't
- * be present in case of a missed restore. In that case
- * it's fine to use the local node's value
- */
- snprintf (key, sizeof (key), "snap%d.brick%d.path",
- volcount, brick_count);
- ret = dict_get_str (dict, key, &value);
- if (!ret)
- strncpy (new_brickinfo->path, value,
- sizeof(new_brickinfo->path));
-
- snprintf (key, sizeof (key), "snap%d.brick%d.snap_status",
- volcount, brick_count);
- ret = dict_get_int32 (dict, key, &new_brickinfo->snap_status);
-
- snprintf (key, sizeof (key), "snap%d.brick%d.device_path",
- volcount, brick_count);
- ret = dict_get_str (dict, key, &value);
- if (!ret)
- strncpy (new_brickinfo->device_path, value,
- sizeof(new_brickinfo->device_path));
-
- snprintf (key, sizeof (key), "snap%d.brick%d.fs_type",
- volcount, brick_count);
- ret = dict_get_str (dict, key, &value);
- if (!ret)
- strncpy (new_brickinfo->fstype, value,
- sizeof(new_brickinfo->fstype));
-
- snprintf (key, sizeof (key), "snap%d.brick%d.mnt_opts",
- volcount, brick_count);
- ret = dict_get_str (dict, key, &value);
- if (!ret)
- strncpy (new_brickinfo->mnt_opts, value,
- sizeof(new_brickinfo->mnt_opts));
-
- /* If the brick is not of this peer, or snapshot is missed *
- * for the brick do not replace the xattr for it */
- if ((!uuid_compare (brickinfo->uuid, MY_UUID)) &&
- (brickinfo->snap_status != -1)) {
- /* We need to replace the volume id of all the bricks
- * to the volume id of the origin volume. new_volinfo
- * has the origin volume's volume id*/
- ret = sys_lsetxattr (new_brickinfo->path,
- GF_XATTR_VOL_ID_KEY,
- new_volinfo->volume_id,
- sizeof (new_volinfo->volume_id),
- XATTR_REPLACE);
- if (ret == -1) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to "
- "set extended attribute %s on %s. "
- "Reason: %s, snap: %s",
- GF_XATTR_VOL_ID_KEY,
- new_brickinfo->path, strerror (errno),
- new_volinfo->volname);
- goto out;
- }
- }
-
- /* If a snapshot is pending for this brick then
- * restore should also be pending
- */
- if (brickinfo->snap_status == -1) {
- /* Adding missed delete to the dict */
- ret = glusterd_add_missed_snaps_to_dict
- (rsp_dict,
- snap_volinfo,
- brickinfo,
- brick_count,
- GF_SNAP_OPTION_TYPE_RESTORE);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to add missed snapshot info "
- "for %s:%s in the rsp_dict",
- brickinfo->hostname,
- brickinfo->path);
- goto out;
- }
- }
-
- list_add_tail (&new_brickinfo->brick_list,
- &new_volinfo->bricks);
- /* ownership of new_brickinfo is passed to new_volinfo */
- new_brickinfo = NULL;
- }
-
- /* Regenerate all volfiles */
- ret = glusterd_create_volfiles_and_notify_services (new_volinfo);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to regenerate volfiles");
- goto out;
- }
-
- /* Restore geo-rep marker.tstamp's timestamp */
- ret = glusterd_snap_geo_rep_restore (snap_volinfo, new_volinfo);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Geo-rep: marker.tstamp's timestamp restoration failed");
- goto out;
- }
-
-out:
- if (ret && (NULL != new_brickinfo)) {
- (void) glusterd_brickinfo_delete (new_brickinfo);
- }
-
- 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)
-{
- int32_t ret = -1;
-
- GF_ASSERT (brickinfo);
-
- list_del_init (&brickinfo->brick_list);
-
- GF_FREE (brickinfo->logfile);
- GF_FREE (brickinfo);
-
- ret = 0;
-
- return ret;
-}
-
-int32_t
-glusterd_volume_brickinfos_delete (glusterd_volinfo_t *volinfo)
-{
- glusterd_brickinfo_t *brickinfo = NULL;
- glusterd_brickinfo_t *tmp = NULL;
- int32_t ret = 0;
-
- GF_ASSERT (volinfo);
-
- list_for_each_entry_safe (brickinfo, tmp, &volinfo->bricks,
- brick_list) {
- ret = glusterd_brickinfo_delete (brickinfo);
- if (ret)
- goto out;
- }
-
-out:
- gf_log (THIS->name, GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-
-int
-glusterd_volinfo_remove (glusterd_volinfo_t *volinfo)
-{
- list_del_init (&volinfo->vol_list);
- glusterd_volinfo_unref (volinfo);
- return 0;
-}
-
-int32_t
-glusterd_volinfo_delete (glusterd_volinfo_t *volinfo)
-{
- int32_t ret = -1;
-
- GF_ASSERT (volinfo);
-
- list_del_init (&volinfo->vol_list);
- list_del_init (&volinfo->snapvol_list);
-
- ret = glusterd_volume_brickinfos_delete (volinfo);
- if (ret)
- goto out;
- if (volinfo->dict)
- dict_unref (volinfo->dict);
- if (volinfo->gsync_slaves)
- dict_unref (volinfo->gsync_slaves);
- if (volinfo->gsync_active_slaves)
- dict_unref (volinfo->gsync_active_slaves);
- GF_FREE (volinfo->logdir);
- if (volinfo->rebal.dict)
- dict_unref (volinfo->rebal.dict);
-
- gf_store_handle_destroy (volinfo->quota_conf_shandle);
-
- glusterd_auth_cleanup (volinfo);
-
- pthread_mutex_destroy (&volinfo->reflock);
- GF_FREE (volinfo);
- ret = 0;
-
-out:
- gf_log (THIS->name, GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-
-int32_t
-glusterd_brickinfo_new (glusterd_brickinfo_t **brickinfo)
-{
- glusterd_brickinfo_t *new_brickinfo = NULL;
- int32_t ret = -1;
-
- GF_ASSERT (brickinfo);
-
- new_brickinfo = GF_CALLOC (1, sizeof(*new_brickinfo),
- gf_gld_mt_glusterd_brickinfo_t);
-
- if (!new_brickinfo)
- goto out;
-
- INIT_LIST_HEAD (&new_brickinfo->brick_list);
-
- *brickinfo = new_brickinfo;
-
- ret = 0;
-
-out:
- gf_log (THIS->name, GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-
-int
-glusterd_get_next_available_brickid (glusterd_volinfo_t *volinfo)
-{
- glusterd_brickinfo_t *brickinfo = NULL;
- char *token = NULL;
- int brickid = 0;
- int max_brickid = -1;
- int ret = -1;
-
- list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) {
- token = strrchr (brickinfo->brick_id, '-');
- ret = gf_string2int32 (++token, &brickid);
- if (ret < 0) {
- gf_log (THIS->name, GF_LOG_ERROR,
- "Unable to generate brick ID");
- return ret;
- }
- if (brickid > max_brickid)
- max_brickid = brickid;
- }
-
- return max_brickid + 1 ;
-}
-
-int32_t
-glusterd_resolve_brick (glusterd_brickinfo_t *brickinfo)
-{
- int32_t ret = -1;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
-
- GF_ASSERT (brickinfo);
-
- ret = glusterd_hostname_to_uuid (brickinfo->hostname, brickinfo->uuid);
- gf_log (this->name, GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-
-int32_t
-glusterd_get_brick_mount_dir (char *brickpath, char *hostname, char *mount_dir)
-{
- char *mnt_pt = NULL;
- char *brick_dir = NULL;
- int32_t ret = -1;
- uuid_t brick_uuid = {0, };
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (brickpath);
- GF_ASSERT (hostname);
- GF_ASSERT (mount_dir);
-
- ret = glusterd_hostname_to_uuid (hostname, brick_uuid);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to convert hostname %s to uuid",
- hostname);
- goto out;
- }
-
- if (!uuid_compare (brick_uuid, MY_UUID)) {
- ret = glusterd_get_brick_root (brickpath, &mnt_pt);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING,
- "Could not get the root of the brick path %s",
- brickpath);
- goto out;
- }
-
- if (strncmp (brickpath, mnt_pt, strlen(mnt_pt))) {
- gf_log (this->name, GF_LOG_WARNING,
- "brick: %s brick mount: %s",
- brickpath, mnt_pt);
- ret = -1;
- goto out;
- }
-
- brick_dir = &brickpath[strlen (mnt_pt)];
- brick_dir++;
-
- snprintf (mount_dir, PATH_MAX, "/%s", brick_dir);
- }
-
-out:
- gf_log (this->name, GF_LOG_TRACE, "Returning %d", ret);
- return ret;
-}
-
-int32_t
-glusterd_brickinfo_new_from_brick (char *brick,
- glusterd_brickinfo_t **brickinfo)
-{
- char *hostname = NULL;
- char *path = NULL;
- char *tmp_host = NULL;
- char *tmp_path = NULL;
- char *vg = NULL;
- int32_t ret = -1;
- glusterd_brickinfo_t *new_brickinfo = NULL;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- 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))
- goto out;
-
- GF_ASSERT (hostname);
- GF_ASSERT (path);
-
- ret = glusterd_brickinfo_new (&new_brickinfo);
- if (ret)
- goto out;
-
-#ifdef HAVE_BD_XLATOR
- vg = strchr (path, '?');
- /* ? is used as a delimiter for vg */
- if (vg) {
- strncpy (new_brickinfo->vg, vg + 1, PATH_MAX - 1);
- *vg = '\0';
- }
- new_brickinfo->caps = CAPS_BD;
-#else
- vg = NULL; /* Avoid compiler warnings when BD not enabled */
-#endif
- ret = gf_canonicalize_path (path);
- if (ret)
- goto out;
-
- strncpy (new_brickinfo->hostname, hostname, 1024);
- strncpy (new_brickinfo->path, path, 1024);
-
- *brickinfo = new_brickinfo;
-
- ret = 0;
-out:
- GF_FREE (tmp_host);
- if (tmp_host)
- GF_FREE (tmp_path);
-
- gf_log (this->name, 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 len1 = 0;
- int len2 = 0;
- int small_len = 0;
- char *bigger = NULL;
- gf_boolean_t prefix = _gf_true;
-
- len1 = strlen (str1);
- len2 = strlen (str2);
- small_len = min (len1, len2);
- for (i = 0; i < small_len; i++) {
- if (str1[i] != str2[i]) {
- prefix = _gf_false;
- break;
- }
- }
-
- if (len1 < len2)
- bigger = str2;
-
- else if (len1 > len2)
- bigger = str1;
-
- else
- return prefix;
-
- if (bigger[small_len] != '/')
- prefix = _gf_false;
-
- 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)) {
- if (errno != ENOENT) {
- goto out;
- }
- /* When realpath(3) fails, tmp_path is undefined. */
- strncpy(tmp_path,path,PATH_MAX);
- }
-
- 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)) {
- if (errno == ENOENT)
- strncpy (tmp_brickpath, brickinfo->path,
- PATH_MAX);
- else
- goto out;
- }
-
- if (_is_prefix (tmp_brickpath, tmp_path))
- goto out;
- }
- }
- available = _gf_true;
-out:
- return available;
-}
-
-#ifdef HAVE_BD_XLATOR
-/*
- * Sets the tag of the format "trusted.glusterfs.volume-id:<uuid>" in
- * the brick VG. It is used to avoid using same VG for another brick.
- * @volume-id - gfid, @brick - brick info, @msg - Error message returned
- * to the caller
- */
-int
-glusterd_bd_set_vg_tag (unsigned char *volume_id, glusterd_brickinfo_t *brick,
- char *msg, int msg_size)
-{
- lvm_t handle = NULL;
- vg_t vg = NULL;
- char *uuid = NULL;
- int ret = -1;
-
- gf_asprintf (&uuid, "%s:%s", GF_XATTR_VOL_ID_KEY,
- uuid_utoa (volume_id));
- if (!uuid) {
- snprintf (msg, sizeof(*msg), "Could not allocate memory "
- "for tag");
- return -1;
- }
-
- handle = lvm_init (NULL);
- if (!handle) {
- snprintf (msg, sizeof(*msg), "lvm_init failed");
- goto out;
- }
-
- vg = lvm_vg_open (handle, brick->vg, "w", 0);
- if (!vg) {
- snprintf (msg, sizeof(*msg), "Could not open VG %s",
- brick->vg);
- goto out;
- }
-
- if (lvm_vg_add_tag (vg, uuid) < 0) {
- snprintf (msg, sizeof(*msg), "Could not set tag %s for "
- "VG %s", uuid, brick->vg);
- goto out;
- }
- lvm_vg_write (vg);
- ret = 0;
-out:
- GF_FREE (uuid);
-
- if (vg)
- lvm_vg_close (vg);
- if (handle)
- lvm_quit (handle);
-
- return ret;
-}
-#endif
-
-int
-glusterd_validate_and_create_brickpath (glusterd_brickinfo_t *brickinfo,
- uuid_t volume_id, char **op_errstr,
- gf_boolean_t is_force)
-{
- int ret = -1;
- char parentdir[PATH_MAX] = {0,};
- struct stat parent_st = {0,};
- struct stat brick_st = {0,};
- struct stat root_st = {0,};
- char msg[2048] = {0,};
- gf_boolean_t is_created = _gf_false;
-
- ret = mkdir (brickinfo->path, 0777);
- if (ret) {
- if (errno != EEXIST) {
- snprintf (msg, sizeof (msg), "Failed to create brick "
- "directory for brick %s:%s. Reason : %s ",
- brickinfo->hostname, brickinfo->path,
- strerror (errno));
- goto out;
- }
- } else {
- is_created = _gf_true;
- }
-
- ret = lstat (brickinfo->path, &brick_st);
- if (ret) {
- snprintf (msg, sizeof (msg), "lstat failed on %s. Reason : %s",
- brickinfo->path, strerror (errno));
- goto out;
- }
-
- if ((!is_created) && (!S_ISDIR (brick_st.st_mode))) {
- snprintf (msg, sizeof (msg), "The provided path %s which is "
- "already present, is not a directory",
- brickinfo->path);
- ret = -1;
- goto out;
- }
-
- snprintf (parentdir, sizeof (parentdir), "%s/..", brickinfo->path);
-
- ret = lstat ("/", &root_st);
- if (ret) {
- snprintf (msg, sizeof (msg), "lstat failed on /. Reason : %s",
- strerror (errno));
- goto out;
- }
-
- ret = lstat (parentdir, &parent_st);
- if (ret) {
- snprintf (msg, sizeof (msg), "lstat failed on %s. Reason : %s",
- parentdir, strerror (errno));
- goto out;
- }
-
- if (!is_force) {
- if (brick_st.st_dev != parent_st.st_dev) {
- snprintf (msg, sizeof (msg), "The brick %s:%s is a "
- "mount point. Please create a sub-directory "
- "under the mount point and use that as the "
- "brick directory. Or use 'force' at the end "
- "of the command if you want to override this "
- "behavior.", brickinfo->hostname,
- brickinfo->path);
- ret = -1;
- goto out;
- }
- else if (parent_st.st_dev == root_st.st_dev) {
- snprintf (msg, sizeof (msg), "The brick %s:%s "
- "is being created in the root partition. It "
- "is recommended that you don't use the "
- "system's root partition for storage backend."
- " Or use 'force' at the end of the command if"
- " you want to override this behavior.",
- brickinfo->hostname, brickinfo->path);
- ret = -1;
- goto out;
- }
- }
-
-#ifdef HAVE_BD_XLATOR
- if (brickinfo->vg[0]) {
- ret = glusterd_bd_set_vg_tag (volume_id, brickinfo, msg,
- sizeof(msg));
- if (ret)
- goto out;
- }
-#endif
- ret = glusterd_check_and_set_brick_xattr (brickinfo->hostname,
- brickinfo->path, volume_id,
- op_errstr, is_force);
- if (ret)
- goto out;
-
- ret = 0;
-
-out:
- if (ret && is_created)
- rmdir (brickinfo->path);
- if (ret && !*op_errstr && msg[0] != '\0')
- *op_errstr = gf_strdup (msg);
-
- return ret;
-}
-
-int32_t
-glusterd_volume_brickinfo_get (uuid_t uuid, char *hostname, char *path,
- glusterd_volinfo_t *volinfo,
- glusterd_brickinfo_t **brickinfo)
-{
- glusterd_brickinfo_t *brickiter = NULL;
- uuid_t peer_uuid = {0};
- int32_t ret = -1;
- xlator_t *this = NULL;
-
- this = THIS;
-
- if (uuid) {
- uuid_copy (peer_uuid, uuid);
- } else {
- ret = glusterd_hostname_to_uuid (hostname, peer_uuid);
- if (ret)
- goto out;
- }
- ret = -1;
- 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_DEBUG, LOGSTR_FOUND_BRICK,
- brickiter->hostname, brickiter->path,
- volinfo->volname);
- ret = 0;
- if (brickinfo)
- *brickinfo = brickiter;
- break;
- }
- }
-
-out:
- gf_log (this->name, GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-
-int32_t
-glusterd_volume_brickinfo_get_by_brick (char *brick,
- glusterd_volinfo_t *volinfo,
- glusterd_brickinfo_t **brickinfo)
-{
- int32_t ret = -1;
- glusterd_brickinfo_t *tmp_brickinfo = NULL;
-
- GF_ASSERT (brick);
- GF_ASSERT (volinfo);
-
- ret = glusterd_brickinfo_new_from_brick (brick, &tmp_brickinfo);
- if (ret)
- goto out;
-
- ret = glusterd_volume_brickinfo_get (NULL, tmp_brickinfo->hostname,
- tmp_brickinfo->path, volinfo,
- brickinfo);
- (void) glusterd_brickinfo_delete (tmp_brickinfo);
-out:
- 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;
-}
-
-int
-glusterd_volinfo_find_by_volume_id (uuid_t volume_id, glusterd_volinfo_t **volinfo)
-{
- int32_t ret = -1;
- xlator_t *this = NULL;
- glusterd_volinfo_t *voliter = NULL;
- glusterd_conf_t *priv = NULL;
-
- if (!volume_id)
- return -1;
-
- this = THIS;
- priv = this->private;
-
- list_for_each_entry (voliter, &priv->volumes, vol_list) {
- if (uuid_compare (volume_id, voliter->volume_id))
- continue;
- *volinfo = voliter;
- ret = 0;
- gf_log (this->name, GF_LOG_DEBUG, "Volume %s found",
- voliter->volname);
- break;
- }
- return ret;
-}
-
-int
-glusterd_snap_volinfo_find_by_volume_id (uuid_t volume_id,
- glusterd_volinfo_t **volinfo)
-{
- int32_t ret = -1;
- xlator_t *this = NULL;
- glusterd_volinfo_t *voliter = NULL;
- glusterd_snap_t *snap = NULL;
- glusterd_conf_t *priv = NULL;
-
- this = THIS;
- priv = this->private;
- GF_ASSERT (priv);
- GF_ASSERT (volinfo);
-
- if (uuid_is_null(volume_id)) {
- gf_log (this->name, GF_LOG_WARNING, "Volume UUID is NULL");
- goto out;
- }
-
- list_for_each_entry (snap, &priv->snapshots, snap_list) {
- list_for_each_entry (voliter, &snap->volumes, vol_list) {
- if (uuid_compare (volume_id, voliter->volume_id))
- continue;
- *volinfo = voliter;
- ret = 0;
- goto out;
- }
- }
-
- gf_log (this->name, GF_LOG_WARNING, "Snap volume not found");
-out:
- gf_log (this->name, GF_LOG_TRACE, "Returning %d", ret);
- return ret;
-}
-
-int32_t
-glusterd_volinfo_find (char *volname, glusterd_volinfo_t **volinfo)
-{
- glusterd_volinfo_t *tmp_volinfo = NULL;
- int32_t ret = -1;
- xlator_t *this = NULL;
- glusterd_conf_t *priv = NULL;
-
- GF_ASSERT (volname);
- this = THIS;
- GF_ASSERT (this);
-
- priv = this->private;
- GF_ASSERT (priv);
-
- list_for_each_entry (tmp_volinfo, &priv->volumes, vol_list) {
- if (!strcmp (tmp_volinfo->volname, volname)) {
- gf_log (this->name, GF_LOG_DEBUG, "Volume %s found",
- volname);
- ret = 0;
- *volinfo = tmp_volinfo;
- break;
- }
- }
-
- gf_log (this->name, GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-
-int32_t
-glusterd_snap_volinfo_find (char *snap_volname, glusterd_snap_t *snap,
- glusterd_volinfo_t **volinfo)
-{
- int32_t ret = -1;
- xlator_t *this = NULL;
- glusterd_volinfo_t *snap_vol = NULL;
- glusterd_conf_t *priv = NULL;
-
- this = THIS;
- priv = this->private;
- GF_ASSERT (priv);
- GF_ASSERT (snap);
- GF_ASSERT (snap_volname);
-
- list_for_each_entry (snap_vol, &snap->volumes, vol_list) {
- if (!strcmp (snap_vol->volname, snap_volname)) {
- ret = 0;
- *volinfo = snap_vol;
- goto out;
- }
- }
-
- gf_log (this->name, GF_LOG_WARNING, "Snap volume %s not found",
- snap_volname);
-out:
- gf_log (this->name, GF_LOG_TRACE, "Returning %d", ret);
- return ret;
-}
-
-int32_t
-glusterd_snap_volinfo_find_from_parent_volname (char *origin_volname,
- glusterd_snap_t *snap,
- glusterd_volinfo_t **volinfo)
-{
- int32_t ret = -1;
- xlator_t *this = NULL;
- glusterd_volinfo_t *snap_vol = NULL;
- glusterd_conf_t *priv = NULL;
-
- this = THIS;
- priv = this->private;
- GF_ASSERT (priv);
- GF_ASSERT (snap);
- GF_ASSERT (origin_volname);
-
- list_for_each_entry (snap_vol, &snap->volumes, vol_list) {
- if (!strcmp (snap_vol->parent_volname, origin_volname)) {
- ret = 0;
- *volinfo = snap_vol;
- goto out;
- }
- }
-
- gf_log (this->name, GF_LOG_DEBUG, "Snap volume not found(snap: %s, "
- "origin-volume: %s", snap->snapname, origin_volname);
-
-out:
- gf_log (this->name, GF_LOG_TRACE, "Returning %d", ret);
- return ret;
-}
-
-int32_t
-glusterd_service_stop (const char *service, char *pidfile, int sig,
- gf_boolean_t force_kill)
-{
- int32_t ret = -1;
- pid_t pid = -1;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- if (!gf_is_service_running (pidfile, &pid)) {
- ret = 0;
- gf_log (this->name, GF_LOG_INFO, "%s already stopped", service);
- goto out;
- }
- gf_log (this->name, GF_LOG_DEBUG, "Stopping gluster %s running in pid: "
- "%d", service, pid);
-
- ret = kill (pid, sig);
- if (ret) {
- switch (errno) {
- case ESRCH:
- gf_log (this->name, GF_LOG_DEBUG, "%s is already stopped",
- service);
- ret = 0;
- goto out;
- default:
- gf_msg (this->name, GF_LOG_ERROR, errno,
- GD_MSG_SVC_KILL_FAIL, "Unable to kill %s "
- "service, reason:%s", service,
- strerror (errno));
- }
- }
- if (!force_kill)
- goto out;
-
- sleep (1);
- if (gf_is_service_running (pidfile, NULL)) {
- ret = kill (pid, SIGKILL);
- if (ret) {
- gf_msg (this->name, GF_LOG_ERROR, errno,
- GD_MSG_PID_KILL_FAIL, "Unable to kill pid:%d, "
- "reason:%s", pid, strerror(errno));
- goto out;
- }
- }
-
- ret = 0;
-out:
- return ret;
-}
-
-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 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;
- GF_ASSERT (len >= expected_file_len);
- this = THIS;
- GF_ASSERT (this);
-
- priv = this->private;
-
- GLUSTERD_GET_VOLUME_DIR (volume_dir, volinfo, priv);
- GLUSTERD_REMOVE_SLASH_FROM_PATH (brickinfo->path, export_path);
- snprintf (sock_filepath, PATH_MAX, "%s/run/%s-%s",
- volume_dir, brickinfo->hostname, export_path);
-
- glusterd_set_socket_filepath (sock_filepath, sockpath, len);
-}
-
-/* connection happens only if it is not aleady connected,
- * reconnections are taken care by rpc-layer
- */
-int32_t
-glusterd_brick_connect (glusterd_volinfo_t *volinfo,
- glusterd_brickinfo_t *brickinfo, char *socketpath)
-{
- int ret = 0;
- char volume_id_str[64];
- char *brickid = NULL;
- dict_t *options = NULL;
- struct rpc_clnt *rpc = NULL;
- glusterd_conf_t *priv = THIS->private;
-
- GF_ASSERT (volinfo);
- GF_ASSERT (brickinfo);
- GF_ASSERT (socketpath);
-
- if (brickinfo->rpc == NULL) {
- /* Setting frame-timeout to 10mins (600seconds).
- * Unix domain sockets ensures that the connection is reliable.
- * The default timeout of 30mins used for unreliable network
- * connections is too long for unix domain socket connections.
- */
- ret = rpc_transport_unix_options_build (&options, socketpath,
- 600);
- if (ret)
- goto out;
-
- uuid_utoa_r (volinfo->volume_id, volume_id_str);
- ret = gf_asprintf (&brickid, "%s:%s:%s", volume_id_str,
- brickinfo->hostname, brickinfo->path);
- if (ret < 0)
- goto out;
-
- ret = glusterd_rpc_create (&rpc, options,
- glusterd_brick_rpc_notify,
- brickid);
- if (ret) {
- GF_FREE (brickid);
- goto out;
- }
- brickinfo->rpc = rpc;
- }
-out:
-
- gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-
-static int
-_mk_rundir_p (glusterd_volinfo_t *volinfo)
-{
- char voldir[PATH_MAX] = {0,};
- char rundir[PATH_MAX] = {0,};
- glusterd_conf_t *priv = NULL;
- xlator_t *this = NULL;
- int ret = -1;
-
- this = THIS;
- priv = this->private;
- GLUSTERD_GET_VOLUME_DIR (voldir, volinfo, priv);
- snprintf (rundir, sizeof (rundir)-1, "%s/run", voldir);
- ret = mkdir_p (rundir, 0777, _gf_true);
- if (ret)
- gf_log (this->name, GF_LOG_ERROR, "Failed to create rundir");
- return ret;
-}
-
-int32_t
-glusterd_volume_start_glusterfs (glusterd_volinfo_t *volinfo,
- glusterd_brickinfo_t *brickinfo,
- gf_boolean_t wait)
-{
- int32_t ret = -1;
- xlator_t *this = NULL;
- glusterd_conf_t *priv = NULL;
- char pidfile[PATH_MAX+1] = {0,};
- char volfile[PATH_MAX] = {0,};
- runner_t runner = {0,};
- char exp_path[PATH_MAX] = {0,};
- char logfile[PATH_MAX] = {0,};
- int port = 0;
- int rdma_port = 0;
- char *bind_address = NULL;
- char socketpath[PATH_MAX] = {0};
- char glusterd_uuid[1024] = {0,};
- char valgrind_logfile[PATH_MAX] = {0};
-
- GF_ASSERT (volinfo);
- GF_ASSERT (brickinfo);
-
- this = THIS;
- GF_ASSERT (this);
-
- priv = this->private;
- GF_ASSERT (priv);
-
- if (brickinfo->snap_status == -1) {
- gf_log (this->name, GF_LOG_INFO,
- "Snapshot is pending on %s:%s. "
- "Hence not starting the brick",
- brickinfo->hostname,
- brickinfo->path);
- ret = 0;
- goto out;
- }
-
- ret = _mk_rundir_p (volinfo);
- if (ret)
- goto out;
-
- glusterd_set_brick_socket_filepath (volinfo, brickinfo, socketpath,
- sizeof (socketpath));
-
- GLUSTERD_GET_BRICK_PIDFILE (pidfile, volinfo, brickinfo, priv);
- if (gf_is_service_running (pidfile, NULL))
- goto connect;
-
- port = brickinfo->port;
- if (!port)
- port = pmap_registry_alloc (THIS);
-
- /* Build the exp_path, before starting the glusterfsd even in
- valgrind mode. Otherwise all the glusterfsd processes start
- writing the valgrind log to the same file.
- */
- GLUSTERD_REMOVE_SLASH_FROM_PATH (brickinfo->path, exp_path);
- runinit (&runner);
-
- if (priv->valgrind) {
- /* Run bricks with 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);
- }
-
- runner_add_args (&runner, "valgrind", "--leak-check=full",
- "--trace-children=yes", "--track-origins=yes",
- NULL);
- runner_argprintf (&runner, "--log-file=%s", valgrind_logfile);
- }
-
- if (volinfo->is_snap_volume) {
- snprintf (volfile, PATH_MAX,"/%s/%s/%s.%s.%s",
- GLUSTERD_VOL_SNAP_DIR_PREFIX,
- volinfo->snapshot->snapname, volinfo->volname,
- brickinfo->hostname, exp_path);
- } else {
- snprintf (volfile, PATH_MAX, "%s.%s.%s", volinfo->volname,
- brickinfo->hostname, exp_path);
- }
-
- if (volinfo->logdir) {
- snprintf (logfile, PATH_MAX, "%s/%s.log",
- volinfo->logdir, exp_path);
- } else {
- snprintf (logfile, PATH_MAX, "%s/bricks/%s.log",
- DEFAULT_LOG_FILE_DIRECTORY, exp_path);
- }
- if (!brickinfo->logfile)
- brickinfo->logfile = gf_strdup (logfile);
-
- (void) snprintf (glusterd_uuid, 1024, "*-posix.glusterd-uuid=%s",
- uuid_utoa (MY_UUID));
- runner_add_args (&runner, SBIN_DIR"/glusterfsd",
- "-s", brickinfo->hostname, "--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 (dict_get_str (this->options, "transport.socket.bind-address",
- &bind_address) == 0) {
- runner_add_arg (&runner, "--xlator-option");
- runner_argprintf (&runner, "transport.socket.bind-address=%s",
- bind_address);
- }
-
- if (volinfo->transport_type == GF_TRANSPORT_RDMA)
- runner_argprintf (&runner, "--volfile-server-transport=rdma");
- else if (volinfo->transport_type == GF_TRANSPORT_BOTH_TCP_RDMA)
- runner_argprintf (&runner,
- "--volfile-server-transport=socket,rdma");
-
- if (volinfo->memory_accounting)
- runner_add_arg (&runner, "--mem-accounting");
-
- runner_log (&runner, "", GF_LOG_DEBUG, "Starting GlusterFS");
- if (wait) {
- synclock_unlock (&priv->big_lock);
- ret = runner_run (&runner);
- synclock_lock (&priv->big_lock);
-
- } else {
- ret = runner_run_nowait (&runner);
- }
-
- if (ret)
- goto out;
-
- brickinfo->port = port;
- brickinfo->rdma_port = rdma_port;
-
-connect:
- ret = glusterd_brick_connect (volinfo, brickinfo, socketpath);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to connect to brick %s:%s on %s",
- brickinfo->hostname, brickinfo->path, socketpath);
- goto out;
- }
-out:
- return ret;
-}
-
-int32_t
-glusterd_brick_unlink_socket_file (glusterd_volinfo_t *volinfo,
- glusterd_brickinfo_t *brickinfo)
-{
- char path[PATH_MAX] = {0,};
- char socketpath[PATH_MAX] = {0};
- xlator_t *this = NULL;
- glusterd_conf_t *priv = NULL;
-
- GF_ASSERT (volinfo);
- GF_ASSERT (brickinfo);
-
- this = THIS;
- GF_ASSERT (this);
-
- priv = this->private;
- GLUSTERD_GET_VOLUME_DIR (path, volinfo, priv);
- glusterd_set_brick_socket_filepath (volinfo, brickinfo, socketpath,
- sizeof (socketpath));
-
- return glusterd_unlink_file (socketpath);
-}
-
-int32_t
-glusterd_brick_disconnect (glusterd_brickinfo_t *brickinfo)
-{
- rpc_clnt_t *rpc = NULL;
- glusterd_conf_t *priv = THIS->private;
-
- GF_ASSERT (brickinfo);
-
- if (!brickinfo) {
- gf_log_callingfn ("glusterd", GF_LOG_WARNING, "!brickinfo");
- return -1;
- }
-
- rpc = brickinfo->rpc;
- brickinfo->rpc = NULL;
-
- if (rpc) {
- glusterd_rpc_clnt_unref (priv, rpc);
- }
-
- return 0;
-}
-
-int32_t
-glusterd_volume_stop_glusterfs (glusterd_volinfo_t *volinfo,
- glusterd_brickinfo_t *brickinfo,
- gf_boolean_t del_brick)
-{
- xlator_t *this = NULL;
- glusterd_conf_t *priv = NULL;
- char pidfile[PATH_MAX] = {0,};
- int ret = 0;
-
- GF_ASSERT (volinfo);
- GF_ASSERT (brickinfo);
-
- this = THIS;
- GF_ASSERT (this);
-
- priv = this->private;
- if (del_brick)
- list_del_init (&brickinfo->brick_list);
-
- if (GLUSTERD_STATUS_STARTED == volinfo->status) {
- (void) glusterd_brick_disconnect (brickinfo);
- GLUSTERD_GET_BRICK_PIDFILE (pidfile, volinfo, brickinfo, priv);
- 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);
- }
- }
-
- if (del_brick)
- glusterd_delete_brick (volinfo, brickinfo);
-
- return ret;
-}
-
-/* Free LINE[0..N-1] and then the LINE buffer. */
-static void
-free_lines (char **line, size_t n)
-{
- size_t i;
- for (i = 0; i < n; i++)
- GF_FREE (line[i]);
- GF_FREE (line);
-}
-
-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;
- void *p;
-
- 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;
- p = GF_REALLOC (lines, n * sizeof (char *));
- if (!p) {
- free_lines (lines, n/2);
- lines = NULL;
- goto out;
- }
- lines = p;
- }
-
- lines[counter] = gf_strdup (buffer);
- }
-
- lines[counter] = NULL;
- /* Reduce allocation to minimal size. */
- p = GF_REALLOC (lines, (counter + 1) * sizeof (char *));
- if (!p) {
- free_lines (lines, counter);
- lines = NULL;
- goto out;
- }
- lines = p;
-
- *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, char *cksum_path,
- char *filepath, gf_boolean_t is_quota_conf,
- uint32_t *cs)
-{
- int32_t ret = -1;
- uint32_t cksum = 0;
- int fd = -1;
- int sort_fd = 0;
- char sort_filepath[PATH_MAX] = {0};
- char *cksum_path_final = NULL;
- char buf[4096] = {0,};
- gf_boolean_t unlink_sortfile = _gf_false;
- glusterd_conf_t *priv = NULL;
- xlator_t *this = NULL;
-
- GF_ASSERT (volinfo);
- this = THIS;
- priv = THIS->private;
- GF_ASSERT (priv);
-
- fd = open (cksum_path, O_RDWR | O_APPEND | O_CREAT| O_TRUNC, 0600);
-
- if (-1 == fd) {
- gf_log (this->name, GF_LOG_ERROR, "Unable to open %s,"
- " errno: %d", cksum_path, errno);
- ret = -1;
- goto out;
- }
-
- if (!is_quota_conf) {
- 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, reason: %s for volume: %s",
- strerror (errno), volinfo->volname);
- goto out;
- } else {
- unlink_sortfile = _gf_true;
- }
-
- /* sort the info file, result in sort_filepath */
-
- ret = glusterd_sort_and_redirect (filepath, sort_fd);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "sorting info file "
- "failed");
- goto out;
- }
-
- ret = close (sort_fd);
- if (ret)
- goto out;
- }
-
- cksum_path_final = is_quota_conf ? filepath : sort_filepath;
-
- ret = get_checksum_for_path (cksum_path_final, &cksum);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "unable to get "
- "checksum for path: %s", cksum_path_final);
- goto out;
- }
- if (!is_quota_conf) {
- snprintf (buf, sizeof (buf), "%s=%u\n", "info", cksum);
- ret = write (fd, buf, strlen (buf));
- if (ret <= 0) {
- ret = -1;
- goto out;
- }
- }
-
- ret = get_checksum_for_file (fd, &cksum);
- if (ret)
- goto out;
-
- *cs = cksum;
-
-out:
- if (fd > 0)
- close (fd);
- if (unlink_sortfile)
- unlink (sort_filepath);
- gf_log (this->name, GF_LOG_DEBUG, "Returning with %d", ret);
-
- return ret;
-}
-
-int glusterd_compute_cksum (glusterd_volinfo_t *volinfo,
- gf_boolean_t is_quota_conf)
-{
- int ret = -1;
- uint32_t cs = 0;
- char cksum_path[PATH_MAX] = {0,};
- char path[PATH_MAX] = {0,};
- char filepath[PATH_MAX] = {0,};
- glusterd_conf_t *conf = NULL;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- conf = this->private;
- GF_ASSERT (conf);
-
- GLUSTERD_GET_VOLUME_DIR (path, volinfo, conf);
-
- if (is_quota_conf) {
- snprintf (cksum_path, sizeof (cksum_path), "%s/%s", path,
- GLUSTERD_VOL_QUOTA_CKSUM_FILE);
- snprintf (filepath, sizeof (filepath), "%s/%s", path,
- GLUSTERD_VOLUME_QUOTA_CONFIG);
- } else {
- snprintf (cksum_path, sizeof (cksum_path), "%s/%s", path,
- GLUSTERD_CKSUM_FILE);
- snprintf (filepath, sizeof (filepath), "%s/%s", path,
- GLUSTERD_VOLUME_INFO_FILE);
- }
-
- ret = glusterd_volume_compute_cksum (volinfo, cksum_path, filepath,
- is_quota_conf, &cs);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to compute checksum "
- "for volume %s", volinfo->volname);
- goto out;
- }
-
- if (is_quota_conf)
- volinfo->quota_conf_cksum = cs;
- else
- volinfo->cksum = cs;
-
- ret = 0;
-out:
- return ret;
-}
-
-int
-_add_dict_to_prdict (dict_t *this, char *key, data_t *value, void *data)
-{
- glusterd_dict_ctx_t *ctx = NULL;
- char optkey[512] = {0,};
- int ret = -1;
-
- ctx = data;
- snprintf (optkey, sizeof (optkey), "%s.%s%d", ctx->prefix,
- ctx->key_name, ctx->opt_count);
- ret = dict_set_str (ctx->dict, optkey, key);
- if (ret)
- gf_log ("", GF_LOG_ERROR, "option add for %s%d %s",
- ctx->key_name, ctx->opt_count, key);
- snprintf (optkey, sizeof (optkey), "%s.%s%d", ctx->prefix,
- ctx->val_name, ctx->opt_count);
- ret = dict_set_str (ctx->dict, optkey, value->data);
- if (ret)
- gf_log ("", GF_LOG_ERROR, "option add for %s%d %s",
- ctx->val_name, ctx->opt_count, value->data);
- ctx->opt_count++;
-
- return ret;
-}
-
-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;
-}
-
-/* Exports a bricks snapshot details only if required
- *
- * The details will be exported only if the cluster op-version is greather than
- * 4, ie. snapshot is supported in the cluster
- */
-int
-gd_add_brick_snap_details_to_dict (dict_t *dict, char *prefix,
- glusterd_brickinfo_t *brickinfo)
-{
- int ret = -1;
- xlator_t *this = NULL;
- glusterd_conf_t *conf = NULL;
- char key[256] = {0,};
-
- this = THIS;
- GF_ASSERT (this != NULL);
- conf = this->private;
- GF_VALIDATE_OR_GOTO (this->name, (conf != NULL), out);
-
- GF_VALIDATE_OR_GOTO (this->name, (dict != NULL), out);
- GF_VALIDATE_OR_GOTO (this->name, (prefix != NULL), out);
- GF_VALIDATE_OR_GOTO (this->name, (brickinfo != NULL), out);
-
- if (conf->op_version < GD_OP_VERSION_3_6_0) {
- ret = 0;
- goto out;
- }
-
- snprintf (key, sizeof (key), "%s.snap_status", prefix);
- ret = dict_set_int32 (dict, key, brickinfo->snap_status);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to set snap_status for %s:%s",
- brickinfo->hostname, brickinfo->path);
- goto out;
- }
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%s.device_path", prefix);
- ret = dict_set_str (dict, key, brickinfo->device_path);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to set snap_device for %s:%s",
- brickinfo->hostname, brickinfo->path);
- goto out;
- }
-
- snprintf (key, sizeof (key), "%s.fs_type", prefix);
- ret = dict_set_str (dict, key, brickinfo->fstype);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to set fstype for %s:%s",
- brickinfo->hostname, brickinfo->path);
- goto out;
- }
-
- snprintf (key, sizeof (key), "%s.mnt_opts", prefix);
- ret = dict_set_str (dict, key, brickinfo->mnt_opts);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to set mnt_opts for %s:%s",
- brickinfo->hostname, brickinfo->path);
- goto out;
- }
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%s.mount_dir", prefix);
- ret = dict_set_str (dict, key, brickinfo->mount_dir);
- if (ret)
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to set mount_dir for %s:%s",
- brickinfo->hostname, brickinfo->path);
-
-out:
- return ret;
-}
-
-/* Exports a volumes snapshot details only if required.
- *
- * The snapshot details will only be exported if the cluster op-version is
- * greater than 4, ie. snapshot is supported in the cluster
- */
-int
-gd_add_vol_snap_details_to_dict (dict_t *dict, char *prefix,
- glusterd_volinfo_t *volinfo)
-{
- int ret = -1;
- xlator_t *this = NULL;
- glusterd_conf_t *conf = NULL;
- char key[256] = {0,};
-
- this = THIS;
- GF_ASSERT (this != NULL);
- conf = this->private;
- GF_VALIDATE_OR_GOTO (this->name, (conf != NULL), out);
-
- GF_VALIDATE_OR_GOTO (this->name, (dict != NULL), out);
- GF_VALIDATE_OR_GOTO (this->name, (volinfo != NULL), out);
- GF_VALIDATE_OR_GOTO (this->name, (prefix != NULL), out);
-
- if (conf->op_version < GD_OP_VERSION_3_6_0) {
- ret =0;
- goto out;
- }
-
- snprintf (key, sizeof (key), "%s.restored_from_snap", prefix);
- ret = dict_set_dynstr_with_alloc
- (dict, key,
- uuid_utoa (volinfo->restored_from_snap));
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Unable to set %s for volume"
- "%s", key, volinfo->volname);
- goto out;
- }
-
- if (strlen (volinfo->parent_volname) > 0) {
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%s.parent_volname", prefix);
- ret = dict_set_dynstr_with_alloc (dict, key,
- volinfo->parent_volname);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Unable to set %s "
- "for volume %s", key, volinfo->volname);
- goto out;
- }
- }
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%s.is_snap_volume", prefix);
- ret = dict_set_uint32 (dict, key, volinfo->is_snap_volume);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Unable to set %s for volume"
- "%s", key, volinfo->volname);
- goto out;
- }
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%s.snap-max-hard-limit", prefix);
- ret = dict_set_uint64 (dict, key, volinfo->snap_max_hard_limit);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Unable to set %s for volume"
- "%s", key, volinfo->volname);
- }
-
-out:
- return ret;
-}
-
-/* The prefix represents the type of volume to be added.
- * It will be "volume" for normal volumes, and snap# like
- * snap1, snap2, for snapshot volumes
- */
-int32_t
-glusterd_add_volume_to_dict (glusterd_volinfo_t *volinfo,
- dict_t *dict, int32_t count,
- char *prefix)
-{
- int32_t ret = -1;
- char pfx[512] = {0,};
- 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_dict_ctx_t ctx = {0};
- char *rebalance_id_str = NULL;
- char *rb_id_str = NULL;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (dict);
- GF_ASSERT (volinfo);
- GF_ASSERT (prefix);
-
- snprintf (key, sizeof (key), "%s%d.name", prefix, count);
- ret = dict_set_str (dict, key, volinfo->volname);
- if (ret)
- goto out;
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%s%d.type", prefix, count);
- ret = dict_set_int32 (dict, key, volinfo->type);
- if (ret)
- goto out;
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%s%d.brick_count", prefix, count);
- ret = dict_set_int32 (dict, key, volinfo->brick_count);
- if (ret)
- goto out;
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%s%d.version", prefix, count);
- ret = dict_set_int32 (dict, key, volinfo->version);
- if (ret)
- goto out;
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%s%d.status", prefix, count);
- ret = dict_set_int32 (dict, key, volinfo->status);
- if (ret)
- goto out;
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%s%d.sub_count", prefix, count);
- ret = dict_set_int32 (dict, key, volinfo->sub_count);
- if (ret)
- goto out;
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%s%d.stripe_count", prefix, count);
- ret = dict_set_int32 (dict, key, volinfo->stripe_count);
- if (ret)
- goto out;
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%s%d.replica_count", prefix, count);
- ret = dict_set_int32 (dict, key, volinfo->replica_count);
- if (ret)
- goto out;
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%s%d.disperse_count", prefix, count);
- ret = dict_set_int32 (dict, key, volinfo->disperse_count);
- if (ret)
- goto out;
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%s%d.redundancy_count", prefix, count);
- ret = dict_set_int32 (dict, key, volinfo->redundancy_count);
- if (ret)
- goto out;
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%s%d.dist_count", prefix, count);
- ret = dict_set_int32 (dict, key, volinfo->dist_leaf_count);
- if (ret)
- goto out;
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%s%d.ckusm", prefix, count);
- ret = dict_set_int64 (dict, key, volinfo->cksum);
- if (ret)
- goto out;
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%s%d.transport_type", prefix, count);
- ret = dict_set_uint32 (dict, key, volinfo->transport_type);
- if (ret)
- goto out;
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%s%d", prefix, count);
- ret = gd_add_vol_snap_details_to_dict (dict, key, volinfo);
- if (ret)
- goto out;
-
- volume_id_str = gf_strdup (uuid_utoa (volinfo->volume_id));
- if (!volume_id_str) {
- ret = -1;
- goto out;
- }
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%s%d.volume_id", prefix, count);
- ret = dict_set_dynstr (dict, key, volume_id_str);
- if (ret)
- goto out;
- volume_id_str = NULL;
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%s%d.username", prefix, 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), "%s%d.password", prefix, 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, "%s%d.rebalance", prefix, count);
- ret = dict_set_int32 (dict, key, volinfo->rebal.defrag_cmd);
- if (ret)
- goto out;
-
- rebalance_id_str = gf_strdup (uuid_utoa
- (volinfo->rebal.rebalance_id));
- if (!rebalance_id_str) {
- ret = -1;
- goto out;
- }
- memset (key, 0, sizeof (key));
- snprintf (key, 256, "%s%d.rebalance-id", prefix, count);
- ret = dict_set_dynstr (dict, key, rebalance_id_str);
- if (ret)
- goto out;
- rebalance_id_str = NULL;
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%s%d.rebalance-op", prefix, count);
- ret = dict_set_uint32 (dict, key, volinfo->rebal.op);
- if (ret)
- goto out;
-
- if (volinfo->rebal.dict) {
- snprintf (pfx, sizeof (pfx), "%s%d", prefix, count);
- ctx.dict = dict;
- ctx.prefix = pfx;
- ctx.opt_count = 1;
- ctx.key_name = "rebal-dict-key";
- ctx.val_name = "rebal-dict-value";
-
- dict_foreach (volinfo->rebal.dict, _add_dict_to_prdict, &ctx);
- ctx.opt_count--;
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "volume%d.rebal-dict-count", count);
- ret = dict_set_int32 (dict, key, ctx.opt_count);
- if (ret)
- goto out;
- }
-
- memset (key, 0, sizeof (key));
- snprintf (key, 256, "%s%d."GLUSTERD_STORE_KEY_RB_STATUS, prefix, count);
- ret = dict_set_int32 (dict, key, volinfo->rep_brick.rb_status);
- if (ret)
- goto out;
-
- if (volinfo->rep_brick.rb_status > GF_RB_STATUS_NONE) {
-
- memset (key, 0, sizeof (key));
- snprintf (key, 256, "%s%d."GLUSTERD_STORE_KEY_RB_SRC_BRICK,
- prefix, count);
- gf_asprintf (&src_brick, "%s:%s",
- volinfo->rep_brick.src_brick->hostname,
- volinfo->rep_brick.src_brick->path);
- ret = dict_set_dynstr (dict, key, src_brick);
- if (ret)
- goto out;
-
- memset (key, 0, sizeof (key));
- snprintf (key, 256, "%s%d."GLUSTERD_STORE_KEY_RB_DST_BRICK,
- prefix, count);
- gf_asprintf (&dst_brick, "%s:%s",
- volinfo->rep_brick.dst_brick->hostname,
- volinfo->rep_brick.dst_brick->path);
- ret = dict_set_dynstr (dict, key, dst_brick);
- if (ret)
- goto out;
-
- rb_id_str = gf_strdup (uuid_utoa (volinfo->rep_brick.rb_id));
- if (!rb_id_str) {
- ret = -1;
- goto out;
- }
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%s%d.rb_id", prefix, count);
- ret = dict_set_dynstr (dict, key, rb_id_str);
- if (ret)
- goto out;
- rb_id_str = NULL;
- }
-
- snprintf (pfx, sizeof (pfx), "%s%d", prefix, count);
- ctx.dict = dict;
- ctx.prefix = pfx;
- ctx.opt_count = 1;
- ctx.key_name = "key";
- ctx.val_name = "value";
- GF_ASSERT (volinfo->dict);
-
- dict_foreach (volinfo->dict, _add_dict_to_prdict, &ctx);
- ctx.opt_count--;
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%s%d.opt-count", prefix, count);
- ret = dict_set_int32 (dict, key, ctx.opt_count);
- if (ret)
- goto out;
-
- ctx.dict = dict;
- ctx.prefix = pfx;
- ctx.opt_count = 1;
- ctx.key_name = "slave-num";
- ctx.val_name = "slave-val";
- GF_ASSERT (volinfo->gsync_slaves);
-
- dict_foreach (volinfo->gsync_slaves, _add_dict_to_prdict, &ctx);
- ctx.opt_count--;
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%s%d.gsync-count", prefix, count);
- ret = dict_set_int32 (dict, key, ctx.opt_count);
- if (ret)
- goto out;
-
- list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) {
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%s%d.brick%d.hostname",
- prefix, count, i);
- ret = dict_set_str (dict, key, brickinfo->hostname);
- if (ret)
- goto out;
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%s%d.brick%d.path",
- prefix, count, i);
- ret = dict_set_str (dict, key, brickinfo->path);
- if (ret)
- goto out;
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%s%d.brick%d.decommissioned",
- prefix, count, i);
- ret = dict_set_int32 (dict, key, brickinfo->decommissioned);
- if (ret)
- goto out;
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%s%d.brick%d.brick_id",
- prefix, count, i);
- ret = dict_set_str (dict, key, brickinfo->brick_id);
- if (ret)
- goto out;
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%s%d.brick%d", prefix, count, i);
- ret = gd_add_brick_snap_details_to_dict (dict, key, brickinfo);
- if (ret)
- goto out;
-
- i++;
- }
-
- /* Add volume op-versions to dict. This prevents volume inconsistencies
- * in the cluster
- */
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%s%d.op-version", prefix, count);
- ret = dict_set_int32 (dict, key, volinfo->op_version);
- if (ret)
- goto out;
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%s%d.client-op-version", prefix, count);
- ret = dict_set_int32 (dict, key, volinfo->client_op_version);
- if (ret)
- goto out;
-
- /*Add volume Capability (BD Xlator) to dict*/
- memset (key, 0 ,sizeof (key));
- snprintf (key, sizeof (key), "%s%d.caps", prefix, count);
- ret = dict_set_int32 (dict, key, volinfo->caps);
-
-out:
- GF_FREE (volume_id_str);
- GF_FREE (rebalance_id_str);
- GF_FREE (rb_id_str);
-
- gf_log (this->name, GF_LOG_DEBUG, "Returning with %d", ret);
- return ret;
-}
-
-/* The prefix represents the type of volume to be added.
- * It will be "volume" for normal volumes, and snap# like
- * snap1, snap2, for snapshot volumes
- */
-int
-glusterd_vol_add_quota_conf_to_dict (glusterd_volinfo_t *volinfo, dict_t* load,
- int vol_idx, char *prefix)
-{
- int fd = -1;
- char *gfid_str = NULL;
- unsigned char buf[16] = {0};
- char key[PATH_MAX] = {0};
- int gfid_idx = 0;
- int ret = -1;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (prefix);
-
- ret = glusterd_store_create_quota_conf_sh_on_absence (volinfo);
- if (ret)
- goto out;
-
- fd = open (volinfo->quota_conf_shandle->path, O_RDONLY);
- if (fd == -1) {
- ret = -1;
- goto out;
- }
-
- ret = glusterd_store_quota_conf_skip_header (this, fd);
- if (ret)
- goto out;
-
- for (gfid_idx=0; ; gfid_idx++) {
-
- ret = read (fd, (void*)&buf, 16) ;
- if (ret <= 0) {
- //Finished reading all entries in the conf file
- break;
- }
- if (ret != 16) {
- //This should never happen. We must have a multiple of
- //entry_sz bytes in our configuration file.
- gf_log (this->name, GF_LOG_CRITICAL, "Quota "
- "configuration store may be corrupt.");
- goto out;
- }
-
- gfid_str = gf_strdup (uuid_utoa (buf));
- if (!gfid_str) {
- ret = -1;
- goto out;
- }
-
- snprintf (key, sizeof(key)-1, "%s%d.gfid%d", prefix,
- vol_idx, gfid_idx);
- key[sizeof(key)-1] = '\0';
- ret = dict_set_dynstr (load, key, gfid_str);
- if (ret) {
- goto out;
- }
-
- gfid_str = NULL;
- }
-
- snprintf (key, sizeof(key)-1, "%s%d.gfid-count", prefix, vol_idx);
- key[sizeof(key)-1] = '\0';
- ret = dict_set_int32 (load, key, gfid_idx);
- if (ret)
- goto out;
-
- snprintf (key, sizeof(key)-1, "%s%d.quota-cksum", prefix, vol_idx);
- key[sizeof(key)-1] = '\0';
- ret = dict_set_uint32 (load, key, volinfo->quota_conf_cksum);
- if (ret)
- goto out;
-
- snprintf (key, sizeof(key)-1, "%s%d.quota-version", prefix, vol_idx);
- key[sizeof(key)-1] = '\0';
- ret = dict_set_uint32 (load, key, volinfo->quota_conf_version);
- if (ret)
- goto out;
-
- ret = 0;
-out:
- if (fd != -1)
- close (fd);
- GF_FREE (gfid_str);
- return ret;
-}
-
-int32_t
-glusterd_add_missed_snaps_to_export_dict (dict_t *peer_data)
-{
- char name_buf[PATH_MAX] = "";
- char value[PATH_MAX] = "";
- int32_t missed_snap_count = 0;
- int32_t ret = -1;
- glusterd_conf_t *priv = NULL;
- glusterd_missed_snap_info *missed_snapinfo = NULL;
- glusterd_snap_op_t *snap_opinfo = NULL;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (peer_data);
-
- priv = this->private;
- GF_ASSERT (priv);
-
- /* Add the missed_entries in the dict */
- list_for_each_entry (missed_snapinfo, &priv->missed_snaps_list,
- missed_snaps) {
- list_for_each_entry (snap_opinfo,
- &missed_snapinfo->snap_ops,
- snap_ops_list) {
- snprintf (name_buf, sizeof(name_buf),
- "missed_snaps_%d", missed_snap_count);
- snprintf (value, sizeof(value), "%s:%s=%s:%d:%s:%d:%d",
- missed_snapinfo->node_uuid,
- missed_snapinfo->snap_uuid,
- snap_opinfo->snap_vol_id,
- snap_opinfo->brick_num,
- snap_opinfo->brick_path,
- snap_opinfo->op,
- snap_opinfo->status);
-
- ret = dict_set_dynstr_with_alloc (peer_data, name_buf,
- value);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Unable to set %s",
- name_buf);
- goto out;
- }
- missed_snap_count++;
- }
- }
-
- ret = dict_set_int32 (peer_data, "missed_snap_count",
- missed_snap_count);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Unable to set missed_snap_count");
- goto out;
- }
-
-out:
- gf_log (this->name, GF_LOG_TRACE, "Returning %d", ret);
- return ret;
-}
-
-int32_t
-glusterd_add_snap_to_dict (glusterd_snap_t *snap, dict_t *peer_data,
- int32_t snap_count)
-{
- char buf[NAME_MAX] = "";
- char prefix[NAME_MAX] = "";
- int32_t ret = -1;
- int32_t volcount = 0;
- glusterd_volinfo_t *volinfo = NULL;
- glusterd_brickinfo_t *brickinfo = NULL;
- gf_boolean_t host_bricks = _gf_false;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (snap);
- GF_ASSERT (peer_data);
-
- snprintf (prefix, sizeof(prefix), "snap%d", snap_count);
-
- list_for_each_entry (volinfo, &snap->volumes, vol_list) {
- volcount++;
- ret = glusterd_add_volume_to_dict (volinfo, peer_data,
- volcount, prefix);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to add snap:%s volume:%s "
- "to peer_data dict for handshake",
- snap->snapname, volinfo->volname);
- goto out;
- }
-
- if (glusterd_is_volume_quota_enabled (volinfo)) {
-
- ret = glusterd_vol_add_quota_conf_to_dict (volinfo,
- peer_data,
- volcount,
- prefix);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to add quota conf for "
- "snap:%s volume:%s to peer_data "
- "dict for handshake", snap->snapname,
- volinfo->volname);
- goto out;
- }
- }
-
- list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) {
- if (!uuid_compare (brickinfo->uuid, MY_UUID)) {
- host_bricks = _gf_true;
- break;
- }
- }
- }
-
- snprintf (buf, sizeof(buf), "%s.host_bricks", prefix);
- ret = dict_set_int8 (peer_data, buf, (int8_t) host_bricks);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Unable to set host_bricks for snap %s",
- snap->snapname);
- goto out;
- }
-
- snprintf (buf, sizeof(buf), "%s.volcount", prefix);
- ret = dict_set_int32 (peer_data, buf, volcount);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Unable to set volcount for snap %s",
- snap->snapname);
- goto out;
- }
-
- snprintf (buf, sizeof(buf), "%s.snapname", prefix);
- ret = dict_set_dynstr_with_alloc (peer_data, buf, snap->snapname);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Unable to set snapname for snap %s",
- snap->snapname);
- goto out;
- }
-
- snprintf (buf, sizeof(buf), "%s.snap_id", prefix);
- ret = dict_set_dynstr_with_alloc (peer_data, buf,
- uuid_utoa (snap->snap_id));
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Unable to set snap_id for snap %s",
- snap->snapname);
- goto out;
- }
-
- if (snap->description) {
- snprintf (buf, sizeof(buf), "%s.snapid", prefix);
- ret = dict_set_dynstr_with_alloc (peer_data, buf,
- snap->description);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Unable to set description for snap %s",
- snap->snapname);
- goto out;
- }
- }
-
- snprintf (buf, sizeof(buf), "%s.time_stamp", prefix);
- ret = dict_set_int64 (peer_data, buf, (int64_t)snap->time_stamp);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Unable to set time_stamp for snap %s",
- snap->snapname);
- goto out;
- }
-
- snprintf (buf, sizeof(buf), "%s.snap_restored", prefix);
- ret = dict_set_int8 (peer_data, buf, snap->snap_restored);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Unable to set snap_restored for snap %s",
- snap->snapname);
- goto out;
- }
-
- snprintf (buf, sizeof(buf), "%s.snap_status", prefix);
- ret = dict_set_int32 (peer_data, buf, snap->snap_status);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Unable to set snap_status for snap %s",
- snap->snapname);
- goto out;
- }
-out:
- gf_log (this->name, GF_LOG_TRACE, "Returning %d", ret);
- return ret;
-}
-
-int32_t
-glusterd_add_snapshots_to_export_dict (dict_t *peer_data)
-{
- int32_t snap_count = 0;
- int32_t ret = -1;
- glusterd_conf_t *priv = NULL;
- glusterd_snap_t *snap = NULL;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- priv = this->private;
- GF_ASSERT (priv);
- GF_ASSERT (peer_data);
-
- list_for_each_entry (snap, &priv->snapshots, snap_list) {
- snap_count++;
- ret = glusterd_add_snap_to_dict (snap, peer_data, snap_count);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to add snap(%s) to the "
- " peer_data dict for handshake",
- snap->snapname);
- goto out;
- }
- }
-
- ret = dict_set_int32 (peer_data, "snap_count", snap_count);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to set snap_count");
- goto out;
- }
-
-out:
- gf_log (this->name, GF_LOG_TRACE, "Returning %d", ret);
- return ret;
-}
-
-int32_t
-glusterd_add_volumes_to_export_dict (dict_t **peer_data)
-{
- int32_t ret = -1;
- dict_t *dict = NULL;
- glusterd_conf_t *priv = NULL;
- glusterd_volinfo_t *volinfo = NULL;
- int32_t count = 0;
- glusterd_dict_ctx_t ctx = {0};
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- priv = this->private;
- GF_ASSERT (priv);
-
- dict = dict_new ();
- if (!dict)
- goto out;
-
- list_for_each_entry (volinfo, &priv->volumes, vol_list) {
- count++;
- ret = glusterd_add_volume_to_dict (volinfo, dict, count,
- "volume");
- if (ret)
- goto out;
- if (!glusterd_is_volume_quota_enabled (volinfo))
- continue;
- ret = glusterd_vol_add_quota_conf_to_dict (volinfo, dict,
- count, "volume");
- if (ret)
- goto out;
- }
-
- ret = dict_set_int32 (dict, "count", count);
- if (ret)
- goto out;
-
- ctx.dict = dict;
- ctx.prefix = "global";
- ctx.opt_count = 1;
- ctx.key_name = "key";
- ctx.val_name = "val";
- dict_foreach (priv->opts, _add_dict_to_prdict, &ctx);
- ctx.opt_count--;
- ret = dict_set_int32 (dict, "global-opt-count", ctx.opt_count);
- if (ret)
- goto out;
-
- *peer_data = dict;
-out:
- if (ret)
- dict_unref (dict);
-
- gf_log (this->name, GF_LOG_TRACE, "Returning %d", ret);
- return ret;
-}
-
-int32_t
-glusterd_compare_friend_volume (dict_t *peer_data, int32_t count,
- int32_t *status, char *hostname)
-{
-
- int32_t ret = -1;
- char key[512] = {0,};
- glusterd_volinfo_t *volinfo = NULL;
- char *volname = NULL;
- uint32_t cksum = 0;
- uint32_t quota_cksum = 0;
- uint32_t quota_version = 0;
- int32_t version = 0;
- xlator_t *this = NULL;
-
- GF_ASSERT (peer_data);
- GF_ASSERT (status);
-
- this = THIS;
- GF_ASSERT (this);
-
- snprintf (key, sizeof (key), "volume%d.name", count);
- ret = dict_get_str (peer_data, key, &volname);
- if (ret)
- goto out;
-
- ret = glusterd_volinfo_find (volname, &volinfo);
-
- if (ret) {
- *status = GLUSTERD_VOL_COMP_UPDATE_REQ;
- ret = 0;
- goto out;
- }
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "volume%d.version", count);
- ret = dict_get_int32 (peer_data, key, &version);
- if (ret)
- goto out;
-
- if (version > volinfo->version) {
- //Mismatch detected
- ret = 0;
- gf_msg (this->name, GF_LOG_INFO, 0, GD_MSG_VOL_VERS_MISMATCH,
- "Version of volume %s differ. local version = %d, "
- "remote version = %d on peer %s", volinfo->volname,
- volinfo->version, version, hostname);
- *status = GLUSTERD_VOL_COMP_UPDATE_REQ;
- goto out;
- } else if (version < volinfo->version) {
- *status = GLUSTERD_VOL_COMP_SCS;
- goto out;
- }
-
- //Now, versions are same, compare cksums.
- //
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "volume%d.ckusm", count);
- ret = dict_get_uint32 (peer_data, key, &cksum);
- if (ret)
- goto out;
-
- if (cksum != volinfo->cksum) {
- ret = 0;
- gf_msg (this->name, GF_LOG_ERROR, 0, GD_MSG_CKSUM_VERS_MISMATCH,
- "Version of Cksums %s differ. local cksum = %u, remote "
- "cksum = %u on peer %s", volinfo->volname,
- volinfo->cksum, cksum, hostname);
- *status = GLUSTERD_VOL_COMP_RJT;
- goto out;
- }
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "volume%d.quota-version", count);
- ret = dict_get_uint32 (peer_data, key, &quota_version);
- if (ret) {
- gf_log (this->name, GF_LOG_DEBUG, "quota-version key absent for"
- " volume %s in peer %s's response", volinfo->volname,
- hostname);
- ret = 0;
- } else {
- if (quota_version > volinfo->quota_conf_version) {
- //Mismatch detected
- ret = 0;
- gf_msg (this->name, GF_LOG_INFO, 0,
- GD_MSG_QUOTA_CONFIG_VERS_MISMATCH,
- "Quota configuration versions of volume %s "
- "differ. local version = %d, remote version = "
- "%d on peer %s", volinfo->volname,
- volinfo->quota_conf_version,
- quota_version, hostname);
- *status = GLUSTERD_VOL_COMP_UPDATE_REQ;
- goto out;
- } else if (quota_version < volinfo->quota_conf_version) {
- *status = GLUSTERD_VOL_COMP_SCS;
- goto out;
- }
- }
-
- //Now, versions are same, compare cksums.
- //
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "volume%d.quota-cksum", count);
- ret = dict_get_uint32 (peer_data, key, &quota_cksum);
- if (ret) {
- gf_log (this->name, GF_LOG_DEBUG, "quota checksum absent for "
- "volume %s in peer %s's response", volinfo->volname,
- hostname);
- ret = 0;
- } else {
- if (quota_cksum != volinfo->quota_conf_cksum) {
- ret = 0;
- gf_msg (this->name, GF_LOG_ERROR, 0,
- GD_MSG_QUOTA_CONFIG_CKSUM_MISMATCH, "Cksums of "
- "quota configuration of volume %s differ. local"
- " cksum = %u, remote cksum = %u on peer %s",
- volinfo->volname, volinfo->quota_conf_cksum,
- quota_cksum, hostname);
- *status = GLUSTERD_VOL_COMP_RJT;
- goto out;
- }
- }
- *status = GLUSTERD_VOL_COMP_SCS;
-
-out:
- gf_log (this->name, GF_LOG_DEBUG, "Returning with ret: %d, status: %d",
- ret, *status);
- return ret;
-}
-
-static int32_t
-import_prdict_dict (dict_t *peer_data, dict_t *dst_dict, char *key_prefix,
- char *value_prefix, int opt_count, char *prefix)
-{
- char key[512] = {0,};
- int32_t ret = 0;
- int i = 1;
- char *opt_key = NULL;
- char *opt_val = NULL;
- char *dup_opt_val = NULL;
- char msg[2048] = {0};
-
- while (i <= opt_count) {
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%s.%s%d",
- prefix, key_prefix, i);
- ret = dict_get_str (peer_data, key, &opt_key);
- if (ret) {
- snprintf (msg, sizeof (msg), "Volume dict key not "
- "specified");
- goto out;
- }
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%s.%s%d",
- prefix, value_prefix, i);
- ret = dict_get_str (peer_data, key, &opt_val);
- if (ret) {
- snprintf (msg, sizeof (msg), "Volume dict value not "
- "specified");
- goto out;
- }
- dup_opt_val = gf_strdup (opt_val);
- if (!dup_opt_val) {
- ret = -1;
- goto out;
- }
- ret = dict_set_dynstr (dst_dict, opt_key, dup_opt_val);
- if (ret) {
- snprintf (msg, sizeof (msg), "Volume set %s %s "
- "unsuccessful", opt_key, dup_opt_val);
- goto out;
- }
- i++;
- }
-
-out:
- if (msg[0])
- gf_log ("glusterd", GF_LOG_ERROR, "%s", msg);
- gf_log ("", GF_LOG_DEBUG, "Returning with %d", ret);
- return ret;
-
-}
-
-gf_boolean_t
-glusterd_is_quorum_option (char *option)
-{
- gf_boolean_t res = _gf_false;
- int i = 0;
- char *keys[] = {GLUSTERD_QUORUM_TYPE_KEY,
- GLUSTERD_QUORUM_RATIO_KEY, NULL};
-
- for (i = 0; keys[i]; i++) {
- if (strcmp (option, keys[i]) == 0) {
- res = _gf_true;
- break;
- }
- }
- return res;
-}
-
-gf_boolean_t
-glusterd_is_quorum_changed (dict_t *options, char *option, char *value)
-{
- int ret = 0;
- gf_boolean_t reconfigured = _gf_false;
- gf_boolean_t all = _gf_false;
- char *oldquorum = NULL;
- char *newquorum = NULL;
- char *oldratio = NULL;
- char *newratio = NULL;
-
- if ((strcmp ("all", option) != 0) &&
- !glusterd_is_quorum_option (option))
- goto out;
-
- if (strcmp ("all", option) == 0)
- all = _gf_true;
-
- if (all || (strcmp (GLUSTERD_QUORUM_TYPE_KEY, option) == 0)) {
- newquorum = value;
- ret = dict_get_str (options, GLUSTERD_QUORUM_TYPE_KEY,
- &oldquorum);
- }
-
- if (all || (strcmp (GLUSTERD_QUORUM_RATIO_KEY, option) == 0)) {
- newratio = value;
- ret = dict_get_str (options, GLUSTERD_QUORUM_RATIO_KEY,
- &oldratio);
- }
-
- reconfigured = _gf_true;
-
- if (oldquorum && newquorum && (strcmp (oldquorum, newquorum) == 0))
- reconfigured = _gf_false;
- if (oldratio && newratio && (strcmp (oldratio, newratio) == 0))
- reconfigured = _gf_false;
-
- if ((oldratio == NULL) && (newratio == NULL) && (oldquorum == NULL) &&
- (newquorum == NULL))
- reconfigured = _gf_false;
-out:
- return reconfigured;
-}
-
-static inline gf_boolean_t
-_is_contributing_to_quorum (gd_quorum_contrib_t contrib)
-{
- if ((contrib == QUORUM_UP) || (contrib == QUORUM_DOWN))
- return _gf_true;
- return _gf_false;
-}
-
-static inline gf_boolean_t
-_does_quorum_meet (int active_count, int quorum_count)
-{
- return (active_count >= quorum_count);
-}
-
-int
-glusterd_get_quorum_cluster_counts (xlator_t *this, int *active_count,
- int *quorum_count,
- struct list_head *peer_list,
- gf_boolean_t _local_xaction_peers)
-{
- glusterd_peerinfo_t *peerinfo = NULL;
- glusterd_conf_t *conf = NULL;
- int ret = -1;
- int inquorum_count = 0;
- char *val = NULL;
- double quorum_percentage = 0.0;
- gf_boolean_t ratio = _gf_false;
- int count = 0;
-
- conf = this->private;
-
- GF_ASSERT (conf);
-
- //Start with counting self
- inquorum_count = 1;
- if (active_count)
- *active_count = 1;
-
- if (!peer_list) {
- list_for_each_entry (peerinfo, &conf->peers, uuid_list) {
- glusterd_quorum_count(peerinfo, inquorum_count,
- active_count, out);
- }
- } else {
- if (_local_xaction_peers) {
- list_for_each_local_xaction_peers (peerinfo,
- peer_list) {
- glusterd_quorum_count(peerinfo, inquorum_count,
- active_count, out);
- }
- } else {
- list_for_each_entry (peerinfo, peer_list,
- op_peers_list) {
- glusterd_quorum_count(peerinfo, inquorum_count,
- active_count, out);
- }
- }
- }
-
- ret = dict_get_str (conf->opts, GLUSTERD_QUORUM_RATIO_KEY, &val);
- if (ret == 0) {
- ratio = _gf_true;
- ret = gf_string2percent (val, &quorum_percentage);
- if (!ret)
- ratio = _gf_true;
- }
- if (ratio)
- count = CEILING_POS (inquorum_count *
- quorum_percentage / 100.0);
- else
- count = (inquorum_count * 50 / 100) + 1;
-
- *quorum_count = count;
- ret = 0;
-out:
- return ret;
-}
-
-gf_boolean_t
-glusterd_is_volume_in_server_quorum (glusterd_volinfo_t *volinfo)
-{
- gf_boolean_t res = _gf_false;
- char *quorum_type = NULL;
- int ret = 0;
-
- ret = dict_get_str (volinfo->dict, GLUSTERD_QUORUM_TYPE_KEY,
- &quorum_type);
- if (ret)
- goto out;
-
- if (strcmp (quorum_type, GLUSTERD_SERVER_QUORUM) == 0)
- res = _gf_true;
-out:
- return res;
-}
-
-gf_boolean_t
-glusterd_is_any_volume_in_server_quorum (xlator_t *this)
-{
- glusterd_conf_t *conf = NULL;
- glusterd_volinfo_t *volinfo = NULL;
-
- conf = this->private;
- list_for_each_entry (volinfo, &conf->volumes, vol_list) {
- if (glusterd_is_volume_in_server_quorum (volinfo)) {
- return _gf_true;
- }
- }
- return _gf_false;
-}
-
-gf_boolean_t
-does_gd_meet_server_quorum (xlator_t *this, struct list_head *peers_list,
- gf_boolean_t _local_xaction_peers)
-{
- int quorum_count = 0;
- int active_count = 0;
- gf_boolean_t in = _gf_false;
- glusterd_conf_t *conf = NULL;
- int ret = -1;
-
- conf = this->private;
- ret = glusterd_get_quorum_cluster_counts (this, &active_count,
- &quorum_count,
- peers_list,
- _local_xaction_peers);
- if (ret)
- goto out;
-
- if (!_does_quorum_meet (active_count, quorum_count)) {
- goto out;
- }
-
- in = _gf_true;
-out:
- return in;
-}
-
-int
-glusterd_spawn_daemons (void *opaque)
-{
- glusterd_conf_t *conf = THIS->private;
- gf_boolean_t start_bricks = !conf->restart_done;
- int ret = -1;
-
- if (start_bricks) {
- glusterd_restart_bricks (conf);
- conf->restart_done = _gf_true;
- }
- glusterd_restart_gsyncds (conf);
- glusterd_restart_rebalance (conf);
- ret = glusterd_restart_snapds (conf);
-
- return ret;
-}
-
-void
-glusterd_do_volume_quorum_action (xlator_t *this, glusterd_volinfo_t *volinfo,
- gf_boolean_t meets_quorum)
-{
- glusterd_brickinfo_t *brickinfo = NULL;
- glusterd_conf_t *conf = NULL;
- gd_quorum_status_t quorum_status = NOT_APPLICABLE_QUORUM;
- gf_boolean_t follows_quorum = _gf_false;
-
- conf = this->private;
- if (volinfo->status != GLUSTERD_STATUS_STARTED) {
- volinfo->quorum_status = NOT_APPLICABLE_QUORUM;
- goto out;
- }
-
- follows_quorum = glusterd_is_volume_in_server_quorum (volinfo);
- if (follows_quorum) {
- if (meets_quorum)
- quorum_status = MEETS_QUORUM;
- else
- quorum_status = DOESNT_MEET_QUORUM;
- } else {
- quorum_status = NOT_APPLICABLE_QUORUM;
- }
-
- /*
- * The following check is added to prevent spurious brick starts when
- * events occur that affect quorum.
- * Example:
- * There is a cluster of 10 peers. Volume is in quorum. User
- * takes down one brick from the volume to perform maintenance.
- * Suddenly one of the peers go down. Cluster is still in quorum. But
- * because of this 'peer going down' event, quorum is calculated and
- * the bricks that are down are brought up again. In this process it
- * also brings up the brick that is purposefully taken down.
- */
- if (volinfo->quorum_status == quorum_status)
- goto out;
-
- if (quorum_status == MEETS_QUORUM) {
- gf_msg (this->name, GF_LOG_CRITICAL, 0,
- GD_MSG_SERVER_QUORUM_MET_STARTING_BRICKS,
- "Server quorum regained for volume %s. Starting local "
- "bricks.", volinfo->volname);
- } else if (quorum_status == DOESNT_MEET_QUORUM) {
- gf_msg (this->name, GF_LOG_CRITICAL, 0,
- GD_MSG_SERVER_QUORUM_LOST_STOPPING_BRICKS,
- "Server quorum lost for volume %s. Stopping local "
- "bricks.", volinfo->volname);
- }
-
- list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) {
- if (!glusterd_is_local_brick (this, volinfo, brickinfo))
- continue;
- if (quorum_status == DOESNT_MEET_QUORUM)
- glusterd_brick_stop (volinfo, brickinfo, _gf_false);
- else
- glusterd_brick_start (volinfo, brickinfo, _gf_false);
- }
- volinfo->quorum_status = quorum_status;
-out:
- return;
-}
-
-int
-glusterd_do_quorum_action ()
-{
- xlator_t *this = NULL;
- glusterd_conf_t *conf = NULL;
- glusterd_volinfo_t *volinfo = NULL;
- int ret = 0;
- int active_count = 0;
- int quorum_count = 0;
- gf_boolean_t meets = _gf_false;
-
- this = THIS;
- conf = this->private;
-
- conf->pending_quorum_action = _gf_true;
- ret = glusterd_lock (conf->uuid);
- if (ret)
- goto out;
-
- {
- ret = glusterd_get_quorum_cluster_counts (this, &active_count,
- &quorum_count, NULL,
- _gf_false);
- if (ret)
- goto unlock;
-
- if (_does_quorum_meet (active_count, quorum_count))
- meets = _gf_true;
- list_for_each_entry (volinfo, &conf->volumes, vol_list) {
- glusterd_do_volume_quorum_action (this, volinfo, meets);
- }
- }
-unlock:
- (void)glusterd_unlock (conf->uuid);
- conf->pending_quorum_action = _gf_false;
-out:
- return ret;
-}
-
-int32_t
-glusterd_import_friend_volume_opts (dict_t *peer_data, int count,
- glusterd_volinfo_t *volinfo)
-{
- char key[512] = {0,};
- int32_t ret = -1;
- int opt_count = 0;
- char msg[2048] = {0};
- char volume_prefix[1024] = {0};
-
- GF_ASSERT (peer_data);
- GF_ASSERT (volinfo);
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "volume%d.opt-count", count);
- ret = dict_get_int32 (peer_data, key, &opt_count);
- if (ret) {
- snprintf (msg, sizeof (msg), "Volume option count not "
- "specified for %s", volinfo->volname);
- goto out;
- }
-
- snprintf (volume_prefix, sizeof (volume_prefix), "volume%d", count);
- ret = import_prdict_dict (peer_data, volinfo->dict, "key", "value",
- opt_count, volume_prefix);
- if (ret) {
- snprintf (msg, sizeof (msg), "Unable to import options dict "
- "specified for %s", volinfo->volname);
- goto out;
- }
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "volume%d.gsync-count", count);
- ret = dict_get_int32 (peer_data, key, &opt_count);
- if (ret) {
- snprintf (msg, sizeof (msg), "Gsync count not "
- "specified for %s", volinfo->volname);
- goto out;
- }
-
- ret = import_prdict_dict (peer_data, volinfo->gsync_slaves, "slave-num",
- "slave-val", opt_count, volume_prefix);
- if (ret) {
- snprintf (msg, sizeof (msg), "Unable to import gsync sessions "
- "specified for %s", volinfo->volname);
- goto out;
- }
-
-out:
- if (msg[0])
- gf_log ("glusterd", GF_LOG_ERROR, "%s", msg);
- gf_log ("", GF_LOG_DEBUG, "Returning with %d", ret);
- return ret;
-}
-
-/* Imports the snapshot details of a brick if required and available
- *
- * Snapshot details will be imported only if the cluster op-verison is >= 4
- */
-int
-gd_import_new_brick_snap_details (dict_t *dict, char *prefix,
- glusterd_brickinfo_t *brickinfo)
-{
- int ret = -1;
- xlator_t *this = NULL;
- glusterd_conf_t *conf = NULL;
- char key[512] = {0,};
- char *snap_device = NULL;
- char *fs_type = NULL;
- char *mnt_opts = NULL;
- char *mount_dir = NULL;
-
- this = THIS;
- GF_ASSERT (this != NULL);
- conf = this->private;
- GF_VALIDATE_OR_GOTO (this->name, (conf != NULL), out);
-
- GF_VALIDATE_OR_GOTO (this->name, (dict != NULL), out);
- GF_VALIDATE_OR_GOTO (this->name, (prefix != NULL), out);
- GF_VALIDATE_OR_GOTO (this->name, (brickinfo != NULL), out);
-
- if (conf->op_version < GD_OP_VERSION_3_6_0) {
- ret = 0;
- goto out;
- }
-
- snprintf (key, sizeof (key), "%s.snap_status", prefix);
- ret = dict_get_int32 (dict, key, &brickinfo->snap_status);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "%s missing in payload", key);
- goto out;
- }
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%s.device_path", prefix);
- ret = dict_get_str (dict, key, &snap_device);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "%s missing in payload", key);
- goto out;
- }
- strcpy (brickinfo->device_path, snap_device);
-
- snprintf (key, sizeof (key), "%s.fs_type", prefix);
- ret = dict_get_str (dict, key, &fs_type);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "%s missing in payload", key);
- goto out;
- }
- strcpy (brickinfo->fstype, fs_type);
-
- snprintf (key, sizeof (key), "%s.mnt_opts", prefix);
- ret = dict_get_str (dict, key, &mnt_opts);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "%s missing in payload", key);
- goto out;
- }
- strcpy (brickinfo->mnt_opts, mnt_opts);
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%s.mount_dir", prefix);
- ret = dict_get_str (dict, key, &mount_dir);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "%s missing in payload", key);
- goto out;
- }
- strcpy (brickinfo->mount_dir, mount_dir);
-
-out:
- return ret;
-}
-
-/* The prefix represents the type of volume to be added.
- * It will be "volume" for normal volumes, and snap# like
- * snap1, snap2, for snapshot volumes
- */
-int32_t
-glusterd_import_new_brick (dict_t *peer_data, int32_t vol_count,
- int32_t brick_count,
- glusterd_brickinfo_t **brickinfo,
- char *prefix)
-{
- char key[512] = {0,};
- int ret = -1;
- char *hostname = NULL;
- char *path = NULL;
- char *brick_id = NULL;
- int decommissioned = 0;
- glusterd_brickinfo_t *new_brickinfo = NULL;
- char msg[2048] = {0};
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (peer_data);
- GF_ASSERT (vol_count >= 0);
- GF_ASSERT (brickinfo);
- GF_ASSERT (prefix);
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%s%d.brick%d.hostname",
- prefix, vol_count, brick_count);
- ret = dict_get_str (peer_data, key, &hostname);
- if (ret) {
- snprintf (msg, sizeof (msg), "%s missing in payload", key);
- goto out;
- }
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%s%d.brick%d.path",
- prefix, vol_count, brick_count);
- ret = dict_get_str (peer_data, key, &path);
- if (ret) {
- snprintf (msg, sizeof (msg), "%s missing in payload", key);
- goto out;
- }
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%s%d.brick%d.brick_id",
- prefix, vol_count, brick_count);
- ret = dict_get_str (peer_data, key, &brick_id);
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%s%d.brick%d.decommissioned",
- prefix, vol_count, brick_count);
- ret = dict_get_int32 (peer_data, key, &decommissioned);
- if (ret) {
- /* For backward compatibility */
- ret = 0;
- }
-
- ret = glusterd_brickinfo_new (&new_brickinfo);
- if (ret)
- goto out;
-
- strcpy (new_brickinfo->path, path);
- strcpy (new_brickinfo->hostname, hostname);
- new_brickinfo->decommissioned = decommissioned;
- if (brick_id)
- strcpy (new_brickinfo->brick_id, brick_id);
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%s%d.brick%d", prefix, vol_count,
- brick_count);
- ret = gd_import_new_brick_snap_details (peer_data, key, new_brickinfo);
- if (ret)
- goto out;
-
- //peerinfo might not be added yet
- (void) glusterd_resolve_brick (new_brickinfo);
- ret = 0;
- *brickinfo = new_brickinfo;
-out:
- if (msg[0])
- gf_log ("glusterd", GF_LOG_ERROR, "%s", msg);
- gf_log ("", GF_LOG_DEBUG, "Returning with %d", ret);
- return ret;
-}
-
-/* The prefix represents the type of volume to be added.
- * It will be "volume" for normal volumes, and snap# like
- * snap1, snap2, for snapshot volumes
- */
-int32_t
-glusterd_import_bricks (dict_t *peer_data, int32_t vol_count,
- glusterd_volinfo_t *new_volinfo, char *prefix)
-{
- int ret = -1;
- int brick_count = 1;
- int brickid = 0;
- glusterd_brickinfo_t *new_brickinfo = NULL;
-
- GF_ASSERT (peer_data);
- GF_ASSERT (vol_count >= 0);
- GF_ASSERT (new_volinfo);
- GF_ASSERT (prefix);
- while (brick_count <= new_volinfo->brick_count) {
-
- ret = glusterd_import_new_brick (peer_data, vol_count,
- brick_count,
- &new_brickinfo, prefix);
- if (ret)
- goto out;
- if (new_brickinfo->brick_id[0] == '\0')
- /*We were probed from a peer having op-version
- less than GD_OP_VER_PERSISTENT_AFR_XATTRS*/
- GLUSTERD_ASSIGN_BRICKID_TO_BRICKINFO (new_brickinfo,
- new_volinfo,
- brickid++);
- list_add_tail (&new_brickinfo->brick_list, &new_volinfo->bricks);
- brick_count++;
- }
- ret = 0;
-out:
- gf_log ("", GF_LOG_DEBUG, "Returning with %d", ret);
- return ret;
-}
-
-/* The prefix represents the type of volume to be added.
- * It will be "volume" for normal volumes, and snap# like
- * snap1, snap2, for snapshot volumes
- */
-static int
-glusterd_import_quota_conf (dict_t *peer_data, int vol_idx,
- glusterd_volinfo_t *new_volinfo,
- char *prefix)
-{
- int gfid_idx = 0;
- int gfid_count = 0;
- int ret = -1;
- int fd = -1;
- char key[PATH_MAX] = {0};
- char *gfid_str = NULL;
- uuid_t gfid = {0,};
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (peer_data);
- GF_ASSERT (prefix);
-
- if (!glusterd_is_volume_quota_enabled (new_volinfo)) {
- (void) glusterd_clean_up_quota_store (new_volinfo);
- return 0;
- }
-
- ret = glusterd_store_create_quota_conf_sh_on_absence (new_volinfo);
- if (ret)
- goto out;
-
- fd = gf_store_mkstemp (new_volinfo->quota_conf_shandle);
- if (fd < 0) {
- ret = -1;
- goto out;
- }
-
- snprintf (key, sizeof (key)-1, "%s%d.quota-cksum", prefix, vol_idx);
- key[sizeof(key)-1] = '\0';
- ret = dict_get_uint32 (peer_data, key, &new_volinfo->quota_conf_cksum);
- if (ret)
- gf_log (this->name, GF_LOG_DEBUG, "Failed to get quota cksum");
-
- snprintf (key, sizeof (key)-1, "%s%d.quota-version", prefix, vol_idx);
- key[sizeof(key)-1] = '\0';
- ret = dict_get_uint32 (peer_data, key,
- &new_volinfo->quota_conf_version);
- if (ret)
- gf_log (this->name, GF_LOG_DEBUG, "Failed to get quota "
- "version");
-
- snprintf (key, sizeof (key)-1, "%s%d.gfid-count", prefix, vol_idx);
- key[sizeof(key)-1] = '\0';
- ret = dict_get_int32 (peer_data, key, &gfid_count);
- if (ret)
- goto out;
-
- ret = glusterd_store_quota_conf_stamp_header (this, fd);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to add header to tmp "
- "file");
- goto out;
- }
-
- gfid_idx = 0;
- for (gfid_idx = 0; gfid_idx < gfid_count; gfid_idx++) {
-
- snprintf (key, sizeof (key)-1, "%s%d.gfid%d",
- prefix, vol_idx, gfid_idx);
- key[sizeof(key)-1] = '\0';
- ret = dict_get_str (peer_data, key, &gfid_str);
- if (ret)
- goto out;
-
- uuid_parse (gfid_str, gfid);
- ret = write (fd, (void*)gfid, 16);
- if (ret != 16) {
- gf_log (this->name, GF_LOG_CRITICAL, "Unable to write "
- "gfid %s into quota.conf for %s", gfid_str,
- new_volinfo->volname);
- ret = -1;
- goto out;
- }
-
- }
-
- ret = gf_store_rename_tmppath (new_volinfo->quota_conf_shandle);
-
- ret = 0;
-
-out:
- if (!ret) {
- ret = glusterd_compute_cksum (new_volinfo, _gf_true);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to compute checksum");
- goto clear_quota_conf;
- }
-
- ret = glusterd_store_save_quota_version_and_cksum (new_volinfo);
- if (ret)
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to save quota version and checksum");
- }
-
-clear_quota_conf:
- if (ret && (fd > 0)) {
- gf_store_unlink_tmppath (new_volinfo->quota_conf_shandle);
- (void) gf_store_handle_destroy
- (new_volinfo->quota_conf_shandle);
- new_volinfo->quota_conf_shandle = NULL;
- }
-
- return ret;
-}
-
-int
-gd_import_friend_volume_rebal_dict (dict_t *dict, int count,
- glusterd_volinfo_t *volinfo)
-{
- int ret = -1;
- char key[256] = {0,};
- int dict_count = 0;
- char prefix[64] = {0};
-
- GF_ASSERT (dict);
- GF_ASSERT (volinfo);
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "volume%d.rebal-dict-count", count);
- ret = dict_get_int32 (dict, key, &dict_count);
- if (ret) {
- /* Older peers will not have this dict */
- ret = 0;
- goto out;
- }
-
- volinfo->rebal.dict = dict_new ();
- if(!volinfo->rebal.dict) {
- ret = -1;
- goto out;
- }
-
- snprintf (prefix, sizeof (prefix), "volume%d", count);
- ret = import_prdict_dict (dict, volinfo->rebal.dict, "rebal-dict-key",
- "rebal-dict-value", dict_count, prefix);
-out:
- if (ret && volinfo->rebal.dict)
- dict_unref (volinfo->rebal.dict);
- gf_log (THIS->name, GF_LOG_DEBUG, "Returning with %d", ret);
- return ret;
-}
-
-/*
- * Imports the snapshot details of a volume if required and available
- *
- * Snapshot details will be imported only if cluster.op_version is greater than
- * or equal to GD_OP_VERSION_3_6_0, the op-version from which volume snapshot is
- * supported.
- */
-int
-gd_import_volume_snap_details (dict_t *dict, glusterd_volinfo_t *volinfo,
- char *prefix, char *volname)
-{
- int ret = -1;
- xlator_t *this = NULL;
- glusterd_conf_t *conf = NULL;
- char key[256] = {0,};
- char *restored_snap = NULL;
-
- this = THIS;
- GF_ASSERT (this != NULL);
- conf = this->private;
- GF_VALIDATE_OR_GOTO (this->name, (conf != NULL), out);
-
- GF_VALIDATE_OR_GOTO (this->name, (dict != NULL), out);
- GF_VALIDATE_OR_GOTO (this->name, (volinfo != NULL), out);
- GF_VALIDATE_OR_GOTO (this->name, (prefix != NULL), out);
- GF_VALIDATE_OR_GOTO (this->name, (volname != NULL), out);
-
- if (conf->op_version < GD_OP_VERSION_3_6_0) {
- ret = 0;
- goto out;
- }
-
- snprintf (key, sizeof (key), "%s.is_snap_volume", prefix);
- ret = dict_get_uint32 (dict, key, &volinfo->is_snap_volume);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "%s missing in payload "
- "for %s", key, volname);
- goto out;
- }
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%s.restored_from_snap", prefix);
- ret = dict_get_str (dict, key, &restored_snap);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "%s missing in payload "
- "for %s", key, volname);
- goto out;
- }
-
- uuid_parse (restored_snap, volinfo->restored_from_snap);
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%s.snap-max-hard-limit", prefix);
- ret = dict_get_uint64 (dict, key,
- &volinfo->snap_max_hard_limit);
- if (ret)
- gf_log (this->name, GF_LOG_ERROR, "%s missing in payload "
- "for %s", key, volname);
-out:
- return ret;
-}
-/* The prefix represents the type of volume to be added.
- * It will be "volume" for normal volumes, and snap# like
- * snap1, snap2, for snapshot volumes
- */
-int32_t
-glusterd_import_volinfo (dict_t *peer_data, int count,
- glusterd_volinfo_t **volinfo,
- char *prefix)
-{
- int ret = -1;
- char key[256] = {0};
- char *parent_volname = NULL;
- char *volname = NULL;
- glusterd_volinfo_t *new_volinfo = NULL;
- char *volume_id_str = NULL;
- char *restored_snap = NULL;
- char msg[2048] = {0};
- char *src_brick = NULL;
- char *dst_brick = NULL;
- char *str = NULL;
- int rb_status = 0;
- char *rebalance_id_str = NULL;
- char *rb_id_str = NULL;
- int op_version = 0;
- int client_op_version = 0;
-
- GF_ASSERT (peer_data);
- GF_ASSERT (volinfo);
- GF_ASSERT (prefix);
-
- snprintf (key, sizeof (key), "%s%d.name", prefix, count);
- ret = dict_get_str (peer_data, key, &volname);
- if (ret) {
- snprintf (msg, sizeof (msg), "%s missing in payload", key);
- goto out;
- }
-
- ret = glusterd_volinfo_new (&new_volinfo);
- if (ret)
- goto out;
- strncpy (new_volinfo->volname, volname, sizeof (new_volinfo->volname));
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%s%d.type", prefix, count);
- ret = dict_get_int32 (peer_data, key, &new_volinfo->type);
- if (ret) {
- snprintf (msg, sizeof (msg), "%s missing in payload for %s",
- key, volname);
- goto out;
- }
-
- snprintf (key, sizeof (key), "%s%d.parent_volname", prefix, count);
- ret = dict_get_str (peer_data, key, &parent_volname);
- if (!ret)
- strncpy (new_volinfo->parent_volname, parent_volname,
- sizeof(new_volinfo->parent_volname));
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%s%d.brick_count", prefix, count);
- ret = dict_get_int32 (peer_data, key, &new_volinfo->brick_count);
- if (ret) {
- snprintf (msg, sizeof (msg), "%s missing in payload for %s",
- key, volname);
- goto out;
- }
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%s%d.version", prefix, count);
- ret = dict_get_int32 (peer_data, key, &new_volinfo->version);
- if (ret) {
- snprintf (msg, sizeof (msg), "%s missing in payload for %s",
- key, volname);
- goto out;
- }
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%s%d.status", prefix, count);
- ret = dict_get_int32 (peer_data, key, (int32_t *)&new_volinfo->status);
- if (ret) {
- snprintf (msg, sizeof (msg), "%s missing in payload for %s",
- key, volname);
- goto out;
- }
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%s%d.sub_count", prefix, count);
- ret = dict_get_int32 (peer_data, key, &new_volinfo->sub_count);
- if (ret) {
- snprintf (msg, sizeof (msg), "%s missing in payload for %s",
- key, volname);
- 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), "%s%d.stripe_count", prefix, count);
- ret = dict_get_int32 (peer_data, 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), "%s%d.replica_count", prefix, count);
- ret = dict_get_int32 (peer_data, key, &new_volinfo->replica_count);
- if (ret)
- gf_log (THIS->name, GF_LOG_INFO,
- "peer is possibly old version");
-
- /* not having a 'disperse_count' key is not a error
- (as peer may be of old version) */
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%s%d.disperse_count", prefix, count);
- ret = dict_get_int32 (peer_data, key, &new_volinfo->disperse_count);
- if (ret)
- gf_log (THIS->name, GF_LOG_INFO,
- "peer is possibly old version");
-
- /* not having a 'redundancy_count' key is not a error
- (as peer may be of old version) */
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%s%d.redundancy_count", prefix, count);
- ret = dict_get_int32 (peer_data, key, &new_volinfo->redundancy_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), "%s%d.dist_count", prefix, count);
- ret = dict_get_int32 (peer_data, key, &new_volinfo->dist_leaf_count);
- if (ret)
- gf_log (THIS->name, GF_LOG_INFO,
- "peer is possibly old version");
- new_volinfo->subvol_count = new_volinfo->brick_count/
- glusterd_get_dist_leaf_count (new_volinfo);
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%s%d.ckusm", prefix, count);
- ret = dict_get_uint32 (peer_data, key, &new_volinfo->cksum);
- if (ret) {
- snprintf (msg, sizeof (msg), "%s missing in payload for %s",
- key, volname);
- goto out;
- }
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%s%d.volume_id", prefix, count);
- ret = dict_get_str (peer_data, key, &volume_id_str);
- 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, sizeof (key), "%s%d.username", prefix, count);
- ret = dict_get_str (peer_data, 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), "%s%d.password", prefix, count);
- ret = dict_get_str (peer_data, 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), "%s%d.transport_type", prefix, count);
- ret = dict_get_uint32 (peer_data, key, &new_volinfo->transport_type);
- if (ret) {
- snprintf (msg, sizeof (msg), "%s missing in payload for %s",
- key, volname);
- goto out;
- }
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%s%d.rebalance", prefix, count);
- ret = dict_get_uint32 (peer_data, key, &new_volinfo->rebal.defrag_cmd);
- if (ret) {
- snprintf (msg, sizeof (msg), "%s missing in payload for %s",
- key, volname);
- goto out;
- }
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%s%d.rebalance-id", prefix, count);
- ret = dict_get_str (peer_data, key, &rebalance_id_str);
- if (ret) {
- /* This is not present in older glusterfs versions,
- * so don't error out
- */
- ret = 0;
- } else {
- uuid_parse (rebalance_id_str, new_volinfo->rebal.rebalance_id);
- }
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%s%d.rebalance-op", prefix, count);
- ret = dict_get_uint32 (peer_data, key,
- (uint32_t *) &new_volinfo->rebal.op);
- if (ret) {
- /* This is not present in older glusterfs versions,
- * so don't error out
- */
- ret = 0;
- }
- ret = gd_import_friend_volume_rebal_dict (peer_data, count,
- new_volinfo);
- if (ret) {
- snprintf (msg, sizeof (msg), "Failed to import rebalance dict "
- "for volume.");
- goto out;
- }
-
- memset (key, 0, sizeof (key));
- snprintf (key, 256, "%s%d."GLUSTERD_STORE_KEY_RB_STATUS, prefix, count);
- ret = dict_get_int32 (peer_data, key, &rb_status);
- if (ret)
- goto out;
- new_volinfo->rep_brick.rb_status = rb_status;
-
- if (new_volinfo->rep_brick.rb_status > GF_RB_STATUS_NONE) {
-
- memset (key, 0, sizeof (key));
- snprintf (key, 256, "%s%d."GLUSTERD_STORE_KEY_RB_SRC_BRICK,
- prefix, count);
- ret = dict_get_str (peer_data, key, &src_brick);
- if (ret)
- goto out;
-
- ret = glusterd_brickinfo_new_from_brick (src_brick,
- &new_volinfo->rep_brick.src_brick);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Unable to create"
- " src brickinfo");
- goto out;
- }
-
- memset (key, 0, sizeof (key));
- snprintf (key, 256, "%s%d."GLUSTERD_STORE_KEY_RB_DST_BRICK,
- prefix, count);
- ret = dict_get_str (peer_data, key, &dst_brick);
- if (ret)
- goto out;
-
- ret = glusterd_brickinfo_new_from_brick (dst_brick,
- &new_volinfo->rep_brick.dst_brick);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Unable to create"
- " dst brickinfo");
- goto out;
- }
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%s%d.rb_id", prefix, count);
- ret = dict_get_str (peer_data, key, &rb_id_str);
- if (ret) {
- /* This is not present in older glusterfs versions,
- * so don't error out
- */
- ret = 0;
- } else {
- uuid_parse (rb_id_str, new_volinfo->rep_brick.rb_id);
- }
- }
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%s%d", prefix, count);
- ret = gd_import_volume_snap_details (peer_data, new_volinfo, key,
- volname);
- if (ret) {
- gf_log ("glusterd", GF_LOG_ERROR, "Failed to import snapshot "
- "details for volume %s", volname);
- goto out;
- }
-
- ret = glusterd_import_friend_volume_opts (peer_data, count,
- new_volinfo);
- if (ret)
- goto out;
-
- /* Import the volume's op-versions if available else set it to 1.
- * Not having op-versions implies this informtation was obtained from a
- * op-version 1 friend (gluster-3.3), ergo the cluster is at op-version
- * 1 and all volumes are at op-versions 1.
- *
- * Either both the volume op-versions should be absent or both should be
- * present. Only one being present is a failure
- */
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%s%d.op-version", prefix, count);
- ret = dict_get_int32 (peer_data, key, &op_version);
- if (ret)
- ret = 0;
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%s%d.client-op-version", prefix, count);
- ret = dict_get_int32 (peer_data, key, &client_op_version);
- if (ret)
- ret = 0;
-
- if (op_version && client_op_version) {
- new_volinfo->op_version = op_version;
- new_volinfo->client_op_version = client_op_version;
- } else if (((op_version == 0) && (client_op_version != 0)) ||
- ((op_version != 0) && (client_op_version == 0))) {
- ret = -1;
- gf_log ("glusterd", GF_LOG_ERROR,
- "Only one volume op-version found");
- goto out;
- } else {
- new_volinfo->op_version = 1;
- new_volinfo->client_op_version = 1;
- }
-
- memset (key, 0 ,sizeof (key));
- snprintf (key, sizeof (key), "%s%d.caps", prefix, count);
- /*This is not present in older glusterfs versions, so ignore ret value*/
- ret = dict_get_int32 (peer_data, key, &new_volinfo->caps);
-
- ret = glusterd_import_bricks (peer_data, count, new_volinfo, prefix);
- if (ret)
- goto out;
-
- *volinfo = new_volinfo;
-out:
- if (msg[0])
- gf_log ("glusterd", GF_LOG_ERROR, "%s", msg);
- gf_log ("", GF_LOG_DEBUG, "Returning with %d", ret);
- return ret;
-}
-
-int32_t
-glusterd_volume_disconnect_all_bricks (glusterd_volinfo_t *volinfo)
-{
- int ret = 0;
- glusterd_brickinfo_t *brickinfo = NULL;
- GF_ASSERT (volinfo);
-
- list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) {
- if (glusterd_is_brick_started (brickinfo)) {
- ret = glusterd_brick_disconnect (brickinfo);
- if (ret) {
- gf_log ("glusterd", GF_LOG_ERROR, "Failed to "
- "disconnect %s:%s", brickinfo->hostname,
- brickinfo->path);
- break;
- }
- }
- }
-
- return ret;
-}
-
-int32_t
-glusterd_volinfo_copy_brick_portinfo (glusterd_volinfo_t *new_volinfo,
- glusterd_volinfo_t *old_volinfo)
-{
- glusterd_brickinfo_t *new_brickinfo = NULL;
- glusterd_brickinfo_t *old_brickinfo = NULL;
-
- int ret = 0;
- GF_ASSERT (new_volinfo);
- GF_ASSERT (old_volinfo);
- if (_gf_false == glusterd_is_volume_started (new_volinfo))
- goto out;
- list_for_each_entry (new_brickinfo, &new_volinfo->bricks, brick_list) {
- ret = glusterd_volume_brickinfo_get (new_brickinfo->uuid,
- new_brickinfo->hostname,
- new_brickinfo->path,
- old_volinfo, &old_brickinfo);
- if ((0 == ret) && glusterd_is_brick_started (old_brickinfo)) {
- new_brickinfo->port = old_brickinfo->port;
- }
- }
-out:
- ret = 0;
- return ret;
-}
-
-int32_t
-glusterd_volinfo_stop_stale_bricks (glusterd_volinfo_t *new_volinfo,
- glusterd_volinfo_t *old_volinfo)
-{
- glusterd_brickinfo_t *new_brickinfo = NULL;
- glusterd_brickinfo_t *old_brickinfo = NULL;
-
- int ret = 0;
- GF_ASSERT (new_volinfo);
- GF_ASSERT (old_volinfo);
- if (_gf_false == glusterd_is_volume_started (old_volinfo))
- goto out;
- list_for_each_entry (old_brickinfo, &old_volinfo->bricks, brick_list) {
- ret = glusterd_volume_brickinfo_get (old_brickinfo->uuid,
- old_brickinfo->hostname,
- old_brickinfo->path,
- new_volinfo, &new_brickinfo);
- /* If the brick is stale, i.e it's not a part of the new volume
- * or if it's part of the new volume and is pending a snap,
- * then stop the brick process
- */
- if (ret || (new_brickinfo->snap_status == -1)) {
- /*TODO: may need to switch to 'atomic' flavour of
- * brick_stop, once we make peer rpc program also
- * synctask enabled*/
- ret = glusterd_brick_stop (old_volinfo, old_brickinfo,
- _gf_false);
- if (ret)
- gf_msg ("glusterd", GF_LOG_ERROR, 0,
- GD_MSG_BRICK_STOP_FAIL, "Failed to stop"
- " brick %s:%s", old_brickinfo->hostname,
- old_brickinfo->path);
- }
- }
- ret = 0;
-out:
- gf_log ("", GF_LOG_DEBUG, "Returning with %d", ret);
- return ret;
-}
-
-int32_t
-glusterd_delete_stale_volume (glusterd_volinfo_t *stale_volinfo,
- glusterd_volinfo_t *valid_volinfo)
-{
- int32_t ret = -1;
- glusterd_volinfo_t *temp_volinfo = NULL;
- glusterd_volinfo_t *voliter = NULL;
- xlator_t *this = NULL;
-
- GF_ASSERT (stale_volinfo);
- GF_ASSERT (valid_volinfo);
- this = THIS;
- GF_ASSERT (this);
-
- /* Copy snap_volumes list from stale_volinfo to valid_volinfo */
- valid_volinfo->snap_count = 0;
- list_for_each_entry_safe (voliter, temp_volinfo,
- &stale_volinfo->snap_volumes, snapvol_list) {
- list_add_tail (&voliter->snapvol_list,
- &valid_volinfo->snap_volumes);
- valid_volinfo->snap_count++;
- }
-
- if ((!uuid_is_null (stale_volinfo->restored_from_snap)) &&
- (uuid_compare (stale_volinfo->restored_from_snap,
- valid_volinfo->restored_from_snap))) {
- ret = glusterd_lvm_snapshot_remove (NULL, stale_volinfo);
- if (ret) {
- gf_log(this->name, GF_LOG_WARNING,
- "Failed to remove lvm snapshot for "
- "restored volume %s", stale_volinfo->volname);
- }
- }
-
- /* If stale volume is in started state, copy the port numbers of the
- * local bricks if they exist in the valid volume information.
- * 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.
- */
- if (glusterd_is_volume_started (stale_volinfo)) {
- if (glusterd_is_volume_started (valid_volinfo)) {
- (void) glusterd_volinfo_stop_stale_bricks (valid_volinfo,
- stale_volinfo);
- //Only valid bricks will be running now.
- (void) glusterd_volinfo_copy_brick_portinfo (valid_volinfo,
- 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
- * performed because some of the bricks could still be running,
- * keeping pid files under run directory
- */
- (void) glusterd_delete_all_bricks (stale_volinfo);
- if (stale_volinfo->shandle) {
- unlink (stale_volinfo->shandle->path);
- (void) gf_store_handle_destroy (stale_volinfo->shandle);
- stale_volinfo->shandle = NULL;
- }
- (void) glusterd_snapd_stop (stale_volinfo);
- (void) glusterd_volinfo_remove (stale_volinfo);
-
- return 0;
-}
-
-/* This function updates the rebalance information of the new volinfo using the
- * information from the old volinfo.
- */
-int
-gd_check_and_update_rebalance_info (glusterd_volinfo_t *old_volinfo,
- glusterd_volinfo_t *new_volinfo)
-{
- int ret = -1;
- glusterd_rebalance_t *old = NULL;
- glusterd_rebalance_t *new = NULL;
-
- GF_ASSERT (old_volinfo);
- GF_ASSERT (new_volinfo);
-
- old = &(old_volinfo->rebal);
- new = &(new_volinfo->rebal);
-
- //Disconnect from rebalance process
- if (old->defrag && old->defrag->rpc) {
- rpc_transport_disconnect (old->defrag->rpc->conn.trans);
- }
-
- if (!uuid_is_null (old->rebalance_id) &&
- uuid_compare (old->rebalance_id, new->rebalance_id)) {
- (void)gd_stop_rebalance_process (old_volinfo);
- goto out;
- }
-
- /* If the tasks match, copy the status and other information of the
- * rebalance process from old_volinfo to new_volinfo
- */
- new->defrag_status = old->defrag_status;
- new->rebalance_files = old->rebalance_files;
- new->rebalance_data = old->rebalance_data;
- new->lookedup_files = old->lookedup_files;
- new->skipped_files = old->skipped_files;
- new->rebalance_failures = old->rebalance_failures;
- new->rebalance_time = old->rebalance_time;
- new->dict = (old->dict ? dict_ref (old->dict) : NULL);
-
- /* glusterd_rebalance_t.{op, id, defrag_cmd} are copied during volume
- * import
- * a new defrag object should come to life with rebalance being restarted
- */
-out:
- return ret;
-}
-
-int32_t
-glusterd_import_friend_volume (dict_t *peer_data, size_t count)
-{
-
- int32_t ret = -1;
- glusterd_conf_t *priv = NULL;
- xlator_t *this = NULL;
- glusterd_volinfo_t *old_volinfo = NULL;
- glusterd_volinfo_t *new_volinfo = NULL;
-
- GF_ASSERT (peer_data);
-
- this = THIS;
- GF_ASSERT (this);
- priv = this->private;
- GF_ASSERT (priv);
- ret = glusterd_import_volinfo (peer_data, count,
- &new_volinfo, "volume");
- if (ret)
- goto out;
-
- if (!new_volinfo) {
- gf_log (this->name, GF_LOG_DEBUG,
- "Not importing snap volume");
- goto out;
- }
-
- ret = glusterd_volinfo_find (new_volinfo->volname, &old_volinfo);
- if (0 == ret) {
- (void) gd_check_and_update_rebalance_info (old_volinfo,
- new_volinfo);
- (void) glusterd_delete_stale_volume (old_volinfo, new_volinfo);
- }
-
- if (glusterd_is_volume_started (new_volinfo)) {
- (void) glusterd_start_bricks (new_volinfo);
- if (glusterd_is_snapd_enabled (new_volinfo))
- (void) glusterd_snapd_start (new_volinfo, _gf_false);
- }
-
- ret = glusterd_store_volinfo (new_volinfo, GLUSTERD_VOLINFO_VER_AC_NONE);
- ret = glusterd_create_volfiles_and_notify_services (new_volinfo);
- if (ret)
- goto out;
-
- ret = glusterd_import_quota_conf (peer_data, count,
- new_volinfo, "volume");
- if (ret)
- goto out;
-
- list_add_order (&new_volinfo->vol_list, &priv->volumes,
- glusterd_compare_volume_name);
-out:
- gf_log ("", GF_LOG_DEBUG, "Returning with ret: %d", ret);
- return ret;
-}
-
-int32_t
-glusterd_import_friend_volumes (dict_t *peer_data)
-{
- int32_t ret = -1;
- int32_t count = 0;
- int i = 1;
-
- GF_ASSERT (peer_data);
-
- ret = dict_get_int32 (peer_data, "count", &count);
- if (ret)
- goto out;
-
- while (i <= count) {
- ret = glusterd_import_friend_volume (peer_data, i);
- if (ret)
- goto out;
- i++;
- }
-
-out:
- gf_log ("", GF_LOG_DEBUG, "Returning with %d", ret);
- return ret;
-}
-
-int
-glusterd_get_global_opt_version (dict_t *opts, uint32_t *version)
-{
- int ret = -1;
- char *version_str = NULL;
-
- ret = dict_get_str (opts, GLUSTERD_GLOBAL_OPT_VERSION, &version_str);
- if (ret)
- goto out;
-
- ret = gf_string2uint (version_str, version);
- if (ret)
- goto out;
- ret = 0;
-out:
- return ret;
-}
-
-int
-glusterd_get_next_global_opt_version_str (dict_t *opts, char **version_str)
-{
- int ret = -1;
- char version_string[64] = {0};
- uint32_t version = 0;
-
- ret = glusterd_get_global_opt_version (opts, &version);
- if (ret)
- goto out;
- version++;
- snprintf (version_string, sizeof (version_string), "%"PRIu32, version);
- *version_str = gf_strdup (version_string);
- if (*version_str)
- ret = 0;
-out:
- return ret;
-}
-
-int32_t
-glusterd_import_global_opts (dict_t *friend_data)
-{
- xlator_t *this = NULL;
- glusterd_conf_t *conf = NULL;
- int ret = -1;
- dict_t *import_options = NULL;
- int count = 0;
- uint32_t local_version = 0;
- uint32_t remote_version = 0;
-
- this = THIS;
- conf = this->private;
-
- ret = dict_get_int32 (friend_data, "global-opt-count", &count);
- if (ret) {
- //old version peer
- ret = 0;
- goto out;
- }
-
- import_options = dict_new ();
- if (!import_options)
- goto out;
- ret = import_prdict_dict (friend_data, import_options, "key", "val",
- count, "global");
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to import"
- " global options");
- goto out;
- }
-
- ret = glusterd_get_global_opt_version (conf->opts, &local_version);
- if (ret)
- goto out;
- ret = glusterd_get_global_opt_version (import_options, &remote_version);
- if (ret)
- goto out;
- if (remote_version > local_version) {
- ret = glusterd_store_options (this, import_options);
- if (ret)
- goto out;
- dict_unref (conf->opts);
- conf->opts = dict_ref (import_options);
- }
- ret = 0;
-out:
- if (import_options)
- dict_unref (import_options);
- return ret;
-}
-
-int32_t
-glusterd_perform_missed_op (glusterd_snap_t *snap, int32_t op)
-{
- dict_t *dict = NULL;
- int32_t ret = -1;
- glusterd_conf_t *priv = NULL;
- glusterd_volinfo_t *snap_volinfo = NULL;
- glusterd_volinfo_t *volinfo = NULL;
- glusterd_volinfo_t *tmp = NULL;
- xlator_t *this = NULL;
- uuid_t null_uuid = {0};
-
- this = THIS;
- GF_ASSERT (this);
-
- priv = this->private;
- GF_ASSERT (priv);
- GF_ASSERT (snap);
-
- dict = dict_new();
- if (!dict) {
- gf_log (this->name, GF_LOG_ERROR, "Unable to create dict");
- ret = -1;
- goto out;
- }
-
- switch (op) {
- case GF_SNAP_OPTION_TYPE_DELETE:
- ret = glusterd_snap_remove (dict, snap, _gf_true, _gf_false);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to remove snap");
- goto out;
- }
-
- break;
- case GF_SNAP_OPTION_TYPE_RESTORE:
- list_for_each_entry_safe (snap_volinfo, tmp,
- &snap->volumes, vol_list) {
- ret = glusterd_volinfo_find
- (snap_volinfo->parent_volname,
- &volinfo);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Could not get volinfo of %s",
- snap_volinfo->parent_volname);
- goto out;
- }
-
- volinfo->version--;
- uuid_copy (volinfo->restored_from_snap, null_uuid);
-
- /* gd_restore_snap_volume() uses the dict and volcount
- * to fetch snap brick info from other nodes, which were
- * collected during prevalidation. As this is an ad-hoc
- * op and only local node's data matter, hence sending
- * volcount as 0 and re-using the same dict because we
- * need not record any missed creates in the rsp_dict.
- */
- ret = gd_restore_snap_volume (dict, dict, volinfo,
- snap_volinfo, 0);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to restore snap for %s",
- snap->snapname);
- volinfo->version++;
- goto out;
- }
-
- ret = glusterd_snapshot_restore_cleanup (dict, volinfo,
- snap);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to perform snapshot restore "
- "cleanup for %s volume",
- snap_volinfo->parent_volname);
- goto out;
- }
- }
-
- break;
- default:
- /* The entry must be a create, delete, or
- * restore entry
- */
- gf_log (this->name, GF_LOG_ERROR, "Invalid missed snap entry");
- ret = -1;
- goto out;
- }
-
-out:
- dict_unref (dict);
- gf_log (this->name, GF_LOG_TRACE, "Returning %d", ret);
- return ret;
-}
-
-/* Perform missed deletes and restores on this node */
-int32_t
-glusterd_perform_missed_snap_ops ()
-{
- int32_t ret = -1;
- int32_t op_status = -1;
- glusterd_conf_t *priv = NULL;
- glusterd_missed_snap_info *missed_snapinfo = NULL;
- glusterd_snap_op_t *snap_opinfo = NULL;
- glusterd_snap_t *snap = NULL;
- uuid_t snap_uuid = {0,};
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
-
- priv = this->private;
- GF_ASSERT (priv);
-
- list_for_each_entry (missed_snapinfo, &priv->missed_snaps_list,
- missed_snaps) {
- /* If the pending snap_op is not for this node then continue */
- if (strcmp (missed_snapinfo->node_uuid, uuid_utoa (MY_UUID)))
- continue;
-
- /* Find the snap id */
- uuid_parse (missed_snapinfo->snap_uuid, snap_uuid);
- snap = NULL;
- snap = glusterd_find_snap_by_id (snap_uuid);
- if (!snap) {
- /* If the snap is not found, then a delete or a
- * restore can't be pending on that snap_uuid.
- */
- gf_log (this->name, GF_LOG_DEBUG,
- "Not a pending delete or restore op");
- continue;
- }
-
- op_status = GD_MISSED_SNAP_PENDING;
- list_for_each_entry (snap_opinfo, &missed_snapinfo->snap_ops,
- snap_ops_list) {
- /* If the snap_op is create or its status is
- * GD_MISSED_SNAP_DONE then continue
- */
- if ((snap_opinfo->status == GD_MISSED_SNAP_DONE) ||
- (snap_opinfo->op == GF_SNAP_OPTION_TYPE_CREATE))
- continue;
-
- /* Perform the actual op for the first time for
- * this snap, and mark the snap_status as
- * GD_MISSED_SNAP_DONE. For other entries for the same
- * snap, just mark the entry as done.
- */
- if (op_status == GD_MISSED_SNAP_PENDING) {
- ret = glusterd_perform_missed_op
- (snap,
- snap_opinfo->op);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to perform missed snap op");
- goto out;
- }
- op_status = GD_MISSED_SNAP_DONE;
- }
-
- snap_opinfo->status = GD_MISSED_SNAP_DONE;
- }
- }
-
- ret = 0;
-out:
- gf_log (this->name, GF_LOG_TRACE, "Returning %d", ret);
- return ret;
-}
-
-/* Import friend volumes missed_snap_list and update *
- * missed_snap_list if need be */
-int32_t
-glusterd_import_friend_missed_snap_list (dict_t *peer_data)
-{
- int32_t missed_snap_count = -1;
- int32_t ret = -1;
- glusterd_conf_t *priv = NULL;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (peer_data);
-
- priv = this->private;
- GF_ASSERT (priv);
-
- /* Add the friends missed_snaps entries to the in-memory list */
- ret = dict_get_int32 (peer_data, "missed_snap_count",
- &missed_snap_count);
- if (ret) {
- gf_log (this->name, GF_LOG_INFO,
- "No missed snaps");
- ret = 0;
- goto out;
- }
-
- ret = glusterd_add_missed_snaps_to_list (peer_data,
- missed_snap_count);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to add missed snaps to list");
- goto out;
- }
-
- ret = glusterd_perform_missed_snap_ops ();
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to perform snap operations");
- /* Not going to out at this point coz some *
- * missed ops might have been performed. We *
- * need to persist the current list *
- */
- }
-
- ret = glusterd_store_update_missed_snaps ();
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to update missed_snaps_list");
- goto out;
- }
-
-out:
- gf_log (this->name, GF_LOG_TRACE, "Returning %d", ret);
- return ret;
-}
-
-/* Check for the peer_snap_name in the list of existing snapshots.
- * If a snap exists with the same name and a different snap_id, then
- * there is a conflict. Set conflict as _gf_true, and snap to the
- * conflicting snap object. If a snap exists with the same name, and the
- * same snap_id, then there is no conflict. Set conflict as _gf_false
- * and snap to the existing snap object. If no snap exists with the
- * peer_snap_name, then there is no conflict. Set conflict as _gf_false
- * and snap to NULL.
- */
-void
-glusterd_is_peer_snap_conflicting (char *peer_snap_name, char *peer_snap_id,
- gf_boolean_t *conflict,
- glusterd_snap_t **snap, char *hostname)
-{
- uuid_t peer_snap_uuid = {0,};
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (peer_snap_name);
- GF_ASSERT (peer_snap_id);
- GF_ASSERT (conflict);
- GF_ASSERT (snap);
- GF_ASSERT (hostname);
-
- *snap = glusterd_find_snap_by_name (peer_snap_name);
- if (*snap) {
- uuid_parse (peer_snap_id, peer_snap_uuid);
- if (!uuid_compare (peer_snap_uuid, (*snap)->snap_id)) {
- /* Current node contains the same snap having
- * the same snapname and snap_id
- */
- gf_log (this->name, GF_LOG_DEBUG,
- "Snapshot %s from peer %s present in "
- "localhost", peer_snap_name, hostname);
- *conflict = _gf_false;
- } else {
- /* Current node contains the same snap having
- * the same snapname but different snap_id
- */
- gf_log (this->name, GF_LOG_DEBUG,
- "Snapshot %s from peer %s conflicts with "
- "snapshot in localhost", peer_snap_name,
- hostname);
- *conflict = _gf_true;
- }
- } else {
- /* Peer contains snapshots missing on the current node */
- gf_log (this->name, GF_LOG_INFO,
- "Snapshot %s from peer %s missing on localhost",
- peer_snap_name, hostname);
- *conflict = _gf_false;
- }
-}
-
-/* Check if the local node is hosting any bricks for the given snapshot */
-gf_boolean_t
-glusterd_are_snap_bricks_local (glusterd_snap_t *snap)
-{
- gf_boolean_t is_local = _gf_false;
- glusterd_volinfo_t *volinfo = NULL;
- glusterd_brickinfo_t *brickinfo = NULL;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (snap);
-
- list_for_each_entry (volinfo, &snap->volumes, vol_list) {
- list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) {
- if (!uuid_compare (brickinfo->uuid, MY_UUID)) {
- is_local = _gf_true;
- goto out;
- }
- }
- }
-
-out:
- gf_log (this->name, GF_LOG_TRACE, "Returning %d", is_local);
- return is_local;
-}
-
-/* Check if the peer has missed any snap delete
- * or restore for the given snap_id
- */
-gf_boolean_t
-glusterd_peer_has_missed_snap_delete (glusterd_peerinfo_t *peerinfo,
- char *peer_snap_id)
-{
- char *peer_uuid = NULL;
- gf_boolean_t missed_delete = _gf_false;
- glusterd_conf_t *priv = NULL;
- glusterd_missed_snap_info *missed_snapinfo = NULL;
- glusterd_snap_op_t *snap_opinfo = NULL;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- priv = this->private;
- GF_ASSERT (priv);
- GF_ASSERT (peerinfo);
- GF_ASSERT (peer_snap_id);
-
- peer_uuid = uuid_utoa (peerinfo->uuid);
-
- list_for_each_entry (missed_snapinfo, &priv->missed_snaps_list,
- missed_snaps) {
- /* Look for missed snap for the same peer, and
- * the same snap_id
- */
- if ((!strcmp (peer_uuid, missed_snapinfo->node_uuid)) &&
- (!strcmp (peer_snap_id, missed_snapinfo->snap_uuid))) {
- /* Check if the missed snap's op is delete and the
- * status is pending
- */
- list_for_each_entry (snap_opinfo,
- &missed_snapinfo->snap_ops,
- snap_ops_list) {
- if (((snap_opinfo->op ==
- GF_SNAP_OPTION_TYPE_DELETE) ||
- (snap_opinfo->op ==
- GF_SNAP_OPTION_TYPE_RESTORE)) &&
- (snap_opinfo->status ==
- GD_MISSED_SNAP_PENDING)) {
- missed_delete = _gf_true;
- goto out;
- }
- }
- }
- }
-
-out:
- gf_log (this->name, GF_LOG_TRACE, "Returning %d", missed_delete);
- return missed_delete;
-}
-
-/* Genrate and store snap volfiles for imported snap object */
-int32_t
-glusterd_gen_snap_volfiles (glusterd_volinfo_t *snap_vol, char *peer_snap_name)
-{
- int32_t ret = -1;
- xlator_t *this = NULL;
- glusterd_volinfo_t *parent_volinfo = NULL;
- glusterd_brickinfo_t *brickinfo = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (snap_vol);
- GF_ASSERT (peer_snap_name);
-
- ret = glusterd_store_volinfo (snap_vol, GLUSTERD_VOLINFO_VER_AC_NONE);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to store snapshot "
- "volinfo (%s) for snap %s", snap_vol->volname,
- peer_snap_name);
- goto out;
- }
-
- ret = generate_brick_volfiles (snap_vol);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "generating the brick volfiles for the "
- "snap %s failed", peer_snap_name);
- goto out;
- }
-
- ret = generate_client_volfiles (snap_vol, GF_CLIENT_TRUSTED);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "generating the trusted client volfiles for "
- "the snap %s failed", peer_snap_name);
- goto out;
- }
-
- ret = generate_client_volfiles (snap_vol, GF_CLIENT_OTHER);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "generating the client volfiles for the "
- "snap %s failed", peer_snap_name);
- goto out;
- }
-
- ret = glusterd_volinfo_find (snap_vol->parent_volname,
- &parent_volinfo);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Parent volinfo "
- "not found for %s volume of snap %s",
- snap_vol->volname, peer_snap_name);
- goto out;
- }
-
- glusterd_list_add_snapvol (parent_volinfo, snap_vol);
-
- snap_vol->status = GLUSTERD_STATUS_STARTED;
-
- ret = glusterd_store_volinfo (snap_vol, GLUSTERD_VOLINFO_VER_AC_NONE);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to store snap volinfo");
- goto out;
- }
-out:
- gf_log (this->name, GF_LOG_TRACE, "Returning %d", ret);
- return ret;
-}
-
-/* Import snapshot info from peer_data and add it to priv */
-int32_t
-glusterd_import_friend_snap (dict_t *peer_data, int32_t snap_count,
- char *peer_snap_name, char *peer_snap_id)
-{
- char buf[NAME_MAX] = "";
- char prefix[NAME_MAX] = "";
- dict_t *dict = NULL;
- glusterd_snap_t *snap = NULL;
- glusterd_volinfo_t *snap_vol = NULL;
- glusterd_conf_t *priv = NULL;
- int32_t ret = -1;
- int32_t volcount = -1;
- int32_t i = -1;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- priv = this->private;
- GF_ASSERT (priv);
- GF_ASSERT (peer_data);
- GF_ASSERT (peer_snap_name);
- GF_ASSERT (peer_snap_id);
-
- snprintf (prefix, sizeof(prefix), "snap%d", snap_count);
-
- snap = glusterd_new_snap_object ();
- if (!snap) {
- gf_log (this->name, GF_LOG_ERROR, "Could not create "
- "the snap object for snap %s", peer_snap_name);
- goto out;
- }
-
- dict = dict_new ();
- if (!dict) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to create dict");
- ret = -1;
- goto out;
- }
-
- strcpy (snap->snapname, peer_snap_name);
- uuid_parse (peer_snap_id, snap->snap_id);
-
- snprintf (buf, sizeof(buf), "%s.snapid", prefix);
- ret = dict_get_str (peer_data, buf, &snap->description);
-
- snprintf (buf, sizeof(buf), "%s.time_stamp", prefix);
- ret = dict_get_int64 (peer_data, buf, &snap->time_stamp);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Unable to get time_stamp for snap %s",
- peer_snap_name);
- goto out;
- }
-
- snprintf (buf, sizeof(buf), "%s.snap_restored", prefix);
- ret = dict_get_int8 (peer_data, buf, (int8_t *) &snap->snap_restored);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Unable to get snap_restored for snap %s",
- peer_snap_name);
- goto out;
- }
-
- snprintf (buf, sizeof(buf), "%s.snap_status", prefix);
- ret = dict_get_int32 (peer_data, buf, (int32_t *) &snap->snap_status);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Unable to get snap_status for snap %s",
- peer_snap_name);
- goto out;
- }
-
- /* If the snap is scheduled to be decommissioned, then
- * don't accept the snap */
- if (snap->snap_status == GD_SNAP_STATUS_DECOMMISSION) {
- gf_log (this->name, GF_LOG_DEBUG,
- "The snap(%s) is scheduled to be decommissioned "
- "Not accepting the snap.", peer_snap_name);
- glusterd_snap_remove (dict, snap,
- _gf_true, _gf_true);
- ret = 0;
- goto out;
- }
-
- snprintf (buf, sizeof(buf), "%s.volcount", prefix);
- ret = dict_get_int32 (peer_data, buf, &volcount);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Unable to get volcount for snap %s",
- peer_snap_name);
- goto out;
- }
-
- ret = glusterd_store_create_snap_dir (snap);
- if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR, "Failed to create snap dir");
- goto out;
- }
-
- list_add_order (&snap->snap_list, &priv->snapshots,
- glusterd_compare_snap_time);
-
- for (i = 1; i <= volcount; i++) {
- ret = glusterd_import_volinfo (peer_data, i,
- &snap_vol, prefix);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to import snap volinfo for "
- "snap %s", peer_snap_name);
- goto out;
- }
-
- snap_vol->snapshot = snap;
-
- ret = glusterd_gen_snap_volfiles (snap_vol, peer_snap_name);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to generate snap vol files "
- "for snap %s", peer_snap_name);
- goto out;
- }
-
- ret = glusterd_import_quota_conf (peer_data, i,
- snap_vol, prefix);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to import quota conf "
- "for snap %s", peer_snap_name);
- goto out;
- }
-
- snap_vol = NULL;
- }
-
- ret = glusterd_store_snap (snap);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING, "Could not store snap"
- "object %s", peer_snap_name);
- goto out;
- }
-
-out:
- if (ret)
- glusterd_snap_remove (dict, snap,
- _gf_true, _gf_true);
-
- if (dict)
- dict_unref (dict);
-
- gf_log (this->name, GF_LOG_TRACE, "Returning %d", ret);
- return ret;
-}
-
-/* During a peer-handshake, after the volumes have synced, and the list of
- * missed snapshots have synced, the node will perform the pending deletes
- * and restores on this list. At this point, the current snapshot list in
- * the node will be updated, and hence in case of conflicts arising during
- * snapshot handshake, the peer hosting the bricks will be given precedence
- * Likewise, if there will be a conflict, and both peers will be in the same
- * state, i.e either both would be hosting bricks or both would not be hosting
- * bricks, then a decision can't be taken and a peer-reject will happen.
- *
- * glusterd_compare_and_update_snap() implements the following algorithm to
- * perform the above task:
- * Step 1: Start.
- * Step 2: Check if the peer is missing a delete or restore on the said snap.
- * If yes, goto step 6.
- * Step 3: Check if there is a conflict between the peer's data and the
- * local snap. If no, goto step 5.
- * Step 4: As there is a conflict, check if both the peer and the local nodes
- * are hosting bricks. Based on the results perform the following:
- * Peer Hosts Bricks Local Node Hosts Bricks Action
- * Yes Yes Goto Step 7
- * No No Goto Step 7
- * Yes No Goto Step 8
- * No Yes Goto Step 6
- * Step 5: Check if the local node is missing the peer's data.
- * If yes, goto step 9.
- * Step 6: It's a no-op. Goto step 10
- * Step 7: Peer Reject. Goto step 10
- * Step 8: Delete local node's data.
- * Step 9: Accept Peer Data.
- * Step 10: Stop
- *
- */
-int32_t
-glusterd_compare_and_update_snap (dict_t *peer_data, int32_t snap_count,
- glusterd_peerinfo_t *peerinfo)
-{
- char buf[NAME_MAX] = "";
- char prefix[NAME_MAX] = "";
- char *peer_snap_name = NULL;
- char *peer_snap_id = NULL;
- dict_t *dict = NULL;
- glusterd_snap_t *snap = NULL;
- gf_boolean_t conflict = _gf_false;
- gf_boolean_t is_local = _gf_false;
- gf_boolean_t is_hosted = _gf_false;
- gf_boolean_t missed_delete = _gf_false;
- int32_t ret = -1;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (peer_data);
- GF_ASSERT (peerinfo);
-
- snprintf (prefix, sizeof(prefix), "snap%d", snap_count);
-
- /* Fetch the peer's snapname */
- snprintf (buf, sizeof(buf), "%s.snapname", prefix);
- ret = dict_get_str (peer_data, buf, &peer_snap_name);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Unable to fetch snapname from peer: %s",
- peerinfo->hostname);
- goto out;
- }
-
- /* Fetch the peer's snap_id */
- snprintf (buf, sizeof(buf), "%s.snap_id", prefix);
- ret = dict_get_str (peer_data, buf, &peer_snap_id);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Unable to fetch snap_id from peer: %s",
- peerinfo->hostname);
- goto out;
- }
-
- /* Check if the peer has missed a snap delete or restore
- * resulting in stale data for the snap in question
- */
- missed_delete = glusterd_peer_has_missed_snap_delete (peerinfo,
- peer_snap_id);
- if (missed_delete == _gf_true) {
- /* Peer has missed delete on the missing/conflicting snap_id */
- gf_log (this->name, GF_LOG_INFO, "Peer %s has missed a delete "
- "on snap %s", peerinfo->hostname, peer_snap_name);
- ret = 0;
- goto out;
- }
-
- /* Check if there is a conflict, and if the
- * peer data is already present
- */
- glusterd_is_peer_snap_conflicting (peer_snap_name, peer_snap_id,
- &conflict, &snap,
- peerinfo->hostname);
- if (conflict == _gf_false) {
- if (snap) {
- /* Peer has snap with the same snapname
- * and snap_id. No need to accept peer data
- */
- ret = 0;
- goto out;
- } else {
- /* Peer has snap with the same snapname
- * and snap_id, which local node doesn't have.
- */
- goto accept_peer_data;
- }
- }
-
- /* There is a conflict. Check if the current node is
- * hosting bricks for the conflicted snap.
- */
- is_local = glusterd_are_snap_bricks_local (snap);
-
- /* Check if the peer is hosting any bricks for the
- * conflicting snap
- */
- snprintf (buf, sizeof(buf), "%s.host_bricks", prefix);
- ret = dict_get_int8 (peer_data, buf, (int8_t *) &is_hosted);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Unable to fetch host_bricks from peer: %s "
- "for %s", peerinfo->hostname, peer_snap_name);
- goto out;
- }
-
- /* As there is a conflict at this point of time, the data of the
- * node that hosts a brick takes precedence. If both the local
- * node and the peer are in the same state, i.e if both of them
- * are either hosting or not hosting the bricks, for the snap,
- * then it's a peer reject
- */
- if (is_hosted == is_local) {
- gf_log (this->name, GF_LOG_ERROR,
- "Conflict in snapshot %s with peer %s",
- peer_snap_name, peerinfo->hostname);
- ret = -1;
- goto out;
- }
-
- if (is_hosted == _gf_false) {
- /* If there was a conflict, and the peer is not hosting
- * any brick, then don't accept peer data
- */
- gf_log (this->name, GF_LOG_DEBUG,
- "Peer doesn't hosts bricks for conflicting "
- "snap(%s). Not accepting peer data.",
- peer_snap_name);
- ret = 0;
- goto out;
- }
-
- /* The peer is hosting a brick in case of conflict
- * And local node isn't. Hence remove local node's
- * data and accept peer data
- */
-
- gf_log (this->name, GF_LOG_DEBUG, "Peer hosts bricks for conflicting "
- "snap(%s). Removing local data. Accepting peer data.",
- peer_snap_name);
-
- dict = dict_new();
- if (!dict) {
- gf_log (this->name, GF_LOG_ERROR,
- "Unable to create dict");
- ret = -1;
- goto out;
- }
-
- ret = glusterd_snap_remove (dict, snap, _gf_true, _gf_false);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to remove snap %s", snap->snapname);
- goto out;
- }
-
-accept_peer_data:
-
- /* Accept Peer Data */
- ret = glusterd_import_friend_snap (peer_data, snap_count,
- peer_snap_name, peer_snap_id);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to import snap %s from peer %s",
- peer_snap_name, peerinfo->hostname);
- goto out;
- }
-
-out:
- if (dict)
- dict_unref (dict);
-
- gf_log (this->name, GF_LOG_TRACE, "Returning %d", ret);
- return ret;
-}
-
-/* Compare snapshots present in peer_data, with the snapshots in
- * the current node
- */
-int32_t
-glusterd_compare_friend_snapshots (dict_t *peer_data,
- glusterd_peerinfo_t *peerinfo)
-{
- int32_t ret = -1;
- int32_t snap_count = 0;
- int i = 1;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (peer_data);
- GF_ASSERT (peerinfo);
-
- ret = dict_get_int32 (peer_data, "snap_count", &snap_count);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to fetch snap_count");
- goto out;
- }
-
- for (i = 1; i <= snap_count; i++) {
- /* Compare one snapshot from peer_data at a time */
- ret = glusterd_compare_and_update_snap (peer_data, i, peerinfo);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to compare snapshots with peer %s",
- peerinfo->hostname);
- goto out;
- }
- }
-
-out:
- gf_log (this->name, GF_LOG_TRACE, "Returning %d", ret);
- return ret;
-}
-
-int32_t
-glusterd_compare_friend_data (dict_t *peer_data, int32_t *status,
- char *hostname)
-{
- int32_t ret = -1;
- int32_t count = 0;
- int i = 1;
- gf_boolean_t update = _gf_false;
- gf_boolean_t stale_nfs = _gf_false;
- gf_boolean_t stale_shd = _gf_false;
- gf_boolean_t stale_qd = _gf_false;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (peer_data);
- GF_ASSERT (status);
-
- ret = glusterd_import_global_opts (peer_data);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Importing global "
- "options failed");
- goto out;
- }
-
- ret = dict_get_int32 (peer_data, "count", &count);
- if (ret)
- goto out;
-
- while (i <= count) {
- ret = glusterd_compare_friend_volume (peer_data, i, status,
- hostname);
- if (ret)
- goto out;
-
- if (GLUSTERD_VOL_COMP_RJT == *status) {
- ret = 0;
- goto out;
- }
- if (GLUSTERD_VOL_COMP_UPDATE_REQ == *status)
- update = _gf_true;
-
- i++;
- }
-
- if (update) {
- if (glusterd_is_nodesvc_running ("nfs"))
- stale_nfs = _gf_true;
- if (glusterd_is_nodesvc_running ("glustershd"))
- stale_shd = _gf_true;
- if (glusterd_is_nodesvc_running ("quotad"))
- stale_qd = _gf_true;
- ret = glusterd_import_friend_volumes (peer_data);
- if (ret)
- goto out;
- if (_gf_false == glusterd_are_all_volumes_stopped ()) {
- ret = glusterd_nodesvcs_handle_graph_change (NULL);
- } else {
- if (stale_nfs)
- glusterd_nfs_server_stop ();
- if (stale_shd)
- glusterd_shd_stop ();
- if (stale_qd)
- glusterd_quotad_stop ();
- }
- }
-
-out:
- gf_log (this->name, GF_LOG_DEBUG,
- "Returning with ret: %d, status: %d", ret, *status);
- return ret;
-}
-
-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));
- if (strcmp ("quotad", server) != 0)
- snprintf (volfile, len, "%s/%s-server.vol", dir, server);
- else
- snprintf (volfile, len, "%s/%s.vol", dir, server);
-}
-
-void
-glusterd_nodesvc_set_online_status (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);
- GF_ASSERT (priv->quotad);
-
- if (!strcmp("glustershd", server))
- priv->shd->online = status;
- else if (!strcmp ("nfs", server))
- priv->nfs->online = status;
- else if (!strcmp ("quotad", server))
- priv->quotad->online = status;
-}
-
-gf_boolean_t
-glusterd_is_nodesvc_online (char *server)
-{
- glusterd_conf_t *conf = NULL;
- gf_boolean_t online = _gf_false;
-
- GF_ASSERT (server);
- conf = THIS->private;
- GF_ASSERT (conf);
- GF_ASSERT (conf->shd);
- GF_ASSERT (conf->nfs);
- GF_ASSERT (conf->quotad);
-
- if (!strcmp (server, "glustershd"))
- online = conf->shd->online;
- else if (!strcmp (server, "nfs"))
- online = conf->nfs->online;
- else if (!strcmp (server, "quotad"))
- online = conf->quotad->online;
-
- return online;
-}
-
-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;
- nodesrv_t *quotad = NULL;
- glusterd_snapd_t *snapd = 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->rebal.defrag)
- rpc = volinfo->rebal.defrag->rpc;
-
- } else if (pending_node->type == GD_NODE_NFS) {
- nfs = pending_node->node;
- rpc = nfs->rpc;
-
- } else if (pending_node->type == GD_NODE_QUOTAD) {
- quotad = pending_node->node;
- rpc = quotad->rpc;
- } else if (pending_node->type == GD_NODE_SNAPD) {
- snapd = pending_node->node;
- rpc = snapd->rpc;
- } else {
- GF_ASSERT (0);
- }
-
-out:
- return rpc;
-}
-
-static inline struct rpc_clnt*
-glusterd_snapd_get_rpc (glusterd_volinfo_t *volinfo)
-{
- return volinfo->snapd.rpc;
-}
-
-struct rpc_clnt*
-glusterd_nodesvc_get_rpc (char *server)
-{
- 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);
- GF_ASSERT (priv->quotad);
-
- if (!strcmp (server, "glustershd"))
- rpc = priv->shd->rpc;
- else if (!strcmp (server, "nfs"))
- rpc = priv->nfs->rpc;
- else if (!strcmp (server, "quotad"))
- rpc = priv->quotad->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;
-
- this = THIS;
- GF_ASSERT (this);
- priv = this->private;
- GF_ASSERT (priv);
- GF_ASSERT (priv->shd);
- GF_ASSERT (priv->nfs);
- GF_ASSERT (priv->quotad);
-
- if (!strcmp ("glustershd", server))
- priv->shd->rpc = rpc;
- else if (!strcmp ("nfs", server))
- priv->nfs->rpc = rpc;
- else if (!strcmp ("quotad", server))
- priv->quotad->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;
- glusterd_conf_t *priv = THIS->private;
-
- rpc = glusterd_nodesvc_get_rpc (server);
-
- if (rpc == NULL) {
- /* Setting frame-timeout to 10mins (600seconds).
- * Unix domain sockets ensures that the connection is reliable.
- * The default timeout of 30mins used for unreliable network
- * connections is too long for unix domain socket connections.
- */
- ret = rpc_transport_unix_options_build (&options, socketpath,
- 600);
- if (ret)
- goto out;
-
- if (!strcmp(server, "glustershd") ||
- !strcmp(server, "nfs") ||
- !strcmp(server, "quotad")) {
- ret = dict_set_str(options, "transport.socket.ignore-enoent", "on");
- 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;
- glusterd_conf_t *priv = THIS->private;
-
- rpc = glusterd_nodesvc_get_rpc (server);
- (void)glusterd_nodesvc_set_rpc (server, NULL);
-
- if (rpc)
- glusterd_rpc_clnt_unref (priv, rpc);
-
- return 0;
-}
-
-int32_t
-glusterd_nodesvc_start (char *server, gf_boolean_t wait)
-{
- 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 *volfileserver = NULL;
- char volfileid[256] = {0};
- char glusterd_uuid_option[1024] = {0};
- char valgrind_logfile[PATH_MAX] = {0};
-
- this = THIS;
- GF_ASSERT(this);
-
- priv = this->private;
-
- glusterd_get_nodesvc_rundir (server, priv->workdir,
- rundir, sizeof (rundir));
- ret = mkdir (rundir, 0777);
-
- if ((ret == -1) && (EEXIST != errno)) {
- gf_log ("", GF_LOG_ERROR, "Unable to create rundir %s",
- rundir);
- goto out;
- }
-
- glusterd_get_nodesvc_pidfile (server, priv->workdir,
- pidfile, sizeof (pidfile));
- glusterd_get_nodesvc_volfile (server, priv->workdir,
- volfile, sizeof (volfile));
- ret = access (volfile, F_OK);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "%s Volfile %s is not present",
- server, volfile);
- goto out;
- }
-
- snprintf (logfile, PATH_MAX, "%s/%s.log", DEFAULT_LOG_FILE_DIRECTORY,
- server);
- snprintf (volfileid, sizeof (volfileid), "gluster/%s", server);
-
- if (dict_get_str (this->options, "transport.socket.bind-address",
- &volfileserver) != 0) {
- volfileserver = "localhost";
- }
-
- glusterd_nodesvc_set_socket_filepath (rundir, MY_UUID,
- sockfpath, sizeof (sockfpath));
-
- if (gf_is_service_running(pidfile, NULL))
- goto connect;
-
- runinit (&runner);
-
- 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", "--track-origins=yes",
- NULL);
- runner_argprintf (&runner, "--log-file=%s", valgrind_logfile);
- }
-
- runner_add_args (&runner, SBIN_DIR"/glusterfs",
- "-s", volfileserver,
- "--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);
- }
- if (!strcmp (server, "quotad")) {
- runner_add_args (&runner, "--xlator-option",
- "*replicate*.data-self-heal=off",
- "--xlator-option",
- "*replicate*.metadata-self-heal=off",
- "--xlator-option",
- "*replicate*.entry-self-heal=off", NULL);
- }
- runner_log (&runner, "", GF_LOG_DEBUG,
- "Starting the nfs/glustershd services");
-
- if (!wait) {
- ret = runner_run_nowait (&runner);
- } else {
- synclock_unlock (&priv->big_lock);
- {
- ret = runner_run (&runner);
- }
- synclock_lock (&priv->big_lock);
- }
-connect:
- if (ret == 0) {
- glusterd_nodesvc_connect (server, sockfpath);
- }
-out:
- return ret;
-}
-
-static gf_boolean_t
-glusterd_nfs_need_start ()
-{
- gf_boolean_t start = _gf_false;
- glusterd_conf_t *priv = NULL;
- glusterd_volinfo_t *volinfo = NULL;
-
- priv = THIS->private;
-
- list_for_each_entry (volinfo, &priv->volumes, vol_list) {
- if (!glusterd_is_volume_started (volinfo))
- continue;
-
- if (dict_get_str_boolean (volinfo->dict, "nfs.disable", 0))
- continue;
-
- start = _gf_true;
- break;
- }
-
- return start;
-}
-
-int
-glusterd_nfs_server_start ()
-{
- if (glusterd_nfs_need_start ())
- return glusterd_nodesvc_start ("nfs", _gf_false);
-
- return 0;
-}
-
-int
-glusterd_shd_start ()
-{
- return glusterd_nodesvc_start ("glustershd", _gf_false);
-}
-
-int
-glusterd_quotad_start ()
-{
- return glusterd_nodesvc_start ("quotad", _gf_false);
-}
-
-int
-glusterd_quotad_start_wait ()
-{
- return glusterd_nodesvc_start ("quotad", _gf_true);
-}
-
-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 gf_is_service_running (pidfile, NULL);
-}
-
-int32_t
-glusterd_unlink_file (char *sockfpath)
-{
- int ret = 0;
-
- ret = unlink (sockfpath);
- if (ret) {
- if (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_unlink_socket_file (char *server)
-{
- 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));
-
- return glusterd_unlink_file (sockfpath);
-}
-
-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);
-
- glusterd_get_nodesvc_pidfile (server, priv->workdir,
- pidfile, sizeof (pidfile));
- ret = glusterd_service_stop (server, pidfile, sig, _gf_true);
-
- if (ret == 0) {
- glusterd_nodesvc_set_online_status (server, _gf_false);
- (void)glusterd_nodesvc_unlink_socket_file (server);
- }
-out:
- return ret;
-}
-
-void
-glusterd_nfs_pmap_deregister ()
-{
- if (pmap_unset (MOUNT_PROGRAM, MOUNTV3_VERSION))
- gf_log ("", GF_LOG_INFO, "De-registered MOUNTV3 successfully");
- else
- gf_log ("", GF_LOG_ERROR, "De-register MOUNTV3 is unsuccessful");
-
- if (pmap_unset (MOUNT_PROGRAM, MOUNTV1_VERSION))
- gf_log ("", GF_LOG_INFO, "De-registered MOUNTV1 successfully");
- else
- gf_log ("", GF_LOG_ERROR, "De-register MOUNTV1 is unsuccessful");
-
- if (pmap_unset (NFS_PROGRAM, NFSV3_VERSION))
- gf_log ("", GF_LOG_INFO, "De-registered NFSV3 successfully");
- 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");
-
- if (pmap_unset (ACL_PROGRAM, ACLV3_VERSION))
- gf_log ("", GF_LOG_INFO, "De-registered ACL v3 successfully");
- else
- gf_log ("", GF_LOG_ERROR, "De-registration of ACL v3 failed");
-}
-
-int
-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_quotad_stop ()
-{
- return glusterd_nodesvc_stop ("quotad", 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;
- 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));
- //Consider service to be running only when glusterd sees it Online
- if (glusterd_is_nodesvc_online (server))
- running = gf_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");
- else if (!strcmp (server, "quotad"))
- ret = dict_set_str (dict, key, "Quota 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;
-
- 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;
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "brick%d.pid", count);
- ret = dict_set_int32 (dict, key, pid);
- if (ret)
- goto out;
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "brick%d.status", count);
- ret = dict_set_int32 (dict, key, running);
- if (ret)
- goto out;
-
-
-out:
- gf_log (THIS->name, GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-
-int
-glusterd_remote_hostname_get (rpcsvc_request_t *req, char *remote_host, int len)
-{
- GF_ASSERT (req);
- GF_ASSERT (remote_host);
- GF_ASSERT (req->trans);
-
- char *name = NULL;
- char *hostname = NULL;
- char *tmp_host = NULL;
- char *canon = NULL;
- int ret = 0;
-
- name = req->trans->peerinfo.identifier;
- tmp_host = gf_strdup (name);
- if (tmp_host)
- get_host_name (tmp_host, &hostname);
-
- GF_ASSERT (hostname);
- if (!hostname) {
- memset (remote_host, 0, len);
- ret = -1;
- goto out;
- }
-
- if ((gf_get_hostname_from_ip(hostname,&canon) == 0) && canon) {
- GF_FREE(tmp_host);
- tmp_host = hostname = canon;
- }
-
- 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;
-
- ret = start ();
-out:
- return ret;
-}
-
-int
-glusterd_reconfigure_nodesvc (int (*create_volfile) ())
-{
- 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_quotad ()
-{
- return glusterd_reconfigure_nodesvc (glusterd_create_quotad_volfile);
-}
-
-int
-glusterd_reconfigure_nfs ()
-{
- int ret = -1;
- gf_boolean_t identical = _gf_false;
-
- /*
- * Check both OLD and NEW volfiles, if they are SAME by size
- * and cksum i.e. "character-by-character". If YES, then
- * NOTHING has been changed, just return.
- */
- ret = glusterd_check_nfs_volfile_identical (&identical);
- if (ret)
- goto out;
-
- if (identical) {
- ret = 0;
- goto out;
- }
-
- /*
- * They are not identical. Find out if the topology is changed
- * OR just the volume options. If just the options which got
- * changed, then inform the xlator to reconfigure the options.
- */
- identical = _gf_false; /* RESET the FLAG */
- ret = glusterd_check_nfs_topology_identical (&identical);
- if (ret)
- goto out;
-
- /* Topology is not changed, but just the options. But write the
- * options to NFS volfile, so that NFS will be reconfigured.
- */
- if (identical) {
- ret = glusterd_create_nfs_volfile();
- if (ret == 0) {/* Only if above PASSES */
- ret = glusterd_fetchspec_notify (THIS);
- }
- goto out;
- }
-
- /*
- * NFS volfile's topology has been changed. NFS server needs
- * to be RESTARTED to ACT on the changed volfile.
- */
- 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_check_generate_start_quotad ()
-{
- int ret = 0;
-
- ret = glusterd_check_generate_start_service (glusterd_create_quotad_volfile,
- glusterd_quotad_stop,
- glusterd_quotad_start);
- if (ret == -EINVAL)
- ret = 0;
- return ret;
-}
-
-/* Blocking start variant of glusterd_check_generate_start_quotad */
-int
-glusterd_check_generate_start_quotad_wait ()
-{
- int ret = 0;
-
- ret = glusterd_check_generate_start_service
- (glusterd_create_quotad_volfile, glusterd_quotad_stop,
- glusterd_quotad_start_wait);
- if (ret == -EINVAL)
- ret = 0;
- return ret;
-}
-
-int
-glusterd_nodesvcs_batch_op (glusterd_volinfo_t *volinfo, int (*nfs_op) (),
- int (*shd_op) (), int (*qd_op) ())
- {
- int ret = 0;
- xlator_t *this = THIS;
- glusterd_conf_t *conf = NULL;
-
- GF_ASSERT (this);
- conf = this->private;
- GF_ASSERT (conf);
-
- ret = nfs_op ();
- if (ret)
- goto out;
-
- if (volinfo && !glusterd_is_volume_replicate (volinfo)) {
- ; //do nothing
- } else {
- ret = shd_op ();
- if (ret)
- goto out;
- }
-
- if (conf->op_version == GD_OP_VERSION_MIN)
- goto out;
-
- if (volinfo && !glusterd_is_volume_quota_enabled (volinfo))
- goto out;
-
- ret = qd_op ();
- if (ret)
- goto out;
-
-out:
- return ret;
-}
-
-int
-glusterd_nodesvcs_start (glusterd_volinfo_t *volinfo)
-{
- return glusterd_nodesvcs_batch_op (volinfo,
- glusterd_nfs_server_start,
- glusterd_shd_start,
- glusterd_quotad_start);
-}
-
-int
-glusterd_nodesvcs_stop (glusterd_volinfo_t *volinfo)
-{
- return glusterd_nodesvcs_batch_op (volinfo,
- glusterd_nfs_server_stop,
- glusterd_shd_stop,
- glusterd_quotad_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;
-}
-
-gf_boolean_t
-glusterd_all_volumes_with_quota_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_quota_enabled (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;
- int (*qd_op) () = NULL;
-
- if (volinfo && volinfo->is_snap_volume)
- return 0;
-
- shd_op = glusterd_check_generate_start_shd;
- nfs_op = glusterd_check_generate_start_nfs;
- qd_op = glusterd_check_generate_start_quotad;
- if (glusterd_are_all_volumes_stopped ()) {
- shd_op = glusterd_shd_stop;
- nfs_op = glusterd_nfs_server_stop;
- qd_op = glusterd_quotad_stop;
- } else {
- if (glusterd_all_replicate_volumes_stopped()) {
- shd_op = glusterd_shd_stop;
- }
- if (glusterd_all_volumes_with_quota_stopped ()) {
- qd_op = glusterd_quotad_stop;
- }
- }
-
- return glusterd_nodesvcs_batch_op (volinfo, nfs_op, shd_op, qd_op);
-}
-
-int
-glusterd_nodesvcs_handle_reconfigure (glusterd_volinfo_t *volinfo)
-{
- return glusterd_nodesvcs_batch_op (volinfo,
- glusterd_reconfigure_nfs,
- glusterd_reconfigure_shd,
- glusterd_reconfigure_quotad);
-}
-
-int
-glusterd_volume_count_get (void)
-{
- glusterd_volinfo_t *tmp_volinfo = NULL;
- int32_t ret = 0;
- xlator_t *this = NULL;
- glusterd_conf_t *priv = NULL;
-
- this = THIS;
- GF_ASSERT (this);
-
- priv = this->private;
-
- list_for_each_entry (tmp_volinfo, &priv->volumes, vol_list) {
- ret++;
- }
-
-
- gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-
-}
-
-int
-glusterd_brickinfo_get (uuid_t uuid, char *hostname, char *path,
- glusterd_brickinfo_t **brickinfo)
-{
- glusterd_volinfo_t *volinfo = NULL;
- glusterd_conf_t *priv = NULL;
- xlator_t *this = NULL;
- int ret = -1;
-
- GF_ASSERT (path);
-
- this = THIS;
- GF_ASSERT (this);
-
- priv = this->private;
-
- list_for_each_entry (volinfo, &priv->volumes, vol_list) {
-
- ret = glusterd_volume_brickinfo_get (uuid, hostname, path,
- volinfo, brickinfo);
- if (ret == 0)
- /*Found*/
- goto out;
- }
-out:
- return ret;
-}
-
-int
-glusterd_brick_start (glusterd_volinfo_t *volinfo,
- glusterd_brickinfo_t *brickinfo,
- gf_boolean_t wait)
-{
- int ret = -1;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
-
- if ((!brickinfo) || (!volinfo))
- goto out;
-
- if (uuid_is_null (brickinfo->uuid)) {
- ret = glusterd_resolve_brick (brickinfo);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, FMTSTR_RESOLVE_BRICK,
- brickinfo->hostname, brickinfo->path);
- goto out;
- }
- }
-
- if (uuid_compare (brickinfo->uuid, MY_UUID)) {
- ret = 0;
- goto out;
- }
- ret = glusterd_volume_start_glusterfs (volinfo, brickinfo, wait);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Unable to start brick %s:%s",
- brickinfo->hostname, brickinfo->path);
- goto out;
- }
-
-out:
- gf_log (this->name, GF_LOG_DEBUG, "returning %d ", ret);
- return ret;
-}
-
-int
-glusterd_restart_bricks (glusterd_conf_t *conf)
-{
- int ret = 0;
- glusterd_volinfo_t *volinfo = NULL;
- glusterd_brickinfo_t *brickinfo = NULL;
- glusterd_snap_t *snap = NULL;
- gf_boolean_t start_nodesvcs = _gf_false;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
-
- list_for_each_entry (volinfo, &conf->volumes, vol_list) {
- if (volinfo->status != GLUSTERD_STATUS_STARTED)
- continue;
- start_nodesvcs = _gf_true;
- gf_log (this->name, GF_LOG_DEBUG, "starting the volume %s",
- volinfo->volname);
- list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) {
- glusterd_brick_start (volinfo, brickinfo, _gf_false);
- }
- }
-
- list_for_each_entry (snap, &conf->snapshots, snap_list) {
- list_for_each_entry (volinfo, &snap->volumes, vol_list) {
- if (volinfo->status != GLUSTERD_STATUS_STARTED)
- continue;
- start_nodesvcs = _gf_true;
- gf_log (this->name, GF_LOG_DEBUG, "starting the snap "
- "volume %s", volinfo->volname);
- list_for_each_entry (brickinfo, &volinfo->bricks,
- brick_list) {
- glusterd_brick_start (volinfo, brickinfo,
- _gf_false);
- }
- }
- }
-
- if (start_nodesvcs)
- glusterd_nodesvcs_handle_graph_change (NULL);
-
- return ret;
-}
-
-int
-_local_gsyncd_start (dict_t *this, char *key, data_t *value, void *data)
-{
- char *path_list = NULL;
- char *slave = NULL;
- char *slave_url = NULL;
- char *slave_vol = NULL;
- char *slave_host = NULL;
- char *statefile = NULL;
- char buf[1024] = "faulty";
- int uuid_len = 0;
- int ret = 0;
- int op_ret = 0;
- int ret_status = 0;
- char uuid_str[64] = {0};
- glusterd_volinfo_t *volinfo = NULL;
- char confpath[PATH_MAX] = "";
- char *op_errstr = NULL;
- glusterd_conf_t *priv = NULL;
- gf_boolean_t is_template_in_use = _gf_false;
- gf_boolean_t is_paused = _gf_false;
- char *key1 = NULL;
- xlator_t *this1 = NULL;
-
- this1 = THIS;
- GF_ASSERT (this1);
- priv = this1->private;
- GF_ASSERT (priv);
- GF_ASSERT (data);
-
- volinfo = data;
- slave = strchr(value->data, ':');
- if (slave)
- slave ++;
- else
- return 0;
- uuid_len = (slave - value->data - 1);
-
- strncpy (uuid_str, (char*)value->data, uuid_len);
-
- /* Getting Local Brickpaths */
- ret = glusterd_get_local_brickpaths (volinfo, &path_list);
-
- /*Generating the conf file path needed by gsyncd */
- ret = glusterd_get_slave_info (slave, &slave_url, &slave_host,
- &slave_vol, &op_errstr);
- if (ret) {
- gf_log (this1->name, GF_LOG_ERROR,
- "Unable to fetch slave details.");
- ret = -1;
- goto out;
- }
-
- ret = snprintf (confpath, sizeof(confpath) - 1,
- "%s/"GEOREP"/%s_%s_%s/gsyncd.conf",
- priv->workdir, volinfo->volname,
- slave_host, slave_vol);
- confpath[ret] = '\0';
-
- /* Fetching the last status of the node */
- ret = glusterd_get_statefile_name (volinfo, slave,
- confpath, &statefile,
- &is_template_in_use);
- if (ret) {
- if (!strstr(slave, "::"))
- gf_log (this1->name, GF_LOG_INFO,
- "%s is not a valid slave url.", slave);
- else
- gf_log (this1->name, GF_LOG_INFO, "Unable to get"
- " statefile's name");
- goto out;
- }
-
- /* If state-file entry is missing from the config file,
- * do not start gsyncd on restart */
- if (is_template_in_use) {
- gf_log (this1->name, GF_LOG_INFO,
- "state-file entry is missing in config file."
- "Not Restarting");
- goto out;
- }
-
- is_template_in_use = _gf_false;
-
- ret = gsync_status (volinfo->volname, slave, confpath,
- &ret_status, &is_template_in_use);
- if (ret == -1) {
- gf_log (this1->name, GF_LOG_INFO,
- GEOREP" start option validation failed ");
- ret = 0;
- goto out;
- }
-
- if (is_template_in_use == _gf_true) {
- gf_log (this1->name, GF_LOG_INFO,
- "pid-file entry is missing in config file."
- "Not Restarting");
- ret = 0;
- goto out;
- }
-
- ret = glusterd_gsync_read_frm_status (statefile, buf, sizeof (buf));
- if (ret < 0) {
- gf_log (this1->name, GF_LOG_ERROR, "Unable to read the status");
- goto out;
- }
-
- /* Move the pointer two characters ahead to surpass '//' */
- if ((key1 = strchr (slave, '/')))
- key1 = key1 + 2;
-
- /* Looks for the last status, to find if the sessiom was running
- * when the node went down. If the session was not started or
- * not started, do not restart the geo-rep session */
- if ((!strcmp (buf, "Not Started")) ||
- (!strcmp (buf, "Stopped"))) {
- gf_log (this1->name, GF_LOG_INFO,
- "Geo-Rep Session was not started between "
- "%s and %s::%s. Not Restarting", volinfo->volname,
- slave_url, slave_vol);
- goto out;
- } else if (strstr(buf, "Paused")) {
- is_paused = _gf_true;
- } else if ((!strcmp (buf, "Config Corrupted"))) {
- gf_log (this1->name, GF_LOG_INFO,
- "Recovering from a corrupted config. "
- "Not Restarting. Use start (force) to "
- "start the session between %s and %s::%s.",
- volinfo->volname,
- slave_url, slave_vol);
- goto out;
- }
-
- if (is_paused) {
- glusterd_start_gsync (volinfo, slave, path_list, confpath,
- uuid_str, NULL, _gf_true);
- }
- else {
- /* Add slave to the dict indicating geo-rep session is running*/
- ret = dict_set_dynstr_with_alloc (volinfo->gsync_active_slaves,
- key1, "running");
- if (ret) {
- gf_log (this1->name, GF_LOG_ERROR, "Unable to set key:%s"
- " value:running in the dict", key1);
- goto out;
- }
- ret = glusterd_start_gsync (volinfo, slave, path_list, confpath,
- uuid_str, NULL, _gf_false);
- if (ret)
- dict_del (volinfo->gsync_active_slaves, key1);
- }
-
-out:
- if (statefile)
- GF_FREE (statefile);
-
- if (is_template_in_use) {
- op_ret = glusterd_create_status_file (volinfo->volname, slave,
- slave_host, slave_vol,
- "Config Corrupted");
- if (op_ret) {
- gf_log (this1->name, GF_LOG_ERROR,
- "Unable to create status file"
- ". Error : %s", strerror (errno));
- ret = op_ret;
- }
- }
-
- GF_FREE (path_list);
- GF_FREE (op_errstr);
-
- return ret;
-}
-
-int
-glusterd_volume_restart_gsyncds (glusterd_volinfo_t *volinfo)
-{
- GF_ASSERT (volinfo);
-
- dict_foreach (volinfo->gsync_slaves, _local_gsyncd_start, volinfo);
- return 0;
-}
-
-int
-glusterd_restart_gsyncds (glusterd_conf_t *conf)
-{
- glusterd_volinfo_t *volinfo = NULL;
- int ret = 0;
-
- list_for_each_entry (volinfo, &conf->volumes, vol_list) {
- glusterd_volume_restart_gsyncds (volinfo);
- }
- return ret;
-}
-
-inline int
-glusterd_get_dist_leaf_count (glusterd_volinfo_t *volinfo)
-{
- int rcount = volinfo->replica_count;
- int scount = volinfo->stripe_count;
-
- if (volinfo->type == GF_CLUSTER_TYPE_DISPERSE)
- return volinfo->disperse_count;
-
- return (rcount ? rcount : 1) * (scount ? scount : 1);
-}
-
-int
-glusterd_get_brickinfo (xlator_t *this, const char *brickname, int port,
- gf_boolean_t localhost, glusterd_brickinfo_t **brickinfo)
-{
- glusterd_conf_t *priv = NULL;
- glusterd_volinfo_t *volinfo = NULL;
- glusterd_brickinfo_t *tmpbrkinfo = NULL;
- int ret = -1;
-
- GF_ASSERT (brickname);
- GF_ASSERT (this);
-
- priv = this->private;
- list_for_each_entry (volinfo, &priv->volumes, vol_list) {
- list_for_each_entry (tmpbrkinfo, &volinfo->bricks,
- brick_list) {
- if (localhost && !gf_is_local_addr (tmpbrkinfo->hostname))
- continue;
- if (!strcmp(tmpbrkinfo->path, brickname) &&
- (tmpbrkinfo->port == port)) {
- *brickinfo = tmpbrkinfo;
- return 0;
- }
- }
- }
- 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_ASSERT (brickinfo);
- brickinfo->status = status;
- if (GF_BRICK_STARTED == status) {
- gf_log ("glusterd", GF_LOG_DEBUG, "Setting brick %s:%s status "
- "to started", brickinfo->hostname, brickinfo->path);
- } else {
- gf_log ("glusterd", GF_LOG_DEBUG, "Setting brick %s:%s status "
- "to stopped", brickinfo->hostname, brickinfo->path);
- }
-}
-
-gf_boolean_t
-glusterd_is_brick_started (glusterd_brickinfo_t *brickinfo)
-{
- GF_ASSERT (brickinfo);
- return (brickinfo->status == GF_BRICK_STARTED);
-}
-
-int
-glusterd_friend_brick_belongs (glusterd_volinfo_t *volinfo,
- glusterd_brickinfo_t *brickinfo, void* uuid)
-{
- int ret = -1;
-
- GF_ASSERT (volinfo);
- GF_ASSERT (brickinfo);
- GF_ASSERT (uuid);
-
- if (uuid_is_null (brickinfo->uuid)) {
- ret = glusterd_resolve_brick (brickinfo);
- if (ret) {
- GF_ASSERT (0);
- goto out;
- }
- }
- if (!uuid_compare (brickinfo->uuid, *((uuid_t *)uuid)))
- return 0;
-out:
- return -1;
-}
-
-int
-glusterd_get_brick_root (char *path, char **mount_point)
-{
- char *ptr = NULL;
- char *mnt_pt = NULL;
- struct stat brickstat = {0};
- struct stat buf = {0};
-
- if (!path)
- goto err;
- mnt_pt = gf_strdup (path);
- if (!mnt_pt)
- goto err;
- if (stat (mnt_pt, &brickstat))
- goto err;
-
- while ((ptr = strrchr (mnt_pt, '/')) &&
- ptr != mnt_pt) {
-
- *ptr = '\0';
- if (stat (mnt_pt, &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 == mnt_pt) {
- 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 (mnt_pt, "/");
- }
-
- *mount_point = mnt_pt;
- return 0;
-
- err:
- GF_FREE (mnt_pt);
- 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 struct fs_info {
- char *fs_type_name;
- char *fs_tool_name;
- char *fs_tool_arg;
- char *fs_tool_pattern;
- char *fs_tool_pkg;
-} glusterd_fs[] = {
- /* some linux have these in /usr/sbin/and others in /sbin/? */
- { "xfs", "xfs_info", NULL, "isize=", "xfsprogs" },
- { "ext3", "tune2fs", "-l", "Inode size:", "e2fsprogs" },
- { "ext4", "tune2fs", "-l", "Inode size:", "e2fsprogs" },
- { "btrfs", NULL, NULL, NULL, NULL },
- { NULL, NULL, NULL, NULL, NULL}
-};
-
-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 *trail = NULL;
- runner_t runner = {0, };
- struct fs_info *fs = NULL;
- char fs_tool_name[256] = {0, };
- static dict_t *cached_fs = NULL;
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "brick%d.device", count);
- ret = dict_get_str (dict, key, &device);
- if (ret)
- goto out;
-
- if (cached_fs) {
- if (dict_get_str (cached_fs, device, &cur_word) == 0) {
- goto cached;
- }
- } else {
- cached_fs = dict_new ();
- }
-
- 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);
-
- for (fs = glusterd_fs ; fs->fs_type_name; fs++) {
- if (strcmp (fs_name, fs->fs_type_name) == 0) {
- snprintf (fs_tool_name, sizeof (fs_tool_name),
- "/usr/sbin/%s", fs->fs_tool_name);
- if (access (fs_tool_name, R_OK|X_OK) == 0)
- runner_add_arg (&runner, fs_tool_name);
- else {
- snprintf (fs_tool_name, sizeof (fs_tool_name),
- "/sbin/%s", fs->fs_tool_name);
- if (access (fs_tool_name, R_OK|X_OK) == 0)
- runner_add_arg (&runner, fs_tool_name);
- }
- break;
- }
- }
-
- if (runner.argv[0]) {
- if (fs->fs_tool_arg)
- runner_add_arg (&runner, fs->fs_tool_arg);
- runner_add_arg (&runner, device);
- } else {
- gf_log (THIS->name, GF_LOG_ERROR, "could not find %s to get"
- "inode size for %s (%s): %s package missing?",
- fs->fs_tool_name, device, fs_name, fs->fs_tool_pkg);
- goto out;
- }
-
- ret = runner_start (&runner);
- if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR, "failed to execute "
- "\"%s\": %s", fs->fs_tool_name, strerror (errno));
- /*
- * Runner_start might return an error after the child has
- * been forked, e.g. if the program isn't there. In that
- * case, we still need to call runner_end to reap the
- * child and free resources. Fortunately, that seems to
- * be harmless for other kinds of failures.
- */
- (void) runner_end (&runner);
- 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, fs->fs_tool_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",
- fs->fs_tool_name);
-
- goto out;
- }
- if (!cur_word) {
- ret = -1;
- gf_log (THIS->name, GF_LOG_ERROR,
- "Unable to retrieve inode size using %s",
- fs->fs_tool_name);
- goto out;
- }
-
- if (dict_set_dynstr_with_alloc (cached_fs, device, cur_word)) {
- /* not fatal if not entered into the cache */
- gf_log (THIS->name, GF_LOG_DEBUG,
- "failed to cache fs inode size for %s", device);
- }
-
-cached:
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "brick%d.inode_size", count);
-
- ret = dict_set_dynstr_with_alloc (dict, key, cur_word);
-
-out:
- if (ret)
- gf_log (THIS->name, GF_LOG_ERROR, "failed to get inode size");
- return ret;
-}
-
-struct mntent *
-glusterd_get_mnt_entry_info (char *mnt_pt, char *buff, int buflen,
- struct mntent *entry_ptr)
-{
- struct mntent *entry = NULL;
- FILE *mtab = NULL;
-
- GF_ASSERT (mnt_pt);
- GF_ASSERT (buff);
- GF_ASSERT (entry_ptr);
-
- mtab = setmntent (_PATH_MOUNTED, "r");
- if (!mtab)
- goto out;
-
- entry = getmntent_r (mtab, entry_ptr, buff, buflen);
-
- while (1) {
- if (!entry)
- goto out;
-
- if (!strcmp (entry->mnt_dir, mnt_pt) &&
- strcmp (entry->mnt_type, "rootfs"))
- break;
- entry = getmntent_r (mtab, entry_ptr, buff, buflen);
- }
-
-out:
- if (NULL != mtab) {
- endmntent (mtab);
- }
- return entry;
-}
-
-static int
-glusterd_add_brick_mount_details (glusterd_brickinfo_t *brickinfo,
- dict_t *dict, int count)
-{
- int ret = -1;
- char key[1024] = {0};
- char buff [PATH_MAX] = {0};
- char base_key[1024] = {0};
- struct mntent save_entry = {0};
- char *mnt_pt = 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;
-
- entry = glusterd_get_mnt_entry_info (mnt_pt, buff, sizeof (buff),
- &save_entry);
- if (!entry) {
- ret = -1;
- goto out;
- }
-
- /* get device file */
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%s.device", base_key);
-
- ret = dict_set_dynstr_with_alloc (dict, key, entry->mnt_fsname);
- if (ret)
- goto out;
-
- /* fs type */
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%s.fs_name", base_key);
-
- ret = dict_set_dynstr_with_alloc (dict, key, entry->mnt_type);
- if (ret)
- goto out;
-
- /* mount options */
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%s.mnt_options", base_key);
-
- ret = dict_set_dynstr_with_alloc (dict, key, entry->mnt_opts);
-
- out:
- GF_FREE (mnt_pt);
-
- return ret;
-}
-
-char*
-glusterd_get_brick_mount_device (char *brick_path)
-{
- int ret = -1;
- char *mnt_pt = NULL;
- char *device = NULL;
- char buff [PATH_MAX] = "";
- struct mntent *entry = NULL;
- struct mntent save_entry = {0,};
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (brick_path);
-
- ret = glusterd_get_brick_root (brick_path, &mnt_pt);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to get mount point "
- "for %s brick", brick_path);
- goto out;
- }
-
- entry = glusterd_get_mnt_entry_info (mnt_pt, buff, sizeof (buff),
- &save_entry);
- if (NULL == entry) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to get mnt entry "
- "for %s mount path", mnt_pt);
- goto out;
- }
-
- /* get the fs_name/device */
- device = gf_strdup (entry->mnt_fsname);
-
-out:
- return device;
-}
-
-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;
- }
-
- ret = glusterd_add_brick_mount_details (brickinfo, dict, count);
- if (ret)
- goto out;
-
- ret = glusterd_add_inode_size_to_dict (dict, count);
- 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};
- 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;
-
- /* add peer uuid */
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%s.peerid", base_key);
- ret = dict_set_dynstr_with_alloc (dict, key,
- uuid_utoa (brickinfo->uuid));
- 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_BRICK_PIDFILE (pidfile, volinfo, brickinfo, priv);
-
- brick_online = gf_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_add_snapd_to_dict (glusterd_volinfo_t *volinfo,
- 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};
- xlator_t *this = NULL;
- glusterd_conf_t *priv = NULL;
-
-
- GF_ASSERT (volinfo);
- 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, "Snapshot Daemon");
- if (ret)
- goto out;
-
- snprintf (key, sizeof (key), "%s.path", base_key);
- ret = dict_set_dynstr (dict, key, gf_strdup (uuid_utoa (MY_UUID)));
- if (ret)
- goto out;
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%s.port", base_key);
- ret = dict_set_int32 (dict, key, volinfo->snapd.port);
- if (ret)
- goto out;
-
- glusterd_get_snapd_pidfile (volinfo, pidfile, sizeof (pidfile));
-
- brick_online = gf_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)
-{
- glusterd_conf_t *priv = NULL;
- glusterd_volinfo_t *volinfo = NULL;
- glusterd_brickinfo_t *brickinfo = NULL;
- int ret = -1;
- xlator_t *this = NULL;
-
- this = THIS;
- priv = this->private;
-
- list_for_each_entry (volinfo, &priv->volumes, vol_list) {
- list_for_each_entry (brickinfo, &volinfo->bricks,
- brick_list) {
- ret = func (volinfo, brickinfo, ctx);
- if (ret != status) {
- ret = -1;
- goto out;
- }
- }
- }
- ret = 0;
-out:
- gf_log ("", GF_LOG_DEBUG, "returning %d", ret);
- return ret;
-}
-
-
-int
-glusterd_brick_stop (glusterd_volinfo_t *volinfo,
- glusterd_brickinfo_t *brickinfo,
- gf_boolean_t del_brick)
-{
- int ret = -1;
- xlator_t *this = NULL;
- glusterd_conf_t *conf = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- conf = this->private;
- GF_ASSERT (conf);
-
- if ((!brickinfo) || (!volinfo))
- goto out;
-
- if (uuid_is_null (brickinfo->uuid)) {
- ret = glusterd_resolve_brick (brickinfo);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, FMTSTR_RESOLVE_BRICK,
- brickinfo->hostname, brickinfo->path);
- goto out;
- }
- }
-
- if (uuid_compare (brickinfo->uuid, MY_UUID)) {
- ret = 0;
- if (del_brick)
- glusterd_delete_brick (volinfo, brickinfo);
- goto out;
- }
-
- gf_log (this->name, GF_LOG_DEBUG, "About to stop glusterfs"
- " for brick %s:%s", brickinfo->hostname,
- brickinfo->path);
- ret = glusterd_volume_stop_glusterfs (volinfo, brickinfo, del_brick);
- if (ret) {
- gf_log (this->name, GF_LOG_CRITICAL, "Unable to stop"
- " brick: %s:%s", brickinfo->hostname,
- brickinfo->path);
- goto out;
- }
-
-out:
- gf_log (this->name, GF_LOG_DEBUG, "returning %d ", ret);
- return ret;
-}
-
-int
-glusterd_is_defrag_on (glusterd_volinfo_t *volinfo)
-{
- return (volinfo->rebal.defrag != NULL);
-}
-
-gf_boolean_t
-glusterd_is_rb_ongoing (glusterd_volinfo_t *volinfo)
-{
- gf_boolean_t ret = _gf_false;
-
- GF_ASSERT (volinfo);
-
- if (glusterd_is_rb_started (volinfo) ||
- glusterd_is_rb_paused (volinfo))
- ret = _gf_true;
-
- return ret;
-}
-
-int
-glusterd_new_brick_validate (char *brick, glusterd_brickinfo_t *brickinfo,
- char *op_errstr, size_t len)
-{
- glusterd_brickinfo_t *newbrickinfo = NULL;
- int ret = -1;
- gf_boolean_t is_allocated = _gf_false;
- glusterd_peerinfo_t *peerinfo = NULL;
- glusterd_conf_t *priv = NULL;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- priv = this->private;
- GF_ASSERT (priv);
-
-
- GF_ASSERT (brick);
- GF_ASSERT (op_errstr);
-
- if (!brickinfo) {
- ret = glusterd_brickinfo_new_from_brick (brick, &newbrickinfo);
- if (ret)
- goto out;
- is_allocated = _gf_true;
- } else {
- newbrickinfo = brickinfo;
- }
-
- ret = glusterd_resolve_brick (newbrickinfo);
- if (ret) {
- snprintf(op_errstr, len, "Host %s is not in \'Peer "
- "in Cluster\' state", newbrickinfo->hostname);
- goto out;
- }
-
- if (!uuid_compare (MY_UUID, newbrickinfo->uuid)) {
- /* brick is local */
- 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", brick);
- ret = -1;
- goto out;
- }
-
- } else {
- peerinfo = glusterd_peerinfo_find_by_uuid (newbrickinfo->uuid);
- if (peerinfo == NULL) {
- ret = -1;
- snprintf (op_errstr, len, "Failed to find host %s",
- newbrickinfo->hostname);
- goto out;
- }
-
- if ((!peerinfo->connected)) {
- snprintf(op_errstr, len, "Host %s not connected",
- newbrickinfo->hostname);
- ret = -1;
- goto out;
- }
-
- if (peerinfo->state.state != GD_FRIEND_STATE_BEFRIENDED) {
- snprintf(op_errstr, len, "Host %s is not in \'Peer "
- "in Cluster\' state",
- newbrickinfo->hostname);
- ret = -1;
- goto out;
- }
- }
-
- ret = 0;
-out:
- if (is_allocated)
- glusterd_brickinfo_delete (newbrickinfo);
- if (op_errstr[0] != '\0')
- gf_log (this->name, GF_LOG_ERROR, "%s", op_errstr);
- gf_log (this->name, GF_LOG_DEBUG, "returning %d ", ret);
- return ret;
-}
-
-int
-glusterd_is_rb_started(glusterd_volinfo_t *volinfo)
-{
- gf_log ("", GF_LOG_DEBUG,
- "is_rb_started:status=%d", volinfo->rep_brick.rb_status);
- return (volinfo->rep_brick.rb_status == GF_RB_STATUS_STARTED);
-
-}
-
-int
-glusterd_is_rb_paused ( glusterd_volinfo_t *volinfo)
-{
- gf_log ("", GF_LOG_DEBUG,
- "is_rb_paused:status=%d", volinfo->rep_brick.rb_status);
-
- return (volinfo->rep_brick.rb_status == GF_RB_STATUS_PAUSED);
-}
-
-inline int
-glusterd_set_rb_status (glusterd_volinfo_t *volinfo, gf_rb_status_t status)
-{
- gf_log ("", GF_LOG_DEBUG,
- "setting status from %d to %d",
- volinfo->rep_brick.rb_status,
- status);
-
- volinfo->rep_brick.rb_status = status;
- return 0;
-}
-
-inline int
-glusterd_rb_check_bricks (glusterd_volinfo_t *volinfo,
- glusterd_brickinfo_t *src, glusterd_brickinfo_t *dst)
-{
- glusterd_replace_brick_t *rb = NULL;
-
- GF_ASSERT (volinfo);
-
- rb = &volinfo->rep_brick;
-
- if (!rb->src_brick || !rb->dst_brick)
- return -1;
-
- if (strcmp (rb->src_brick->hostname, src->hostname) ||
- strcmp (rb->src_brick->path, src->path)) {
- gf_log("", GF_LOG_ERROR, "Replace brick src bricks differ");
- return -1;
- }
-
- if (strcmp (rb->dst_brick->hostname, dst->hostname) ||
- strcmp (rb->dst_brick->path, dst->path)) {
- gf_log ("", GF_LOG_ERROR, "Replace brick dst bricks differ");
- return -1;
- }
-
- 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) {
- if (!strcmp (path, curdir)) {
- snprintf (msg, sizeof (msg), "%s is already part of a "
- "volume", path);
- } else {
- snprintf (msg, sizeof (msg), "parent directory %s is "
- "already part of a volume", curdir);
- }
- }
-
- if (strlen (msg)) {
- gf_log (THIS->name, GF_LOG_ERROR, "%s", msg);
- *op_errstr = gf_strdup (msg);
- }
-
- return ret;
-}
-
-int
-glusterd_check_and_set_brick_xattr (char *host, char *path, uuid_t uuid,
- char **op_errstr, gf_boolean_t is_force)
-{
- int ret = -1;
- char msg[2048] = {0,};
- gf_boolean_t in_use = _gf_false;
- int flags = 0;
-
- /* Check for xattr support in backend fs */
- ret = sys_lsetxattr (path, "trusted.glusterfs.test",
- "working", 8, 0);
- if (ret == -1) {
- 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 && !is_force) {
- ret = -1;
- goto out;
- }
-
-
- if (!is_force)
- flags = XATTR_CREATE;
-
- ret = sys_lsetxattr (path, GF_XATTR_VOL_ID_KEY, uuid, 16,
- flags);
- if (ret == -1) {
- snprintf (msg, sizeof (msg), "Failed to set extended "
- "attributes %s, reason: %s",
- GF_XATTR_VOL_ID_KEY, strerror (errno));
- goto out;
- }
-
- ret = 0;
-out:
- if (strlen (msg))
- *op_errstr = gf_strdup (msg);
-
- return ret;
-}
-
-int
-glusterd_sm_tr_log_transition_add_to_dict (dict_t *dict,
- glusterd_sm_tr_log_t *log, int i,
- int count)
-{
- int ret = -1;
- char key[512] = {0};
- char timestr[64] = {0,};
- char *str = NULL;
-
- GF_ASSERT (dict);
- GF_ASSERT (log);
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "log%d-old-state", count);
- str = log->state_name_get (log->transitions[i].old_state);
- ret = dict_set_str (dict, key, str);
- if (ret)
- goto out;
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "log%d-event", count);
- str = log->event_name_get (log->transitions[i].event);
- ret = dict_set_str (dict, key, str);
- if (ret)
- goto out;
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "log%d-new-state", count);
- str = log->state_name_get (log->transitions[i].new_state);
- ret = dict_set_str (dict, key, str);
- if (ret)
- goto out;
-
-
- 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);
- ret = dict_set_dynstr_with_alloc (dict, key, timestr);
- if (ret)
- goto out;
-
-out:
- gf_log ("", GF_LOG_DEBUG, "returning %d", ret);
- return ret;
-}
-
-int
-glusterd_sm_tr_log_add_to_dict (dict_t *dict,
- glusterd_sm_tr_log_t *circular_log)
-{
- int ret = -1;
- int i = 0;
- int start = 0;
- int end = 0;
- int index = 0;
- char key[256] = {0};
- glusterd_sm_tr_log_t *log = NULL;
- int count = 0;
-
- GF_ASSERT (dict);
- GF_ASSERT (circular_log);
-
- log = circular_log;
- if (!log->count)
- return 0;
-
- if (log->count == log->size)
- start = log->current + 1;
-
- end = start + log->count;
- for (i = start; i < end; i++, count++) {
- index = i % log->count;
- ret = glusterd_sm_tr_log_transition_add_to_dict (dict, log, index,
- count);
- if (ret)
- goto out;
- }
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "count");
- ret = dict_set_int32 (dict, key, log->count);
-
-out:
- gf_log ("", GF_LOG_DEBUG, "returning %d", ret);
- return ret;
-}
-
-int
-glusterd_sm_tr_log_init (glusterd_sm_tr_log_t *log,
- char * (*state_name_get) (int),
- char * (*event_name_get) (int),
- size_t size)
-{
- glusterd_sm_transition_t *transitions = NULL;
- int ret = -1;
-
- GF_ASSERT (size > 0);
- GF_ASSERT (log && state_name_get && event_name_get);
-
- if (!log || !state_name_get || !event_name_get || (size <= 0))
- goto out;
-
- transitions = GF_CALLOC (size, sizeof (*transitions),
- gf_gld_mt_sm_tr_log_t);
- if (!transitions)
- goto out;
-
- log->transitions = transitions;
- log->size = size;
- log->state_name_get = state_name_get;
- log->event_name_get = event_name_get;
- ret = 0;
-
-out:
- gf_log ("", GF_LOG_DEBUG, "returning %d", ret);
- return ret;
-}
-
-void
-glusterd_sm_tr_log_delete (glusterd_sm_tr_log_t *log)
-{
- if (!log)
- return;
- GF_FREE (log->transitions);
- return;
-}
-
-int
-glusterd_sm_tr_log_transition_add (glusterd_sm_tr_log_t *log,
- int old_state, int new_state,
- int event)
-{
- glusterd_sm_transition_t *transitions = NULL;
- int ret = -1;
- int next = 0;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
-
- GF_ASSERT (log);
- if (!log)
- goto out;
-
- transitions = log->transitions;
- if (!transitions)
- goto out;
-
- if (log->count)
- next = (log->current + 1) % log->size;
- else
- next = 0;
-
- transitions[next].old_state = old_state;
- transitions[next].new_state = new_state;
- transitions[next].event = event;
- time (&transitions[next].time);
- log->current = next;
- if (log->count < log->size)
- log->count++;
- ret = 0;
- gf_log (this->name, GF_LOG_DEBUG, "Transitioning from '%s' to '%s' "
- "due to event '%s'", log->state_name_get (old_state),
- log->state_name_get (new_state), log->event_name_get (event));
-out:
- gf_log (this->name, GF_LOG_DEBUG, "returning %d", ret);
- return ret;
-}
-
-int
-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;
-
- list_for_each_entry_safe (pending_node, tmp, list, list) {
- if (elem == pending_node->node) {
- list_del_init (&pending_node->list);
- GF_FREE (pending_node);
- ret = 0;
- goto out;
- }
- }
-out:
- gf_log (THIS->name, GF_LOG_DEBUG, "returning %d", ret);
- return ret;
-
-}
-
-int
-glusterd_clear_pending_nodes (struct list_head *list)
-{
- glusterd_pending_node_t *pending_node = NULL;
- glusterd_pending_node_t *tmp = NULL;
-
- list_for_each_entry_safe (pending_node, tmp, list, list) {
- list_del_init (&pending_node->list);
- GF_FREE (pending_node);
- }
-
- return 0;
-}
-
-int32_t
-glusterd_delete_volume (glusterd_volinfo_t *volinfo)
-{
- int ret = -1;
- GF_ASSERT (volinfo);
-
- ret = glusterd_store_delete_volume (volinfo);
-
- if (ret)
- goto out;
-
- glusterd_volinfo_remove (volinfo);
-out:
- gf_log (THIS->name, GF_LOG_DEBUG, "returning %d", ret);
- return ret;
-}
-
-int32_t
-glusterd_delete_brick (glusterd_volinfo_t* volinfo,
- glusterd_brickinfo_t *brickinfo)
-{
- int ret = 0;
- char voldir[PATH_MAX] = {0,};
- glusterd_conf_t *priv = THIS->private;
- GF_ASSERT (volinfo);
- GF_ASSERT (brickinfo);
-
- GLUSTERD_GET_VOLUME_DIR(voldir, volinfo, priv);
-
- glusterd_delete_volfile (volinfo, brickinfo);
- glusterd_store_delete_brick (brickinfo, voldir);
- glusterd_brickinfo_delete (brickinfo);
- volinfo->brick_count--;
- return ret;
-}
-
-int32_t
-glusterd_delete_all_bricks (glusterd_volinfo_t* volinfo)
-{
- int ret = 0;
- glusterd_brickinfo_t *brickinfo = NULL;
- glusterd_brickinfo_t *tmp = NULL;
-
- GF_ASSERT (volinfo);
-
- list_for_each_entry_safe (brickinfo, tmp, &volinfo->bricks, brick_list) {
- ret = glusterd_delete_brick (volinfo, brickinfo);
- }
- return ret;
-}
-
-int
-glusterd_get_local_brickpaths (glusterd_volinfo_t *volinfo, char **pathlist)
-{
- char **path_tokens = NULL;
- char *tmp_path_list = NULL;
- char path[PATH_MAX] = "";
- int32_t count = 0;
- int32_t pathlen = 0;
- int32_t total_len = 0;
- int32_t ret = 0;
- int i = 0;
- glusterd_brickinfo_t *brickinfo = NULL;
-
- if ((!volinfo) || (!pathlist))
- goto out;
-
- path_tokens = GF_CALLOC (sizeof(char*), volinfo->brick_count,
- gf_gld_mt_charptr);
- if (!path_tokens) {
- gf_log ("", GF_LOG_DEBUG, "Could not allocate memory.");
- ret = -1;
- goto out;
- }
-
- list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) {
- if (uuid_compare (brickinfo->uuid, MY_UUID))
- continue;
-
- pathlen = snprintf (path, sizeof(path),
- "--path=%s ", brickinfo->path);
- if (pathlen < sizeof(path))
- path[pathlen] = '\0';
- else
- path[sizeof(path)-1] = '\0';
- path_tokens[count] = gf_strdup (path);
- if (!path_tokens[count]) {
- gf_log ("", GF_LOG_DEBUG,
- "Could not allocate memory.");
- ret = -1;
- goto out;
- }
- count++;
- total_len += pathlen;
- }
-
- tmp_path_list = GF_CALLOC (sizeof(char), total_len + 1,
- gf_gld_mt_char);
- if (!tmp_path_list) {
- gf_log ("", GF_LOG_DEBUG, "Could not allocate memory.");
- ret = -1;
- goto out;
- }
-
- for (i = 0; i < count; i++)
- strcat (tmp_path_list, path_tokens[i]);
-
- if (count)
- *pathlist = tmp_path_list;
-
- ret = count;
-out:
- if (path_tokens) {
- for (i = 0; i < count; i++) {
- GF_FREE (path_tokens[i]);
- }
- }
-
- GF_FREE (path_tokens);
- path_tokens = NULL;
-
- if (ret == 0) {
- gf_log ("", GF_LOG_DEBUG, "No Local Bricks Present.");
- GF_FREE (tmp_path_list);
- tmp_path_list = NULL;
- }
-
- gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-
-int
-glusterd_start_gsync (glusterd_volinfo_t *master_vol, char *slave,
- char *path_list, char *conf_path,
- char *glusterd_uuid_str,
- char **op_errstr, gf_boolean_t is_pause)
-{
- int32_t ret = 0;
- int32_t status = 0;
- char uuid_str [64] = {0};
- runner_t runner = {0,};
- xlator_t *this = NULL;
- glusterd_conf_t *priv = NULL;
- int errcode = 0;
- gf_boolean_t is_template_in_use = _gf_false;
-
- this = THIS;
- GF_ASSERT (this);
- priv = this->private;
- GF_ASSERT (priv);
-
- uuid_utoa_r (MY_UUID, uuid_str);
-
- if (!path_list) {
- ret = 0;
- gf_log ("", GF_LOG_DEBUG, "No Bricks in this node."
- " Not starting gsyncd.");
- goto out;
- }
-
- ret = gsync_status (master_vol->volname, slave, conf_path,
- &status, &is_template_in_use);
- if (status == 0)
- goto out;
-
- if (is_template_in_use == _gf_true) {
- gf_asprintf (op_errstr, GEOREP" start failed for %s %s : "
- "pid-file entry missing in config file",
- master_vol->volname, slave);
- ret = -1;
- goto out;
- }
-
- uuid_utoa_r (master_vol->volume_id, uuid_str);
- runinit (&runner);
- runner_add_args (&runner, GSYNCD_PREFIX"/gsyncd",
- path_list, "-c", NULL);
- runner_argprintf (&runner, "%s", conf_path);
- runner_argprintf (&runner, ":%s", master_vol->volname);
- runner_add_args (&runner, slave, "--config-set", "session-owner",
- uuid_str, NULL);
- synclock_unlock (&priv->big_lock);
- ret = runner_run (&runner);
- synclock_lock (&priv->big_lock);
- if (ret == -1) {
- errcode = -1;
- goto out;
- }
-
- runinit (&runner);
- runner_add_args (&runner, GSYNCD_PREFIX"/gsyncd",
- path_list, "--monitor", "-c", NULL);
- runner_argprintf (&runner, "%s", conf_path);
- runner_argprintf (&runner, "--iprefix=%s", DATADIR);
- runner_argprintf (&runner, ":%s", master_vol->volname);
- runner_argprintf (&runner, "--glusterd-uuid=%s",
- uuid_utoa (priv->uuid));
- runner_add_arg (&runner, slave);
- if (is_pause)
- runner_add_arg (&runner, "--pause-on-start");
- synclock_unlock (&priv->big_lock);
- ret = runner_run (&runner);
- synclock_lock (&priv->big_lock);
- if (ret == -1) {
- gf_asprintf (op_errstr, GEOREP" start failed for %s %s",
- master_vol->volname, slave);
- goto out;
- }
-
- ret = 0;
-
-out:
- if ((ret != 0) && errcode == -1) {
- if (op_errstr)
- *op_errstr = gf_strdup ("internal error, cannot start "
- "the " GEOREP " session");
- }
-
- gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-
-int32_t
-glusterd_recreate_volfiles (glusterd_conf_t *conf)
-{
-
- glusterd_volinfo_t *volinfo = NULL;
- int ret = 0;
- int op_ret = 0;
-
- GF_ASSERT (conf);
- list_for_each_entry (volinfo, &conf->volumes, vol_list) {
- ret = generate_brick_volfiles (volinfo);
- if (ret) {
- gf_log ("glusterd", GF_LOG_ERROR, "Failed to "
- "regenerate brick volfiles for %s",
- volinfo->volname);
- op_ret = ret;
- }
- ret = generate_client_volfiles (volinfo, GF_CLIENT_TRUSTED);
- if (ret) {
- gf_log ("glusterd", GF_LOG_ERROR, "Failed to "
- "regenerate trusted client volfiles for %s",
- volinfo->volname);
- op_ret = ret;
- }
- ret = generate_client_volfiles (volinfo, GF_CLIENT_OTHER);
- if (ret) {
- gf_log ("glusterd", GF_LOG_ERROR, "Failed to "
- "regenerate client volfiles for %s",
- volinfo->volname);
- op_ret = ret;
- }
- }
- return op_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_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_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_volfiles) {
- ret = glusterd_recreate_volfiles (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 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, MY_UUID)) {
- ret = 0;
- goto out;
- }
-
- GLUSTERD_GET_BRICK_PIDFILE (pidfile_path, volinfo, brickinfo, conf);
-
- 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),
- DEFAULT_VAR_RUN_DIRECTORY"/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),
- DEFAULT_VAR_RUN_DIRECTORY"/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;
-}
-
-int
-glusterd_quotad_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, "quotad")) {
- snprintf (msg, sizeof (msg), "for quotad statedump, options "
- "should be after the key 'quotad'");
- *op_errstr = gf_strdup (msg);
- ret = -1;
- goto out;
- }
-
- GLUSTERD_GET_QUOTAD_DIR (path, conf);
- GLUSTERD_GET_QUOTAD_PIDFILE (pidfile_path, path);
-
- pidfile = fopen (pidfile_path, "r");
- if (!pidfile) {
- gf_log (this->name, GF_LOG_ERROR, "Unable to open pidfile: %s",
- pidfile_path);
- ret = -1;
- goto out;
- }
-
- ret = fscanf (pidfile, "%d", &pid);
- if (ret <= 0) {
- gf_log (this->name, GF_LOG_ERROR, "Unable to get pid of quotad "
- "process");
- ret = -1;
- goto out;
- }
-
- snprintf (dumpoptions_path, sizeof (dumpoptions_path),
- DEFAULT_VAR_RUN_DIRECTORY"/glusterdump.%d.options", pid);
- ret = glusterd_set_dump_options (dumpoptions_path, options, option_cnt);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR, "error while parsing "
- "statedump options");
- ret = -1;
- goto out;
- }
-
- gf_log (this->name, GF_LOG_INFO, "Performing statedump on quotad 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 bricks belonging to the given volume.
- * Returns,
- * 2 - if peer contains all the bricks
- * 1 - if peer contains at least 1 brick
- * 0 - if peer contains no bricks
- */
-int
-glusterd_friend_contains_vol_bricks (glusterd_volinfo_t *volinfo,
- uuid_t friend_uuid)
-{
- int ret = 0;
- glusterd_brickinfo_t *brickinfo = NULL;
- int count = 0;
-
- GF_ASSERT (volinfo);
-
- list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) {
- if (!uuid_compare (brickinfo->uuid, friend_uuid)) {
- count++;
- }
- }
-
- if (count) {
- if (count == volinfo->brick_count)
- ret = 2;
- else
- ret = 1;
- }
- gf_log (THIS->name, GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-
-/* Cleanup the stale volumes left behind in the cluster. The volumes which are
- * contained completely within the detached peer are stale with respect to the
- * cluster.
- */
-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) == 2) {
- 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;
-}
-
-int
-glusterd_get_client_filepath (char *filepath, glusterd_volinfo_t *volinfo,
- gf_transport_type type)
-{
- int ret = 0;
- char path[PATH_MAX] = {0,};
- glusterd_conf_t *priv = NULL;
-
- priv = THIS->private;
-
- GLUSTERD_GET_VOLUME_DIR (path, volinfo, priv);
-
- switch (type) {
- case GF_TRANSPORT_TCP:
- snprintf (filepath, PATH_MAX,
- "%s/%s.tcp-fuse.vol", path, volinfo->volname);
- break;
-
- case GF_TRANSPORT_RDMA:
- snprintf (filepath, PATH_MAX,
- "%s/%s.rdma-fuse.vol", path, volinfo->volname);
- break;
- default:
- ret = -1;
- break;
- }
-
- return ret;
-}
-
-int
-glusterd_get_trusted_client_filepath (char *filepath,
- glusterd_volinfo_t *volinfo,
- gf_transport_type type)
-{
- int ret = 0;
- char path[PATH_MAX] = {0,};
- glusterd_conf_t *priv = NULL;
-
- priv = THIS->private;
-
- GLUSTERD_GET_VOLUME_DIR (path, volinfo, priv);
-
- switch (type) {
- case GF_TRANSPORT_TCP:
- snprintf (filepath, PATH_MAX, "%s/trusted-%s.tcp-fuse.vol",
- path, volinfo->volname);
- break;
-
- case GF_TRANSPORT_RDMA:
- snprintf (filepath, PATH_MAX, "%s/trusted-%s.rdma-fuse.vol",
- path, volinfo->volname);
- break;
- default:
- ret = -1;
- break;
- }
-
- return ret;
-}
-
-int
-glusterd_volume_defrag_restart (glusterd_volinfo_t *volinfo, char *op_errstr,
- size_t len, int cmd, defrag_cbk_fn_t cbk)
-{
- xlator_t *this = NULL;
- glusterd_conf_t *priv = NULL;
- char pidfile[PATH_MAX] = {0,};
- int ret = -1;
- pid_t pid = 0;
-
- this = THIS;
- GF_ASSERT (this);
-
- priv = this->private;
- if (!priv)
- return ret;
-
- /* Don't start the rebalance process if the stautus is already
- * completed, stopped or failed. If the status is started, check if
- * there is an existing process already and connect to it. If not, then
- * start the rebalance process
- */
- switch (volinfo->rebal.defrag_status) {
- case GF_DEFRAG_STATUS_COMPLETE:
- case GF_DEFRAG_STATUS_STOPPED:
- case GF_DEFRAG_STATUS_FAILED:
- break;
- case GF_DEFRAG_STATUS_STARTED:
- GLUSTERD_GET_DEFRAG_PID_FILE(pidfile, volinfo, priv);
- if (gf_is_service_running (pidfile, &pid)) {
- glusterd_rebalance_rpc_create (volinfo, _gf_true);
- break;
- }
- case GF_DEFRAG_STATUS_NOT_STARTED:
- glusterd_handle_defrag_start (volinfo, op_errstr, len, cmd,
- cbk, volinfo->rebal.op);
- break;
- default:
- gf_log (this->name, GF_LOG_ERROR, "Unknown defrag status (%d)."
- "Not starting rebalance process for %s.",
- volinfo->rebal.defrag_status, volinfo->volname);
- break;
- }
-
- 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->rebal.defrag_cmd)
- continue;
- if (!gd_should_i_start_rebalance (volinfo))
- continue;
- glusterd_volume_defrag_restart (volinfo, op_errstr, 256,
- volinfo->rebal.defrag_cmd, NULL);
- }
- return ret;
-}
-
-void
-glusterd_volinfo_reset_defrag_stats (glusterd_volinfo_t *volinfo)
-{
- glusterd_rebalance_t *rebal = NULL;
- GF_ASSERT (volinfo);
-
- rebal = &volinfo->rebal;
- rebal->rebalance_files = 0;
- rebal->rebalance_data = 0;
- rebal->lookedup_files = 0;
- rebal->rebalance_failures = 0;
- rebal->rebalance_time = 0;
- rebal->skipped_files = 0;
-
-}
-
-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, MY_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, };
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
-
- ret = dict_get_str (op_dict, "vol-id", &volid_str);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to get volume id for "
- "volume %s", volinfo->volname);
- goto out;
- }
- ret = uuid_parse (volid_str, vol_uid);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to parse volume id "
- "for volume %s", volinfo->volname);
- goto out;
- }
-
- if (uuid_compare (vol_uid, volinfo->volume_id)) {
- gf_log (this->name, GF_LOG_ERROR, "Volume ids of volume %s - %s"
- " and %s - are different. Possibly a split brain among "
- "peers.", volinfo->volname, volid_str,
- uuid_utoa (volinfo->volume_id));
- 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;
- uint64_t skipped = 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_uint64 (rsp_dict, "skipped", &skipped);
- if (ret)
- gf_log (this->name, GF_LOG_TRACE,
- "failed to get skipped 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->rebal.rebalance_files = files;
- if (size)
- volinfo->rebal.rebalance_data = size;
- if (lookup)
- volinfo->rebal.lookedup_files = lookup;
- if (status)
- volinfo->rebal.defrag_status = status;
- if (failures)
- volinfo->rebal.rebalance_failures = failures;
- if (skipped)
- volinfo->rebal.skipped_files = skipped;
- if (run_time)
- volinfo->rebal.rebalance_time = run_time;
-
- return ret;
-}
-
-int
-glusterd_check_topology_identical (const char *filename1,
- const char *filename2,
- gf_boolean_t *identical)
-{
- int ret = -1; /* FAILURE */
- xlator_t *this = THIS;
- FILE *fp1 = NULL;
- FILE *fp2 = NULL;
- glusterfs_graph_t *grph1 = NULL;
- glusterfs_graph_t *grph2 = NULL;
-
- /* Invalid xlator, Nothing to do */
- if (!this)
- return (-1);
-
- /* Sanitize the inputs */
- GF_VALIDATE_OR_GOTO (this->name, filename1, out);
- GF_VALIDATE_OR_GOTO (this->name, filename2, out);
- GF_VALIDATE_OR_GOTO (this->name, identical, out);
-
- /* fopen() the volfile1 to create the graph */
- fp1 = fopen (filename1, "r");
- if (fp1 == NULL) {
- gf_log (this->name, GF_LOG_ERROR, "fopen() on file: %s failed "
- "(%s)", filename1, strerror (errno));
- goto out;
- }
-
- /* fopen() the volfile2 to create the graph */
- fp2 = fopen (filename2, "r");
- if (fp2 == NULL) {
- gf_log (this->name, GF_LOG_ERROR, "fopen() on file: %s failed "
- "(%s)", filename2, strerror (errno));
- goto out;
- }
-
- /* create the graph for filename1 */
- grph1 = glusterfs_graph_construct(fp1);
- if (grph1 == NULL)
- goto out;
-
- /* create the graph for filename2 */
- grph2 = glusterfs_graph_construct(fp2);
- if (grph2 == NULL)
- goto out;
-
- /* compare the graph topology */
- *identical = is_graph_topology_equal(grph1, grph2);
- ret = 0; /* SUCCESS */
-out:
- if (fp1)
- fclose(fp1);
- if (fp2)
- fclose(fp2);
- if (grph1)
- glusterfs_graph_destroy(grph1);
- if (grph2)
- glusterfs_graph_destroy(grph2);
-
- gf_log (this->name, GF_LOG_DEBUG, "Returning with %d", ret);
- 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;
-}
-
-int
-glusterd_volset_help (dict_t *dict, char **op_errstr)
-{
- int ret = -1;
- gf_boolean_t xml_out = _gf_false;
- xlator_t *this = NULL;
-
- this = THIS;
-
- if (!dict) {
- if (!(dict = glusterd_op_get_ctx ())) {
- ret = 0;
- goto out;
- }
- }
-
- if (dict_get (dict, "help" )) {
- xml_out = _gf_false;
-
- } else if (dict_get (dict, "help-xml" )) {
- xml_out = _gf_true;
-#if (HAVE_LIB_XML)
- ret = 0;
-#else
- gf_log (this->name, GF_LOG_ERROR,
- "libxml not present in the system");
- if (op_errstr)
- *op_errstr = gf_strdup ("Error: xml libraries not "
- "present to produce "
- "xml-output");
- goto out;
-#endif
-
- } else {
- goto out;
- }
-
- ret = glusterd_get_volopt_content (dict, xml_out);
- if (ret && op_errstr)
- *op_errstr = gf_strdup ("Failed to get volume options help");
- out:
-
- gf_log ("glusterd", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-
-int
-glusterd_to_cli (rpcsvc_request_t *req, gf_cli_rsp *arg, struct iovec *payload,
- int payloadcount, struct iobref *iobref, xdrproc_t xdrproc,
- dict_t *dict)
-{
- int ret = -1;
- char *cmd = NULL;
- int op_ret = 0;
- char *op_errstr = NULL;
- int op_errno = 0;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
-
- op_ret = arg->op_ret;
- op_errstr = arg->op_errstr;
- op_errno = arg->op_errno;
-
- ret = dict_get_str (dict, "cmd-str", &cmd);
- if (ret)
- gf_log (this->name, GF_LOG_ERROR, "Failed to get command "
- "string");
-
- if (cmd) {
- if (op_ret)
- gf_cmd_log ("", "%s : FAILED %s %s", cmd,
- (op_errstr)? ":" : " ",
- (op_errstr)? op_errstr : " ");
- else
- gf_cmd_log ("", "%s : SUCCESS", cmd);
- }
-
- glusterd_submit_reply (req, arg, payload, payloadcount, iobref,
- (xdrproc_t) xdrproc);
- if (dict)
- dict_unref (dict);
-
- 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_with_alloc (dst, "gsync-status", 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;
-
-}
-
-int32_t
-glusterd_append_status_dicts (dict_t *dst, dict_t *src)
-{
- char sts_val_name[PATH_MAX] = {0, };
- int dst_count = 0;
- int src_count = 0;
- int i = 0;
- int ret = 0;
- gf_gsync_status_t *sts_val = NULL;
- gf_gsync_status_t *dst_sts_val = NULL;
-
- GF_ASSERT (dst);
-
- if (src == NULL)
- goto out;
-
- ret = dict_get_int32 (dst, "gsync-count", &dst_count);
- if (ret)
- dst_count = 0;
-
- ret = dict_get_int32 (src, "gsync-count", &src_count);
- if (ret || !src_count) {
- gf_log ("", GF_LOG_DEBUG, "Source brick empty");
- ret = 0;
- goto out;
- }
-
- for (i = 0; i < src_count; i++) {
- memset (sts_val_name, '\0', sizeof(sts_val_name));
- snprintf (sts_val_name, sizeof(sts_val_name), "status_value%d", i);
-
- ret = dict_get_bin (src, sts_val_name, (void **) &sts_val);
- if (ret)
- goto out;
-
- dst_sts_val = GF_CALLOC (1, sizeof(gf_gsync_status_t),
- gf_common_mt_gsync_status_t);
- if (!dst_sts_val) {
- gf_log ("", GF_LOG_ERROR, "Out Of Memory");
- goto out;
- }
-
- memcpy (dst_sts_val, sts_val, sizeof(gf_gsync_status_t));
-
- memset (sts_val_name, '\0', sizeof(sts_val_name));
- snprintf (sts_val_name, sizeof(sts_val_name), "status_value%d", i + dst_count);
-
- ret = dict_set_bin (dst, sts_val_name, dst_sts_val, sizeof(gf_gsync_status_t));
- if (ret)
- goto out;
- }
-
- ret = dict_set_int32 (dst, "gsync-count", dst_count+src_count);
-
- out:
- gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-
-}
-
-int32_t
-glusterd_aggr_brick_mount_dirs (dict_t *aggr, dict_t *rsp_dict)
-{
- char key[PATH_MAX] = "";
- char *brick_mount_dir = NULL;
- int32_t brick_count = -1;
- int32_t ret = -1;
- int32_t i = -1;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (aggr);
- GF_ASSERT (rsp_dict);
-
- ret = dict_get_int32 (rsp_dict, "brick_count", &brick_count);
- if (ret) {
- gf_log (this->name, GF_LOG_DEBUG, "No brick_count present");
- ret = 0;
- goto out;
- }
-
- for (i = 1; i <= brick_count; i++) {
- brick_mount_dir = NULL;
- snprintf (key, sizeof(key), "brick%d.mount_dir", i);
- ret = dict_get_str (rsp_dict, key, &brick_mount_dir);
- if (ret) {
- /* Coz the info will come from a different node */
- gf_log (this->name, GF_LOG_DEBUG,
- "%s not present", key);
- continue;
- }
-
- ret = dict_set_dynstr_with_alloc (aggr, key,
- brick_mount_dir);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to set %s", key);
- goto out;
- }
- }
-
- ret = 0;
-out:
- gf_log (this->name, GF_LOG_TRACE, "Returning %d ", ret);
- return ret;
-}
-
-int32_t
-glusterd_gsync_use_rsp_dict (dict_t *aggr, dict_t *rsp_dict, char *op_errstr)
-{
- dict_t *ctx = NULL;
- int ret = 0;
- char *conf_path = NULL;
-
- if (aggr) {
- ctx = aggr;
-
- } else {
- ctx = glusterd_op_get_ctx ();
- if (!ctx) {
- gf_log ("", GF_LOG_ERROR,
- "Operation Context is not present");
- GF_ASSERT (0);
- }
- }
-
- if (rsp_dict) {
- ret = glusterd_append_status_dicts (ctx, rsp_dict);
- if (ret)
- goto out;
-
- ret = glusterd_append_gsync_status (ctx, rsp_dict);
- if (ret)
- goto out;
-
- ret = dict_get_str (rsp_dict, "conf_path", &conf_path);
- if (!ret && conf_path) {
- ret = dict_set_dynstr_with_alloc (ctx, "conf_path",
- conf_path);
- if (ret) {
- gf_log ("", GF_LOG_ERROR,
- "Unable to store conf path.");
- goto out;
- }
- }
- }
- if ((op_errstr) && (strcmp ("", op_errstr))) {
- ret = dict_set_dynstr_with_alloc (ctx, "errstr",
- op_errstr);
- if (ret)
- goto out;
- }
-
- ret = 0;
- out:
- gf_log ("", GF_LOG_DEBUG, "Returning %d ", ret);
- return ret;
-}
-
-int32_t
-glusterd_rb_use_rsp_dict (dict_t *aggr, dict_t *rsp_dict)
-{
- int32_t src_port = 0;
- int32_t dst_port = 0;
- int ret = 0;
- dict_t *ctx = NULL;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
-
- if (aggr) {
- ctx = aggr;
-
- } else {
- ctx = glusterd_op_get_ctx ();
- if (!ctx) {
- gf_log ("", GF_LOG_ERROR,
- "Operation Context is not present");
- GF_ASSERT (0);
- }
- }
-
- if (rsp_dict) {
- ret = dict_get_int32 (rsp_dict, "src-brick-port", &src_port);
- if (ret == 0) {
- gf_log ("", GF_LOG_DEBUG,
- "src-brick-port=%d found", src_port);
- }
-
- ret = dict_get_int32 (rsp_dict, "dst-brick-port", &dst_port);
- if (ret == 0) {
- gf_log ("", GF_LOG_DEBUG,
- "dst-brick-port=%d found", dst_port);
- }
-
- ret = glusterd_aggr_brick_mount_dirs (ctx, rsp_dict);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to "
- "aggregate brick mount dirs");
- goto out;
- }
- }
-
- if (src_port) {
- ret = dict_set_int32 (ctx, "src-brick-port",
- src_port);
- if (ret) {
- gf_log ("", GF_LOG_DEBUG,
- "Could not set src-brick");
- goto out;
- }
- }
-
- if (dst_port) {
- ret = dict_set_int32 (ctx, "dst-brick-port",
- dst_port);
- if (ret) {
- gf_log ("", GF_LOG_DEBUG,
- "Could not set dst-brick");
- goto out;
- }
-
- }
-
-out:
- return ret;
-
-}
-
-int32_t
-glusterd_sync_use_rsp_dict (dict_t *aggr, dict_t *rsp_dict)
-{
- int ret = 0;
-
- GF_ASSERT (rsp_dict);
-
- if (!rsp_dict) {
- goto out;
- }
-
- ret = glusterd_import_friend_volumes (rsp_dict);
-out:
- return ret;
-
-}
-
-static int
-_profile_volume_add_friend_rsp (dict_t *this, char *key, data_t *value,
- void *data)
-{
- char new_key[256] = {0};
- glusterd_pr_brick_rsp_conv_t *rsp_ctx = NULL;
- data_t *new_value = NULL;
- int brick_count = 0;
- char brick_key[256];
-
- if (strcmp (key, "count") == 0)
- return 0;
- sscanf (key, "%d%s", &brick_count, brick_key);
- rsp_ctx = data;
- new_value = data_copy (value);
- GF_ASSERT (new_value);
- snprintf (new_key, sizeof (new_key), "%d%s",
- rsp_ctx->count + brick_count, brick_key);
- dict_set (rsp_ctx->dict, new_key, new_value);
- return 0;
-}
-
-int
-glusterd_profile_volume_use_rsp_dict (dict_t *aggr, dict_t *rsp_dict)
-{
- int ret = 0;
- glusterd_pr_brick_rsp_conv_t rsp_ctx = {0};
- int32_t brick_count = 0;
- int32_t 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", &brick_count);
- if (ret) {
- ret = 0; //no bricks in the rsp
- goto out;
- }
-
- op = glusterd_op_get_op ();
- GF_ASSERT (GD_OP_PROFILE_VOLUME == op);
- if (aggr) {
- ctx_dict = aggr;
-
- } else {
- ctx_dict = glusterd_op_get_ctx ();
- }
-
- ret = dict_get_int32 (ctx_dict, "count", &count);
- rsp_ctx.count = count;
- rsp_ctx.dict = ctx_dict;
- dict_foreach (rsp_dict, _profile_volume_add_friend_rsp, &rsp_ctx);
- dict_del (ctx_dict, "count");
- ret = dict_set_int32 (ctx_dict, "count", count + brick_count);
-out:
- return ret;
-}
-
-static int
-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;
-
- /* Skip the following keys, they are already present in the ctx_dict */
- /* Also, skip all the task related pairs. They will be added to the
- * ctx_dict later
- */
- if (!strcmp (key, "count") || !strcmp (key, "cmd") ||
- !strcmp (key, "brick-index-max") || !strcmp (key, "other-count") ||
- !strncmp (key, "task", 4))
- return 0;
-
- 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 0;
-}
-
-static int
-glusterd_volume_status_copy_tasks_to_ctx_dict (dict_t *this, char *key,
- data_t *value, void *data)
-{
- int ret = 0;
- dict_t *ctx_dict = NULL;
- data_t *new_value = NULL;
-
- if (strncmp (key, "task", 4))
- return 0;
-
- ctx_dict = data;
- GF_ASSERT (ctx_dict);
-
- new_value = data_copy (value);
- GF_ASSERT (new_value);
-
- ret = dict_set (ctx_dict, key, new_value);
-
- return ret;
-}
-
-int
-glusterd_volume_status_aggregate_tasks_status (dict_t *ctx_dict,
- dict_t *rsp_dict)
-{
- int ret = -1;
- xlator_t *this = NULL;
- int local_count = 0;
- int remote_count = 0;
- int i = 0;
- int j = 0;
- char key[128] = {0,};
- char *task_type = NULL;
- int local_status = 0;
- int remote_status = 0;
- char *local_task_id = NULL;
- char *remote_task_id = NULL;
-
- GF_ASSERT (ctx_dict);
- GF_ASSERT (rsp_dict);
-
- this = THIS;
- GF_ASSERT (this);
-
- ret = dict_get_int32 (rsp_dict, "tasks", &remote_count);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to get remote task count");
- goto out;
- }
- /* Local count will not be present when this is called for the first
- * time with the origins rsp_dict
- */
- ret = dict_get_int32 (ctx_dict, "tasks", &local_count);
- if (ret) {
- ret = dict_foreach (rsp_dict,
- glusterd_volume_status_copy_tasks_to_ctx_dict,
- ctx_dict);
- if (ret)
- gf_log (this->name, GF_LOG_ERROR, "Failed to copy tasks"
- "to ctx_dict.");
- goto out;
- }
-
- if (local_count != remote_count) {
- gf_log (this->name, GF_LOG_ERROR, "Local tasks count (%d) and "
- "remote tasks count (%d) do not match. Not aggregating "
- "tasks status.", local_count, remote_count);
- ret = -1;
- goto out;
- }
-
- /* Update the tasks statuses. For every remote tasks, search for the
- * local task, and update the local task status based on the remote
- * status.
- */
- for (i = 0; i < remote_count; i++) {
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "task%d.type", i);
- ret = dict_get_str (rsp_dict, key, &task_type);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to get task typpe from rsp dict");
- goto out;
- }
-
- /* Skip replace-brick status as it is going to be the same on
- * all peers. rb_status is set by the replace brick commit
- * function on all peers based on the replace brick command.
- * We return the value of rb_status as the status for a
- * replace-brick task in a 'volume status' command.
- */
- if (!strcmp (task_type, "Replace brick"))
- continue;
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "task%d.status", i);
- ret = dict_get_int32 (rsp_dict, key, &remote_status);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to get task status from rsp dict");
- goto out;
- }
- snprintf (key, sizeof (key), "task%d.id", i);
- ret = dict_get_str (rsp_dict, key, &remote_task_id);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to get task id from rsp dict");
- goto out;
- }
- for (j = 0; j < local_count; j++) {
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "task%d.id", j);
- ret = dict_get_str (ctx_dict, key, &local_task_id);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to get local task-id");
- goto out;
- }
-
- if (strncmp (remote_task_id, local_task_id,
- strlen (remote_task_id))) {
- /* Quit if a matching local task is not found */
- if (j == (local_count - 1)) {
- gf_log (this->name, GF_LOG_ERROR,
- "Could not find matching local "
- "task for task %s",
- remote_task_id);
- goto out;
- }
- continue;
- }
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "task%d.status", j);
- ret = dict_get_int32 (ctx_dict, key, &local_status);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to get local task status");
- goto out;
- }
-
- /* Rebalance has 5 states,
- * NOT_STARTED, STARTED, STOPPED, COMPLETE, FAILED
- * The precedence used to determine the aggregate status
- * is as below,
- * STARTED > FAILED > STOPPED > COMPLETE > NOT_STARTED
- */
- /* TODO: Move this to a common place utilities that both
- * CLI and glusterd need.
- * Till then if the below algorithm is changed, change
- * it in cli_xml_output_vol_rebalance_status in
- * cli-xml-output.c
- */
- ret = 0;
- int rank[] = {
- [GF_DEFRAG_STATUS_STARTED] = 1,
- [GF_DEFRAG_STATUS_FAILED] = 2,
- [GF_DEFRAG_STATUS_STOPPED] = 3,
- [GF_DEFRAG_STATUS_COMPLETE] = 4,
- [GF_DEFRAG_STATUS_NOT_STARTED] = 5
- };
- if (rank[remote_status] <= rank[local_status])
- ret = dict_set_int32 (ctx_dict, key,
- remote_status);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to "
- "update task status");
- goto out;
- }
- break;
- }
- }
-
-out:
- return ret;
-}
-
-gf_boolean_t
-glusterd_status_has_tasks (int cmd) {
- if (((cmd & GF_CLI_STATUS_MASK) == GF_CLI_STATUS_NONE) &&
- (cmd & GF_CLI_STATUS_VOL))
- return _gf_true;
- return _gf_false;
-}
-
-int
-glusterd_volume_status_copy_to_op_ctx_dict (dict_t *aggr, dict_t *rsp_dict)
-{
- int ret = 0;
- glusterd_status_rsp_conv_t rsp_ctx = {0};
- int32_t cmd = GF_CLI_STATUS_NONE;
- int32_t node_count = 0;
- int32_t other_count = 0;
- int32_t brick_index_max = -1;
- int32_t rsp_node_count = 0;
- int32_t rsp_other_count = 0;
- int vol_count = -1;
- int i = 0;
- dict_t *ctx_dict = NULL;
- char key[PATH_MAX] = {0,};
- char *volname = NULL;
-
- GF_ASSERT (rsp_dict);
-
- if (aggr) {
- ctx_dict = aggr;
-
- } else {
- ctx_dict = glusterd_op_get_ctx (GD_OP_STATUS_VOLUME);
-
- }
-
- ret = dict_get_int32 (ctx_dict, "cmd", &cmd);
- if (ret)
- goto out;
-
- if (cmd & GF_CLI_STATUS_ALL && is_origin_glusterd (ctx_dict)) {
- ret = dict_get_int32 (rsp_dict, "vol_count", &vol_count);
- if (ret == 0) {
- ret = dict_set_int32 (ctx_dict, "vol_count",
- vol_count);
- if (ret)
- goto out;
-
- for (i = 0; i < vol_count; i++) {
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "vol%d", i);
- ret = dict_get_str (rsp_dict, key, &volname);
- if (ret)
- goto out;
-
- ret = dict_set_str (ctx_dict, key, volname);
- if (ret)
- goto out;
- }
- }
- }
-
- if ((cmd & GF_CLI_STATUS_TASKS) != 0)
- goto aggregate_tasks;
-
- 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;
- }
-
- ret = dict_get_int32 (ctx_dict, "count", &node_count);
- ret = dict_get_int32 (ctx_dict, "other-count", &other_count);
- if (!dict_get (ctx_dict, "brick-index-max")) {
- ret = dict_get_int32 (rsp_dict, "brick-index-max", &brick_index_max);
- if (ret)
- goto out;
- ret = dict_set_int32 (ctx_dict, "brick-index-max", brick_index_max);
- if (ret)
- goto out;
-
- } else {
- ret = dict_get_int32 (ctx_dict, "brick-index-max", &brick_index_max);
- }
-
- 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");
- goto out;
- }
-
-aggregate_tasks:
- /* Tasks are only present for a normal status command for a volume or
- * for an explicit tasks status command for a volume
- */
- if (!(cmd & GF_CLI_STATUS_ALL) &&
- (((cmd & GF_CLI_STATUS_TASKS) != 0) ||
- glusterd_status_has_tasks (cmd)))
- ret = glusterd_volume_status_aggregate_tasks_status (ctx_dict,
- rsp_dict);
-
-out:
- return ret;
-}
-
-int
-glusterd_volume_rebalance_use_rsp_dict (dict_t *aggr, dict_t *rsp_dict)
-{
- char key[256] = {0,};
- char *node_uuid = NULL;
- char *node_uuid_str = NULL;
- char *volname = NULL;
- dict_t *ctx_dict = NULL;
- double elapsed_time = 0;
- glusterd_conf_t *conf = NULL;
- glusterd_op_t op = GD_OP_NONE;
- glusterd_peerinfo_t *peerinfo = NULL;
- glusterd_volinfo_t *volinfo = NULL;
- int ret = 0;
- int32_t index = 0;
- int32_t count = 0;
- int32_t current_index = 2;
- int32_t value32 = 0;
- uint64_t value = 0;
- char *peer_uuid_str = NULL;
-
- GF_ASSERT (rsp_dict);
- conf = THIS->private;
-
- op = glusterd_op_get_op ();
- GF_ASSERT ((GD_OP_REBALANCE == op) ||
- (GD_OP_DEFRAG_BRICK_VOLUME == op));
-
- if (aggr) {
- ctx_dict = aggr;
-
- } else {
- ctx_dict = glusterd_op_get_ctx (op);
-
- }
-
- if (!ctx_dict)
- goto out;
-
- 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");
-
- memset (key, 0, 256);
- snprintf (key, 256, "node-uuid-%d", index);
- ret = dict_get_str (rsp_dict, key, &node_uuid);
- if (!ret) {
- node_uuid_str = gf_strdup (node_uuid);
-
- /* Finding the index of the node-uuid in the peer-list */
- list_for_each_entry (peerinfo, &conf->peers, uuid_list) {
- peer_uuid_str = gd_peer_uuid_str (peerinfo);
- if (strcmp (peer_uuid_str, node_uuid_str) == 0)
- break;
-
- current_index++;
- }
-
- /* Setting the largest index value as the total count. */
- ret = dict_get_int32 (ctx_dict, "count", &count);
- if (count < current_index) {
- ret = dict_set_int32 (ctx_dict, "count", current_index);
- if (ret)
- gf_log ("", GF_LOG_ERROR, "Failed to set count");
- }
-
- /* Setting the same index for the node, as is in the peerlist.*/
- memset (key, 0, 256);
- snprintf (key, 256, "node-uuid-%d", current_index);
- ret = dict_set_dynstr (ctx_dict, key, node_uuid_str);
- if (ret) {
- gf_log (THIS->name, GF_LOG_DEBUG,
- "failed to set node-uuid");
- }
- }
-
- 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", current_index);
- 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", current_index);
- 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", current_index);
- 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", current_index);
- 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, "failures-%d", index);
- ret = dict_get_uint64 (rsp_dict, key, &value);
- if (!ret) {
- memset (key, 0, 256);
- snprintf (key, 256, "failures-%d", current_index);
- 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, "skipped-%d", index);
- ret = dict_get_uint64 (rsp_dict, key, &value);
- if (!ret) {
- memset (key, 0, 256);
- snprintf (key, 256, "skipped-%d", current_index);
- ret = dict_set_uint64 (ctx_dict, key, value);
- if (ret) {
- gf_log (THIS->name, GF_LOG_DEBUG,
- "failed to set skipped 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", current_index);
- 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_snap_config_use_rsp_dict (dict_t *dst, dict_t *src)
-{
- char buf[PATH_MAX] = "";
- char *volname = NULL;
- int ret = -1;
- int config_command = 0;
- uint64_t i = 0;
- uint64_t hard_limit = GLUSTERD_SNAPS_MAX_HARD_LIMIT;
- uint64_t soft_limit = GLUSTERD_SNAPS_DEF_SOFT_LIMIT_PERCENT;
- uint64_t value = 0;
- uint64_t voldisplaycount = 0;
-
- if (!dst || !src) {
- gf_log ("", GF_LOG_ERROR, "Source or Destination "
- "dict is empty.");
- goto out;
- }
-
- ret = dict_get_int32 (dst, "config-command", &config_command);
- if (ret) {
- gf_log ("", GF_LOG_ERROR,
- "failed to get config-command type");
- goto out;
- }
-
- switch (config_command) {
- case GF_SNAP_CONFIG_DISPLAY:
- ret = dict_get_uint64 (src,
- GLUSTERD_STORE_KEY_SNAP_MAX_HARD_LIMIT,
- &hard_limit);
- if (!ret) {
- ret = dict_set_uint64 (dst,
- GLUSTERD_STORE_KEY_SNAP_MAX_HARD_LIMIT,
- hard_limit);
- if (ret) {
- gf_log ("", GF_LOG_ERROR,
- "Unable to set snap_max_hard_limit");
- goto out;
- }
- } else {
- /* Received dummy response from other nodes */
- ret = 0;
- goto out;
- }
-
- ret = dict_get_uint64 (src,
- GLUSTERD_STORE_KEY_SNAP_MAX_SOFT_LIMIT,
- &soft_limit);
- if (ret) {
- gf_log ("", GF_LOG_ERROR,
- "Unable to get snap_max_soft_limit");
- goto out;
- }
-
- ret = dict_set_uint64 (dst,
- GLUSTERD_STORE_KEY_SNAP_MAX_SOFT_LIMIT,
- soft_limit);
- if (ret) {
- gf_log ("", GF_LOG_ERROR,
- "Unable to set snap_max_soft_limit");
- goto out;
- }
-
- ret = dict_get_uint64 (src, "voldisplaycount",
- &voldisplaycount);
- if (ret) {
- gf_log ("", GF_LOG_ERROR,
- "Unable to get voldisplaycount");
- goto out;
- }
-
- ret = dict_set_uint64 (dst, "voldisplaycount",
- voldisplaycount);
- if (ret) {
- gf_log ("", GF_LOG_ERROR,
- "Unable to set voldisplaycount");
- goto out;
- }
-
- for (i = 0; i < voldisplaycount; i++) {
- snprintf (buf, sizeof(buf), "volume%"PRIu64"-volname", i);
- ret = dict_get_str (src, buf, &volname);
- if (ret) {
- gf_log ("", GF_LOG_ERROR,
- "Unable to get %s", buf);
- goto out;
- }
- ret = dict_set_str (dst, buf, volname);
- if (ret) {
- gf_log ("", GF_LOG_ERROR,
- "Unable to set %s", buf);
- goto out;
- }
-
- snprintf (buf, sizeof(buf),
- "volume%"PRIu64"-snap-max-hard-limit", i);
- ret = dict_get_uint64 (src, buf, &value);
- if (ret) {
- gf_log ("", GF_LOG_ERROR,
- "Unable to get %s", buf);
- goto out;
- }
- ret = dict_set_uint64 (dst, buf, value);
- if (ret) {
- gf_log ("", GF_LOG_ERROR,
- "Unable to set %s", buf);
- goto out;
- }
-
- snprintf (buf, sizeof(buf),
- "volume%"PRIu64"-active-hard-limit", i);
- ret = dict_get_uint64 (src, buf, &value);
- if (ret) {
- gf_log ("", GF_LOG_ERROR,
- "Unable to get %s", buf);
- goto out;
- }
- ret = dict_set_uint64 (dst, buf, value);
- if (ret) {
- gf_log ("", GF_LOG_ERROR,
- "Unable to set %s", buf);
- goto out;
- }
-
- snprintf (buf, sizeof(buf),
- "volume%"PRIu64"-snap-max-soft-limit", i);
- ret = dict_get_uint64 (src, buf, &value);
- if (ret) {
- gf_log ("", GF_LOG_ERROR,
- "Unable to get %s", buf);
- goto out;
- }
- ret = dict_set_uint64 (dst, buf, value);
- if (ret) {
- gf_log ("", GF_LOG_ERROR,
- "Unable to set %s", buf);
- goto out;
- }
- }
-
- break;
- default:
- break;
- }
-
- ret = 0;
-out:
- gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-
-int
-glusterd_merge_brick_status (dict_t *dst, dict_t *src)
-{
- int64_t volume_count = 0;
- int64_t index = 0;
- int64_t j = 0;
- int64_t brick_count = 0;
- int64_t brick_order = 0;
- char key[PATH_MAX] = {0, };
- char snapbrckcnt[PATH_MAX] = {0, };
- char snapbrckord[PATH_MAX] = {0, };
- int ret = -1;
- int32_t brick_online = 0;
- xlator_t *this = NULL;
- int32_t snap_command = 0;
-
- this = THIS;
- GF_ASSERT (this);
-
- if (!dst || !src) {
- gf_log (this->name, GF_LOG_ERROR, "Source or Destination "
- "dict is empty.");
- goto out;
- }
-
- ret = dict_get_int32 (dst, "type", &snap_command);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "unable to get the type of "
- "the snapshot command");
- goto out;
- }
-
- if (snap_command == GF_SNAP_OPTION_TYPE_DELETE) {
- gf_log (this->name, GF_LOG_DEBUG, "snapshot delete command."
- " Need not merge the status of the bricks");
- ret = 0;
- goto out;
- }
-
- ret = dict_get_int64 (src, "volcount", &volume_count);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "failed to "
- "get the volume count");
- goto out;
- }
-
- for (index = 0; index < volume_count; index++) {
- ret = snprintf (snapbrckcnt, sizeof(snapbrckcnt) - 1,
- "snap-vol%"PRId64"_brickcount", index+1);
- ret = dict_get_int64 (src, snapbrckcnt, &brick_count);
- if (ret) {
- gf_log (this->name, GF_LOG_TRACE,
- "No bricks for this volume in this dict (%s)",
- snapbrckcnt);
- continue;
- }
-
- for (j = 0; j < brick_count; j++) {
- /* Fetching data from source dict */
- snprintf (snapbrckord, sizeof(snapbrckord) - 1,
- "snap-vol%"PRId64".brick%"PRId64".order", index+1, j);
-
- ret = dict_get_int64 (src, snapbrckord, &brick_order);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to get brick order (%s)",
- snapbrckord);
- goto out;
- }
-
- snprintf (key, sizeof (key) - 1,
- "snap-vol%"PRId64".brick%"PRId64".status", index+1,
- brick_order);
- ret = dict_get_int32 (src, key, &brick_online);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "failed to "
- "get the brick status (%s)", key);
- goto out;
- }
-
- ret = dict_set_int32 (dst, key, brick_online);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "failed to "
- "set the brick status (%s)", key);
- goto out;
- }
- brick_online = 0;
- }
- }
-
- ret = 0;
-
-out:
- return ret;
-}
-
-/* Aggregate missed_snap_counts from different nodes and save it *
- * in the req_dict of the originator node */
-int
-glusterd_snap_create_use_rsp_dict (dict_t *dst, dict_t *src)
-{
- char *buf = NULL;
- char *tmp_str = NULL;
- char name_buf[PATH_MAX] = "";
- int32_t i = -1;
- int32_t ret = -1;
- int32_t src_missed_snap_count = -1;
- int32_t dst_missed_snap_count = -1;
- xlator_t *this = NULL;
- int8_t soft_limit_flag = -1;
-
- this = THIS;
- GF_ASSERT (this);
-
- if (!dst || !src) {
- gf_log (this->name, GF_LOG_ERROR, "Source or Destination "
- "dict is empty.");
- goto out;
- }
-
- ret = glusterd_merge_brick_status (dst, src);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "failed to merge brick "
- "status");
- goto out;
- }
-
- ret = dict_get_str (src, "snapuuid", &buf);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "failed to get snap UUID");
- goto out;
- }
-
- ret = dict_set_dynstr_with_alloc (dst, "snapuuid", buf);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to set snap uuid in dict");
- goto out;
- }
-
- /* set in dst dictionary soft-limit-reach only if soft-limit-reach
- * is present src dictionary */
- ret = dict_get_int8 (src, "soft-limit-reach", &soft_limit_flag);
- if (!ret) {
- ret = dict_set_int8 (dst, "soft-limit-reach", soft_limit_flag);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to set "
- "soft_limit_flag");
- goto out;
- }
- }
-
- ret = dict_get_int32 (src, "missed_snap_count",
- &src_missed_snap_count);
- if (ret) {
- gf_log (this->name, GF_LOG_DEBUG, "No missed snaps");
- ret = 0;
- goto out;
- }
-
- ret = dict_get_int32 (dst, "missed_snap_count",
- &dst_missed_snap_count);
- if (ret) {
- /* Initialize dst_missed_count for the first time */
- dst_missed_snap_count = 0;
- }
-
- for (i = 0; i < src_missed_snap_count; i++) {
- snprintf (name_buf, sizeof(name_buf), "missed_snaps_%d",
- i);
- ret = dict_get_str (src, name_buf, &buf);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Unable to fetch %s", name_buf);
- goto out;
- }
-
- snprintf (name_buf, sizeof(name_buf), "missed_snaps_%d",
- dst_missed_snap_count);
-
- tmp_str = gf_strdup (buf);
- if (!tmp_str) {
- ret = -1;
- goto out;
- }
-
- ret = dict_set_dynstr (dst, name_buf, tmp_str);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Unable to set %s", name_buf);
- goto out;
- }
-
- tmp_str = NULL;
- dst_missed_snap_count++;
- }
-
- ret = dict_set_int32 (dst, "missed_snap_count", dst_missed_snap_count);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Unable to set dst_missed_snap_count");
- goto out;
- }
-
-out:
- if (ret && tmp_str)
- GF_FREE(tmp_str);
-
- gf_log (this->name, GF_LOG_TRACE, "Returning %d", ret);
- return ret;
-}
-
-int
-glusterd_snap_use_rsp_dict (dict_t *dst, dict_t *src)
-{
- int ret = -1;
- int32_t snap_command = 0;
-
- if (!dst || !src) {
- gf_log ("", GF_LOG_ERROR, "Source or Destination "
- "dict is empty.");
- goto out;
- }
-
- ret = dict_get_int32 (dst, "type", &snap_command);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "unable to get the type of "
- "the snapshot command");
- goto out;
- }
-
- switch (snap_command) {
- case GF_SNAP_OPTION_TYPE_CREATE:
- case GF_SNAP_OPTION_TYPE_DELETE:
- ret = glusterd_snap_create_use_rsp_dict (dst, src);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Unable to use rsp dict");
- goto out;
- }
- break;
- case GF_SNAP_OPTION_TYPE_CONFIG:
- ret = glusterd_snap_config_use_rsp_dict (dst, src);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Unable to use rsp dict");
- goto out;
- }
- break;
- default:
- // copy the response dictinary's contents to the dict to be
- // sent back to the cli
- dict_copy (src, dst);
- break;
- }
-
- ret = 0;
-out:
- gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-
-int
-glusterd_sys_exec_output_rsp_dict (dict_t *dst, dict_t *src)
-{
- char output_name[PATH_MAX] = "";
- char *output = NULL;
- int ret = 0;
- int i = 0;
- int len = 0;
- int src_output_count = 0;
- int dst_output_count = 0;
-
- if (!dst || !src) {
- gf_log ("", GF_LOG_ERROR, "Source or Destination "
- "dict is empty.");
- goto out;
- }
-
- ret = dict_get_int32 (dst, "output_count", &dst_output_count);
-
- ret = dict_get_int32 (src, "output_count", &src_output_count);
- if (ret) {
- gf_log ("", GF_LOG_DEBUG, "No output from source");
- ret = 0;
- goto out;
- }
-
- for (i = 1; i <= src_output_count; i++) {
- len = snprintf (output_name, sizeof(output_name) - 1,
- "output_%d", i);
- output_name[len] = '\0';
- ret = dict_get_str (src, output_name, &output);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Unable to fetch %s",
- output_name);
- goto out;
- }
-
- len = snprintf (output_name, sizeof(output_name) - 1,
- "output_%d", i+dst_output_count);
- output_name[len] = '\0';
- ret = dict_set_dynstr (dst, output_name, gf_strdup (output));
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Unable to set %s",
- output_name);
- goto out;
- }
- }
-
- ret = dict_set_int32 (dst, "output_count",
- dst_output_count+src_output_count);
-out:
- gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-
-int
-glusterd_use_rsp_dict (dict_t *aggr, dict_t *rsp_dict)
-{
- int ret = 0;
- glusterd_op_t op = GD_OP_NONE;
-
- op = glusterd_op_get_op ();
- GF_ASSERT (aggr);
- GF_ASSERT (rsp_dict);
-
- if (!aggr)
- goto out;
- dict_copy (rsp_dict, aggr);
-out:
- return ret;
-}
-
-int
-glusterd_volume_heal_use_rsp_dict (dict_t *aggr, 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);
-
- if (aggr) {
- ctx_dict = aggr;
-
- } else {
- ctx_dict = glusterd_op_get_ctx (op);
- }
-
- if (!ctx_dict)
- goto out;
- dict_copy (rsp_dict, ctx_dict);
-out:
- return ret;
-}
-
-int
-_profile_volume_add_brick_rsp (dict_t *this, char *key, data_t *value,
- void *data)
-{
- char new_key[256] = {0};
- glusterd_pr_brick_rsp_conv_t *rsp_ctx = NULL;
- data_t *new_value = NULL;
-
- rsp_ctx = data;
- new_value = data_copy (value);
- GF_ASSERT (new_value);
- snprintf (new_key, sizeof (new_key), "%d-%s", rsp_ctx->count, key);
- dict_set (rsp_ctx->dict, new_key, new_value);
- return 0;
-}
-
-int
-glusterd_volume_quota_copy_to_op_ctx_dict (dict_t *dict, dict_t *rsp_dict)
-{
- int ret = -1;
- int i = 0;
- int count = 0;
- int rsp_dict_count = 0;
- char *uuid_str = NULL;
- char *uuid_str_dup = NULL;
- char key[256] = {0,};
- xlator_t *this = NULL;
- int type = GF_QUOTA_OPTION_TYPE_NONE;
-
- this = THIS;
- GF_ASSERT (this);
-
- ret = dict_get_int32 (dict, "type", &type);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to get quota opcode");
- goto out;
- }
-
- if ((type != GF_QUOTA_OPTION_TYPE_LIMIT_USAGE) &&
- (type != GF_QUOTA_OPTION_TYPE_REMOVE)) {
- dict_copy (rsp_dict, dict);
- ret = 0;
- goto out;
- }
-
- ret = dict_get_int32 (rsp_dict, "count", &rsp_dict_count);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to get the count of "
- "gfids from the rsp dict");
- goto out;
- }
-
- ret = dict_get_int32 (dict, "count", &count);
- if (ret)
- /* The key "count" is absent in op_ctx when this function is
- * called after self-staging on the originator. This must not
- * be treated as error.
- */
- gf_log (this->name, GF_LOG_DEBUG, "Failed to get count of gfids"
- " from req dict. This could be because count is not yet"
- " copied from rsp_dict into op_ctx");
-
- for (i = 0; i < rsp_dict_count; i++) {
- snprintf (key, sizeof(key)-1, "gfid%d", i);
-
- ret = dict_get_str (rsp_dict, key, &uuid_str);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to get gfid "
- "from rsp dict");
- goto out;
- }
-
- snprintf (key, sizeof (key)-1, "gfid%d", i + count);
-
- uuid_str_dup = gf_strdup (uuid_str);
- if (!uuid_str_dup) {
- ret = -1;
- goto out;
- }
-
- ret = dict_set_dynstr (dict, key, uuid_str_dup);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to set gfid "
- "from rsp dict into req dict");
- GF_FREE (uuid_str_dup);
- goto out;
- }
- }
-
- ret = dict_set_int32 (dict, "count", rsp_dict_count + count);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to set aggregated "
- "count in req dict");
- goto out;
- }
-
-out:
- return ret;
-}
-
-int
-glusterd_profile_volume_brick_rsp (void *pending_entry,
- dict_t *rsp_dict, dict_t *op_ctx,
- char **op_errstr, gd_node_type type)
-{
- 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;
-
- 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);
-
- ret = dict_get_int32 (op_ctx, "count", &count);
- if (ret) {
- count = 1;
- } else {
- 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));
- }
- full_brick = gf_strdup (brick);
- GF_ASSERT (full_brick);
- ret = dict_set_dynstr (op_ctx, key, full_brick);
-
- rsp_ctx.count = count;
- rsp_ctx.dict = op_ctx;
- dict_foreach (rsp_dict, _profile_volume_add_brick_rsp, &rsp_ctx);
- dict_del (op_ctx, "count");
- ret = dict_set_int32 (op_ctx, "count", count);
- return ret;
-}
-
-//input-key: <replica-id>:<child-id>-*
-//output-key: <brick-id>-*
-int
-_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 0;
-}
-
-int
-_heal_volume_add_shd_rsp_of_statistics (dict_t *this, char *key, data_t
- *value, void *data)
-{
- char new_key[256] = {0,};
- char int_str[16] = {0,};
- char key_begin_string[128] = {0,};
- data_t *new_value = NULL;
- char *rxl_end = NULL;
- char *rxl_child_end = NULL;
- glusterd_volinfo_t *volinfo = NULL;
- char *key_begin_str = 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;
- key_begin_str = strchr (key, '-');
- if (!key_begin_str)
- goto out;
-
- int_len = strlen (key) - strlen (key_begin_str);
- strncpy (key_begin_string, key, int_len);
- key_begin_string[int_len] = '\0';
-
- rxl_end = strchr (key_begin_str + 1, '-');
- if (!rxl_end)
- goto out;
-
- int_len = strlen (key_begin_str) - strlen (rxl_end) - 1;
- strncpy (int_str, key_begin_str + 1, 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;
-
- 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), "%s-%d%s", key_begin_string,
- brick_id, rxl_child_end);
- dict_set (rsp_ctx->dict, new_key, new_value);
-
-out:
- return 0;
-
-}
-
-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;
- int heal_op = -1;
-
- 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 = dict_get_int32 (req_dict, "heal-op", &heal_op);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Unable to get heal_op");
- 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;
- if (heal_op == GF_AFR_OP_STATISTICS)
- dict_foreach (rsp_dict, _heal_volume_add_shd_rsp_of_statistics,
- &rsp_ctx);
- else
- dict_foreach (rsp_dict, _heal_volume_add_shd_rsp, &rsp_ctx);
-
-
-out:
- return ret;
-}
-
-int
-_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 0;
-}
-
-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->rebal.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->rebal.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->rebal.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->rebal.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->rebal.rebalance_failures);
- if (ret)
- gf_log (THIS->name, GF_LOG_ERROR,
- "failed to set failure count");
-
- memset (key, 0 , 256);
- snprintf (key, 256, "skipped-%d", i);
- ret = dict_set_uint64 (op_ctx, key, volinfo->rebal.skipped_files);
- if (ret)
- gf_log (THIS->name, GF_LOG_ERROR,
- "failed to set skipped count");
-
- memset (key, 0, 256);
- snprintf (key, 256, "run-time-%d", i);
- ret = dict_set_double (op_ctx, key, volinfo->rebal.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 (dict_t *req_dict, void *pending_entry,
- glusterd_op_t op, dict_t *rsp_dict, dict_t *op_ctx,
- char **op_errstr, gd_node_type type)
-{
- 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_dict,
- rsp_dict, op_ctx);
- break;
-
- case GD_OP_HEAL_VOLUME:
- ret = glusterd_heal_volume_brick_rsp (req_dict, rsp_dict,
- op_ctx, op_errstr);
- break;
- default:
- break;
- }
-
- gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-
-int32_t
-glusterd_set_originator_uuid (dict_t *dict)
-{
- int ret = -1;
- uuid_t *originator_uuid = NULL;
-
- GF_ASSERT (dict);
-
- originator_uuid = GF_CALLOC (1, sizeof(uuid_t),
- gf_common_mt_uuid_t);
- if (!originator_uuid) {
- ret = -1;
- goto out;
- }
-
- uuid_copy (*originator_uuid, MY_UUID);
- ret = dict_set_bin (dict, "originator_uuid",
- originator_uuid, sizeof (uuid_t));
- if (ret) {
- gf_log ("", GF_LOG_ERROR,
- "Failed to set originator_uuid.");
- goto out;
- }
-
-out:
- if (ret && originator_uuid)
- GF_FREE (originator_uuid);
-
- return ret;
-}
-
-/* Should be used only when an operation is in progress, as that is the only
- * time a lock_owner is set
- */
-gf_boolean_t
-is_origin_glusterd (dict_t *dict)
-{
- gf_boolean_t ret = _gf_false;
- uuid_t lock_owner = {0,};
- uuid_t *originator_uuid = NULL;
-
- GF_ASSERT (dict);
-
- ret = dict_get_bin (dict, "originator_uuid",
- (void **) &originator_uuid);
- if (ret) {
- /* If not originator_uuid has been set, then the command
- * has been originated from a glusterd running on older version
- * Hence fetching the lock owner */
- ret = glusterd_get_lock_owner (&lock_owner);
- if (ret) {
- ret = _gf_false;
- goto out;
- }
- ret = !uuid_compare (MY_UUID, lock_owner);
- } else
- ret = !uuid_compare (MY_UUID, *originator_uuid);
-
-out:
- return ret;
-}
-
-int
-glusterd_generate_and_set_task_id (dict_t *dict, char *key)
-{
- int ret = -1;
- uuid_t task_id = {0,};
- char *uuid_str = NULL;
- xlator_t *this = NULL;
-
- GF_ASSERT (dict);
-
- this = THIS;
- GF_ASSERT (this);
-
- uuid_generate (task_id);
- uuid_str = gf_strdup (uuid_utoa (task_id));
- if (!uuid_str) {
- ret = -1;
- goto out;
- }
-
- ret = dict_set_dynstr (dict, key, uuid_str);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to set %s in dict",
- key);
- goto out;
- }
- gf_log (this->name, GF_LOG_INFO, "Generated task-id %s for key %s",
- uuid_str, key);
-
-out:
- if (ret)
- GF_FREE (uuid_str);
- return ret;
-}
-
-int
-glusterd_copy_uuid_to_dict (uuid_t uuid, dict_t *dict, char *key)
-{
- int ret = -1;
- char tmp_str[40] = {0,};
- char *task_id_str = NULL;
-
- GF_ASSERT (dict);
- GF_ASSERT (key);
-
- uuid_unparse (uuid, tmp_str);
- task_id_str = gf_strdup (tmp_str);
- if (!task_id_str)
- return -1;
-
- ret = dict_set_dynstr (dict, key, task_id_str);
- if (ret) {
- GF_FREE (task_id_str);
- gf_log (THIS->name, GF_LOG_ERROR,
- "Error setting uuid in dict with key %s", key);
- }
-
- return 0;
-}
-
-int
-_update_volume_op_versions (dict_t *this, char *key, data_t *value, void *data)
-{
- int op_version = 0;
- glusterd_volinfo_t *ctx = NULL;
- gf_boolean_t enabled = _gf_true;
- int ret = -1;
-
- GF_ASSERT (data);
- ctx = data;
-
- op_version = glusterd_get_op_version_for_key (key);
-
- if (gd_is_xlator_option (key) || gd_is_boolean_option (key)) {
- ret = gf_string2boolean (value->data, &enabled);
- if (ret)
- return 0;
-
- if (!enabled)
- return 0;
- }
-
- if (op_version > ctx->op_version)
- ctx->op_version = op_version;
-
- if (gd_is_client_option (key) &&
- (op_version > ctx->client_op_version))
- ctx->client_op_version = op_version;
-
- return 0;
-}
-
-void
-gd_update_volume_op_versions (glusterd_volinfo_t *volinfo)
-{
- glusterd_conf_t *conf = NULL;
- gf_boolean_t ob_enabled = _gf_false;
-
- GF_ASSERT (volinfo);
-
- conf = THIS->private;
- GF_ASSERT (conf);
-
- /* Reset op-versions to minimum */
- volinfo->op_version = 1;
- volinfo->client_op_version = 1;
-
- dict_foreach (volinfo->dict, _update_volume_op_versions, volinfo);
-
- /* Special case for open-behind
- * If cluster op-version >= 2 and open-behind hasn't been explicitly
- * disabled, volume op-versions must be updated to account for it
- */
-
- /* TODO: Remove once we have a general way to update automatically
- * enabled features
- */
- if (conf->op_version >= 2) {
- ob_enabled = dict_get_str_boolean (volinfo->dict,
- "performance.open-behind",
- _gf_true);
- if (ob_enabled) {
-
- if (volinfo->op_version < 2)
- volinfo->op_version = 2;
- if (volinfo->client_op_version < 2)
- volinfo->client_op_version = 2;
- }
- }
-
- if (volinfo->type == GF_CLUSTER_TYPE_DISPERSE) {
- if (volinfo->op_version < GD_OP_VERSION_3_6_0)
- volinfo->op_version = GD_OP_VERSION_3_6_0;
- if (volinfo->client_op_version < GD_OP_VERSION_3_6_0)
- volinfo->client_op_version = GD_OP_VERSION_3_6_0;
- }
-
- return;
-}
-
-int
-op_version_check (xlator_t *this, int min_op_version, char *msg, int msglen)
-{
- int ret = 0;
- glusterd_conf_t *priv = NULL;
-
- GF_ASSERT (this);
- GF_ASSERT (msg);
-
- priv = this->private;
- if (priv->op_version < min_op_version) {
- snprintf (msg, msglen, "One or more nodes do not support "
- "the required op-version. Cluster op-version must "
- "atleast be %d.", min_op_version);
- gf_log (this->name, GF_LOG_ERROR, "%s", msg);
- ret = -1;
- }
- return ret;
-}
-
-
-/* A task is committed/completed once the task-id for it is cleared */
-gf_boolean_t
-gd_is_remove_brick_committed (glusterd_volinfo_t *volinfo)
-{
- GF_ASSERT (volinfo);
-
- if ((GD_OP_REMOVE_BRICK == volinfo->rebal.op) &&
- !uuid_is_null (volinfo->rebal.rebalance_id))
- return _gf_false;
-
- return _gf_true;
-}
-
-gf_boolean_t
-glusterd_is_status_tasks_op (glusterd_op_t op, dict_t *dict)
-{
- int ret = -1;
- uint32_t cmd = GF_CLI_STATUS_NONE;
- gf_boolean_t is_status_tasks = _gf_false;
-
- if (op != GD_OP_STATUS_VOLUME)
- goto out;
-
- ret = dict_get_uint32 (dict, "cmd", &cmd);
- if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR, "Failed to get opcode");
- goto out;
- }
-
- if (cmd & GF_CLI_STATUS_TASKS)
- is_status_tasks = _gf_true;
-
-out:
- return is_status_tasks;
-}
-
-int
-glusterd_compare_snap_time(struct list_head *list1, struct list_head *list2)
-{
- glusterd_snap_t *snap1 = NULL;
- glusterd_snap_t *snap2 = NULL;
- double diff_time = 0;
-
- GF_ASSERT (list1);
- GF_ASSERT (list2);
-
- snap1 = list_entry(list1, glusterd_snap_t, snap_list);
- snap2 = list_entry(list2, glusterd_snap_t, snap_list);
- diff_time = difftime(snap1->time_stamp, snap2->time_stamp);
-
- return ((int)diff_time);
-}
-
-int
-glusterd_compare_snap_vol_time(struct list_head *list1, struct list_head *list2)
-{
- glusterd_volinfo_t *snapvol1 = NULL;
- glusterd_volinfo_t *snapvol2 = NULL;
- double diff_time = 0;
-
- GF_ASSERT (list1);
- GF_ASSERT (list2);
-
- snapvol1 = list_entry(list1, glusterd_volinfo_t, snapvol_list);
- snapvol2 = list_entry(list2, glusterd_volinfo_t, snapvol_list);
- diff_time = difftime(snapvol1->snapshot->time_stamp,
- snapvol2->snapshot->time_stamp);
-
- return ((int)diff_time);
-}
-
-int32_t
-glusterd_missed_snapinfo_new (glusterd_missed_snap_info **missed_snapinfo)
-{
- glusterd_missed_snap_info *new_missed_snapinfo = NULL;
- int32_t ret = -1;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (missed_snapinfo);
-
- new_missed_snapinfo = GF_CALLOC (1, sizeof(*new_missed_snapinfo),
- gf_gld_mt_missed_snapinfo_t);
-
- if (!new_missed_snapinfo)
- goto out;
-
- INIT_LIST_HEAD (&new_missed_snapinfo->missed_snaps);
- INIT_LIST_HEAD (&new_missed_snapinfo->snap_ops);
-
- *missed_snapinfo = new_missed_snapinfo;
-
- ret = 0;
-
-out:
- gf_log (this->name, GF_LOG_TRACE, "Returning %d", ret);
- return ret;
-}
-
-int32_t
-glusterd_missed_snap_op_new (glusterd_snap_op_t **snap_op)
-{
- glusterd_snap_op_t *new_snap_op = NULL;
- int32_t ret = -1;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (snap_op);
-
- new_snap_op = GF_CALLOC (1, sizeof(*new_snap_op),
- gf_gld_mt_missed_snapinfo_t);
-
- if (!new_snap_op)
- goto out;
-
- new_snap_op->brick_num = -1;
- new_snap_op->op = -1;
- new_snap_op->status = -1;
- INIT_LIST_HEAD (&new_snap_op->snap_ops_list);
-
- *snap_op = new_snap_op;
-
- ret = 0;
-out:
- gf_log (this->name, GF_LOG_TRACE, "Returning %d", ret);
- return ret;
-}
-
-/* Tells if rebalance needs to be started for the given volume on the peer
- *
- * Rebalance should be started on a peer only if an involved brick is present on
- * the peer.
- *
- * For a normal rebalance, if any one brick of the given volume is present on
- * the peer, the rebalance process should be started.
- *
- * For a rebalance as part of a remove-brick operation, the rebalance process
- * should be started only if one of the bricks being removed is present on the
- * peer
- */
-gf_boolean_t
-gd_should_i_start_rebalance (glusterd_volinfo_t *volinfo) {
- gf_boolean_t retval = _gf_false;
- int ret = -1;
- glusterd_brickinfo_t *brick = NULL;
- int count = 0;
- int i = 0;
- char key[1023] = {0,};
- char *brickname = NULL;
-
-
- switch (volinfo->rebal.op) {
- case GD_OP_REBALANCE:
- list_for_each_entry (brick, &volinfo->bricks, brick_list) {
- if (uuid_compare (MY_UUID, brick->uuid) == 0) {
- retval = _gf_true;
- break;
- }
- }
- break;
- case GD_OP_REMOVE_BRICK:
- ret = dict_get_int32 (volinfo->rebal.dict, "count", &count);
- if (ret) {
- goto out;
- }
- for (i = 1; i <= count; i++) {
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "brick%d", i);
- ret = dict_get_str (volinfo->rebal.dict, key,
- &brickname);
- if (ret)
- goto out;
- ret = glusterd_volume_brickinfo_get_by_brick (brickname,
- volinfo,
- &brick);
- if (ret)
- goto out;
- if (uuid_compare (MY_UUID, brick->uuid) == 0) {
- retval = _gf_true;
- break;
- }
- }
- break;
- default:
- break;
- }
-
-out:
- return retval;
-}
-
-int
-glusterd_is_volume_quota_enabled (glusterd_volinfo_t *volinfo)
-{
- return (glusterd_volinfo_get_boolean (volinfo, VKEY_FEATURES_QUOTA));
-}
-
-int
-glusterd_validate_and_set_gfid (dict_t *op_ctx, dict_t *req_dict,
- char **op_errstr)
-{
- int ret = -1;
- int count = 0;
- int i = 0;
- int op_code = GF_QUOTA_OPTION_TYPE_NONE;
- uuid_t uuid1 = {0};
- uuid_t uuid2 = {0,};
- char *path = NULL;
- char key[256] = {0,};
- char *uuid1_str = NULL;
- char *uuid1_str_dup = NULL;
- char *uuid2_str = NULL;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
-
- ret = dict_get_int32 (op_ctx, "type", &op_code);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to get quota opcode");
- goto out;
- }
-
- if ((op_code != GF_QUOTA_OPTION_TYPE_LIMIT_USAGE) &&
- (op_code != GF_QUOTA_OPTION_TYPE_REMOVE)) {
- ret = 0;
- goto out;
- }
-
- ret = dict_get_str (op_ctx, "path", &path);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to get path");
- goto out;
- }
-
- ret = dict_get_int32 (op_ctx, "count", &count);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to get count");
- goto out;
- }
-
- /* If count is 0, fail the command with ENOENT.
- *
- * If count is 1, treat gfid0 as the gfid on which the operation
- * is to be performed and resume the command.
- *
- * if count > 1, get the 0th gfid from the op_ctx and,
- * compare it with the remaining 'count -1' gfids.
- * If they are found to be the same, set gfid0 in the op_ctx and
- * resume the operation, else error out.
- */
-
- if (count == 0) {
- gf_asprintf (op_errstr, "Failed to get trusted.gfid attribute "
- "on path %s. Reason : %s", path,
- strerror (ENOENT));
- ret = -1;
- goto out;
- }
-
- snprintf (key, sizeof (key) - 1, "gfid%d", 0);
-
- ret = dict_get_str (op_ctx, key, &uuid1_str);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to get key '%s'",
- key);
- goto out;
- }
-
- uuid_parse (uuid1_str, uuid1);
-
- for (i = 1; i < count; i++) {
- snprintf (key, sizeof (key)-1, "gfid%d", i);
-
- ret = dict_get_str (op_ctx, key, &uuid2_str);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to get key "
- "'%s'", key);
- goto out;
- }
-
- uuid_parse (uuid2_str, uuid2);
-
- if (uuid_compare (uuid1, uuid2)) {
- gf_asprintf (op_errstr, "gfid mismatch between %s and "
- "%s for path %s", uuid1_str, uuid2_str,
- path);
- ret = -1;
- goto out;
- }
- }
-
- if (i == count) {
- uuid1_str_dup = gf_strdup (uuid1_str);
- if (!uuid1_str_dup) {
- ret = -1;
- goto out;
- }
-
- ret = dict_set_dynstr (req_dict, "gfid", uuid1_str_dup);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to set gfid");
- GF_FREE (uuid1_str_dup);
- goto out;
- }
- } else {
- gf_log (this->name, GF_LOG_ERROR, "Failed to iterate through %d"
- " entries in the req dict", count);
- ret = -1;
- goto out;
- }
-
- ret = 0;
-out:
- return ret;
-}
-
-void
-glusterd_clean_up_quota_store (glusterd_volinfo_t *volinfo)
-{
- char voldir[PATH_MAX] = {0,};
- char quota_confpath[PATH_MAX] = {0,};
- char cksum_path[PATH_MAX] = {0,};
- xlator_t *this = NULL;
- glusterd_conf_t *conf = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- conf = this->private;
- GF_ASSERT (conf);
-
- GLUSTERD_GET_VOLUME_DIR (voldir, volinfo, conf);
-
- snprintf (quota_confpath, sizeof (quota_confpath), "%s/%s", voldir,
- GLUSTERD_VOLUME_QUOTA_CONFIG);
- snprintf (cksum_path, sizeof (cksum_path), "%s/%s", voldir,
- GLUSTERD_VOL_QUOTA_CKSUM_FILE);
-
- unlink (quota_confpath);
- unlink (cksum_path);
-
- gf_store_handle_destroy (volinfo->quota_conf_shandle);
- volinfo->quota_conf_shandle = NULL;
- volinfo->quota_conf_version = 0;
-
-}
-
-#define QUOTA_CONF_HEADER \
- "GlusterFS Quota conf | version: v%d.%d\n"
-
-int
-glusterd_store_quota_conf_skip_header (xlator_t *this, int fd)
-{
- char buf[PATH_MAX] = {0,};
-
- snprintf (buf, sizeof(buf)-1, QUOTA_CONF_HEADER, 1, 1);
- return gf_skip_header_section (fd, strlen (buf));
-}
-
-int
-glusterd_store_quota_conf_stamp_header (xlator_t *this, int fd)
-{
- char buf[PATH_MAX] = {0,};
- int buf_len = 0;
- ssize_t ret = -1;
- ssize_t written = 0;
-
- snprintf (buf, sizeof(buf)-1, QUOTA_CONF_HEADER, 1, 1);
- buf_len = strlen (buf);
- for (written = 0; written != buf_len; written += ret) {
- ret = write (fd, buf + written, buf_len - written);
- if (ret == -1) {
- goto out;
- }
- }
-
- ret = 0;
-out:
- return ret;
-}
-
-int
-glusterd_remove_auxiliary_mount (char *volname)
-{
- int ret = -1;
- char mountdir[PATH_MAX] = {0,};
- char pidfile[PATH_MAX] = {0,};
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
-
- GLUSTERFS_GET_AUX_MOUNT_PIDFILE (pidfile, volname);
-
- if (!gf_is_service_running (pidfile, NULL)) {
- gf_log (this->name, GF_LOG_DEBUG, "Aux mount of volume %s "
- "absent, hence returning", volname);
- return 0;
- }
-
- GLUSTERD_GET_QUOTA_AUX_MOUNT_PATH (mountdir, volname, "/");
- ret = gf_umount_lazy (this->name, mountdir, 1);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "umount on %s failed, "
- "reason : %s", mountdir, strerror (errno));
-
- /* Hide EBADF as it means the mount is already gone */
- if (errno == EBADF)
- ret = 0;
- }
-
- return ret;
-}
-
-/* Stops the rebalance process of the given volume
- */
-int
-gd_stop_rebalance_process (glusterd_volinfo_t *volinfo)
-{
- int ret = -1;
- xlator_t *this = NULL;
- glusterd_conf_t *conf = NULL;
- char pidfile[PATH_MAX] = {0,};
-
- GF_ASSERT (volinfo);
-
- this = THIS;
- GF_ASSERT (this);
-
- conf = this->private;
- GF_ASSERT (conf);
-
- GLUSTERD_GET_DEFRAG_PID_FILE (pidfile, volinfo, conf);
- ret = glusterd_service_stop ("rebalance", pidfile, SIGTERM, _gf_true);
-
- return ret;
-}
-
-rpc_clnt_t *
-glusterd_rpc_clnt_unref (glusterd_conf_t *conf, rpc_clnt_t *rpc)
-{
- rpc_clnt_t *ret = NULL;
-
- GF_ASSERT (conf);
- GF_ASSERT (rpc);
- synclock_unlock (&conf->big_lock);
- ret = rpc_clnt_unref (rpc);
- synclock_lock (&conf->big_lock);
-
- return ret;
-}
-
-int32_t
-glusterd_compare_volume_name(struct list_head *list1, struct list_head *list2)
-{
- glusterd_volinfo_t *volinfo1 = NULL;
- glusterd_volinfo_t *volinfo2 = NULL;
-
- volinfo1 = list_entry(list1, glusterd_volinfo_t, vol_list);
- volinfo2 = list_entry(list2, glusterd_volinfo_t, vol_list);
- return strcmp(volinfo1->volname, volinfo2->volname);
-}
-
-int32_t
-glusterd_mount_lvm_snapshot (glusterd_brickinfo_t *brickinfo,
- char *brick_mount_path)
-{
- char msg[NAME_MAX] = "";
- char mnt_opts[1024] = "";
- int32_t ret = -1;
- runner_t runner = {0, };
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (brick_mount_path);
- GF_ASSERT (brickinfo);
-
-
- runinit (&runner);
- snprintf (msg, sizeof (msg), "mount %s %s",
- brickinfo->device_path, brick_mount_path);
-
- strcpy (mnt_opts, brickinfo->mnt_opts);
-
- /* XFS file-system does not allow to mount file-system with duplicate
- * UUID. File-system UUID of snapshot and its origin volume is same.
- * Therefore to mount such a snapshot in XFS we need to pass nouuid
- * option
- */
- if (!strcmp (brickinfo->fstype, "xfs") &&
- !mntopts_exists (mnt_opts, "nouuid")) {
- if ( strlen (mnt_opts) > 0 )
- strcat (mnt_opts, ",");
- strcat (mnt_opts, "nouuid");
- }
-
-
- if ( strlen (mnt_opts) > 0 ) {
- runner_add_args (&runner, "mount", "-o", mnt_opts,
- brickinfo->device_path, brick_mount_path, NULL);
- } else {
- runner_add_args (&runner, "mount", brickinfo->device_path,
- brick_mount_path, NULL);
- }
-
- runner_log (&runner, this->name, GF_LOG_DEBUG, msg);
- ret = runner_run (&runner);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "mounting the snapshot "
- "logical device %s failed (error: %s)",
- brickinfo->device_path, strerror (errno));
- goto out;
- } else
- gf_log (this->name, GF_LOG_DEBUG, "mounting the snapshot "
- "logical device %s successful", brickinfo->device_path);
-
-out:
- gf_log (this->name, GF_LOG_TRACE, "Returning with %d", ret);
- return ret;
-}
-
-int32_t
-glusterd_umount (const char *path)
-{
- char msg[NAME_MAX] = "";
- int32_t ret = -1;
- runner_t runner = {0, };
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (path);
-
- runinit (&runner);
- snprintf (msg, sizeof (msg), "umount path %s", path);
- runner_add_args (&runner, _PATH_UMOUNT, "-f", path, NULL);
- runner_log (&runner, this->name, GF_LOG_DEBUG, msg);
- ret = runner_run (&runner);
- if (ret)
- gf_log (this->name, GF_LOG_ERROR, "umounting %s failed (%s)",
- path, strerror (errno));
-
- gf_log (this->name, GF_LOG_TRACE, "Returning with %d", ret);
- return ret;
-}
-
-int32_t
-glusterd_copy_file (const char *source, const char *destination)
-{
- int32_t ret = -1;
- xlator_t *this = NULL;
- char buffer[1024] = "";
- int src_fd = -1;
- int dest_fd = -1;
- int read_len = -1;
- struct stat stbuf = {0,};
- mode_t dest_mode = 0;
-
- this = THIS;
- GF_ASSERT (this);
-
- GF_ASSERT (source);
- GF_ASSERT (destination);
-
- /* Here is stat is made to get the file permission of source file*/
- ret = lstat (source, &stbuf);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "%s not found", source);
- goto out;
- }
-
- dest_mode = stbuf.st_mode & 0777;
-
- src_fd = open (source, O_RDONLY);
- if (src_fd < 0) {
- ret = -1;
- gf_log (this->name, GF_LOG_ERROR, "Unable to open file %s",
- source);
- goto out;
- }
-
- dest_fd = open (destination, O_CREAT | O_RDWR, dest_mode);
- if (dest_fd < 0) {
- ret = -1;
- gf_log (this->name, GF_LOG_ERROR,
- "Unble to open a file %s", destination);
- goto out;
- }
-
- do {
- ret = read (src_fd, buffer, sizeof (buffer));
- if (ret == -1) {
- gf_log (this->name, GF_LOG_ERROR, "Error reading file "
- "%s", source);
- goto out;
- }
- read_len = ret;
- if (read_len == 0)
- break;
-
- ret = write (dest_fd, buffer, read_len);
- if (ret != read_len) {
- gf_log (this->name, GF_LOG_ERROR, "Error writing in "
- "file %s", destination);
- goto out;
- }
- } while (ret > 0);
-out :
- if (src_fd > 0)
- close (src_fd);
-
- if (dest_fd > 0)
- close (dest_fd);
- return ret;
-}
-
-int32_t
-glusterd_copy_folder (const char *source, const char *destination)
-{
- DIR *dir_ptr = NULL;
- struct dirent *direntp = NULL;
- int32_t ret = -1;
- char src_path[PATH_MAX] = "";
- char dest_path[PATH_MAX] = "";
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
-
- GF_ASSERT (source);
- GF_ASSERT (destination);
-
- dir_ptr = opendir (source);
- if (!dir_ptr) {
- gf_log (this->name, GF_LOG_ERROR, "Unable to open %s", source);
- goto out;
- }
-
- while ((direntp = readdir (dir_ptr)) != NULL) {
- if (strcmp (direntp->d_name, ".") == 0 ||
- strcmp (direntp->d_name, "..") == 0)
- continue;
- ret = snprintf (src_path, sizeof (src_path), "%s/%s",
- source, direntp->d_name);
- if (ret < 0)
- goto out;
-
- ret = snprintf (dest_path, sizeof (dest_path), "%s/%s",
- destination, direntp->d_name);
- if (ret < 0)
- goto out;
-
- ret = glusterd_copy_file (src_path, dest_path);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Could not copy "
- "%s to %s", src_path, dest_path);
- goto out;
- }
- }
-out:
- if (dir_ptr)
- closedir (dir_ptr);
-
- return ret;
-}
-
-int32_t
-glusterd_get_geo_rep_session (char *slave_key, char *origin_volname,
- dict_t *gsync_slaves_dict, char *session,
- char *slave)
-{
- int32_t ret = -1;
- char *token = NULL;
- char *temp = NULL;
- char *ip = NULL;
- char *buffer = NULL;
- xlator_t *this = NULL;
- char *slave_temp = NULL;
- char *save_ptr = NULL;
-
- this = THIS;
- GF_ASSERT (this);
-
- GF_ASSERT (slave_key);
- GF_ASSERT (origin_volname);
- GF_ASSERT (gsync_slaves_dict);
-
- ret = dict_get_str (gsync_slaves_dict, slave_key, &buffer);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to "
- "get value for key %s", slave_key);
- goto out;
- }
-
- temp = gf_strdup (buffer);
- if (!temp) {
- ret = -1;
- goto out;
- }
-
- token = strtok_r (temp, "/", &save_ptr);
-
- token = strtok_r (NULL, ":", &save_ptr);
- if (!token) {
- ret = -1;
- goto out;
- }
- token++;
-
- ip = gf_strdup (token);
- if (!ip) {
- ret = -1;
- goto out;
- }
-
- token = strtok_r (NULL, "\0", &save_ptr);
- if (!token) {
- ret = -1;
- goto out;
- }
- token++;
-
- slave_temp = gf_strdup (token);
- if (!slave) {
- ret = -1;
- goto out;
- }
-
- ret = snprintf (session, PATH_MAX, "%s_%s_%s",
- origin_volname, ip, slave_temp);
- if (ret < 0) /* Negative value is an error */
- goto out;
-
- ret = snprintf (slave, PATH_MAX, "%s::%s", ip, slave_temp);
- if (ret < 0) {
- goto out;
- }
-
- ret = 0; /* Success */
-
-out:
- if (temp)
- GF_FREE (temp);
-
- if (ip)
- GF_FREE (ip);
-
- if (slave_temp)
- GF_FREE (slave_temp);
-
- return ret;
-}
-
-int32_t
-glusterd_copy_quota_files (glusterd_volinfo_t *src_vol,
- glusterd_volinfo_t *dest_vol) {
-
- int32_t ret = -1;
- char src_dir[PATH_MAX] = "";
- char dest_dir[PATH_MAX] = "";
- char src_path[PATH_MAX] = "";
- char dest_path[PATH_MAX] = "";
- xlator_t *this = NULL;
- glusterd_conf_t *priv = NULL;
- struct stat stbuf = {0,};
-
- this = THIS;
- GF_ASSERT (this);
- priv = this->private;
- GF_ASSERT (priv);
-
- GF_ASSERT (src_vol);
- GF_ASSERT (dest_vol);
-
- GLUSTERD_GET_VOLUME_DIR (src_dir, src_vol, priv);
-
- GLUSTERD_GET_VOLUME_DIR (dest_dir, dest_vol, priv);
-
- ret = snprintf (src_path, sizeof (src_path), "%s/quota.conf",
- src_dir);
- if (ret < 0)
- goto out;
-
- /* quota.conf is not present if quota is not enabled, Hence ignoring
- * the absence of this file
- */
- ret = lstat (src_path, &stbuf);
- if (ret) {
- ret = 0;
- gf_log (this->name, GF_LOG_DEBUG, "%s not found", src_path);
- goto out;
- }
-
- ret = snprintf (dest_path, sizeof (dest_path), "%s/quota.conf",
- dest_dir);
- if (ret < 0)
- goto out;
-
- ret = glusterd_copy_file (src_path, dest_path);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to copy %s in %s",
- src_path, dest_path);
- goto out;
- }
-
- ret = snprintf (src_path, sizeof (src_path), "%s/quota.cksum",
- src_dir);
- if (ret < 0)
- goto out;
-
- /* If quota.conf is present and quota.cksum is not present, then
- * that scenario is considered as invalid, hence error out.
- */
- ret = lstat (src_path, &stbuf);
- if (ret) {
- ret = -1;
- gf_log (this->name, GF_LOG_ERROR, "%s not found", src_path);
- goto out;
- }
-
- ret = snprintf (dest_path, sizeof (dest_path), "%s/quota.cksum",
- dest_dir);
- if (ret < 0)
- goto out;
-
- ret = glusterd_copy_file (src_path, dest_path);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to copy %s in %s",
- src_path, dest_path);
- goto out;
- }
-
-out:
- return ret;
-
-}
-
-int32_t
-glusterd_restore_geo_rep_files (glusterd_volinfo_t *snap_vol)
-{
- int32_t ret = -1;
- char src_path[PATH_MAX] = "";
- char dest_path[PATH_MAX] = "";
- xlator_t *this = NULL;
- char *origin_volname = NULL;
- glusterd_volinfo_t *origin_vol = NULL;
- int i = 0;
- char key[PATH_MAX] = "";
- char session[PATH_MAX] = "";
- char slave[PATH_MAX] = "";
- char snapgeo_dir[PATH_MAX] = "";
- glusterd_conf_t *priv = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- priv = this->private;
- GF_ASSERT (priv);
-
- GF_ASSERT (snap_vol);
-
- origin_volname = gf_strdup (snap_vol->parent_volname);
- if (!origin_volname) {
- ret = -1;
- goto out;
- }
-
- ret = glusterd_volinfo_find (origin_volname, &origin_vol);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Unable to fetch "
- "volinfo for volname %s", origin_volname);
- goto out;
- }
-
- for (i = 1 ; i <= snap_vol->gsync_slaves->count; i++) {
- ret = snprintf (key, sizeof (key), "slave%d", i);
- if (ret < 0) {
- goto out;
- }
-
- /* "origin_vol" is used here because geo-replication saves
- * the session in the form of master_ip_slave.
- * As we need the master volume to be same even after
- * restore, we are passing the origin volume name.
- *
- * "snap_vol->gsync_slaves" contain the slave information
- * when the snapshot was taken, hence we have to restore all
- * those slaves information when we do snapshot restore.
- */
- ret = glusterd_get_geo_rep_session (key, origin_vol->volname,
- snap_vol->gsync_slaves,
- session, slave);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to get geo-rep session");
- goto out;
- }
-
- GLUSTERD_GET_SNAP_GEO_REP_DIR(snapgeo_dir, snap_vol->snapshot,
- priv);
- ret = snprintf (src_path, sizeof (src_path),
- "%s/%s", snapgeo_dir, session);
- if (ret < 0)
- goto out;
-
- ret = snprintf (dest_path, sizeof (dest_path),
- "%s/%s/%s", priv->workdir, GEOREP,
- session);
- if (ret < 0)
- goto out;
-
- ret = glusterd_copy_folder (src_path, dest_path);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Could not copy "
- "%s to %s", src_path, dest_path);
- goto out;
- }
- }
-out:
- if (origin_volname)
- GF_ASSERT (origin_volname);
-
- return ret;
-}
-
-/* This is an utility function which will recursively delete
- * a folder and its contents.
- *
- * @param delete_path folder to be deleted.
- *
- * @return 0 on success and -1 on failure.
- */
-int
-glusterd_recursive_rmdir (const char *delete_path)
-{
- int ret = -1;
- char path [PATH_MAX] = {0,};
- struct stat st = {0,};
- DIR *dir = NULL;
- struct dirent *entry = NULL;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- GF_VALIDATE_OR_GOTO (this->name, delete_path, out);
-
- dir = opendir (delete_path);
- if (!dir) {
- gf_log (this->name, GF_LOG_DEBUG, "Failed to open directory %s."
- " Reason : %s", delete_path, strerror (errno));
- ret = 0;
- goto out;
- }
-
- glusterd_for_each_entry (entry, dir);
- while (entry) {
- snprintf (path, PATH_MAX, "%s/%s", delete_path, entry->d_name);
- ret = lstat (path, &st);
- if (ret == -1) {
- gf_log (this->name, GF_LOG_DEBUG, "Failed to stat "
- "entry %s : %s", path, strerror (errno));
- goto out;
- }
-
- if (S_ISDIR (st.st_mode))
- ret = glusterd_recursive_rmdir (path);
- else
- ret = unlink (path);
-
- if (ret) {
- gf_log (this->name, GF_LOG_DEBUG, " Failed to remove "
- "%s. Reason : %s", path, strerror (errno));
- }
-
- gf_log (this->name, GF_LOG_DEBUG, "%s %s",
- ret ? "Failed to remove":"Removed",
- entry->d_name);
-
- glusterd_for_each_entry (entry, dir);
- }
-
- ret = closedir (dir);
- if (ret) {
- gf_log (this->name, GF_LOG_DEBUG, "Failed to close dir %s. "
- "Reason : %s", delete_path, strerror (errno));
- }
-
- ret = rmdir (delete_path);
- if (ret) {
- gf_log (this->name, GF_LOG_DEBUG, "Failed to rmdir: %s,err: %s",
- delete_path, strerror (errno));
- }
-
-out:
- return ret;
-}
-
-gf_boolean_t
-glusterd_volume_quorum_calculate (glusterd_volinfo_t *volinfo, dict_t *dict,
- int down_count, gf_boolean_t first_brick_on,
- int8_t snap_force, int quorum_count,
- char *quorum_type, char **op_errstr)
-{
- gf_boolean_t quorum_met = _gf_false;
- char err_str[PATH_MAX] = {0, };
- xlator_t *this = NULL;
- int up_count = 0;
-
- this = THIS;
- GF_ASSERT (this);
-
- if (!volinfo || !dict) {
- gf_log (this->name, GF_LOG_WARNING, "input parameters NULL");
- goto out;
- }
-
- if (!snap_force && down_count) {
- snprintf (err_str, sizeof (err_str), "One or more bricks may "
- "be down. Use the force option ");
- gf_log (this->name, GF_LOG_ERROR, "%s", err_str);
- *op_errstr = gf_strdup (err_str);
- goto out;
- }
-
- up_count = volinfo->dist_leaf_count - down_count;
-
- if (quorum_type && !strcmp (quorum_type, "fixed")) {
- if (up_count >= quorum_count) {
- quorum_met = _gf_true;
- goto out;
- }
- } else {
- if ((GF_CLUSTER_TYPE_DISPERSE != volinfo->type) &&
- (volinfo->dist_leaf_count % 2 == 0)) {
- if ((up_count > quorum_count) ||
- ((up_count == quorum_count) && first_brick_on)) {
- quorum_met = _gf_true;
- goto out;
- }
- } else {
- if (up_count >= quorum_count) {
- quorum_met = _gf_true;
- goto out;
- }
- }
- }
-
- if (!quorum_met) {
- snprintf (err_str, sizeof (err_str), "quorum is not met");
- gf_log (this->name, GF_LOG_WARNING, "%s", err_str);
- *op_errstr = gf_strdup (err_str);
- }
-
-out:
- return quorum_met;
-}
-
-int32_t
-glusterd_volume_quorum_check (glusterd_volinfo_t *volinfo, int64_t index,
- dict_t *dict, char *key_prefix,
- int8_t snap_force, int quorum_count,
- char *quorum_type, char **op_errstr)
-{
- int ret = 0;
- xlator_t *this = NULL;
- int64_t i = 0;
- int64_t j = 0;
- char key[1024] = {0, };
- int down_count = 0;
- gf_boolean_t first_brick_on = _gf_true;
- glusterd_conf_t *priv = NULL;
- gf_boolean_t quorum_met = _gf_false;
- int distribute_subvols = 0;
- int32_t brick_online = 0;
- char err_str[PATH_MAX] = {0, };
-
- this = THIS;
- GF_ASSERT (this);
- priv = this->private;
- GF_ASSERT (priv);
-
- if (!volinfo || !dict) {
- gf_log (this->name, GF_LOG_WARNING, "input parameters NULL");
- goto out;
- }
-
- if ((!glusterd_is_volume_replicate (volinfo) ||
- volinfo->replica_count < 3) &&
- (GF_CLUSTER_TYPE_DISPERSE != volinfo->type)) {
- for (i = 0; i < volinfo->brick_count ; i++) {
- /* for a pure distribute volume, and replica volume
- with replica count 2, quorum is not met if even
- one of its subvolumes is down
- */
- snprintf (key, sizeof (key), "%s%"PRId64".brick%"PRId64".status",
- key_prefix, index, i);
- ret = dict_get_int32 (dict, key, &brick_online);
- if (ret || !brick_online) {
- ret = 1;
- snprintf (err_str, sizeof (err_str), "quorum "
- "is not met");
- gf_log (this->name, GF_LOG_ERROR, "%s",
- err_str);
- *op_errstr = gf_strdup (err_str);
- goto out;
- }
- }
- ret = 0;
- quorum_met = _gf_true;
- } else {
- distribute_subvols = volinfo->brick_count /
- volinfo->dist_leaf_count;
- for (j = 0; j < distribute_subvols; j++) {
- // by default assume quorum is not met
- /* TODO: Handle distributed striped replicate volumes
- Currently only distributed replicate volumes are
- handled.
- */
- ret = 1;
- quorum_met = _gf_false;
- for (i = 0; i < volinfo->dist_leaf_count; i++) {
- snprintf (key, sizeof (key),
- "%s%"PRId64".brick%"PRId64".status", key_prefix,
- index,
- (j * volinfo->dist_leaf_count) + i);
- ret = dict_get_int32 (dict, key, &brick_online);
- if (ret || !brick_online) {
- if (i == 0)
- first_brick_on = _gf_false;
- down_count++;
- }
- }
-
- quorum_met = glusterd_volume_quorum_calculate (volinfo,
- dict,
- down_count,
- first_brick_on,
- snap_force,
- quorum_count,
- quorum_type,
- op_errstr);
- // goto out if quorum is not met
- if (!quorum_met) {
- ret = -1;
- goto out;
- }
-
- down_count = 0;
- first_brick_on = _gf_true;
- }
- }
-
- if (quorum_met) {
- gf_log (this->name, GF_LOG_DEBUG, "volume %s is in quorum",
- volinfo->volname);
- ret = 0;
- }
-
-out:
- return ret;
-}
-
-int32_t
-glusterd_snap_quorum_check_for_create (dict_t *dict, gf_boolean_t snap_volume,
- char **op_errstr,
- struct list_head *peers_list)
-{
- int8_t snap_force = 0;
- int32_t force = 0;
- char err_str[PATH_MAX] = {0, };
- int quorum_count = 0;
- char *quorum_type = NULL;
- int32_t tmp = 0;
- char key_prefix[PATH_MAX] = {0, };
- char *snapname = NULL;
- glusterd_snap_t *snap = NULL;
- glusterd_volinfo_t *volinfo = NULL;
- char *volname = NULL;
- int64_t volcount = 0;
- char key[PATH_MAX] = {0, };
- int64_t i = 0;
- int32_t ret = -1;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
-
- if (!dict) {
- gf_log (this->name, GF_LOG_ERROR, "dict is NULL");
- goto out;
- }
-
- if (snap_volume) {
- ret = dict_get_str (dict, "snapname", &snapname);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "failed to "
- "get snapname");
- goto out;
- }
-
- snap = glusterd_find_snap_by_name (snapname);
- if (!snap) {
- gf_log (this->name, GF_LOG_ERROR, "failed to "
- "get the snapshot %s", snapname);
- ret = -1;
- goto out;
- }
- }
-
- ret = dict_get_int32 (dict, "flags", &force);
- if (!ret && (force & GF_CLI_FLAG_OP_FORCE))
- snap_force = 1;
- if (!snap_force) {
- /* Do a quorum check of glusterds also. Because,
- the missed snapshot information will be saved
- by glusterd and if glusterds are not in
- quorum, then better fail the snapshot
- */
- if (!does_gd_meet_server_quorum (this, peers_list, _gf_true)) {
- snprintf (err_str, sizeof (err_str),
- "glusterds are not in quorum");
- gf_log (this->name, GF_LOG_WARNING, "%s",
- err_str);
- *op_errstr = gf_strdup (err_str);
- ret = -1;
- goto out;
- }
-
- gf_log (this->name, GF_LOG_DEBUG, "glusterds are in "
- "quorum");
- }
-
- ret = dict_get_int64 (dict, "volcount", &volcount);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "failed to get "
- "volcount");
- goto out;
- }
-
- for (i = 1; i <= volcount; i++) {
- snprintf (key, sizeof (key), "%s%"PRId64,
- snap_volume?"snap-volname":"volname", i);
- ret = dict_get_str (dict, key, &volname);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "failed to "
- "get volname");
- goto out;
- }
-
- if (snap_volume) {
- ret = glusterd_snap_volinfo_find (volname, snap,
- &volinfo);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "failed to get snap volume %s "
- "for snap %s", volname,
- snapname);
- goto out;
- }
- } else {
- ret = glusterd_volinfo_find (volname, &volinfo);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "failed to find the volume %s",
- volname);
- goto out;
- }
- }
-
- /* for replicate volumes with replica count equal to or
- greater than 3, do quorum check by getting what type
- of quorum rule has been set by getting the volume
- option set. If getting the option fails, then assume
- default.
- AFR does this:
- if quorum type is "auto":
- - for odd numner of bricks (n), n/2 + 1
- bricks should be present
- - for even number of bricks n, n/2 bricks
- should be present along with the 1st
- subvolume
- if quorum type is not "auto":
- - get the quorum count from dict with the
- help of the option "cluster.quorum-count"
- if the option is not there in the dict,
- then assume quorum type is auto and follow
- the above method.
- For non replicate volumes quorum is met only if all
- the bricks of the volume are online
- */
-
- if (GF_CLUSTER_TYPE_REPLICATE == volinfo->type) {
- if (volinfo->replica_count %2 == 0)
- quorum_count = volinfo->replica_count/2;
- else
- quorum_count =
- volinfo->replica_count/2 + 1;
- } else if (GF_CLUSTER_TYPE_DISPERSE == volinfo->type) {
- quorum_count = volinfo->disperse_count -
- volinfo->redundancy_count;
- } else {
- quorum_count = volinfo->brick_count;
- }
-
- ret = dict_get_str (volinfo->dict,
- "cluster.quorum-type",
- &quorum_type);
- if (!ret && !strcmp (quorum_type, "fixed")) {
- ret = dict_get_int32 (volinfo->dict,
- "cluster.quorum-count",
- &tmp);
- /* if quorum-type option is not found in the
- dict assume auto quorum type. i.e n/2 + 1.
- The same assumption is made when quorum-count
- option cannot be obtained from the dict (even
- if the quorum-type option is not set to auto,
- the behavior is set to the default behavior)
- */
- if (!ret) {
- /* for dispersed volumes, only allow quorums
- equal or larger than minimum functional
- value.
- */
- if ((GF_CLUSTER_TYPE_DISPERSE !=
- volinfo->type) ||
- (tmp >= quorum_count)) {
- quorum_count = tmp;
- } else {
- gf_log(this->name, GF_LOG_INFO,
- "Ignoring small quorum-count "
- "(%d) on dispersed volume", tmp);
- quorum_type = NULL;
- }
- }
- else
- quorum_type = NULL;
- }
-
- snprintf (key_prefix, sizeof (key_prefix),
- "%s", snap_volume?"snap-vol":"vol");
-
- ret = glusterd_volume_quorum_check (volinfo, i, dict,
- key_prefix,
- snap_force,
- quorum_count,
- quorum_type,
- op_errstr);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING, "volume %s "
- "is not in quorum", volinfo->volname);
- goto out;
- }
- }
-out:
- return ret;
-}
-
-int32_t
-glusterd_snap_quorum_check (dict_t *dict, gf_boolean_t snap_volume,
- char **op_errstr,
- struct list_head *peers_list)
-{
- int32_t ret = -1;
- xlator_t *this = NULL;
- int32_t snap_command = 0;
- char err_str[PATH_MAX] = {0, };
-
- this = THIS;
- GF_ASSERT (this);
-
- if (!dict) {
- gf_log (this->name, GF_LOG_ERROR, "dict is NULL");
- goto out;
- }
-
-
- ret = dict_get_int32 (dict, "type", &snap_command);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "unable to get the type of "
- "the snapshot command");
- goto out;
- }
-
- switch (snap_command) {
- case GF_SNAP_OPTION_TYPE_CREATE:
- ret = glusterd_snap_quorum_check_for_create (dict, snap_volume,
- op_errstr,
- peers_list);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING, "Quorum check"
- "failed during snapshot create command");
- goto out;
- }
- break;
- case GF_SNAP_OPTION_TYPE_DELETE:
- case GF_SNAP_OPTION_TYPE_RESTORE:
- if (!does_gd_meet_server_quorum (this, peers_list, _gf_true)) {
- ret = -1;
- snprintf (err_str, sizeof (err_str),
- "glusterds are not in quorum");
- gf_log (this->name, GF_LOG_WARNING, "%s",
- err_str);
- *op_errstr = gf_strdup (err_str);
- goto out;
- }
-
- gf_log (this->name, GF_LOG_DEBUG, "glusterds are in "
- "quorum");
- break;
- default:
- break;
- }
-
- ret = 0;
-
-out:
- return ret;
-}
-
-static int
-gd_default_synctask_cbk (int ret, call_frame_t *frame, void *opaque)
-{
- glusterd_conf_t *priv = THIS->private;
- synclock_unlock (&priv->big_lock);
- return ret;
-}
-
-void
-glusterd_launch_synctask (synctask_fn_t fn, void *opaque)
-{
- xlator_t *this = NULL;
- glusterd_conf_t *priv = NULL;
- int ret = -1;
-
- this = THIS;
- priv = this->private;
-
- synclock_lock (&priv->big_lock);
- ret = synctask_new (this->ctx->env, fn, gd_default_synctask_cbk, NULL,
- opaque);
- if (ret)
- gf_log (this->name, GF_LOG_CRITICAL, "Failed to spawn bricks"
- " and other volume related services");
-}
-
-/*
- * glusterd_enable_default_options enable certain options by default on the
- * given volume based on the cluster op-version. This is called only during
- * volume create or during volume reset
- *
- * @volinfo - volume on which to enable the default options
- * @option - option to be set to default. If NULL, all possible options will be
- * set to default
- *
- * Returns 0 on sucess and -1 on failure. If @option is given, but doesn't match
- * any of the options that could be set, it is a success.
- */
-/*
- * TODO: Make this able to parse the volume-set table to set options
- * Currently, the check and set for any option which wants to make use of this
- * 'framework' needs to be done here manually. This would mean more work for the
- * developer. This little extra work can be avoided if we make it possible to
- * parse the volume-set table to get the options which could be set and their
- * default values
- */
-int
-glusterd_enable_default_options (glusterd_volinfo_t *volinfo, char *option)
-{
- int ret = 0;
- xlator_t *this = NULL;
- glusterd_conf_t *conf = NULL;
-
- this = THIS;
- GF_ASSERT (this);
-
- GF_VALIDATE_OR_GOTO (this->name, volinfo, out);
-
- conf = this->private;
- GF_ASSERT (conf);
-
- if (conf->op_version >= GD_OP_VERSION_3_6_0) {
- /* Set needed volume options in volinfo->dict
- * For ex.,
- *
- * if (!option || !strcmp("someoption", option) {
- * ret = dict_set_str(volinfo->dict, "someoption", "on");
- * ...
- * }
- * */
- }
-out:
- return ret;
-}
-
-void
-glusterd_get_rebalance_volfile (glusterd_volinfo_t *volinfo,
- char *path, int path_len)
-{
- char workdir[PATH_MAX] = {0,};
- glusterd_conf_t *priv = THIS->private;
-
- GLUSTERD_GET_VOLUME_DIR (workdir, volinfo, priv);
-
- snprintf (path, path_len, "%s/%s-rebalance.vol", workdir,
- volinfo->volname);
-}
-
-/* Snapd functions */
-int
-glusterd_is_snapd_enabled (glusterd_volinfo_t *volinfo)
-{
- int ret = 0;
- xlator_t *this = THIS;
-
- ret = dict_get_str_boolean (volinfo->dict, "features.uss", -2);
- if (ret == -2) {
- gf_log (this->name, GF_LOG_DEBUG, "Key features.uss not "
- "present in the dict for volume %s", volinfo->volname);
- ret = 0;
-
- } else if (ret == -1) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to get 'features.uss'"
- " from dict for volume %s", volinfo->volname);
- }
-
- return ret;
-}
-
-void
-glusterd_get_snapd_rundir (glusterd_volinfo_t *volinfo,
- char *path, int path_len)
-{
- char workdir [PATH_MAX] = {0,};
- glusterd_conf_t *priv = THIS->private;
-
- GLUSTERD_GET_VOLUME_DIR (workdir, volinfo, priv);
-
- snprintf (path, path_len, "%s/run", workdir);
-}
-
-void
-glusterd_get_snapd_volfile (glusterd_volinfo_t *volinfo,
- char *path, int path_len)
-{
- char workdir [PATH_MAX] = {0,};
- glusterd_conf_t *priv = THIS->private;
-
- GLUSTERD_GET_VOLUME_DIR (workdir, volinfo, priv);
-
- snprintf (path, path_len, "%s/%s-snapd.vol", workdir,
- volinfo->volname);
-}
-
-void
-glusterd_get_snapd_pidfile (glusterd_volinfo_t *volinfo,
- char *path, int path_len)
-{
- char rundir [PATH_MAX] = {0,};
-
- glusterd_get_snapd_rundir (volinfo, rundir, sizeof (rundir));
-
- snprintf (path, path_len, "%s/%s-snapd.pid", rundir, volinfo->volname);
-}
-
-void
-glusterd_set_snapd_socket_filepath (glusterd_volinfo_t *volinfo,
- char *path, int path_len)
-{
- char sockfilepath[PATH_MAX] = {0,};
- char rundir[PATH_MAX] = {0,};
-
- glusterd_get_snapd_rundir (volinfo, rundir, sizeof (rundir));
- snprintf (sockfilepath, sizeof (sockfilepath), "%s/run-%s",
- rundir, uuid_utoa (MY_UUID));
-
- glusterd_set_socket_filepath (sockfilepath, path, path_len);
-}
-
-gf_boolean_t
-glusterd_is_snapd_running (glusterd_volinfo_t *volinfo)
-{
- char pidfile [PATH_MAX] = {0,};
- int pid = -1;
- glusterd_conf_t *priv = THIS->private;
-
- glusterd_get_snapd_pidfile (volinfo, pidfile,
- sizeof (pidfile));
-
- return gf_is_service_running (pidfile, &pid);
-}
-
-int
-glusterd_restart_snapds (glusterd_conf_t *priv)
-{
- glusterd_volinfo_t *volinfo = NULL;
- int ret = 0;
- xlator_t *this = THIS;
-
- list_for_each_entry (volinfo, &priv->volumes, vol_list) {
- if (volinfo->status == GLUSTERD_STATUS_STARTED &&
- glusterd_is_snapd_enabled (volinfo)) {
- ret = glusterd_snapd_start (volinfo,
- _gf_false);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Couldn't start snapd for "
- "vol: %s", volinfo->volname);
- goto out;
- }
- }
- }
-out:
- return ret;
-}
-
-gf_boolean_t
-glusterd_is_snapd_online (glusterd_volinfo_t *volinfo)
-{
- return volinfo->snapd.online;
-}
-
-void
-glusterd_snapd_set_online_status (glusterd_volinfo_t *volinfo,
- gf_boolean_t status)
-{
- volinfo->snapd.online = status;
-}
-
-static inline void
-glusterd_snapd_set_rpc (glusterd_volinfo_t *volinfo, struct rpc_clnt *rpc)
-{
- volinfo->snapd.rpc = rpc;
-}
-
-int32_t
-glusterd_snapd_connect (glusterd_volinfo_t *volinfo, char *socketpath)
-{
- int ret = 0;
- dict_t *options = NULL;
- struct rpc_clnt *rpc = NULL;
- glusterd_conf_t *priv = THIS->private;
-
- rpc = glusterd_snapd_get_rpc (volinfo);
-
- if (rpc == NULL) {
- /* Setting frame-timeout to 10mins (600seconds).
- * Unix domain sockets ensures that the connection is reliable.
- * The default timeout of 30mins used for unreliable network
- * connections is too long for unix domain socket connections.
- */
- ret = rpc_transport_unix_options_build (&options, socketpath,
- 600);
- if (ret)
- goto out;
-
- ret = dict_set_str(options,
- "transport.socket.ignore-enoent", "on");
- if (ret)
- goto out;
-
- glusterd_volinfo_ref (volinfo);
-
- synclock_unlock (&priv->big_lock);
- ret = glusterd_rpc_create (&rpc, options,
- glusterd_snapd_rpc_notify,
- volinfo);
- synclock_lock (&priv->big_lock);
- if (ret)
- goto out;
-
- (void) glusterd_snapd_set_rpc (volinfo, rpc);
- }
-out:
- return ret;
-}
-
-int32_t
-glusterd_snapd_disconnect (glusterd_volinfo_t *volinfo)
-{
- struct rpc_clnt *rpc = NULL;
- glusterd_conf_t *priv = THIS->private;
-
- rpc = glusterd_snapd_get_rpc (volinfo);
-
- (void) glusterd_snapd_set_rpc (volinfo, NULL);
-
- if (rpc)
- glusterd_rpc_clnt_unref (priv, rpc);
-
- return 0;
-}
-
-int32_t
-glusterd_snapd_start (glusterd_volinfo_t *volinfo, gf_boolean_t wait)
-{
- 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 logdir[PATH_MAX] = {0,};
- char volfile[PATH_MAX] = {0,};
- char glusterd_uuid [1024] = {0,};
- char rundir[PATH_MAX] = {0,};
- char sockfpath[PATH_MAX] = {0,};
- char volfileid[256] = {0};
- char *volfileserver = NULL;
- char valgrind_logfile[PATH_MAX] = {0};
- int snapd_port = 0;
- char *volname = volinfo->volname;
- char snapd_id [PATH_MAX] = {0,};
- char msg [1024] = {0,};
-
- this = THIS;
- GF_ASSERT(this);
-
- if (glusterd_is_snapd_running (volinfo)) {
- ret = 0;
- goto connect;
- }
-
- priv = this->private;
-
- glusterd_get_snapd_rundir (volinfo, rundir, sizeof (rundir));
- ret = mkdir (rundir, 0777);
-
- if ((ret == -1) && (EEXIST != errno)) {
- gf_log (this->name, GF_LOG_ERROR, "Unable to create rundir %s",
- rundir);
- goto out;
- }
-
- glusterd_get_snapd_pidfile (volinfo, pidfile, sizeof (pidfile));
- glusterd_get_snapd_volfile (volinfo, volfile, sizeof (volfile));
-
- ret = sys_access (volfile, F_OK);
- if (ret) {
- gf_log (this->name, GF_LOG_DEBUG,
- "snapd Volfile %s is not present", volfile);
-
- /* If glusterd is down on one of the nodes and during
- * that time "USS is enabled" for the first time. After some
- * time when the glusterd which was down comes back it tries
- * to look for the snapd volfile and it does not find snapd
- * volfile and because of this starting of snapd fails.
- * Therefore, if volfile is not present then create a fresh
- * volfile.
- */
- ret = glusterd_create_snapd_volfile (volinfo);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Couldn't create "
- "snapd volfile for volume: %s",
- volinfo->volname);
- goto out;
- }
- }
-
- snprintf (logdir, PATH_MAX, "%s/snaps/%s",
- DEFAULT_LOG_FILE_DIRECTORY, volname);
- ret = mkdir_p (logdir, 0755, _gf_true);
- if ((ret == -1) && (EEXIST != errno)) {
- gf_log (this->name, GF_LOG_ERROR, "Unable to create logdir %s",
- logdir);
- goto out;
- }
-
- snprintf (logfile, PATH_MAX, "%s/snapd.log", logdir);
-
- snprintf (volfileid, sizeof (volfileid), "snapd/%s", volname);
- glusterd_set_snapd_socket_filepath (volinfo, sockfpath,
- sizeof (sockfpath));
-
- if (dict_get_str (this->options, "transport.socket.bind-address",
- &volfileserver) != 0) {
- volfileserver = "localhost";
- }
-
- runinit (&runner);
-
- if (priv->valgrind) {
- snprintf (valgrind_logfile, PATH_MAX, "%s/valgrind-snapd.log",
- logdir);
-
- runner_add_args (&runner, "valgrind", "--leak-check=full",
- "--trace-children=yes", "--track-origins=yes",
- NULL);
- runner_argprintf (&runner, "--log-file=%s", valgrind_logfile);
- }
-
- snprintf (snapd_id, sizeof (snapd_id), "snapd-%s", volname);
- runner_add_args (&runner, SBIN_DIR"/glusterfsd",
- "-s", volfileserver,
- "--volfile-id", volfileid,
- "-p", pidfile,
- "-l", logfile,
- "--brick-name", snapd_id,
- "-S", sockfpath, NULL);
-
- snapd_port = volinfo->snapd.port;
- if (!snapd_port) {
- snapd_port = pmap_registry_alloc (THIS);
- if (!snapd_port) {
- snprintf (msg, sizeof (msg), "Could not allocate port "
- "for snapd service for volume %s", volname);
-
- runner_log (&runner, this->name, GF_LOG_DEBUG, msg);
- ret = -1;
- goto out;
- }
- }
-
- runner_add_arg (&runner, "--brick-port");
- runner_argprintf (&runner, "%d", snapd_port);
- runner_add_arg (&runner, "--xlator-option");
- runner_argprintf (&runner, "%s-server.listen-port=%d",
- volname, snapd_port);
-
- snprintf (msg, sizeof (msg),
- "Starting the snapd service for volume %s", volname);
- runner_log (&runner, this->name, GF_LOG_DEBUG, msg);
-
- if (!wait) {
- ret = runner_run_nowait (&runner);
- } else {
- synclock_unlock (&priv->big_lock);
- {
- ret = runner_run (&runner);
- }
- synclock_lock (&priv->big_lock);
- }
-
- volinfo->snapd.port = snapd_port;
-
-connect:
- if (ret == 0)
- glusterd_snapd_connect (volinfo, sockfpath);
-
-out:
- return ret;
-}
-
-int
-glusterd_snapd_stop (glusterd_volinfo_t *volinfo)
-{
- char pidfile [PATH_MAX] = {0,};
- char sockfpath [PATH_MAX] = {0,};
- glusterd_conf_t *priv = THIS->private;
- int ret = 0;
-
- (void)glusterd_snapd_disconnect (volinfo);
-
- if (!glusterd_is_snapd_running (volinfo))
- goto out;
-
- glusterd_get_snapd_pidfile (volinfo, pidfile, sizeof (pidfile));
- ret = glusterd_service_stop ("snapd", pidfile, SIGTERM, _gf_true);
-
- if (ret == 0) {
- glusterd_set_snapd_socket_filepath (volinfo, sockfpath,
- sizeof (sockfpath));
- (void)glusterd_unlink_file (sockfpath);
- }
-out:
- return ret;
-}
-
-int
-glusterd_handle_snapd_option (glusterd_volinfo_t *volinfo)
-{
- int ret = 0;
- xlator_t *this = THIS;
-
- if (volinfo->is_snap_volume)
- return 0;
-
- ret = glusterd_is_snapd_enabled (volinfo);
- if (ret == -1) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to read volume "
- "options");
- goto out;
- }
-
- if (ret) {
- if (!glusterd_is_volume_started (volinfo)) {
- if (glusterd_is_snapd_running (volinfo)) {
- ret = glusterd_snapd_stop (volinfo);
- if (ret)
- gf_log (this->name, GF_LOG_ERROR,
- "Couldn't stop snapd for "
- "volume: %s",
- volinfo->volname);
- } else {
- /* Since snapd is not running set ret to 0 */
- ret = 0;
- }
- goto out;
- }
-
- ret = glusterd_create_snapd_volfile (volinfo);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Couldn't create "
- "snapd volfile for volume: %s",
- volinfo->volname);
- goto out;
- }
-
- ret = glusterd_snapd_start (volinfo, _gf_false);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Couldn't start "
- "snapd for volume: %s", volinfo->volname);
- goto out;
- }
-
- } else if (glusterd_is_snapd_running (volinfo)) {
- ret = glusterd_snapd_stop (volinfo);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Couldn't stop snapd for volume: %s",
- volinfo->volname);
- goto out;
- }
- volinfo->snapd.port = 0;
- }
-
-out:
- return ret;
-}
-
-int32_t
-glusterd_is_snap_soft_limit_reached (glusterd_volinfo_t *volinfo, dict_t *dict)
-{
- int32_t ret = -1;
- uint64_t opt_max_hard = GLUSTERD_SNAPS_MAX_HARD_LIMIT;
- uint64_t opt_max_soft = GLUSTERD_SNAPS_DEF_SOFT_LIMIT_PERCENT;
- uint64_t limit = 0;
- int auto_delete = 0;
- uint64_t effective_max_limit = 0;
- xlator_t *this = NULL;
- glusterd_conf_t *priv = NULL;
-
- GF_ASSERT (volinfo);
- GF_ASSERT (dict);
-
- this = THIS;
- GF_ASSERT (this);
- priv = this->private;
- GF_ASSERT (priv);
-
- /* config values snap-max-hard-limit and snap-max-soft-limit are
- * optional and hence we are not erroring out if values are not
- * present
- */
- gd_get_snap_conf_values_if_present (priv->opts, &opt_max_hard,
- &opt_max_soft);
-
- /* "auto-delete" might not be set by user explicitly,
- * in that case it's better to consider the default value.
- * Hence not erroring out if Key is not found.
- */
- auto_delete = dict_get_str_boolean (priv->opts,
- GLUSTERD_STORE_KEY_SNAP_AUTO_DELETE,
- _gf_false);
-
- if (volinfo->snap_max_hard_limit < opt_max_hard)
- effective_max_limit = volinfo->snap_max_hard_limit;
- else
- effective_max_limit = opt_max_hard;
-
- limit = (opt_max_soft * effective_max_limit)/100;
-
- if (volinfo->snap_count >= limit && auto_delete != _gf_true) {
- gf_log (this->name, GF_LOG_WARNING, "Soft-limit "
- "(value = %"PRIu64") of volume %s is reached. "
- "Snapshot creation is not possible once effective "
- "hard-limit (value = %"PRIu64") is reached.",
- limit, volinfo->volname, effective_max_limit);
-
- ret = dict_set_int8 (dict, "soft-limit-reach",
- _gf_true);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to "
- "set soft limit exceed flag in "
- "response dictionary");
- }
- goto out;
- }
- ret = 0;
-out :
- return ret;
-}
-
-/* This function initializes the parameter sys_hard_limit,
- * sys_soft_limit and auto_delete value to the value set
- * in dictionary, If value is not present then it is
- * initialized to default values. Hence this function does not
- * return any values.
- */
-void
-gd_get_snap_conf_values_if_present (dict_t *dict, uint64_t *sys_hard_limit,
- uint64_t *sys_soft_limit)
-{
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
-
- GF_ASSERT (dict);
-
- /* "snap-max-hard-limit" might not be set by user explicitly,
- * in that case it's better to consider the default value.
- * Hence not erroring out if Key is not found.
- */
- if (dict_get_uint64 (dict, GLUSTERD_STORE_KEY_SNAP_MAX_HARD_LIMIT,
- sys_hard_limit)) {
- gf_log (this->name, GF_LOG_DEBUG, "%s is not present in"
- "dictionary",
- GLUSTERD_STORE_KEY_SNAP_MAX_HARD_LIMIT);
- }
-
- /* "snap-max-soft-limit" might not be set by user explicitly,
- * in that case it's better to consider the default value.
- * Hence not erroring out if Key is not found.
- */
- if (dict_get_uint64 (dict, GLUSTERD_STORE_KEY_SNAP_MAX_SOFT_LIMIT,
- sys_soft_limit)) {
- gf_log (this->name, GF_LOG_DEBUG, "%s is not present in"
- "dictionary",
- GLUSTERD_STORE_KEY_SNAP_MAX_SOFT_LIMIT);
- }
-}
-
-/* This function will update the backend file-system
- * type and the mount options in origin and snap brickinfo.
- * This will be later used to perform file-system specific operation
- * during LVM snapshot.
- *
- * @param brick_path brickpath for which fstype to be found
- * @param brickinfo brickinfo of snap/origin volume
- * @return 0 on success and -1 on failure
- */
-int
-glusterd_update_mntopts (char *brick_path, glusterd_brickinfo_t *brickinfo)
-{
- int32_t ret = -1;
- char *mnt_pt = NULL;
- char buff [PATH_MAX] = "";
- char msg [PATH_MAX] = "";
- char *cmd = NULL;
- struct mntent *entry = NULL;
- struct mntent save_entry = {0,};
- runner_t runner = {0,};
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (brick_path);
- GF_ASSERT (brickinfo);
-
- ret = glusterd_get_brick_root (brick_path, &mnt_pt);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "getting the root "
- "of the brick (%s) failed ", brick_path);
- goto out;
- }
-
- entry = glusterd_get_mnt_entry_info (mnt_pt, buff, sizeof (buff),
- &save_entry);
- if (!entry) {
- gf_log (this->name, GF_LOG_ERROR, "getting the mount entry for "
- "the brick (%s) failed", brick_path);
- ret = -1;
- goto out;
- }
-
- strcpy (brickinfo->fstype, entry->mnt_type);
- strcpy (brickinfo->mnt_opts, entry->mnt_opts);
-
- ret = 0;
-out:
- GF_FREE (mnt_pt);
- return ret;
-}
-
-
-gf_boolean_t
-glusterd_have_peers ()
-{
- xlator_t *this = NULL;
- glusterd_conf_t *conf = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- conf = this->private;
- GF_ASSERT (conf);
-
- return !list_empty (&conf->peers);
-}
-
-gf_boolean_t
-mntopts_exists (const char *str, const char *opts)
-{
- char *dup_val = NULL;
- char *savetok = NULL;
- char *token = NULL;
- gf_boolean_t exists = _gf_false;
-
- GF_ASSERT (opts);
-
- if (!str || !strlen(str))
- goto out;
-
- dup_val = gf_strdup (str);
- if (!dup_val)
- goto out;
-
- token = strtok_r (dup_val, ",", &savetok);
- while (token) {
- if (!strcmp (token, opts)) {
- exists = _gf_true;
- goto out;
- }
- token = strtok_r (NULL, ",", &savetok);
- }
-
-out:
- GF_FREE (dup_val);
- return exists;
-}
-
-void
-gd_cleanup_local_xaction_peers_list (struct list_head *xact_peers)
-{
- glusterd_local_peers_t *local_peers = NULL;
- glusterd_local_peers_t *tmp = NULL;
-
- GF_ASSERT (xact_peers);
-
- if (list_empty (xact_peers))
- return;
-
- list_for_each_entry_safe (local_peers, tmp, xact_peers,
- op_peers_list) {
- GF_FREE (local_peers);
- /* local_peers->peerinfo need not be freed because it does not
- * ownership of peerinfo, but merely refer it */
- }
-}
diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.h b/xlators/mgmt/glusterd/src/glusterd-utils.h
deleted file mode 100644
index 49783fb816f..00000000000
--- a/xlators/mgmt/glusterd/src/glusterd-utils.h
+++ /dev/null
@@ -1,932 +0,0 @@
-/*
- Copyright (c) 2006-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 _GLUSTERD_UTILS_H
-#define _GLUSTERD_UTILS_H
-
-#ifndef _CONFIG_H
-#define _CONFIG_H
-#include "config.h"
-#endif
-
-#include <pthread.h>
-#include "uuid.h"
-
-#include "glusterfs.h"
-#include "xlator.h"
-#include "logging.h"
-#include "call-stub.h"
-#include "fd.h"
-#include "byte-order.h"
-#include "glusterd.h"
-#include "rpc-clnt.h"
-#include "protocol-common.h"
-
-#include "glusterfs3-xdr.h"
-#include "glusterd-peer-utils.h"
-
-#define GLUSTERD_SOCK_DIR "/var/run"
-#define GLUSTERD_ASSIGN_BRICKID_TO_BRICKINFO(brickinfo, volinfo, brickid) do {\
- sprintf (brickinfo->brick_id, "%s-client-%d",\
- volinfo->volname, brickid);\
-} while (0)
-
-#define glusterd_quorum_count(peerinfo, inquorum_count, active_count, _exit)\
- if (peerinfo->quorum_contrib == QUORUM_WAITING)\
- goto _exit;\
- if (_is_contributing_to_quorum (peerinfo->quorum_contrib))\
- inquorum_count = inquorum_count + 1;\
- if (active_count && (peerinfo->quorum_contrib == QUORUM_UP))\
- *active_count = *active_count + 1;\
-
-#define list_for_each_local_xaction_peers(xact_peer, xact_peers_head) \
- glusterd_local_peers_t *pos = NULL; \
- for (pos = list_entry ((xact_peers_head)->next, \
- glusterd_local_peers_t, op_peers_list), \
- xact_peer = pos->peerinfo; \
- &pos->op_peers_list != (xact_peers_head); \
- pos = list_entry(pos->op_peers_list.next, \
- glusterd_local_peers_t, op_peers_list), \
- xact_peer = pos->peerinfo)
-
-struct glusterd_lock_ {
- uuid_t owner;
- time_t timestamp;
-};
-
-typedef struct glusterd_dict_ctx_ {
- dict_t *dict;
- int opt_count;
- char *key_name;
- char *val_name;
- char *prefix;
-} glusterd_dict_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);
-
-int32_t
-glusterd_lock (uuid_t new_owner);
-
-int32_t
-glusterd_unlock (uuid_t owner);
-
-int32_t
-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);
-
-int
-glusterd_to_cli (rpcsvc_request_t *req, gf_cli_rsp *arg, struct iovec *payload,
- int payloadcount, struct iobref *iobref, xdrproc_t xdrproc,
- dict_t *dict);
-
-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);
-int32_t
-glusterd_volinfo_new (glusterd_volinfo_t **volinfo);
-
-int32_t
-glusterd_volinfo_dup (glusterd_volinfo_t *volinfo,
- glusterd_volinfo_t **dup_volinfo,
- gf_boolean_t set_userauth);
-
-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);
-
-int32_t
-glusterd_brickinfo_new (glusterd_brickinfo_t **brickinfo);
-
-int32_t
-glusterd_brickinfo_new_from_brick (char *brick, glusterd_brickinfo_t **brickinfo);
-
-int32_t
-glusterd_snap_volinfo_find (char *volname, glusterd_snap_t *snap,
- glusterd_volinfo_t **volinfo);
-int32_t
-glusterd_snap_volinfo_find_from_parent_volname (char *origin_volname,
- glusterd_snap_t *snap,
- glusterd_volinfo_t **volinfo);
-
-int32_t
-glusterd_volinfo_find (char *volname, glusterd_volinfo_t **volinfo);
-
-int
-glusterd_volinfo_find_by_volume_id (uuid_t volume_id, glusterd_volinfo_t **volinfo);
-
-int
-glusterd_snap_volinfo_find_by_volume_id (uuid_t volume_id,
- glusterd_volinfo_t **volinfo);
-
-int32_t
-glusterd_service_stop(const char *service, char *pidfile, int sig,
- gf_boolean_t force_kill);
-
-int
-glusterd_get_next_available_brickid (glusterd_volinfo_t *volinfo);
-
-int32_t
-glusterd_resolve_brick (glusterd_brickinfo_t *brickinfo);
-
-int32_t
-glusterd_volume_start_glusterfs (glusterd_volinfo_t *volinfo,
- glusterd_brickinfo_t *brickinfo,
- gf_boolean_t wait);
-
-int32_t
-glusterd_volume_stop_glusterfs (glusterd_volinfo_t *volinfo,
- glusterd_brickinfo_t *brickinfo,
- gf_boolean_t del_brick);
-
-glusterd_volinfo_t *
-glusterd_volinfo_ref (glusterd_volinfo_t *volinfo);
-
-glusterd_volinfo_t *
-glusterd_volinfo_unref (glusterd_volinfo_t *volinfo);
-
-int32_t
-glusterd_volinfo_delete (glusterd_volinfo_t *volinfo);
-
-int32_t
-glusterd_brickinfo_delete (glusterd_brickinfo_t *brickinfo);
-
-gf_boolean_t
-glusterd_is_cli_op_req (int32_t op);
-
-int32_t
-glusterd_volume_brickinfo_get_by_brick (char *brick,
- glusterd_volinfo_t *volinfo,
- glusterd_brickinfo_t **brickinfo);
-
-int32_t
-glusterd_add_volumes_to_export_dict (dict_t **peer_data);
-
-int32_t
-glusterd_compare_friend_data (dict_t *peer_data, int32_t *status,
- char *hostname);
-
-int
-glusterd_compute_cksum (glusterd_volinfo_t *volinfo,
- gf_boolean_t is_quota_conf);
-
-void
-glusterd_get_nodesvc_volfile (char *server, char *workdir,
- char *volfile, size_t len);
-
-gf_boolean_t
-glusterd_is_nodesvc_running ();
-
-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 ();
-
-int32_t
-glusterd_quotad_start ();
-
-int32_t
-glusterd_quotad_start_wait ();
-
-int32_t
-glusterd_quotad_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_online_status (char *server, gf_boolean_t status);
-
-gf_boolean_t
-glusterd_is_nodesvc_online (char *server);
-
-int
-glusterd_remote_hostname_get (rpcsvc_request_t *req,
- char *remote_host, int len);
-int32_t
-glusterd_import_friend_volumes (dict_t *peer_data);
-void
-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_check_generate_start_quotad (void);
-
-int
-glusterd_check_generate_start_quotad_wait (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
-glusterd_add_volume_to_dict (glusterd_volinfo_t *volinfo,
- dict_t *dict, int32_t count,
- char *prefix);
-int
-glusterd_get_brickinfo (xlator_t *this, const char *brickname,
- int port, gf_boolean_t localhost,
- glusterd_brickinfo_t **brickinfo);
-
-void
-glusterd_set_brick_status (glusterd_brickinfo_t *brickinfo,
- gf_brick_status_t status);
-
-gf_boolean_t
-glusterd_is_brick_started (glusterd_brickinfo_t *brickinfo);
-
-int
-glusterd_friend_brick_belongs (glusterd_volinfo_t *volinfo,
- glusterd_brickinfo_t *brickinfo, void *uuid);
-int
-glusterd_all_volume_cond_check (glusterd_condition_func func, int status,
- void *ctx);
-int
-glusterd_brick_start (glusterd_volinfo_t *volinfo,
- glusterd_brickinfo_t *brickinfo,
- gf_boolean_t wait);
-int
-glusterd_brick_stop (glusterd_volinfo_t *volinfo,
- glusterd_brickinfo_t *brickinfo,
- gf_boolean_t del_brick);
-
-int
-glusterd_is_defrag_on (glusterd_volinfo_t *volinfo);
-
-int32_t
-glusterd_volinfo_bricks_delete (glusterd_volinfo_t *volinfo);
-
-int
-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);
-int
-glusterd_is_rb_started (glusterd_volinfo_t *volinfo);
-
-int
-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_rb_check_bricks (glusterd_volinfo_t *volinfo,
- glusterd_brickinfo_t *src_brick,
- glusterd_brickinfo_t *dst_brick);
-
-int
-glusterd_check_and_set_brick_xattr (char *host, char *path, uuid_t uuid,
- char **op_errstr, gf_boolean_t is_force);
-
-int
-glusterd_validate_and_create_brickpath (glusterd_brickinfo_t *brickinfo,
- uuid_t volume_id, char **op_errstr,
- gf_boolean_t is_force);
-int
-glusterd_sm_tr_log_transition_add (glusterd_sm_tr_log_t *log,
- int old_state, int new_state,
- int event);
-int
-glusterd_sm_tr_log_init (glusterd_sm_tr_log_t *log,
- char * (*state_name_get) (int),
- char * (*event_name_get) (int),
- size_t size);
-void
-glusterd_sm_tr_log_delete (glusterd_sm_tr_log_t *log);
-
-int
-glusterd_sm_tr_log_add_to_dict (dict_t *dict,
- glusterd_sm_tr_log_t *circular_log);
-int
-glusterd_remove_pending_entry (struct list_head *list, void *elem);
-int
-glusterd_clear_pending_nodes (struct list_head *list);
-int32_t
-glusterd_brick_connect (glusterd_volinfo_t *volinfo,
- glusterd_brickinfo_t *brickinfo, char *socketpath);
-int32_t
-glusterd_brick_disconnect (glusterd_brickinfo_t *brickinfo);
-int32_t
-glusterd_delete_volume (glusterd_volinfo_t *volinfo);
-int32_t
-glusterd_delete_brick (glusterd_volinfo_t* volinfo,
- glusterd_brickinfo_t *brickinfo);
-
-int32_t
-glusterd_delete_all_bricks (glusterd_volinfo_t* volinfo);
-
-int
-glusterd_spawn_daemons (void *opaque);
-
-int
-glusterd_restart_gsyncds (glusterd_conf_t *conf);
-
-int
-glusterd_start_gsync (glusterd_volinfo_t *master_vol, char *slave,
- char *path_list, char *conf_path,
- char *glusterd_uuid_str,
- char **op_errstr, gf_boolean_t is_pause);
-int
-glusterd_get_local_brickpaths (glusterd_volinfo_t *volinfo,
- char **pathlist);
-
-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_add_snapd_to_dict (glusterd_volinfo_t *volinfo,
- 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);
-
-int
-glusterd_quotad_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);
-int
-glusterd_friend_contains_vol_bricks (glusterd_volinfo_t *volinfo,
- uuid_t friend_uuid);
-int
-glusterd_friend_remove_cleanup_vols (uuid_t uuid);
-
-int
-glusterd_get_client_filepath (char *filepath,
- glusterd_volinfo_t *volinfo,
- gf_transport_type type);
-int
-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);
-
-int
-glusterd_get_dist_leaf_count (glusterd_volinfo_t *volinfo);
-
-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);
-
-int
-glusterd_check_topology_identical (const char *filename1,
- const char *filename2,
- gf_boolean_t *identical);
-
-void
-glusterd_volinfo_reset_defrag_stats (glusterd_volinfo_t *volinfo);
-int
-glusterd_volset_help (dict_t *dict, char **op_errstr);
-
-int32_t
-glusterd_sync_use_rsp_dict (dict_t *aggr, dict_t *rsp_dict);
-int32_t
-glusterd_gsync_use_rsp_dict (dict_t *aggr, dict_t *rsp_dict, char *op_errstr);
-int32_t
-glusterd_rb_use_rsp_dict (dict_t *aggr, dict_t *rsp_dict);
-int
-glusterd_profile_volume_use_rsp_dict (dict_t *aggr, dict_t *rsp_dict);
-int
-glusterd_volume_status_copy_to_op_ctx_dict (dict_t *aggr, dict_t *rsp_dict);
-int
-glusterd_volume_rebalance_use_rsp_dict (dict_t *aggr, dict_t *rsp_dict);
-int
-glusterd_volume_heal_use_rsp_dict (dict_t *aggr, dict_t *rsp_dict);
-int
-glusterd_use_rsp_dict (dict_t *aggr, dict_t *rsp_dict);
-int
-glusterd_sys_exec_output_rsp_dict (dict_t *aggr, dict_t *rsp_dict);
-int
-glusterd_snap_use_rsp_dict (dict_t *aggr, dict_t *rsp_dict);
-int32_t
-glusterd_handle_node_rsp (dict_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);
-int
-glusterd_volume_rebalance_use_rsp_dict (dict_t *aggr, dict_t *rsp_dict);
-int
-glusterd_volume_heal_use_rsp_dict (dict_t *aggr, dict_t *rsp_dict);
-
-int32_t
-glusterd_check_if_quota_trans_enabled (glusterd_volinfo_t *volinfo);
-int
-glusterd_volume_quota_copy_to_op_ctx_dict (dict_t *aggr, dict_t *rsp);
-int
-_profile_volume_add_brick_rsp (dict_t *this, char *key, data_t *value,
- void *data);
-int
-glusterd_profile_volume_brick_rsp (void *pending_entry,
- dict_t *rsp_dict, dict_t *op_ctx,
- char **op_errstr, gd_node_type type);
-
-int32_t
-glusterd_set_originator_uuid (dict_t *dict);
-
-/* Should be used only when an operation is in progress, as that is the only
- * time a lock_owner is set
- */
-gf_boolean_t
-is_origin_glusterd (dict_t *dict);
-
-gf_boolean_t
-glusterd_is_quorum_changed (dict_t *options, char *option, char *value);
-
-int
-glusterd_do_quorum_action ();
-
-int
-glusterd_get_quorum_cluster_counts (xlator_t *this, int *active_count,
- int *quorum_count,
- struct list_head *peer_list,
- gf_boolean_t _local__xaction_peers);
-
-int
-glusterd_get_next_global_opt_version_str (dict_t *opts, char **version_str);
-gf_boolean_t
-glusterd_is_quorum_option (char *option);
-gf_boolean_t
-glusterd_is_volume_in_server_quorum (glusterd_volinfo_t *volinfo);
-gf_boolean_t
-glusterd_is_any_volume_in_server_quorum (xlator_t *this);
-gf_boolean_t
-does_gd_meet_server_quorum (xlator_t *this,
- struct list_head *peers_list,
- gf_boolean_t _local__xaction_peers);
-
-int
-glusterd_generate_and_set_task_id (dict_t *dict, char *key);
-
-int
-glusterd_validate_and_set_gfid (dict_t *op_ctx, dict_t *req_dict,
- char **op_errstr);
-
-int
-glusterd_copy_uuid_to_dict (uuid_t uuid, dict_t *dict, char *key);
-
-gf_boolean_t
-glusterd_is_same_address (char *name1, char *name2);
-
-void
-gd_update_volume_op_versions (glusterd_volinfo_t *volinfo);
-
-int
-op_version_check (xlator_t *this, int min_op_version, char *msg, int msglen);
-
-gf_boolean_t
-gd_is_remove_brick_committed (glusterd_volinfo_t *volinfo);
-
-int
-glusterd_get_slave_details_confpath (glusterd_volinfo_t *volinfo,
- dict_t *dict, char **slave_url,
- char **slave_host, char **slave_vol,
- char **conf_path, char **op_errstr);
-
-int
-glusterd_get_slave_info (char *slave,
- char **slave_url, char **hostname,
- char **slave_vol, char **op_errstr);
-
-int
-glusterd_get_statefile_name (glusterd_volinfo_t *volinfo, char *slave,
- char *conf_path, char **statefile,
- gf_boolean_t *is_template_in_use);
-
-int
-glusterd_gsync_read_frm_status (char *path, char *buf, size_t blen);
-
-int
-glusterd_create_status_file (char *master, char *slave, char *slave_url,
- char *slave_vol, char *status);
-
-int
-glusterd_check_restart_gsync_session (glusterd_volinfo_t *volinfo, char *slave,
- dict_t *resp_dict, char *path_list,
- char *conf_path, gf_boolean_t is_force);
-
-int
-glusterd_check_gsync_running_local (char *master, char *slave,
- char *conf_path,
- gf_boolean_t *is_run);
-
-gf_boolean_t
-glusterd_is_status_tasks_op (glusterd_op_t op, dict_t *dict);
-
-gf_boolean_t
-gd_should_i_start_rebalance (glusterd_volinfo_t *volinfo);
-
-int
-glusterd_is_volume_quota_enabled (glusterd_volinfo_t *volinfo);
-
-gf_boolean_t
-glusterd_all_volumes_with_quota_stopped ();
-
-int
-glusterd_reconfigure_quotad ();
-
-void
-glusterd_clean_up_quota_store (glusterd_volinfo_t *volinfo);
-
-int
-glusterd_store_quota_conf_skip_header (xlator_t *this, int fd);
-
-int
-glusterd_store_quota_conf_stamp_header (xlator_t *this, int fd);
-
-int
-glusterd_remove_auxiliary_mount (char *volname);
-
-gf_boolean_t
-glusterd_status_has_tasks (int cmd);
-
-int
-gd_stop_rebalance_process (glusterd_volinfo_t *volinfo);
-
-rpc_clnt_t *
-glusterd_rpc_clnt_unref (glusterd_conf_t *conf, rpc_clnt_t *rpc);
-
-int32_t
-glusterd_compare_volume_name(struct list_head *, struct list_head *);
-
-char*
-glusterd_get_brick_mount_device (char *brick_path);
-
-struct mntent *
-glusterd_get_mnt_entry_info (char *mnt_pt, char *buff, int buflen,
- struct mntent *entry_ptr);
-
-int
-glusterd_get_brick_root (char *path, char **mount_point);
-
-
-int
-glusterd_compare_snap_time(struct list_head *, struct list_head *);
-
-int
-glusterd_compare_snap_vol_time(struct list_head *, struct list_head *);
-
-int32_t
-glusterd_snap_volinfo_restore (dict_t *dict, dict_t *rsp_dict,
- glusterd_volinfo_t *new_volinfo,
- glusterd_volinfo_t *snap_volinfo,
- int32_t volcount);
-
-int32_t
-glusterd_lvm_snapshot_remove (dict_t *rsp_dict, glusterd_volinfo_t *snap_vol);
-
-int32_t
-glusterd_missed_snapinfo_new (glusterd_missed_snap_info **missed_snapinfo);
-
-int32_t
-glusterd_missed_snap_op_new (glusterd_snap_op_t **snap_op);
-
-int32_t
-glusterd_add_missed_snaps_to_dict (dict_t *rsp_dict,
- glusterd_volinfo_t *snap_vol,
- glusterd_brickinfo_t *brickinfo,
- int32_t brick_number, int32_t op);
-
-int32_t
-glusterd_add_missed_snaps_to_export_dict (dict_t *peer_data);
-
-int32_t
-glusterd_import_friend_missed_snap_list (dict_t *peer_data);
-
-int
-gd_restore_snap_volume (dict_t *dict, dict_t *rsp_dict,
- glusterd_volinfo_t *orig_vol,
- glusterd_volinfo_t *snap_vol,
- int32_t volcount);
-
-int32_t
-glusterd_mount_lvm_snapshot (glusterd_brickinfo_t *brickinfo,
- char *brick_mount_path);
-
-int32_t
-glusterd_umount (const char *path);
-
-int32_t
-glusterd_add_snapshots_to_export_dict (dict_t *peer_data);
-
-int32_t
-glusterd_compare_friend_snapshots (dict_t *peer_data,
- glusterd_peerinfo_t *peerinfo);
-
-int32_t
-glusterd_snapobject_delete (glusterd_snap_t *snap);
-
-int32_t
-glusterd_snap_volume_remove (dict_t *rsp_dict,
- glusterd_volinfo_t *snap_vol,
- gf_boolean_t remove_lvm,
- gf_boolean_t force);
-
-int32_t
-glusterd_store_create_snap_dir (glusterd_snap_t *snap);
-
-int32_t
-glusterd_copy_file (const char *source, const char *destination);
-
-int32_t
-glusterd_copy_folder (const char *source, const char *destination);
-
-int32_t
-glusterd_get_geo_rep_session (char *slave_key, char *origin_volname,
- dict_t *gsync_slaves_dict, char *session,
- char *slave);
-
-int32_t
-glusterd_restore_geo_rep_files (glusterd_volinfo_t *snap_vol);
-
-gf_boolean_t
-gd_vol_is_geo_rep_active (glusterd_volinfo_t *volinfo);
-
-int32_t
-glusterd_copy_quota_files (glusterd_volinfo_t *src_vol,
- glusterd_volinfo_t *dest_vol);
-
-int
-glusterd_recursive_rmdir (const char *delete_path);
-
-int32_t
-glusterd_get_brick_mount_dir (char *brickpath, char *hostname, char *mount_dir);
-
-int32_t
-glusterd_aggr_brick_mount_dirs (dict_t *aggr, dict_t *rsp_dict);
-
-int32_t
-glusterd_take_lvm_snapshot (glusterd_brickinfo_t *brickinfo,
- char *origin_brick_path);
-
-int32_t
-glusterd_snap_quorum_check (dict_t *dict, gf_boolean_t snap_volume,
- char **op_errstr,
- struct list_head *peers_list);
-
-int32_t
-glusterd_snap_quorum_check_for_create (dict_t *dict, gf_boolean_t snap_volume,
- char **op_errstr,
- struct list_head *peers_list);
-
-int32_t
-glusterd_volume_quorum_check (glusterd_volinfo_t *volinfo, int64_t index,
- dict_t *dict, char *key_prefix,
- int8_t snap_force, int32_t quorum_count,
- char *quorum_type, char **op_errstr);
-
-gf_boolean_t
-glusterd_volume_quorum_calculate (glusterd_volinfo_t *volinfo, dict_t *dict,
- int down_count, gf_boolean_t first_brick_on,
- int8_t snap_force, int32_t quorum_count,
- char *quorum_type, char **op_errstr);
-
-int
-glusterd_merge_brick_status (dict_t *dst, dict_t *src);
-
-int32_t
-glusterd_snap_brick_create (glusterd_volinfo_t *snap_volinfo,
- glusterd_brickinfo_t *brickinfo,
- int32_t brick_count);
-
-void
-glusterd_launch_synctask (synctask_fn_t fn, void *opaque);
-
-int
-glusterd_enable_default_options (glusterd_volinfo_t *volinfo, char *option);
-
-int
-glusterd_snapshot_restore_cleanup (dict_t *rsp_dict,
- glusterd_volinfo_t *volinfo,
- glusterd_snap_t *snap);
-
-int
-glusterd_unlink_file (char *sock_file_path);
-
-/* Snapd functions */
-int
-glusterd_handle_snapd_option (glusterd_volinfo_t *volinfo);
-
-int32_t
-glusterd_snapd_disconnect (glusterd_volinfo_t *volinfo);
-
-void
-glusterd_get_snapd_dir (glusterd_volinfo_t *volinfo,
- char *path, int path_len);
-
-void
-glusterd_get_snapd_rundir (glusterd_volinfo_t *volinfo,
- char *path, int path_len);
-
-void
-glusterd_get_snapd_volfile (glusterd_volinfo_t *volinfo,
- char *path, int path_len);
-
-void
-glusterd_get_snapd_pidfile (glusterd_volinfo_t *volinfo,
- char *path, int path_len);
-
-void
-glusterd_set_snapd_socket_filepath (glusterd_volinfo_t *volinfo,
- char *path, int path_len);
-
-gf_boolean_t
-glusterd_is_snapd_running (glusterd_volinfo_t *volinfo);
-
-int
-glusterd_snapd_stop (glusterd_volinfo_t *volinfo);
-
-int
-glusterd_snapd_start (glusterd_volinfo_t *volinfo, gf_boolean_t wait);
-
-int
-glusterd_is_snapd_enabled (glusterd_volinfo_t *volinfo);
-
-gf_boolean_t
-glusterd_is_snapd_online (glusterd_volinfo_t *volinfo);
-
-void
-glusterd_snapd_set_online_status (glusterd_volinfo_t *volinfo,
- gf_boolean_t status);
-
-int
-glusterd_restart_snapds (glusterd_conf_t *priv);
-/* End snapd functions */
-
-int32_t
-glusterd_check_and_set_config_limit (glusterd_conf_t *priv);
-
-int32_t
-glusterd_is_snap_soft_limit_reached (glusterd_volinfo_t *volinfo,
- dict_t *dict);
-
-int32_t
-glusterd_find_brick_mount_path (char *brick_path, int32_t brick_count,
- char **brick_mount_path);
-/*
- * Function to retrieve list of snap volnames and their uuids
- */
-int glusterd_snapshot_get_volnames_uuids (dict_t *dict,
- char *volname, gf_getsnap_name_uuid_rsp *snap_info_rsp);
-
-int
-glusterd_update_mntopts (char *brick_path, glusterd_brickinfo_t *brickinfo);
-
-int
-glusterd_update_fs_label (glusterd_brickinfo_t *brickinfo);
-
-void
-gd_get_snap_conf_values_if_present (dict_t *opts, uint64_t *sys_hard_limit,
- uint64_t *sys_soft_limit);
-
-gf_boolean_t
-glusterd_have_peers ();
-
-gf_boolean_t
-mntopts_exists (const char *str, const char *opts);
-
-void
-glusterd_get_rebalance_volfile (glusterd_volinfo_t *volinfo,
- char *path, int path_len);
-
-void
-gd_cleanup_local_xaction_peers_list (struct list_head *peers);
-
-#endif
diff --git a/xlators/mgmt/glusterd/src/glusterd-volgen.c b/xlators/mgmt/glusterd/src/glusterd-volgen.c
deleted file mode 100644
index 90e22bec5c3..00000000000
--- a/xlators/mgmt/glusterd/src/glusterd-volgen.c
+++ /dev/null
@@ -1,4820 +0,0 @@
-/*
- Copyright (c) 2010-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 <fnmatch.h>
-#include <sys/wait.h>
-#include <dlfcn.h>
-#include <utime.h>
-
-#if (HAVE_LIB_XML)
-#include <libxml/encoding.h>
-#include <libxml/xmlwriter.h>
-#endif
-
-#include "xlator.h"
-#include "glusterd.h"
-#include "defaults.h"
-#include "logging.h"
-#include "dict.h"
-#include "graph-utils.h"
-#include "glusterd-store.h"
-#include "glusterd-hooks.h"
-#include "trie.h"
-#include "glusterd-mem-types.h"
-#include "cli1-xdr.h"
-#include "glusterd-volgen.h"
-#include "glusterd-op-sm.h"
-#include "glusterd-utils.h"
-#include "run.h"
-#include "options.h"
-
-extern struct volopt_map_entry glusterd_volopt_map[];
-
-/*********************************************
- *
- * xlator generation / graph manipulation API
- *
- *********************************************/
-
-
-struct volgen_graph {
- char **errstr;
- glusterfs_graph_t graph;
-};
-typedef struct volgen_graph volgen_graph_t;
-
-static void
-set_graph_errstr (volgen_graph_t *graph, const char *str)
-{
- if (!graph->errstr)
- return;
-
- *graph->errstr = gf_strdup (str);
-}
-
-static xlator_t *
-xlator_instantiate_va (const char *type, const char *format, va_list arg)
-{
- xlator_t *xl = NULL;
- char *volname = NULL;
- int ret = 0;
-
- ret = gf_vasprintf (&volname, format, arg);
- if (ret < 0) {
- volname = NULL;
-
- goto error;
- }
-
- xl = GF_CALLOC (1, sizeof (*xl), gf_common_mt_xlator_t);
- if (!xl)
- goto error;
- ret = xlator_set_type_virtual (xl, type);
- if (ret)
- goto error;
- xl->options = get_new_dict();
- if (!xl->options)
- goto error;
- xl->name = volname;
- INIT_LIST_HEAD (&xl->volume_options);
-
- xl->ctx = THIS->ctx;
-
- return xl;
-
- error:
- gf_log ("", GF_LOG_ERROR, "creating xlator of type %s failed",
- type);
- GF_FREE (volname);
- if (xl)
- xlator_destroy (xl);
-
- return NULL;
-}
-
-#ifdef __not_used_as_of_now_
-static xlator_t *
-xlator_instantiate (const char *type, const char *format, ...)
-{
- va_list arg;
- xlator_t *xl;
-
- va_start (arg, format);
- xl = xlator_instantiate_va (type, format, arg);
- va_end (arg);
-
- return xl;
-}
-#endif
-
-static int
-volgen_xlator_link (xlator_t *pxl, xlator_t *cxl)
-{
- int ret = 0;
-
- ret = glusterfs_xlator_link (pxl, cxl);
- if (ret == -1) {
- gf_log ("", GF_LOG_ERROR,
- "Out of memory, cannot link xlators %s <- %s",
- pxl->name, cxl->name);
- }
-
- return ret;
-}
-
-static int
-volgen_graph_link (volgen_graph_t *graph, xlator_t *xl)
-{
- int ret = 0;
-
- /* no need to care about graph->top here */
- if (graph->graph.first)
- ret = volgen_xlator_link (xl, graph->graph.first);
- if (ret == -1) {
- gf_log ("", GF_LOG_ERROR, "failed to add graph entry %s",
- xl->name);
-
- return -1;
- }
-
- return 0;
-}
-
-static xlator_t *
-volgen_graph_add_as (volgen_graph_t *graph, const char *type,
- const char *format, ...)
-{
- va_list arg;
- xlator_t *xl = NULL;
-
- va_start (arg, format);
- xl = xlator_instantiate_va (type, format, arg);
- va_end (arg);
-
- if (!xl)
- return NULL;
-
- if (volgen_graph_link (graph, xl)) {
- xlator_destroy (xl);
-
- return NULL;
- } else
- glusterfs_graph_set_first (&graph->graph, xl);
-
- return xl;
-}
-
-static xlator_t *
-volgen_graph_add_nolink (volgen_graph_t *graph, const char *type,
- const char *format, ...)
-{
- va_list arg;
- xlator_t *xl = NULL;
-
- va_start (arg, format);
- xl = xlator_instantiate_va (type, format, arg);
- va_end (arg);
-
- if (!xl)
- return NULL;
-
- glusterfs_graph_set_first (&graph->graph, xl);
-
- return xl;
-}
-
-static xlator_t *
-volgen_graph_add (volgen_graph_t *graph, char *type, char *volname)
-{
- char *shorttype = NULL;
-
- shorttype = strrchr (type, '/');
- GF_ASSERT (shorttype);
- shorttype++;
- GF_ASSERT (*shorttype);
-
- return volgen_graph_add_as (graph, type, "%s-%s", volname, shorttype);
-}
-
-/* XXX Seems there is no such generic routine?
- * Maybe should put to xlator.c ??
- */
-static int
-xlator_set_option (xlator_t *xl, char *key, char *value)
-{
- char *dval = NULL;
-
- dval = gf_strdup (value);
- if (!dval) {
- gf_log ("", GF_LOG_ERROR,
- "failed to set xlator opt: %s[%s] = %s",
- xl->name, key, value);
-
- return -1;
- }
-
- 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)
-{
- return (xlator_t *)graph->graph.first;
-}
-
-
-
-
-/**************************
- *
- * Trie glue
- *
- *************************/
-
-
-static int
-volopt_selector (int lvl, char **patt, void *param,
- int (*optcbk)(char *word, void *param))
-{
- struct volopt_map_entry *vme = NULL;
- char *w = NULL;
- int i = 0;
- int len = 0;
- int ret = 0;
- char *dot = NULL;
-
- for (vme = glusterd_volopt_map; vme->key; vme++) {
- w = vme->key;
-
- for (i = 0; i < lvl; i++) {
- if (patt[i]) {
- w = strtail (w, patt[i]);
- GF_ASSERT (!w || *w);
- if (!w || *w != '.')
- goto next;
- } else {
- w = strchr (w, '.');
- GF_ASSERT (w);
- }
- w++;
- }
-
- dot = strchr (w, '.');
- if (dot) {
- len = dot - w;
- w = gf_strdup (w);
- if (!w)
- return -1;
- w[len] = '\0';
- }
- ret = optcbk (w, param);
- if (dot)
- GF_FREE (w);
- if (ret)
- return -1;
- next:
- continue;
- }
-
- return 0;
-}
-
-static int
-volopt_trie_cbk (char *word, void *param)
-{
- return trie_add ((trie_t *)param, word);
-}
-
-static int
-process_nodevec (struct trienodevec *nodevec, char **hint)
-{
- int ret = 0;
- char *hint1 = NULL;
- char *hint2 = NULL;
- char *hintinfx = "";
- trienode_t **nodes = nodevec->nodes;
-
- if (!nodes[0]) {
- *hint = NULL;
- return 0;
- }
-
-#if 0
- /* Limit as in git */
- if (trienode_get_dist (nodes[0]) >= 6) {
- *hint = NULL;
- return 0;
- }
-#endif
-
- if (trienode_get_word (nodes[0], &hint1))
- return -1;
-
- if (nodevec->cnt < 2 || !nodes[1]) {
- *hint = hint1;
- return 0;
- }
-
- if (trienode_get_word (nodes[1], &hint2))
- return -1;
-
- if (*hint)
- hintinfx = *hint;
- ret = gf_asprintf (hint, "%s or %s%s", hint1, hintinfx, hint2);
- if (ret > 0)
- ret = 0;
- return ret;
-}
-
-static int
-volopt_trie_section (int lvl, char **patt, char *word, char **hint, int hints)
-{
- trienode_t *nodes[] = { NULL, NULL };
- struct trienodevec nodevec = { nodes, 2};
- trie_t *trie = NULL;
- int ret = 0;
-
- trie = trie_new ();
- if (!trie)
- return -1;
-
- if (volopt_selector (lvl, patt, trie, &volopt_trie_cbk)) {
- trie_destroy (trie);
-
- return -1;
- }
-
- GF_ASSERT (hints <= 2);
- nodevec.cnt = hints;
- ret = trie_measure_vec (trie, word, &nodevec);
- if (!ret && nodevec.nodes[0])
- ret = process_nodevec (&nodevec, hint);
-
- trie_destroy (trie);
-
- return ret;
-}
-
-static int
-volopt_trie (char *key, char **hint)
-{
- char *patt[] = { NULL };
- char *fullhint = NULL;
- char *dot = NULL;
- char *dom = NULL;
- int len = 0;
- int ret = 0;
-
- *hint = NULL;
-
- dot = strchr (key, '.');
- if (!dot)
- return volopt_trie_section (1, patt, key, hint, 2);
-
- len = dot - key;
- dom = gf_strdup (key);
- if (!dom)
- return -1;
- dom[len] = '\0';
-
- ret = volopt_trie_section (0, NULL, dom, patt, 1);
- GF_FREE (dom);
- if (ret) {
- patt[0] = NULL;
- goto out;
- }
- if (!patt[0])
- goto out;
-
- *hint = "...";
- ret = volopt_trie_section (1, patt, dot + 1, hint, 2);
- if (ret)
- goto out;
- if (*hint) {
- ret = gf_asprintf (&fullhint, "%s.%s", patt[0], *hint);
- GF_FREE (*hint);
- if (ret >= 0) {
- ret = 0;
- *hint = fullhint;
- }
- }
-
- out:
- GF_FREE (patt[0]);
- if (ret)
- *hint = NULL;
-
- return ret;
-}
-
-
-
-
-/**************************
- *
- * Volume generation engine
- *
- **************************/
-
-
-typedef int (*volgen_opthandler_t) (volgen_graph_t *graph,
- struct volopt_map_entry *vme,
- void *param);
-
-struct opthandler_data {
- volgen_graph_t *graph;
- volgen_opthandler_t handler;
- struct volopt_map_entry *vme;
- gf_boolean_t found;
- gf_boolean_t data_t_fake;
- int rv;
- char *volname;
- void *param;
-};
-
-static int
-process_option (char *key, data_t *value, void *param)
-{
- struct opthandler_data *odt = param;
- struct volopt_map_entry vme = {0,};
-
- if (odt->rv)
- return 0;
- odt->found = _gf_true;
-
- vme.key = key;
- vme.voltype = odt->vme->voltype;
- vme.option = odt->vme->option;
- vme.op_version = odt->vme->op_version;
-
- if (!vme.option) {
- vme.option = strrchr (key, '.');
- if (vme.option)
- vme.option++;
- else
- vme.option = key;
- }
- if (odt->data_t_fake)
- vme.value = (char *)value;
- else
- vme.value = value->data;
-
- odt->rv = odt->handler (odt->graph, &vme, odt->param);
- return 0;
-}
-
-static int
-volgen_graph_set_options_generic (volgen_graph_t *graph, dict_t *dict,
- void *param, volgen_opthandler_t handler)
-{
- struct volopt_map_entry *vme = NULL;
- struct opthandler_data odt = {0,};
- data_t *data = NULL;
-
- odt.graph = graph;
- odt.handler = handler;
- odt.param = param;
- (void)data;
-
- for (vme = glusterd_volopt_map; vme->key; vme++) {
- odt.vme = vme;
- odt.found = _gf_false;
- odt.data_t_fake = _gf_false;
-
- data = dict_get (dict, vme->key);
-
- if (data)
- process_option (vme->key, data, &odt);
- if (odt.rv)
- return odt.rv;
-
- if (odt.found)
- continue;
-
- /* check for default value */
-
- if (vme->value) {
- /* stupid hack to be able to reuse dict iterator
- * in this context
- */
- odt.data_t_fake = _gf_true;
- process_option (vme->key, (data_t *)vme->value, &odt);
- if (odt.rv)
- return odt.rv;
- }
- }
-
- return 0;
-}
-
-static int
-no_filter_option_handler (volgen_graph_t *graph, struct volopt_map_entry *vme,
- void *param)
-{
- xlator_t *trav;
- int ret = 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 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;
-}
-
-static int
-volgen_graph_set_options (volgen_graph_t *graph, dict_t *dict)
-{
- return volgen_graph_set_options_generic (graph, dict, NULL,
- &basic_option_handler);
-}
-
-static int
-optget_option_handler (volgen_graph_t *graph, struct volopt_map_entry *vme,
- void *param)
-{
- struct volopt_map_entry *vme2 = param;
-
- if (strcmp (vme->key, vme2->key) == 0)
- vme2->value = vme->value;
-
- return 0;
-}
-
-static glusterd_server_xlator_t
-get_server_xlator (char *xlator)
-{
- glusterd_server_xlator_t subvol = GF_XLATOR_NONE;
-
- if (strcmp (xlator, "posix") == 0)
- subvol = GF_XLATOR_POSIX;
- if (strcmp (xlator, "acl") == 0)
- subvol = GF_XLATOR_ACL;
- if (strcmp (xlator, "locks") == 0)
- subvol = GF_XLATOR_LOCKS;
- if (strcmp (xlator, "io-threads") == 0)
- subvol = GF_XLATOR_IOT;
- if (strcmp (xlator, "index") == 0)
- subvol = GF_XLATOR_INDEX;
- if (strcmp (xlator, "marker") == 0)
- subvol = GF_XLATOR_MARKER;
- if (strcmp (xlator, "io-stats") == 0)
- subvol = GF_XLATOR_IO_STATS;
- if (strcmp (xlator, "bd") == 0)
- subvol = GF_XLATOR_BD;
-
- return subvol;
-}
-
-static glusterd_client_xlator_t
-get_client_xlator (char *xlator)
-{
- glusterd_client_xlator_t subvol = GF_CLNT_XLATOR_NONE;
-
- if (strcmp (xlator, "client") == 0)
- subvol = GF_CLNT_XLATOR_FUSE;
-
- return subvol;
-}
-
-static int
-debugxl_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, "!debug") != 0)
- return 0;
-
- if (!strcmp (vme->key , "debug.trace") ||
- !strcmp (vme->key, "debug.error-gen")) {
- if (get_server_xlator (vme->value) == GF_XLATOR_NONE &&
- get_client_xlator (vme->value) == GF_CLNT_XLATOR_NONE)
- return 0;
- else
- goto add_graph;
- }
-
- if (gf_string2boolean (vme->value, &enabled) == -1)
- return -1;
- if (!enabled)
- return 0;
-
-add_graph:
- if (volgen_graph_add (graph, vme->voltype, volname))
- return 0;
- else
- return -1;
-}
-
-int
-check_and_add_debug_xl (volgen_graph_t *graph, dict_t *set_dict, char *volname,
- char *xlname)
-{
- int ret = 0;
- char *value_str = NULL;
-
- ret = dict_get_str (set_dict, "debug.trace", &value_str);
- if (!ret) {
- if (strcmp (xlname, value_str) == 0) {
- ret = volgen_graph_set_options_generic (graph, set_dict, volname,
- &debugxl_option_handler);
- if (ret)
- goto out;
- }
- }
-
- ret = dict_get_str (set_dict, "debug.error-gen", &value_str);
- if (!ret) {
- if (strcmp (xlname, value_str) == 0) {
- ret = volgen_graph_set_options_generic (graph, set_dict, volname,
- &debugxl_option_handler);
- if (ret)
- goto out;
- }
- }
-
- ret = 0;
-
-out:
- return ret;
-}
-
-/* This getter considers defaults also. */
-static int
-volgen_dict_get (dict_t *dict, char *key, char **value)
-{
- struct volopt_map_entry vme = {0,};
- int ret = 0;
-
- vme.key = key;
-
- ret = volgen_graph_set_options_generic (NULL, dict, &vme,
- &optget_option_handler);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Out of memory");
-
- return -1;
- }
-
- *value = vme.value;
-
- return 0;
-}
-
-static int
-option_complete (char *key, char **completion)
-{
- struct volopt_map_entry *vme = NULL;
-
- *completion = NULL;
- for (vme = glusterd_volopt_map; vme->key; vme++) {
- if (strcmp (strchr (vme->key, '.') + 1, key) != 0)
- continue;
-
- if (*completion && strcmp (*completion, vme->key) != 0) {
- /* cancel on non-unique match */
- *completion = NULL;
-
- return 0;
- } else
- *completion = vme->key;
- }
-
- if (*completion) {
- /* For sake of unified API we want
- * have the completion to be a to-be-freed
- * string.
- */
- *completion = gf_strdup (*completion);
- return -!*completion;
- }
-
- return 0;
-}
-
-int
-glusterd_volinfo_get (glusterd_volinfo_t *volinfo, char *key, char **value)
-{
- return volgen_dict_get (volinfo->dict, key, value);
-}
-
-int
-glusterd_volinfo_get_boolean (glusterd_volinfo_t *volinfo, char *key)
-{
- char *val = NULL;
- gf_boolean_t enabled = _gf_false;
- int ret = 0;
-
- ret = glusterd_volinfo_get (volinfo, key, &val);
- if (ret)
- return -1;
-
- if (val)
- ret = gf_string2boolean (val, &enabled);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "value for %s option is not valid", key);
-
- return -1;
- }
-
- return enabled;
-}
-
-gf_boolean_t
-glusterd_check_voloption_flags (char *key, int32_t flags)
-{
- char *completion = NULL;
- struct volopt_map_entry *vmep = NULL;
- int ret = 0;
-
- COMPLETE_OPTION(key, completion, ret);
- for (vmep = glusterd_volopt_map; vmep->key; vmep++) {
- if (strcmp (vmep->key, key) == 0) {
- if (vmep->flags & flags)
- return _gf_true;
- else
- return _gf_false;
- }
- }
-
- return _gf_false;
-}
-
-gf_boolean_t
-glusterd_check_globaloption (char *key)
-{
- char *completion = NULL;
- struct volopt_map_entry *vmep = NULL;
- int ret = 0;
-
- COMPLETE_OPTION(key, completion, ret);
- for (vmep = glusterd_volopt_map; vmep->key; vmep++) {
- if (strcmp (vmep->key, key) == 0) {
- if ((vmep->type == GLOBAL_DOC) ||
- (vmep->type == GLOBAL_NO_DOC))
- return _gf_true;
- else
- return _gf_false;
- }
- }
-
- return _gf_false;
-}
-
-gf_boolean_t
-glusterd_check_localoption (char *key)
-{
- char *completion = NULL;
- struct volopt_map_entry *vmep = NULL;
- int ret = 0;
-
- COMPLETE_OPTION(key, completion, ret);
- for (vmep = glusterd_volopt_map; vmep->key; vmep++) {
- if (strcmp (vmep->key, key) == 0) {
- if ((vmep->type == DOC) ||
- (vmep->type == NO_DOC))
- return _gf_true;
- else
- return _gf_false;
- }
- }
-
- return _gf_false;
-}
-
-int
-glusterd_check_voloption (char *key)
-{
- char *completion = NULL;
- struct volopt_map_entry *vmep = NULL;
- int ret = 0;
-
- COMPLETE_OPTION(key, completion, ret);
- for (vmep = glusterd_volopt_map; vmep->key; vmep++) {
- if (strcmp (vmep->key, key) == 0) {
- if ((vmep->type == DOC) ||
- (vmep->type == DOC))
- return _gf_true;
- else
- return _gf_false;
- }
- }
-
- return _gf_false;
-
-}
-
-int
-glusterd_check_option_exists (char *key, char **completion)
-{
- struct volopt_map_entry vme = {0,};
- struct volopt_map_entry *vmep = NULL;
- int ret = 0;
- xlator_t *this = THIS;
-
- (void)vme;
- (void)vmep;
-
- if (!strchr (key, '.')) {
- if (completion) {
- ret = option_complete (key, completion);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Out of memory");
- return -1;
- }
-
- ret = !!*completion;
- if (ret)
- return ret;
- else
- goto trie;
- } else
- return 0;
- }
-
- for (vmep = glusterd_volopt_map; vmep->key; vmep++) {
- if (strcmp (vmep->key, key) == 0) {
- ret = 1;
- break;
- }
- }
-
- if (ret || !completion)
- return ret;
-
- trie:
- ret = volopt_trie (key, completion);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Some error occurred 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)
-{
- 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;
-
- for (trav = first_of (dgraph); trav->next; trav = trav->next);
-
- trav->next = first_of (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);
- }
-}
-
-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;
-
- if (gf_asprintf (&ftmp, "%s.tmp", filename) == -1) {
- ftmp = NULL;
-
- 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;
-
- 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;
- goto error;
- }
-
- f = NULL;
-
- if (rename (ftmp, filename) == -1)
- goto error;
-
- GF_FREE (ftmp);
-
- volgen_apply_filters(filename);
-
- return 0;
-
- error:
-
- GF_FREE (ftmp);
- if (f)
- fclose (f);
-
- gf_log (this->name, GF_LOG_ERROR,
- "failed to create volfile %s", filename);
-
- return -1;
-}
-
-static void
-volgen_graph_free (volgen_graph_t *graph)
-{
- xlator_t *trav = NULL;
- xlator_t *trav_old = NULL;
-
- for (trav = first_of (graph) ;; trav = trav->next) {
- if (trav_old)
- xlator_destroy (trav_old);
-
- trav_old = trav;
-
- if (!trav)
- break;
- }
-}
-
-static int
-build_graph_generic (volgen_graph_t *graph, glusterd_volinfo_t *volinfo,
- dict_t *mod_dict, void *param,
- int (*builder) (volgen_graph_t *graph,
- glusterd_volinfo_t *volinfo,
- dict_t *set_dict, void *param))
-{
- dict_t *set_dict = NULL;
- int ret = 0;
-
- if (mod_dict) {
- set_dict = dict_copy (volinfo->dict, NULL);
- if (!set_dict)
- return -1;
- 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)
- ret = volgen_graph_set_options (graph, set_dict);
-
- if (mod_dict)
- dict_destroy (set_dict);
-
- 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)
-{
- switch (type) {
- case GF_TRANSPORT_RDMA:
- strcpy (tt, "rdma");
- break;
- case GF_TRANSPORT_TCP:
- strcpy (tt, "tcp");
- break;
- case GF_TRANSPORT_BOTH_TCP_RDMA:
- strcpy (tt, "tcp,rdma");
- break;
- }
-}
-
-static void
-get_vol_transport_type (glusterd_volinfo_t *volinfo, char *tt)
-{
- transport_type_to_str (volinfo->transport_type, tt);
-}
-
-/* If no value has specfied for tcp,rdma volume from cli
- * use tcp as default value.Otherwise, use transport type
- * mentioned in volinfo
- */
-static void
-get_vol_nfs_transport_type (glusterd_volinfo_t *volinfo, char *tt)
-{
- if (volinfo->transport_type == GF_TRANSPORT_BOTH_TCP_RDMA) {
- strcpy (tt, "tcp");
- gf_log ("glusterd", GF_LOG_INFO,
- "The default transport type for tcp,rdma volume "
- "is tcp if option is not defined by the user ");
- } else
- transport_type_to_str (volinfo->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)
-{
- xlator_t *xl = NULL;
- xlator_list_t *trav = NULL;
- char *aa = NULL;
- int ret = 0;
- char *key = NULL;
-
- if (strcmp (vme->option, "!server-auth") != 0)
- return 0;
-
- xl = first_of (graph);
-
- /* from 'auth.allow' -> 'allow', and 'auth.reject' -> 'reject' */
- key = strchr (vme->key, '.') + 1;
-
- for (trav = xl->children; trav; trav = trav->next) {
- ret = gf_asprintf (&aa, "auth.addr.%s.%s", trav->xlator->name,
- key);
- if (ret != -1) {
- ret = xlator_set_option (xl, aa, vme->value);
- GF_FREE (aa);
- }
- if (ret)
- return -1;
- }
-
- return 0;
-}
-
-static int
-loglevel_option_handler (volgen_graph_t *graph,
- struct volopt_map_entry *vme, void *param)
-{
- 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))
- return 0;
-
- memcpy (&vme2, vme, sizeof (vme2));
- vme2.option = "log-level";
-
- return basic_option_handler (graph, &vme2, NULL);
-}
-
-static int
-server_check_marker_off (volgen_graph_t *graph, struct volopt_map_entry *vme,
- glusterd_volinfo_t *volinfo)
-{
- gf_boolean_t enabled = _gf_false;
- int ret = 0;
-
- GF_ASSERT (volinfo);
- GF_ASSERT (vme);
-
- if (strcmp (vme->option, "!xtime") != 0)
- return 0;
-
- ret = gf_string2boolean (vme->value, &enabled);
- if (ret || enabled)
- goto out;
-
- ret = glusterd_volinfo_get_boolean (volinfo, VKEY_MARKER_XTIME);
- if (ret < 0) {
- gf_log ("", GF_LOG_WARNING, "failed to get the marker status");
- ret = -1;
- goto out;
- }
-
- if (ret) {
- enabled = _gf_false;
- ret = glusterd_check_gsync_running (volinfo, &enabled);
-
- if (enabled) {
- gf_log ("", GF_LOG_WARNING, GEOREP" sessions active"
- "for the volume %s, cannot disable marker "
- ,volinfo->volname);
- set_graph_errstr (graph,
- VKEY_MARKER_XTIME" cannot be disabled "
- "while "GEOREP" sessions exist");
- ret = -1;
- goto out;
- }
-
- if (ret) {
- gf_log ("", GF_LOG_WARNING, "Unable to get the status"
- " of active gsync session");
- goto out;
- }
- }
-
- ret = 0;
- out:
- gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-
-}
-
-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
-logger_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, "!logger") != 0 ||
- !strstr (vme->key, role))
- return 0;
-
- memcpy (&vme2, vme, sizeof (vme2));
- vme2.option = "logger";
-
- return basic_option_handler (graph, &vme2, NULL);
-}
-
-static int
-log_format_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, "!log-format") != 0 ||
- !strstr (vme->key, role))
- return 0;
-
- memcpy (&vme2, vme, sizeof (vme2));
- vme2.option = "log-format";
-
- return basic_option_handler (graph, &vme2, NULL);
-}
-
-static int
-log_buf_size_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, "!log-buf-size") != 0 ||
- !strstr (vme->key, role))
- return 0;
-
- memcpy (&vme2, vme, sizeof (vme2));
- vme2.option = "log-buf-size";
-
- return basic_option_handler (graph, &vme2, NULL);
-}
-
-static int
-log_flush_timeout_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, "!log-flush-timeout") != 0 ||
- !strstr (vme->key, role))
- return 0;
-
- memcpy (&vme2, vme, sizeof (vme2));
- vme2.option = "log-flush-timeout";
-
- 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)
-{
- int ret = 0;
- glusterd_volinfo_t *volinfo = NULL;
-
- volinfo = param;
-
- ret = server_auth_option_handler (graph, vme, NULL);
- if (!ret)
- ret = server_check_marker_off (graph, vme, volinfo);
-
- if (!ret)
- ret = loglevel_option_handler (graph, vme, "brick");
-
- if (!ret)
- ret = sys_loglevel_option_handler (graph, vme, "brick");
-
- if (!ret)
- ret = logger_option_handler (graph, vme, "brick");
-
- if (!ret)
- ret = log_format_option_handler (graph, vme, "brick");
-
- if (!ret)
- ret = log_buf_size_option_handler (graph, vme, "brick");
-
- if (!ret)
- ret = log_flush_timeout_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;
-}
-
-static void get_vol_tstamp_file (char *filename, glusterd_volinfo_t *volinfo);
-
-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};
- glusterd_brickinfo_t *brickinfo = NULL;
- char changelog_basepath[PATH_MAX] = {0,};
- gf_boolean_t quota_enabled = _gf_true;
- gf_boolean_t pgfid_feat = _gf_false;
- char *value = NULL;
- char *ssl_user = NULL;
-
- brickinfo = param;
- path = brickinfo->path;
- 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;
- }
- }
-
- ret = glusterd_volinfo_get (volinfo, VKEY_FEATURES_QUOTA, &value);
- if (value) {
- ret = gf_string2boolean (value, &quota_enabled);
- if (ret)
- goto out;
- }
-
- ret = glusterd_volinfo_get (volinfo,
- "update-link-count-parent",
- &value);
- if (value) {
- ret = gf_string2boolean (value, &pgfid_feat);
- if (ret)
- goto out;
- }
-
- xl = volgen_graph_add (graph, "storage/posix", volname);
- if (!xl)
- return -1;
-
- ret = xlator_set_option (xl, "directory", path);
- if (ret)
- return -1;
-
- ret = xlator_set_option (xl, "volume-id",
- uuid_utoa (volinfo->volume_id));
- if (ret)
- return -1;
-
- if (quota_enabled || pgfid_feat)
- xlator_set_option (xl, "update-link-count-parent",
- "on");
-
- ret = check_and_add_debug_xl (graph, set_dict, volname,
- "posix");
- if (ret)
- return -1;
-#ifdef HAVE_BD_XLATOR
- if (*brickinfo->vg != '\0') {
- /* Now add BD v2 xlator if volume is BD type */
- xl = volgen_graph_add (graph, "storage/bd", volname);
- if (!xl)
- return -1;
-
- ret = xlator_set_option (xl, "device", "vg");
- if (ret)
- return -1;
- ret = xlator_set_option (xl, "export", brickinfo->vg);
- if (ret)
- return -1;
-
- ret = check_and_add_debug_xl (graph, set_dict, volname, "bd");
- if (ret)
- return -1;
-
- }
-#endif
-
- xl = volgen_graph_add (graph, "features/changelog", volname);
- if (!xl)
- return -1;
-
- ret = xlator_set_option (xl, "changelog-brick", path);
- if (ret)
- return -1;
-
- snprintf (changelog_basepath, sizeof (changelog_basepath),
- "%s/%s", path, ".glusterfs/changelogs");
- ret = xlator_set_option (xl, "changelog-dir", changelog_basepath);
- if (ret)
- return -1;
-
- ret = check_and_add_debug_xl (graph, set_dict, volname, "changelog");
- 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;
-
- xl = volgen_graph_add (graph, "features/barrier", volname);
- if (!xl)
- 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);
-
- rbxl = volgen_graph_add_nolink (graph, "protocol/client",
- "%s-replace-brick", volname);
- if (!rbxl)
- return -1;
-
- ptranst = glusterd_get_trans_type_rb (volinfo->transport_type);
- if (NULL == ptranst)
- return -1;
-
- if (dict_get_str (set_dict, SSL_CERT_DEPTH_OPT, &value) == 0) {
- ret = xlator_set_option (rbxl, "ssl-cert-depth", value);
- if (ret) {
- gf_log ("glusterd", GF_LOG_WARNING,
- "failed to set ssl-cert-depth");
- return -1;
- }
- }
-
- if (dict_get_str (set_dict, SSL_CIPHER_LIST_OPT, &value) == 0) {
- ret = xlator_set_option (rbxl, "ssl-cipher-list",
- value);
- if (ret) {
- gf_log ("glusterd", GF_LOG_WARNING,
- "failed to set ssl-cipher-list");
- 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);
- if (ret)
- return -1;
-
- xl = volgen_graph_add_nolink (graph, "cluster/pump", "%s-pump",
- volname);
- if (!xl)
- return -1;
- ret = volgen_xlator_link (xl, txl);
- if (ret)
- return -1;
- ret = volgen_xlator_link (xl, rbxl);
- if (ret)
- 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)
- return -1;
- get_vol_tstamp_file (tstamp_file, volinfo);
- ret = xlator_set_option (xl, "timestamp-file", tstamp_file);
- if (ret)
- return -1;
-
- ret = check_and_add_debug_xl (graph, set_dict, volname, "marker");
- if (ret)
- return -1;
-
- xl = volgen_graph_add (graph, "features/quota", volname);
- if (!xl)
- return -1;
- ret = xlator_set_option (xl, "volume-uuid", volname);
- if (ret)
- return -1;
-
- ret = glusterd_volinfo_get (volinfo, VKEY_FEATURES_QUOTA, &value);
- if (value) {
- ret = xlator_set_option (xl, "server-quota", value);
- 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;
- }
- }
-
- /* Check for compress volume option, and add it to the graph on server side */
- ret = dict_get_str_boolean (set_dict, "network.compression", 0);
- if (ret == -1)
- goto out;
- if (ret) {
- xl = volgen_graph_add (graph, "features/cdc", volname);
- if (!xl) {
- ret = -1;
- goto out;
- }
- ret = xlator_set_option (xl, "mode", "server");
- if (ret)
- goto out;
- }
-
- xl = volgen_graph_add_as (graph, "debug/io-stats", path);
- if (!xl)
- return -1;
-
- xl = volgen_graph_add (graph, "protocol/server", volname);
- if (!xl)
- return -1;
- ret = xlator_set_option (xl, "transport-type", transt);
- if (ret)
- return -1;
-
- /*In the case of running multiple glusterds on a single machine,
- * we should ensure that bricks don't listen on all IPs on that
- * machine and break the IP based separation being brought about.*/
- if (dict_get (THIS->options, "transport.socket.bind-address")) {
- ret = xlator_set_option (xl, "transport.socket.bind-address",
- brickinfo->hostname);
- if (ret)
- return -1;
- }
-
- if (dict_get_str (set_dict, SSL_CERT_DEPTH_OPT, &value) == 0) {
- ret = xlator_set_option (xl, "ssl-cert-depth", value);
- if (ret) {
- gf_log ("glusterd", GF_LOG_WARNING,
- "failed to set ssl-cert-depth");
- return -1;
- }
- }
-
- if (dict_get_str (set_dict, SSL_CIPHER_LIST_OPT, &value) == 0) {
- ret = xlator_set_option (xl, "ssl-cipher-list", value);
- if (ret) {
- gf_log ("glusterd", GF_LOG_WARNING,
- "failed to set ssl-cipher-list");
- return -1;
- }
- }
-
- if (username) {
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "auth.login.%s.allow", path);
-
- 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;
- }
-
- if (dict_get_str (volinfo->dict, "auth.ssl-allow", &ssl_user) == 0) {
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "auth.login.%s.ssl-allow", path);
-
- ret = xlator_set_option (xl, key, ssl_user);
- 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;
-}
-
-
-/* builds a graph for server role , with option overrides in mod_dict */
-static int
-build_server_graph (volgen_graph_t *graph, glusterd_volinfo_t *volinfo,
- dict_t *mod_dict, glusterd_brickinfo_t *brickinfo)
-{
- return build_graph_generic (graph, volinfo, mod_dict, brickinfo,
- &server_graph_builder);
-}
-
-static int
-perfxl_option_handler (volgen_graph_t *graph, struct volopt_map_entry *vme,
- void *param)
-{
- gf_boolean_t enabled = _gf_false;
- glusterd_volinfo_t *volinfo = NULL;
-
- GF_ASSERT (param);
- volinfo = param;
-
- if (strcmp (vme->option, "!perf") != 0)
- return 0;
-
- if (gf_string2boolean (vme->value, &enabled) == -1)
- return -1;
- if (!enabled)
- return 0;
-
- /* Check op-version before adding the 'open-behind' xlator in the graph
- */
- if (!strcmp (vme->key, "performance.open-behind") &&
- (vme->op_version > volinfo->client_op_version))
- return 0;
-
- if (volgen_graph_add (graph, vme->voltype, volinfo->volname))
- return 0;
- else
- return -1;
-}
-
-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_xlator_opt_key_from_vme ( 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;
-}
-
-static void
-_free_xlator_opt_key (char *key)
-{
- GF_ASSERT (key);
-
- if (!strcmp (key, AUTH_ALLOW_OPT_KEY) ||
- !strcmp (key, AUTH_REJECT_OPT_KEY) ||
- !strcmp (key, NFS_DISABLE_OPT_KEY))
- GF_FREE (key);
-
- return;
-}
-
-int
-glusterd_get_volopt_content (dict_t * ctx, gf_boolean_t xml_out)
-{
- 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[51200] = {0, };
- char *output = NULL;
- char tmp_str[2048] = {0, };
-#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
-
- 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 (vme->description) {
- descr = vme->description;
- def_val = vme->value;
- } else {
- if (_get_xlator_opt_key_from_vme (vme, &key)) {
- gf_log ("glusterd", GF_LOG_DEBUG, "Failed to "
- "get %s key from volume option entry",
- vme->key);
- goto out; /*Some error while geting key*/
- }
-
- ret = xlator_volopt_dynload (vme->voltype,
- &dl_handle,
- &vol_opt_handle);
-
- if (ret) {
- gf_log ("glusterd", GF_LOG_DEBUG,
- "xlator_volopt_dynload error(%d)", ret);
- ret = 0;
- goto cont;
- }
-
- ret = xlator_option_info_list (&vol_opt_handle, key,
- &def_val, &descr);
- if (ret) { /*Swallow Error i.e if option not found*/
- gf_log ("glusterd", GF_LOG_DEBUG,
- "Failed to get option for %s key", key);
- ret = 0;
- goto cont;
- }
- }
-
- if (xml_out) {
-#if (HAVE_LIB_XML)
- if (xml_add_volset_element (writer,vme->key,
- def_val, descr)) {
- ret = -1;
- goto cont;
- }
-#else
- gf_log ("glusterd", GF_LOG_ERROR, "Libxml not present");
-#endif
- } else {
- snprintf (tmp_str, sizeof (tmp_str), "Option: %s\nDefault "
- "Value: %s\nDescription: %s\n\n",
- vme->key, def_val, descr);
- strcat (output_string, tmp_str);
- }
-cont:
- if (dl_handle) {
- dlclose (dl_handle);
- dl_handle = NULL;
- vol_opt_handle.given_opt = NULL;
- }
- if (key) {
- _free_xlator_opt_key (key);
- key = NULL;
- }
- if (ret)
- goto out;
- }
-
-#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 xlator_t *
-volgen_graph_build_client (volgen_graph_t *graph, glusterd_volinfo_t *volinfo,
- char *hostname, char *subvol, char *xl_id,
- char *transt, dict_t *set_dict)
-{
- xlator_t *xl = NULL;
- int ret = -2;
- uint32_t client_type = GF_CLIENT_OTHER;
- char *str = NULL;
- char *ssl_str = NULL;
- gf_boolean_t ssl_bool = _gf_false;
- char *value = NULL;
-
- GF_ASSERT (graph);
- GF_ASSERT (subvol);
- GF_ASSERT (xl_id);
- GF_ASSERT (transt);
-
- xl = volgen_graph_add_nolink (graph, "protocol/client",
- "%s", xl_id);
- if (!xl)
- goto err;
-
- ret = xlator_set_option (xl, "ping-timeout", "42");
- if (ret)
- goto err;
-
- if (hostname) {
- ret = xlator_set_option (xl, "remote-host", hostname);
- if (ret)
- goto err;
- }
-
- ret = xlator_set_option (xl, "remote-subvolume", subvol);
- if (ret)
- goto err;
-
- ret = xlator_set_option (xl, "transport-type", transt);
- if (ret)
- goto err;
-
- 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 err;
- }
-
- str = glusterd_auth_get_password (volinfo);
- if (str) {
- ret = xlator_set_option (xl, "password",
- str);
- if (ret)
- goto err;
- }
- }
-
- 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 err;
- }
- }
- }
- }
-
- if (dict_get_str (set_dict, SSL_CERT_DEPTH_OPT, &value) == 0) {
- ret = xlator_set_option (xl, "ssl-cert-depth", value);
- if (ret) {
- gf_log ("glusterd", GF_LOG_WARNING,
- "failed to set ssl-cert-depth");
- goto err;
- }
- }
-
- if (dict_get_str (set_dict, SSL_CIPHER_LIST_OPT, &value) == 0) {
- ret = xlator_set_option (xl, "ssl-cipher-list", value);
- if (ret) {
- gf_log ("glusterd", GF_LOG_WARNING,
- "failed to set ssl-cipher-list");
- goto err;
- }
- }
-
- return xl;
-err:
- return NULL;
-}
-
-static int
-volgen_graph_build_clients (volgen_graph_t *graph, glusterd_volinfo_t *volinfo,
- dict_t *set_dict, void *param)
-{
- int i = 0;
- int ret = -1;
- char transt[16] = {0,};
- char *volname = NULL;
- glusterd_brickinfo_t *brick = NULL;
- xlator_t *xl = NULL;
-
- volname = volinfo->volname;
-
- 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)) {
- 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;
- }
-
- get_transport_type (volinfo, set_dict, transt, _gf_false);
-
- if (!strcmp (transt, "tcp,rdma"))
- strcpy (transt, "tcp");
-
- i = 0;
- list_for_each_entry (brick, &volinfo->bricks, brick_list) {
- xl = volgen_graph_build_client (graph, volinfo,
- brick->hostname, brick->path,
- brick->brick_id,
- transt, set_dict);
- if (!xl) {
- ret = -1;
- goto out;
- }
-
- 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;
- }
- 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)
- break;
-
- i++;
- }
-
- ret = j;
-out:
- return ret;
-}
-
-/**
- * This is the build graph function for user-serviceable snapshots.
- * Generates snapview-client
- */
-static int
-volgen_graph_build_snapview_client (volgen_graph_t *graph,
- glusterd_volinfo_t *volinfo,
- char *volname, dict_t *set_dict)
-{
- int ret = 0;
- xlator_t *prev_top = NULL;
- xlator_t *prot_clnt = NULL;
- xlator_t *svc = NULL;
- char transt [16] = {0,};
- char *svc_args[] = {"features/snapview-client",
- "%s-snapview-client"};
- char subvol [1024] = {0,};
- char xl_id [1024] = {0,};
-
- prev_top = (xlator_t *)(graph->graph.first);
-
- snprintf (subvol, sizeof (subvol), "snapd-%s", volinfo->volname);
- snprintf (xl_id, sizeof (xl_id), "%s-snapd-client", volinfo->volname);
-
- get_transport_type (volinfo, set_dict, transt, _gf_false);
-
- prot_clnt = volgen_graph_build_client (graph, volinfo, NULL, subvol,
- xl_id, transt, set_dict);
- if (!prot_clnt) {
- ret = -1;
- goto out;
- }
-
- svc = volgen_graph_add_nolink (graph, svc_args[0], svc_args[1],
- volname);
- if (!svc) {
- ret = -1;
- goto out;
- }
-
- /**
- * Ordering the below two traslators (cur_top & prot_clnt) is important
- * as snapview client implementation is built on the policy that
- * normal volume path goes to FIRST_CHILD and snap world operations
- * goes to SECOND_CHILD
- **/
- ret = volgen_xlator_link (graph->graph.first, prev_top);
- if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR, "failed to link the "
- "snapview-client to distribute");
- goto out;
- }
-
- ret = volgen_xlator_link (graph->graph.first, prot_clnt);
- if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR, "failed to link the "
- "snapview-client to snapview-server");
- goto out;
- }
-
-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)
- break;
-
- 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;
- }
-
- if (comma)
- strcat (*children, ",");
- strcat (*children, cxl->name);
- comma = _gf_true;
- }
-
- xl_child = xl_child->next;
- }
- ret = 0;
-out:
- return ret;
-}
-
-static int
-volgen_graph_build_dht_cluster (volgen_graph_t *graph,
- glusterd_volinfo_t *volinfo, size_t child_count,
- gf_boolean_t is_quotad)
-{
- int32_t clusters = 0;
- int ret = -1;
- char *decommissioned_children = NULL;
- xlator_t *dht = NULL;
- char *voltype = "cluster/distribute";
- char *name_fmt = NULL;
-
- /* NUFA and Switch section */
- if (dict_get_str_boolean (volinfo->dict, "cluster.nufa", 0) &&
- dict_get_str_boolean (volinfo->dict, "cluster.switch", 0)) {
- gf_log (THIS->name, GF_LOG_ERROR,
- "nufa and switch cannot be set together");
- ret = -1;
- goto out;
- }
-
- /* Check for NUFA volume option, and change the voltype */
- if (dict_get_str_boolean (volinfo->dict, "cluster.nufa", 0))
- voltype = "cluster/nufa";
-
- /* Check for switch volume option, and change the voltype */
- if (dict_get_str_boolean (volinfo->dict, "cluster.switch", 0))
- voltype = "cluster/switch";
-
- if (is_quotad)
- name_fmt = "%s";
- else
- name_fmt = "%s-dht";
-
- clusters = volgen_graph_build_clusters (graph, volinfo,
- voltype,
- name_fmt,
- 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;
- }
- ret = 0;
-out:
- GF_FREE (decommissioned_children);
- return ret;
-}
-
-static int
-volume_volgen_graph_build_clusters (volgen_graph_t *graph,
- glusterd_volinfo_t *volinfo,
- gf_boolean_t is_quotad)
-{
- char *replicate_args[] = {"cluster/replicate",
- "%s-replicate-%d"};
- char *stripe_args[] = {"cluster/stripe",
- "%s-stripe-%d"};
- char *disperse_args[] = {"cluster/disperse",
- "%s-disperse-%d"};
- char option[32] = "";
- int rclusters = 0;
- int clusters = 0;
- int dist_count = 0;
- int ret = -1;
- xlator_t * ec = NULL;
-
- 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;
- case GF_CLUSTER_TYPE_DISPERSE:
- clusters = volgen_graph_build_clusters (graph, volinfo,
- disperse_args[0],
- disperse_args[1],
- volinfo->brick_count,
- volinfo->disperse_count);
- if (clusters < 0)
- goto out;
-
- sprintf(option, "%d", volinfo->redundancy_count);
- ec = first_of (graph);
- while (clusters-- > 0) {
- ret = xlator_set_option (ec, "redundancy", option);
- if (ret)
- goto out;
-
- ec = ec->next;
- }
-
- break;
- default:
- gf_log ("", GF_LOG_ERROR, "volume inconsistency: "
- "unrecognized clustering type");
- goto out;
- }
-
-build_distribute:
- dist_count = volinfo->brick_count / volinfo->dist_leaf_count;
- if (!dist_count) {
- ret = -1;
- goto out;
- }
-
- ret = volgen_graph_build_dht_cluster (graph, volinfo,
- dist_count, is_quotad);
- if (ret)
- goto out;
-
- ret = 0;
-out:
- return ret;
-}
-
-static int client_graph_set_perf_options(volgen_graph_t *graph,
- glusterd_volinfo_t *volinfo,
- dict_t *set_dict)
-{
- data_t *tmp_data = NULL;
- char *volname = NULL;
-
- /*
- * Logic to make sure NFS doesn't have performance translators by
- * default for a volume
- */
- volname = volinfo->volname;
- tmp_data = dict_get (set_dict, "nfs-volume-file");
- if (!tmp_data)
- return volgen_graph_set_options_generic(graph, set_dict,
- volinfo,
- &perfxl_option_handler);
- else
- return volgen_graph_set_options_generic(graph, set_dict,
- volname,
- &nfsperfxl_option_handler);
-}
-
-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;
- glusterd_conf_t *conf = THIS->private;
- char *tmp = NULL;
- gf_boolean_t var = _gf_false;
- gf_boolean_t ob = _gf_false;
- gf_boolean_t uss_enabled = _gf_false;
- gf_boolean_t rebal_volfile = _gf_false;
- xlator_t *this = THIS;
-
- GF_ASSERT (this);
- GF_ASSERT (conf);
-
- 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, _gf_false);
- if (ret == -1)
- goto out;
-
- /* As of now snapshot volume is read-only. Read-only xlator is loaded
- * in client graph so that AFR & DHT healing can be done in server.
- */
- if (volinfo->is_snap_volume) {
- xl = volgen_graph_add (graph, "features/read-only", volname);
- if (!xl) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to add "
- "read-only feature to the graph of %s "
- "snapshot with %s origin volume",
- volname, volinfo->parent_volname);
- ret = -1;
- goto out;
- }
- }
-
- /* Check for compress volume option, and add it to the graph on client side */
- ret = dict_get_str_boolean (set_dict, "network.compression", 0);
- if (ret == -1)
- goto out;
- if (ret) {
- xl = volgen_graph_add (graph, "features/cdc", volname);
- if (!xl) {
- ret = -1;
- goto out;
- }
- ret = xlator_set_option (xl, "mode", "client");
- if (ret)
- goto out;
- }
-
- ret = glusterd_volinfo_get_boolean (volinfo, "features.encryption");
- if (ret == -1)
- goto out;
- if (ret) {
- xl = volgen_graph_add (graph, "encryption/crypt", volname);
-
- if (!xl) {
- ret = -1;
- goto out;
- }
- }
-
- if (conf->op_version == GD_OP_VERSION_MIN) {
- ret = glusterd_volinfo_get_boolean (volinfo,
- VKEY_FEATURES_QUOTA);
- if (ret == -1)
- goto out;
- if (ret) {
- xl = volgen_graph_add (graph, "features/quota",
- volname);
- if (!xl) {
- ret = -1;
- goto out;
- }
- }
- }
-
-
- ret = glusterd_volinfo_get_boolean (volinfo, "features.file-snapshot");
- if (ret == -1)
- goto out;
- if (ret) {
- xl = volgen_graph_add (graph, "features/qemu-block", volname);
-
- if (!xl) {
- ret = -1;
- goto out;
- }
- }
-
- /* Do not allow changing read-after-open option if root-squash is
- enabled.
- */
- ret = dict_get_str (set_dict, "performance.read-after-open", &tmp);
- if (!ret) {
- ret = dict_get_str (volinfo->dict, "server.root-squash", &tmp);
- if (!ret) {
- ob = _gf_false;
- ret = gf_string2boolean (tmp, &ob);
- if (!ret && ob) {
- gf_log (this->name, GF_LOG_WARNING,
- "root-squash is enabled. Please turn it"
- " off to change read-after-open "
- "option");
- ret = -1;
- goto out;
- }
- }
- }
-
- /* open behind causes problems when root-squash is enabled
- (by allowing reads to happen even though the squashed user
- does not have permissions to do so) as it fakes open to be
- successful and later sends reads on anonymous fds. So when
- root-squash is enabled, open-behind's option to read after
- open is done is also enabled.
- */
- ret = dict_get_str (set_dict, "server.root-squash", &tmp);
- if (!ret) {
- ret = gf_string2boolean (tmp, &var);
- if (ret)
- goto out;
-
- if (var) {
- ret = dict_get_str (volinfo->dict,
- "performance.read-after-open",
- &tmp);
- if (!ret) {
- ret = gf_string2boolean (tmp, &ob);
- /* go ahead with turning read-after-open on
- even if string2boolean conversion fails,
- OR if read-after-open option is turned off
- */
- if (ret || !ob)
- ret = dict_set_str (set_dict,
- "performance.read-after-open",
- "yes");
- } else {
- ret = dict_set_str (set_dict,
- "performance.read-after-open",
- "yes");
- }
- } else {
- /* When root-squash has to be turned off, open-behind's
- read-after-open option should be reset to what was
- there before root-squash was turned on. If the option
- cannot be found in volinfo's dict, it means that
- option was not set before turning on root-squash.
- */
- ob = _gf_false;
- ret = dict_get_str (volinfo->dict,
- "performance.read-after-open",
- &tmp);
- if (!ret) {
- ret = gf_string2boolean (tmp, &ob);
-
- if (!ret && ob) {
- ret = dict_set_str (set_dict,
- "performance.read-after-open",
- "yes");
- }
- }
- /* consider operation is failure only if read-after-open
- option is enabled and could not set into set_dict
- */
- if (!ob)
- ret = 0;
- }
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING, "setting "
- "open behind option as part of root "
- "squash failed");
- goto out;
- }
- }
-
- ret = dict_get_str_boolean (set_dict, "server.manage-gids", _gf_false);
- if (ret != -1) {
- ret = dict_set_str (set_dict, "client.send-gids",
- ret ? "false" : "true");
- if (ret)
- gf_log (THIS->name, GF_LOG_WARNING, "changing client"
- " protocol option failed");
- }
-
- ret = client_graph_set_perf_options(graph, volinfo, set_dict);
- if (ret)
- goto out;
-
- uss_enabled = dict_get_str_boolean (set_dict, "features.uss",
- _gf_false);
- if (uss_enabled == -1)
- goto out;
- if (uss_enabled && !volinfo->is_snap_volume) {
- rebal_volfile = dict_get_str_boolean (set_dict,
- "rebalance-volfile-creation",
- _gf_false);
- if (rebal_volfile == -1)
- goto out;
-
- if (!rebal_volfile) {
- ret = volgen_graph_build_snapview_client
- (graph, volinfo,
- volname, set_dict);
- if (ret == -1)
- goto out;
- }
- }
-
- /* add debug translators depending on the options */
- ret = check_and_add_debug_xl (graph, set_dict, volname,
- "client");
- if (ret)
- return -1;
-
- ret = -1;
- xl = volgen_graph_add_as (graph, "debug/io-stats", volname);
- if (!xl)
- 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 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");
-
- ret = volgen_graph_set_options_generic (graph, set_dict, "client",
- &logger_option_handler);
-
- if (ret)
- gf_log (this->name, GF_LOG_WARNING, "changing client logger"
- " failed");
-
- ret = volgen_graph_set_options_generic (graph, set_dict, "client",
- &log_format_option_handler);
- if (ret)
- gf_log (this->name, GF_LOG_WARNING, "changing client log format"
- " failed");
-
- ret = volgen_graph_set_options_generic (graph, set_dict, "client",
- &log_buf_size_option_handler);
- if (ret)
- gf_log (this->name, GF_LOG_WARNING, "Failed to change "
- "log-buf-size option");
-
- ret = volgen_graph_set_options_generic (graph, set_dict, "client",
- &log_flush_timeout_option_handler);
- if (ret)
- gf_log (this->name, GF_LOG_WARNING, "Failed to change "
- "log-flush-timeout option");
-
-out:
- return ret;
-}
-
-
-/* builds a graph for client role , with option overrides in mod_dict */
-static int
-build_client_graph (volgen_graph_t *graph, glusterd_volinfo_t *volinfo,
- dict_t *mod_dict)
-{
- return build_graph_generic (graph, volinfo, mod_dict, NULL,
- &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;
-
- shd_option = gd_get_matching_option (gd_shd_options, vme->option);
- if ((vme->option[0] == '!') && !shd_option)
- goto out;
- new_vme = *vme;
- if (shd_option) {
- 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)
-{
- xlator_t *xl = NULL;
- char *aa = NULL;
- int ret = 0;
- glusterd_volinfo_t *volinfo = NULL;
-
- volinfo = param;
-
- xl = first_of (graph);
-
-/* if (vme->type == GLOBAL_DOC || vme->type == GLOBAL_NO_DOC) {
-
- ret = xlator_set_option (xl, vme->key, vme->value);
- }*/
- if (!volinfo || (volinfo->volname[0] == '\0'))
- return 0;
-
- if (! strcmp (vme->option, "!rpc-auth.addr.*.allow")) {
- ret = gf_asprintf (&aa, "rpc-auth.addr.%s.allow",
- volinfo->volname);
-
- if (ret != -1) {
- ret = xlator_set_option (xl, aa, vme->value);
- GF_FREE (aa);
- }
-
- if (ret)
- return -1;
- }
-
- if (! strcmp (vme->option, "!rpc-auth.addr.*.reject")) {
- ret = gf_asprintf (&aa, "rpc-auth.addr.%s.reject",
- volinfo->volname);
-
- if (ret != -1) {
- ret = xlator_set_option (xl, aa, vme->value);
- GF_FREE (aa);
- }
-
- if (ret)
- return -1;
- }
-
- if (! strcmp (vme->option, "!rpc-auth.auth-unix.*")) {
- ret = gf_asprintf (&aa, "rpc-auth.auth-unix.%s",
- volinfo->volname);
-
- if (ret != -1) {
- ret = xlator_set_option (xl, aa, vme->value);
- GF_FREE (aa);
- }
-
- if (ret)
- return -1;
- }
- if (! strcmp (vme->option, "!rpc-auth.auth-null.*")) {
- ret = gf_asprintf (&aa, "rpc-auth.auth-null.%s",
- volinfo->volname);
-
- if (ret != -1) {
- ret = xlator_set_option (xl, aa, vme->value);
- GF_FREE (aa);
- }
-
- if (ret)
- return -1;
- }
-
- if (! strcmp (vme->option, "!nfs3.*.trusted-sync")) {
- ret = gf_asprintf (&aa, "nfs3.%s.trusted-sync",
- volinfo->volname);
-
- if (ret != -1) {
- ret = xlator_set_option (xl, aa, vme->value);
- GF_FREE (aa);
- }
-
- if (ret)
- return -1;
- }
-
- if (! strcmp (vme->option, "!nfs3.*.trusted-write")) {
- ret = gf_asprintf (&aa, "nfs3.%s.trusted-write",
- volinfo->volname);
-
- if (ret != -1) {
- ret = xlator_set_option (xl, aa, vme->value);
- GF_FREE (aa);
- }
-
- if (ret)
- return -1;
- }
-
- if (! strcmp (vme->option, "!nfs3.*.volume-access")) {
- ret = gf_asprintf (&aa, "nfs3.%s.volume-access",
- volinfo->volname);
-
- if (ret != -1) {
- ret = xlator_set_option (xl, aa, vme->value);
- GF_FREE (aa);
- }
-
- if (ret)
- return -1;
- }
-
- if (! strcmp (vme->option, "!nfs3.*.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);
- }
-
- if (ret)
- return -1;
- }
-
-
-
- if (! strcmp (vme->option, "!rpc-auth.ports.*.insecure")) {
- ret = gf_asprintf (&aa, "rpc-auth.ports.%s.insecure",
- volinfo->volname);
-
- if (ret != -1) {
- ret = xlator_set_option (xl, aa, vme->value);
- GF_FREE (aa);
- }
-
- if (ret)
- return -1;
- }
-
-
- if (! strcmp (vme->option, "!nfs-disable")) {
- ret = gf_asprintf (&aa, "nfs.%s.disable",
- volinfo->volname);
-
- if (ret != -1) {
- ret = xlator_set_option (xl, aa, vme->value);
- GF_FREE (aa);
- }
-
- if (ret)
- return -1;
- }
-
- if (! strcmp (vme->option, "!nfs-ganesha.enable")) {
- ret = gf_asprintf (&aa, "nfs-ganesha.%s.enable",
- volinfo->volname);
-
- if (ret != -1) {
- ret = xlator_set_option (xl, aa, vme->value);
- GF_FREE (aa);
- }
-
- if (ret)
- return -1;
- }
-
- if (! strcmp (vme->option, "!nfs-ganesha.host")) {
- ret = gf_asprintf (&aa, "nfs-ganesha.%s.host",
- volinfo->volname);
-
- if (ret != -1) {
- ret = xlator_set_option (xl, aa, vme->value);
- GF_FREE (aa);
- }
-
- if (ret)
- 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;
-
- for (trav = xl->children; trav; trav = trav->next) {
- ret = gf_asprintf (&aa, "auth.addr.%s.%s", trav->xlator->name,
- key);
- if (ret != -1) {
- ret = xlator_set_option (xl, aa, vme->value);
- GF_FREE (aa);
- }
- if (ret)
- return -1;
- }*/
-
- return 0;
-}
-
-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)
-{
- 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");
-
- ret = volgen_graph_set_options_generic (graph, set_dict,
- "client",
- &logger_option_handler);
-
- if (ret)
- gf_log (this->name, GF_LOG_WARNING, "changing logger "
- "of self-heal daemon failed");
-
- ret = volgen_graph_set_options_generic (graph, set_dict,
- "client",
- &log_format_option_handler);
- if (ret)
- gf_log (this->name, GF_LOG_WARNING, "changing log "
- "format of self-heal daemon failed");
-
- ret = volgen_graph_set_options_generic (graph, set_dict,
- "client",
- &log_buf_size_option_handler);
- if (ret)
- gf_log (this->name, GF_LOG_WARNING, "changing "
- "log-buf-size for self-heal daemon failed");
-
- ret = volgen_graph_set_options_generic (graph, set_dict,
- "client",
- &log_flush_timeout_option_handler);
- if (ret)
- gf_log (this->name, GF_LOG_WARNING, "changing "
- "log-flush-timeout for self-heal daemon "
- "failed");
-
-
- ret = dict_reset (set_dict);
- if (ret)
- goto out;
- }
-out:
- if (set_dict)
- dict_unref (set_dict);
- if (!valid_config)
- ret = -EINVAL;
- return ret;
-}
-
-/* builds a graph for nfs server role, with option overrides in mod_dict */
-static int
-build_nfs_graph (volgen_graph_t *graph, dict_t *mod_dict)
-{
- volgen_graph_t cgraph = {0,};
- glusterd_volinfo_t *voliter = NULL;
- xlator_t *this = NULL;
- glusterd_conf_t *priv = NULL;
- dict_t *set_dict = NULL;
- xlator_t *nfsxl = NULL;
- char *skey = NULL;
- int ret = 0;
- char nfs_xprt[16] = {0,};
- char *volname = NULL;
- data_t *data = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- priv = this->private;
- GF_ASSERT (priv);
-
- set_dict = dict_new ();
- if (!set_dict) {
- gf_log ("", GF_LOG_ERROR, "Out of memory");
- return -1;
- }
-
- nfsxl = volgen_graph_add_as (graph, "nfs/server", "nfs-server");
- if (!nfsxl) {
- ret = -1;
- goto out;
- }
- 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;
-
- ret = xlator_set_option (nfsxl, "nfs.drc", "off");
- if (ret)
- goto out;
-
- list_for_each_entry (voliter, &priv->volumes, vol_list) {
- if (voliter->status != GLUSTERD_STATUS_STARTED)
- continue;
-
- if (dict_get_str_boolean (voliter->dict, "nfs.disable", 0))
- continue;
-
- ret = gf_asprintf (&skey, "rpc-auth.addr.%s.allow",
- voliter->volname);
- if (ret == -1) {
- gf_log ("", GF_LOG_ERROR, "Out of memory");
- goto out;
- }
- ret = xlator_set_option (nfsxl, skey, "*");
- GF_FREE (skey);
- if (ret)
- goto out;
-
- ret = gf_asprintf (&skey, "nfs3.%s.volume-id",
- voliter->volname);
- if (ret == -1) {
- gf_log ("", GF_LOG_ERROR, "Out of memory");
- goto out;
- }
- ret = xlator_set_option (nfsxl, skey, uuid_utoa (voliter->volume_id));
- GF_FREE (skey);
- if (ret)
- goto out;
-
- /* If both RDMA and TCP are the transport_type, use TCP for NFS
- * client protocols, because tcp,rdma volume can be created in
- * servers which does not have rdma supported hardware
- * The transport type specified here is client transport type
- * which is used for communication between gluster-nfs and brick
- * processes.
- * User can specify client transport for tcp,rdma volume using
- * nfs.transport-type, if it is not set by user default
- * one will be tcp.
- */
- 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, "performance.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;
-
- ret = dict_set_str (set_dict, "nfs-volume-file", "yes");
- if (ret)
- goto out;
-
- if (mod_dict && (data = dict_get (mod_dict, "volume-name"))) {
- volname = data->data;
- if (strcmp (volname, voliter->volname) == 0)
- dict_copy (mod_dict, set_dict);
- }
-
- ret = build_client_graph (&cgraph, voliter, set_dict);
- 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);
- }
-
- 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;
-}
-
-/****************************
- *
- * Volume generation interface
- *
- ****************************/
-
-
-static void
-get_brick_filepath (char *filename, glusterd_volinfo_t *volinfo,
- glusterd_brickinfo_t *brickinfo)
-{
- char path[PATH_MAX] = {0,};
- char brick[PATH_MAX] = {0,};
- glusterd_conf_t *priv = NULL;
-
- priv = THIS->private;
-
- GLUSTERD_REMOVE_SLASH_FROM_PATH (brickinfo->path, brick);
- GLUSTERD_GET_VOLUME_DIR (path, volinfo, priv);
-
- snprintf (filename, PATH_MAX, "%s/%s.%s.%s.vol",
- path, volinfo->volname,
- brickinfo->hostname,
- 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;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
-
- ret = glusterd_brickinfo_new_from_brick (brick, &brickinfo);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING, "Failed to create brickinfo"
- " for brick %s", brick );
- ret = 0;
- goto out;
- }
- ret = glusterd_volinfo_new (&volinfo);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING, "Failed to create volinfo");
- ret = 0;
- goto out;
- }
- strncpy (volinfo->volname, volname, sizeof (volinfo->volname));
- get_brick_filepath (volfpath, volinfo, brickinfo);
-
- ret = ((strlen(volfpath) < PATH_MAX) &&
- strlen (strrchr(volfpath, '/')) < _POSIX_PATH_MAX);
-
-out:
- if (brickinfo)
- glusterd_brickinfo_delete (brickinfo);
- if (volinfo)
- glusterd_volinfo_unref (volinfo);
- return ret;
-}
-
-static int
-glusterd_generate_brick_volfile (glusterd_volinfo_t *volinfo,
- glusterd_brickinfo_t *brickinfo)
-{
- volgen_graph_t graph = {0,};
- char filename[PATH_MAX] = {0,};
- int ret = -1;
-
- GF_ASSERT (volinfo);
- GF_ASSERT (brickinfo);
-
- get_brick_filepath (filename, volinfo, brickinfo);
-
- ret = build_server_graph (&graph, volinfo, NULL, brickinfo);
- if (!ret)
- ret = volgen_write_volfile (&graph, filename);
-
- volgen_graph_free (&graph);
-
- return ret;
-}
-
-static int
-build_quotad_graph (volgen_graph_t *graph, dict_t *mod_dict)
-{
- 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;
- xlator_t *quotad_xl = NULL;
- char *skey = NULL;
-
- this = THIS;
- priv = this->private;
-
- set_dict = dict_new ();
- if (!set_dict) {
- ret = -ENOMEM;
- goto out;
- }
-
- quotad_xl = volgen_graph_add_as (graph, "features/quotad", "quotad");
- if (!quotad_xl) {
- ret = -1;
- goto out;
- }
-
- list_for_each_entry (voliter, &priv->volumes, vol_list) {
- if (voliter->status != GLUSTERD_STATUS_STARTED)
- continue;
-
- if (1 != glusterd_is_volume_quota_enabled (voliter))
- continue;
-
- 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);
-
- ret = gf_asprintf(&skey, "%s.volume-id", voliter->volname);
- if (ret == -1) {
- gf_log("", GF_LOG_ERROR, "Out of memory");
- goto out;
- }
- ret = xlator_set_option(quotad_xl, skey, voliter->volname);
- GF_FREE(skey);
- if (ret)
- goto out;
-
- memset (&cgraph, 0, sizeof (cgraph));
- ret = volgen_graph_build_clients (&cgraph, voliter, set_dict,
- NULL);
- if (ret)
- goto out;
-
- ret = volume_volgen_graph_build_clusters (&cgraph, voliter,
- _gf_true);
- if (ret) {
- ret = -1;
- 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);
- }
- 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;
- }
-
-out:
- if (set_dict)
- dict_unref (set_dict);
- return ret;
-}
-
-static void
-get_vol_tstamp_file (char *filename, glusterd_volinfo_t *volinfo)
-{
- glusterd_conf_t *priv = NULL;
-
- priv = THIS->private;
-
- GLUSTERD_GET_VOLUME_DIR (filename, volinfo, priv);
- strncat (filename, "/marker.tstamp",
- PATH_MAX - strlen(filename) - 1);
-}
-
-static void
-get_parent_vol_tstamp_file (char *filename, glusterd_volinfo_t *volinfo)
-{
- glusterd_conf_t *priv = NULL;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- priv = this->private;
- GF_ASSERT (priv);
-
- snprintf (filename, PATH_MAX, "%s/vols/%s", priv->workdir,
- volinfo->parent_volname);
- strncat (filename, "/marker.tstamp",
- PATH_MAX - strlen(filename) - 1);
-}
-
-int
-generate_brick_volfiles (glusterd_volinfo_t *volinfo)
-{
- glusterd_brickinfo_t *brickinfo = NULL;
- char tstamp_file[PATH_MAX] = {0,};
- char parent_tstamp_file[PATH_MAX] = {0,};
- int ret = -1;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
-
- ret = glusterd_volinfo_get_boolean (volinfo, VKEY_MARKER_XTIME);
- if (ret == -1)
- return -1;
-
- get_vol_tstamp_file (tstamp_file, volinfo);
-
- if (ret) {
- ret = open (tstamp_file, O_WRONLY|O_CREAT|O_EXCL, 0600);
- if (ret == -1 && errno == EEXIST) {
- gf_log (this->name, GF_LOG_DEBUG,
- "timestamp file exist");
- ret = -2;
- }
- if (ret == -1) {
- gf_log (this->name, GF_LOG_ERROR, "failed to create "
- "%s (%s)", tstamp_file, strerror (errno));
- return -1;
- }
- if (ret >= 0) {
- close (ret);
- /* If snap_volume, retain timestamp for marker.tstamp
- * from parent. Geo-replication depends on mtime of
- * 'marker.tstamp' to decide the volume-mark, i.e.,
- * geo-rep start time just after session is created.
- */
- if (volinfo->is_snap_volume) {
- get_parent_vol_tstamp_file (parent_tstamp_file,
- volinfo);
- ret = gf_set_timestamp (parent_tstamp_file,
- tstamp_file);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Unable to set atime and mtime"
- " of %s as of %s", tstamp_file,
- parent_tstamp_file);
- goto out;
- }
- }
- }
- } else {
- ret = unlink (tstamp_file);
- if (ret == -1 && errno == ENOENT)
- ret = 0;
- if (ret == -1) {
- gf_log (this->name, GF_LOG_ERROR, "failed to unlink "
- "%s (%s)", tstamp_file, strerror (errno));
- return -1;
- }
- }
-
- list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) {
- gf_log (this->name, GF_LOG_DEBUG,
- "Found a brick - %s:%s", brickinfo->hostname,
- brickinfo->path);
-
- ret = glusterd_generate_brick_volfile (volinfo, brickinfo);
- if (ret)
- goto out;
-
- }
-
- ret = 0;
-
-out:
- gf_log (this->name, GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-
-static int
-generate_single_transport_client_volfile (glusterd_volinfo_t *volinfo,
- char *filepath, dict_t *dict)
-{
- volgen_graph_t graph = {0,};
- int ret = -1;
-
- ret = build_client_graph (&graph, volinfo, dict);
- if (!ret)
- ret = volgen_write_volfile (&graph, filepath);
-
- volgen_graph_free (&graph);
-
- return ret;
-}
-
-static void
-enumerate_transport_reqs (gf_transport_type type, char **types)
-{
- 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;
- }
-}
-
-int
-generate_client_volfiles (glusterd_volinfo_t *volinfo,
- glusterd_client_type_t client_type)
-{
- int i = 0;
- int ret = -1;
- char filepath[PATH_MAX] = {0,};
- char *types[] = {NULL, NULL, NULL};
- dict_t *dict = NULL;
- xlator_t *this = NULL;
- gf_transport_type type = GF_TRANSPORT_TCP;
-
- this = THIS;
-
- 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]);
-
- ret = dict_set_uint32 (dict, "trusted-client", client_type);
- if (ret)
- goto out;
-
- if (client_type == GF_CLIENT_TRUSTED) {
- ret = glusterd_get_trusted_client_filepath (filepath,
- volinfo,
- type);
- } else {
- ret = glusterd_get_client_filepath (filepath,
- volinfo,
- type);
- }
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Received invalid transport-type");
- goto out;
- }
-
- ret = generate_single_transport_client_volfile (volinfo,
- filepath,
- dict);
- if (ret)
- goto out;
- }
-
- /* Generate volfile for rebalance process */
- ret = dict_set_int32 (dict, "rebalance-volfile-creation", _gf_true);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to set rebalance-volfile-creation");
- goto out;
- }
-
- glusterd_get_rebalance_volfile (volinfo, filepath, PATH_MAX);
-
- ret = generate_single_transport_client_volfile (volinfo,
- filepath,
- dict);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to create rebalance volfile for %s",
- volinfo->volname);
- goto out;
- }
-
-out:
- if (dict)
- dict_unref (dict);
-
- gf_log ("", GF_LOG_TRACE, "Returning %d", ret);
- return ret;
-}
-
-int
-glusterd_create_rb_volfiles (glusterd_volinfo_t *volinfo,
- glusterd_brickinfo_t *brickinfo)
-{
- int ret = -1;
-
- ret = glusterd_generate_brick_volfile (volinfo, brickinfo);
- if (!ret)
- ret = generate_client_volfiles (volinfo, GF_CLIENT_TRUSTED);
- if (!ret)
- ret = glusterd_fetchspec_notify (THIS);
-
- return ret;
-}
-
-int
-glusterd_create_volfiles (glusterd_volinfo_t *volinfo)
-{
- int ret = -1;
- xlator_t *this = NULL;
-
- this = THIS;
-
- ret = generate_brick_volfiles (volinfo);
- if (ret) {
- gf_log (this->name, 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);
- if (ret)
- gf_log (this->name, GF_LOG_ERROR,
- "Could not generate client volfiles");
-
-out:
- return ret;
-}
-
-int
-glusterd_create_volfiles_and_notify_services (glusterd_volinfo_t *volinfo)
-{
- int ret = -1;
- xlator_t *this = NULL;
-
- this = THIS;
-
- ret = glusterd_create_volfiles (volinfo);
- if (ret)
- goto out;
-
- 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)
-{
- volgen_graph_t graph = {0,};
- int ret = -1;
-
- ret = builder (&graph, mod_dict);
- if (!ret)
- ret = volgen_write_volfile (&graph, filepath);
-
- volgen_graph_free (&graph);
-
- return ret;
-}
-
-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;
-
- ret = glusterd_check_files_identical (nfsvol, tmpnfsvol,
- identical);
- if (ret)
- goto out;
-
-out:
- if (need_unlink)
- unlink (tmpnfsvol);
-
- if (tmp_fd >= 0)
- close (tmp_fd);
-
- return ret;
-}
-
-int
-glusterd_check_nfs_topology_identical (gf_boolean_t *identical)
-{
- char nfsvol[PATH_MAX] = {0,};
- char tmpnfsvol[PATH_MAX] = {0,};
- glusterd_conf_t *conf = NULL;
- xlator_t *this = THIS;
- int ret = -1;
- int tmpclean = 0;
- int tmpfd = -1;
-
- if ((!identical) || (!this) || (!this->private))
- goto out;
-
- conf = (glusterd_conf_t *) this->private;
-
- /* Fetch the original NFS volfile */
- glusterd_get_nodesvc_volfile ("nfs", conf->workdir,
- nfsvol, sizeof (nfsvol));
-
- /* Create the temporary NFS volfile */
- snprintf (tmpnfsvol, sizeof (tmpnfsvol), "/tmp/gnfs-XXXXXX");
- tmpfd = mkstemp (tmpnfsvol);
- if (tmpfd < 0) {
- gf_log (this->name, GF_LOG_WARNING,
- "Unable to create temp file %s: (%s)",
- tmpnfsvol, strerror (errno));
- goto out;
- }
-
- tmpclean = 1; /* SET the flag to unlink() tmpfile */
-
- ret = glusterd_create_global_volfile (build_nfs_graph,
- tmpnfsvol, NULL);
- if (ret)
- goto out;
-
- /* Compare the topology of volfiles */
- ret = glusterd_check_topology_identical (nfsvol, tmpnfsvol,
- identical);
-out:
- if (tmpfd >= 0)
- close (tmpfd);
- if (tmpclean)
- unlink (tmpnfsvol);
- return ret;
-}
-
-int
-glusterd_generate_snapd_volfile (volgen_graph_t *graph,
- glusterd_volinfo_t *volinfo)
-{
- xlator_t *xl = NULL;
- char *username = NULL;
- char *passwd = NULL;
- int ret = 0;
- char key [PATH_MAX] = {0, };
- dict_t *set_dict = NULL;
- char *loglevel = NULL;
- char *xlator = NULL;
- char *value = NULL;
-
- set_dict = dict_copy (volinfo->dict, NULL);
- if (!set_dict)
- return -1;
-
- ret = dict_get_str (set_dict, "xlator", &xlator);
- 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");
- return -1;
- }
- }
-
- xl = volgen_graph_add (graph, "features/snapview-server",
- volinfo->volname);
- if (!xl)
- return -1;
-
- ret = xlator_set_option (xl, "volname", volinfo->volname);
- if (ret)
- return -1;
-
- xl = volgen_graph_add (graph, "performance/io-threads",
- volinfo->volname);
- if (!xl)
- return -1;
-
- snprintf (key, sizeof (key), "snapd-%s", volinfo->volname);
- xl = volgen_graph_add_as (graph, "debug/io-stats", key);
- if (!xl)
- return -1;
-
- xl = volgen_graph_add (graph, "protocol/server", volinfo->volname);
- if (!xl)
- return -1;
-
- ret = xlator_set_option (xl, "transport-type", "tcp");
- if (ret)
- return -1;
-
- if (dict_get_str (set_dict, SSL_CERT_DEPTH_OPT, &value) == 0) {
- ret = xlator_set_option (xl, "ssl-cert-depth", value);
- if (ret) {
- gf_log ("glusterd", GF_LOG_WARNING,
- "failed to set ssl-cert-depth");
- return -1;
- }
- }
-
- if (dict_get_str (set_dict, SSL_CIPHER_LIST_OPT, &value) == 0) {
- ret = xlator_set_option (xl, "ssl-cipher-list", value);
- if (ret) {
- gf_log ("glusterd", GF_LOG_WARNING,
- "failed to set ssl-cipher-list");
- return -1;
- }
- }
-
- username = glusterd_auth_get_username (volinfo);
- passwd = glusterd_auth_get_password (volinfo);
-
- snprintf (key, sizeof (key), "auth.login.snapd-%s.allow",
- volinfo->volname);
- ret = xlator_set_option (xl, key, username);
- if (ret)
- return -1;
-
- snprintf (key, sizeof (key), "auth.login.%s.password", username);
- ret = xlator_set_option (xl, key, passwd);
- 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);
-
- return ret;
-}
-
-int
-glusterd_create_snapd_volfile (glusterd_volinfo_t *volinfo)
-{
- volgen_graph_t graph = {0,};
- int ret = -1;
- char filename [PATH_MAX] = {0,};
-
- glusterd_get_snapd_volfile (volinfo, filename, PATH_MAX);
-
- ret = glusterd_generate_snapd_volfile (&graph, volinfo);
- if (!ret)
- ret = volgen_write_volfile (&graph, filename);
-
- volgen_graph_free (&graph);
-
- return ret;
-}
-
-int
-glusterd_create_quotad_volfile (void *data)
-{
- char filepath[PATH_MAX] = {0,};
- glusterd_conf_t *conf = THIS->private;
-
- glusterd_get_nodesvc_volfile ("quotad", conf->workdir,
- filepath, sizeof (filepath));
- return glusterd_create_global_volfile (build_quotad_graph,
- filepath, NULL);
-}
-
-
-int
-glusterd_delete_volfile (glusterd_volinfo_t *volinfo,
- glusterd_brickinfo_t *brickinfo)
-{
- int ret = 0;
- char filename[PATH_MAX] = {0,};
-
- GF_ASSERT (volinfo);
- GF_ASSERT (brickinfo);
-
- get_brick_filepath (filename, volinfo, brickinfo);
- ret = unlink (filename);
- if (ret)
- gf_log ("glusterd", GF_LOG_ERROR, "failed to delete file: %s, "
- "reason: %s", filename, strerror (errno));
- return ret;
-}
-
-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,};
- xlator_t *this = THIS;
-
- GF_ASSERT (this);
-
- 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 (this->name, 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 = dict_set_str (val_dict, "volume-name", volinfo->volname);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to set volume name");
- goto out;
- }
-
- ret = build_nfs_graph (&graph, val_dict);
- if (!ret)
- ret = graph_reconf_validateopt (&graph.graph, op_errstr);
-
- volgen_graph_free (&graph);
-
-out:
- if (dict_get (val_dict, "volume-name"))
- dict_del (val_dict, "volume-name");
- gf_log (this->name, GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-
-
-int
-validate_clientopts (glusterd_volinfo_t *volinfo,
- dict_t *val_dict,
- char **op_errstr)
-{
- volgen_graph_t graph = {0,};
- int ret = -1;
-
- GF_ASSERT (volinfo);
-
- graph.errstr = op_errstr;
-
- ret = build_client_graph (&graph, volinfo, val_dict);
- if (!ret)
- ret = graph_reconf_validateopt (&graph.graph, op_errstr);
-
- volgen_graph_free (&graph);
-
- gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-
-int
-validate_brickopts (glusterd_volinfo_t *volinfo,
- glusterd_brickinfo_t *brickinfo,
- dict_t *val_dict,
- char **op_errstr)
-{
- volgen_graph_t graph = {0,};
- int ret = -1;
-
- GF_ASSERT (volinfo);
-
- graph.errstr = op_errstr;
-
- ret = build_server_graph (&graph, volinfo, val_dict, brickinfo);
- if (!ret)
- ret = graph_reconf_validateopt (&graph.graph, op_errstr);
-
- volgen_graph_free (&graph);
-
- gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-
-int
-glusterd_validate_brickreconf (glusterd_volinfo_t *volinfo,
- dict_t *val_dict,
- char **op_errstr)
-{
- glusterd_brickinfo_t *brickinfo = NULL;
- int ret = -1;
-
- list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) {
- gf_log ("", GF_LOG_DEBUG,
- "Validating %s", brickinfo->hostname);
-
- ret = validate_brickopts (volinfo, brickinfo, val_dict,
- op_errstr);
- if (ret)
- goto out;
- }
-
- ret = 0;
-
-out:
- return ret;
-}
-
-static int
-_check_globalopt (dict_t *this, char *key, data_t *value, void *ret_val)
-{
- int *ret = NULL;
-
- ret = ret_val;
- if (*ret)
- return 0;
- if (!glusterd_check_globaloption (key))
- *ret = 1;
-
- return 0;
-}
-
-int
-glusterd_validate_globalopts (glusterd_volinfo_t *volinfo,
- dict_t *val_dict, char **op_errstr)
-{
- int ret = 0;
-
- dict_foreach (val_dict, _check_globalopt, &ret);
- if (ret) {
- *op_errstr = gf_strdup ( "option specified is not a global option");
- return -1;
- }
- ret = glusterd_validate_brickreconf (volinfo, val_dict, op_errstr);
-
- if (ret) {
- gf_log ("", GF_LOG_DEBUG,
- "Could not Validate bricks");
- goto out;
- }
-
- ret = validate_clientopts (volinfo, val_dict, op_errstr);
- if (ret) {
- gf_log ("", GF_LOG_DEBUG,
- "Could not Validate client");
- goto out;
- }
-
- 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;
-}
-
-static int
-_check_localopt (dict_t *this, char *key, data_t *value, void *ret_val)
-{
- int *ret = NULL;
-
- ret = ret_val;
- if (*ret)
- return 0;
- if (!glusterd_check_localoption (key))
- *ret = 1;
-
- return 0;
-}
-
-int
-glusterd_validate_reconfopts (glusterd_volinfo_t *volinfo, dict_t *val_dict,
- char **op_errstr)
-{
- int ret = 0;
-
- dict_foreach (val_dict, _check_localopt, &ret);
- if (ret) {
- *op_errstr = gf_strdup ( "option specified is not a local option");
- return -1;
- }
- ret = glusterd_validate_brickreconf (volinfo, val_dict, op_errstr);
-
- if (ret) {
- gf_log ("", GF_LOG_DEBUG,
- "Could not Validate bricks");
- goto out;
- }
-
- ret = validate_clientopts (volinfo, val_dict, op_errstr);
- if (ret) {
- gf_log ("", GF_LOG_DEBUG,
- "Could not Validate client");
- goto out;
- }
-
- 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;
-}
-
-static struct volopt_map_entry *
-_gd_get_vmep (char *key) {
- char *completion = NULL;
- struct volopt_map_entry *vmep = NULL;
- int ret = 0;
-
- COMPLETE_OPTION ((char *)key, completion, ret);
- for (vmep = glusterd_volopt_map; vmep->key; vmep++) {
- if (strcmp (vmep->key, key) == 0)
- return vmep;
- }
-
- return NULL;
-}
-
-uint32_t
-glusterd_get_op_version_for_key (char *key)
-{
- struct volopt_map_entry *vmep = NULL;
-
- GF_ASSERT (key);
-
- vmep = _gd_get_vmep (key);
- if (vmep)
- return vmep->op_version;
-
- return 0;
-}
-
-gf_boolean_t
-gd_is_client_option (char *key)
-{
- struct volopt_map_entry *vmep = NULL;
-
- GF_ASSERT (key);
-
- vmep = _gd_get_vmep (key);
- if (vmep && (vmep->flags & OPT_FLAG_CLIENT_OPT))
- return _gf_true;
-
- return _gf_false;
-}
-
-gf_boolean_t
-gd_is_xlator_option (char *key)
-{
- struct volopt_map_entry *vmep = NULL;
-
- GF_ASSERT (key);
-
- vmep = _gd_get_vmep (key);
- if (vmep && (vmep->flags & OPT_FLAG_XLATOR_OPT))
- return _gf_true;
-
- return _gf_false;
-}
-
-volume_option_type_t
-_gd_get_option_type (char *key)
-{
- struct volopt_map_entry *vmep = NULL;
- void *dl_handle = NULL;
- volume_opt_list_t vol_opt_list = {{0},};
- int ret = -1;
- volume_option_t *opt = NULL;
- char *xlopt_key = NULL;
- volume_option_type_t opt_type = GF_OPTION_TYPE_MAX;
-
- GF_ASSERT (key);
-
- vmep = _gd_get_vmep (key);
-
- if (vmep) {
- INIT_LIST_HEAD (&vol_opt_list.list);
- ret = xlator_volopt_dynload (vmep->voltype, &dl_handle,
- &vol_opt_list);
- if (ret)
- goto out;
-
- if (_get_xlator_opt_key_from_vme (vmep, &xlopt_key))
- goto out;
-
- opt = xlator_volume_option_get_list (&vol_opt_list, xlopt_key);
- _free_xlator_opt_key (xlopt_key);
-
- if (opt)
- opt_type = opt->type;
- }
-
-out:
- if (dl_handle) {
- dlclose (dl_handle);
- dl_handle = NULL;
- }
-
- return opt_type;
-}
-
-gf_boolean_t
-gd_is_boolean_option (char *key)
-{
- GF_ASSERT (key);
-
- if (GF_OPTION_TYPE_BOOL == _gd_get_option_type (key))
- return _gf_true;
-
- return _gf_false;
-}
diff --git a/xlators/mgmt/glusterd/src/glusterd-volgen.h b/xlators/mgmt/glusterd/src/glusterd-volgen.h
deleted file mode 100644
index 71b6a770fac..00000000000
--- a/xlators/mgmt/glusterd/src/glusterd-volgen.h
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- Copyright (c) 2006-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 _GLUSTERD_VOLGEN_H_
-#define _GLUSTERD_VOLGEN_H_
-
-#ifndef _CONFIG_H
-#define _CONFIG_H
-#include "config.h"
-#endif
-
-#include "glusterd.h"
-
-/* volopt map key name definitions */
-
-#define VKEY_DIAG_CNT_FOP_HITS "diagnostics.count-fop-hits"
-#define VKEY_DIAG_LAT_MEASUREMENT "diagnostics.latency-measurement"
-#define VKEY_FEATURES_LIMIT_USAGE "features.limit-usage"
-#define VKEY_FEATURES_SOFT_LIMIT "features.soft-limit"
-#define VKEY_MARKER_XTIME GEOREP".indexing"
-#define VKEY_MARKER_XTIME_FORCE GEOREP".ignore-pid-check"
-#define VKEY_CHANGELOG "changelog.changelog"
-#define VKEY_FEATURES_QUOTA "features.quota"
-
-#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"
-
-#define SSL_CERT_DEPTH_OPT "ssl.certificate-depth"
-#define SSL_CIPHER_LIST_OPT "ssl.cipher-list"
-
-
-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 = 0x01, // option needs force to be reset
- OPT_FLAG_XLATOR_OPT = 0x02, // option enables/disables xlators
- OPT_FLAG_CLIENT_OPT = 0x04, // option affects clients
-} gd_volopt_flags_t;
-
-typedef enum {
- GF_XLATOR_POSIX = 0,
- GF_XLATOR_ACL,
- GF_XLATOR_LOCKS,
- GF_XLATOR_IOT,
- GF_XLATOR_INDEX,
- GF_XLATOR_MARKER,
- GF_XLATOR_IO_STATS,
- GF_XLATOR_BD,
- GF_XLATOR_NONE,
-} glusterd_server_xlator_t;
-
-/* As of now debug xlators can be loaded only below fuse in the client
- * graph via cli. More xlators can be added below when the cli option
- * for adding debug xlators anywhere in the client graph has to be made
- * available.
- */
-typedef enum {
- GF_CLNT_XLATOR_FUSE = 0,
- GF_CLNT_XLATOR_NONE,
-} glusterd_client_xlator_t;
-
-typedef enum { DOC, NO_DOC, GLOBAL_DOC, GLOBAL_NO_DOC } option_type_t;
-
-typedef int (*vme_option_validation) (dict_t *dict, char *key, char *value,
- char **op_errstr);
-
-struct volopt_map_entry {
- char *key;
- char *voltype;
- char *option;
- char *value;
- option_type_t type;
- uint32_t flags;
- uint32_t op_version;
- char *description;
- vme_option_validation validate_fn;
- /* If client_option is true, the option affects clients.
- * this is used to calculate client-op-version of volumes
- */
- //gf_boolean_t client_option;
-};
-
-int glusterd_create_rb_volfiles (glusterd_volinfo_t *volinfo,
- glusterd_brickinfo_t *brickinfo);
-
-int glusterd_create_volfiles (glusterd_volinfo_t *volinfo);
-
-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_create_quotad_volfile ();
-int glusterd_create_snapd_volfile (glusterd_volinfo_t *volinfo);
-
-int glusterd_delete_volfile (glusterd_volinfo_t *volinfo,
- glusterd_brickinfo_t *brickinfo);
-int
-glusterd_delete_snap_volfile (glusterd_volinfo_t *volinfo,
- glusterd_volinfo_t *snap_volinfo,
- glusterd_brickinfo_t *brickinfo);
-
-int glusterd_volinfo_get (glusterd_volinfo_t *volinfo, char *key, char **value);
-int glusterd_volinfo_get_boolean (glusterd_volinfo_t *volinfo, char *key);
-
-int glusterd_validate_globalopts (glusterd_volinfo_t *volinfo, dict_t *val_dict, char **op_errstr);
-
-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 generate_snap_brick_volfiles (glusterd_volinfo_t *volinfo,
- glusterd_volinfo_t *snap_volinfo);
-int generate_client_volfiles (glusterd_volinfo_t *volinfo,
- glusterd_client_type_t client_type);
-int
-generate_snap_client_volfiles (glusterd_volinfo_t *actual_volinfo,
- glusterd_volinfo_t *snap_volinfo,
- glusterd_client_type_t client_type,
- gf_boolean_t vol_restore);
-int glusterd_get_volopt_content (dict_t *dict, 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);
-int
-glusterd_check_nfs_topology_identical (gf_boolean_t *identical);
-
-uint32_t
-glusterd_get_op_version_for_key (char *key);
-
-gf_boolean_t
-gd_is_client_option (char *key);
-
-gf_boolean_t
-gd_is_xlator_option (char *key);
-
-gf_boolean_t
-gd_is_boolean_option (char *key);
-
-#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 cb5d6f832f6..00000000000
--- a/xlators/mgmt/glusterd/src/glusterd-volume-ops.c
+++ /dev/null
@@ -1,2533 +0,0 @@
-/*
- Copyright (c) 2011-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
-
-#ifdef HAVE_BD_XLATOR
-#include <lvm2app.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 "glusterd-messages.h"
-#include "run.h"
-
-#define glusterd_op_start_volume_args_get(dict, volname, flags) \
- glusterd_op_stop_volume_args_get (dict, volname, flags)
-
-extern int
-_get_slave_status (dict_t *this, char *key, data_t *value, void *data);
-
-int
-__glusterd_handle_create_volume (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;
- 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};
- int32_t type = 0;
- char *username = NULL;
- char *password = NULL;
-
- GF_ASSERT (req);
-
- this = THIS;
- GF_ASSERT(this);
-
- ret = -1;
- ret = xdr_to_generic (req->msg[0], &cli_req, (xdrproc_t)xdr_gf_cli_req);
- if (ret < 0) {
- req->rpc_err = GARBAGE_ARGS;
- snprintf (err_str, sizeof (err_str), "Failed to decode request "
- "received from cli");
- gf_log (this->name, GF_LOG_ERROR, "%s", err_str);
- goto out;
- }
-
- gf_log (this->name, GF_LOG_DEBUG, "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 (this->name, GF_LOG_ERROR,
- "failed to "
- "unserialize req-buffer to dictionary");
- snprintf (err_str, sizeof (err_str), "Unable to decode "
- "the command");
- goto out;
- } else {
- dict->extra_stdfree = cli_req.dict.dict_val;
- }
- }
-
- ret = dict_get_str (dict, "volname", &volname);
-
- if (ret) {
- snprintf (err_str, sizeof (err_str), "Unable to get volume "
- "name");
- gf_log (this->name, GF_LOG_ERROR, "%s", err_str);
- goto out;
- }
-
- if ((ret = glusterd_check_volume_exists (volname))) {
- snprintf (err_str, sizeof (err_str), "Volume %s already exists",
- volname);
- gf_log (this->name, GF_LOG_ERROR, "%s", err_str);
- goto out;
- }
-
- ret = dict_get_int32 (dict, "count", &brick_count);
- if (ret) {
- snprintf (err_str, sizeof (err_str), "Unable to get brick count"
- " for volume %s", volname);
- gf_log (this->name, GF_LOG_ERROR, "%s", err_str);
- goto out;
- }
-
- ret = dict_get_int32 (dict, "type", &type);
- if (ret) {
- snprintf (err_str, sizeof (err_str), "Unable to get type of "
- "volume %s", volname);
- gf_log (this->name, GF_LOG_ERROR, "%s", err_str);
- goto out;
- }
-
- ret = dict_get_str (dict, "transport", &trans_type);
- if (ret) {
- snprintf (err_str, sizeof (err_str), "Unable to get "
- "transport-type of volume %s", volname);
- gf_log (this->name, GF_LOG_ERROR, "%s", err_str);
- goto out;
- }
- ret = dict_get_str (dict, "bricks", &bricks);
- if (ret) {
- snprintf (err_str, sizeof (err_str), "Unable to get bricks for "
- "volume %s", volname);
- gf_log (this->name, GF_LOG_ERROR, "%s", err_str);
- goto out;
- }
-
- if (!dict_get (dict, "force")) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to get 'force' flag");
- 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) {
- snprintf (err_str, sizeof (err_str), "Unable to set volume "
- "id of volume %s", volname);
- gf_log (this->name, GF_LOG_ERROR, "%s", err_str);
- goto out;
- }
- free_ptr = 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) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to set username for "
- "volume %s", volname);
- goto out;
- }
-
- uuid_generate (tmp_uuid);
- password = gf_strdup (uuid_utoa (tmp_uuid));
- ret = dict_set_dynstr (dict, "internal-password", password);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to set password for "
- "volume %s", volname);
- goto out;
- }
-
- ret = glusterd_op_begin_synctask (req, GD_OP_CREATE_VOLUME, dict);
-
-out:
- if (ret) {
- 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_to_cli (req, cli_rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gf_cli_rsp, dict);
- ret = 0; //Client response sent, prevent second response
- }
-
- GF_FREE(free_ptr);
-
- return ret;
-}
-
-int
-glusterd_handle_create_volume (rpcsvc_request_t *req)
-{
- return glusterd_big_locked_handler (req,
- __glusterd_handle_create_volume);
-}
-
-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;
- char errstr[2048] = {0,};
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (req);
-
- ret = xdr_to_generic (req->msg[0], &cli_req, (xdrproc_t)xdr_gf_cli_req);
- if (ret < 0) {
- snprintf (errstr, sizeof (errstr), "Failed to decode message "
- "received from cli");
- req->rpc_err = GARBAGE_ARGS;
- gf_log (this->name, sizeof (errstr), "%s", errstr);
- 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");
- snprintf (errstr, sizeof (errstr), "Unable to decode "
- "the command");
- goto out;
- }
- }
-
- ret = dict_get_str (dict, "volname", &volname);
- if (ret) {
- snprintf (errstr, sizeof (errstr), "Unable to get volume name");
- gf_log (this->name, GF_LOG_ERROR, "%s", errstr);
- goto out;
- }
-
- gf_log (this->name, GF_LOG_DEBUG, "Received start vol req"
- " for volume %s", volname);
-
- ret = glusterd_op_begin_synctask (req, GD_OP_START_VOLUME, dict);
-
-out:
- free (cli_req.dict.dict_val); //its malloced by xdr
-
- if (ret) {
- if(errstr[0] == '\0')
- snprintf (errstr, sizeof (errstr), "Operation failed");
- ret = glusterd_op_send_cli_response (cli_op, ret, 0, req,
- dict, errstr);
- }
-
- return ret;
-}
-
-int
-glusterd_handle_cli_start_volume (rpcsvc_request_t *req)
-{
- return glusterd_big_locked_handler (req,
- __glusterd_handle_cli_start_volume);
-}
-
-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;
- char err_str[2048] = {0,};
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (req);
-
- ret = xdr_to_generic (req->msg[0], &cli_req, (xdrproc_t)xdr_gf_cli_req);
- if (ret < 0) {
- snprintf (err_str, sizeof (err_str), "Failed to decode message "
- "received from cli");
- req->rpc_err = GARBAGE_ARGS;
- gf_log (this->name, GF_LOG_ERROR, "%s", err_str);
- 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");
- snprintf (err_str, sizeof (err_str), "Unable to decode "
- "the command");
- goto out;
- }
- }
-
- ret = dict_get_str (dict, "volname", &dup_volname);
-
- if (ret) {
- snprintf (err_str, sizeof (err_str), "Failed to get volume "
- "name");
- gf_log (this->name, GF_LOG_ERROR, "%s", err_str);
- goto out;
- }
-
- gf_log (this->name, GF_LOG_DEBUG, "Received stop vol req "
- "for volume %s", dup_volname);
-
- ret = glusterd_op_begin_synctask (req, GD_OP_STOP_VOLUME, dict);
-
-out:
- free (cli_req.dict.dict_val); //its malloced by xdr
-
- if (ret) {
- if (err_str[0] == '\0')
- snprintf (err_str, sizeof (err_str),
- "Operation failed");
- ret = glusterd_op_send_cli_response (cli_op, ret, 0, req,
- dict, err_str);
- }
-
- return ret;
-}
-
-int
-glusterd_handle_cli_stop_volume (rpcsvc_request_t *req)
-{
- return glusterd_big_locked_handler (req,
- __glusterd_handle_cli_stop_volume);
-}
-
-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;
- char err_str[2048]= {0,};
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
-
- GF_ASSERT (req);
-
- ret = xdr_to_generic (req->msg[0], &cli_req, (xdrproc_t)xdr_gf_cli_req);
- if (ret < 0) {
- snprintf (err_str, sizeof (err_str), "Failed to decode request "
- "received from cli");
- gf_log (this->name, GF_LOG_ERROR, "%s", err_str);
- 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");
- snprintf (err_str, sizeof (err_str), "Unable to decode "
- "the command");
- goto out;
- }
- }
-
- ret = dict_get_str (dict, "volname", &volname);
- if (ret) {
- snprintf (err_str, sizeof (err_str), "Failed to get volume "
- "name");
- gf_log (this->name, GF_LOG_ERROR, "%s", err_str);
- req->rpc_err = GARBAGE_ARGS;
- goto out;
- }
-
- gf_log (this->name, GF_LOG_DEBUG, "Received delete vol req"
- "for volume %s", volname);
-
- ret = glusterd_op_begin_synctask (req, GD_OP_DELETE_VOLUME, dict);
-
-out:
- free (cli_req.dict.dict_val); //its malloced by xdr
-
- if (ret) {
- if (err_str[0] == '\0')
- snprintf (err_str, sizeof (err_str),
- "Operation failed");
- ret = glusterd_op_send_cli_response (cli_op, ret, 0, req,
- dict, err_str);
- }
-
- return ret;
-}
-
-int
-glusterd_handle_cli_delete_volume (rpcsvc_request_t *req)
-{
- return glusterd_big_locked_handler (req,
- __glusterd_handle_cli_delete_volume);
-}
-
-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[2048] = {0,};
-
- GF_ASSERT (req);
-
- ret = xdr_to_generic (req->msg[0], &cli_req, (xdrproc_t)xdr_gf_cli_req);
- if (ret < 0) {
- //failed to decode msg;
- req->rpc_err = GARBAGE_ARGS;
- goto out;
- }
-
- this = THIS;
- GF_ASSERT (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");
- snprintf (op_errstr, sizeof (op_errstr),
- "Unable to decode the command");
- goto out;
- } else {
- dict->extra_stdfree = cli_req.dict.dict_val;
- }
- }
-
- ret = dict_get_str (dict, "volname", &volname);
- if (ret) {
- snprintf (op_errstr, sizeof (op_errstr), "Unable to find "
- "volume name");
- gf_log (this->name, GF_LOG_ERROR, "%s", op_errstr);
- 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) {
- snprintf (op_errstr, sizeof (op_errstr),
- "Volume %s does not exist", volname);
- gf_log (this->name, GF_LOG_ERROR, "%s", op_errstr);
- 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_synctask (req, GD_OP_HEAL_VOLUME, dict);
-
-out:
- if (ret) {
- if (op_errstr[0] == '\0')
- snprintf (op_errstr, sizeof (op_errstr),
- "operation failed");
- ret = glusterd_op_send_cli_response (cli_op, ret, 0, req,
- dict, op_errstr);
- }
-
- return ret;
-}
-
-int
-glusterd_handle_cli_heal_volume (rpcsvc_request_t *req)
-{
- return glusterd_big_locked_handler (req,
- __glusterd_handle_cli_heal_volume);
-}
-
-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;
- glusterd_op_t cli_op = GD_OP_STATEDUMP_VOLUME;
- char err_str[2048] = {0,};
- xlator_t *this = NULL;
- glusterd_conf_t *priv = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- priv = this->private;
- GF_ASSERT (priv);
-
- GF_ASSERT (req);
-
- ret = -1;
- ret = xdr_to_generic (req->msg[0], &cli_req, (xdrproc_t)xdr_gf_cli_req);
- if (ret < 0) {
- 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");
- snprintf (err_str, sizeof (err_str), "Unable to "
- "decode the command");
- goto out;
- }
- }
- ret = dict_get_str (dict, "volname", &volname);
- if (ret) {
- snprintf (err_str, sizeof (err_str), "Unable to get the volume "
- "name");
- gf_log (this->name, GF_LOG_ERROR, "%s", err_str);
- goto out;
- }
-
- ret = dict_get_str (dict, "options", &options);
- if (ret) {
- snprintf (err_str, sizeof (err_str), "Unable to get options");
- gf_log (this->name, GF_LOG_ERROR, "%s", err_str);
- goto out;
- }
-
- ret = dict_get_int32 (dict, "option_cnt", &option_cnt);
- if (ret) {
- snprintf (err_str , sizeof (err_str), "Unable to get option "
- "count");
- gf_log (this->name, GF_LOG_ERROR, "%s", err_str);
- goto out;
- }
-
- if (priv->op_version == GD_OP_VERSION_MIN &&
- strstr (options, "quotad")) {
- snprintf (err_str, sizeof (err_str), "The cluster is operating "
- "at op-version 1. Taking quotad's statedump is "
- "disallowed in this state");
- ret = -1;
- goto out;
- }
-
- gf_log (this->name, GF_LOG_INFO, "Received statedump request for "
- "volume %s with options %s", volname, options);
-
- ret = glusterd_op_begin_synctask (req, GD_OP_STATEDUMP_VOLUME, dict);
-
-out:
- if (ret) {
- if (err_str[0] == '\0')
- snprintf (err_str, sizeof (err_str),
- "Operation failed");
- ret = glusterd_op_send_cli_response (cli_op, ret, 0, req,
- dict, err_str);
- }
- free (cli_req.dict.dict_val);
-
- return ret;
-}
-
-int
-glusterd_handle_cli_statedump_volume (rpcsvc_request_t *req)
-{
- return glusterd_big_locked_handler (req,
- __glusterd_handle_cli_statedump_volume);
-}
-
-#ifdef HAVE_BD_XLATOR
-/*
- * Validates if given VG in the brick exists or not. Also checks if VG has
- * GF_XATTR_VOL_ID_KEY tag set to avoid using same VG for multiple bricks.
- * Tag is checked only during glusterd_op_stage_create_volume. Tag is set during
- * glusterd_validate_and_create_brickpath().
- * @brick - brick info, @check_tag - check for VG tag or not
- * @msg - Error message to return to caller
- */
-int
-glusterd_is_valid_vg (glusterd_brickinfo_t *brick, int check_tag, char *msg)
-{
- lvm_t handle = NULL;
- vg_t vg = NULL;
- char *vg_name = NULL;
- int retval = 0;
- char *p = NULL;
- char *ptr = NULL;
- struct dm_list *dm_lvlist = NULL;
- struct dm_list *dm_seglist = NULL;
- struct lvm_lv_list *lv_list = NULL;
- struct lvm_property_value prop = {0, };
- struct lvm_lvseg_list *seglist = NULL;
- struct dm_list *taglist = NULL;
- struct lvm_str_list *strl = NULL;
-
- handle = lvm_init (NULL);
- if (!handle) {
- sprintf (msg, "lvm_init failed, could not validate vg");
- return -1;
- }
- if (*brick->vg == '\0') { /* BD xlator has vg in brick->path */
- p = gf_strdup (brick->path);
- vg_name = strtok_r (p, "/", &ptr);
- } else
- vg_name = brick->vg;
-
- vg = lvm_vg_open (handle, vg_name, "r", 0);
- if (!vg) {
- sprintf (msg, "no such vg: %s", vg_name);
- retval = -1;
- goto out;
- }
- if (!check_tag)
- goto next;
-
- taglist = lvm_vg_get_tags (vg);
- if (!taglist)
- goto next;
-
- dm_list_iterate_items (strl, taglist) {
- if (!strncmp(strl->str, GF_XATTR_VOL_ID_KEY,
- strlen (GF_XATTR_VOL_ID_KEY))) {
- sprintf (msg, "VG %s is already part of"
- " a brick", vg_name);
- retval = -1;
- goto out;
- }
- }
-next:
-
- brick->caps = CAPS_BD | CAPS_OFFLOAD_COPY | CAPS_OFFLOAD_SNAPSHOT;
-
- dm_lvlist = lvm_vg_list_lvs (vg);
- if (!dm_lvlist)
- goto out;
-
- dm_list_iterate_items (lv_list, dm_lvlist) {
- dm_seglist = lvm_lv_list_lvsegs (lv_list->lv);
- dm_list_iterate_items (seglist, dm_seglist) {
- prop = lvm_lvseg_get_property (seglist->lvseg,
- "segtype");
- if (!prop.is_valid || !prop.value.string)
- continue;
- if (!strcmp (prop.value.string, "thin-pool")) {
- brick->caps |= CAPS_THIN;
- gf_log (THIS->name, GF_LOG_INFO, "Thin Pool "
- "\"%s\" will be used for thin LVs",
- lvm_lv_get_name (lv_list->lv));
- break;
- }
- }
- }
-
- retval = 0;
-out:
- if (vg)
- lvm_vg_close (vg);
- lvm_quit (handle);
- if (p)
- GF_FREE (p);
- return retval;
-}
-#endif
-
-/* op-sm */
-int
-glusterd_op_stage_create_volume (dict_t *dict, char **op_errstr,
- dict_t *rsp_dict)
-{
- int ret = 0;
- char *volname = NULL;
- gf_boolean_t exists = _gf_false;
- char *bricks = NULL;
- char *brick_list = NULL;
- char *free_ptr = NULL;
- char key[PATH_MAX] = "";
- glusterd_brickinfo_t *brick_info = NULL;
- int32_t brick_count = 0;
- int32_t local_brick_count = 0;
- int32_t i = 0;
- char *brick = NULL;
- char *tmpptr = NULL;
- xlator_t *this = NULL;
- glusterd_conf_t *priv = NULL;
- char msg[2048] = {0};
- uuid_t volume_uuid;
- char *volume_uuid_str;
- gf_boolean_t is_force = _gf_false;
-
- this = THIS;
- GF_ASSERT (this);
- priv = this->private;
- GF_ASSERT (priv);
- GF_ASSERT (rsp_dict);
-
- ret = dict_get_str (dict, "volname", &volname);
- if (ret) {
- gf_log (this->name, 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);
- ret = -1;
- goto out;
- } else {
- ret = 0;
- }
-
- ret = dict_get_int32 (dict, "count", &brick_count);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Unable to get brick count "
- "for volume %s", volname);
- goto out;
- }
-
- ret = dict_get_str (dict, "volume-id", &volume_uuid_str);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Unable to get volume id of "
- "volume %s", volname);
- goto out;
- }
-
- ret = uuid_parse (volume_uuid_str, volume_uuid);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Unable to parse volume id of"
- " volume %s", volname);
- goto out;
- }
-
- ret = dict_get_str (dict, "bricks", &bricks);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Unable to get bricks for "
- "volume %s", volname);
- goto out;
- }
-
- is_force = dict_get_str_boolean (dict, "force", _gf_false);
-
- if (bricks) {
- brick_list = gf_strdup (bricks);
- if (!brick_list) {
- ret = -1;
- 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)) {
- snprintf (msg, sizeof (msg), "brick path %s is too "
- "long.", brick);
- ret = -1;
- goto out;
- }
-
- if (!glusterd_is_valid_volfpath (volname, brick)) {
- snprintf (msg, sizeof (msg), "Volume file path for "
- "volume %s and brick path %s is too long.",
- volname, brick);
- ret = -1;
- goto out;
- }
-
- ret = glusterd_brickinfo_new_from_brick (brick, &brick_info);
- if (ret)
- goto out;
-
- ret = glusterd_new_brick_validate (brick, brick_info, msg,
- sizeof (msg));
- if (ret)
- goto out;
-
- ret = glusterd_resolve_brick (brick_info);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, FMTSTR_RESOLVE_BRICK,
- brick_info->hostname, brick_info->path);
- goto out;
- }
-
- if (!uuid_compare (brick_info->uuid, MY_UUID)) {
-#ifdef HAVE_BD_XLATOR
- if (brick_info->vg[0]) {
- ret = glusterd_is_valid_vg (brick_info, 1, msg);
- if (ret)
- goto out;
- }
-#endif
- ret = glusterd_validate_and_create_brickpath (brick_info,
- volume_uuid, op_errstr,
- is_force);
- if (ret)
- goto out;
-
- /* A bricks mount dir is required only by snapshots which were
- * introduced in gluster-3.6.0
- */
- if (priv->op_version >= GD_OP_VERSION_3_6_0) {
- ret = glusterd_get_brick_mount_dir
- (brick_info->path, brick_info->hostname,
- brick_info->mount_dir);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to get brick mount_dir");
- goto out;
- }
-
- snprintf (key, sizeof(key), "brick%d.mount_dir",
- i);
- ret = dict_set_dynstr_with_alloc
- (rsp_dict, key, brick_info->mount_dir);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to set %s", key);
- goto out;
- }
- }
- local_brick_count = i;
-
- brick_list = tmpptr;
- }
- glusterd_brickinfo_delete (brick_info);
- brick_info = NULL;
- }
-
- ret = dict_set_int32 (rsp_dict, "brick_count", local_brick_count);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to set local_brick_count");
- goto out;
- }
-out:
- GF_FREE (free_ptr);
- if (brick_info)
- glusterd_brickinfo_delete (brick_info);
-
- if (msg[0] != '\0') {
- gf_log (this->name, GF_LOG_ERROR, "%s", msg);
- *op_errstr = gf_strdup (msg);
- }
- gf_log (this->name, 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;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
-
- if (!dict || !volname || !flags)
- 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 = dict_get_int32 (dict, "flags", flags);
- if (ret) {
- gf_log (this->name, 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,
- dict_t *rsp_dict)
-{
- int ret = 0;
- char *volname = NULL;
- char key[PATH_MAX] = "";
- int flags = 0;
- int32_t brick_count = 0;
- int32_t local_brick_count = 0;
- gf_boolean_t exists = _gf_false;
- glusterd_volinfo_t *volinfo = NULL;
- glusterd_brickinfo_t *brickinfo = NULL;
- char msg[2048] = {0,};
- glusterd_conf_t *priv = NULL;
- xlator_t *this = NULL;
- uuid_t volume_id = {0,};
- char volid[50] = {0,};
- char xattr_volid[50] = {0,};
- int caps = 0;
-
- this = THIS;
- GF_ASSERT (this);
- priv = this->private;
- GF_ASSERT (priv);
- GF_ASSERT (rsp_dict);
-
- 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), FMTSTR_CHECK_VOL_EXISTS, volname);
- ret = -1;
- goto out;
- }
-
- ret = glusterd_volinfo_find (volname, &volinfo);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, FMTSTR_CHECK_VOL_EXISTS,
- volname);
- goto out;
- }
-
- ret = glusterd_validate_volume_id (dict, volinfo);
- 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);
- ret = -1;
- goto out;
- }
- }
-
- list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) {
- brick_count++;
- ret = glusterd_resolve_brick (brickinfo);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, FMTSTR_RESOLVE_BRICK,
- brickinfo->hostname, brickinfo->path);
- goto out;
- }
-
- if ((uuid_compare (brickinfo->uuid, MY_UUID)) ||
- (brickinfo->snap_status == -1))
- continue;
-
- ret = gf_lstat_dir (brickinfo->path, NULL);
- if (ret && (flags & GF_CLI_FLAG_OP_FORCE)) {
- continue;
- } else if (ret) {
- snprintf (msg, sizeof (msg), "Failed to find "
- "brick directory %s for volume %s. "
- "Reason : %s", brickinfo->path,
- volname, strerror (errno));
- goto out;
- }
- ret = sys_lgetxattr (brickinfo->path, GF_XATTR_VOL_ID_KEY,
- volume_id, 16);
- if (ret < 0 && (!(flags & GF_CLI_FLAG_OP_FORCE))) {
- snprintf (msg, sizeof (msg), "Failed to get "
- "extended attribute %s for brick dir %s. "
- "Reason : %s", GF_XATTR_VOL_ID_KEY,
- brickinfo->path, strerror (errno));
- ret = -1;
- goto out;
- } else if (ret < 0) {
- ret = sys_lsetxattr (brickinfo->path,
- GF_XATTR_VOL_ID_KEY,
- volinfo->volume_id, 16,
- XATTR_CREATE);
- if (ret == -1) {
- snprintf (msg, sizeof (msg), "Failed to set "
- "extended attribute %s on %s. Reason: "
- "%s", GF_XATTR_VOL_ID_KEY,
- brickinfo->path, strerror (errno));
- goto out;
- } else {
- continue;
- }
- }
- if (uuid_compare (volinfo->volume_id, volume_id)) {
- snprintf (msg, sizeof (msg), "Volume id mismatch for "
- "brick %s:%s. Expected volume id %s, "
- "volume id %s found", brickinfo->hostname,
- brickinfo->path,
- uuid_utoa_r (volinfo->volume_id, volid),
- uuid_utoa_r (volume_id, xattr_volid));
- ret = -1;
- goto out;
- }
-
- /* A bricks mount dir is required only by snapshots which were
- * introduced in gluster-3.6.0
- */
- if (priv->op_version >= GD_OP_VERSION_3_6_0) {
- if (strlen(brickinfo->mount_dir) < 1) {
- ret = glusterd_get_brick_mount_dir
- (brickinfo->path, brickinfo->hostname,
- brickinfo->mount_dir);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to get brick mount_dir");
- goto out;
- }
-
- snprintf (key, sizeof(key), "brick%d.mount_dir",
- brick_count);
- ret = dict_set_dynstr_with_alloc
- (rsp_dict, key, brickinfo->mount_dir);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to set %s", key);
- goto out;
- }
- local_brick_count = brick_count;
- }
- }
-
-#ifdef HAVE_BD_XLATOR
- if (brickinfo->vg[0])
- caps = CAPS_BD | CAPS_THIN |
- CAPS_OFFLOAD_COPY | CAPS_OFFLOAD_SNAPSHOT;
- /* Check for VG/thin pool if its BD volume */
- if (brickinfo->vg[0]) {
- ret = glusterd_is_valid_vg (brickinfo, 0, msg);
- if (ret)
- goto out;
- /* if anyone of the brick does not have thin support,
- disable it for entire volume */
- caps &= brickinfo->caps;
- } else
- caps = 0;
-#endif
- }
-
- ret = dict_set_int32 (rsp_dict, "brick_count", local_brick_count);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to set local_brick_count");
- goto out;
- }
-
- volinfo->caps = caps;
- ret = 0;
-out:
- if (ret && (msg[0] != '\0')) {
- gf_log (this->name, GF_LOG_ERROR, "%s", msg);
- *op_errstr = gf_strdup (msg);
- }
- 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};
- xlator_t *this = NULL;
- gsync_status_param_t param = {0,};
-
- this = THIS;
- GF_ASSERT (this);
-
- 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), FMTSTR_CHECK_VOL_EXISTS, volname);
- gf_log (this->name, GF_LOG_ERROR, "%s", msg);
- ret = -1;
- goto out;
- }
-
- ret = glusterd_volinfo_find (volname, &volinfo);
- if (ret) {
- snprintf (msg, sizeof (msg), FMTSTR_CHECK_VOL_EXISTS, volname);
- gf_log (this->name, GF_LOG_ERROR, "%s", msg);
- 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 (this->name, GF_LOG_ERROR, "%s", msg);
- ret = -1;
- goto out;
- }
- ret = glusterd_check_gsync_running (volinfo, &is_run);
- if (ret && (is_run == _gf_false))
- gf_log (this->name, GF_LOG_WARNING, "Unable to get the status"
- " of active "GEOREP" session");
-
- param.volinfo = volinfo;
- ret = dict_foreach (volinfo->gsync_slaves, _get_slave_status, &param);
-
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING, "_get_slave_satus failed");
- snprintf (msg, sizeof(msg), GEOREP" Unable to get the status "
- "of active "GEOREP" session for the volume '%s'.\n"
- "Please check the log file for more info. Use "
- "'force' option to ignore and stop the volume.",
- volname);
- ret = -1;
- goto out;
- }
-
- if (is_run && param.is_active) {
- gf_log (this->name, 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 the volume.",
- volname);
- 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_WARNING, "replace-brick in progress "
- "on volume %s", volname);
- 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);
- ret = -1;
- goto out;
- }
- if (volinfo->rep_brick.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);
- ret = -1;
- goto out;
- }
-
-out:
- if (msg[0] != 0)
- *op_errstr = gf_strdup (msg);
- gf_log (this->name, 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};
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
-
- ret = dict_get_str (dict, "volname", &volname);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Unable to get volume name");
- goto out;
- }
-
- exists = glusterd_check_volume_exists (volname);
- if (!exists) {
- snprintf (msg, sizeof (msg), FMTSTR_CHECK_VOL_EXISTS, volname);
- ret = -1;
- goto out;
- } else {
- ret = 0;
- }
-
- ret = glusterd_volinfo_find (volname, &volinfo);
- if (ret) {
- snprintf (msg, sizeof (msg), FMTSTR_CHECK_VOL_EXISTS, volname);
- 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);
- ret = -1;
- goto out;
- }
-
- if (volinfo->snap_count > 0 || !list_empty(&volinfo->snap_volumes)) {
- snprintf (msg, sizeof (msg), "Cannot delete Volume %s ,"
- "as it has %"PRIu64" snapshots. "
- "To delete the volume, "
- "first delete all the snapshots under it.",
- volname, volinfo->snap_count);
- ret = -1;
- goto out;
- }
-
- ret = 0;
-
-out:
- if (msg[0] != '\0') {
- gf_log (this->name, GF_LOG_ERROR, "%s", msg);
- *op_errstr = gf_strdup (msg);
- }
- gf_log (this->name, 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;
- xlator_t *this = NULL;
-
- this = THIS;
- 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;
- }
-
- ret = dict_get_int32 (dict, "heal-op", (int32_t*)&heal_op);
- if (ret || (heal_op == GF_AFR_OP_INVALID)) {
- ret = -1;
- *op_errstr = gf_strdup("Invalid heal-op");
- gf_log (this->name, GF_LOG_WARNING, "%s", "Invalid heal-op");
- goto out;
- }
-
- switch (heal_op) {
- case GF_AFR_OP_HEALED_FILES:
- case GF_AFR_OP_HEAL_FAILED_FILES:
- ret = -1;
- snprintf (msg, sizeof (msg),"Command not supported. "
- "Please use \"gluster volume heal %s info\" "
- "and logs to find the heal information.",
- volname);
- *op_errstr = gf_strdup (msg);
- goto out;
-
- case GF_AFR_OP_INDEX_SUMMARY:
- case GF_AFR_OP_STATISTICS_HEAL_COUNT:
- case GF_AFR_OP_STATISTICS_HEAL_COUNT_PER_REPLICA:
- break;
- default:
- if (!glusterd_is_nodesvc_online("glustershd")){
- ret = -1;
- *op_errstr = gf_strdup ("Self-heal daemon is "
- "not running. Check self-heal "
- "daemon log file.");
- gf_log (this->name, GF_LOG_WARNING, "%s",
- "Self-heal daemon is not running."
- "Check self-heal daemon log file.");
- 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,};
- xlator_t *this = NULL;
- glusterd_conf_t *priv = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- priv = this->private;
- GF_ASSERT (priv);
-
- 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), FMTSTR_CHECK_VOL_EXISTS, volname);
- 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 the started"
- " state", volname);
- ret = -1;
- goto out;
- }
-
- if (priv->op_version == GD_OP_VERSION_MIN &&
- strstr (options, "quotad")) {
- snprintf (msg, sizeof (msg), "The cluster is operating "
- "at op-version 1. Taking quotad's statedump is "
- "disallowed in this state");
- ret = -1;
- goto out;
- }
- if ((strstr (options, "quotad")) &&
- (!glusterd_is_volume_quota_enabled (volinfo))) {
- snprintf (msg, sizeof (msg), "Quota is not enabled on "
- "volume %s", volname);
- ret = -1;
- goto out;
- }
-out:
- if (ret && msg[0] != '\0')
- *op_errstr = gf_strdup (msg);
- gf_log (this->name, 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;
- int caps = 0;
- int brickid = 0;
- char msg[1024] __attribute__((unused)) = {0, };
- char *brick_mount_dir = NULL;
- char key[PATH_MAX] = "";
-
- 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 for volinfo");
- 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, sizeof(volinfo->volname));
- 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 of volume"
- " %s", volname);
- goto out;
- }
-
- ret = dict_get_int32 (dict, "count", &volinfo->brick_count);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Unable to get brick count of"
- " volume %s", volname);
- 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 for "
- "volume %s", volname);
- 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) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to get "
- "replica count for volume %s", volname);
- goto out;
- }
- } else if (GF_CLUSTER_TYPE_STRIPE == volinfo->type) {
- ret = dict_get_int32 (dict, "stripe-count",
- &volinfo->stripe_count);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to get stripe"
- " count for volume %s", volname);
- goto out;
- }
- } else if (GF_CLUSTER_TYPE_STRIPE_REPLICATE == volinfo->type) {
- ret = dict_get_int32 (dict, "stripe-count",
- &volinfo->stripe_count);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to get stripe"
- " count for volume %s", volname);
- goto out;
- }
- ret = dict_get_int32 (dict, "replica-count",
- &volinfo->replica_count);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to get "
- "replica count for volume %s", volname);
- goto out;
- }
- } else if (GF_CLUSTER_TYPE_DISPERSE == volinfo->type) {
- ret = dict_get_int32 (dict, "disperse-count",
- &volinfo->disperse_count);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to get "
- "disperse count for volume %s", volname);
- goto out;
- }
- ret = dict_get_int32 (dict, "redundancy-count",
- &volinfo->redundancy_count);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to get "
- "redundancy count for volume %s", volname);
- goto out;
- }
- if (priv->op_version < GD_OP_VERSION_3_6_0) {
- gf_log (this->name, GF_LOG_ERROR, "Disperse volume "
- "needs op-version 3.6.0 or higher");
- ret = -1;
- goto out;
- }
- }
-
- /* dist-leaf-count is the count of brick nodes for a given
- subvolume of distribute */
- volinfo->dist_leaf_count = glusterd_get_dist_leaf_count (volinfo);
-
- /* subvol_count is the count of number of subvolumes present
- for a given distribute volume */
- volinfo->subvol_count = (volinfo->brick_count /
- volinfo->dist_leaf_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 type of volume %s", volname);
- goto out;
- }
-
- ret = dict_get_str (dict, "volume-id", &str);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Unable to get volume-id of volume %s", volname);
- goto out;
- }
- ret = uuid_parse (str, volinfo->volume_id);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "unable to parse uuid %s of volume %s", str, volname);
- goto out;
- }
-
- ret = dict_get_str (dict, "internal-username", &username);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "unable to get internal username of volume %s",
- volname);
- 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 of volume %s",
- volname);
- goto out;
- }
- glusterd_auth_set_password (volinfo, password);
-
- 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;
- }
-
- if (bricks) {
- brick_list = gf_strdup (bricks);
- free_ptr = brick_list;
- }
-
- if (count)
- brick = strtok_r (brick_list+1, " \n", &saveptr);
- caps = CAPS_BD | CAPS_THIN | CAPS_OFFLOAD_COPY | CAPS_OFFLOAD_SNAPSHOT;
-
- brickid = glusterd_get_next_available_brickid (volinfo);
- if (brickid < 0)
- goto out;
- while ( i <= count) {
- ret = glusterd_brickinfo_new_from_brick (brick, &brickinfo);
- if (ret)
- goto out;
-
- GLUSTERD_ASSIGN_BRICKID_TO_BRICKINFO (brickinfo, volinfo,
- brickid++);
-
- ret = glusterd_resolve_brick (brickinfo);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, FMTSTR_RESOLVE_BRICK,
- brickinfo->hostname, brickinfo->path);
- goto out;
- }
-
- /* A bricks mount dir is required only by snapshots which were
- * introduced in gluster-3.6.0
- */
- if (priv->op_version >= GD_OP_VERSION_3_6_0) {
- brick_mount_dir = NULL;
- snprintf (key, sizeof(key), "brick%d.mount_dir", i);
- ret = dict_get_str (dict, key, &brick_mount_dir);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "%s not present", key);
- goto out;
- }
- strncpy (brickinfo->mount_dir, brick_mount_dir,
- sizeof(brickinfo->mount_dir));
- }
-
-#ifdef HAVE_BD_XLATOR
- if (!uuid_compare (brickinfo->uuid, MY_UUID)
- && brickinfo->vg[0]) {
- ret = glusterd_is_valid_vg (brickinfo, 0, msg);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "%s", msg);
- goto out;
- }
-
- /* if anyone of the brick does not have thin
- support, disable it for entire volume */
- caps &= brickinfo->caps;
- } else {
- caps = 0;
- }
-
-#endif
-
- list_add_tail (&brickinfo->brick_list, &volinfo->bricks);
- brick = strtok_r (NULL, " \n", &saveptr);
- i++;
- }
-
- ret = glusterd_enable_default_options (volinfo, NULL);
- if (ret) {
- gf_msg (this->name, GF_LOG_ERROR, 0,
- GD_MSG_FAIL_DEFAULT_OPT_SET, "Failed to set default "
- "options on create for volume %s", volinfo->volname);
- goto out;
- }
-
- gd_update_volume_op_versions (volinfo);
-
- volinfo->caps = caps;
-
- 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;
- }
-
- volinfo->rebal.defrag_status = 0;
- list_add_order (&volinfo->vol_list, &priv->volumes,
- glusterd_compare_volume_name);
- vol_added = _gf_true;
-
-out:
- GF_FREE(free_ptr);
- if (!vol_added && volinfo)
- glusterd_volinfo_unref (volinfo);
- return ret;
-}
-
-int
-glusterd_start_volume (glusterd_volinfo_t *volinfo, int flags,
- gf_boolean_t wait)
-
-{
- int ret = 0;
- glusterd_brickinfo_t *brickinfo = NULL;
- xlator_t *this = NULL;
- glusterd_volinfo_ver_ac_t verincrement = 0;
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (volinfo);
-
- list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) {
- ret = glusterd_brick_start (volinfo, brickinfo, wait);
- /* If 'force' try to start all bricks regardless of success or
- * failure
- */
- if (!(flags & GF_CLI_FLAG_OP_FORCE) && ret)
- goto out;
- }
-
- /* Increment the volinfo version only if there is a
- * change in status. Force option can be used to start
- * dead bricks even if the volume is in started state.
- * In such case volume status will be GLUSTERD_STATUS_STARTED.
- * Therefore we should not increment the volinfo version.*/
- if (GLUSTERD_STATUS_STARTED != volinfo->status) {
- verincrement = GLUSTERD_VOLINFO_VER_AC_INCREMENT;
- } else {
- verincrement = GLUSTERD_VOLINFO_VER_AC_NONE;
- }
-
- glusterd_set_volume_status (volinfo, GLUSTERD_STATUS_STARTED);
-
- ret = glusterd_store_volinfo (volinfo, verincrement);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to store volinfo of "
- "%s volume", volinfo->volname);
- goto out;
- }
-out:
- gf_log (this->name, GF_LOG_TRACE, "returning %d ", ret);
- return ret;
-}
-
-int
-glusterd_op_start_volume (dict_t *dict, char **op_errstr)
-{
- int ret = 0;
- int32_t brick_count = 0;
- char *brick_mount_dir = NULL;
- char key[PATH_MAX] = "";
- char *volname = NULL;
- int flags = 0;
- glusterd_volinfo_t *volinfo = NULL;
- glusterd_brickinfo_t *brickinfo = NULL;
- xlator_t *this = NULL;
- glusterd_conf_t *conf = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- conf = this->private;
- GF_ASSERT (conf);
-
- ret = glusterd_op_start_volume_args_get (dict, &volname, &flags);
- if (ret)
- goto out;
-
- ret = glusterd_volinfo_find (volname, &volinfo);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, FMTSTR_CHECK_VOL_EXISTS,
- volname);
- goto out;
- }
-
- /* A bricks mount dir is required only by snapshots which were
- * introduced in gluster-3.6.0
- */
- if (conf->op_version >= GD_OP_VERSION_3_6_0) {
- list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) {
- brick_count++;
- /* Don't check bricks that are not owned by you
- */
- if (uuid_compare (brickinfo->uuid, MY_UUID))
- continue;
- if (strlen(brickinfo->mount_dir) < 1) {
- brick_mount_dir = NULL;
- snprintf (key, sizeof(key), "brick%d.mount_dir",
- brick_count);
- ret = dict_get_str (dict, key,
- &brick_mount_dir);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "%s not present", key);
- goto out;
- }
- strncpy (brickinfo->mount_dir, brick_mount_dir,
- sizeof(brickinfo->mount_dir));
- }
- }
- }
-
- ret = glusterd_start_volume (volinfo, flags, _gf_true);
- if (ret)
- goto out;
-
- ret = glusterd_handle_snapd_option (volinfo);
- if (ret)
- goto out;
-
- ret = glusterd_nodesvcs_handle_graph_change (volinfo);
-
-out:
- gf_log (this->name, GF_LOG_TRACE, "returning %d ", ret);
- return ret;
-}
-
-int
-glusterd_stop_volume (glusterd_volinfo_t *volinfo)
-{
- int ret = -1;
- glusterd_brickinfo_t *brickinfo = NULL;
- char mountdir[PATH_MAX] = {0,};
- char pidfile[PATH_MAX] = {0,};
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
-
- GF_VALIDATE_OR_GOTO (this->name, volinfo, out);
-
- list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) {
- ret = glusterd_brick_stop (volinfo, brickinfo, _gf_false);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to stop "
- "brick (%s)", brickinfo->path);
- goto out;
- }
- }
-
- glusterd_set_volume_status (volinfo, GLUSTERD_STATUS_STOPPED);
-
- ret = glusterd_store_volinfo (volinfo, GLUSTERD_VOLINFO_VER_AC_INCREMENT);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to store volinfo of "
- "%s volume", volinfo->volname);
- goto out;
- }
-
- /* If quota auxiliary mount is present, unmount it */
- GLUSTERFS_GET_AUX_MOUNT_PIDFILE (pidfile, volinfo->volname);
-
- if (!gf_is_service_running (pidfile, NULL)) {
- gf_log (this->name, GF_LOG_DEBUG, "Aux mount of volume %s "
- "absent", volinfo->volname);
- } else {
- GLUSTERD_GET_QUOTA_AUX_MOUNT_PATH (mountdir, volinfo->volname,
- "/");
-
- ret = gf_umount_lazy (this->name, mountdir, 0);
- if (ret)
- gf_log (this->name, GF_LOG_ERROR,
- "umount on %s failed, reason : %s",
- mountdir, strerror (errno));
- }
-
- ret = glusterd_handle_snapd_option (volinfo);
- if (ret)
- goto out;
-
- ret = glusterd_nodesvcs_handle_graph_change (volinfo);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to notify graph "
- "change for %s volume", volinfo->volname);
-
- goto out;
- }
-
-out:
- return ret;
-}
-
-int
-glusterd_op_stop_volume (dict_t *dict)
-{
- int ret = 0;
- int flags = 0;
- char *volname = NULL;
- glusterd_volinfo_t *volinfo = NULL;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
-
- ret = glusterd_op_stop_volume_args_get (dict, &volname, &flags);
- if (ret)
- goto out;
-
- ret = glusterd_volinfo_find (volname, &volinfo);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, FMTSTR_CHECK_VOL_EXISTS,
- volname);
- goto out;
- }
-
- ret = glusterd_stop_volume (volinfo);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to stop %s volume",
- volname);
- goto out;
- }
-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 (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, FMTSTR_CHECK_VOL_EXISTS,
- volname);
- goto out;
- }
-
- ret = glusterd_remove_auxiliary_mount (volname);
- if (ret)
- goto out;
-
- ret = glusterd_delete_volume (volinfo);
-out:
- gf_log (this->name, 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 if (strstr (options, "quotad")) {
- ret = glusterd_quotad_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, _PATH_UMOUNT, "-f", NULL);
- runner_argprintf (&runner, "%s", mntpt);
-
- synclock_unlock (&priv->big_lock);
- ret = runner_run (&runner);
- synclock_lock (&priv->big_lock);
- 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);
- synclock_unlock (&priv->big_lock);
- ret = runner_run (&runner);
- synclock_lock (&priv->big_lock);
- 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;
- char brickname[PATH_MAX] = {0,};
- 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;
-
- if (volinfo->transport_type == GF_TRANSPORT_RDMA) {
- snprintf (brickname, sizeof(brickname), "%s.rdma",
- brickinfo->path);
- } else
- snprintf (brickname, sizeof(brickname), "%s",
- brickinfo->path);
-
- port = pmap_registry_search (THIS, brickname,
- 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, dict_t *rsp_dict)
-{
- 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;
- 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;
- }
-
- free_ptr = gf_strdup(result);
- if (dict_set_dynstr (rsp_dict, "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-volume-set.c b/xlators/mgmt/glusterd/src/glusterd-volume-set.c
deleted file mode 100644
index 0ed5b316c4f..00000000000
--- a/xlators/mgmt/glusterd/src/glusterd-volume-set.c
+++ /dev/null
@@ -1,1676 +0,0 @@
-/*
- Copyright (c) 2013 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 "glusterd-volgen.h"
-#include "glusterd-utils.h"
-
-static int
-check_dict_key_value (dict_t *dict, char *key, char *value)
-{
- glusterd_conf_t *priv = NULL;
- int ret = 0;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- priv = this->private;
- GF_ASSERT (priv);
-
- if (!dict) {
- gf_log (this->name, GF_LOG_ERROR, "Received Empty Dict.");
- ret = -1;
- goto out;
- }
-
- if (!key) {
- gf_log (this->name, GF_LOG_ERROR, "Received Empty Key.");
- ret = -1;
- goto out;
- }
-
- if (!value) {
- gf_log (this->name, GF_LOG_ERROR, "Received Empty Value.");
- ret = -1;
- goto out;
- }
-
-out:
- gf_log (this->name, GF_LOG_DEBUG, "Returning %d", ret);
-
- return ret;
-}
-
-static int
-get_volname_volinfo (dict_t *dict, char **volname, glusterd_volinfo_t **volinfo)
-{
- glusterd_conf_t *priv = NULL;
- int ret = 0;
- 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 (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 allocate memory");
- goto out;
- }
-
-out:
- gf_log (this->name, GF_LOG_DEBUG, "Returning %d", ret);
-
- return ret;
-}
-
-static int
-validate_cache_max_min_size (dict_t *dict, char *key, char *value,
- char **op_errstr)
-{
- char *current_max_value = NULL;
- char *current_min_value = NULL;
- char errstr[2048] = "";
- char *volname = NULL;
- glusterd_conf_t *priv = NULL;
- glusterd_volinfo_t *volinfo = NULL;
- int ret = 0;
- uint64_t max_value = 0;
- uint64_t min_value = 0;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- priv = this->private;
- GF_ASSERT (priv);
-
- ret = check_dict_key_value (dict, key, value);
- if (ret)
- goto out;
-
- ret = get_volname_volinfo (dict, &volname, &volinfo);
- if (ret)
- goto out;
-
- if ((!strcmp (key, "performance.cache-min-file-size")) ||
- (!strcmp (key, "cache-min-file-size"))) {
- glusterd_volinfo_get (volinfo,
- "performance.cache-max-file-size",
- &current_max_value);
- if (current_max_value) {
- gf_string2bytesize_uint64 (current_max_value, &max_value);
- gf_string2bytesize_uint64 (value, &min_value);
- current_min_value = value;
- }
- } else if ((!strcmp (key, "performance.cache-max-file-size")) ||
- (!strcmp (key, "cache-max-file-size"))) {
- glusterd_volinfo_get (volinfo,
- "performance.cache-min-file-size",
- &current_min_value);
- if (current_min_value) {
- gf_string2bytesize_uint64 (current_min_value, &min_value);
- gf_string2bytesize_uint64 (value, &max_value);
- current_max_value = value;
- }
- }
-
- if (min_value > max_value) {
- snprintf (errstr, sizeof (errstr),
- "cache-min-file-size (%s) is greater than "
- "cache-max-file-size (%s)",
- current_min_value, current_max_value);
- gf_log (this->name, GF_LOG_ERROR, "%s", errstr);
- *op_errstr = gf_strdup (errstr);
- ret = -1;
- goto out;
- }
-
-out:
- gf_log (this->name, GF_LOG_DEBUG, "Returning %d", ret);
-
- return ret;
-}
-
-static int
-validate_quota (dict_t *dict, char *key, char *value,
- char **op_errstr)
-{
- char errstr[2048] = "";
- char *volname = NULL;
- glusterd_conf_t *priv = NULL;
- glusterd_volinfo_t *volinfo = NULL;
- int ret = 0;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- priv = this->private;
- GF_ASSERT (priv);
-
- ret = check_dict_key_value (dict, key, value);
- if (ret)
- goto out;
-
- ret = get_volname_volinfo (dict, &volname, &volinfo);
- if (ret)
- goto out;
-
- ret = glusterd_volinfo_get_boolean (volinfo, VKEY_FEATURES_QUOTA);
- if (ret == -1) {
- gf_log (this->name, GF_LOG_ERROR,
- "failed to get the quota status");
- goto out;
- }
-
- if (ret == _gf_false) {
- snprintf (errstr, sizeof (errstr),
- "Cannot set %s. Enable quota first.", key);
- gf_log (this->name, GF_LOG_ERROR, "%s", errstr);
- *op_errstr = gf_strdup (errstr);
- ret = -1;
- goto out;
- }
-
- ret = 0;
-out:
- gf_log (this->name, GF_LOG_DEBUG, "Returning %d", ret);
-
- return ret;
-}
-
-static int
-validate_stripe (dict_t *dict, char *key, char *value, char **op_errstr)
-{
- char errstr[2048] = "";
- char *volname = NULL;
- glusterd_conf_t *priv = NULL;
- glusterd_volinfo_t *volinfo = NULL;
- int ret = 0;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- priv = this->private;
- GF_ASSERT (priv);
-
- ret = check_dict_key_value (dict, key, value);
- if (ret)
- goto out;
-
- ret = get_volname_volinfo (dict, &volname, &volinfo);
- if (ret)
- goto out;
-
- if (volinfo->stripe_count == 1) {
- snprintf (errstr, sizeof (errstr),
- "Cannot set %s for a non-stripe volume.", key);
- gf_log (this->name, GF_LOG_ERROR, "%s", errstr);
- *op_errstr = gf_strdup (errstr);
- ret = -1;
- goto out;
- }
-
-out:
- gf_log (this->name, GF_LOG_DEBUG, "Returning %d", ret);
-
- return ret;
-}
-
-static int
-validate_subvols_per_directory (dict_t *dict, char *key, char *value,
- char **op_errstr)
-{
- char errstr[2048] = "";
- char *volname = NULL;
- glusterd_conf_t *priv = NULL;
- glusterd_volinfo_t *volinfo = NULL;
- int ret = 0;
- int subvols = 0;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- priv = this->private;
- GF_ASSERT (priv);
-
- ret = check_dict_key_value (dict, key, value);
- if (ret)
- goto out;
-
- ret = get_volname_volinfo (dict, &volname, &volinfo);
- if (ret)
- goto out;
-
- subvols = atoi(value);
-
- /* Checking if the subvols-per-directory exceed the total
- number of subvolumes. */
- if (subvols > volinfo->subvol_count) {
- snprintf (errstr, sizeof(errstr),
- "subvols-per-directory(%d) is greater "
- "than the number of subvolumes(%d).",
- subvols, volinfo->subvol_count);
- gf_log (this->name, GF_LOG_ERROR,
- "%s.", errstr);
- *op_errstr = gf_strdup (errstr);
- ret = -1;
- goto out;
- }
-
-out:
- gf_log (this->name, GF_LOG_DEBUG, "Returning %d", ret);
-
- return ret;
-}
-
-
-/* dispatch table for VOLUME SET
- * -----------------------------
- *
- * Format of entries:
- *
- * First field is the <key>, for the purpose of looking it up
- * in volume dictionary. Each <key> is of the format "<domain>.<specifier>".
- *
- * Second field is <voltype>.
- *
- * Third field is <option>, if its unset, it's assumed to be
- * the same as <specifier>.
- *
- * Fourth field is <value>. In this context they are used to specify
- * a default. That is, even the volume dict doesn't have a value,
- * we procced as if the default value were set for it.
- *
- * Fifth field is <doctype>, which decides if the option is public and available
- * in "set help" or not. "NO_DOC" entries are not part of the public interface
- * and are subject to change at any time. This also decides if an option is
- * global (apllies to all volumes) or normal (applies to only specified volume).
- *
- * Sixth field is <flags>.
- *
- * Seventh field is <op-version>.
- *
- * Eight field is description of option: If NULL, tried to fetch from
- * translator code's xlator_options table.
- *
- * Nineth field is validation function: If NULL, xlator's option specific
- * validation will be tried, otherwise tried at glusterd code itself.
- *
- * There are two type of entries: basic and special.
- *
- * - Basic entries are the ones where the <option> does _not_ start with
- * the bang! character ('!').
- *
- * In their case, <option> is understood as an option for an xlator of
- * type <voltype>. Their effect is to copy over the volinfo->dict[<key>]
- * value to all graph nodes of type <voltype> (if such a value is set).
- *
- * You are free to add entries of this type, they will become functional
- * just by being present in the table.
- *
- * - Special entries where the <option> starts with the bang!.
- *
- * They are not applied to all graphs during generation, and you cannot
- * extend them in a trivial way which could be just picked up. Better
- * not touch them unless you know what you do.
- *
- *
- * Another kind of grouping for options, according to visibility:
- *
- * - Exported: one which is used in the code. These are characterized by
- * being used a macro as <key> (of the format VKEY_..., defined in
- * glusterd-volgen.h
- *
- * - Non-exported: the rest; these have string literal <keys>.
- *
- * Adhering to this policy, option name changes shall be one-liners.
- *
- */
-
-struct volopt_map_entry glusterd_volopt_map[] = {
- /* DHT xlator options */
- { .key = "cluster.lookup-unhashed",
- .voltype = "cluster/distribute",
- .op_version = 1,
- .flags = OPT_FLAG_CLIENT_OPT
- },
- { .key = "cluster.min-free-disk",
- .voltype = "cluster/distribute",
- .op_version = 1,
- .flags = OPT_FLAG_CLIENT_OPT
- },
- { .key = "cluster.min-free-inodes",
- .voltype = "cluster/distribute",
- .op_version = 1,
- .flags = OPT_FLAG_CLIENT_OPT
- },
- { .key = "cluster.rebalance-stats",
- .voltype = "cluster/distribute",
- .op_version = 2,
- .flags = OPT_FLAG_CLIENT_OPT
- },
- { .key = "cluster.subvols-per-directory",
- .voltype = "cluster/distribute",
- .option = "directory-layout-spread",
- .op_version = 2,
- .validate_fn = validate_subvols_per_directory,
- .flags = OPT_FLAG_CLIENT_OPT
- },
- { .key = "cluster.readdir-optimize",
- .voltype = "cluster/distribute",
- .op_version = 1,
- .flags = OPT_FLAG_CLIENT_OPT
- },
- { .key = "cluster.rsync-hash-regex",
- .voltype = "cluster/distribute",
- .type = NO_DOC,
- .op_version = 3,
- .flags = OPT_FLAG_CLIENT_OPT
- },
- { .key = "cluster.extra-hash-regex",
- .voltype = "cluster/distribute",
- .type = NO_DOC,
- .op_version = 3,
- .flags = OPT_FLAG_CLIENT_OPT
- },
- { .key = "cluster.dht-xattr-name",
- .voltype = "cluster/distribute",
- .option = "xattr-name",
- .type = NO_DOC,
- .op_version = 3,
- .flags = OPT_FLAG_CLIENT_OPT
- },
- { .key = "cluster.randomize-hash-range-by-gfid",
- .voltype = "cluster/distribute",
- .option = "randomize-hash-range-by-gfid",
- .type = NO_DOC,
- .op_version = GD_OP_VERSION_3_6_0,
- .flags = OPT_FLAG_CLIENT_OPT,
- },
- /* NUFA xlator options (Distribute special case) */
- { .key = "cluster.nufa",
- .voltype = "cluster/distribute",
- .option = "!nufa",
- .type = NO_DOC,
- .op_version = 2,
- .flags = OPT_FLAG_CLIENT_OPT
- },
- { .key = "cluster.local-volume-name",
- .voltype = "cluster/nufa",
- .option = "local-volume-name",
- .type = NO_DOC,
- .op_version = 3,
- .flags = OPT_FLAG_CLIENT_OPT
- },
- { .key = "cluster.weighted-rebalance",
- .voltype = "cluster/distribute",
- .op_version = GD_OP_VERSION_3_6_0,
- },
-
- /* Switch xlator options (Distribute special case) */
- { .key = "cluster.switch",
- .voltype = "cluster/distribute",
- .option = "!switch",
- .type = NO_DOC,
- .op_version = 3,
- .flags = OPT_FLAG_CLIENT_OPT
- },
- { .key = "cluster.switch-pattern",
- .voltype = "cluster/switch",
- .option = "pattern.switch.case",
- .type = NO_DOC,
- .op_version = 3,
- .flags = OPT_FLAG_CLIENT_OPT
- },
-
- /* AFR xlator options */
- { .key = "cluster.entry-change-log",
- .voltype = "cluster/replicate",
- .op_version = 1,
- .flags = OPT_FLAG_CLIENT_OPT
- },
- { .key = "cluster.read-subvolume",
- .voltype = "cluster/replicate",
- .op_version = 1,
- .flags = OPT_FLAG_CLIENT_OPT
- },
- { .key = "cluster.read-subvolume-index",
- .voltype = "cluster/replicate",
- .op_version = 2,
- .flags = OPT_FLAG_CLIENT_OPT
- },
- { .key = "cluster.read-hash-mode",
- .voltype = "cluster/replicate",
- .op_version = 2,
- .flags = OPT_FLAG_CLIENT_OPT
- },
- { .key = "cluster.background-self-heal-count",
- .voltype = "cluster/replicate",
- .op_version = 1,
- .flags = OPT_FLAG_CLIENT_OPT
- },
- { .key = "cluster.metadata-self-heal",
- .voltype = "cluster/replicate",
- .op_version = 1,
- .flags = OPT_FLAG_CLIENT_OPT
- },
- { .key = "cluster.data-self-heal",
- .voltype = "cluster/replicate",
- .op_version = 1,
- .flags = OPT_FLAG_CLIENT_OPT
- },
- { .key = "cluster.entry-self-heal",
- .voltype = "cluster/replicate",
- .op_version = 1,
- .flags = OPT_FLAG_CLIENT_OPT
- },
- { .key = "cluster.self-heal-daemon",
- .voltype = "cluster/replicate",
- .option = "!self-heal-daemon",
- .op_version = 1
- },
- { .key = "cluster.heal-timeout",
- .voltype = "cluster/replicate",
- .option = "!heal-timeout",
- .op_version = 2,
- .flags = OPT_FLAG_CLIENT_OPT
- },
- { .key = "cluster.strict-readdir",
- .voltype = "cluster/replicate",
- .type = NO_DOC,
- .op_version = 1,
- .flags = OPT_FLAG_CLIENT_OPT
- },
- { .key = "cluster.self-heal-window-size",
- .voltype = "cluster/replicate",
- .option = "data-self-heal-window-size",
- .op_version = 1,
- .flags = OPT_FLAG_CLIENT_OPT
- },
- { .key = "cluster.data-change-log",
- .voltype = "cluster/replicate",
- .op_version = 1,
- .flags = OPT_FLAG_CLIENT_OPT
- },
- { .key = "cluster.metadata-change-log",
- .voltype = "cluster/replicate",
- .op_version = 1,
- .flags = OPT_FLAG_CLIENT_OPT
- },
- { .key = "cluster.data-self-heal-algorithm",
- .voltype = "cluster/replicate",
- .option = "data-self-heal-algorithm",
- .op_version = 1,
- .flags = OPT_FLAG_CLIENT_OPT
- },
- { .key = "cluster.eager-lock",
- .voltype = "cluster/replicate",
- .op_version = 1,
- .flags = OPT_FLAG_CLIENT_OPT
- },
- { .key = "cluster.quorum-type",
- .voltype = "cluster/replicate",
- .option = "quorum-type",
- .op_version = 1,
- .flags = OPT_FLAG_CLIENT_OPT
- },
- { .key = "cluster.quorum-count",
- .voltype = "cluster/replicate",
- .option = "quorum-count",
- .op_version = 1,
- .flags = OPT_FLAG_CLIENT_OPT
- },
- { .key = "cluster.choose-local",
- .voltype = "cluster/replicate",
- .op_version = 2,
- .flags = OPT_FLAG_CLIENT_OPT
- },
- { .key = "cluster.self-heal-readdir-size",
- .voltype = "cluster/replicate",
- .op_version = 2,
- .flags = OPT_FLAG_CLIENT_OPT
- },
- { .key = "cluster.post-op-delay-secs",
- .voltype = "cluster/replicate",
- .type = NO_DOC,
- .op_version = 2,
- .flags = OPT_FLAG_CLIENT_OPT
- },
- { .key = "cluster.readdir-failover",
- .voltype = "cluster/replicate",
- .op_version = 2,
- .flags = OPT_FLAG_CLIENT_OPT
- },
- { .key = "cluster.ensure-durability",
- .voltype = "cluster/replicate",
- .op_version = 3,
- .flags = OPT_FLAG_CLIENT_OPT
- },
- { .key = "cluster.consistent-metadata",
- .voltype = "cluster/replicate",
- .type = DOC,
- .op_version = GD_OP_VERSION_3_6_3,
- .flags = OPT_FLAG_CLIENT_OPT
- },
-
- /* Stripe xlator options */
- { .key = "cluster.stripe-block-size",
- .voltype = "cluster/stripe",
- .option = "block-size",
- .op_version = 1,
- .validate_fn = validate_stripe,
- .flags = OPT_FLAG_CLIENT_OPT
- },
- { .key = "cluster.stripe-coalesce",
- .voltype = "cluster/stripe",
- .option = "coalesce",
- .op_version = 1,
- .flags = OPT_FLAG_CLIENT_OPT
- },
-
- /* IO-stats xlator options */
- { .key = VKEY_DIAG_LAT_MEASUREMENT,
- .voltype = "debug/io-stats",
- .option = "latency-measurement",
- .value = "off",
- .op_version = 1
- },
- { .key = "diagnostics.dump-fd-stats",
- .voltype = "debug/io-stats",
- .op_version = 1
- },
- { .key = VKEY_DIAG_CNT_FOP_HITS,
- .voltype = "debug/io-stats",
- .option = "count-fop-hits",
- .value = "off",
- .type = NO_DOC,
- .op_version = 1
- },
- { .key = "diagnostics.brick-log-level",
- .voltype = "debug/io-stats",
- .option = "!brick-log-level",
- .op_version = 1
- },
- { .key = "diagnostics.client-log-level",
- .voltype = "debug/io-stats",
- .option = "!client-log-level",
- .op_version = 1,
- .flags = OPT_FLAG_CLIENT_OPT
- },
- { .key = "diagnostics.brick-sys-log-level",
- .voltype = "debug/io-stats",
- .option = "!sys-log-level",
- .op_version = 1
- },
- { .key = "diagnostics.client-sys-log-level",
- .voltype = "debug/io-stats",
- .option = "!sys-log-level",
- .op_version = 1,
- .flags = OPT_FLAG_CLIENT_OPT
- },
- { .key = "diagnostics.brick-logger",
- .voltype = "debug/io-stats",
- .option = "!logger",
- .op_version = GD_OP_VERSION_3_6_0,
- },
- { .key = "diagnostics.client-logger",
- .voltype = "debug/io-stats",
- .option = "!logger",
- .op_version = GD_OP_VERSION_3_6_0,
- .flags = OPT_FLAG_CLIENT_OPT
- },
- { .key = "diagnostics.brick-log-format",
- .voltype = "debug/io-stats",
- .option = "!log-format",
- .op_version = GD_OP_VERSION_3_6_0,
- },
- { .key = "diagnostics.client-log-format",
- .voltype = "debug/io-stats",
- .option = "!log-format",
- .op_version = GD_OP_VERSION_3_6_0,
- .flags = OPT_FLAG_CLIENT_OPT
- },
- { .key = "diagnostics.brick-log-buf-size",
- .voltype = "debug/io-stats",
- .option = "!log-buf-size",
- .op_version = GD_OP_VERSION_3_6_0,
- },
- { .key = "diagnostics.client-log-buf-size",
- .voltype = "debug/io-stats",
- .option = "!log-buf-size",
- .op_version = GD_OP_VERSION_3_6_0,
- .flags = OPT_FLAG_CLIENT_OPT
- },
- { .key = "diagnostics.brick-log-flush-timeout",
- .voltype = "debug/io-stats",
- .option = "!log-flush-timeout",
- .op_version = GD_OP_VERSION_3_6_0,
- },
- { .key = "diagnostics.client-log-flush-timeout",
- .voltype = "debug/io-stats",
- .option = "!log-flush-timeout",
- .op_version = GD_OP_VERSION_3_6_0,
- .flags = OPT_FLAG_CLIENT_OPT
- },
-
- /* IO-cache xlator options */
- { .key = "performance.cache-max-file-size",
- .voltype = "performance/io-cache",
- .option = "max-file-size",
- .op_version = 1,
- .validate_fn = validate_cache_max_min_size,
- .flags = OPT_FLAG_CLIENT_OPT
- },
- { .key = "performance.cache-min-file-size",
- .voltype = "performance/io-cache",
- .option = "min-file-size",
- .op_version = 1,
- .validate_fn = validate_cache_max_min_size,
- .flags = OPT_FLAG_CLIENT_OPT
- },
- { .key = "performance.cache-refresh-timeout",
- .voltype = "performance/io-cache",
- .option = "cache-timeout",
- .op_version = 1,
- .flags = OPT_FLAG_CLIENT_OPT
- },
- { .key = "performance.cache-priority",
- .voltype = "performance/io-cache",
- .option = "priority",
- .op_version = 1,
- .flags = OPT_FLAG_CLIENT_OPT
- },
- { .key = "performance.cache-size",
- .voltype = "performance/io-cache",
- .op_version = 1,
- .flags = OPT_FLAG_CLIENT_OPT
- },
-
- /* IO-threads xlator options */
- { .key = "performance.io-thread-count",
- .voltype = "performance/io-threads",
- .option = "thread-count",
- .op_version = 1
- },
- { .key = "performance.high-prio-threads",
- .voltype = "performance/io-threads",
- .op_version = 1
- },
- { .key = "performance.normal-prio-threads",
- .voltype = "performance/io-threads",
- .op_version = 1
- },
- { .key = "performance.low-prio-threads",
- .voltype = "performance/io-threads",
- .op_version = 1
- },
- { .key = "performance.least-prio-threads",
- .voltype = "performance/io-threads",
- .op_version = 1
- },
- { .key = "performance.enable-least-priority",
- .voltype = "performance/io-threads",
- .op_version = 1
- },
- { .key = "performance.least-rate-limit",
- .voltype = "performance/io-threads",
- .op_version = 2
- },
-
- /* Other perf xlators' options */
- { .key = "performance.cache-size",
- .voltype = "performance/quick-read",
- .op_version = 1,
- .flags = OPT_FLAG_CLIENT_OPT
- },
- { .key = "performance.flush-behind",
- .voltype = "performance/write-behind",
- .option = "flush-behind",
- .op_version = 1,
- .flags = OPT_FLAG_CLIENT_OPT
- },
- { .key = "performance.nfs.flush-behind",
- .voltype = "performance/write-behind",
- .option = "flush-behind",
- .op_version = 1,
- .flags = OPT_FLAG_CLIENT_OPT
- },
- { .key = "performance.write-behind-window-size",
- .voltype = "performance/write-behind",
- .option = "cache-size",
- .op_version = 1,
- .flags = OPT_FLAG_CLIENT_OPT
- },
- { .key = "performance.nfs.write-behind-window-size",
- .voltype = "performance/write-behind",
- .option = "cache-size",
- .op_version = 1,
- .flags = OPT_FLAG_CLIENT_OPT
- },
- { .key = "performance.strict-o-direct",
- .voltype = "performance/write-behind",
- .option = "strict-O_DIRECT",
- .op_version = 2,
- .flags = OPT_FLAG_CLIENT_OPT
- },
- { .key = "performance.nfs.strict-o-direct",
- .voltype = "performance/write-behind",
- .option = "strict-O_DIRECT",
- .op_version = 2,
- .flags = OPT_FLAG_CLIENT_OPT
- },
- { .key = "performance.strict-write-ordering",
- .voltype = "performance/write-behind",
- .option = "strict-write-ordering",
- .op_version = 2,
- .flags = OPT_FLAG_CLIENT_OPT
- },
- { .key = "performance.nfs.strict-write-ordering",
- .voltype = "performance/write-behind",
- .option = "strict-write-ordering",
- .op_version = 2,
- .flags = OPT_FLAG_CLIENT_OPT
- },
- { .key = "performance.lazy-open",
- .voltype = "performance/open-behind",
- .option = "lazy-open",
- .op_version = 3,
- .flags = OPT_FLAG_CLIENT_OPT
- },
- { .key = "performance.read-after-open",
- .voltype = "performance/open-behind",
- .option = "read-after-open",
- .op_version = 3,
- .flags = OPT_FLAG_CLIENT_OPT
- },
- { .key = "performance.read-ahead-page-count",
- .voltype = "performance/read-ahead",
- .option = "page-count",
- .op_version = 1,
- .flags = OPT_FLAG_CLIENT_OPT
- },
- { .key = "performance.md-cache-timeout",
- .voltype = "performance/md-cache",
- .option = "md-cache-timeout",
- .op_version = 2,
- .flags = OPT_FLAG_CLIENT_OPT
- },
-
- /* Crypt xlator options */
-
- { .key = "features.encryption",
- .voltype = "encryption/crypt",
- .option = "!feat",
- .value = "off",
- .op_version = 3,
- .description = "enable/disable client-side encryption for "
- "the volume.",
- .flags = OPT_FLAG_CLIENT_OPT | OPT_FLAG_XLATOR_OPT
- },
-
- { .key = "encryption.master-key",
- .voltype = "encryption/crypt",
- .op_version = 3,
- .flags = OPT_FLAG_CLIENT_OPT
- },
- { .key = "encryption.data-key-size",
- .voltype = "encryption/crypt",
- .op_version = 3,
- .flags = OPT_FLAG_CLIENT_OPT
- },
- { .key = "encryption.block-size",
- .voltype = "encryption/crypt",
- .op_version = 3,
- .flags = OPT_FLAG_CLIENT_OPT
- },
-
- /* Client xlator options */
- { .key = "network.frame-timeout",
- .voltype = "protocol/client",
- .op_version = 1,
- .flags = OPT_FLAG_CLIENT_OPT
- },
- { .key = "network.ping-timeout",
- .voltype = "protocol/client",
- .op_version = 1,
- .flags = OPT_FLAG_CLIENT_OPT
- },
- { .key = "network.tcp-window-size",
- .voltype = "protocol/client",
- .op_version = 1,
- .flags = OPT_FLAG_CLIENT_OPT
- },
- { .key = "features.lock-heal",
- .voltype = "protocol/client",
- .option = "lk-heal",
- .op_version = 1,
- .flags = OPT_FLAG_CLIENT_OPT
- },
- { .key = "features.grace-timeout",
- .voltype = "protocol/client",
- .option = "grace-timeout",
- .op_version = 1,
- .flags = OPT_FLAG_CLIENT_OPT
- },
- { .key = "client.ssl",
- .voltype = "protocol/client",
- .option = "transport.socket.ssl-enabled",
- .type = NO_DOC,
- .op_version = 2,
- .flags = OPT_FLAG_CLIENT_OPT
- },
- { .key = "network.remote-dio",
- .voltype = "protocol/client",
- .option = "filter-O_DIRECT",
- .op_version = 2,
- .flags = OPT_FLAG_CLIENT_OPT
- },
-
- /* Server xlator options */
- { .key = "network.tcp-window-size",
- .voltype = "protocol/server",
- .op_version = 1
- },
- { .key = "network.inode-lru-limit",
- .voltype = "protocol/server",
- .op_version = 1
- },
- { .key = AUTH_ALLOW_MAP_KEY,
- .voltype = "protocol/server",
- .option = "!server-auth",
- .value = "*",
- .op_version = 1
- },
- { .key = AUTH_REJECT_MAP_KEY,
- .voltype = "protocol/server",
- .option = "!server-auth",
- .op_version = 1
- },
- { .key = "transport.keepalive",
- .voltype = "protocol/server",
- .option = "transport.socket.keepalive",
- .type = NO_DOC,
- .op_version = 1
- },
- { .key = "server.allow-insecure",
- .voltype = "protocol/server",
- .option = "rpc-auth-allow-insecure",
- .type = NO_DOC,
- .op_version = 1
- },
- { .key = "server.root-squash",
- .voltype = "protocol/server",
- .option = "root-squash",
- .op_version = 2
- },
- { .key = "server.anonuid",
- .voltype = "protocol/server",
- .option = "anonuid",
- .op_version = 3
- },
- { .key = "server.anongid",
- .voltype = "protocol/server",
- .option = "anongid",
- .op_version = 3
- },
- { .key = "server.statedump-path",
- .voltype = "protocol/server",
- .option = "statedump-path",
- .op_version = 1
- },
- { .key = "server.outstanding-rpc-limit",
- .voltype = "protocol/server",
- .option = "rpc.outstanding-rpc-limit",
- .type = GLOBAL_DOC,
- .op_version = 3
- },
- { .key = "features.lock-heal",
- .voltype = "protocol/server",
- .option = "lk-heal",
- .type = NO_DOC,
- .op_version = 1
- },
- { .key = "features.grace-timeout",
- .voltype = "protocol/server",
- .option = "grace-timeout",
- .type = NO_DOC,
- .op_version = 1
- },
- { .key = "server.ssl",
- .voltype = "protocol/server",
- .option = "transport.socket.ssl-enabled",
- .type = NO_DOC,
- .op_version = 2
- },
- { .key = "auth.ssl-allow",
- .voltype = "protocol/server",
- .option = "!ssl-allow",
- .type = NO_DOC,
- .op_version = GD_OP_VERSION_3_6_0,
- },
- { .key = "server.manage-gids",
- .voltype = "protocol/server",
- .op_version = GD_OP_VERSION_3_6_0,
- },
- { .key = "client.send-gids",
- .voltype = "protocol/client",
- .type = NO_DOC,
- .op_version = GD_OP_VERSION_3_6_0,
- },
- { .key = "server.gid-timeout",
- .voltype = "protocol/server",
- .op_version = GD_OP_VERSION_3_6_0,
- },
-
- /* Generic transport options */
- { .key = SSL_CERT_DEPTH_OPT,
- .voltype = "rpc-transport/socket",
- .option = "!ssl-cert-depth",
- .op_version = GD_OP_VERSION_3_6_0,
- },
- { .key = SSL_CIPHER_LIST_OPT,
- .voltype = "rpc-transport/socket",
- .option = "!ssl-cipher-list",
- .op_version = GD_OP_VERSION_3_6_0,
- },
-
- /* Performance xlators enable/disbable options */
- { .key = "performance.write-behind",
- .voltype = "performance/write-behind",
- .option = "!perf",
- .value = "on",
- .op_version = 1,
- .description = "enable/disable write-behind translator in the "
- "volume.",
- .flags = OPT_FLAG_CLIENT_OPT | OPT_FLAG_XLATOR_OPT
- },
- { .key = "performance.read-ahead",
- .voltype = "performance/read-ahead",
- .option = "!perf",
- .value = "on",
- .op_version = 1,
- .description = "enable/disable read-ahead translator in the volume.",
- .flags = OPT_FLAG_CLIENT_OPT | OPT_FLAG_XLATOR_OPT
- },
- { .key = "performance.readdir-ahead",
- .voltype = "performance/readdir-ahead",
- .option = "!perf",
- .value = "off",
- .op_version = 3,
- .description = "enable/disable readdir-ahead translator in the volume.",
- .flags = OPT_FLAG_CLIENT_OPT | OPT_FLAG_XLATOR_OPT
- },
-
- { .key = "performance.io-cache",
- .voltype = "performance/io-cache",
- .option = "!perf",
- .value = "on",
- .op_version = 1,
- .description = "enable/disable io-cache translator in the volume.",
- .flags = OPT_FLAG_CLIENT_OPT
- },
- { .key = "performance.quick-read",
- .voltype = "performance/quick-read",
- .option = "!perf",
- .value = "on",
- .op_version = 1,
- .description = "enable/disable quick-read translator in the volume.",
- .flags = OPT_FLAG_CLIENT_OPT | OPT_FLAG_XLATOR_OPT
-
- },
- { .key = "performance.open-behind",
- .voltype = "performance/open-behind",
- .option = "!perf",
- .value = "on",
- .op_version = 2,
- .description = "enable/disable open-behind translator in the volume.",
- .flags = OPT_FLAG_CLIENT_OPT | OPT_FLAG_XLATOR_OPT
-
- },
- { .key = "performance.stat-prefetch",
- .voltype = "performance/md-cache",
- .option = "!perf",
- .value = "on",
- .op_version = 1,
- .description = "enable/disable meta-data caching translator in the "
- "volume.",
- .flags = OPT_FLAG_CLIENT_OPT | OPT_FLAG_XLATOR_OPT
- },
- { .key = "performance.client-io-threads",
- .voltype = "performance/io-threads",
- .option = "!perf",
- .value = "off",
- .op_version = 1,
- .description = "enable/disable io-threads translator in the client "
- "graph of volume.",
- .flags = OPT_FLAG_CLIENT_OPT | OPT_FLAG_XLATOR_OPT
- },
- { .key = "performance.nfs.write-behind",
- .voltype = "performance/write-behind",
- .option = "!nfsperf",
- .value = "on",
- .op_version = 1,
- .description = "enable/disable write-behind translator in the volume",
- .flags = OPT_FLAG_XLATOR_OPT
- },
- { .key = "performance.nfs.read-ahead",
- .voltype = "performance/read-ahead",
- .option = "!nfsperf",
- .value = "off",
- .type = NO_DOC,
- .op_version = 1,
- .flags = OPT_FLAG_XLATOR_OPT
- },
- { .key = "performance.nfs.io-cache",
- .voltype = "performance/io-cache",
- .option = "!nfsperf",
- .value = "off",
- .type = NO_DOC,
- .op_version = 1,
- .flags = OPT_FLAG_XLATOR_OPT
- },
- { .key = "performance.nfs.quick-read",
- .voltype = "performance/quick-read",
- .option = "!nfsperf",
- .value = "off",
- .type = NO_DOC,
- .op_version = 1,
- .flags = OPT_FLAG_XLATOR_OPT
- },
- { .key = "performance.nfs.stat-prefetch",
- .voltype = "performance/md-cache",
- .option = "!nfsperf",
- .value = "off",
- .type = NO_DOC,
- .op_version = 1,
- .flags = OPT_FLAG_XLATOR_OPT
- },
- { .key = "performance.nfs.io-threads",
- .voltype = "performance/io-threads",
- .option = "!nfsperf",
- .value = "off",
- .type = NO_DOC,
- .op_version = 1,
- .flags = OPT_FLAG_XLATOR_OPT
- },
- { .key = "performance.force-readdirp",
- .voltype = "performance/md-cache",
- .option = "force-readdirp",
- .op_version = 2,
- .flags = OPT_FLAG_CLIENT_OPT
- },
-
- /* Feature translators */
- { .key = "features.file-snapshot",
- .voltype = "features/qemu-block",
- .option = "!feat",
- .value = "off",
- .op_version = 3,
- .description = "enable/disable file-snapshot feature in the "
- "volume.",
- .flags = OPT_FLAG_CLIENT_OPT | OPT_FLAG_XLATOR_OPT
- },
-
- { .key = "features.uss",
- .voltype = "features/snapview-server",
- .op_version = GD_OP_VERSION_3_6_0,
- .value = "off",
- .flags = OPT_FLAG_CLIENT_OPT | OPT_FLAG_XLATOR_OPT,
- .description = "enable/disable User Serviceable Snapshots on the "
- "volume."
- },
-
- { .key = "features.snapshot-directory",
- .voltype = "features/snapview-client",
- .op_version = GD_OP_VERSION_3_6_0,
- .value = ".snaps",
- .flags = OPT_FLAG_CLIENT_OPT | OPT_FLAG_XLATOR_OPT,
- .description = "Entry point directory for entering snapshot world"
- },
-
- { .key = "features.show-snapshot-directory",
- .voltype = "features/snapview-client",
- .op_version = GD_OP_VERSION_3_6_0,
- .value = "off",
- .flags = OPT_FLAG_CLIENT_OPT | OPT_FLAG_XLATOR_OPT,
- .description = "show entry point in readdir output of "
- "snapdir-entry-path which is set by samba"
- },
-
-#ifdef HAVE_LIB_Z
- /* Compressor-decompressor xlator options
- * defaults used from xlator/features/compress/src/cdc.h
- */
- { .key = "network.compression",
- .voltype = "features/cdc",
- .option = "!feat",
- .value = "off",
- .op_version = 3,
- .description = "enable/disable network compression translator",
- .flags = OPT_FLAG_XLATOR_OPT
- },
- { .key = "network.compression.window-size",
- .voltype = "features/cdc",
- .option = "window-size",
- .op_version = 3
- },
- { .key = "network.compression.mem-level",
- .voltype = "features/cdc",
- .option = "mem-level",
- .op_version = 3
- },
- { .key = "network.compression.min-size",
- .voltype = "features/cdc",
- .option = "min-size",
- .op_version = 3
- },
- { .key = "network.compression.compression-level",
- .voltype = "features/cdc",
- .option = "compression-level",
- .op_version = 3
- },
- { .key = "network.compression.debug",
- .voltype = "features/cdc",
- .option = "debug",
- .type = NO_DOC,
- .op_version = 3
- },
-#endif
-
- /* Quota xlator options */
- { .key = VKEY_FEATURES_LIMIT_USAGE,
- .voltype = "features/quota",
- .option = "limit-set",
- .type = NO_DOC,
- .op_version = 1,
- },
- {
- .key = "features.quota-timeout",
- .voltype = "features/quota",
- .option = "timeout",
- .value = "0",
- .op_version = 1,
- .validate_fn = validate_quota,
- },
- { .key = "features.default-soft-limit",
- .voltype = "features/quota",
- .option = "default-soft-limit",
- .type = NO_DOC,
- .op_version = 3,
- },
- { .key = "features.soft-timeout",
- .voltype = "features/quota",
- .option = "soft-timeout",
- .type = NO_DOC,
- .op_version = 3,
- },
- { .key = "features.hard-timeout",
- .voltype = "features/quota",
- .option = "hard-timeout",
- .type = NO_DOC,
- .op_version = 3,
- },
- { .key = "features.alert-time",
- .voltype = "features/quota",
- .option = "alert-time",
- .type = NO_DOC,
- .op_version = 3,
- },
- { .key = "features.quota-deem-statfs",
- .voltype = "features/quota",
- .option = "deem-statfs",
- .value = "off",
- .type = DOC,
- .op_version = 2,
- .validate_fn = validate_quota,
- },
-
- /* Marker xlator options */
- { .key = VKEY_MARKER_XTIME,
- .voltype = "features/marker",
- .option = "xtime",
- .value = "off",
- .type = NO_DOC,
- .flags = OPT_FLAG_FORCE,
- .op_version = 1
- },
- { .key = VKEY_MARKER_XTIME,
- .voltype = "features/marker",
- .option = "!xtime",
- .value = "off",
- .type = NO_DOC,
- .flags = OPT_FLAG_FORCE,
- .op_version = 1
- },
- { .key = VKEY_MARKER_XTIME_FORCE,
- .voltype = "features/marker",
- .option = "gsync-force-xtime",
- .value = "off",
- .type = NO_DOC,
- .flags = OPT_FLAG_FORCE,
- .op_version = 2
- },
- { .key = VKEY_MARKER_XTIME_FORCE,
- .voltype = "features/marker",
- .option = "!gsync-force-xtime",
- .value = "off",
- .type = NO_DOC,
- .flags = OPT_FLAG_FORCE,
- .op_version = 2
- },
- { .key = VKEY_FEATURES_QUOTA,
- .voltype = "features/marker",
- .option = "quota",
- .value = "off",
- .type = NO_DOC,
- .flags = OPT_FLAG_FORCE,
- .op_version = 1
- },
-
- /* Debug xlators options */
- { .key = "debug.trace",
- .voltype = "debug/trace",
- .option = "!debug",
- .value = "off",
- .type = NO_DOC,
- .op_version = 1,
- .flags = OPT_FLAG_XLATOR_OPT
- },
- { .key = "debug.log-history",
- .voltype = "debug/trace",
- .option = "log-history",
- .type = NO_DOC,
- .op_version = 2
- },
- { .key = "debug.log-file",
- .voltype = "debug/trace",
- .option = "log-file",
- .type = NO_DOC,
- .op_version = 2
- },
- { .key = "debug.exclude-ops",
- .voltype = "debug/trace",
- .option = "exclude-ops",
- .type = NO_DOC,
- .op_version = 2
- },
- { .key = "debug.include-ops",
- .voltype = "debug/trace",
- .option = "include-ops",
- .type = NO_DOC,
- .op_version = 2
- },
- { .key = "debug.error-gen",
- .voltype = "debug/error-gen",
- .option = "!debug",
- .value = "off",
- .type = NO_DOC,
- .op_version = 1,
- .flags = OPT_FLAG_XLATOR_OPT
- },
- { .key = "debug.error-failure",
- .voltype = "debug/error-gen",
- .option = "failure",
- .type = NO_DOC,
- .op_version = 3
- },
- { .key = "debug.error-number",
- .voltype = "debug/error-gen",
- .option = "error-no",
- .type = NO_DOC,
- .op_version = 3
- },
- { .key = "debug.random-failure",
- .voltype = "debug/error-gen",
- .option = "random-failure",
- .type = NO_DOC,
- .op_version = 3
- },
- { .key = "debug.error-fops",
- .voltype = "debug/error-gen",
- .option = "enable",
- .type = NO_DOC,
- .op_version = 3
- },
-
-
- /* NFS xlator options */
- { .key = "nfs.enable-ino32",
- .voltype = "nfs/server",
- .option = "nfs.enable-ino32",
- .type = GLOBAL_DOC,
- .op_version = 1
- },
- { .key = "nfs.mem-factor",
- .voltype = "nfs/server",
- .option = "nfs.mem-factor",
- .type = GLOBAL_DOC,
- .op_version = 1
- },
- { .key = "nfs.export-dirs",
- .voltype = "nfs/server",
- .option = "nfs3.export-dirs",
- .type = GLOBAL_DOC,
- .op_version = 1
- },
- { .key = "nfs.export-volumes",
- .voltype = "nfs/server",
- .option = "nfs3.export-volumes",
- .type = GLOBAL_DOC,
- .op_version = 1
- },
- { .key = "nfs.addr-namelookup",
- .voltype = "nfs/server",
- .option = "rpc-auth.addr.namelookup",
- .type = GLOBAL_DOC,
- .op_version = 1
- },
- { .key = "nfs.dynamic-volumes",
- .voltype = "nfs/server",
- .option = "nfs.dynamic-volumes",
- .type = GLOBAL_DOC,
- .op_version = 1
- },
- { .key = "nfs.register-with-portmap",
- .voltype = "nfs/server",
- .option = "rpc.register-with-portmap",
- .type = GLOBAL_DOC,
- .op_version = 1
- },
- { .key = "nfs.outstanding-rpc-limit",
- .voltype = "nfs/server",
- .option = "rpc.outstanding-rpc-limit",
- .type = GLOBAL_DOC,
- .op_version = 3
- },
- { .key = "nfs.port",
- .voltype = "nfs/server",
- .option = "nfs.port",
- .type = GLOBAL_DOC,
- .op_version = 1
- },
- { .key = "nfs.rpc-auth-unix",
- .voltype = "nfs/server",
- .option = "!rpc-auth.auth-unix.*",
- .op_version = 1
- },
- { .key = "nfs.rpc-auth-null",
- .voltype = "nfs/server",
- .option = "!rpc-auth.auth-null.*",
- .op_version = 1
- },
- { .key = "nfs.rpc-auth-allow",
- .voltype = "nfs/server",
- .option = "!rpc-auth.addr.*.allow",
- .op_version = 1
- },
- { .key = "nfs.rpc-auth-reject",
- .voltype = "nfs/server",
- .option = "!rpc-auth.addr.*.reject",
- .op_version = 1
- },
- { .key = "nfs.ports-insecure",
- .voltype = "nfs/server",
- .option = "!rpc-auth.ports.*.insecure",
- .op_version = 1
- },
- { .key = "nfs.transport-type",
- .voltype = "nfs/server",
- .option = "!nfs.transport-type",
- .op_version = 1,
- .description = "Specifies the nfs transport type. Valid "
- "transport types are 'tcp' and 'rdma'."
- },
- { .key = "nfs.trusted-sync",
- .voltype = "nfs/server",
- .option = "!nfs3.*.trusted-sync",
- .op_version = 1
- },
- { .key = "nfs.trusted-write",
- .voltype = "nfs/server",
- .option = "!nfs3.*.trusted-write",
- .op_version = 1
- },
- { .key = "nfs.volume-access",
- .voltype = "nfs/server",
- .option = "!nfs3.*.volume-access",
- .op_version = 1
- },
- { .key = "nfs.export-dir",
- .voltype = "nfs/server",
- .option = "!nfs3.*.export-dir",
- .op_version = 1
- },
- { .key = NFS_DISABLE_MAP_KEY,
- .voltype = "nfs/server",
- .option = "!nfs-disable",
- .op_version = 1
- },
- { .key = "nfs-ganesha.enable",
- .voltype = "nfs/server",
- .option = "!nfs-ganesha.enable",
- .op_version = GD_OP_VERSION_3_6_0,
- },
- { .key = "nfs-ganesha.host",
- .voltype = "nfs/server",
- .option = "!nfs-ganesha.host",
- .op_version = GD_OP_VERSION_3_6_0,
- },
- { .key = "nfs.nlm",
- .voltype = "nfs/server",
- .option = "nfs.nlm",
- .type = GLOBAL_DOC,
- .op_version = 1
- },
- { .key = "nfs.acl",
- .voltype = "nfs/server",
- .option = "nfs.acl",
- .type = GLOBAL_DOC,
- .op_version = 3
- },
- { .key = "nfs.mount-udp",
- .voltype = "nfs/server",
- .option = "nfs.mount-udp",
- .type = GLOBAL_DOC,
- .op_version = 1
- },
- { .key = "nfs.mount-rmtab",
- .voltype = "nfs/server",
- .option = "nfs.mount-rmtab",
- .type = GLOBAL_DOC,
- .op_version = 1
- },
- { .key = "nfs.rpc-statd",
- .voltype = "nfs/server",
- .option = "nfs.rpc-statd",
- .type = NO_DOC,
- .op_version = GD_OP_VERSION_3_6_0,
- },
- { .key = "nfs.log-level",
- .voltype = "nfs/server",
- .option = "nfs.log-level",
- .type = NO_DOC,
- .op_version = GD_OP_VERSION_3_6_0,
- },
- { .key = "nfs.server-aux-gids",
- .voltype = "nfs/server",
- .option = "nfs.server-aux-gids",
- .type = NO_DOC,
- .op_version = 2
- },
- { .key = "nfs.drc",
- .voltype = "nfs/server",
- .option = "nfs.drc",
- .type = GLOBAL_DOC,
- .op_version = 3
- },
- { .key = "nfs.drc-size",
- .voltype = "nfs/server",
- .option = "nfs.drc-size",
- .type = GLOBAL_DOC,
- .op_version = 3
- },
- { .key = "nfs.read-size",
- .voltype = "nfs/server",
- .option = "nfs3.read-size",
- .type = GLOBAL_DOC,
- .op_version = 3
- },
- { .key = "nfs.write-size",
- .voltype = "nfs/server",
- .option = "nfs3.write-size",
- .type = GLOBAL_DOC,
- .op_version = 3
- },
- { .key = "nfs.readdir-size",
- .voltype = "nfs/server",
- .option = "nfs3.readdir-size",
- .type = GLOBAL_DOC,
- .op_version = 3
- },
-
- /* Other options which don't fit any place above */
- { .key = "features.read-only",
- .voltype = "features/read-only",
- .option = "!read-only",
- .value = "off",
- .op_version = 1,
- .flags = OPT_FLAG_CLIENT_OPT | OPT_FLAG_XLATOR_OPT
- },
- { .key = "features.worm",
- .voltype = "features/worm",
- .option = "!worm",
- .value = "off",
- .op_version = 2,
- .flags = OPT_FLAG_CLIENT_OPT | OPT_FLAG_XLATOR_OPT
- },
- { .key = "storage.linux-aio",
- .voltype = "storage/posix",
- .op_version = 1
- },
- { .key = "storage.batch-fsync-mode",
- .voltype = "storage/posix",
- .op_version = 3
- },
- { .key = "storage.batch-fsync-delay-usec",
- .voltype = "storage/posix",
- .op_version = 3
- },
- { .key = "storage.xattr-user-namespace-mode",
- .voltype = "storage/posix",
- .op_version = GD_OP_VERSION_3_6_0,
- },
- { .key = "storage.owner-uid",
- .voltype = "storage/posix",
- .option = "brick-uid",
- .op_version = 1
- },
- { .key = "storage.owner-gid",
- .voltype = "storage/posix",
- .option = "brick-gid",
- .op_version = 1
- },
- { .key = "storage.node-uuid-pathinfo",
- .voltype = "storage/posix",
- .op_version = 3
- },
- { .key = "storage.health-check-interval",
- .voltype = "storage/posix",
- .op_version = 3
- },
- { .option = "update-link-count-parent",
- .key = "storage.build-pgfid",
- .voltype = "storage/posix",
- .op_version = GD_OP_VERSION_3_6_0,
- },
- { .key = "storage.bd-aio",
- .voltype = "storage/bd",
- .op_version = 3
- },
- { .key = "config.memory-accounting",
- .voltype = "configuration",
- .option = "!config",
- .op_version = 2,
- .flags = OPT_FLAG_CLIENT_OPT
- },
- { .key = "config.transport",
- .voltype = "configuration",
- .option = "!config",
- .op_version = 2
- },
- { .key = GLUSTERD_QUORUM_TYPE_KEY,
- .voltype = "mgmt/glusterd",
- .value = "off",
- .op_version = 2
- },
- { .key = GLUSTERD_QUORUM_RATIO_KEY,
- .voltype = "mgmt/glusterd",
- .value = "0",
- .op_version = 2
- },
- /* changelog translator - global tunables */
- { .key = "changelog.changelog",
- .voltype = "features/changelog",
- .type = NO_DOC,
- .op_version = 3
- },
- { .key = "changelog.changelog-dir",
- .voltype = "features/changelog",
- .type = NO_DOC,
- .op_version = 3
- },
- { .key = "changelog.encoding",
- .voltype = "features/changelog",
- .type = NO_DOC,
- .op_version = 3
- },
- { .key = "changelog.rollover-time",
- .voltype = "features/changelog",
- .type = NO_DOC,
- .op_version = 3
- },
- { .key = "changelog.fsync-interval",
- .voltype = "features/changelog",
- .type = NO_DOC,
- .op_version = 3
- },
- { .key = "changelog.changelog-barrier-timeout",
- .voltype = "features/changelog",
- .value = BARRIER_TIMEOUT,
- .op_version = GD_OP_VERSION_3_6_0,
- },
- { .key = "features.barrier",
- .voltype = "features/barrier",
- .value = "disable",
- .op_version = GD_OP_VERSION_3_6_0,
- },
- { .key = "features.barrier-timeout",
- .voltype = "features/barrier",
- .value = BARRIER_TIMEOUT,
- .op_version = GD_OP_VERSION_3_6_0,
- },
- { .key = "cluster.op-version",
- .voltype = "mgmt/glusterd",
- .op_version = GD_OP_VERSION_3_6_0,
- },
- { .key = NULL
- }
-};
diff --git a/xlators/mgmt/glusterd/src/glusterd.c b/xlators/mgmt/glusterd/src/glusterd.c
deleted file mode 100644
index c6886c1231d..00000000000
--- a/xlators/mgmt/glusterd/src/glusterd.c
+++ /dev/null
@@ -1,1713 +0,0 @@
-/*
- Copyright (c) 2006-2013 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 <time.h>
-#include <grp.h>
-#include <sys/uio.h>
-#include <sys/resource.h>
-
-#include <libgen.h>
-#include "uuid.h"
-
-#include "glusterd.h"
-#include "rpcsvc.h"
-#include "fnmatch.h"
-#include "xlator.h"
-#include "call-stub.h"
-#include "defaults.h"
-#include "list.h"
-#include "dict.h"
-#include "compat.h"
-#include "compat-errno.h"
-#include "syscall.h"
-#include "statedump.h"
-#include "glusterd-sm.h"
-#include "glusterd-op-sm.h"
-#include "glusterd-store.h"
-#include "glusterd-hooks.h"
-#include "glusterd-utils.h"
-#include "glusterd-locks.h"
-#include "common-utils.h"
-#include "run.h"
-#include "rpc-clnt-ping.h"
-
-#include "syncop.h"
-
-#include "glusterd-mountbroker.h"
-
-extern struct rpcsvc_program gluster_handshake_prog;
-extern struct rpcsvc_program gluster_cli_getspec_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_mgmt_v3_prog;
-extern struct rpcsvc_program gd_svc_peer_prog;
-extern struct rpcsvc_program gd_svc_cli_prog;
-extern struct rpcsvc_program gd_svc_cli_trusted_progs;
-extern struct rpc_clnt_program gd_brick_prog;
-extern struct rpcsvc_program glusterd_mgmt_hndsk_prog;
-
-extern char snap_mount_folder[PATH_MAX];
-
-rpcsvc_cbk_program_t glusterd_cbk_prog = {
- .progname = "Gluster Callback",
- .prognum = GLUSTER_CBK_PROGRAM,
- .progver = GLUSTER_CBK_VERSION,
-};
-
-struct rpcsvc_program *gd_inet_programs[] = {
- &gd_svc_peer_prog,
- &gd_svc_cli_trusted_progs, /* Must be index 1 for secure_mgmt! */
- &gd_svc_mgmt_prog,
- &gd_svc_mgmt_v3_prog,
- &gluster_pmap_prog,
- &gluster_handshake_prog,
- &glusterd_mgmt_hndsk_prog,
-};
-int gd_inet_programs_count = (sizeof (gd_inet_programs) /
- sizeof (gd_inet_programs[0]));
-
-struct rpcsvc_program *gd_uds_programs[] = {
- &gd_svc_cli_prog,
- &gluster_cli_getspec_prog,
-};
-int gd_uds_programs_count = (sizeof (gd_uds_programs) /
- sizeof (gd_uds_programs[0]));
-
-const char *gd_op_list[GD_OP_MAX + 1] = {
- [GD_OP_NONE] = "Invalid op",
- [GD_OP_CREATE_VOLUME] = "Create",
- [GD_OP_START_BRICK] = "Start Brick",
- [GD_OP_STOP_BRICK] = "Stop Brick",
- [GD_OP_DELETE_VOLUME] = "Delete",
- [GD_OP_START_VOLUME] = "Start",
- [GD_OP_STOP_VOLUME] = "Stop",
- [GD_OP_DEFRAG_VOLUME] = "Rebalance",
- [GD_OP_ADD_BRICK] = "Add brick",
- [GD_OP_REMOVE_BRICK] = "Remove brick",
- [GD_OP_REPLACE_BRICK] = "Replace brick",
- [GD_OP_SET_VOLUME] = "Set",
- [GD_OP_RESET_VOLUME] = "Reset",
- [GD_OP_SYNC_VOLUME] = "Sync",
- [GD_OP_LOG_ROTATE] = "Log rotate",
- [GD_OP_GSYNC_SET] = "Geo-replication",
- [GD_OP_PROFILE_VOLUME] = "Profile",
- [GD_OP_QUOTA] = "Quota",
- [GD_OP_STATUS_VOLUME] = "Status",
- [GD_OP_REBALANCE] = "Rebalance",
- [GD_OP_HEAL_VOLUME] = "Heal",
- [GD_OP_STATEDUMP_VOLUME] = "Statedump",
- [GD_OP_LIST_VOLUME] = "Lists",
- [GD_OP_CLEARLOCKS_VOLUME] = "Clear locks",
- [GD_OP_DEFRAG_BRICK_VOLUME] = "Rebalance",
- [GD_OP_COPY_FILE] = "Copy File",
- [GD_OP_SYS_EXEC] = "Execute system commands",
- [GD_OP_GSYNC_CREATE] = "Geo-replication Create",
- [GD_OP_SNAP] = "Snapshot",
- [GD_OP_MAX] = "Invalid op"
-};
-
-static int
-glusterd_opinfo_init ()
-{
- int32_t ret = -1;
-
- opinfo.op = GD_OP_NONE;
-
- return ret;
-}
-
-
-int
-glusterd_uuid_init ()
-{
- int ret = -1;
- xlator_t *this = NULL;
- glusterd_conf_t *priv = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- priv = this->private;
-
- ret = glusterd_retrieve_uuid ();
- if (ret == 0) {
- gf_log (this->name, GF_LOG_INFO,
- "retrieved UUID: %s", uuid_utoa (priv->uuid));
- return 0;
- }
-
- ret = glusterd_uuid_generate_save ();
-
- if (ret) {
- gf_log ("glusterd", GF_LOG_ERROR,
- "Unable to generate and save new UUID");
- return ret;
- }
-
- return 0;
-}
-
-int
-glusterd_uuid_generate_save ()
-{
- int ret = -1;
- glusterd_conf_t *priv = NULL;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- priv = this->private;
- GF_ASSERT (priv);
-
- uuid_generate (priv->uuid);
-
- gf_log (this->name, GF_LOG_INFO, "generated UUID: %s",
- uuid_utoa (priv->uuid));
-
- ret = glusterd_store_global_info (this);
-
- if (ret)
- gf_log (this->name, GF_LOG_ERROR,
- "Unable to store the generated uuid %s",
- uuid_utoa (priv->uuid));
-
- return ret;
-}
-
-int
-glusterd_options_init (xlator_t *this)
-{
- int ret = -1;
- glusterd_conf_t *priv = NULL;
- char *initial_version = "0";
-
- priv = this->private;
-
- priv->opts = dict_new ();
- if (!priv->opts)
- goto out;
-
- ret = glusterd_store_retrieve_options (this);
- if (ret == 0) {
- goto out;
- }
-
- ret = dict_set_str (priv->opts, GLUSTERD_GLOBAL_OPT_VERSION,
- initial_version);
- if (ret)
- goto out;
-
- ret = glusterd_store_options (this, priv->opts);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Unable to store version");
- return ret;
- }
-out:
- return 0;
-}
-
-int
-glusterd_fetchspec_notify (xlator_t *this)
-{
- int ret = -1;
- glusterd_conf_t *priv = NULL;
- rpc_transport_t *trans = NULL;
-
- priv = this->private;
-
- pthread_mutex_lock (&priv->xprt_lock);
- {
- list_for_each_entry (trans, &priv->xprt_list, list) {
- rpcsvc_callback_submit (priv->rpc, trans,
- &glusterd_cbk_prog,
- GF_CBK_FETCHSPEC, NULL, 0);
- }
- }
- pthread_mutex_unlock (&priv->xprt_lock);
-
- ret = 0;
-
- return ret;
-}
-
-int
-glusterd_fetchsnap_notify (xlator_t *this)
-{
- int ret = -1;
- glusterd_conf_t *priv = NULL;
- rpc_transport_t *trans = NULL;
-
- priv = this->private;
-
- /*
- * TODO: As of now, the identification of the rpc clients in the
- * handshake protocol is not there. So among so many glusterfs processes
- * registered with glusterd, it is hard to identify one particular
- * process (in this particular case, the snap daemon). So the callback
- * notification is sent to all the transports from the transport list.
- * Only those processes which have a rpc client registered for this
- * callback will respond to the notification. Once the identification
- * of the rpc clients becomes possible, the below section can be changed
- * to send callback notification to only those rpc clients, which have
- * registered.
- */
- pthread_mutex_lock (&priv->xprt_lock);
- {
- list_for_each_entry (trans, &priv->xprt_list, list) {
- rpcsvc_callback_submit (priv->rpc, trans,
- &glusterd_cbk_prog,
- GF_CBK_GET_SNAPS, NULL, 0);
- }
- }
- pthread_mutex_unlock (&priv->xprt_lock);
-
- ret = 0;
-
- return ret;
-}
-
-int
-glusterd_priv (xlator_t *this)
-{
- return 0;
-}
-
-
-
-int32_t
-mem_acct_init (xlator_t *this)
-{
- int ret = -1;
-
- if (!this)
- return ret;
-
- ret = xlator_mem_acct_init (this, gf_gld_mt_end + 1);
-
- if (ret != 0) {
- gf_log (this->name, GF_LOG_ERROR, "Memory accounting init"
- " failed");
- return ret;
- }
-
- return ret;
-}
-
-int
-glusterd_rpcsvc_notify (rpcsvc_t *rpc, void *xl, rpcsvc_event_t event,
- void *data)
-{
- xlator_t *this = NULL;
- rpc_transport_t *xprt = NULL;
- glusterd_conf_t *priv = NULL;
-
- if (!xl || !data) {
- gf_log ("glusterd", GF_LOG_WARNING,
- "Calling rpc_notify without initializing");
- goto out;
- }
-
- this = xl;
- xprt = data;
-
- priv = this->private;
-
- switch (event) {
- case RPCSVC_EVENT_ACCEPT:
- {
- INIT_LIST_HEAD (&xprt->list);
-
- pthread_mutex_lock (&priv->xprt_lock);
- list_add_tail (&xprt->list, &priv->xprt_list);
- pthread_mutex_unlock (&priv->xprt_lock);
- break;
- }
- case RPCSVC_EVENT_DISCONNECT:
- {
- pthread_mutex_lock (&priv->xprt_lock);
- list_del (&xprt->list);
- pthread_mutex_unlock (&priv->xprt_lock);
- pmap_registry_remove (this, 0, NULL, GF_PMAP_PORT_NONE, xprt);
- break;
- }
-
- default:
- break;
- }
-
-out:
- return 0;
-}
-
-
-static inline int32_t
-glusterd_program_register (xlator_t *this, rpcsvc_t *svc,
- rpcsvc_program_t *prog)
-{
- int32_t ret = -1;
-
- ret = rpcsvc_program_register (svc, prog);
- if (ret) {
- gf_log (this->name, GF_LOG_DEBUG,
- "cannot register program (name: %s, prognum:%d, "
- "progver:%d)", prog->progname, prog->prognum,
- prog->progver);
- goto out;
- }
-
-out:
- return ret;
-}
-
-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 (ret)
- goto out;
- }
-
- gf_log ("", GF_LOG_DEBUG, "listen-backlog value: %d", backlog);
-
-out:
- return ret;
-}
-
-#if SYNCDAEMON_COMPILE
-static int
-glusterd_check_gsync_present (int *valid_state)
-{
- char buff[PATH_MAX] = {0, };
- runner_t runner = {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;
- }
- goto out;
- }
-
- ptr = fgets(buff, sizeof(buff), runner_chio (&runner, STDOUT_FILENO));
- 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:
-
- runner_end (&runner);
-
- gf_log ("glusterd", 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
-glusterd_crt_georep_folders (char *georepdir, glusterd_conf_t *conf)
-{
- char *greplg_s = NULL;
- struct group *gr = NULL;
- int ret = 0;
-
- GF_ASSERT (georepdir);
- GF_ASSERT (conf);
-
- if (strlen (conf->workdir)+2 > PATH_MAX-strlen(GEOREP)) {
- ret = -1;
- gf_log ("glusterd", GF_LOG_CRITICAL,
- "directory path %s/"GEOREP" is longer than PATH_MAX",
- conf->workdir);
- goto out;
- }
-
- snprintf (georepdir, PATH_MAX, "%s/"GEOREP, conf->workdir);
- ret = mkdir_p (georepdir, 0777, _gf_true);
- if (-1 == ret) {
- gf_log ("glusterd", GF_LOG_CRITICAL,
- "Unable to create "GEOREP" directory %s",
- georepdir);
- goto out;
- }
-
- if (strlen (DEFAULT_LOG_FILE_DIRECTORY"/"GEOREP) >= PATH_MAX) {
- ret = -1;
- gf_log ("glusterd", GF_LOG_CRITICAL,
- "directory path "DEFAULT_LOG_FILE_DIRECTORY"/"
- GEOREP" is longer than PATH_MAX");
- goto out;
- }
- ret = mkdir_p (DEFAULT_LOG_FILE_DIRECTORY"/"GEOREP, 0777, _gf_true);
- if (-1 == ret) {
- gf_log ("glusterd", GF_LOG_CRITICAL,
- "Unable to create "GEOREP" log directory");
- goto out;
- }
-
- /* Slave log file directory */
- if (strlen(DEFAULT_LOG_FILE_DIRECTORY"/"GEOREP"-slaves") >= PATH_MAX) {
- ret = -1;
- gf_log ("glusterd", GF_LOG_CRITICAL,
- "directory path "DEFAULT_LOG_FILE_DIRECTORY"/"
- GEOREP"-slaves"" is longer than PATH_MAX");
- goto out;
- }
- ret = mkdir_p (DEFAULT_LOG_FILE_DIRECTORY"/"GEOREP"-slaves", 0777,
- _gf_true);
- if (-1 == ret) {
- gf_log ("glusterd", GF_LOG_CRITICAL,
- "Unable to create "GEOREP" slave log directory");
- goto out;
- }
-
- /* MountBroker log file directory */
- if (strlen(DEFAULT_LOG_FILE_DIRECTORY"/"GEOREP"-slaves/mbr") >= PATH_MAX) {
- ret = -1;
- gf_log ("glusterd", GF_LOG_CRITICAL,
- "directory path "DEFAULT_LOG_FILE_DIRECTORY"/"GEOREP
- "-slaves/mbr"" is longer than PATH_MAX");
- goto out;
- }
- ret = mkdir_p (DEFAULT_LOG_FILE_DIRECTORY"/"GEOREP"-slaves/mbr", 0777,
- _gf_true);
- if (-1 == ret) {
- gf_log ("glusterd", GF_LOG_CRITICAL,
- "Unable to create "GEOREP" mountbroker 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);
- if (ret == 0)
- ret = group_write_allow (DEFAULT_LOG_FILE_DIRECTORY"/"
- GEOREP"-slaves/mbr", gr->gr_gid);
- }
-
- out:
- gf_log("", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-
-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_TEMPLATE, conf->workdir);
- runner_add_arg (runner, "--config-set-rx");
-}
-
-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;
- runner_t runner = {0,};
- char georepdir[PATH_MAX] = {0,};
- int valid_state = 0;
-
- ret = setenv ("_GLUSTERD_CALLED_", "1", 1);
- if (ret < 0) {
- ret = 0;
- goto out;
- }
- valid_state = -1;
- ret = glusterd_check_gsync_present (&valid_state);
- if (-1 == ret) {
- ret = valid_state;
- goto out;
- }
-
- glusterd_crt_georep_folders (georepdir, conf);
- if (ret) {
- ret = 0;
- goto out;
- }
-
- /************
- * 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", "/nonexistent/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",
- "aux-gfid-mount",
- ".", ".", NULL);
- RUN_GSYNCD_CMD;
-
- /* 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;
-
- /* ssh-command tar */
- runinit_gsyncd_setrx (&runner, conf);
- runner_add_arg (&runner, "ssh-command-tar");
- runner_argprintf (&runner,
- "ssh -oPasswordAuthentication=no "
- "-oStrictHostKeyChecking=no "
- "-i %s/tar_ssh.pem", georepdir);
- runner_add_args (&runner, ".", ".", NULL);
- RUN_GSYNCD_CMD;
-
- /* pid-file */
- runinit_gsyncd_setrx (&runner, conf);
- runner_add_arg (&runner, "pid-file");
- runner_argprintf (&runner, "%s/${mastervol}_${remotehost}_${slavevol}/${eSlave}.pid", georepdir);
- runner_add_args (&runner, ".", ".", NULL);
- RUN_GSYNCD_CMD;
-
- /* geo-rep working dir */
- runinit_gsyncd_setrx (&runner, conf);
- runner_add_arg (&runner, "georep-session-working-dir");
- runner_argprintf (&runner, "%s/${mastervol}_${remotehost}_${slavevol}/", georepdir);
- runner_add_args (&runner, ".", ".", NULL);
- RUN_GSYNCD_CMD;
-
- /* state-file */
- runinit_gsyncd_setrx (&runner, conf);
- runner_add_arg (&runner, "state-file");
- runner_argprintf (&runner, "%s/${mastervol}_${remotehost}_${slavevol}/${eSlave}.status", georepdir);
- runner_add_args (&runner, ".", ".", NULL);
- RUN_GSYNCD_CMD;
-
- /* state-detail-file */
- runinit_gsyncd_setrx (&runner, conf);
- runner_add_arg (&runner, "state-detail-file");
- runner_argprintf (&runner, "%s/${mastervol}_${remotehost}_${slavevol}/${eSlave}-detail.status",
- georepdir);
- runner_add_args (&runner, ".", ".", NULL);
- RUN_GSYNCD_CMD;
-
- /* state-detail-file */
- runinit_gsyncd_setrx (&runner, conf);
- runner_add_arg (&runner, "state-detail-file");
- runner_argprintf (&runner, "%s/${mastervol}_${remotehost}_${slavevol}/${eSlave}-detail.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;
-
- /* socketdir */
- runinit_gsyncd_setrx (&runner, conf);
- runner_add_args (&runner, "socketdir", GLUSTERD_SOCK_DIR, ".", ".", NULL);
- RUN_GSYNCD_CMD;
-
- /* 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;
-
- /* gluster-log-file */
- runinit_gsyncd_setrx (&runner, conf);
- runner_add_args (&runner,
- "gluster-log-file",
- DEFAULT_LOG_FILE_DIRECTORY"/"GEOREP"/${mastervol}/${eSlave}${local_id}.gluster.log",
- ".", ".", NULL);
- RUN_GSYNCD_CMD;
-
- /* ignore-deletes */
- runinit_gsyncd_setrx (&runner, conf);
- runner_add_args (&runner, "ignore-deletes", "true", ".", ".", NULL);
- RUN_GSYNCD_CMD;
-
- /* special-sync-mode */
- runinit_gsyncd_setrx (&runner, conf);
- runner_add_args (&runner, "special-sync-mode", "partial", ".", ".", NULL);
- RUN_GSYNCD_CMD;
-
- /* change-detector == changelog */
- runinit_gsyncd_setrx (&runner, conf);
- runner_add_args(&runner, "change-detector", "changelog", ".", ".", NULL);
- RUN_GSYNCD_CMD;
-
- runinit_gsyncd_setrx (&runner, conf);
- runner_add_arg(&runner, "working-dir");
- runner_argprintf(&runner, "%s/${mastervol}/${eSlave}",
- DEFAULT_VAR_RUN_DIRECTORY);
- runner_add_args (&runner, ".", ".", NULL);
- RUN_GSYNCD_CMD;
-
- /************
- * 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",
- "aux-gfid-mount",
- ".", NULL);
- RUN_GSYNCD_CMD;
-
- /* 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;
-
- /* MountBroker log-file */
- runinit_gsyncd_setrx (&runner, conf);
- runner_add_args (&runner,
- "log-file-mbr",
- DEFAULT_LOG_FILE_DIRECTORY"/"GEOREP"-slaves/mbr/${session_owner}:${eSlave}.log",
- ".", NULL);
- RUN_GSYNCD_CMD;
-
- /* 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;
-
- out:
- return ret ? -1 : 0;
-}
-#undef RUN_GSYNCD_CMD
-#else /* SYNCDAEMON_COMPILE */
-static int
-configure_syncdaemon (glusterd_conf_t *conf)
-{
- return 0;
-}
-#endif /* !SYNCDAEMON_COMPILE */
-
-
-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 = sys_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 = sys_mkdirat (dfd0, MB_HIVE, 0711);
- if (ret == -1 && errno == EEXIST)
- ret = 0;
- if (ret != -1)
- ret = sys_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 int
-_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 rv = 0;
- gf_mount_spec_t *mspec = NULL;
- char *user = NULL;
- char *volfile_server = NULL;
-
- 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 0;
-
- 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 0;
- err:
-
- gf_log ("", GF_LOG_ERROR,
- "adding %smount spec failed: label: %s desc: %s",
- georep ? GEOREP" " : "", label, pdesc);
-
- if (mspec) {
- if (mspec->patterns) {
- GF_FREE (mspec->patterns->components);
- GF_FREE (mspec->patterns);
- }
- GF_FREE (mspec);
- }
-
- return -1;
-}
-
-
-int
-glusterd_uds_rpcsvc_notify (rpcsvc_t *rpc, void *xl, rpcsvc_event_t event,
- void *data)
-{
- /* glusterd_rpcsvc_notify() does stuff that calls coming in from the
- * unix domain socket don't need. This is just an empty function to be
- * used for the uds listener. This will be used later if required.
- */
- return 0;
-}
-
-/* The glusterd unix domain socket listener only listens for cli */
-rpcsvc_t *
-glusterd_init_uds_listener (xlator_t *this)
-{
- int ret = -1;
- dict_t *options = NULL;
- rpcsvc_t *rpc = NULL;
- data_t *sock_data = NULL;
- char sockfile[PATH_MAX+1] = {0,};
- int i = 0;
-
-
- GF_ASSERT (this);
-
- sock_data = dict_get (this->options, "glusterd-sockfile");
- if (!sock_data) {
- strncpy (sockfile, DEFAULT_GLUSTERD_SOCKFILE, PATH_MAX);
- } else {
- strncpy (sockfile, sock_data->data, PATH_MAX);
- }
-
- options = dict_new ();
- if (!options)
- goto out;
-
- ret = rpcsvc_transport_unix_options_build (&options, sockfile);
- if (ret)
- goto out;
-
- rpc = rpcsvc_init (this, this->ctx, options, 8);
- if (rpc == NULL) {
- ret = -1;
- goto out;
- }
-
- ret = rpcsvc_register_notify (rpc, glusterd_uds_rpcsvc_notify,
- this);
- if (ret) {
- gf_log (this->name, GF_LOG_DEBUG,
- "Failed to register notify function");
- goto out;
- }
-
- ret = rpcsvc_create_listeners (rpc, options, this->name);
- if (ret != 1) {
- gf_log (this->name, GF_LOG_DEBUG, "Failed to create listener");
- goto out;
- }
- ret = 0;
-
- for (i = 0; i < gd_uds_programs_count; i++) {
- ret = glusterd_program_register (this, rpc, gd_uds_programs[i]);
- if (ret) {
- i--;
- for (; i >= 0; i--)
- rpcsvc_program_unregister (rpc,
- gd_uds_programs[i]);
-
- goto out;
- }
- }
-
-out:
- if (options)
- dict_unref (options);
-
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to start glusterd "
- "unix domain socket listener.");
- if (rpc) {
- GF_FREE (rpc);
- rpc = NULL;
- }
- }
- return rpc;
-}
-
-void
-glusterd_stop_uds_listener (xlator_t *this)
-{
- glusterd_conf_t *conf = NULL;
- rpcsvc_listener_t *listener = NULL;
- rpcsvc_listener_t *next = NULL;
-
- GF_ASSERT (this);
- conf = this->private;
-
- (void) rpcsvc_program_unregister (conf->uds_rpc, &gd_svc_cli_prog);
- (void) rpcsvc_program_unregister (conf->uds_rpc, &gluster_handshake_prog);
-
- list_for_each_entry_safe (listener, next, &conf->uds_rpc->listeners,
- list) {
- rpcsvc_listener_destroy (listener);
- }
-
- (void) rpcsvc_unregister_notify (conf->uds_rpc, glusterd_rpcsvc_notify,
- this);
-
- unlink (DEFAULT_GLUSTERD_SOCKFILE);
-
- GF_FREE (conf->uds_rpc);
- conf->uds_rpc = NULL;
-
- return;
-}
-
-static int
-glusterd_init_snap_folder (xlator_t *this)
-{
- int ret = -1;
- struct stat buf = {0,};
-
- GF_ASSERT (this);
-
- /* Snapshot volumes are mounted under /var/run/gluster/snaps folder.
- * But /var/run is normally a symbolic link to /run folder, which
- * creates problems as the entry point in the mtab for the mount point
- * and glusterd maintained entry point will be different. Therefore
- * identify the correct run folder and use it for snap volume mounting.
- */
- ret = lstat (GLUSTERD_VAR_RUN_DIR, &buf);
- if (ret != 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "stat fails on %s, exiting. (errno = %d)",
- GLUSTERD_VAR_RUN_DIR, errno);
- goto out;
- }
-
- /* If /var/run is symlink then use /run folder */
- if (S_ISLNK (buf.st_mode)) {
- strcpy (snap_mount_folder, GLUSTERD_RUN_DIR);
- } else {
- strcpy (snap_mount_folder, GLUSTERD_VAR_RUN_DIR);
- }
-
- strcat (snap_mount_folder, GLUSTERD_DEFAULT_SNAPS_BRICK_DIR);
-
- ret = stat (snap_mount_folder, &buf);
- if ((ret != 0) && (ENOENT != errno)) {
- gf_log (this->name, GF_LOG_ERROR,
- "stat fails on %s, exiting. (errno = %d)",
- snap_mount_folder, errno);
- ret = -1;
- goto out;
- }
-
- if ((!ret) && (!S_ISDIR(buf.st_mode))) {
- gf_log (this->name, GF_LOG_CRITICAL,
- "Provided snap path %s is not a directory,"
- "exiting", snap_mount_folder);
- ret = -1;
- goto out;
- }
-
- if ((-1 == ret) && (ENOENT == errno)) {
- /* Create missing folders */
- ret = mkdir_p (snap_mount_folder, 0777, _gf_true);
-
- if (-1 == ret) {
- gf_log (this->name, GF_LOG_CRITICAL,
- "Unable to create directory %s"
- " ,errno = %d", snap_mount_folder, errno);
- goto out;
- }
- }
-
-out:
- return ret;
-}
-
-
-/*
- * init - called during glusterd initialization
- *
- * @this:
- *
- */
-int
-init (xlator_t *this)
-{
- int32_t ret = -1;
- rpcsvc_t *rpc = NULL;
- rpcsvc_t *uds_rpc = NULL;
- glusterd_conf_t *conf = NULL;
- data_t *dir_data = NULL;
- struct stat buf = {0,};
- char storedir [PATH_MAX] = {0,};
- char workdir [PATH_MAX] = {0,};
- char hooks_dir [PATH_MAX] = {0,};
- char cmd_log_filename [PATH_MAX] = {0,};
- int first_time = 0;
- char *mountbroker_root = NULL;
- int i = 0;
- char *valgrind_str = NULL;
-
-#ifndef GF_DARWIN_HOST_OS
- {
- struct rlimit lim;
- lim.rlim_cur = 65536;
- lim.rlim_max = 65536;
-
- if (setrlimit (RLIMIT_NOFILE, &lim) == -1) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to set 'ulimit -n "
- " 65536': %s", strerror(errno));
- } else {
- gf_log (this->name, GF_LOG_INFO,
- "Maximum allowed open file descriptors "
- "set to 65536");
- }
- }
-#endif
-
- dir_data = dict_get (this->options, "working-directory");
-
- if (!dir_data) {
- //Use default working dir
- strncpy (workdir, GLUSTERD_DEFAULT_WORKDIR, PATH_MAX);
- } else {
- strncpy (workdir, dir_data->data, PATH_MAX);
- }
-
- ret = stat (workdir, &buf);
- if ((ret != 0) && (ENOENT != errno)) {
- gf_log (this->name, GF_LOG_ERROR,
- "stat fails on %s, exiting. (errno = %d)",
- workdir, errno);
- exit (1);
- }
-
- if ((!ret) && (!S_ISDIR(buf.st_mode))) {
- gf_log (this->name, GF_LOG_CRITICAL,
- "Provided working area %s is not a directory,"
- "exiting", workdir);
- exit (1);
- }
-
-
- if ((-1 == ret) && (ENOENT == errno)) {
- ret = mkdir_p (workdir, 0777, _gf_true);
-
- if (-1 == ret) {
- gf_log (this->name, GF_LOG_CRITICAL,
- "Unable to create directory %s"
- " ,errno = %d", workdir, errno);
- exit (1);
- }
-
- first_time = 1;
- }
-
- setenv ("GLUSTERD_WORKDIR", workdir, 1);
- gf_log (this->name, GF_LOG_INFO, "Using %s as working directory",
- workdir);
-
- ret = glusterd_init_snap_folder (this);
-
- if (ret) {
- gf_log (this->name, GF_LOG_CRITICAL, "Unable to create "
- "snap backend folder");
- exit (1);
- }
-
- snprintf (cmd_log_filename, PATH_MAX,"%s/.cmd_log_history",
- DEFAULT_LOG_FILE_DIRECTORY);
- ret = gf_cmd_log_init (cmd_log_filename);
-
- if (ret == -1) {
- gf_log ("this->name", GF_LOG_CRITICAL,
- "Unable to create cmd log file %s", cmd_log_filename);
- exit (1);
- }
-
- snprintf (storedir, PATH_MAX, "%s/vols", workdir);
-
- ret = mkdir (storedir, 0777);
-
- if ((-1 == ret) && (errno != EEXIST)) {
- gf_log (this->name, GF_LOG_CRITICAL,
- "Unable to create volume directory %s"
- " ,errno = %d", storedir, errno);
- exit (1);
- }
-
- snprintf (storedir, PATH_MAX, "%s/snaps", workdir);
-
- ret = mkdir (storedir, 0777);
-
- if ((-1 == ret) && (errno != EEXIST)) {
- gf_log (this->name, GF_LOG_CRITICAL,
- "Unable to create snaps directory %s"
- " ,errno = %d", storedir, errno);
- exit (1);
- }
-
- snprintf (storedir, PATH_MAX, "%s/peers", workdir);
-
- ret = mkdir (storedir, 0777);
-
- if ((-1 == ret) && (errno != EEXIST)) {
- gf_log (this->name, GF_LOG_CRITICAL,
- "Unable to create peers directory %s"
- " ,errno = %d", storedir, errno);
- exit (1);
- }
-
- snprintf (storedir, PATH_MAX, "%s/bricks", DEFAULT_LOG_FILE_DIRECTORY);
- ret = mkdir (storedir, 0777);
- if ((-1 == ret) && (errno != EEXIST)) {
- gf_log (this->name, GF_LOG_CRITICAL,
- "Unable to create logs directory %s"
- " ,errno = %d", storedir, errno);
- exit (1);
- }
-
- snprintf (storedir, PATH_MAX, "%s/nfs", workdir);
- ret = mkdir (storedir, 0777);
- if ((-1 == ret) && (errno != EEXIST)) {
- gf_log (this->name, GF_LOG_CRITICAL,
- "Unable to create nfs directory %s"
- " ,errno = %d", storedir, errno);
- exit (1);
- }
-
- snprintf (storedir, PATH_MAX, "%s/glustershd", workdir);
- ret = mkdir (storedir, 0777);
- if ((-1 == ret) && (errno != EEXIST)) {
- gf_log (this->name, GF_LOG_CRITICAL,
- "Unable to create glustershd directory %s"
- " ,errno = %d", storedir, errno);
- exit (1);
- }
-
- snprintf (storedir, PATH_MAX, "%s/quotad", workdir);
- ret = mkdir (storedir, 0777);
- if ((-1 == ret) && (errno != EEXIST)) {
- gf_log (this->name, GF_LOG_CRITICAL,
- "Unable to create quotad directory %s"
- " ,errno = %d", storedir, errno);
- exit (1);
- }
-
- snprintf (storedir, PATH_MAX, "%s/groups", workdir);
- ret = mkdir (storedir, 0777);
- if ((-1 == ret) && (errno != EEXIST)) {
- gf_log (this->name, GF_LOG_CRITICAL,
- "Unable to create glustershd directory %s"
- " ,errno = %d", storedir, errno);
- exit (1);
- }
-
- ret = glusterd_rpcsvc_options_build (this->options);
- if (ret)
- goto out;
- rpc = rpcsvc_init (this, this->ctx, this->options, 64);
- if (rpc == NULL) {
- gf_log (this->name, GF_LOG_ERROR,
- "failed to init rpc");
- goto out;
- }
-
- ret = rpcsvc_register_notify (rpc, glusterd_rpcsvc_notify, this);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "rpcsvc_register_notify returned %d", ret);
- goto out;
- }
-
- /* Enable encryption for the TCP listener is management encryption is
- * enabled
- */
- if (this->ctx->secure_mgmt) {
- ret = dict_set_str (this->options,
- "transport.socket.ssl-enabled", "on");
- if (ret != 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "failed to set ssl-enabled in dict");
- goto out;
- }
- /*
- * With strong authentication, we can afford to allow
- * privileged operations over TCP.
- */
- gd_inet_programs[1] = &gd_svc_cli_prog;
- /*
- * This is the only place where we want secure_srvr to reflect
- * the management-plane setting.
- */
- this->ctx->secure_srvr = MGMT_SSL_ALWAYS;
- }
-
- /*
- * only one (at most a pair - rdma and socket) listener for
- * glusterd1_mop_prog, gluster_pmap_prog and gluster_handshake_prog.
- */
- ret = rpcsvc_create_listeners (rpc, this->options, this->name);
- if (ret < 1) {
- gf_log (this->name, GF_LOG_ERROR,
- "creation of listener failed");
- ret = -1;
- goto out;
- }
-
- for (i = 0; i < gd_inet_programs_count; i++) {
- ret = glusterd_program_register (this, rpc,
- gd_inet_programs[i]);
- if (ret) {
- i--;
- for (; i >= 0; i--)
- rpcsvc_program_unregister (rpc,
- gd_inet_programs[i]);
-
- goto out;
- }
- }
-
- /*
- * Start a unix domain socket listener just for cli commands This
- * should prevent ports from being wasted by being in TIMED_WAIT when
- * cli commands are done continuously
- */
- uds_rpc = glusterd_init_uds_listener (this);
- if (uds_rpc == NULL) {
- ret = -1;
- goto out;
- }
-
- 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);
- conf->quotad = GF_CALLOC (1, sizeof (nodesrv_t),
- gf_gld_mt_nodesrv_t);
- GF_VALIDATE_OR_GOTO(this->name, conf->quotad, out);
-
- INIT_LIST_HEAD (&conf->peers);
- INIT_LIST_HEAD (&conf->volumes);
- INIT_LIST_HEAD (&conf->snapshots);
- INIT_LIST_HEAD (&conf->missed_snaps_list);
-
- pthread_mutex_init (&conf->mutex, NULL);
- conf->rpc = rpc;
- conf->uds_rpc = uds_rpc;
- conf->gfs_mgmt = &gd_brick_prog;
- strncpy (conf->workdir, workdir, PATH_MAX);
-
- synclock_init (&conf->big_lock);
- pthread_mutex_init (&conf->xprt_lock, NULL);
- 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,
- GLUSTERD_TR_LOG_SIZE);
- if (ret)
- goto out;
-
- conf->base_port = GF_IANA_PRIV_PORTS_START;
- if (dict_get_uint32(this->options, "base-port", &conf->base_port) == 0) {
- gf_log (this->name, GF_LOG_INFO,
- "base-port override: %d", conf->base_port);
- }
-
- /* Set option to run bricks on valgrind if enabled in glusterd.vol */
- 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");
- }
- }
-
- this->private = conf;
- glusterd_mgmt_v3_lock_init ();
- glusterd_txn_opinfo_dict_init ();
- (void) glusterd_nodesvc_set_online_status ("glustershd", _gf_false);
-
- GLUSTERD_GET_HOOKS_DIR (hooks_dir, GLUSTERD_HOOK_VER, conf);
- if (stat (hooks_dir, &buf)) {
- ret = glusterd_hooks_create_hooks_directory (conf->workdir);
- if (-1 == ret) {
- gf_log (this->name, GF_LOG_CRITICAL,
- "Unable to create hooks directory ");
- exit (1);
- }
- }
-
- INIT_LIST_HEAD (&conf->mount_specs);
-
- ret = dict_foreach (this->options, _install_mount_spec, NULL);
- 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)
- goto out;
-
- ret = configure_syncdaemon (conf);
- if (ret)
- goto out;
-
- ret = glusterd_restore ();
- if (ret < 0)
- goto out;
-
- /* If there are no 'friends', this would be the best time to
- * spawn process/bricks that may need (re)starting since last
- * time (this) glusterd was up.*/
-
- if (list_empty (&conf->peers)) {
- glusterd_launch_synctask (glusterd_spawn_daemons, NULL);
- }
- ret = glusterd_options_init (this);
- if (ret < 0)
- goto out;
-
- ret = glusterd_handle_upgrade_downgrade (this->options, conf);
- if (ret)
- goto out;
-
- ret = glusterd_hooks_spawn_worker (this);
- if (ret)
- goto out;
-
- ret = 0;
-out:
- if (ret < 0) {
- if (this->private != NULL) {
- GF_FREE (this->private);
- this->private = NULL;
- }
-
- }
-
- return ret;
-}
-
-
-
-
-/*
- * fini - finish function for glusterd, called before
- * unloading gluster.
- *
- * @this:
- *
- */
-void
-fini (xlator_t *this)
-{
- glusterd_conf_t *conf = NULL;
- if (!this || !this->private)
- goto out;
-
- conf = this->private;
-
- glusterd_stop_uds_listener (this);
-
- FREE (conf->pmap);
- if (conf->handle)
- gf_store_handle_destroy (conf->handle);
- glusterd_sm_tr_log_delete (&conf->op_sm_log);
- glusterd_mgmt_v3_lock_fini ();
- glusterd_txn_opinfo_dict_fini ();
- GF_FREE (conf);
-
- this->private = NULL;
-out:
- return;
-}
-
-/*
- * notify - notify function for glusterd
- * @this:
- * @trans:
- * @event:
- *
- */
-int
-notify (xlator_t *this, int32_t event, void *data, ...)
-{
- int ret = 0;
-
- switch (event) {
- case GF_EVENT_POLLIN:
- break;
-
- case GF_EVENT_POLLERR:
- break;
-
- case GF_EVENT_TRANSPORT_CLEANUP:
- break;
-
- default:
- default_notify (this, event, data);
- break;
-
- }
-
- return ret;
-}
-
-
-struct xlator_fops fops;
-
-struct xlator_cbks cbks;
-
-struct xlator_dumpops dumpops = {
- .priv = glusterd_priv,
-};
-
-
-struct volume_options options[] = {
- { .key = {"working-directory"},
- .type = GF_OPTION_TYPE_PATH,
- },
- { .key = {"transport-type"},
- .type = GF_OPTION_TYPE_ANY,
- },
- { .key = {"transport.*"},
- .type = GF_OPTION_TYPE_ANY,
- },
- { .key = {"rpc-auth.*"},
- .type = GF_OPTION_TYPE_ANY,
- },
- { .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,
- },
- { .key = {"run-with-valgrind"},
- .type = GF_OPTION_TYPE_BOOL,
- },
- { .key = {"server-quorum-type"},
- .type = GF_OPTION_TYPE_STR,
- .value = { "none", "server"},
- .description = "This feature is on the server-side i.e. in glusterd."
- " Whenever the glusterd on a machine observes that "
- "the quorum is not met, it brings down the bricks to "
- "prevent data split-brains. When the network "
- "connections are brought back up and the quorum is "
- "restored the bricks in the volume are brought back "
- "up."
- },
- { .key = {"server-quorum-ratio"},
- .type = GF_OPTION_TYPE_PERCENT,
- .description = "Sets the quorum percentage for the trusted "
- "storage pool."
- },
- { .key = {"glusterd-sockfile"},
- .type = GF_OPTION_TYPE_PATH,
- .description = "The socket file on which glusterd should listen for "
- "cli requests. Default is "DEFAULT_GLUSTERD_SOCKFILE "."
- },
- { .key = {"base-port"},
- .type = GF_OPTION_TYPE_INT,
- .description = "Sets the base port for portmap query"
- },
- { .key = {"snap-brick-path"},
- .type = GF_OPTION_TYPE_STR,
- .description = "directory where the bricks for the snapshots will be created"
- },
- { .key = {"ping-timeout"},
- .type = GF_OPTION_TYPE_TIME,
- .min = 0,
- .max = 300,
- .default_value = TOSTRING(RPC_DEFAULT_PING_TIMEOUT),
- },
- { .key = {NULL} },
-};
diff --git a/xlators/mgmt/glusterd/src/glusterd.h b/xlators/mgmt/glusterd/src/glusterd.h
deleted file mode 100644
index 61e38c07109..00000000000
--- a/xlators/mgmt/glusterd/src/glusterd.h
+++ /dev/null
@@ -1,1047 +0,0 @@
-/*
- Copyright (c) 2006-2013 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 _GLUSTERD_H_
-#define _GLUSTERD_H_
-
-#ifndef _CONFIG_H
-#define _CONFIG_H
-#include "config.h"
-#endif
-
-#include <sys/types.h>
-#include <dirent.h>
-#include <pthread.h>
-#include <libgen.h>
-
-#include "uuid.h"
-
-#include "rpc-clnt.h"
-#include "glusterfs.h"
-#include "xlator.h"
-#include "logging.h"
-#include "call-stub.h"
-#include "fd.h"
-#include "byte-order.h"
-#include "glusterd-mem-types.h"
-#include "rpcsvc.h"
-#include "glusterd-sm.h"
-#include "glusterd1-xdr.h"
-#include "protocol-common.h"
-#include "glusterd-pmap.h"
-#include "cli1-xdr.h"
-#include "syncop.h"
-#include "store.h"
-
-#define GLUSTERD_TR_LOG_SIZE 50
-#define GLUSTERD_NAME "glusterd"
-#define GLUSTERD_SOCKET_LISTEN_BACKLOG 128
-#define GLUSTERD_QUORUM_TYPE_KEY "cluster.server-quorum-type"
-#define GLUSTERD_QUORUM_RATIO_KEY "cluster.server-quorum-ratio"
-#define GLUSTERD_GLOBAL_OPT_VERSION "global-option-version"
-#define GLUSTERD_COMMON_PEM_PUB_FILE "/geo-replication/common_secret.pem.pub"
-#define GEO_CONF_MAX_OPT_VALS 6
-#define GLUSTERD_CREATE_HOOK_SCRIPT "/hooks/1/gsync-create/post/" \
- "S56glusterd-geo-rep-create-post.sh"
-
-
-#define GLUSTERD_SNAPS_MAX_HARD_LIMIT 256
-#define GLUSTERD_SNAPS_DEF_SOFT_LIMIT_PERCENT 90
-#define GLUSTERD_SNAPS_MAX_SOFT_LIMIT_PERCENT 100
-#define GLUSTERD_SERVER_QUORUM "server"
-
-#define FMTSTR_CHECK_VOL_EXISTS "Volume %s does not exist"
-#define FMTSTR_RESOLVE_BRICK "Could not find peer on which brick %s:%s resides"
-
-#define LOGSTR_FOUND_BRICK "Found brick %s:%s in volume %s"
-#define LOGSTR_BUILD_PAYLOAD "Failed to build payload for operation 'Volume %s'"
-#define LOGSTR_STAGE_FAIL "Staging of operation 'Volume %s' failed on %s %s %s"
-#define LOGSTR_COMMIT_FAIL "Commit of operation 'Volume %s' failed on %s %s %s"
-
-#define OPERRSTR_BUILD_PAYLOAD "Failed to build payload. Please check the log "\
- "file for more details."
-#define OPERRSTR_STAGE_FAIL "Staging failed on %s. Please check the log file " \
- "for more details."
-#define OPERRSTR_COMMIT_FAIL "Commit failed on %s. Please check the log file "\
- "for more details."
-
-struct glusterd_volinfo_;
-typedef struct glusterd_volinfo_ glusterd_volinfo_t;
-
-struct glusterd_snap_;
-typedef struct glusterd_snap_ glusterd_snap_t;
-
-typedef enum glusterd_op_ {
- GD_OP_NONE = 0,
- GD_OP_CREATE_VOLUME,
- GD_OP_START_BRICK,
- GD_OP_STOP_BRICK,
- GD_OP_DELETE_VOLUME,
- GD_OP_START_VOLUME,
- GD_OP_STOP_VOLUME,
- GD_OP_DEFRAG_VOLUME,
- GD_OP_ADD_BRICK,
- GD_OP_REMOVE_BRICK,
- GD_OP_REPLACE_BRICK,
- GD_OP_SET_VOLUME,
- GD_OP_RESET_VOLUME,
- GD_OP_SYNC_VOLUME,
- 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_COPY_FILE,
- GD_OP_SYS_EXEC,
- GD_OP_GSYNC_CREATE,
- GD_OP_SNAP,
- GD_OP_BARRIER,
- GD_OP_MAX,
-} glusterd_op_t;
-
-extern const char * gd_op_list[];
-
-struct glusterd_volgen {
- dict_t *dict;
-};
-
-typedef struct {
- struct rpc_clnt *rpc;
- gf_boolean_t online;
-} nodesrv_t;
-
-typedef struct {
- struct rpc_clnt *rpc;
- int port;
- gf_boolean_t online;
- gf_store_handle_t *handle;
-} glusterd_snapd_t;
-
-typedef struct {
- struct _volfile_ctx *volfile;
- pthread_mutex_t mutex;
- struct list_head peers;
- struct list_head xaction_peers;
- gf_boolean_t verify_volfile_checksum;
- gf_boolean_t trace;
- uuid_t uuid;
- char workdir[PATH_MAX];
- rpcsvc_t *rpc;
- nodesrv_t *shd;
- nodesrv_t *nfs;
- nodesrv_t *quotad;
- struct pmap_registry *pmap;
- struct list_head volumes;
- struct list_head snapshots; /*List of snap volumes */
- pthread_mutex_t xprt_lock;
- struct list_head xprt_list;
- gf_store_handle_t *handle;
- gf_timer_t *timer;
- glusterd_sm_tr_log_t op_sm_log;
- struct rpc_clnt_program *gfs_mgmt;
- dict_t *mgmt_v3_lock; /* Dict for saving
- * mgmt_v3 locks */
- dict_t *glusterd_txn_opinfo; /* Dict for saving
- * transaction opinfos */
- uuid_t global_txn_id; /* To be used in
- * heterogeneous
- * cluster with no
- * transaction ids */
-
- struct list_head mount_specs;
- gf_boolean_t valgrind;
- pthread_t brick_thread;
- void *hooks_priv;
-
- /* need for proper handshake_t */
- int op_version; /* Starts with 1 for 3.3.0 */
- xlator_t *xl; /* Should be set to 'THIS' before creating thread */
- gf_boolean_t pending_quorum_action;
- dict_t *opts;
- synclock_t big_lock;
- gf_boolean_t restart_done;
- rpcsvc_t *uds_rpc; /* RPCSVC for the unix domain socket */
- uint32_t base_port;
- char *snap_bricks_directory;
- gf_store_handle_t *missed_snaps_list_shandle;
- struct list_head missed_snaps_list;
- int ping_timeout;
-} glusterd_conf_t;
-
-
-typedef enum gf_brick_status {
- GF_BRICK_STOPPED,
- GF_BRICK_STARTED,
-} gf_brick_status_t;
-
-struct glusterd_brickinfo {
- char hostname[1024];
- char path[PATH_MAX];
- char device_path[PATH_MAX];
- char mount_dir[PATH_MAX];
- char brick_id[1024];/*Client xlator name, AFR changelog name*/
- char fstype [NAME_MAX]; /* Brick file-system type */
- char mnt_opts [1024]; /* Brick mount options */
- struct list_head brick_list;
- uuid_t uuid;
- int port;
- int rdma_port;
- char *logfile;
- gf_boolean_t signed_in;
- gf_store_handle_t *shandle;
- gf_brick_status_t status;
- struct rpc_clnt *rpc;
- int decommissioned;
- char vg[PATH_MAX]; /* FIXME: Use max size for length of vg */
- int caps; /* Capability */
- int32_t snap_status;
-};
-
-typedef struct glusterd_brickinfo glusterd_brickinfo_t;
-
-struct gf_defrag_brickinfo_ {
- char *name;
- int files;
- int size;
-};
-
-typedef int (*defrag_cbk_fn_t) (glusterd_volinfo_t *volinfo,
- gf_defrag_status_t status);
-
-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;
-};
-
-
-typedef struct glusterd_defrag_info_ glusterd_defrag_info_t;
-
-typedef enum gf_transport_type_ {
- GF_TRANSPORT_TCP, //DEFAULT
- GF_TRANSPORT_RDMA,
- GF_TRANSPORT_BOTH_TCP_RDMA,
-} gf_transport_type;
-
-
-typedef enum gf_rb_status_ {
- GF_RB_STATUS_NONE,
- GF_RB_STATUS_STARTED,
- GF_RB_STATUS_PAUSED,
-} gf_rb_status_t;
-
-struct _auth {
- char *username;
- char *password;
-};
-
-typedef struct _auth auth_t;
-
-/* Capabilities of xlator */
-#define CAPS_BD 0x00000001
-#define CAPS_THIN 0x00000002
-#define CAPS_OFFLOAD_COPY 0x00000004
-#define CAPS_OFFLOAD_SNAPSHOT 0x00000008
-#define CAPS_OFFLOAD_ZERO 0x00000020
-
-struct glusterd_rebalance_ {
- gf_defrag_status_t defrag_status;
- uint64_t rebalance_files;
- uint64_t rebalance_data;
- uint64_t lookedup_files;
- uint64_t skipped_files;
- glusterd_defrag_info_t *defrag;
- gf_cli_defrag_type defrag_cmd;
- uint64_t rebalance_failures;
- uuid_t rebalance_id;
- double rebalance_time;
- glusterd_op_t op;
- dict_t *dict; /* Dict to store misc information
- * like list of bricks being removed */
-};
-
-typedef struct glusterd_rebalance_ glusterd_rebalance_t;
-
-struct glusterd_replace_brick_ {
- gf_rb_status_t rb_status;
- glusterd_brickinfo_t *src_brick;
- glusterd_brickinfo_t *dst_brick;
- uuid_t rb_id;
-};
-
-typedef struct glusterd_replace_brick_ glusterd_replace_brick_t;
-
-typedef enum gd_quorum_status_ {
- NOT_APPLICABLE_QUORUM, //Does not follow quorum
- MEETS_QUORUM, //Follows quorum and meets.
- DOESNT_MEET_QUORUM, //Follows quorum and does not meet.
-} gd_quorum_status_t;
-
-struct glusterd_volinfo_ {
- gf_lock_t lock;
- gf_boolean_t is_snap_volume;
- glusterd_snap_t *snapshot;
- uuid_t restored_from_snap;
- char parent_volname[GD_VOLUME_NAME_MAX];
- /* In case of a snap volume
- i.e (is_snap_volume == TRUE) this
- field will contain the name of
- the volume which is snapped. In
- case of a non-snap volume, this
- field will be initialized as N/A */
- char volname[GD_VOLUME_NAME_MAX];
- int type;
- int brick_count;
- uint64_t snap_count;
- uint64_t snap_max_hard_limit;
- struct list_head vol_list;
- /* In case of a snap volume
- i.e (is_snap_volume == TRUE) this
- is linked to glusterd_snap_t->volumes.
- In case of a non-snap volume, this is
- linked to glusterd_conf_t->volumes */
- struct list_head snapvol_list;
- /* This is a current pointer for
- glusterd_volinfo_t->snap_volumes */
- struct list_head bricks;
- struct list_head snap_volumes;
- /* TODO : Need to remove this, as this
- * is already part of snapshot object.
- */
- glusterd_volume_status status;
- int sub_count; /* backward compatibility */
- int stripe_count;
- int replica_count;
- int disperse_count;
- int redundancy_count;
- int subvol_count; /* Number of subvolumes in a
- distribute volume */
- int dist_leaf_count; /* Number of bricks in one
- distribute subvolume */
- int port;
- gf_store_handle_t *shandle;
- gf_store_handle_t *rb_shandle;
- gf_store_handle_t *node_state_shandle;
- gf_store_handle_t *quota_conf_shandle;
-
- /* Defrag/rebalance related */
- glusterd_rebalance_t rebal;
-
- /* Replace brick status */
- glusterd_replace_brick_t rep_brick;
-
- int version;
- uint32_t quota_conf_version;
- uint32_t cksum;
- uint32_t quota_conf_cksum;
- gf_transport_type transport_type;
-
- dict_t *dict;
-
- uuid_t volume_id;
- auth_t auth;
- char *logdir;
-
- dict_t *gsync_slaves;
- dict_t *gsync_active_slaves;
-
- int decommission_in_progress;
- xlator_t *xl;
-
- gf_boolean_t memory_accounting;
- int caps; /* Capability */
-
- int op_version;
- int client_op_version;
- pthread_mutex_t reflock;
- int refcnt;
- gd_quorum_status_t quorum_status;
-
- glusterd_snapd_t snapd;
-};
-
-typedef enum gd_snap_status_ {
- GD_SNAP_STATUS_NONE,
- GD_SNAP_STATUS_INIT,
- GD_SNAP_STATUS_IN_USE,
- GD_SNAP_STATUS_DECOMMISSION,
- GD_SNAP_STATUS_UNDER_RESTORE,
- GD_SNAP_STATUS_RESTORED,
-} gd_snap_status_t;
-
-struct glusterd_snap_ {
- gf_lock_t lock;
- struct list_head volumes;
- struct list_head snap_list;
- char snapname[GLUSTERD_MAX_SNAP_NAME];
- uuid_t snap_id;
- char *description;
- time_t time_stamp;
- gf_boolean_t snap_restored;
- gd_snap_status_t snap_status;
- gf_store_handle_t *shandle;
-};
-
-typedef struct glusterd_snap_op_ {
- char *snap_vol_id;
- int32_t brick_num;
- char *brick_path;
- int32_t op;
- int32_t status;
- struct list_head snap_ops_list;
-} glusterd_snap_op_t;
-
-typedef struct glusterd_missed_snap_ {
- char *node_uuid;
- char *snap_uuid;
- struct list_head missed_snaps;
- struct list_head snap_ops;
-} glusterd_missed_snap_info;
-
-typedef enum gd_node_type_ {
- GD_NODE_NONE,
- GD_NODE_BRICK,
- GD_NODE_SHD,
- GD_NODE_REBALANCE,
- GD_NODE_NFS,
- GD_NODE_QUOTAD,
- GD_NODE_SNAPD,
-} gd_node_type;
-
-typedef enum missed_snap_stat {
- GD_MISSED_SNAP_NONE,
- GD_MISSED_SNAP_PENDING,
- GD_MISSED_SNAP_DONE,
-} missed_snap_stat;
-
-typedef struct glusterd_pending_node_ {
- struct list_head list;
- void *node;
- gd_node_type type;
- int32_t index;
-} glusterd_pending_node_t;
-
-struct gsync_config_opt_vals_ {
- char *op_name;
- int no_of_pos_vals;
- gf_boolean_t case_sensitive;
- char *values[GEO_CONF_MAX_OPT_VALS];
-};
-
-enum glusterd_op_ret {
- GLUSTERD_CONNECTION_AWAITED = 100,
-};
-
-enum glusterd_vol_comp_status_ {
- GLUSTERD_VOL_COMP_NONE = 0,
- GLUSTERD_VOL_COMP_SCS = 1,
- GLUSTERD_VOL_COMP_UPDATE_REQ,
- GLUSTERD_VOL_COMP_RJT,
-};
-
-#define GLUSTERD_DEFAULT_PORT GF_DEFAULT_BASE_PORT
-#define GLUSTERD_INFO_FILE "glusterd.info"
-#define GLUSTERD_VOLUME_QUOTA_CONFIG "quota.conf"
-#define GLUSTERD_VOLUME_DIR_PREFIX "vols"
-#define GLUSTERD_PEER_DIR_PREFIX "peers"
-#define GLUSTERD_VOLUME_INFO_FILE "info"
-#define GLUSTERD_VOLUME_SNAPD_INFO_FILE "snapd.info"
-#define GLUSTERD_SNAP_INFO_FILE "info"
-#define GLUSTERD_VOLUME_RBSTATE_FILE "rbstate"
-#define GLUSTERD_BRICK_INFO_DIR "bricks"
-#define GLUSTERD_CKSUM_FILE "cksum"
-#define GLUSTERD_VOL_QUOTA_CKSUM_FILE "quota.cksum"
-#define GLUSTERD_TRASH "trash"
-#define GLUSTERD_NODE_STATE_FILE "node_state.info"
-#define GLUSTERD_MISSED_SNAPS_LIST_FILE "missed_snaps_list"
-#define GLUSTERD_VOL_SNAP_DIR_PREFIX "snaps"
-
-#define GLUSTERD_DEFAULT_SNAPS_BRICK_DIR "/gluster/snaps"
-#define GLUSTERD_VAR_RUN_DIR "/var/run"
-#define GLUSTERD_RUN_DIR "/run"
-
-/* definitions related to replace brick */
-#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_VOLUME_DIR(path, volinfo, priv) \
- if (volinfo->is_snap_volume) { \
- snprintf (path, PATH_MAX, "%s/snaps/%s/%s", priv->workdir, \
- volinfo->snapshot->snapname, volinfo->volname); \
- } else { \
- snprintf (path, PATH_MAX, "%s/vols/%s", priv->workdir, \
- volinfo->volname); \
- }
-
-#define GLUSTERD_GET_SNAP_DIR(path, snap, priv) \
- snprintf (path, PATH_MAX, "%s/snaps/%s", priv->workdir, \
- snap->snapname);
-
-#define GLUSTERD_GET_SNAP_GEO_REP_DIR(path, snap, priv) \
- snprintf (path, PATH_MAX, "%s/snaps/%s/%s", priv->workdir, \
- snap->snapname, GEOREP);
-
-#define GLUSTERD_GET_BRICK_DIR(path, volinfo, priv) \
- if (volinfo->is_snap_volume) { \
- snprintf (path, PATH_MAX, "%s/snaps/%s/%s/%s", priv->workdir, \
- volinfo->snapshot->snapname, volinfo->volname, \
- GLUSTERD_BRICK_INFO_DIR); \
- } else { \
- snprintf (path, PATH_MAX, "%s/%s/%s/%s", priv->workdir, \
- 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_QUOTAD_DIR(path, priv) \
- snprintf (path, PATH_MAX, "%s/quotad", priv->workdir);
-
-#define GLUSTERD_GET_QUOTA_AUX_MOUNT_PATH(abspath, volname, path) \
- snprintf (abspath, sizeof (abspath)-1, \
- DEFAULT_VAR_RUN_DIRECTORY"/%s%s", volname, path);
-
-#define GLUSTERD_REMOVE_SLASH_FROM_PATH(path,string) do { \
- int i = 0; \
- for (i = 1; i < strlen (path); i++) { \
- string[i-1] = path[i]; \
- if (string[i-1] == '/' && (i != strlen(path) - 1)) \
- string[i-1] = '-'; \
- } \
- } while (0)
-
-#define GLUSTERD_GET_BRICK_PIDFILE(pidfile,volinfo,brickinfo, priv) do { \
- char exp_path[PATH_MAX] = {0,}; \
- char volpath[PATH_MAX] = {0,}; \
- GLUSTERD_GET_VOLUME_DIR (volpath, volinfo, priv); \
- GLUSTERD_REMOVE_SLASH_FROM_PATH (brickinfo->path, exp_path); \
- snprintf (pidfile, PATH_MAX, "%s/run/%s-%s.pid", \
- volpath, brickinfo->hostname, exp_path); \
- } while (0)
-
-#define GLUSTERD_GET_NFS_PIDFILE(pidfile,nfspath) { \
- snprintf (pidfile, PATH_MAX, "%s/run/nfs.pid", \
- nfspath); \
- }
-
-#define GLUSTERD_GET_QUOTAD_PIDFILE(pidfile,quotadpath) { \
- snprintf (pidfile, PATH_MAX, "%s/run/quotad.pid", \
- quotadpath); \
- }
-
-#define GLUSTERD_STACK_DESTROY(frame) do {\
- 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_OLD(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(MY_UUID)); \
- } while (0)
-
-#define GLUSTERD_GET_DEFRAG_SOCK_FILE(path, volinfo) do { \
- snprintf (path, UNIX_PATH_MAX, DEFAULT_VAR_RUN_DIRECTORY \
- "/gluster-rebalance-%s.sock", \
- uuid_utoa(volinfo->volume_id)); \
- } 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(MY_UUID)); \
- } while (0)
-
-#define GLUSTERFS_GET_AUX_MOUNT_PIDFILE(pidfile, volname) { \
- snprintf (pidfile, PATH_MAX-1, \
- DEFAULT_VAR_RUN_DIRECTORY"/%s.pid", volname); \
- }
-
-#define GLUSTERD_GET_UUID_NOHYPHEN(ret_string, uuid) do { \
- char *snap_volname_ptr = ret_string; \
- char *snap_volid_ptr = uuid_utoa(uuid); \
- while (*snap_volid_ptr) { \
- if (*snap_volid_ptr == '-') { \
- snap_volid_ptr++; \
- } else { \
- (*snap_volname_ptr++) = \
- (*snap_volid_ptr++); \
- } \
- } \
- *snap_volname_ptr = '\0'; \
- } while (0)
-
-int glusterd_uuid_init();
-
-int glusterd_uuid_generate_save ();
-
-#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];
-}
-
-int glusterd_big_locked_notify (struct rpc_clnt *rpc, void *mydata,
- rpc_clnt_event_t event,
- void *data, rpc_clnt_notify_t notify_fn);
-
-int
-glusterd_big_locked_cbk (struct rpc_req *req, struct iovec *iov,
- int count, void *myframe, fop_cbk_fn_t fn);
-
-int glusterd_big_locked_handler (rpcsvc_request_t *req, rpcsvc_actor actor_fn);
-
-int32_t
-glusterd_brick_from_brickinfo (glusterd_brickinfo_t *brickinfo,
- char **new_brick);
-int
-glusterd_probe_begin (rpcsvc_request_t *req, const char *hoststr, int port,
- dict_t *dict, int *op_errno);
-
-int
-glusterd_xfer_friend_add_resp (rpcsvc_request_t *req, char *myhostname,
- char *remote_hostname, int port, int32_t op_ret,
- int32_t op_errno);
-
-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);
-
-int
-glusterd_friend_add_from_peerinfo (glusterd_peerinfo_t *friend,
- gf_boolean_t restore,
- glusterd_peerctx_args_t *args);
-int
-glusterd_friend_rpc_create (xlator_t *this, glusterd_peerinfo_t *peerinfo,
- glusterd_peerctx_args_t *args);
-int
-glusterd_friend_remove (uuid_t uuid, char *hostname);
-
-int
-glusterd_op_lock_send_resp (rpcsvc_request_t *req, int32_t status);
-
-int
-glusterd_op_unlock_send_resp (rpcsvc_request_t *req, int32_t status);
-
-int
-glusterd_op_mgmt_v3_lock_send_resp (rpcsvc_request_t *req,
- uuid_t *txn_id, int32_t status);
-
-int
-glusterd_op_mgmt_v3_unlock_send_resp (rpcsvc_request_t *req,
- uuid_t *txn_id, int32_t status);
-
-int
-glusterd_op_stage_send_resp (rpcsvc_request_t *req,
- int32_t op, int32_t status,
- char *op_errstr, dict_t *rsp_dict);
-
-int
-glusterd_op_commmit_send_resp (rpcsvc_request_t *req,
- int32_t op, int32_t status);
-
-int32_t
-glusterd_create_volume (rpcsvc_request_t *req, dict_t *dict);
-
-int
-glusterd_handle_incoming_friend_req (rpcsvc_request_t *req);
-
-int
-glusterd_handle_probe_query (rpcsvc_request_t *req);
-
-int
-glusterd_handle_cluster_lock (rpcsvc_request_t *req);
-
-int
-glusterd_handle_cluster_unlock (rpcsvc_request_t *req);
-
-int
-glusterd_handle_stage_op (rpcsvc_request_t *req);
-
-int
-glusterd_handle_commit_op (rpcsvc_request_t *req);
-
-int
-glusterd_handle_cli_probe (rpcsvc_request_t *req);
-
-int
-glusterd_handle_create_volume (rpcsvc_request_t *req);
-
-int
-glusterd_handle_defrag_volume (rpcsvc_request_t *req);
-
-int
-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, dict_t *dict);
-
-int
-glusterd_op_commit_send_resp (rpcsvc_request_t *req,
- int32_t op, int32_t status, char *op_errstr,
- dict_t *rsp_dict);
-
-int
-glusterd_xfer_friend_remove_resp (rpcsvc_request_t *req, char *hostname, int port);
-
-int
-glusterd_deprobe_begin (rpcsvc_request_t *req, const char *hoststr, int port,
- uuid_t uuid, dict_t *dict, int *op_errno);
-
-int
-glusterd_handle_cli_deprobe (rpcsvc_request_t *req);
-
-int
-glusterd_handle_incoming_unfriend_req (rpcsvc_request_t *req);
-
-int32_t
-glusterd_list_friends (rpcsvc_request_t *req, dict_t *dict, int32_t flags);
-
-int
-glusterd_handle_cli_list_friends (rpcsvc_request_t *req);
-
-int
-glusterd_handle_cli_start_volume (rpcsvc_request_t *req);
-
-int
-glusterd_handle_friend_update (rpcsvc_request_t *req);
-
-int
-glusterd_handle_cli_stop_volume (rpcsvc_request_t *req);
-
-int
-glusterd_handle_cli_delete_volume (rpcsvc_request_t *req);
-
-int
-glusterd_handle_cli_get_volume (rpcsvc_request_t *req);
-
-int32_t
-glusterd_get_volumes (rpcsvc_request_t *req, dict_t *dict, int32_t flags);
-
-int
-glusterd_handle_add_brick (rpcsvc_request_t *req);
-
-int
-glusterd_handle_replace_brick (rpcsvc_request_t *req);
-
-int
-glusterd_handle_remove_brick (rpcsvc_request_t *req);
-
-int
-glusterd_handle_log_rotate (rpcsvc_request_t *req);
-
-int
-glusterd_handle_sync_volume (rpcsvc_request_t *req);
-
-int32_t
-glusterd_log_filename (rpcsvc_request_t *req, dict_t *dict);
-
-int32_t
-glusterd_log_rotate (rpcsvc_request_t *req, dict_t *dict);
-
-int32_t
-glusterd_remove_brick (rpcsvc_request_t *req, dict_t *dict);
-
-int32_t
-glusterd_set_volume (rpcsvc_request_t *req, dict_t *dict);
-
-int32_t
-glusterd_reset_volume (rpcsvc_request_t *req, dict_t *dict);
-
-int32_t
-glusterd_gsync_set (rpcsvc_request_t *req, dict_t *dict);
-
-int32_t
-glusterd_quota (rpcsvc_request_t *req, dict_t *dict);
-
-int
-glusterd_handle_set_volume (rpcsvc_request_t *req);
-
-int
-glusterd_handle_reset_volume (rpcsvc_request_t *req);
-
-int
-glusterd_handle_copy_file (rpcsvc_request_t *req);
-
-int
-glusterd_handle_sys_exec (rpcsvc_request_t *req);
-
-int
-glusterd_handle_gsync_set (rpcsvc_request_t *req);
-
-int
-glusterd_handle_quota (rpcsvc_request_t *req);
-
-int
-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, dict_t *dict);
-
-int
-glusterd_fetchspec_notify (xlator_t *this);
-
-int
-glusterd_fetchsnap_notify (xlator_t *this);
-
-int
-glusterd_add_volume_detail_to_dict (glusterd_volinfo_t *volinfo,
- dict_t *volumes, int count);
-
-int
-glusterd_restart_bricks (glusterd_conf_t *conf);
-
-int32_t
-glusterd_volume_txn (rpcsvc_request_t *req, char *volname, int flags,
- glusterd_op_t op);
-
-int
-glusterd_peer_dump_version (xlator_t *this, struct rpc_clnt *rpc,
- glusterd_peerctx_t *peerctx);
-
-int
-glusterd_validate_reconfopts (glusterd_volinfo_t *volinfo, dict_t *val_dict, char **op_errstr);
-int
-glusterd_handle_cli_profile_volume (rpcsvc_request_t *req);
-
-int
-glusterd_handle_getwd (rpcsvc_request_t *req);
-
-int32_t
-glusterd_set_volume (rpcsvc_request_t *req, dict_t *dict);
-int
-glusterd_peer_rpc_notify (struct rpc_clnt *rpc, void *mydata,
- rpc_clnt_event_t event,
- void *data);
-int
-glusterd_brick_rpc_notify (struct rpc_clnt *rpc, void *mydata,
- rpc_clnt_event_t event, void *data);
-
-int
-glusterd_snapd_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,
- char *err_str, size_t size);
-
-/* 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,
- glusterd_op_t op);
-int
-glusterd_rebalance_rpc_create (glusterd_volinfo_t *volinfo,
- gf_boolean_t reconnect);
-
-int glusterd_handle_cli_heal_volume (rpcsvc_request_t *req);
-
-int glusterd_handle_cli_list_volume (rpcsvc_request_t *req);
-
-int
-glusterd_handle_snapshot (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_stage_copy_file (dict_t *dict, char **op_errstr);
-int glusterd_op_copy_file (dict_t *dict, char **op_errstr);
-int glusterd_op_stage_sys_exec (dict_t *dict, char **op_errstr);
-int glusterd_op_sys_exec (dict_t *dict, char **op_errstr, dict_t *rsp_dict);
-int glusterd_op_stage_gsync_create (dict_t *dict, char **op_errstr);
-int glusterd_op_gsync_create (dict_t *dict, char **op_errstr, dict_t *rsp_dict);
-int glusterd_op_quota (dict_t *dict, char **op_errstr, dict_t *rsp_dict);
-int glusterd_op_stage_quota (dict_t *dict, char **op_errstr, dict_t *rsp_dict);
-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,
- dict_t *rsp_dict);
-int glusterd_op_stage_start_volume (dict_t *dict, char **op_errstr,
- dict_t *rsp_dict);
-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,
- dict_t *rsp_dict);
-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,
- dict_t *rsp_dict);
-
-int glusterd_op_stage_barrier (dict_t *dict, char **op_errstr);
-int glusterd_op_barrier (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, char **host_uuid);
-
-int glusterd_start_volume (glusterd_volinfo_t *volinfo, int flags,
- gf_boolean_t wait);
-
-int glusterd_stop_volume (glusterd_volinfo_t *volinfo);
-
-/* 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);
-
-int32_t
-glusterd_txn_opinfo_dict_init ();
-
-void
-glusterd_txn_opinfo_dict_fini ();
-
-void
-glusterd_txn_opinfo_init ();
-
-/* snapshot */
-glusterd_snap_t*
-glusterd_new_snap_object();
-
-int32_t
-glusterd_list_add_snapvol (glusterd_volinfo_t *origin_vol,
- glusterd_volinfo_t *snap_vol);
-
-glusterd_snap_t*
-glusterd_remove_snap_by_id (uuid_t snap_id);
-
-glusterd_snap_t*
-glusterd_remove_snap_by_name (char *snap_name);
-
-glusterd_snap_t*
-glusterd_find_snap_by_name (char *snap_name);
-
-glusterd_snap_t*
-glusterd_find_snap_by_id (uuid_t snap_id);
-
-int
-glusterd_snapshot_prevalidate (dict_t *dict, char **op_errstr,
- dict_t *rsp_dict);
-int
-glusterd_snapshot_brickop (dict_t *dict, char **op_errstr, dict_t *rsp_dict);
-int
-glusterd_snapshot (dict_t *dict, char **op_errstr, dict_t *rsp_dict);
-int
-glusterd_snapshot_postvalidate (dict_t *dict, int32_t op_ret, char **op_errstr,
- dict_t *rsp_dict);
-char *
-glusterd_build_snap_device_path (char *device, char *snapname,
- int32_t brick_count);
-
-int32_t
-glusterd_snap_remove (dict_t *rsp_dict, glusterd_snap_t *snap,
- gf_boolean_t remove_lvm, gf_boolean_t force);
-int32_t
-glusterd_snapshot_cleanup (dict_t *dict, char **op_errstr, dict_t *rsp_dict);
-
-int32_t
-glusterd_add_missed_snaps_to_list (dict_t *dict, int32_t missed_snap_count);
-
-int32_t
-glusterd_add_new_entry_to_list (char *missed_info, char *snap_vol_id,
- int32_t brick_num, char *brick_path,
- int32_t snap_op, int32_t snap_status);
-
-int
-glusterd_snapshot_revert_restore_from_snap (glusterd_snap_t *snap);
-
-
-int
-glusterd_add_brick_status_to_dict (dict_t *dict, glusterd_volinfo_t *volinfo,
- glusterd_brickinfo_t *brickinfo,
- char *key_prefix);
-
-int32_t
-glusterd_handle_snap_limit (dict_t *dict, dict_t *rsp_dict);
-
-#endif
diff --git a/xlators/mount/fuse/src/Makefile.am b/xlators/mount/fuse/src/Makefile.am
index 7d1f93447bf..e85d63887dc 100644
--- a/xlators/mount/fuse/src/Makefile.am
+++ b/xlators/mount/fuse/src/Makefile.am
@@ -1,38 +1,17 @@
-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\
- $(CONTRIBDIR)/macfuse/fuse_param.h\
- $(CONTRIBDIR)/macfuse/fuse_ioctl.h
-noinst_HEADERS_common = $(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
+noinst_HEADERS = $(CONTRIBDIR)/fuse-include/fuse_kernel.h\
+ $(CONTRIBDIR)/fuse-include/fuse-mount.h\
+ $(CONTRIBDIR)/fuse-include/fuse-misc.h
xlator_LTLIBRARIES = fuse.la
xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/mount
+fuse_la_SOURCES = fuse-bridge.c $(CONTRIBDIR)/fuse-lib/misc.c \
+ $(CONTRIBDIR)/fuse-lib/mount.c
+fuse_la_LDFLAGS = -module -avoidversion -shared -nostartfiles
-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
-endif
-
-fuse_la_SOURCES = fuse-helpers.c fuse-resolve.c fuse-bridge.c \
- $(CONTRIBDIR)/fuse-lib/misc.c $(mount_source)
-
-fuse_la_LDFLAGS = -module -avoid-version
-fuse_la_LIBADD = @GF_FUSE_LDADD@
-
-AM_CPPFLAGS = $(GF_CPPFLAGS) \
+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_FUSE_CFLAGS)
+ $(GF_CFLAGS) -DFUSERMOUNT_DIR=\"$(bindir)\"
+
-AM_CFLAGS = -Wall $(GF_CFLAGS)
+CLEANFILES =
-CLEANFILES =
diff --git a/xlators/mount/fuse/src/fuse-bridge.c b/xlators/mount/fuse/src/fuse-bridge.c
index 62d524b9e87..27f1aa8232a 100644
--- a/xlators/mount/fuse/src/fuse-bridge.c
+++ b/xlators/mount/fuse/src/fuse-bridge.c
@@ -1,168 +1,261 @@
/*
- Copyright (c) 2006-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) 2006-2009 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 <sys/wait.h>
-#include "fuse-bridge.h"
-#include "mount-gluster-compat.h"
-#include "glusterfs.h"
-#include "byte-order.h"
-#include "compat-errno.h"
-#include "glusterfs-acl.h"
-
-#ifdef __NetBSD__
-#undef open /* in perfuse.h, pulled from mount-gluster-compat.h */
-#endif
-
-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;
+#include <stdint.h>
+#include <signal.h>
+#include <pthread.h>
+#include <stddef.h>
+#include <dirent.h>
+#include <sys/mount.h>
+#include <sys/time.h>
- /*
- * 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;
+#ifndef _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif /* _CONFIG_H */
- nodeid = inode_to_fuse_nodeid(inode);
- gf_log(this->name, GF_LOG_DEBUG, "Invalidate inode id %"GF_PRI_INODE"." , nodeid);
- fuse_log_eh (this, "Sending invalidate inode id: %"GF_PRI_INODE" gfid: %s", nodeid,
- uuid_utoa (inode->gfid));
- fuse_invalidate_inode(this, nodeid);
+#include "glusterfs.h"
+#include "logging.h"
+#include "xlator.h"
+#include "defaults.h"
+#include "common-utils.h"
+#include "statedump.h"
- return 0;
-}
+#include "fuse_kernel.h"
+#include "fuse-misc.h"
+#include "fuse-mount.h"
-static int32_t
-fuse_forget_cbk (xlator_t *this, inode_t *inode)
-{
- //Nothing to free in inode ctx, hence return.
- return 0;
-}
-
-void
-fuse_inode_set_need_lookup (inode_t *inode, xlator_t *this)
-{
- uint64_t need_lookup = 1;
+#include "list.h"
+#include "dict.h"
- if (!inode || !this)
- return;
+#include "compat.h"
+#include "compat-errno.h"
- inode_ctx_set (inode, this, &need_lookup);
+/* TODO: when supporting posix acl, remove this definition */
+#define DISABLE_POSIX_ACL
- return;
-}
+#define ZR_MOUNTPOINT_OPT "mountpoint"
+#define ZR_DIRECT_IO_OPT "direct-io-mode"
+#define ZR_STRICT_VOLFILE_CHECK "strict-volfile-check"
+#define FUSE_713_OP_HIGH (FUSE_POLL + 1)
+#define GLUSTERFS_XATTR_LEN_MAX 65536
-gf_boolean_t
-fuse_inode_needs_lookup (inode_t *inode, xlator_t *this)
-{
- uint64_t need_lookup = 0;
- gf_boolean_t ret = _gf_false;
+#define MAX_FUSE_PROC_DELAY 1
- if (!inode || !this)
- return ret;
+static int gf_fuse_conn_err_log;
- inode_ctx_get (inode, this, &need_lookup);
- if (need_lookup)
- ret = _gf_true;
- need_lookup = 0;
- inode_ctx_set (inode, this, &need_lookup);
+typedef struct fuse_in_header fuse_in_header_t;
+typedef void (fuse_handler_t) (xlator_t *this, fuse_in_header_t *finh,
+ void *msg);
+
+struct fuse_private {
+ int fd;
+ uint32_t proto_minor;
+ char *volfile;
+ size_t volfile_size;
+ char *mount_point;
+ struct iobuf *iobuf;
+ pthread_t fuse_thread;
+ char fuse_thread_started;
+ uint32_t direct_io_mode;
+ size_t *msg0_len_p;
+ double entry_timeout;
+ double attribute_timeout;
+ pthread_cond_t first_call_cond;
+ pthread_mutex_t first_call_mutex;
+ char first_call;
+ gf_boolean_t strict_volfile_check;
+ pthread_cond_t child_up_cond;
+ pthread_mutex_t child_up_mutex;
+ char child_up_value;
- return ret;
-}
+};
+typedef struct fuse_private fuse_private_t;
+
+#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))
+
+#define FUSE_FOP(state, ret, op_num, fop, args ...) \
+ do { \
+ call_frame_t *frame = NULL; \
+ xlator_t *xl = NULL; \
+ \
+ frame = get_call_frame_for_req (state); \
+ if (!frame) { \
+ /* This is not completely clean, as some \
+ * earlier allocations might remain unfreed \
+ * if we return at this point, but still \
+ * better than trying to go on with a NULL \
+ * frame ... \
+ */ \
+ gf_log ("glusterfs-fuse", \
+ GF_LOG_ERROR, \
+ "FUSE message" \
+ " unique %"PRIu64" opcode %d:" \
+ " frame allocation failed", \
+ state->finh->unique, \
+ state->finh->opcode); \
+ free_state (state); \
+ return; \
+ } \
+ xl = frame->this->children ? \
+ frame->this->children->xlator : NULL; \
+ frame->root->state = state; \
+ frame->root->op = op_num; \
+ STACK_WIND (frame, ret, xl, xl->fops->fop, args); \
+ } while (0)
+
+#define GF_SELECT_LOG_LEVEL(_errno) \
+ (((_errno == ENOENT) || (_errno == ESTALE))? \
+ GF_LOG_DEBUG)
+
+#define GET_STATE(this, finh, state) \
+ do { \
+ state = get_state (this, finh); \
+ if (!state) { \
+ gf_log ("glusterfs-fuse", \
+ GF_LOG_ERROR, \
+ "FUSE message unique %"PRIu64" opcode %d:" \
+ " state allocation failed", \
+ finh->unique, finh->opcode); \
+ \
+ send_fuse_err (this, finh, ENOMEM); \
+ FREE (finh); \
+ \
+ return; \
+ } \
+ } while (0)
+
+
+typedef struct {
+ void *pool;
+ xlator_t *this;
+ inode_table_t *itable;
+ loc_t loc;
+ loc_t loc2;
+ fuse_in_header_t *finh;
+ int32_t flags;
+ off_t off;
+ size_t size;
+ unsigned long nlookup;
+ fd_t *fd;
+ dict_t *dict;
+ char *name;
+ char is_revalidate;
+ gf_boolean_t truncate_needed;
+ gf_lock_t lock;
+ uint64_t lk_owner;
+} fuse_state_t;
-fuse_fd_ctx_t *
-__fuse_fd_ctx_check_n_create (xlator_t *this, fd_t *fd)
+static void
+free_state (fuse_state_t *state)
{
- uint64_t val = 0;
- int32_t ret = 0;
- fuse_fd_ctx_t *fd_ctx = NULL;
+ loc_wipe (&state->loc);
- ret = __fd_ctx_get (fd, this, &val);
+ loc_wipe (&state->loc2);
- 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);
- if (!fd_ctx) {
- goto out;
- }
- 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;
- }
+ if (state->dict) {
+ dict_unref (state->dict);
+ state->dict = (void *)0xaaaaeeee;
}
-out:
- return fd_ctx;
+ if (state->name) {
+ FREE (state->name);
+ state->name = NULL;
+ }
+ if (state->fd) {
+ fd_unref (state->fd);
+ state->fd = (void *)0xfdfdfdfd;
+ }
+ if (state->finh) {
+ FREE (state->finh);
+ state->finh = NULL;
+ }
+#ifdef DEBUG
+ memset (state, 0x90, sizeof (*state));
+#endif
+ FREE (state);
+ state = NULL;
}
-fuse_fd_ctx_t *
-fuse_fd_ctx_check_n_create (xlator_t *this, fd_t *fd)
+
+fuse_state_t *
+get_state (xlator_t *this, fuse_in_header_t *finh)
{
- fuse_fd_ctx_t *fd_ctx = NULL;
+ fuse_state_t *state = NULL;
- if ((fd == NULL) || (this == NULL)) {
- goto out;
- }
+ state = (void *)calloc (1, sizeof (*state));
+ if (!state)
+ return NULL;
+ state->pool = this->ctx->pool;
+ state->itable = this->itable;
+ state->finh = finh;
+ state->this = this;
- LOCK (&fd->lock);
- {
- fd_ctx = __fuse_fd_ctx_check_n_create (this, fd);
- }
- UNLOCK (&fd->lock);
+ LOCK_INIT (&state->lock);
-out:
- return fd_ctx;
+ return state;
}
-fuse_fd_ctx_t *
-fuse_fd_ctx_get (xlator_t *this, fd_t *fd)
+
+static call_frame_t *
+get_call_frame_for_req (fuse_state_t *state)
{
- fuse_fd_ctx_t *fdctx = NULL;
- uint64_t value = 0;
- int ret = 0;
+ call_pool_t *pool = NULL;
+ fuse_in_header_t *finh = NULL;
+ call_frame_t *frame = NULL;
+ xlator_t *this = NULL;
+ fuse_private_t *priv = NULL;
- ret = fd_ctx_get (fd, this, &value);
- if (ret < 0) {
- goto out;
+ pool = state->pool;
+ finh = state->finh;
+ this = state->this;
+ priv = this->private;
+
+ frame = create_frame (this, pool);
+ if (!frame)
+ return NULL;
+
+ if (finh) {
+ 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;
}
- fdctx = (fuse_fd_ctx_t *) (unsigned long)value;
+ frame->root->type = GF_OP_TYPE_FOP_REQUEST;
-out:
- return fdctx;
+ return frame;
}
+
/*
* iov_out should contain a fuse_out_header at zeroth position.
* The error value of this header is sent to kernel.
@@ -175,10 +268,6 @@ send_fuse_iov (xlator_t *this, fuse_in_header_t *finh, struct iovec *iov_out,
struct fuse_out_header *fouh = NULL;
int res, i;
- if (!this || !finh || !iov_out) {
- gf_log ("send_fuse_iov", GF_LOG_ERROR,"Invalid arguments");
- return EINVAL;
- }
priv = this->private;
fouh = iov_out[0].iov_base;
@@ -189,29 +278,11 @@ send_fuse_iov (xlator_t *this, fuse_in_header_t *finh, struct iovec *iov_out,
fouh->unique = finh->unique;
res = writev (priv->fd, iov_out, count);
- gf_log ("glusterfs-fuse", GF_LOG_TRACE, "writev() result %d/%d %s",
- res, fouh->len, res == -1 ? strerror (errno) : "");
if (res == -1)
return errno;
if (res != fouh->len)
return EINVAL;
-
- if (priv->fuse_dump_fd != -1) {
- char w = 'W';
-
- pthread_mutex_lock (&priv->fuse_dump_mutex);
- res = write (priv->fuse_dump_fd, &w, 1);
- if (res != -1)
- res = writev (priv->fuse_dump_fd, iov_out, count);
- pthread_mutex_unlock (&priv->fuse_dump_mutex);
-
- if (res == -1)
- gf_log ("glusterfs-fuse", GF_LOG_ERROR,
- "failed to dump fuse message (W): %s",
- strerror (errno));
- }
-
return 0;
}
@@ -220,226 +291,188 @@ send_fuse_data (xlator_t *this, fuse_in_header_t *finh, void *data, size_t size)
{
struct fuse_out_header fouh = {0, };
struct iovec iov_out[2];
- int ret = 0;
fouh.error = 0;
iov_out[0].iov_base = &fouh;
iov_out[1].iov_base = data;
iov_out[1].iov_len = size;
- ret = send_fuse_iov (this, finh, iov_out, 2);
- if (ret != 0)
- gf_log ("glusterfs-fuse", GF_LOG_ERROR, "send_fuse_iov() "
- "failed: %s", strerror (ret));
-
- return ret;
+ return send_fuse_iov (this, finh, iov_out, 2);
}
#define send_fuse_obj(this, finh, obj) \
send_fuse_data (this, finh, obj, sizeof (*(obj)))
-
-#if FUSE_KERNEL_MINOR_VERSION >= 11
-static void
-fuse_invalidate_entry (xlator_t *this, uint64_t fuse_ino)
+static int
+send_fuse_err (xlator_t *this, fuse_in_header_t *finh, int error)
{
- 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);
+ struct fuse_out_header fouh = {0, };
+ struct iovec iov_out;
- rv = write (priv->revchan_out, inval_buf, fouh->len);
- if (rv != fouh->len) {
- gf_log ("glusterfs-fuse", GF_LOG_ERROR,
- "kernel notification daemon defunct");
+ fouh.error = -error;
+ iov_out.iov_base = &fouh;
- close (priv->fd);
- break;
- }
+ return send_fuse_iov (this, finh, &iov_out, 1);
+}
- gf_log ("glusterfs-fuse", GF_LOG_TRACE, "INVALIDATE entry: "
- "%"PRIu64"/%s", fnieo->parent, dentry->name);
+static inode_t *
+fuse_ino_to_inode (uint64_t ino, inode_table_t *table)
+{
+ inode_t *inode = NULL;
- if (dentry->parent) {
- fuse_log_eh (this, "Invalidated entry %s (parent: %s)",
- dentry->name,
- uuid_utoa (dentry->parent->gfid));
- } else {
- fuse_log_eh (this, "Invalidated entry %s(nodeid: %ld)",
- dentry->name, fnieo->parent);
- }
+ if (ino == 1) {
+ inode = table->root;
+ } else {
+ inode = (inode_t *) (unsigned long) ino;
+ inode_ref (inode);
}
- if (inode)
- inode_unref (inode);
+ return inode;
}
-#endif
-/*
- * 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)
+static uint64_t
+inode_to_nodeid (inode_t *inode)
{
-#if FUSE_KERNEL_MINOR_VERSION >= 11
- 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};
- inode_t *inode = NULL;
+ if (!inode || inode->ino == 1)
+ return 1;
- fouh = (struct fuse_out_header *) inval_buf;
- fniio = (struct fuse_notify_inval_inode_out *) (fouh + 1);
+ return (unsigned long) inode;
+}
- 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);
+GF_MUST_CHECK static int32_t
+fuse_loc_fill (loc_t *loc, fuse_state_t *state, ino_t ino,
+ ino_t par, const char *name)
+{
+ inode_t *inode = NULL;
+ inode_t *parent = NULL;
+ int32_t ret = -1;
+ char *path = NULL;
- /* inval the entire mapping until we learn how to be more granular */
- fniio->ino = fuse_ino;
- fniio->off = 0;
- fniio->len = -1;
+ /* resistance against multiple invocation of loc_fill not to get
+ reference leaks via inode_search() */
- inode = fuse_ino_to_inode (fuse_ino, this);
+ inode = loc->inode;
- 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);
- }
+ if (name) {
+ parent = loc->parent;
+ if (!parent) {
+ parent = fuse_ino_to_inode (par, state->itable);
+ loc->parent = parent;
+ }
- gf_log("glusterfs-fuse", GF_LOG_TRACE, "INVALIDATE inode: %lu", fuse_ino);
+ inode = loc->inode;
+ if (!inode) {
+ inode = inode_grep (state->itable, parent, name);
+ loc->inode = inode;
+ }
- if (inode) {
- fuse_log_eh (this, "Invalidated inode %lu (gfid: %s)",
- fuse_ino, uuid_utoa (inode->gfid));
+ ret = inode_path (parent, name, &path);
+ if (ret <= 0) {
+ gf_log ("glusterfs-fuse", GF_LOG_DEBUG,
+ "inode_path failed for %"PRId64"/%s",
+ parent->ino, name);
+ goto fail;
+ }
+ loc->path = path;
} else {
- fuse_log_eh (this, "Invalidated inode %lu ", fuse_ino);
- }
-
- if (inode)
- inode_unref (inode);
-#else
- gf_log ("glusterfs-fuse", GF_LOG_WARNING,
- "fuse_invalidate_inode not implemented on OS X due to missing FUSE notification");
-#endif
-}
+ inode = loc->inode;
+ if (!inode) {
+ inode = fuse_ino_to_inode (ino, state->itable);
+ loc->inode = inode;
+ }
+ parent = loc->parent;
+ if (!parent) {
+ parent = inode_parent (inode, par, name);
+ loc->parent = parent;
+ }
-int
-send_fuse_err (xlator_t *this, fuse_in_header_t *finh, int error)
-{
- struct fuse_out_header fouh = {0, };
- struct iovec iov_out;
- inode_t *inode = NULL;
+ ret = inode_path (inode, NULL, &path);
+ if (ret <= 0) {
+ gf_log ("glusterfs-fuse", GF_LOG_DEBUG,
+ "inode_path failed for %"PRId64,
+ inode->ino);
+ goto fail;
+ }
+ loc->path = path;
+ }
- fouh.error = -error;
- iov_out.iov_base = &fouh;
+ if (inode)
+ loc->ino = inode->ino;
- inode = fuse_ino_to_inode (finh->nodeid, this);
+ if (loc->path) {
+ loc->name = strrchr (loc->path, '/');
+ if (loc->name)
+ loc->name++;
+ else
+ loc->name = "";
+ }
- // filter out ENOENT
- if (error != ENOENT) {
- if (inode) {
- fuse_log_eh (this,"Sending %s for operation %d on "
- "inode %s", strerror (error), finh->opcode,
- uuid_utoa (inode->gfid));
- } else {
- fuse_log_eh (this, "Sending %s for operation %d on "
- "inode %" GF_PRI_INODE, strerror (error),
- finh->opcode, finh->nodeid);
- }
+ if ((ino != 1) && (parent == NULL)) {
+ gf_log ("fuse-bridge", GF_LOG_DEBUG,
+ "failed to search parent for %"PRId64"/%s (%"PRId64")",
+ (ino_t)par, name, (ino_t)ino);
+ ret = -1;
+ goto fail;
}
+ ret = 0;
+fail:
+ return ret;
+}
- if (inode)
- inode_unref (inode);
- return send_fuse_iov (this, finh, &iov_out, 1);
+/* courtesy of folly */
+static void
+stat2attr (struct stat *st, struct fuse_attr *fa)
+{
+ fa->ino = st->st_ino;
+ fa->size = st->st_size;
+ fa->blocks = st->st_blocks;
+ fa->atime = st->st_atime;
+ fa->mtime = st->st_mtime;
+ fa->ctime = st->st_ctime;
+ fa->atimensec = ST_ATIM_NSEC (st);
+ fa->mtimensec = ST_MTIM_NSEC (st);
+ fa->ctimensec = ST_CTIM_NSEC (st);
+ fa->mode = st->st_mode;
+ fa->nlink = st->st_nlink;
+ fa->uid = st->st_uid;
+ fa->gid = st->st_gid;
+ fa->rdev = st->st_rdev;
+ fa->blksize = st->st_blksize;
}
+
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 stat *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 == 0) {
- if (__is_root_gfid (state->loc.inode->gfid))
- buf->ia_ino = 1;
- if (uuid_is_null (buf->ia_gfid)) {
- /* With a NULL gfid inode linking is
- not possible. Let's not pretend this
- call was a "success".
- */
- gf_log ("glusterfs-fuse", GF_LOG_WARNING,
- "Received NULL gfid for %s. Forcing EIO",
- state->loc.path);
- op_ret = -1;
- op_errno = EIO;
- }
+ if (!op_ret && state->loc.ino == 1) {
+ buf->st_ino = 1;
}
- /* log into the event-history after the null uuid check is done, since
- * the op_ret and op_errno are being changed if the gfid is NULL.
- */
- fuse_log_eh (this, "op_ret: %d op_errno: %d "
- "%"PRIu64": %s() %s => %s", op_ret, op_errno,
- frame->root->unique, gf_fop_list[frame->root->op],
- state->loc.path, (op_ret == 0)?
- uuid_utoa(buf->ia_gfid):uuid_utoa(state->loc.gfid));
-
if (op_ret == 0) {
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64": %s() %s => %"PRIu64,
+ "%"PRIu64": %s() %s => %"PRId64" (%"PRId64")",
frame->root->unique, gf_fop_list[frame->root->op],
- state->loc.path, buf->ia_ino);
+ state->loc.path, buf->st_ino, state->loc.ino);
- buf->ia_blksize = this->ctx->page_size;
- gf_fuse_stat2attr (buf, &feo.attr, priv->enable_ino32);
+ buf->st_blksize = this->ctx->page_size;
+ stat2attr (buf, &feo.attr);
- if (!buf->ia_ino) {
+ if (!buf->st_ino) {
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
"%"PRIu64": %s() %s returning inode 0",
frame->root->unique,
@@ -450,11 +483,22 @@ fuse_entry_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
state->loc.name, buf);
if (linked_inode != inode) {
+ gf_log ("glusterfs-fuse", GF_LOG_WARNING,
+ "%s(%s) inode (ptr=%p, ino=%"PRId64", "
+ "gen=%"PRId64") found conflict (ptr=%p, "
+ "ino=%"PRId64", gen=%"PRId64")",
+ gf_fop_list[frame->root->op],
+ state->loc.path, inode, inode->ino,
+ inode->generation, linked_inode,
+ linked_inode->ino, linked_inode->generation);
}
inode_lookup (linked_inode);
- feo.nodeid = inode_to_fuse_nodeid (linked_inode);
+ /* TODO: make these timeouts configurable (via meta?) */
+ feo.nodeid = inode_to_nodeid (linked_inode);
+
+ feo.generation = linked_inode->generation;
inode_unref (linked_inode);
@@ -467,219 +511,131 @@ fuse_entry_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
feo.attr_valid_nsec =
calc_timeout_nsec (priv->attribute_timeout);
-#if FUSE_KERNEL_MINOR_VERSION >= 9
priv->proto_minor >= 9 ?
- send_fuse_obj (this, finh, &feo) :
- send_fuse_data (this, finh, &feo,
- FUSE_COMPAT_ENTRY_OUT_SIZE);
-#else
- send_fuse_obj (this, finh, &feo);
-#endif
+ send_fuse_obj (this, finh, &feo) :
+ send_fuse_data (this, finh, &feo,
+ FUSE_COMPAT_ENTRY_OUT_SIZE);
} else {
gf_log ("glusterfs-fuse",
(op_errno == ENOENT ? GF_LOG_TRACE : GF_LOG_WARNING),
"%"PRIu64": %s() %s => -1 (%s)", frame->root->unique,
gf_fop_list[frame->root->op], state->loc.path,
strerror (op_errno));
-
- if ((op_errno == ENOENT) && (priv->negative_timeout != 0)) {
- 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);
+ free_state (state);
STACK_DESTROY (frame->root);
return 0;
}
+
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)
+ inode_t *inode, struct stat *buf, struct stat *preparent,
+ struct stat *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;
}
+
static int
fuse_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno,
- inode_t *inode, struct iatt *stat, dict_t *dict,
- struct iatt *postparent)
+ inode_t *inode, struct stat *stat, dict_t *dict,
+ struct stat *postparent)
{
fuse_state_t *state = NULL;
call_frame_t *prev = NULL;
- inode_table_t *itable = NULL;
state = frame->root->state;
prev = cookie;
if (op_ret == -1 && state->is_revalidate == 1) {
- itable = state->itable;
- /*
- * A stale mapping might exist for a dentry/inode that has been
- * removed from another client.
- */
- if (op_errno == ENOENT)
- inode_unlink(state->loc.inode, state->loc.parent,
- state->loc.name);
inode_unref (state->loc.inode);
- state->loc.inode = inode_new (itable);
+ state->loc.inode = inode_new (state->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;
}
-void
-fuse_fop_resume (fuse_state_t *state)
+
+static void
+fuse_lookup (xlator_t *this, fuse_in_header_t *finh, void *msg)
{
- fuse_resume_fn_t fn = NULL;
+ char *name = msg;
- /*
- * Fail fd resolution failures right away.
- */
- if (state->resolve.fd && state->resolve.op_ret < 0) {
- send_fuse_err (state->this, state->finh,
- state->resolve.op_errno);
- free_fuse_state (state);
- return;
- }
+ fuse_state_t *state = NULL;
+ int32_t ret = -1;
- fn = state->resume_fn;
- fn (state);
-}
+ GET_STATE (this, finh, state);
-void
-fuse_lookup_resume (fuse_state_t *state)
-{
- if (!state->loc.parent && !state->loc.inode) {
- gf_log ("fuse", GF_LOG_ERROR, "failed to resolve path %s",
- state->loc.path);
- send_fuse_err (state->this, state->finh,
- state->resolve.op_errno);
- free_fuse_state (state);
- return;
- }
+ ret = fuse_loc_fill (&state->loc, state, 0, finh->nodeid, name);
- /* parent was resolved, entry could not, may be a missing gfid?
- * Hence try to do a regular lookup
- */
- if ((state->resolve.op_ret == -1)
- && (state->resolve.op_errno == ENODATA)) {
- state->resolve.op_ret = 0;
+ if (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_state (state);
+ return;
}
- if (state->loc.inode) {
+ 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;
+ "%"PRIu64": LOOKUP %s", finh->unique,
+ state->loc.path);
+
+ state->loc.inode = inode_new (state->itable);
} else {
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64": LOOKUP %s", state->finh->unique,
- state->loc.path);
- state->loc.inode = inode_new (state->loc.parent->table);
- if (uuid_is_null (state->gfid))
- uuid_generate (state->gfid);
- fuse_gfid_set (state);
+ "%"PRIu64": LOOKUP %s(%"PRId64")", finh->unique,
+ state->loc.path, state->loc.inode->ino);
+ state->is_revalidate = 1;
}
- FUSE_FOP (state, fuse_lookup_cbk, GF_FOP_LOOKUP,
- lookup, &state->loc, state->xdata);
-}
-
-static void
-fuse_lookup (xlator_t *this, fuse_in_header_t *finh, void *msg)
-{
- char *name = msg;
- fuse_state_t *state = NULL;
+ state->dict = dict_new ();
- GET_STATE (this, finh, state);
-
- (void) fuse_resolve_entry_init (state, &state->resolve,
- finh->nodeid, name);
-
- fuse_resolve_and_resume (state, fuse_lookup_resume);
-
- return;
+ FUSE_FOP (state, fuse_lookup_cbk, GF_FOP_LOOKUP,
+ lookup, &state->loc, state->dict);
}
-static inline void
-do_forget(xlator_t *this, uint64_t unique, uint64_t nodeid, uint64_t nlookup)
-{
- inode_t *fuse_inode = fuse_ino_to_inode(nodeid, this);
-
- fuse_log_eh(this, "%"PRIu64": FORGET %"PRIu64"/%"PRIu64" gfid: (%s)",
- unique, nodeid, nlookup, uuid_utoa(fuse_inode->gfid));
-
- inode_forget(fuse_inode, nlookup);
- inode_unref(fuse_inode);
-}
static void
fuse_forget (xlator_t *this, fuse_in_header_t *finh, void *msg)
{
- struct fuse_forget_in *ffi = msg;
+ struct fuse_forget_in *ffi = msg;
+
+ inode_t *fuse_inode;
if (finh->nodeid == 1) {
- GF_FREE (finh);
+ FREE (finh);
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->itable);
- do_forget(this, finh->unique, finh->nodeid, ffi->nlookup);
+ inode_forget (fuse_inode, ffi->nlookup);
+ inode_unref (fuse_inode);
- GF_FREE (finh);
+ FREE (finh);
}
-#if FUSE_KERNEL_MINOR_VERSION >= 16
-static void
-fuse_batch_forget(xlator_t *this, fuse_in_header_t *finh, void *msg)
-{
- struct fuse_batch_forget_in *fbfi = msg;
- struct fuse_forget_one *ffo = (struct fuse_forget_one *) (fbfi + 1);
- int i;
-
- gf_log("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64": BATCH_FORGET %"PRIu64"/%"PRIu32,
- finh->unique, finh->nodeid, fbfi->count);
-
- for (i = 0; i < fbfi->count; i++) {
- if (ffo[i].nodeid == 1)
- continue;
- do_forget(this, finh->unique, ffo[i].nodeid, ffo[i].nlookup);
- }
- GF_FREE(finh);
-}
-#endif
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)
+ int32_t op_ret, int32_t op_errno, struct stat *prebuf,
+ struct stat *postbuf)
{
fuse_state_t *state;
fuse_in_header_t *finh;
@@ -690,30 +646,26 @@ fuse_truncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
state = frame->root->state;
finh = state->finh;
- fuse_log_eh_fop(this, state, frame, op_ret, op_errno);
-
if (op_ret == 0) {
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64": %s() %s => %"PRIu64, frame->root->unique,
+ "%"PRIu64": %s() %s => %"PRId64, frame->root->unique,
gf_fop_list[frame->root->op],
state->loc.path ? state->loc.path : "ERR",
- prebuf->ia_ino);
+ prebuf->st_ino);
- postbuf->ia_blksize = this->ctx->page_size;
- gf_fuse_stat2attr (postbuf, &fao.attr, priv->enable_ino32);
+ /* TODO: make these timeouts configurable via meta */
+ /* TODO: what if the inode number has changed by now */
+ postbuf->st_blksize = this->ctx->page_size;
+ stat2attr (postbuf, &fao.attr);
fao.attr_valid = calc_timeout_sec (priv->attribute_timeout);
fao.attr_valid_nsec =
calc_timeout_nsec (priv->attribute_timeout);
-#if FUSE_KERNEL_MINOR_VERSION >= 9
priv->proto_minor >= 9 ?
send_fuse_obj (this, finh, &fao) :
send_fuse_data (this, finh, &fao,
FUSE_COMPAT_ATTR_OUT_SIZE);
-#else
- send_fuse_obj (this, finh, &fao);
-#endif
} else {
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
"%"PRIu64": %s() %s => -1 (%s)", frame->root->unique,
@@ -724,15 +676,16 @@ fuse_truncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
send_fuse_err (this, finh, op_errno);
}
- free_fuse_state (state);
+ free_state (state);
STACK_DESTROY (frame->root);
return 0;
}
+
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 stat *buf)
{
fuse_state_t *state;
fuse_in_header_t *finh;
@@ -743,290 +696,199 @@ fuse_attr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
state = frame->root->state;
finh = state->finh;
- fuse_log_eh (this, "op_ret: %d, op_errno: %d, %"PRIu64": %s() %s => "
- "gfid: %s", op_ret, op_errno, frame->root->unique,
- gf_fop_list[frame->root->op], state->loc.path,
- state->loc.inode ? uuid_utoa (state->loc.inode->gfid) : "");
if (op_ret == 0) {
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64": %s() %s => %"PRIu64, frame->root->unique,
+ "%"PRIu64": %s() %s => %"PRId64, frame->root->unique,
gf_fop_list[frame->root->op],
state->loc.path ? state->loc.path : "ERR",
- buf->ia_ino);
+ buf->st_ino);
- buf->ia_blksize = this->ctx->page_size;
- gf_fuse_stat2attr (buf, &fao.attr, priv->enable_ino32);
+ /* TODO: make these timeouts configurable via meta */
+ /* TODO: what if the inode number has changed by now */
+ buf->st_blksize = this->ctx->page_size;
+ stat2attr (buf, &fao.attr);
fao.attr_valid = calc_timeout_sec (priv->attribute_timeout);
fao.attr_valid_nsec =
calc_timeout_nsec (priv->attribute_timeout);
-#if FUSE_KERNEL_MINOR_VERSION >= 9
priv->proto_minor >= 9 ?
send_fuse_obj (this, finh, &fao) :
send_fuse_data (this, finh, &fao,
FUSE_COMPAT_ATTR_OUT_SIZE);
-#else
- send_fuse_obj (this, finh, &fao);
-#endif
} else {
- GF_LOG_OCCASIONALLY ( gf_fuse_conn_err_log, "glusterfs-fuse",
- GF_LOG_WARNING,
- "%"PRIu64": %s() %s => -1 (%s)",
- frame->root->unique,
- gf_fop_list[frame->root->op],
- state->loc.path ? state->loc.path : "ERR",
- strerror (op_errno));
+ GF_LOG_OCCASIONALLY (gf_fuse_conn_err_log,
+ "glusterfs-fuse", GF_LOG_WARNING,
+ "%"PRIu64": %s() %s => -1 (%s)", frame->root->unique,
+ gf_fop_list[frame->root->op],
+ state->loc.path ? state->loc.path : "ERR",
+ strerror (op_errno));
send_fuse_err (this, finh, op_errno);
}
- free_fuse_state (state);
+ free_state (state);
STACK_DESTROY (frame->root);
return 0;
}
+
static int
fuse_root_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno,
- inode_t *inode, struct iatt *stat, dict_t *dict,
- struct iatt *postparent)
+ inode_t *inode, struct stat *stat, dict_t *dict,
+ struct stat *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;
}
-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,
- state->resolve.op_errno);
- 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) {
- 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);
- } else {
-
- gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64": FGETATTR %"PRIu64" (%s/%p)",
- state->finh->unique, state->finh->nodeid,
- state->loc.path, state->fd);
-
- FUSE_FOP (state, fuse_attr_cbk, GF_FOP_FSTAT,
- fstat, state->fd, state->xdata);
- }
-}
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);
if (finh->nodeid == 1) {
- state->gfid[15] = 1;
-
ret = fuse_loc_fill (&state->loc, state, finh->nodeid, 0, NULL);
if (ret < 0) {
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
- "%"PRIu64": GETATTR on / (fuse_loc_fill() failed)",
- finh->unique);
+ "%"PRIu64": GETATTR %"PRIu64" (fuse_loc_fill() failed)",
+ finh->unique, finh->nodeid);
send_fuse_err (this, finh, ENOENT);
- free_fuse_state (state);
+ free_state (state);
return;
}
- fuse_gfid_set (state);
+ state->dict = dict_new ();
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);
+ ret = fuse_loc_fill (&state->loc, state, finh->nodeid, 0, NULL);
- fuse_resolve_and_resume (state, fuse_getattr_resume);
-}
-
-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_get (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)",
+ finh->unique, finh->nodeid, state->loc.path);
+ send_fuse_err (this, finh, ENOENT);
+ free_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, finh->pid);
+ state->fd = fd;
+ if (!fd || S_ISDIR (state->loc.inode->st_mode)) {
+ /* 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)",
+ finh->unique, finh->nodeid);
+ send_fuse_err (this, finh, ENOENT);
+ free_state (state);
+ return;
}
- }
- fdctx->open_flags |= (foo->open_flags & FOPEN_DIRECT_IO);
+ gf_log ("glusterfs-fuse", GF_LOG_TRACE,
+ "%"PRIu64": GETATTR %"PRIu64" (%s)",
+ finh->unique, finh->nodeid, state->loc.path);
- if (tmp_fd != NULL) {
- fd_unref (tmp_fd);
- }
- ret = 0;
-out:
- return ret;
-}
+ FUSE_FOP (state, fuse_attr_cbk, GF_FOP_STAT,
+ stat, &state->loc);
+ } else {
+ gf_log ("glusterfs-fuse", GF_LOG_TRACE,
+ "%"PRIu64": FGETATTR %"PRIu64" (%s/%p)",
+ finh->unique, finh->nodeid, state->loc.path, fd);
-gf_boolean_t
-direct_io_mode (dict_t *xdata)
-{
- if (xdata && dict_get (xdata, "direct-io-mode"))
- return _gf_true;
- return _gf_false;
+ FUSE_FOP (state,fuse_attr_cbk, GF_FOP_FSTAT,
+ fstat, fd);
+ }
}
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;
finh = state->finh;
- fuse_log_eh_fop(this, state, frame, op_ret, op_errno);
-
if (op_ret >= 0) {
foo.fh = (uintptr_t) fd;
foo.open_flags = 0;
- if (!IA_ISDIR (fd->inode->ia_type)) {
+ if (!S_ISDIR (fd->inode->st_mode)) {
if (((priv->direct_io_mode == 2)
&& ((state->flags & O_ACCMODE) != O_RDONLY))
- || (priv->direct_io_mode == 1)
- || (direct_io_mode (xdata)))
+ || (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;
-#endif
}
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
"%"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 for fd "
- "(ptr:%p inode-gfid:%s) from fds already "
- "opened", fd, uuid_utoa (fd->inode->gfid));
- 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);
+ free_state (state);
STACK_DESTROY (frame->root);
return 0;
}
+
static void
-fuse_do_truncate (fuse_state_t *state)
+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, state->off, state->xdata);
+ ftruncate, state->fd, size);
} else {
FUSE_FOP (state, fuse_truncate_cbk, GF_FOP_TRUNCATE,
- truncate, &state->loc, state->off, state->xdata);
+ truncate, &state->loc, size);
}
return;
}
+
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 stat *statpre, struct stat *statpost)
{
fuse_state_t *state;
fuse_in_header_t *finh;
@@ -1039,36 +901,31 @@ fuse_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
state = frame->root->state;
finh = state->finh;
- fuse_log_eh(this, "op_ret: %d, op_errno: %d, %"PRIu64", %s() %s => "
- "gfid: %s", op_ret, op_errno, frame->root->unique,
- gf_fop_list[frame->root->op], state->loc.path,
- state->loc.inode ? uuid_utoa (state->loc.inode->gfid) : "");
-
if (op_ret == 0) {
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64": %s() %s => %"PRIu64, frame->root->unique,
+ "%"PRIu64": %s() %s => %"PRId64, frame->root->unique,
gf_fop_list[frame->root->op],
state->loc.path ? state->loc.path : "ERR",
- statpost->ia_ino);
+ statpost->st_ino);
+
+ /* TODO: make these timeouts configurable via meta */
+ /* TODO: what if the inode number has changed by now */
+
+ statpost->st_blksize = this->ctx->page_size;
- statpost->ia_blksize = this->ctx->page_size;
- gf_fuse_stat2attr (statpost, &fao.attr, priv->enable_ino32);
+ stat2attr (statpost, &fao.attr);
fao.attr_valid = calc_timeout_sec (priv->attribute_timeout);
fao.attr_valid_nsec =
calc_timeout_nsec (priv->attribute_timeout);
if (state->truncate_needed) {
- fuse_do_truncate (state);
+ fuse_do_truncate (state, state->size);
} else {
-#if FUSE_KERNEL_MINOR_VERSION >= 9
priv->proto_minor >= 9 ?
- send_fuse_obj (this, finh, &fao) :
- send_fuse_data (this, finh, &fao,
- FUSE_COMPAT_ATTR_OUT_SIZE);
-#else
- send_fuse_obj (this, finh, &fao);
-#endif
+ send_fuse_obj (this, finh, &fao) :
+ send_fuse_data (this, finh, &fao,
+ FUSE_COMPAT_ATTR_OUT_SIZE);
op_done = 1;
}
} else {
@@ -1083,7 +940,7 @@ fuse_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
}
if (op_done) {
- free_fuse_state (state);
+ free_state (state);
}
STACK_DESTROY (frame->root);
@@ -1091,6 +948,7 @@ fuse_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
return 0;
}
+
static int32_t
fattr_to_gf_set_attr (int32_t valid)
{
@@ -1117,81 +975,35 @@ fattr_to_gf_set_attr (int32_t valid)
return gf_valid;
}
+
#define FATTR_MASK (FATTR_SIZE \
| FATTR_UID | FATTR_GID \
| FATTR_ATIME | FATTR_MTIME \
| FATTR_MODE)
-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,
- state->resolve.op_errno);
- 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) ||
- (state->valid & FATTR_MTIME))) {
- /*
- there is no "futimes" call, so don't send
- fsetattr if ATIME or MTIME is set
- */
-
- FUSE_FOP (state, fuse_setattr_cbk, GF_FOP_FSETATTR,
- fsetattr, state->fd, &state->attr,
- fattr_to_gf_set_attr (state->valid),
- state->xdata);
- } else {
- FUSE_FOP (state, fuse_setattr_cbk, GF_FOP_SETATTR,
- setattr, &state->loc, &state->attr,
- fattr_to_gf_set_attr (state->valid),
- state->xdata);
- }
- } else {
- fuse_do_truncate (state);
- }
-
-}
static void
fuse_setattr (xlator_t *this, fuse_in_header_t *finh, void *msg)
{
struct fuse_setattr_in *fsi = msg;
-#if FUSE_KERNEL_MINOR_VERSION >= 9
+ struct stat attr = {0, };
+
fuse_private_t *priv = NULL;
-#endif
fuse_state_t *state = NULL;
+ int32_t ret = -1;
+ int32_t valid = 0;
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
@@ -1206,45 +1018,81 @@ fuse_setattr (xlator_t *this, fuse_in_header_t *finh, void *msg)
* http://git.kernel.org/?p=linux/kernel/git/torvalds/
* linux-2.6.git;a=commit;h=v2.6.23-5896-gf333211
*/
-#if FUSE_KERNEL_MINOR_VERSION >= 9
priv = this->private;
if (priv->proto_minor >= 9 && fsi->valid & FATTR_LOCKOWNER)
state->lk_owner = fsi->lock_owner;
-#endif
- state->valid = fsi->valid;
+ if ((state->loc.inode == NULL && ret == 0) ||
+ (ret < 0)) {
- if ((fsi->valid & (FATTR_MASK)) != FATTR_SIZE) {
- if (fsi->valid & FATTR_SIZE) {
- state->off = fsi->size;
+ 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_state (state);
+
+ return;
+ }
+
+ gf_log ("glusterfs-fuse", GF_LOG_TRACE,
+ "%"PRIu64": SETATTR (%"PRIu64")%s", finh->unique,
+ finh->nodeid, state->loc.path);
+
+ valid = fsi->valid;
+
+ if (fsi->valid & FATTR_FH) {
+ state->fd = FH_TO_FD (fsi->fh);
+ }
+
+ if ((valid & (FATTR_MASK)) != FATTR_SIZE) {
+ if (valid & FATTR_SIZE) {
+ state->size = fsi->size;
state->truncate_needed = _gf_true;
}
- state->attr.ia_size = fsi->size;
- state->attr.ia_atime = fsi->atime;
- state->attr.ia_mtime = fsi->mtime;
- state->attr.ia_atime_nsec = fsi->atimensec;
- state->attr.ia_mtime_nsec = fsi->mtimensec;
+ attr.st_size = fsi->size;
+ attr.st_atime = fsi->atime;
+ attr.st_mtime = fsi->mtime;
+ ST_ATIM_NSEC_SET (&attr, fsi->atimensec);
+ ST_MTIM_NSEC_SET (&attr, fsi->mtimensec);
+
+ attr.st_mode = fsi->mode;
+ attr.st_uid = fsi->uid;
+ attr.st_gid = fsi->gid;
- state->attr.ia_prot = ia_prot_from_st_mode (fsi->mode);
- state->attr.ia_uid = fsi->uid;
- state->attr.ia_gid = fsi->gid;
+ if (state->fd &&
+ !((fsi->valid & FATTR_ATIME) || (fsi->valid & FATTR_MTIME))) {
+
+ /*
+ there is no "futimes" call, so don't send
+ fsetattr if ATIME or MTIME is set
+ */
+
+ FUSE_FOP (state, fuse_setattr_cbk, GF_FOP_FSETATTR,
+ fsetattr, state->fd, &attr,
+ fattr_to_gf_set_attr (fsi->valid));
+ } else {
+ FUSE_FOP (state, fuse_setattr_cbk, GF_FOP_SETATTR,
+ setattr, &state->loc, &attr,
+ fattr_to_gf_set_attr (fsi->valid));
+ }
} else {
- state->off = fsi->size;
+ fuse_do_truncate (state, fsi->size);
}
- fuse_resolve_and_resume (state, fuse_setattr_resume);
}
+
+static int gf_fuse_xattr_enotsup_log;
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)
+fuse_fsync_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct stat *prebuf,
+ struct stat *postbuf)
{
fuse_state_t *state = frame->root->state;
fuse_in_header_t *finh = state->finh;
- fuse_log_eh_fop(this, state, frame, op_ret, op_errno);
-
if (op_ret == 0) {
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
"%"PRIu64": %s() %s => 0", frame->root->unique,
@@ -1253,47 +1101,99 @@ fuse_err_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
send_fuse_err (this, finh, 0);
} else {
- gf_log ("glusterfs-fuse", GF_LOG_WARNING,
- "%"PRIu64": %s() %s => -1 (%s)",
- frame->root->unique,
- gf_fop_list[frame->root->op],
- state->loc.path ? state->loc.path : "ERR",
- strerror (op_errno));
+ if (frame->root->op == GF_FOP_SETXATTR) {
+ op_ret = gf_compat_setxattr (state->dict);
+ if (op_ret == 0)
+ op_errno = 0;
+ if (op_errno == ENOTSUP) {
+ gf_fuse_xattr_enotsup_log++;
+ if (!(gf_fuse_xattr_enotsup_log % GF_UNIVERSAL_ANSWER))
+ gf_log ("glusterfs-fuse",
+ GF_LOG_CRITICAL,
+ "extended attribute not "
+ "supported by the backend "
+ "storage");
+ }
+ } else {
+ if ((frame->root->op == GF_FOP_REMOVEXATTR)
+ && (op_errno == ENOATTR)) {
+ goto nolog;
+ }
+ gf_log ("glusterfs-fuse", GF_LOG_WARNING,
+ "%"PRIu64": %s() %s => -1 (%s)",
+ frame->root->unique,
+ gf_fop_list[frame->root->op],
+ state->loc.path ? state->loc.path : "ERR",
+ strerror (op_errno));
+ }
+ nolog:
send_fuse_err (this, finh, op_errno);
}
- free_fuse_state (state);
+ free_state (state);
STACK_DESTROY (frame->root);
return 0;
}
-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)
-{
- return fuse_err_cbk (frame, cookie, this, op_ret, op_errno, xdata);
-}
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)
+fuse_err_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno)
{
- if (op_ret == -1 && op_errno == ENOTSUP)
- GF_LOG_OCCASIONALLY (gf_fuse_xattr_enotsup_log,
- "glusterfs-fuse", GF_LOG_CRITICAL,
- "extended attribute not supported "
- "by the backend storage");
+ fuse_state_t *state = frame->root->state;
+ fuse_in_header_t *finh = state->finh;
- return fuse_err_cbk (frame, cookie, this, op_ret, op_errno, xdata);
+ if (op_ret == 0) {
+ gf_log ("glusterfs-fuse", GF_LOG_TRACE,
+ "%"PRIu64": %s() %s => 0", frame->root->unique,
+ gf_fop_list[frame->root->op],
+ state->loc.path ? state->loc.path : "ERR");
+
+ send_fuse_err (this, finh, 0);
+ } else {
+ if (frame->root->op == GF_FOP_SETXATTR) {
+ op_ret = gf_compat_setxattr (state->dict);
+ if (op_ret == 0)
+ op_errno = 0;
+ if (op_errno == ENOTSUP) {
+ gf_fuse_xattr_enotsup_log++;
+ if (!(gf_fuse_xattr_enotsup_log % GF_UNIVERSAL_ANSWER))
+ gf_log ("glusterfs-fuse",
+ GF_LOG_CRITICAL,
+ "extended attribute not "
+ "supported by the backend "
+ "storage");
+ }
+ } else {
+ if ((frame->root->op == GF_FOP_REMOVEXATTR)
+ && (op_errno == ENOATTR)) {
+ goto nolog;
+ }
+ gf_log ("glusterfs-fuse", GF_LOG_WARNING,
+ "%"PRIu64": %s() %s => -1 (%s)",
+ frame->root->unique,
+ gf_fop_list[frame->root->op],
+ state->loc.path ? state->loc.path : "ERR",
+ strerror (op_errno));
+ }
+ nolog:
+
+ send_fuse_err (this, finh, op_errno);
+ }
+
+ free_state (state);
+ STACK_DESTROY (frame->root);
+
+ return 0;
}
+
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)
+ int32_t op_ret, int32_t op_errno, struct stat *preparent,
+ struct stat *postparent)
{
fuse_state_t *state = NULL;
fuse_in_header_t *finh = NULL;
@@ -1301,14 +1201,11 @@ fuse_unlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
state = frame->root->state;
finh = state->finh;
- fuse_log_eh (this, "op_ret: %d, op_errno: %d, %"PRIu64": %s() %s => "
- "gfid: %s", op_ret, op_errno, frame->root->unique,
- gf_fop_list[frame->root->op], state->loc.path,
- state->loc.inode ? uuid_utoa (state->loc.inode->gfid) : "");
-
- if (op_ret == 0) {
+ if (op_ret == 0)
inode_unlink (state->loc.inode, state->loc.parent,
state->loc.name);
+
+ if (op_ret == 0) {
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
"%"PRIu64": %s() %s => 0", frame->root->unique,
gf_fop_list[frame->root->op], state->loc.path);
@@ -1324,56 +1221,50 @@ fuse_unlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
send_fuse_err (this, finh, op_errno);
}
- free_fuse_state (state);
+ free_state (state);
STACK_DESTROY (frame->root);
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,
- state->resolve.op_errno);
- 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);
-}
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_state (state);
+ return;
+ }
- state->mask = fai->mask;
+ gf_log ("glusterfs-fuse", GF_LOG_TRACE,
+ "%"PRIu64" ACCESS %s/%"PRIu64" mask=%d", finh->unique,
+ state->loc.path, finh->nodeid, fai->mask);
- fuse_resolve_and_resume (state, fuse_access_resume);
+ FUSE_FOP (state, fuse_err_cbk,
+ GF_FOP_ACCESS, access,
+ &state->loc, fai->mask);
return;
}
+
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 stat *buf)
{
fuse_state_t *state = NULL;
fuse_in_header_t *finh = NULL;
@@ -1381,17 +1272,14 @@ fuse_readlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
state = frame->root->state;
finh = state->finh;
- fuse_log_eh (this, "op_ret: %d, op_errno: %d %"PRIu64": %s() => %s"
- " linkname: %s, gfid: %s", op_ret, op_errno,
- frame->root->unique, gf_fop_list[frame->root->op],
- state->loc.gfid, linkname,
- uuid_utoa (state->loc.gfid));
-
if (op_ret > 0) {
+ ((char *)linkname)[op_ret] = '\0';
+
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64": %s => %s (size:%d)", frame->root->unique,
- state->loc.path, linkname, op_ret);
- send_fuse_data (this, finh, (void *)linkname, op_ret);
+ "%"PRIu64": %s => %s", frame->root->unique,
+ state->loc.path, linkname);
+
+ send_fuse_data (this, finh, (void *)linkname, op_ret + 1);
} else {
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
"%"PRIu64": %s => -1 (%s)", frame->root->unique,
@@ -1400,83 +1288,43 @@ fuse_readlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
send_fuse_err (this, finh, op_errno);
}
- free_fuse_state (state);
+ free_state (state);
STACK_DESTROY (frame->root);
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,
- state->resolve.op_errno);
- 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));
-
- FUSE_FOP (state, fuse_readlink_cbk, GF_FOP_READLINK,
- readlink, &state->loc, 4096, state->xdata);
-}
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);
-
- fuse_resolve_inode_init (state, &state->resolve, finh->nodeid);
-
- 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 %"PRIu64"/%s (%s/%s) resolution failed",
- state->finh->nodeid, state->resolve.bname,
- uuid_utoa (state->resolve.gfid), state->resolve.bname);
- send_fuse_err (state->this, state->finh,
- state->resolve.op_errno);
- free_fuse_state (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/%"PRId64" (fuse_loc_fill() returned NULL inode)",
+ finh->unique, state->loc.path,
+ state->loc.inode->ino);
+ send_fuse_err (this, finh, ENOENT);
+ free_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);
-
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64": MKNOD %s", state->finh->unique,
- state->loc.path);
+ "%"PRIu64" READLINK %s/%"PRId64, finh->unique,
+ state->loc.path, state->loc.inode->ino);
- FUSE_FOP (state, fuse_newentry_cbk, GF_FOP_MKNOD,
- mknod, &state->loc, state->mode, state->rdev, state->umask,
- state->xdata);
+ FUSE_FOP (state, fuse_readlink_cbk, GF_FOP_READLINK,
+ readlink, &state->loc, 4096);
+
+ return;
}
+
static void
fuse_mknod (xlator_t *this, fuse_in_header_t *finh, void *msg)
{
@@ -1484,234 +1332,172 @@ fuse_mknod (xlator_t *this, fuse_in_header_t *finh, void *msg)
char *name = (char *)(fmi + 1);
fuse_state_t *state = NULL;
-#if FUSE_KERNEL_MINOR_VERSION >= 12
fuse_private_t *priv = NULL;
- int32_t ret = -1;
+ int32_t ret = -1;
priv = this->private;
if (priv->proto_minor < 12)
name = (char *)msg + FUSE_COMPAT_MKNOD_IN_SIZE;
-#endif
GET_STATE (this, finh, state);
-
- uuid_generate (state->gfid);
-
- fuse_resolve_entry_init (state, &state->resolve, finh->nodeid, name);
-
- state->mode = fmi->mode;
- state->rdev = fmi->rdev;
-
-#if FUSE_KERNEL_MINOR_VERSION >=12
- priv = this->private;
- FUSE_ENTRY_CREATE(this, priv, finh, state, fmi, "MKNOD");
-#endif
-
- 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 %"PRIu64" (%s/%s) resolution failed",
- state->finh->nodeid, uuid_utoa (state->resolve.gfid),
- state->resolve.bname);
- send_fuse_err (state->this, state->finh,
- state->resolve.op_errno);
- free_fuse_state (state);
+ ret = fuse_loc_fill (&state->loc, state, 0, finh->nodeid, name);
+ if (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_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);
+ state->loc.inode = inode_new (state->itable);
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64": MKDIR %s", state->finh->unique,
+ "%"PRIu64": MKNOD %s", finh->unique,
state->loc.path);
- FUSE_FOP (state, fuse_newentry_cbk, GF_FOP_MKDIR,
- mkdir, &state->loc, state->mode, state->umask, state->xdata);
+ FUSE_FOP (state, fuse_newentry_cbk, GF_FOP_MKNOD,
+ mknod, &state->loc, fmi->mode, fmi->rdev);
+
+ return;
}
+
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);
-#if FUSE_KERNEL_MINOR_VERSION >=12
- fuse_private_t *priv = NULL;
- int32_t ret = -1;
-#endif
fuse_state_t *state;
+ int32_t ret = -1;
GET_STATE (this, finh, state);
-
- uuid_generate (state->gfid);
-
- fuse_resolve_entry_init (state, &state->resolve, finh->nodeid, name);
-
- state->mode = fmi->mode;
-
-#if FUSE_KERNEL_MINOR_VERSION >=12
- priv = this->private;
- FUSE_ENTRY_CREATE(this, priv, finh, state, fmi, "MKDIR");
-#endif
-
- 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 %"PRIu64" (%s/%s) resolution failed",
- state->finh->nodeid, uuid_utoa (state->resolve.gfid),
- state->resolve.bname);
- send_fuse_err (state->this, state->finh,
- state->resolve.op_errno);
- free_fuse_state (state);
+ ret = fuse_loc_fill (&state->loc, state, 0, finh->nodeid, name);
+ if (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_state (state);
return;
}
+ state->loc.inode = inode_new (state->itable);
+
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64": UNLINK %s", state->finh->unique,
+ "%"PRIu64": MKDIR %s", finh->unique,
state->loc.path);
- FUSE_FOP (state, fuse_unlink_cbk, GF_FOP_UNLINK,
- unlink, &state->loc, 0, state->xdata);
+ FUSE_FOP (state, fuse_newentry_cbk, GF_FOP_MKDIR,
+ mkdir, &state->loc, fmi->mode);
+
+ return;
}
+
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);
- fuse_resolve_entry_init (state, &state->resolve, finh->nodeid, name);
-
- fuse_resolve_and_resume (state, fuse_unlink_resume);
-
- return;
-}
+ ret = fuse_loc_fill (&state->loc, state, 0, finh->nodeid, name);
-void
-fuse_rmdir_resume (fuse_state_t *state)
-{
- if (!state->loc.parent || !state->loc.inode) {
- gf_log ("glusterfs-fuse", GF_LOG_ERROR,
- "RMDIR %"PRIu64" (%s/%s) resolution failed",
- state->finh->nodeid, uuid_utoa (state->resolve.gfid),
- state->resolve.bname);
- send_fuse_err (state->this, state->finh,
- state->resolve.op_errno);
- free_fuse_state (state);
+ if ((state->loc.inode == NULL) ||
+ (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_state (state);
return;
}
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64": RMDIR %s", state->finh->unique,
+ "%"PRIu64": UNLINK %s", finh->unique,
state->loc.path);
- FUSE_FOP (state, fuse_unlink_cbk, GF_FOP_RMDIR,
- rmdir, &state->loc, 0, state->xdata);
+ FUSE_FOP (state, fuse_unlink_cbk, GF_FOP_UNLINK,
+ unlink, &state->loc);
+
+ return;
}
+
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);
-
- fuse_resolve_entry_init (state, &state->resolve, finh->nodeid, name);
-
- 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 %"PRIu64" (%s/%s) -> %s resolution failed",
- state->finh->nodeid, uuid_utoa (state->resolve.gfid),
- state->resolve.bname, state->name);
- send_fuse_err (state->this, state->finh,
- state->resolve.op_errno);
- free_fuse_state (state);
+ ret = fuse_loc_fill (&state->loc, state, 0, finh->nodeid, name);
+ if ((state->loc.inode == NULL) ||
+ (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_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);
-
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64": SYMLINK %s -> %s", state->finh->unique,
- state->loc.path, state->name);
+ "%"PRIu64": RMDIR %s", finh->unique,
+ state->loc.path);
- FUSE_FOP (state, fuse_newentry_cbk, GF_FOP_SYMLINK,
- symlink, state->name, &state->loc, state->umask, state->xdata);
+ FUSE_FOP (state, fuse_unlink_cbk, GF_FOP_RMDIR,
+ rmdir, &state->loc);
+
+ return;
}
+
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);
+ ret = fuse_loc_fill (&state->loc, state, 0, finh->nodeid, name);
+ if (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_state (state);
+ return;
+ }
- uuid_generate (state->gfid);
-
- fuse_resolve_entry_init (state, &state->resolve, finh->nodeid, name);
+ state->loc.inode = inode_new (state->itable);
- state->name = gf_strdup (linkname);
+ gf_log ("glusterfs-fuse", GF_LOG_TRACE,
+ "%"PRIu64": SYMLINK %s -> %s", finh->unique,
+ state->loc.path, linkname);
- fuse_resolve_and_resume (state, fuse_symlink_resume);
+ FUSE_FOP (state, fuse_newentry_cbk, GF_FOP_SYMLINK,
+ symlink, linkname, &state->loc);
return;
}
+
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)
+ int32_t op_ret, int32_t op_errno, struct stat *buf,
+ struct stat *preoldparent, struct stat *postoldparent,
+ struct stat *prenewparent, struct stat *postnewparent)
{
fuse_state_t *state = NULL;
fuse_in_header_t *finh = NULL;
@@ -1719,30 +1505,22 @@ fuse_rename_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
state = frame->root->state;
finh = state->finh;
- fuse_log_eh (this, "op_ret: %d, op_errno: %d, %"PRIu64": %s() "
- "path: %s parent: %s ==> path: %s parent: %s"
- "gfid: %s", op_ret, op_errno, frame->root->unique,
- gf_fop_list[frame->root->op], state->loc.path,
- state->loc.parent?uuid_utoa (state->loc.parent->gfid):"",
- state->loc2.path,
- state->loc2.parent?uuid_utoa (state->loc2.parent->gfid):"",
- state->loc.inode?uuid_utoa (state->loc.inode->gfid):"");
-
if (op_ret == 0) {
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64": %s -> %s => 0 (buf->ia_ino=%"PRIu64")",
+ "%"PRIu64": %s -> %s => 0 (buf->st_ino=%"PRId64" , loc->ino=%"PRId64")",
frame->root->unique, state->loc.path, state->loc2.path,
- buf->ia_ino);
+ buf->st_ino, state->loc.ino);
{
/* ugly ugly - to stay blind to situation where
rename happens on a new inode
*/
- buf->ia_type = state->loc.inode->ia_type;
+ buf->st_ino = state->loc.ino;
+ buf->st_mode = state->loc.inode->st_mode;
}
- buf->ia_blksize = this->ctx->page_size;
+ buf->st_blksize = this->ctx->page_size;
- inode_rename (state->loc.parent->table,
+ inode_rename (state->itable,
state->loc.parent, state->loc.name,
state->loc2.parent, state->loc2.name,
state->loc.inode, buf);
@@ -1756,57 +1534,11 @@ fuse_rename_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
send_fuse_err (this, finh, op_errno);
}
- free_fuse_state (state);
+ free_state (state);
STACK_DESTROY (frame->root);
return 0;
}
-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,
- state->resolve.op_errno);
- 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);
-
- 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);
-
- FUSE_FOP (state, fuse_rename_cbk, GF_FOP_RENAME,
- rename, &state->loc, &state->loc2, state->xdata);
-}
static void
fuse_rename (xlator_t *this, fuse_in_header_t *finh, void *msg)
@@ -1814,111 +1546,138 @@ 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);
-
- fuse_resolve_entry_init (state, &state->resolve2, fri->newdir, newname);
-
- fuse_resolve_and_resume (state, fuse_rename_resume);
-
- return;
-}
-
-void
-fuse_link_resume (fuse_state_t *state)
-{
- if (!state->loc2.inode || !state->loc.parent) {
+ ret = fuse_loc_fill (&state->loc, state, 0, finh->nodeid, oldname);
+ if ((state->loc.inode == NULL) ||
+ (ret < 0)) {
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,
- state->resolve.op_errno);
- free_fuse_state (state);
+ "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_state (state);
return;
}
- state->resolve.op_ret = 0;
- state->resolve2.op_ret = 0;
+ ret = fuse_loc_fill (&state->loc2, state, 0, fri->newdir, newname);
+ if (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);
- if (state->loc.inode) {
- inode_unref (state->loc.inode);
- state->loc.inode = NULL;
- }
- state->loc.inode = inode_ref (state->loc2.inode);
+ send_fuse_err (this, finh, ENOENT);
+ free_state (state);
+ return;
+ }
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64": LINK() %s -> %s",
- state->finh->unique, state->loc2.path,
- state->loc.path);
+ "%"PRIu64": RENAME `%s (%"PRId64")' -> `%s (%"PRId64")'",
+ finh->unique, state->loc.path, state->loc.ino,
+ state->loc2.path, state->loc2.ino);
- FUSE_FOP (state, fuse_newentry_cbk, GF_FOP_LINK,
- link, &state->loc2, &state->loc, state->xdata);
+ FUSE_FOP (state, fuse_rename_cbk, GF_FOP_RENAME,
+ rename, &state->loc, &state->loc2);
+
+ return;
}
+
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 == NULL) ||
+ (ret < 0)) {
+ gf_log ("glusterfs-fuse", GF_LOG_WARNING,
+ "fuse_loc_fill() failed for %s %"PRIu64": LINK %s %s",
+ state->loc2.path, finh->unique,
+ state->loc2.path, state->loc.path);
+ send_fuse_err (this, finh, ENOENT);
+ free_state (state);
+ return;
+ }
- fuse_resolve_entry_init (state, &state->resolve, finh->nodeid, name);
+ state->loc.inode = inode_ref (state->loc2.inode);
+ gf_log ("glusterfs-fuse", GF_LOG_TRACE,
+ "%"PRIu64": LINK() %s (%"PRId64") -> %s (%"PRId64")",
+ finh->unique, state->loc2.path, state->loc2.ino,
+ state->loc.path, state->loc.ino);
- fuse_resolve_and_resume (state, fuse_link_resume);
+ FUSE_FOP (state, fuse_newentry_cbk, GF_FOP_LINK,
+ link, &state->loc2, &state->loc);
return;
}
+
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)
+ fd_t *fd, inode_t *inode, struct stat *buf,
+ struct stat *preparent, struct stat *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;
finh = state->finh;
foo.open_flags = 0;
- fuse_log_eh_fop(this, state, frame, op_ret, op_errno);
-
if (op_ret >= 0) {
foo.fh = (uintptr_t) fd;
if (((priv->direct_io_mode == 2)
&& ((state->flags & O_ACCMODE) != O_RDONLY))
- || (priv->direct_io_mode == 1)
- || direct_io_mode (xdata))
+ || (priv->direct_io_mode == 1))
foo.open_flags |= FOPEN_DIRECT_IO;
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64": %s() %s => %p (ino=%"PRIu64")",
+ "%"PRIu64": %s() %s => %p (ino=%"PRId64")",
frame->root->unique, gf_fop_list[frame->root->op],
- state->loc.path, fd, buf->ia_ino);
+ state->loc.path, fd, buf->st_ino);
- buf->ia_blksize = this->ctx->page_size;
- gf_fuse_stat2attr (buf, &feo.attr, priv->enable_ino32);
+ buf->st_blksize = this->ctx->page_size;
+ stat2attr (buf, &feo.attr);
linked_inode = inode_link (inode, state->loc.parent,
state->loc.name, buf);
if (linked_inode != inode) {
+ gf_log ("glusterfs-fuse", GF_LOG_WARNING,
+ "create(%s) inode (ptr=%p, ino=%"PRId64", "
+ "gen=%"PRId64") found conflict (ptr=%p, "
+ "ino=%"PRId64", gen=%"PRId64")",
+ state->loc.path, inode, inode->ino,
+ inode->generation, linked_inode,
+ linked_inode->ino, linked_inode->generation);
+
/*
VERY racy code (if used anywhere else)
-- don't do this without understanding
@@ -1931,7 +1690,11 @@ fuse_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
inode_unref (linked_inode);
- feo.nodeid = inode_to_fuse_nodeid (linked_inode);
+ fd_ref (fd);
+
+ feo.nodeid = inode_to_nodeid (linked_inode);
+
+ feo.generation = linked_inode->generation;
feo.entry_valid = calc_timeout_sec (priv->entry_timeout);
feo.entry_valid_nsec = calc_timeout_nsec (priv->entry_timeout);
@@ -1942,21 +1705,16 @@ fuse_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
fouh.error = 0;
iov_out[0].iov_base = &fouh;
iov_out[1].iov_base = &feo;
-#if FUSE_KERNEL_MINOR_VERSION >= 9
iov_out[1].iov_len = priv->proto_minor >= 9 ?
sizeof (feo) :
FUSE_COMPAT_ENTRY_OUT_SIZE;
-#else
- iov_out[1].iov_len = sizeof (feo);
-#endif
iov_out[2].iov_base = &foo;
iov_out[2].iov_len = sizeof (foo);
-
if (send_fuse_iov (this, finh, iov_out, 3) == ENOENT) {
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;
}
@@ -1966,196 +1724,104 @@ 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);
+ free_state (state);
STACK_DESTROY (frame->root);
return 0;
}
-void
-fuse_create_resume (fuse_state_t *state)
-{
- fd_t *fd = NULL;
- fuse_private_t *priv = NULL;
- fuse_fd_ctx_t *fdctx = 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);
- send_fuse_err (state->this, state->finh,
- state->resolve.op_errno);
- 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 = inode_new (state->loc.parent->table);
-
- fd = fd_create (state->loc.inode, state->finh->pid);
- if (fd == NULL) {
- gf_log ("glusterfs-fuse", GF_LOG_WARNING,
- "%"PRIu64" CREATE cannot create a new fd",
- state->finh->unique);
- send_fuse_err (state->this, state->finh, ENOMEM);
- free_fuse_state (state);
- return;
- }
-
- fdctx = fuse_fd_ctx_check_n_create (state->this, fd);
- if (fdctx == NULL) {
- gf_log ("glusterfs-fuse", GF_LOG_WARNING,
- "%"PRIu64" CREATE creation of fdctx failed",
- state->finh->unique);
- fd_unref (fd);
- send_fuse_err (state->this, state->finh, ENOMEM);
- free_fuse_state (state);
- return;
- }
-
- priv = state->this->private;
-
- state->fd_no = gf_fd_unused_get (priv->fdtable, fd);
-
- state->fd = fd_ref (fd);
- fd->flags = state->flags;
-
- gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64": CREATE %s", state->finh->unique,
- state->loc.path);
-
- FUSE_FOP (state, fuse_create_cbk, GF_FOP_CREATE,
- create, &state->loc, state->flags, state->mode,
- state->umask, fd, state->xdata);
-
-}
static void
fuse_create (xlator_t *this, fuse_in_header_t *finh, void *msg)
{
-#if FUSE_KERNEL_MINOR_VERSION >= 12
struct fuse_create_in *fci = msg;
- fuse_private_t *priv = NULL;
- int32_t ret = -1;
-#else
- struct fuse_open_in *fci = msg;
-#endif
char *name = (char *)(fci + 1);
+ fuse_private_t *priv = NULL;
fuse_state_t *state = NULL;
+ fd_t *fd = NULL;
+ int32_t ret = -1;
-#if FUSE_KERNEL_MINOR_VERSION >= 12
priv = this->private;
if (priv->proto_minor < 12)
name = (char *)((struct fuse_open_in *)msg + 1);
-#endif
GET_STATE (this, finh, state);
-
- uuid_generate (state->gfid);
-
- fuse_resolve_entry_init (state, &state->resolve, finh->nodeid, name);
-
- state->mode = fci->mode;
state->flags = fci->flags;
-#if FUSE_KERNEL_MINOR_VERSION >=12
- priv = this->private;
- FUSE_ENTRY_CREATE(this, priv, finh, state, fci, "CREATE");
-#endif
- 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;
- fuse_fd_ctx_t *fdctx = 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,
- state->resolve.op_errno);
- free_fuse_state (state);
- return;
- }
-
- fd = fd_create (state->loc.inode, state->finh->pid);
- if (!fd) {
- gf_log ("fuse", GF_LOG_ERROR,
- "fd is NULL");
- send_fuse_err (state->this, state->finh, ENOENT);
- free_fuse_state (state);
- return;
- }
-
- fdctx = fuse_fd_ctx_check_n_create (state->this, fd);
- if (fdctx == NULL) {
+ ret = fuse_loc_fill (&state->loc, state, 0, finh->nodeid, name);
+ if (ret < 0) {
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
- "%"PRIu64": OPEN creation of fdctx failed",
- state->finh->unique);
- fd_unref (fd);
- send_fuse_err (state->this, state->finh, ENOMEM);
- free_fuse_state (state);
+ "%"PRIu64" CREATE %s (fuse_loc_fill() failed)",
+ finh->unique, state->loc.path);
+ send_fuse_err (this, finh, ENOENT);
+ free_state (state);
return;
}
- priv = state->this->private;
+ state->loc.inode = inode_new (state->itable);
- state->fd_no = gf_fd_unused_get (priv->fdtable, fd);
- state->fd = fd_ref (fd);
+ fd = fd_create (state->loc.inode, finh->pid);
+ state->fd = fd;
fd->flags = state->flags;
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64": OPEN %s", state->finh->unique,
+ "%"PRIu64": CREATE %s", finh->unique,
state->loc.path);
- FUSE_FOP (state, fuse_fd_cbk, GF_FOP_OPEN,
- open, &state->loc, state->flags, fd, state->xdata);
+ FUSE_FOP (state, fuse_create_cbk, GF_FOP_CREATE,
+ create, &state->loc, state->flags, fci->mode, fd);
+
+ return;
}
+
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;
+ fd_t *fd = NULL;
+ int32_t ret = -1;
GET_STATE (this, finh, state);
+ state->flags = foi->flags;
- 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);
- state->flags = foi->flags;
+ send_fuse_err (this, finh, ENOENT);
+ free_state (state);
+ return;
+ }
- fuse_resolve_and_resume (state, fuse_open_resume);
+ fd = fd_create (state->loc.inode, finh->pid);
+ state->fd = fd;
+ fd->flags = foi->flags;
+
+ gf_log ("glusterfs-fuse", GF_LOG_TRACE,
+ "%"PRIu64": OPEN %s", finh->unique,
+ state->loc.path);
+
+ FUSE_FOP (state, fuse_fd_cbk, GF_FOP_OPEN,
+ open, &state->loc, foi->flags, fd, 0);
return;
}
+
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 stat *stbuf, struct iobref *iobref)
{
fuse_state_t *state = NULL;
fuse_in_header_t *finh = NULL;
@@ -2165,22 +1831,19 @@ fuse_readv_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
state = frame->root->state;
finh = state->finh;
- fuse_log_eh_fop(this, state, frame, op_ret, op_errno);
-
if (op_ret >= 0) {
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64": READ => %d/%"GF_PRI_SIZET",%"PRId64"/%"PRIu64,
+ "%"PRIu64": READ => %d/%"GF_PRI_SIZET",%"PRId64"/%"PRId64,
frame->root->unique,
- op_ret, state->size, state->off, stbuf->ia_size);
+ op_ret, state->size, state->off, stbuf->st_size);
- iov_out = GF_CALLOC (count + 1, sizeof (*iov_out),
- gf_fuse_mt_iovec);
+ iov_out = CALLOC (count + 1, sizeof (*iov_out));
if (iov_out) {
fouh.error = 0;
iov_out[0].iov_base = &fouh;
memcpy (iov_out + 1, vector, count * sizeof (*iov_out));
send_fuse_iov (this, finh, iov_out, count + 1);
- GF_FREE (iov_out);
+ FREE (iov_out);
} else
send_fuse_err (this, finh, ENOMEM);
} else {
@@ -2191,61 +1854,49 @@ fuse_readv_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
send_fuse_err (this, finh, op_errno);
}
- free_fuse_state (state);
+ free_state (state);
STACK_DESTROY (frame->root);
return 0;
}
-void
-fuse_readv_resume (fuse_state_t *state)
-{
- gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"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);
-}
static void
fuse_readv (xlator_t *this, fuse_in_header_t *finh, void *msg)
{
struct fuse_read_in *fri = msg;
-#if FUSE_KERNEL_MINOR_VERSION >= 9
fuse_private_t *priv = NULL;
-#endif
fuse_state_t *state = NULL;
fd_t *fd = NULL;
GET_STATE (this, finh, state);
+ state->size = fri->size;
+ state->off = fri->offset;
+
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 */
-#if FUSE_KERNEL_MINOR_VERSION >= 9
priv = this->private;
if (priv->proto_minor >= 9 && fri->read_flags & FUSE_READ_LOCKOWNER)
state->lk_owner = fri->lock_owner;
-#endif
- state->size = fri->size;
- state->off = fri->offset;
- /* lets ignore 'fri->read_flags', but just consider 'fri->flags' */
-#if FUSE_KERNEL_MINOR_VERSION >= 9
- state->io_flags = fri->flags;
-#endif
- fuse_resolve_and_resume (state, fuse_readv_resume);
+ gf_log ("glusterfs-fuse", GF_LOG_TRACE,
+ "%"PRIu64": READ (%p, size=%"PRIu32", offset=%"PRIu64")",
+ finh->unique, fd, fri->size, fri->offset);
+
+ FUSE_FOP (state, fuse_readv_cbk, GF_FOP_READ,
+ readv, fd, fri->size, fri->offset);
+
}
+
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 stat *stbuf, struct stat *postbuf)
{
fuse_state_t *state = NULL;
fuse_in_header_t *finh = NULL;
@@ -2254,13 +1905,11 @@ fuse_writev_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
state = frame->root->state;
finh = state->finh;
- fuse_log_eh_fop(this, state, frame, op_ret, op_errno);
-
if (op_ret >= 0) {
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64": WRITE => %d/%"GF_PRI_SIZET",%"PRId64"/%"PRIu64,
+ "%"PRIu64": WRITE => %d/%"GF_PRI_SIZET",%"PRId64"/%"PRId64,
frame->root->unique,
- op_ret, state->size, state->off, stbuf->ia_size);
+ op_ret, state->size, state->off, stbuf->st_size);
fwo.size = op_ret;
send_fuse_obj (this, finh, &fwo);
@@ -2272,43 +1921,12 @@ fuse_writev_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
send_fuse_err (this, finh, op_errno);
}
- free_fuse_state (state);
+ free_state (state);
STACK_DESTROY (frame->root);
return 0;
}
-void
-fuse_write_resume (fuse_state_t *state)
-{
- struct iobref *iobref = NULL;
- struct iobuf *iobuf = NULL;
-
-
- iobref = iobref_new ();
- if (!iobref) {
- gf_log ("glusterfs-fuse", GF_LOG_ERROR,
- "%"PRIu64": WRITE iobref allocation failed",
- state->finh->unique);
- send_fuse_err (state->this, state->finh, ENOMEM);
-
- free_fuse_state (state);
- return;
- }
-
- iobuf = ((fuse_private_t *) (state->this->private))->iobuf;
- iobref_add (iobref, iobuf);
-
- gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64": WRITE (%p, size=%"GF_PRI_SIZET", 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);
-
- iobref_unref (iobref);
-}
static void
fuse_write (xlator_t *this, fuse_in_header_t *finh, void *msg)
@@ -2319,53 +1937,51 @@ fuse_write (xlator_t *this, fuse_in_header_t *finh, void *msg)
struct fuse_write_in *fwi = (struct fuse_write_in *)
(finh + 1);
+ fuse_private_t *priv = NULL;
fuse_state_t *state = NULL;
+ struct iovec vector;
fd_t *fd = NULL;
-#if FUSE_KERNEL_MINOR_VERSION >= 9
- fuse_private_t *priv = NULL;
+ struct iobref *iobref = NULL;
+ struct iobuf *iobuf = NULL;
+
priv = this->private;
-#endif
GET_STATE (this, finh, state);
- fd = FH_TO_FD (fwi->fh);
- state->fd = fd;
state->size = fwi->size;
state->off = fwi->offset;
-
- /* lets ignore 'fwi->write_flags', but just consider 'fwi->flags' */
-#if FUSE_KERNEL_MINOR_VERSION >= 9
- state->io_flags = fwi->flags;
-#else
- state->io_flags = fwi->write_flags;
-#endif
- /* TODO: may need to handle below flag
- (fwi->write_flags & FUSE_WRITE_CACHE);
- */
-
-
- fuse_resolve_fd_init (state, &state->resolve, fd);
+ fd = FH_TO_FD (fwi->fh);
+ state->fd = fd;
+ vector.iov_base = msg;
+ vector.iov_len = fwi->size;
/* See comment by similar code in fuse_settatr */
-#if FUSE_KERNEL_MINOR_VERSION >= 9
priv = this->private;
if (priv->proto_minor >= 9 && fwi->write_flags & FUSE_WRITE_LOCKOWNER)
state->lk_owner = fwi->lock_owner;
-#endif
- state->vector.iov_base = msg;
- state->vector.iov_len = fwi->size;
+ gf_log ("glusterfs-fuse", GF_LOG_TRACE,
+ "%"PRIu64": WRITE (%p, size=%"PRIu32", offset=%"PRId64")",
+ finh->unique, fd, fwi->size, fwi->offset);
+
+ iobref = iobref_new ();
+ if (!iobref) {
+ gf_log ("glusterfs-fuse", GF_LOG_ERROR,
+ "%"PRIu64": WRITE iobref allocation failed",
+ finh->unique);
- fuse_resolve_and_resume (state, fuse_write_resume);
+ free_state (state);
+ return;
+ }
+ iobuf = ((fuse_private_t *) (state->this->private))->iobuf;
+ iobref_add (iobref, iobuf);
+ FUSE_FOP (state, fuse_writev_cbk, GF_FOP_WRITE,
+ writev, fd, &vector, 1, fwi->offset, iobref);
+
+ iobref_unref (iobref);
return;
}
-void
-fuse_flush_resume (fuse_state_t *state)
-{
- FUSE_FOP (state, fuse_err_cbk, GF_FOP_FLUSH,
- flush, state->fd, state->xdata);
-}
static void
fuse_flush (xlator_t *this, fuse_in_header_t *finh, void *msg)
@@ -2378,88 +1994,88 @@ fuse_flush (xlator_t *this, fuse_in_header_t *finh, void *msg)
GET_STATE (this, finh, state);
fd = FH_TO_FD (ffi->fh);
state->fd = fd;
-
- fuse_resolve_fd_init (state, &state->resolve, fd);
+ if (fd)
+ fd->flush_unique = finh->unique;
state->lk_owner = ffi->lock_owner;
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
"%"PRIu64": FLUSH %p", finh->unique, fd);
- fuse_resolve_and_resume (state, fuse_flush_resume);
+ FUSE_FOP (state, fuse_err_cbk, GF_FOP_FLUSH,
+ flush, fd);
return;
}
-int
-fuse_internal_release (xlator_t *this, fd_t *fd)
-{
- //This is a place holder function to prevent "xlator does not implement
- //release_cbk" Warning log.
- //Actual release happens as part of fuse_release which gets executed
- //when kernel fuse sends it.
- return 0;
-}
static void
fuse_release (xlator_t *this, fuse_in_header_t *finh, void *msg)
{
- struct fuse_release_in *fri = msg;
- fd_t *activefd = 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 *fd = NULL;
+ int do_flush = 0;
+
+ fuse_state_t *state = NULL;
GET_STATE (this, finh, state);
fd = FH_TO_FD (fri->fh);
state->fd = fd;
- priv = this->private;
+#ifdef GF_LINUX_HOST_OS
+ /* This is an ugly Linux specific hack, relying on subtle
+ * implementation details.
+ *
+ * The self-heal algorithm of replicate relies on being
+ * notified by means of a flush fop whenever a consumer
+ * of a file is done with that file. If this happens
+ * from userspace by means of close(2) or process termination,
+ * the kernel sends us a FLUSH message which we can handle with
+ * the flush fop (nb. this mechanism itself is Linux specific!!).
+ *
+ * However, if it happens from a kernel context, we get no FLUSH,
+ * just the final RELEASE when all references to the file are gone.
+ * We try to guess that this is the case by checking if the last FLUSH
+ * on the file was just the previous message. If not, we conjecture
+ * that this release is from a kernel context and call the flush fop
+ * here.
+ *
+ * Note #1: we check the above condition by means of looking at
+ * the "unique" values of the FUSE messages, relying on which is
+ * a big fat NO NO NO in any sane code.
+ *
+ * Note #2: there is no guarantee against false positives (in theory
+ * it's possible that the scheduler arranges an unrelated FUSE message
+ * in between FLUSH and RELEASE, although it seems to be unlikely), but
+ * extra flushes are not a problem.
+ *
+ * Note #3: cf. Bug #223.
+ */
- fuse_log_eh (this, "RELEASE(): %"PRIu64":, fd: %p, gfid: %s",
- finh->unique, fd, uuid_utoa (fd->inode->gfid));
+ if (fd && fd->flush_unique + 1 != finh->unique)
+ do_flush = 1;
+#endif
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64": RELEASE %p", finh->unique, state->fd);
-
- ret = fd_ctx_del (fd, this, &val);
- if (!ret) {
- fdctx = (fuse_fd_ctx_t *)(unsigned long)val;
- if (fdctx) {
- activefd = fdctx->activefd;
- if (activefd) {
- fd_unref (activefd);
- }
-
- GF_FREE (fdctx);
- }
- }
- fd_unref (fd);
+ "%"PRIu64": RELEASE %p%s", finh->unique, fd,
+ do_flush ? " (FLUSH implied)" : "");
- state->fd = NULL;
+ if (do_flush) {
+ state->lk_owner = (uint64_t)-1;
+ FUSE_FOP (state, fuse_err_cbk, GF_FOP_FLUSH, flush, fd);
+ fd_unref (fd);
+ } else {
+ fd_unref (fd);
- gf_fdptr_put (priv->fdtable, fd);
+ send_fuse_err (this, finh, 0);
- send_fuse_err (this, finh, 0);
+ free_state (state);
+ }
- 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);
-}
static void
fuse_fsync (xlator_t *this, fuse_in_header_t *finh, void *msg)
@@ -2473,103 +2089,77 @@ 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);
+
+ /* fsync_flags: 1 means "datasync" (no defines for this) */
+ FUSE_FOP (state, fuse_fsync_cbk, GF_FOP_FSYNC,
+ fsync, fd, fsi->fsync_flags & 1);
- 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;
- fuse_fd_ctx_t *fdctx = NULL;
- priv = state->this->private;
+static void
+fuse_opendir (xlator_t *this, fuse_in_header_t *finh, void *msg)
+{
+ /*
+ struct fuse_open_in *foi = msg;
+ */
- 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,
- state->resolve.op_errno);
- free_fuse_state (state);
- return;
- }
+ fuse_state_t *state = NULL;
+ fd_t *fd = NULL;
+ int32_t ret = -1;
- fd = fd_create (state->loc.inode, state->finh->pid);
- if (fd == NULL) {
+ 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 fd creation failed",
- state->finh->unique);
- send_fuse_err (state->this, state->finh, ENOMEM);
- free_fuse_state (state);
- }
+ "%"PRIu64": OPENDIR %s (fuse_loc_fill() failed)",
+ finh->unique, state->loc.path);
- fdctx = fuse_fd_ctx_check_n_create (state->this, fd);
- if (fdctx == NULL) {
- gf_log ("glusterfs-fuse", GF_LOG_WARNING,
- "%"PRIu64": OPENDIR creation of fdctx failed",
- state->finh->unique);
- fd_unref (fd);
- send_fuse_err (state->this, state->finh, ENOMEM);
- free_fuse_state (state);
+ send_fuse_err (this, finh, ENOENT);
+ free_state (state);
return;
}
- state->fd = fd_ref (fd);
- state->fd_no = gf_fd_unused_get (priv->fdtable, fd);
+ fd = fd_create (state->loc.inode, finh->pid);
+ state->fd = fd;
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64": OPENDIR %s", state->finh->unique,
+ "%"PRIu64": OPENDIR %s", 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)
-{
- /*
- struct fuse_open_in *foi = 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_opendir_resume);
-}
unsigned char
-d_type_from_stat (struct iatt *buf)
+d_type_from_stat (struct stat *buf)
{
unsigned char d_type;
- if (IA_ISLNK (buf->ia_type)) {
+ if (S_ISLNK (buf->st_mode)) {
d_type = DT_LNK;
- } else if (IA_ISDIR (buf->ia_type)) {
+ } else if (S_ISDIR (buf->st_mode)) {
d_type = DT_DIR;
- } else if (IA_ISFIFO (buf->ia_type)) {
+ } else if (S_ISFIFO (buf->st_mode)) {
d_type = DT_FIFO;
- } else if (IA_ISSOCK (buf->ia_type)) {
+ } else if (S_ISSOCK (buf->st_mode)) {
d_type = DT_SOCK;
- } else if (IA_ISCHR (buf->ia_type)) {
+ } else if (S_ISCHR (buf->st_mode)) {
d_type = DT_CHR;
- } else if (IA_ISBLK (buf->ia_type)) {
+ } else if (S_ISBLK (buf->st_mode)) {
d_type = DT_BLK;
- } else if (IA_ISREG (buf->ia_type)) {
+ } else if (S_ISREG (buf->st_mode)) {
d_type = DT_REG;
} else {
@@ -2579,25 +2169,20 @@ d_type_from_stat (struct iatt *buf)
return d_type;
}
+
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;
- size_t size = 0;
- size_t max_size = 0;
+ int size = 0;
char *buf = NULL;
gf_dirent_t *entry = NULL;
struct fuse_dirent *fde = NULL;
- fuse_private_t *priv = NULL;
state = frame->root->state;
finh = state->finh;
- priv = state->this->private;
-
- fuse_log_eh_fop(this, state, frame, op_ret, op_errno);
if (op_ret < 0) {
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
@@ -2613,23 +2198,11 @@ fuse_readdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
frame->root->unique, op_ret, state->size, state->off);
list_for_each_entry (entry, &entries->list, list) {
- size_t fde_size = FUSE_DIRENT_ALIGN (FUSE_NAME_OFFSET +
- strlen (entry->d_name));
- max_size += fde_size;
-
- if (max_size > state->size) {
- /* we received too many entries to fit in the reply */
- max_size -= fde_size;
- break;
- }
+ size += FUSE_DIRENT_ALIGN (FUSE_NAME_OFFSET +
+ strlen (entry->d_name));
}
- if (max_size == 0) {
- send_fuse_data (this, finh, 0, 0);
- goto out;
- }
-
- buf = GF_CALLOC (1, max_size, gf_fuse_mt_char);
+ buf = CALLOC (1, size);
if (!buf) {
gf_log ("glusterfs-fuse", GF_LOG_DEBUG,
"%"PRIu64": READDIR => -1 (%s)", frame->root->unique,
@@ -2641,36 +2214,24 @@ fuse_readdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
size = 0;
list_for_each_entry (entry, &entries->list, list) {
fde = (struct fuse_dirent *)(buf + size);
- gf_fuse_fill_dirent (entry, fde, priv->enable_ino32);
+ fde->ino = entry->d_ino;
+ fde->off = entry->d_off;
+ fde->namelen = strlen (entry->d_name);
+ strncpy (fde->name, entry->d_name, fde->namelen);
size += FUSE_DIRENT_SIZE (fde);
-
- if (size == max_size)
- break;
}
send_fuse_data (this, finh, buf, size);
- /* TODO: */
- /* gf_link_inodes_from_dirent (this, state->fd->inode, entries); */
-
out:
- free_fuse_state (state);
+ free_state (state);
STACK_DESTROY (frame->root);
- GF_FREE (buf);
+ if (buf)
+ FREE (buf);
return 0;
}
-void
-fuse_readdir_resume (fuse_state_t *state)
-{
- gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64": READDIR (%p, size=%"GF_PRI_SIZET", offset=%"PRId64")",
- 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);
-}
static void
fuse_readdir (xlator_t *this, fuse_in_header_t *finh, void *msg)
@@ -2686,264 +2247,37 @@ 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);
-}
-
-#if FUSE_KERNEL_MINOR_VERSION >= 20
-static int
-fuse_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)
-{
- fuse_state_t *state = NULL;
- fuse_in_header_t *finh = NULL;
- size_t max_size = 0;
- size_t size = 0;
- char *buf = NULL;
- gf_dirent_t *entry = NULL;
- struct fuse_direntplus *fde = NULL;
- struct fuse_entry_out *feo = NULL;
- fuse_private_t *priv = NULL;
-
- state = frame->root->state;
- finh = state->finh;
- priv = this->private;
-
- if (op_ret < 0) {
- gf_log ("glusterfs-fuse", GF_LOG_WARNING,
- "%"PRIu64": READDIRP => -1 (%s)", frame->root->unique,
- strerror (op_errno));
-
- send_fuse_err (this, finh, op_errno);
- goto out;
- }
-
- gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64": READDIRP => %d/%"GF_PRI_SIZET",%"PRId64,
- frame->root->unique, op_ret, state->size, state->off);
-
- list_for_each_entry (entry, &entries->list, list) {
- size_t fdes = FUSE_DIRENT_ALIGN (FUSE_NAME_OFFSET_DIRENTPLUS +
- strlen (entry->d_name));
- max_size += fdes;
-
- if (max_size > state->size) {
- /* we received too many entries to fit in the reply */
- max_size -= fdes;
- break;
- }
- }
-
- if (max_size == 0) {
- send_fuse_data (this, finh, 0, 0);
- goto out;
- }
-
- buf = GF_CALLOC (1, max_size, gf_fuse_mt_char);
- if (!buf) {
- gf_log ("glusterfs-fuse", GF_LOG_DEBUG,
- "%"PRIu64": READDIRP => -1 (%s)", frame->root->unique,
- strerror (ENOMEM));
- send_fuse_err (this, finh, ENOMEM);
- goto out;
- }
-
- size = 0;
- list_for_each_entry (entry, &entries->list, list) {
- inode_t *linked_inode;
-
- fde = (struct fuse_direntplus *)(buf + size);
- feo = &fde->entry_out;
-
- if (priv->enable_ino32)
- fde->dirent.ino = GF_FUSE_SQUASH_INO(entry->d_ino);
- else
- fde->dirent.ino = entry->d_ino;
-
- fde->dirent.off = entry->d_off;
- fde->dirent.type = entry->d_type;
- fde->dirent.namelen = strlen (entry->d_name);
- strncpy (fde->dirent.name, entry->d_name, fde->dirent.namelen);
- size += FUSE_DIRENTPLUS_SIZE (fde);
-
- if (!entry->inode)
- goto next_entry;
-
- entry->d_stat.ia_blksize = this->ctx->page_size;
- gf_fuse_stat2attr (&entry->d_stat, &feo->attr, priv->enable_ino32);
-
- linked_inode = inode_link (entry->inode, state->fd->inode,
- entry->d_name, &entry->d_stat);
- if (!linked_inode)
- goto next_entry;
-
- inode_lookup (linked_inode);
-
- feo->nodeid = inode_to_fuse_nodeid (linked_inode);
-
- fuse_inode_set_need_lookup (linked_inode, this);
-
- inode_unref (linked_inode);
-
- feo->entry_valid =
- calc_timeout_sec (priv->entry_timeout);
- feo->entry_valid_nsec =
- calc_timeout_nsec (priv->entry_timeout);
- feo->attr_valid =
- calc_timeout_sec (priv->attribute_timeout);
- feo->attr_valid_nsec =
- calc_timeout_nsec (priv->attribute_timeout);
-
-next_entry:
- if (size == max_size)
- break;
- }
-
- send_fuse_data (this, finh, buf, size);
-out:
- free_fuse_state (state);
- STACK_DESTROY (frame->root);
- GF_FREE (buf);
- return 0;
-
-}
-
-void
-fuse_readdirp_resume (fuse_state_t *state)
-{
- gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64": READDIRP (%p, size=%"GF_PRI_SIZET", offset=%"PRId64")",
- state->finh->unique, state->fd, state->size, state->off);
-
- FUSE_FOP (state, fuse_readdirp_cbk, GF_FOP_READDIRP,
- readdirp, state->fd, state->size, state->off, state->xdata);
-}
-
-
-static void
-fuse_readdirp (xlator_t *this, fuse_in_header_t *finh, void *msg)
-{
- struct fuse_read_in *fri = msg;
-
- fuse_state_t *state = NULL;
- fd_t *fd = NULL;
-
- GET_STATE (this, finh, state);
- state->size = fri->size;
- state->off = fri->offset;
- fd = FH_TO_FD (fri->fh);
- state->fd = fd;
-
- fuse_resolve_fd_init (state, &state->resolve, fd);
-
- fuse_resolve_and_resume (state, fuse_readdirp_resume);
-}
-#endif
-
-#if FUSE_KERNEL_MINOR_VERSION >= 19
-#ifdef FALLOC_FL_KEEP_SIZE
-static int
-fuse_fallocate_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)
-{
- return fuse_err_cbk(frame, cookie, this, op_ret, op_errno, xdata);
-}
+ gf_log ("glusterfs-fuse", GF_LOG_TRACE,
+ "%"PRIu64": READDIR (%p, size=%"PRIu32", offset=%"PRId64")",
+ finh->unique, fd, fri->size, fri->offset);
-static void
-fuse_fallocate_resume(fuse_state_t *state)
-{
- gf_log("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64": FALLOCATE (%p, flags=%d, size=%zu, offset=%"PRId64")",
- state->finh->unique, state->fd, state->flags, state->size,
- state->off);
-
- if (state->flags & FALLOC_FL_PUNCH_HOLE)
- FUSE_FOP(state, fuse_fallocate_cbk, GF_FOP_DISCARD, discard,
- state->fd, state->off, state->size, state->xdata);
- else
- FUSE_FOP(state, fuse_fallocate_cbk, GF_FOP_FALLOCATE, fallocate,
- state->fd, (state->flags & FALLOC_FL_KEEP_SIZE),
- state->off, state->size, state->xdata);
+ FUSE_FOP (state, fuse_readdir_cbk, GF_FOP_READDIR,
+ readdir, fd, fri->size, fri->offset);
}
-static void
-fuse_fallocate(xlator_t *this, fuse_in_header_t *finh, void *msg)
-{
- struct fuse_fallocate_in *ffi = msg;
- fuse_state_t *state = NULL;
-
- GET_STATE(this, finh, state);
- state->off = ffi->offset;
- state->size = ffi->length;
- state->flags = ffi->mode;
- state->fd = FH_TO_FD(ffi->fh);
-
- fuse_resolve_fd_init(state, &state->resolve, state->fd);
- fuse_resolve_and_resume(state, fuse_fallocate_resume);
-}
-#endif /* FALLOC_FL_KEEP_SIZE */
-#endif /* FUSE minor version >= 19 */
static void
fuse_releasedir (xlator_t *this, fuse_in_header_t *finh, void *msg)
{
- struct fuse_release_in *fri = msg;
- fd_t *activefd = 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;
+
+ fuse_state_t *state = NULL;
GET_STATE (this, finh, state);
state->fd = FH_TO_FD (fri->fh);
- priv = this->private;
-
- fuse_log_eh (this, "RELEASEDIR (): %"PRIu64": fd: %p, gfid: %s",
- finh->unique, state->fd,
- uuid_utoa (state->fd->inode->gfid));
-
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
"%"PRIu64": RELEASEDIR %p", finh->unique, state->fd);
- ret = fd_ctx_del (state->fd, this, &val);
-
- if (!ret) {
- fdctx = (fuse_fd_ctx_t *)(unsigned long)val;
- if (fdctx) {
- activefd = fdctx->activefd;
- if (activefd) {
- fd_unref (activefd);
- }
-
- GF_FREE (fdctx);
- }
- }
-
fd_unref (state->fd);
- gf_fdptr_put (priv->fdtable, state->fd);
-
- state->fd = NULL;
-
send_fuse_err (this, finh, 0);
- free_fuse_state (state);
+ free_state (state);
return;
}
-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);
-
-}
static void
fuse_fsyncdir (xlator_t *this, fuse_in_header_t *finh, void *msg)
@@ -2958,18 +2292,16 @@ 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);
+ FUSE_FOP (state, fuse_err_cbk, GF_FOP_FSYNCDIR,
+ fsyncdir, fd, fsi->fsync_flags & 1);
return;
}
+
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;
@@ -2979,10 +2311,19 @@ fuse_statfs_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
state = frame->root->state;
priv = this->private;
finh = state->finh;
-
- fuse_log_eh (this, "op_ret: %d, op_errno: %d, %"PRIu64": %s()",
- op_ret, op_errno, frame->root->unique,
- gf_fop_list[frame->root->op]);
+ /*
+ 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 st_blksize
+ * so the df with old coreutils this wont work :(
+ */
if (op_ret == 0) {
#ifndef GF_DARWIN_HOST_OS
@@ -3017,83 +2358,37 @@ fuse_statfs_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
send_fuse_err (this, finh, op_errno);
}
- free_fuse_state (state);
+ free_state (state);
STACK_DESTROY (frame->root);
return 0;
}
-void
-fuse_statfs_resume (fuse_state_t *state)
-{
- if (!state->loc.inode) {
- gf_log ("glusterfs-fuse", GF_LOG_WARNING,
- "%"PRIu64": STATFS (%s) resolution fail",
- state->finh->unique, uuid_utoa (state->resolve.gfid));
-
- send_fuse_err (state->this, state->finh,
- state->resolve.op_errno);
- free_fuse_state (state);
- return;
- }
-
- gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64": STATFS", state->finh->unique);
-
- FUSE_FOP (state, fuse_statfs_cbk, GF_FOP_STATFS,
- statfs, &state->loc, state->xdata);
-}
-
static void
fuse_statfs (xlator_t *this, fuse_in_header_t *finh, void *msg)
{
fuse_state_t *state = NULL;
+ int32_t ret = -1;
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) {
+ 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": 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,
- state->resolve.op_errno);
- free_fuse_state (state);
+ "%"PRIu64": STATFS (fuse_loc_fill() fail)",
+ finh->unique);
+
+ send_fuse_err (this, finh, ENOENT);
+ free_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": STATFS", finh->unique);
- FUSE_FOP (state, fuse_setxattr_cbk, GF_FOP_SETXATTR,
- setxattr, &state->loc, state->xattr, state->flags,
- state->xdata);
- }
+ FUSE_FOP (state, fuse_statfs_cbk, GF_FOP_STATFS,
+ statfs, &state->loc);
}
@@ -3103,118 +2398,59 @@ 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;
-
- GET_STATE (this, finh, state);
-#ifdef GF_DARWIN_HOST_OS
- if (fsi->position) {
- gf_log ("glusterfs-fuse", GF_LOG_WARNING,
- "%"PRIu64": SETXATTR %s/%"PRIu64" (%s):"
- "refusing positioned setxattr",
- finh->unique, state->loc.path, finh->nodeid, name);
- send_fuse_err (this, finh, EINVAL);
+#ifdef DISABLE_POSIX_ACL
+ if (!strncmp (name, "system.", 7)) {
+ send_fuse_err (this, finh, EOPNOTSUPP);
FREE (finh);
return;
}
#endif
- if (fuse_ignore_xattr_set (priv, name)) {
- (void) send_fuse_err (this, finh, 0);
- return;
- }
-
- if (!priv->acl) {
- if ((strcmp (name, POSIX_ACL_ACCESS_XATTR) == 0) ||
- (strcmp (name, POSIX_ACL_DEFAULT_XATTR) == 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;
- }
- }
-
- /* Check if the command is for changing the log
- level of process or specific xlator */
- ret = is_gf_log_command (this, name, value);
- if (ret >= 0) {
- send_fuse_err (this, finh, ret);
- GF_FREE (finh);
- 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);
-#if FUSE_KERNEL_MINOR_VERSION >= 11
- fuse_invalidate_entry (this, finh->nodeid);
-#endif
- 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);
- if (!strcmp (GFID_XATTR_KEY, name) || !strcmp (GF_XATTR_VOL_ID_KEY, name)) {
- send_fuse_err (this, finh, EPERM);
- GF_FREE (finh);
+ send_fuse_err (this, finh, ENOENT);
+ free_state (state);
return;
}
- state->size = fsi->size;
-
- fuse_resolve_inode_init (state, &state->resolve, finh->nodeid);
-
- 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);
- send_fuse_err (this, finh, ENOMEM);
- free_fuse_state (state);
- return;
- }
-
- ret = fuse_flip_xattr_ns (priv, name, &newkey);
- if (ret) {
- send_fuse_err (this, finh, ENOMEM);
- free_fuse_state (state);
+ free_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;
+ gf_log ("glusterfs-fuse", GF_LOG_TRACE,
+ "%"PRIu64": SETXATTR %s/%"PRIu64" (%s)", finh->unique,
+ state->loc.path, finh->nodeid, name);
- fuse_resolve_and_resume (state, fuse_setxattr_resume);
+ FUSE_FOP (state, fuse_err_cbk, GF_FOP_SETXATTR,
+ setxattr, &state->loc, state->dict, fsi->flags);
return;
}
-
static void
send_fuse_xattr (xlator_t *this, fuse_in_header_t *finh, const char *value,
size_t size, size_t expected)
@@ -3238,44 +2474,55 @@ 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(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 = "";
fuse_state_t *state = NULL;
fuse_in_header_t *finh = NULL;
+ int32_t dummy_ret = 0;
data_t *value_data = NULL;
+ fuse_private_t *priv = NULL;
+ struct stat st;
+ char *file = NULL;
+ int32_t fd = -1;
int ret = -1;
int32_t len = 0;
- int32_t len_next = 0;
+ data_pair_t *trav = NULL;
+ priv = this->private;
+ ret = op_ret;
state = frame->root->state;
finh = state->finh;
+ dummy_ret = 0;
- fuse_log_eh_fop(this, state, frame, op_ret, op_errno);
+#ifdef GF_DARWIN_HOST_OS
+ /* This is needed in MacFuse, where MacOSX Finder needs some specific
+ * keys to be supported from FS
+ */
- if (op_ret >= 0) {
+ if (state->name) {
+ if (!dict) {
+ dict = get_new_dict ();
+ need_to_free_dict = 1;
+ }
+ dummy_ret = gf_compat_getxattr (state->name, dict);
+ if (dummy_ret != -1)
+ ret = dummy_ret;
+ } else {
+ if (!dict) {
+ dict = get_new_dict ();
+ need_to_free_dict = 1;
+ }
+ dummy_ret = gf_compat_listxattr (ret, dict, state->size);
+ if (dummy_ret != -1)
+ ret = dummy_ret;
+ }
+#endif /* DARWIN */
+
+ if (ret >= 0) {
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
"%"PRIu64": %s() %s => %d", frame->root->unique,
gf_fop_list[frame->root->op], state->loc.path, op_ret);
@@ -3285,260 +2532,144 @@ fuse_xattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
/* if callback for getxattr */
value_data = dict_get (dict, state->name);
if (value_data) {
-
ret = value_data->len; /* Don't return the value for '\0' */
value = value_data->data;
send_fuse_xattr (this, finh, value, ret, state->size);
/* if(ret >...)...else if...else */
+ } else if (!strcmp (state->name, "user.glusterfs-booster-volfile")) {
+ if (!priv->volfile) {
+ memset (&st, 0, sizeof (st));
+ fd = fileno (this->ctx->specfp);
+ ret = fstat (fd, &st);
+ if (ret != 0) {
+ gf_log (this->name,
+ GF_LOG_ERROR,
+ "fstat on fd (%d) failed (%s)", fd, strerror (errno));
+ send_fuse_err (this, finh, ENODATA);
+ }
+
+ priv->volfile_size = st.st_size;
+ file = priv->volfile = CALLOC (1, priv->volfile_size);
+ ret = lseek (fd, 0, SEEK_SET);
+ while ((ret = read (fd, file, GF_UNIT_KB)) > 0) {
+ file += ret;
+ }
+ }
+
+ send_fuse_xattr (this, finh, priv->volfile,
+ priv->volfile_size, state->size);
+ /* if(ret >...)...else if...else */
+ } else if (!strcmp (state->name, "user.glusterfs-booster-path")) {
+ send_fuse_xattr (this, finh, state->loc.path,
+ strlen (state->loc.path) + 1, state->size);
+ } else if (!strcmp (state->name, "user.glusterfs-booster-mount")) {
+ send_fuse_xattr (this, finh, priv->mount_point,
+ strlen (priv->mount_point) + 1, state->size);
} else {
send_fuse_err (this, finh, ENODATA);
} /* 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
- */
- len = dict_keys_join (NULL, 0, dict, fuse_filter_xattr);
- if (len < 0)
- goto out;
-
+ trav = dict->members_list;
+ while (trav) {
+ len += strlen (trav->key) + 1;
+ trav = trav->next;
+ } /* while(trav) */
value = alloca (len + 1);
- if (!value)
- goto out;
-
- len_next = dict_keys_join (value, len, dict,
- fuse_filter_xattr);
- if (len_next != len)
- gf_log (THIS->name, GF_LOG_ERROR,
- "sizes not equal %d != %d",
- len, len_next);
-
+ ERR_ABORT (value);
+ len = 0;
+ trav = dict->members_list;
+ while (trav) {
+ 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);
} /* if(state->name)...else */
} else {
/* if failure - no need to check if listxattr or getxattr */
- if (op_errno != ENODATA && op_errno != ENOATTR) {
- if (op_errno == ENOTSUP) {
- GF_LOG_OCCASIONALLY (gf_fuse_xattr_enotsup_log,
- "glusterfs-fuse",
- GF_LOG_ERROR,
- "extended attribute not "
- "supported by the backend "
- "storage");
- } else {
+ if (op_errno != ENODATA) {
+ if (op_errno == ENOTSUP)
+ {
+ gf_fuse_xattr_enotsup_log++;
+ if (!(gf_fuse_xattr_enotsup_log % GF_UNIVERSAL_ANSWER))
+ gf_log ("glusterfs-fuse", GF_LOG_ERROR,
+ "extended attribute not "
+ "supported by the backend "
+ "storage");
+ }
+ else
+ {
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
- "%"PRIu64": %s(%s) %s => -1 (%s)",
+ "%"PRIu64": %s() %s => -1 (%s)",
frame->root->unique,
- gf_fop_list[frame->root->op], state->name,
+ gf_fop_list[frame->root->op],
state->loc.path, strerror (op_errno));
}
} else {
- gf_log ("glusterfs-fuse", GF_LOG_DEBUG,
- "%"PRIu64": %s(%s) %s => -1 (%s)",
+ gf_log ("glusterfs-fuse", GF_LOG_WARNING,
+ "%"PRIu64": %s() %s => -1 (%s)",
frame->root->unique,
- gf_fop_list[frame->root->op], state->name,
- state->loc.path, strerror (op_errno));
+ gf_fop_list[frame->root->op], state->loc.path,
+ strerror (op_errno));
} /* if(op_errno!= ENODATA)...else */
send_fuse_err (this, finh, op_errno);
} /* if(op_ret>=0)...else */
-out:
if (need_to_free_dict)
dict_unref (dict);
- free_fuse_state (state);
+ free_state (state);
STACK_DESTROY (frame->root);
return 0;
}
-void
-fuse_getxattr_resume (fuse_state_t *state)
-{
- char *value = NULL;
-
- 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,
- state->resolve.op_errno);
- 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->name &&
- (strcmp (state->name, VIRTUAL_GFID_XATTR_KEY) == 0)) {
- /* send glusterfs gfid in binary form */
-
- value = GF_CALLOC (16 + 1, sizeof(char),
- gf_common_mt_char);
- if (!value) {
- send_fuse_err (state->this, state->finh, ENOMEM);
- goto internal_out;
- }
- memcpy (value, state->loc.inode->gfid, 16);
-
- send_fuse_xattr (THIS, state->finh, value, 16, state->size);
- GF_FREE (value);
- internal_out:
- free_fuse_state (state);
- return;
- }
-
- if (state->name &&
- (strcmp (state->name, VIRTUAL_GFID_XATTR_KEY_STR) == 0)) {
- /* transform binary gfid to canonical form */
-
- value = GF_CALLOC (UUID_CANONICAL_FORM_LEN + 1, sizeof(char),
- gf_common_mt_char);
- if (!value) {
- send_fuse_err (state->this, state->finh, ENOMEM);
- goto internal_out1;
- }
- uuid_utoa_r (state->loc.inode->gfid, value);
-
- send_fuse_xattr (THIS, state->finh, value,
- UUID_CANONICAL_FORM_LEN, state->size);
- GF_FREE (value);
- internal_out1:
- free_fuse_state (state);
- return;
- }
-
-
- 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);
-
- FUSE_FOP (state, fuse_xattr_cbk, GF_FOP_GETXATTR,
- getxattr, &state->loc, state->name, state->xdata);
- }
-}
-
-
static void
fuse_getxattr (xlator_t *this, fuse_in_header_t *finh, void *msg)
{
- struct fuse_getxattr_in *fgxi = msg;
- char *name = (char *)(fgxi + 1);
- fuse_state_t *state = NULL;
- struct fuse_private *priv = NULL;
- int rv = 0;
- int op_errno = EINVAL;
- char *newkey = NULL;
-
- priv = this->private;
- GET_STATE (this, finh, state);
+ struct fuse_getxattr_in *fgxi = msg;
+ char *name = (char *)(fgxi + 1);
-#ifdef GF_DARWIN_HOST_OS
- if (fgxi->position) {
- /* position can be used only for
- * resource fork queries which we
- * don't support anyway... so handling
- * it separately is just sort of a
- * matter of aesthetics, not strictly
- * necessary.
- */
+ fuse_state_t *state = NULL;
+ int32_t ret = -1;
- gf_log ("glusterfs-fuse", GF_LOG_WARNING,
- "%"PRIu64": GETXATTR %s/%"PRIu64" (%s):"
- "refusing positioned getxattr",
- finh->unique, state->loc.path, finh->nodeid, name);
- op_errno = EINVAL;
- goto err;
+#ifdef DISABLE_POSIX_ACL
+ if (!strncmp (name, "system.", 7)) {
+ send_fuse_err (this, finh, ENODATA);
+ FREE (finh);
+ return;
}
#endif
- if (!priv->acl) {
- if ((strcmp (name, POSIX_ACL_ACCESS_XATTR) == 0) ||
- (strcmp (name, POSIX_ACL_DEFAULT_XATTR) == 0)) {
- op_errno = ENOTSUP;
- goto err;
- }
- }
-
- if (!priv->selinux) {
- if (strncmp (name, "security.", 9) == 0) {
- op_errno = ENODATA;
- goto err;
- }
- }
-
- fuse_resolve_inode_init (state, &state->resolve, finh->nodeid);
-
- rv = fuse_flip_xattr_ns (priv, name, &newkey);
- if (rv) {
- op_errno = ENOMEM;
- goto err;
- }
-
+ GET_STATE (this, finh, state);
state->size = fgxi->size;
- state->name = newkey;
-
- fuse_resolve_and_resume (state, fuse_getxattr_resume);
+ state->name = strdup (name);
- return;
- err:
- send_fuse_err (this, finh, op_errno);
- free_fuse_state (state);
- return;
-}
-
-
-void
-fuse_listxattr_resume (fuse_state_t *state)
-{
- if (!state->loc.inode) {
+ 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
- "resolution failed", state->finh->unique,
- uuid_utoa (state->resolve.gfid), state->finh->nodeid);
+ "%"PRIu64": GETXATTR %s/%"PRIu64" (%s) (fuse_loc_fill() failed)",
+ finh->unique, state->loc.path, finh->nodeid, name);
- send_fuse_err (state->this, state->finh,
- state->resolve.op_errno);
- free_fuse_state (state);
+ send_fuse_err (this, finh, ENOENT);
+ free_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);
+ gf_log ("glusterfs-fuse", GF_LOG_TRACE,
+ "%"PRIu64": GETXATTR %s/%"PRIu64" (%s)", finh->unique,
+ state->loc.path, finh->nodeid, name);
- 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);
+ FUSE_FOP (state, fuse_xattr_cbk, GF_FOP_GETXATTR,
+ getxattr, &state->loc, name);
- FUSE_FOP (state, fuse_xattr_cbk, GF_FOP_GETXATTR,
- getxattr, &state->loc, NULL, state->xdata);
- }
+ return;
}
@@ -3546,90 +2677,64 @@ 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);
-
state->size = fgxi->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": LISTXATTR %s/%"PRIu64" (fuse_loc_fill() failed)",
+ finh->unique, state->loc.path, finh->nodeid);
- 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,
- state->resolve.op_errno);
- free_fuse_state (state);
+ send_fuse_err (this, finh, ENOENT);
+ free_state (state);
return;
}
-#ifdef GF_TEST_FFOP
- state->fd = fd_lookup (state->loc.inode, state->finh->pid);
-#endif /* GF_TEST_FFOP */
+ gf_log ("glusterfs-fuse", GF_LOG_TRACE,
+ "%"PRIu64": LISTXATTR %s/%"PRIu64, finh->unique,
+ state->loc.path, finh->nodeid);
- 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_xattr_cbk, GF_FOP_GETXATTR,
+ getxattr, &state->loc, NULL);
- 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);
-
- FUSE_FOP (state, fuse_err_cbk, GF_FOP_REMOVEXATTR,
- removexattr, &state->loc, state->name, state->xdata);
- }
+ return;
}
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) || !strcmp (GF_XATTR_VOL_ID_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);
- free_fuse_state (state);
+ send_fuse_err (this, finh, ENOENT);
+ free_state (state);
return;
}
- state->name = newkey;
+ gf_log ("glusterfs-fuse", GF_LOG_TRACE,
+ "%"PRIu64": REMOVEXATTR %s/%"PRIu64" (%s)", finh->unique,
+ state->loc.path, finh->nodeid, name);
+
+ FUSE_FOP (state, fuse_err_cbk, GF_FOP_REMOVEXATTR,
+ removexattr, &state->loc, name);
- fuse_resolve_and_resume (state, fuse_removexattr_resume);
return;
}
@@ -3638,16 +2743,13 @@ 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 flock *lock)
{
fuse_state_t *state = NULL;
state = frame->root->state;
struct fuse_lk_out flo = {{0, }, };
- fuse_log_eh_fop(this, state, frame, op_ret, op_errno);
-
if (op_ret == 0) {
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
"%"PRIu64": ERR => 0", frame->root->unique);
@@ -3679,24 +2781,13 @@ fuse_getlk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
send_fuse_err (this, state->finh, op_errno);
}
- free_fuse_state (state);
+ free_state (state);
STACK_DESTROY (frame->root);
return 0;
}
-void
-fuse_getlk_resume (fuse_state_t *state)
-{
- gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"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);
-}
-
-
static void
fuse_getlk (xlator_t *this, fuse_in_header_t *finh, void *msg)
{
@@ -3704,19 +2795,20 @@ fuse_getlk (xlator_t *this, fuse_in_header_t *finh, void *msg)
fuse_state_t *state = NULL;
fd_t *fd = NULL;
+ struct flock lock = {0, };
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);
+ convert_fuse_file_lock (&fli->lk, &lock);
state->lk_owner = fli->owner;
- fuse_resolve_and_resume (state, fuse_getlk_resume);
+ gf_log ("glusterfs-fuse", GF_LOG_TRACE,
+ "%"PRIu64": GETLK %p", finh->unique, fd);
+
+ FUSE_FOP (state, fuse_getlk_cbk, GF_FOP_LK,
+ lk, fd, F_GETLK, &lock);
return;
}
@@ -3724,24 +2816,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 flock *lock)
{
- uint32_t op = 0;
fuse_state_t *state = NULL;
state = frame->root->state;
- op = state->finh->opcode;
-
- fuse_log_eh_fop(this, state, frame, op_ret, op_errno);
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) {
@@ -3755,11 +2838,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)",
@@ -3769,26 +2853,13 @@ fuse_setlk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
send_fuse_err (this, state->finh, op_errno);
}
- free_fuse_state (state);
+ free_state (state);
STACK_DESTROY (frame->root);
return 0;
}
-void
-fuse_setlk_resume (fuse_state_t *state)
-{
- gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64": SETLK%s %p", state->finh->unique,
- state->finh->opcode == FUSE_SETLK ? "" : "W", state->fd);
-
- 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);
-}
-
-
static void
fuse_setlk (xlator_t *this, fuse_in_header_t *finh, void *msg)
{
@@ -3796,77 +2867,40 @@ fuse_setlk (xlator_t *this, fuse_in_header_t *finh, void *msg)
fuse_state_t *state = NULL;
fd_t *fd = NULL;
+ struct flock lock = {0, };
fd = FH_TO_FD (fli->fh);
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);
+ convert_fuse_file_lock (&fli->lk, &lock);
state->lk_owner = fli->owner;
- fuse_resolve_and_resume (state, fuse_setlk_resume);
+ gf_log ("glusterfs-fuse", GF_LOG_TRACE,
+ "%"PRIu64": SETLK%s %p", finh->unique,
+ finh->opcode == FUSE_SETLK ? "" : "W", fd);
+
+ FUSE_FOP (state, fuse_setlk_cbk, GF_FOP_LK,
+ lk, fd, finh->opcode == FUSE_SETLK ? F_SETLK : F_SETLKW,
+ &lock);
return;
}
-#if FUSE_KERNEL_MINOR_VERSION >= 11
-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;
-}
-#endif
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;
-#if FUSE_KERNEL_MINOR_VERSION >= 9
- int pfd[2] = {0,};
- pthread_t messenger;
-#endif
+ struct fuse_init_in *fini = msg;
+
+ struct fuse_init_out fino;
+ fuse_private_t *priv = NULL;
+ int ret;
priv = this->private;
- if (priv->init_recvd) {
+ if (!priv->first_call) {
gf_log ("glusterfs-fuse", GF_LOG_ERROR,
"got INIT after first message");
@@ -3874,8 +2908,6 @@ fuse_init (xlator_t *this, fuse_in_header_t *finh, void *msg)
goto out;
}
- priv->init_recvd = 1;
-
if (fini->major != FUSE_KERNEL_VERSION) {
gf_log ("glusterfs-fuse", GF_LOG_ERROR,
"unsupported FUSE protocol version %d.%d",
@@ -3891,121 +2923,27 @@ 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 >= 17
- if (fini->minor >= 17)
- fino.flags |= FUSE_FLOCK_LOCKS;
-#endif
-#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) {
- /* no need for direct I/O mode by default if big writes are supported */
- if (priv->direct_io_mode == 2)
- 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 = gf_thread_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.
+ * no need for direct I/O mode by default if big writes are
+ * supported
*/
- 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 (priv->direct_io_mode == 2) {
+ priv->direct_io_mode = 0;
}
- }
+ fino.flags |= FUSE_BIG_WRITES;
+ }
if (fini->minor >= 13) {
- fino.max_background = priv->background_qlen;
- fino.congestion_threshold = priv->congestion_threshold;
+ /* these values seemed to work fine during testing */
+
+ fino.max_background = 64;
+ fino.congestion_threshold = 48;
}
if (fini->minor < 9)
*priv->msg0_len_p = sizeof(*finh) + FUSE_COMPAT_WRITE_IN_SIZE;
- if (priv->use_readdirp) {
- if (fini->flags & FUSE_DO_READDIRPLUS)
- fino.flags |= FUSE_DO_READDIRPLUS;
- }
-#endif
- if (priv->fopen_keep_cache == 2) {
- /* If user did not explicitly set --fopen-keep-cache[=off],
- then check if kernel support FUSE_AUTO_INVAL_DATA and ...
- */
-#if FUSE_KERNEL_MINOR_VERSION >= 20
- if (fini->flags & FUSE_AUTO_INVAL_DATA) {
- /* ... enable fopen_keep_cache mode if supported.
- */
- gf_log ("glusterfs-fuse", GF_LOG_DEBUG, "Detected "
- "support for FUSE_AUTO_INVAL_DATA. Enabling "
- "fopen_keep_cache automatically.");
- fino.flags |= FUSE_AUTO_INVAL_DATA;
- priv->fopen_keep_cache = 1;
- } else
-#endif
- {
-
- gf_log ("glusterfs-fuse", GF_LOG_DEBUG, "No support "
- "for FUSE_AUTO_INVAL_DATA. Disabling "
- "fopen_keep_cache.");
- /* ... else disable. */
- priv->fopen_keep_cache = 0;
- }
- } else if (priv->fopen_keep_cache == 1) {
- /* If user explicitly set --fopen-keep-cache[=on],
- then enable FUSE_AUTO_INVAL_DATA if possible.
- */
-#if FUSE_KERNEL_MINOR_VERSION >= 20
- if (fini->flags & FUSE_AUTO_INVAL_DATA) {
- gf_log ("glusterfs-fuse", GF_LOG_DEBUG, "fopen_keep_cache "
- "is explicitly set. Enabling FUSE_AUTO_INVAL_DATA");
- fino.flags |= FUSE_AUTO_INVAL_DATA;
- } else
-#endif
- {
- gf_log ("glusterfs-fuse", GF_LOG_WARNING, "fopen_keep_cache "
- "is explicitly set. Support for "
- "FUSE_AUTO_INVAL_DATA is missing");
- }
- }
-
-#if FUSE_KERNEL_MINOR_VERSION >= 22
- if (fini->flags & FUSE_ASYNC_DIO)
- fino.flags |= FUSE_ASYNC_DIO;
-#endif
ret = send_fuse_obj (this, finh, &fino);
if (ret == 0)
gf_log ("glusterfs-fuse", GF_LOG_INFO,
@@ -4021,7 +2959,7 @@ fuse_init (xlator_t *this, fuse_in_header_t *finh, void *msg)
}
out:
- GF_FREE (finh);
+ FREE (finh);
}
@@ -4030,7 +2968,7 @@ fuse_enosys (xlator_t *this, fuse_in_header_t *finh, void *msg)
{
send_fuse_err (this, finh, ENOSYS);
- GF_FREE (finh);
+ FREE (finh);
}
@@ -4039,26 +2977,20 @@ fuse_destroy (xlator_t *this, fuse_in_header_t *finh, void *msg)
{
send_fuse_err (this, finh, 0);
- GF_FREE (finh);
+ FREE (finh);
}
-
-
-struct fuse_first_lookup {
- pthread_mutex_t mutex;
- pthread_cond_t cond;
- char fin;
-};
+static fuse_handler_t *fuse_ops[FUSE_713_OP_HIGH];
int
fuse_first_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)
+ inode_t *inode, struct stat *buf, dict_t *xattr,
+ struct stat *postparent)
{
- struct fuse_first_lookup *stub = NULL;
+ fuse_private_t *priv = NULL;
- stub = frame->local;
+ priv = this->private;
if (op_ret == 0) {
gf_log (this->name, GF_LOG_TRACE,
@@ -4067,14 +2999,13 @@ fuse_first_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
gf_log (this->name, GF_LOG_DEBUG,
"first lookup on root failed.");
}
-
- pthread_mutex_lock (&stub->mutex);
+ STACK_DESTROY (frame->root);
+ pthread_mutex_lock (&priv->first_call_mutex);
{
- stub->fin = 1;
- pthread_cond_broadcast (&stub->cond);
+ priv->first_call = 0;
+ pthread_cond_broadcast (&priv->first_call_cond);
}
- pthread_mutex_unlock (&stub->mutex);
-
+ pthread_mutex_unlock (&priv->first_call_mutex);
return 0;
}
@@ -4082,731 +3013,112 @@ fuse_first_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int
fuse_first_lookup (xlator_t *this)
{
- fuse_private_t *priv = NULL;
- loc_t loc = {0, };
- call_frame_t *frame = NULL;
- xlator_t *xl = NULL;
- dict_t *dict = NULL;
- struct fuse_first_lookup stub;
- uuid_t gfid;
- int ret;
+ fuse_private_t *priv = NULL;
+ loc_t loc;
+ call_frame_t *frame = NULL;
+ xlator_t *xl = NULL;
+ dict_t *dict = NULL;
priv = this->private;
+ pthread_cond_init (&priv->first_call_cond, NULL);
+ pthread_mutex_init (&priv->first_call_mutex, NULL);
+
loc.path = "/";
loc.name = "";
- loc.inode = fuse_ino_to_inode (1, this);
- uuid_copy (loc.gfid, loc.inode->gfid);
+ loc.ino = 1;
+ loc.inode = fuse_ino_to_inode (1, this->itable);
loc.parent = NULL;
dict = dict_new ();
frame = create_frame (this, this->ctx->pool);
- frame->root->type = GF_OP_TYPE_FOP;
-
- xl = priv->active_subvol;
-
- pthread_mutex_init (&stub.mutex, NULL);
- pthread_cond_init (&stub.cond, NULL);
- stub.fin = 0;
-
- frame->local = &stub;
-
- 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'");
+ frame->root->type = GF_OP_TYPE_FOP_REQUEST;
+ xl = this->children->xlator;
STACK_WIND (frame, fuse_first_lookup_cbk, xl, xl->fops->lookup,
&loc, dict);
dict_unref (dict);
- pthread_mutex_lock (&stub.mutex);
+ pthread_mutex_lock (&priv->first_call_mutex);
{
- while (!stub.fin) {
- pthread_cond_wait (&stub.cond, &stub.mutex);
+ while (priv->first_call) {
+ pthread_cond_wait (&priv->first_call_cond,
+ &priv->first_call_mutex);
}
}
- pthread_mutex_unlock (&stub.mutex);
-
- pthread_mutex_destroy (&stub.mutex);
- pthread_cond_destroy (&stub.cond);
-
- frame->local = NULL;
- STACK_DESTROY (frame->root);
+ pthread_mutex_unlock (&priv->first_call_mutex);
return 0;
}
-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)) {
- ret = -EINVAL;
- goto out;
- }
-
- if (loc->inode == NULL) {
- loc->inode = inode_new (xl->itable);
- if (loc->inode == NULL) {
- ret = -ENOMEM;
- goto out;
- }
- }
-
- uuid_copy (loc->gfid, gfid);
-
- xattr_req = dict_new ();
- if (xattr_req == NULL) {
- ret = -ENOMEM;
- 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_open (xlator_t *this, fd_t *basefd, fd_t *oldfd,
- xlator_t *old_subvol, xlator_t *new_subvol)
-{
- loc_t loc = {0, };
- fd_t *newfd = NULL, *old_activefd = NULL;
- fuse_fd_ctx_t *basefd_ctx = NULL;
- fuse_fd_ctx_t *newfd_ctx = NULL;
- int ret = 0, flags = 0;
-
- ret = inode_path (basefd->inode, NULL, (char **)&loc.path);
- if (ret < 0) {
- gf_log ("glusterfs-fuse", GF_LOG_WARNING,
- "cannot construct path of gfid (%s) failed"
- "(old-subvolume:%s-%d new-subvolume:%s-%d)",
- uuid_utoa (basefd->inode->gfid),
- old_subvol->name, old_subvol->graph->id,
- new_subvol->name, new_subvol->graph->id);
- goto out;
- }
-
- uuid_copy (loc.gfid, basefd->inode->gfid);
-
- loc.inode = inode_find (new_subvol->itable, basefd->inode->gfid);
-
- if (loc.inode == NULL) {
- ret = fuse_nameless_lookup (new_subvol, basefd->inode->gfid,
- &loc);
- if (ret < 0) {
- gf_log ("glusterfs-fuse", GF_LOG_WARNING,
- "name-less lookup of gfid (%s) failed (%s)"
- "(old-subvolume:%s-%d new-subvolume:%s-%d)",
- uuid_utoa (basefd->inode->gfid),
- strerror (-ret),
- old_subvol->name, old_subvol->graph->id,
- new_subvol->name, new_subvol->graph->id);
- ret = -1;
- goto out;
- }
-
- }
-
- basefd_ctx = fuse_fd_ctx_get (this, basefd);
- GF_VALIDATE_OR_GOTO ("glusterfs-fuse", basefd_ctx, out);
-
- newfd = fd_create (loc.inode, basefd->pid);
- if (newfd == NULL) {
- gf_log ("glusterfs-fuse", GF_LOG_WARNING,
- "cannot create new fd, hence not migrating basefd "
- "(ptr:%p inode-gfid:%s) "
- "(old-subvolume:%s-%d new-subvolume:%s-%d)", basefd,
- uuid_utoa (loc.inode->gfid),
- old_subvol->name, old_subvol->graph->id,
- new_subvol->name, new_subvol->graph->id);
- ret = -1;
- goto out;
- }
-
- newfd->flags = basefd->flags;
- if (newfd->lk_ctx)
- fd_lk_ctx_unref (newfd->lk_ctx);
-
- newfd->lk_ctx = fd_lk_ctx_ref (oldfd->lk_ctx);
-
- newfd_ctx = fuse_fd_ctx_check_n_create (this, newfd);
- GF_VALIDATE_OR_GOTO ("glusterfs-fuse", newfd_ctx, out);
-
- if (IA_ISDIR (basefd->inode->ia_type)) {
- ret = syncop_opendir (new_subvol, &loc, newfd);
- } else {
- flags = basefd->flags & ~(O_CREAT | O_EXCL | O_TRUNC);
- ret = syncop_open (new_subvol, &loc, flags, newfd);
- }
-
- if (ret < 0) {
- gf_log ("glusterfs-fuse", GF_LOG_WARNING,
- "open on basefd (ptr:%p inode-gfid:%s) failed (%s)"
- "(old-subvolume:%s-%d new-subvolume:%s-%d)", basefd,
- uuid_utoa (basefd->inode->gfid), strerror (-ret),
- old_subvol->name, old_subvol->graph->id,
- new_subvol->name, new_subvol->graph->id);
- ret = -1;
- goto out;
- }
-
- fd_bind (newfd);
-
- LOCK (&basefd->lock);
- {
- if (basefd_ctx->activefd != NULL) {
- old_activefd = basefd_ctx->activefd;
- }
-
- basefd_ctx->activefd = newfd;
- }
- UNLOCK (&basefd->lock);
-
- if (old_activefd != NULL) {
- fd_unref (old_activefd);
- }
-
- gf_log ("glusterfs-fuse", GF_LOG_INFO,
- "migrated basefd (%p) to newfd (%p) (inode-gfid:%s)"
- "(old-subvolume:%s-%d new-subvolume:%s-%d)", basefd, newfd,
- uuid_utoa (basefd->inode->gfid),
- old_subvol->name, old_subvol->graph->id,
- new_subvol->name, new_subvol->graph->id);
-
- ret = 0;
-
-out:
- loc_wipe (&loc);
-
- return ret;
-}
-
-int
-fuse_migrate_locks (xlator_t *this, fd_t *basefd, fd_t *oldfd,
- xlator_t *old_subvol, xlator_t *new_subvol)
-{
- int ret = -1;
- dict_t *lockinfo = NULL;
- void *ptr = NULL;
- fd_t *newfd = NULL;
- fuse_fd_ctx_t *basefd_ctx = NULL;
-
-
- if (!oldfd->lk_ctx || fd_lk_ctx_empty (oldfd->lk_ctx))
- return 0;
-
- basefd_ctx = fuse_fd_ctx_get (this, basefd);
- GF_VALIDATE_OR_GOTO ("glusterfs-fuse", basefd_ctx, out);
-
- LOCK (&basefd->lock);
- {
- newfd = fd_ref (basefd_ctx->activefd);
- }
- UNLOCK (&basefd->lock);
-
- ret = syncop_fgetxattr (old_subvol, oldfd, &lockinfo,
- GF_XATTR_LOCKINFO_KEY);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_WARNING,
- "getting lockinfo failed while migrating locks"
- "(oldfd:%p newfd:%p inode-gfid:%s)"
- "(old-subvol:%s-%d new-subvol:%s-%d)",
- oldfd, newfd, uuid_utoa (newfd->inode->gfid),
- old_subvol->name, old_subvol->graph->id,
- new_subvol->name, new_subvol->graph->id);
- ret = -1;
- goto out;
- }
-
- ret = dict_get_ptr (lockinfo, GF_XATTR_LOCKINFO_KEY, &ptr);
- if (ptr == NULL) {
- ret = 0;
- gf_log (this->name, GF_LOG_INFO,
- "No lockinfo present on any of the bricks "
- "(oldfd: %p newfd:%p inode-gfid:%s) "
- "(old-subvol:%s-%d new-subvol:%s-%d)",
- oldfd, newfd, uuid_utoa (newfd->inode->gfid),
- old_subvol->name, old_subvol->graph->id,
- new_subvol->name, new_subvol->graph->id);
-
- goto out;
- }
-
- ret = syncop_fsetxattr (new_subvol, newfd, lockinfo, 0);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_WARNING,
- "migrating locks failed (oldfd:%p newfd:%p "
- "inode-gfid:%s) (old-subvol:%s-%d new-subvol:%s-%d)",
- oldfd, newfd, uuid_utoa (newfd->inode->gfid),
- old_subvol->name, old_subvol->graph->id,
- new_subvol->name, new_subvol->graph->id);
- ret = -1;
- goto out;
- }
-
-out:
- if (newfd)
- fd_unref (newfd);
-
- if (lockinfo != NULL) {
- dict_unref (lockinfo);
- }
-
- return ret;
-}
-
-
-int
-fuse_migrate_fd (xlator_t *this, fd_t *basefd, xlator_t *old_subvol,
- xlator_t *new_subvol)
-{
- int ret = -1;
- char create_in_progress = 0;
- fuse_fd_ctx_t *basefd_ctx = NULL;
- fd_t *oldfd = NULL;
-
- basefd_ctx = fuse_fd_ctx_get (this, basefd);
- GF_VALIDATE_OR_GOTO ("glusterfs-fuse", basefd_ctx, out);
-
- LOCK (&basefd->lock);
- {
- oldfd = basefd_ctx->activefd ? basefd_ctx->activefd
- : basefd;
- fd_ref (oldfd);
- }
- UNLOCK (&basefd->lock);
-
- LOCK (&oldfd->inode->lock);
- {
- if (uuid_is_null (oldfd->inode->gfid)) {
- create_in_progress = 1;
- } else {
- create_in_progress = 0;
- }
- }
- UNLOCK (&oldfd->inode->lock);
-
- if (create_in_progress) {
- gf_log ("glusterfs-fuse", GF_LOG_INFO,
- "create call on fd (%p) is in progress "
- "(basefd-ptr:%p basefd-inode.gfid:%s), "
- "hence deferring migration till application does an "
- "fd based operation on this fd"
- "(old-subvolume:%s-%d, new-subvolume:%s-%d)",
- oldfd, basefd, uuid_utoa (basefd->inode->gfid),
- old_subvol->name, old_subvol->graph->id,
- new_subvol->name, new_subvol->graph->id);
-
- ret = 0;
- goto out;
- }
-
- if (oldfd->inode->table->xl == old_subvol) {
- ret = syncop_fsync (old_subvol, oldfd, 0);
- if (ret < 0) {
- gf_log ("glusterfs-fuse", GF_LOG_WARNING,
- "syncop_fsync failed (%s) on fd (%p)"
- "(basefd:%p basefd-inode.gfid:%s) "
- "(old-subvolume:%s-%d new-subvolume:%s-%d)",
- strerror (-ret), oldfd, basefd,
- uuid_utoa (basefd->inode->gfid),
- old_subvol->name, old_subvol->graph->id,
- new_subvol->name, new_subvol->graph->id);
- ret = -1;
- }
- } else {
- gf_log ("glusterfs-fuse", GF_LOG_WARNING,
- "basefd (ptr:%p inode-gfid:%s) was not "
- "migrated during previous graph switch"
- "(old-subvolume:%s-%d new-subvolume: %s-%d)", basefd,
- basefd->inode->gfid,
- old_subvol->name, old_subvol->graph->id,
- new_subvol->name, new_subvol->graph->id);
- }
-
- ret = fuse_migrate_fd_open (this, basefd, oldfd, old_subvol,
- new_subvol);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_WARNING, "open corresponding to "
- "basefd (ptr:%p inode-gfid:%s) in new graph failed "
- "(old-subvolume:%s-%d new-subvolume:%s-%d)", basefd,
- uuid_utoa (basefd->inode->gfid), old_subvol->name,
- old_subvol->graph->id, new_subvol->name,
- new_subvol->graph->id);
- goto out;
- }
-
- ret = fuse_migrate_locks (this, basefd, oldfd, old_subvol,
- new_subvol);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_WARNING,
- "migrating locks from old-subvolume (%s-%d) to "
- "new-subvolume (%s-%d) failed (inode-gfid:%s oldfd:%p "
- "basefd:%p)", old_subvol->name, old_subvol->graph->id,
- new_subvol->name, new_subvol->graph->id,
- uuid_utoa (basefd->inode->gfid), oldfd, basefd);
-
- }
-out:
- if (ret < 0) {
- gf_log (this->name, GF_LOG_WARNING, "migration of basefd "
- "(ptr:%p inode-gfid:%s) failed"
- "(old-subvolume:%s-%d new-subvolume:%s-%d)", basefd,
- oldfd ? uuid_utoa (oldfd->inode->gfid) : NULL,
- old_subvol->name, old_subvol->graph->id,
- new_subvol->name, new_subvol->graph->id);
- }
-
- fd_unref (oldfd);
-
- 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_get (this, fd);
- if (fdctx) {
- LOCK (&fd->lock);
- {
- if (ret < 0) {
- fdctx->migration_failed = 1;
- } else {
- fdctx->migration_failed = 0;
- }
- }
- UNLOCK (&fd->lock);
- }
- }
-
- 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;
-
- priv = this->private;
-
- pthread_mutex_lock (&priv->sync_mutex);
- {
- if (!priv->next_graph)
- goto unlock;
-
- old_subvol = priv->active_subvol;
- new_subvol = 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);
- if (ret != 0) {
- gf_log (this->name, GF_LOG_DEBUG,
- "timedwait returned non zero value "
- "ret: %d errno: %d", ret, errno);
- break;
- }
- }
- }
-unlock:
- pthread_mutex_unlock (&priv->sync_mutex);
-
- if (need_first_lookup) {
- 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 = NULL;
- 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;
+ int ret = -1;
+
+ struct timeval now;
+ struct timespec timeout;
this = data;
priv = this->private;
- fuse_ops = priv->fuse_ops;
THIS = this;
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");
+ pthread_mutex_lock (&priv->child_up_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_value) {
+
+ ret = pthread_cond_timedwait (&priv->child_up_cond,
+ &priv->child_up_mutex,
+ &timeout);
+ if (ret != 0)
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.
- */
+ }
+ }
+ pthread_mutex_unlock (&priv->child_up_mutex);
- if (priv->init_recvd)
- fuse_graph_sync (this);
+ gf_log (this->name, GF_LOG_DEBUG,
+ " pthread_cond_timedout returned non zero value"
+ " ret: %d errno: %d", ret, errno);
- /* 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 */
+ for (;;) {
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
* rest via realloc).
*/
- iov_in[0].iov_base = GF_CALLOC (1, msg0_size,
- gf_fuse_mt_iov_base);
+ iov_in[0].iov_base = CALLOC (1, msg0_size);
if (!iobuf || !iov_in[0].iov_base) {
gf_log (this->name, GF_LOG_ERROR,
"Out of memory");
if (iobuf)
iobuf_unref (iobuf);
- GF_FREE (iov_in[0].iov_base);
+ FREE (iov_in[0].iov_base);
sleep (10);
continue;
}
@@ -4815,55 +3127,39 @@ fuse_thread_proc (void *data)
res = readv (priv->fd, iov_in, 2);
+ if (priv->first_call) {
+ if (priv->first_call > 1) {
+ priv->first_call--;
+ } else {
+ fuse_first_lookup (this);
+ }
+ }
+
if (res == -1) {
if (errno == ENODEV || errno == EBADF) {
- gf_log ("glusterfs-fuse", GF_LOG_DEBUG,
+ gf_log ("glusterfs-fuse", GF_LOG_NORMAL,
"terminating upon getting %s when "
"reading /dev/fuse",
errno == ENODEV ? "ENODEV" : "EBADF");
- fuse_log_eh (this, "glusterfs-fuse: terminating"
- " upon getting %s when "
- "reading /dev/fuse",
- errno == ENODEV ? "ENODEV":
- "EBADF");
+
break;
}
if (errno != EINTR) {
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
"read from /dev/fuse returned -1 (%s)",
strerror (errno));
- fuse_log_eh (this, "glusterfs-fuse: read from "
- "/dev/fuse returned -1 (%s)",
- strerror (errno));
}
goto cont_err;
}
if (res < sizeof (finh)) {
- gf_log ("glusterfs-fuse", GF_LOG_WARNING,
- "short read on /dev/fuse");
- fuse_log_eh (this, "glusterfs-fuse: short read on "
- "/dev/fuse");
+ gf_log ("glusterfs-fuse", GF_LOG_WARNING, "short read on /dev/fuse");
break;
}
finh = (fuse_in_header_t *)iov_in[0].iov_base;
-
- if (res != finh->len
-#ifdef GF_DARWIN_HOST_OS
- /* work around fuse4bsd/MacFUSE msg size miscalculation bug,
- * that is, payload size is not taken into account for
- * buffered writes
- */
- && !(finh->opcode == FUSE_WRITE &&
- finh->len == sizeof(*finh) + sizeof(struct fuse_write_in) &&
- res == finh->len + ((struct fuse_write_in *)(finh + 1))->size)
-#endif
- ) {
- gf_log ("glusterfs-fuse", GF_LOG_WARNING,
- "inconsistent read on /dev/fuse");
- fuse_log_eh (this, "glusterfs-fuse: inconsistent read "
- "on /dev/fuse");
+ if (res != finh->len) {
+ gf_log ("glusterfs-fuse", GF_LOG_WARNING, "inconsistent read on /dev/fuse");
break;
}
@@ -4873,12 +3169,11 @@ fuse_thread_proc (void *data)
msg = iov_in[1].iov_base;
else {
if (res > msg0_size) {
- void *b = GF_REALLOC (iov_in[0].iov_base, res);
- if (b) {
- iov_in[0].iov_base = b;
+ iov_in[0].iov_base =
+ realloc (iov_in[0].iov_base, res);
+ if (iov_in[0].iov_base)
finh = (fuse_in_header_t *)
iov_in[0].iov_base;
- }
else {
gf_log ("glusterfs-fuse", GF_LOG_ERROR,
"Out of memory");
@@ -4895,44 +3190,33 @@ fuse_thread_proc (void *data)
msg = finh + 1;
}
- if (priv->uid_map_root &&
- finh->uid == priv->uid_map_root)
- finh->uid = 0;
-
- if (finh->opcode >= FUSE_OP_HIGH)
- /* turn down MacFUSE specific messages */
- fuse_enosys (this, finh, msg);
- else
- fuse_ops[finh->opcode] (this, finh, msg);
+ fuse_ops[finh->opcode] (this, finh, msg);
iobuf_unref (iobuf);
continue;
cont_err:
iobuf_unref (iobuf);
- GF_FREE (iov_in[0].iov_base);
+ 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);
+ FREE (iov_in[0].iov_base);
if (dict_get (this->options, ZR_MOUNTPOINT_OPT))
mount_point = data_to_str (dict_get (this->options,
ZR_MOUNTPOINT_OPT));
if (mount_point) {
- gf_log (this->name, GF_LOG_INFO,
+ gf_log (this->name, GF_LOG_NORMAL,
"unmounting %s", mount_point);
+ dict_del (this->options, ZR_MOUNTPOINT_OPT);
}
- /* Kill the whole process, not just this thread. */
- kill (getpid(), SIGTERM);
+ raise (SIGTERM);
+
return NULL;
}
-
int32_t
fuse_itable_dump (xlator_t *this)
{
@@ -4942,7 +3226,7 @@ fuse_itable_dump (xlator_t *this)
gf_proc_dump_add_section("xlator.mount.fuse.itable");
inode_table_dump(this->itable, "xlator.mount.fuse.itable");
- return 0;
+ return 0;
}
int32_t
@@ -4960,312 +3244,98 @@ 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",
- (int)private->init_recvd);
- gf_proc_dump_write("strict_volfile_check", "%d",
+ gf_proc_dump_write("xlator.mount.fuse.first_call", "%d",
+ (int)private->first_call);
+ 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);
- gf_proc_dump_write("use_readdirp", "%d", private->use_readdirp);
return 0;
}
-int
-fuse_history_dump (xlator_t *this)
-{
- int ret = -1;
- char key_prefix[GF_DUMP_MAX_BUF_LEN] = {0,};
-
- GF_VALIDATE_OR_GOTO ("fuse", this, out);
- GF_VALIDATE_OR_GOTO (this->name, this->history, out);
- gf_proc_dump_build_key (key_prefix, "xlator.mount.fuse",
- "history");
- gf_proc_dump_add_section (key_prefix);
- eh_dump (this->history, NULL, dump_history_fuse);
-
- ret = 0;
-out:
- return ret;
-}
-
-int
-dump_history_fuse (circular_buffer_t *cb, void *data)
-{
- char *string = NULL;
- struct tm *tm = NULL;
- char timestr[256] = {0,};
-
- string = (char *)cb->data;
- tm = localtime (&cb->tv.tv_sec);
-
- if (tm) {
- strftime (timestr, 256, "%Y-%m-%d %H:%M:%S", tm);
- snprintf (timestr + strlen (timestr), 256 - strlen (timestr),
- ".%"GF_PRI_SUSECONDS, cb->tv.tv_usec);
- gf_proc_dump_write ("TIME", "%s", timestr);
- }
-
- gf_proc_dump_write ("message", "%s\n", string);
-
- return 0;
-}
-
-int
-fuse_graph_setup (xlator_t *this, glusterfs_graph_t *graph)
-{
- inode_table_t *itable = NULL;
- int ret = 0, winds = 0;
- fuse_private_t *priv = NULL;
- glusterfs_graph_t *prev_graph = NULL;
-
- priv = this->private;
-
- /* handle the case of more than one CHILD_UP on same graph */
- if (priv->active_subvol == graph->top)
- return 0; /* This is a valid case */
-
- if (graph->used)
- return 0;
-
- graph->used = 1;
-
- itable = inode_table_new (0, graph->top);
- if (!itable)
- return -1;
-
- ((xlator_t *)graph->top)->itable = itable;
-
- pthread_mutex_lock (&priv->sync_mutex);
- {
- prev_graph = priv->next_graph;
-
- if ((prev_graph != NULL) && (prev_graph->id > graph->id)) {
- /* there was a race and an old graph was initialised
- * before new one.
- */
- prev_graph = graph;
- } else {
- priv->next_graph = graph;
- priv->event_recvd = 0;
-
- pthread_cond_signal (&priv->sync_cond);
- }
-
- if (prev_graph != NULL)
- winds = ((xlator_t *)prev_graph->top)->winds;
- }
- pthread_mutex_unlock (&priv->sync_mutex);
-
- if ((prev_graph != NULL) && (winds == 0)) {
- xlator_notify (prev_graph->top, GF_EVENT_PARENT_DOWN,
- prev_graph->top, NULL);
- }
-
- gf_log ("fuse", GF_LOG_INFO, "switched to graph %d",
- ((graph) ? graph->id : 0));
-
- return ret;
-}
-
-
-int
+int32_t
notify (xlator_t *this, int32_t event, void *data, ...)
{
- int32_t ret = 0;
- fuse_private_t *private = NULL;
- glusterfs_graph_t *graph = NULL;
+ int32_t ret = 0;
+ fuse_private_t *private = NULL;
private = this->private;
- graph = data;
-
- gf_log ("fuse", GF_LOG_DEBUG, "got event %d on graph %d",
- event, ((graph) ? graph->id : 0));
-
switch (event)
{
- case GF_EVENT_GRAPH_NEW:
- break;
-
case GF_EVENT_CHILD_UP:
- case GF_EVENT_CHILD_DOWN:
case GF_EVENT_CHILD_CONNECTING:
{
- if (graph) {
- ret = fuse_graph_setup (this, graph);
- if (ret)
- gf_log (this->name, GF_LOG_WARNING,
- "failed to setup the graph");
+ pthread_mutex_lock (&private->child_up_mutex);
+ {
+ private->child_up_value = 0;
+ pthread_cond_broadcast (&private->child_up_cond);
}
+ pthread_mutex_unlock (&private->child_up_mutex);
- if ((event == GF_EVENT_CHILD_UP)
- || (event == GF_EVENT_CHILD_DOWN)) {
- pthread_mutex_lock (&private->sync_mutex);
- {
- private->event_recvd = 1;
- pthread_cond_broadcast (&private->sync_cond);
- }
- pthread_mutex_unlock (&private->sync_mutex);
- }
+ break;
+ }
- if (!private->fuse_thread_started) {
+ case GF_EVENT_PARENT_UP:
+ {
+ if (!private->fuse_thread_started)
+ {
private->fuse_thread_started = 1;
- ret = gf_thread_create (&private->fuse_thread, NULL,
- fuse_thread_proc, this);
+ ret = pthread_create (&private->fuse_thread, NULL,
+ fuse_thread_proc, this);
+
if (ret != 0) {
- gf_log (this->name, GF_LOG_DEBUG,
+ gf_log ("glusterfs-fuse", GF_LOG_DEBUG,
"pthread_create() failed (%s)",
strerror (errno));
- break;
+
+ /* If fuse thread is not started, that means,
+ its hung, we can't use this process. */
+ raise (SIGTERM);
}
}
+ default_notify (this, GF_EVENT_PARENT_UP, data);
break;
}
-
- case GF_EVENT_AUTH_FAILED:
+ case GF_EVENT_VOLFILE_MODIFIED:
{
- /* Authentication failure is an error and glusterfs should stop */
- gf_log (this->name, GF_LOG_ERROR, "Server authenication failed. Shutting down.");
- fini (this);
- break;
+ gf_log ("fuse", GF_LOG_CRITICAL,
+ "Remote volume file changed, try re-mounting.");
+ if (private->strict_volfile_check) {
+ //fuse_session_remove_chan (private->ch);
+ //fuse_session_destroy (private->se);
+ //fuse_unmount (private->mount_point, private->ch);
+ /* TODO: Above code if works, will be a cleaner way,
+ but for now, lets just achieve what we want */
+ raise (SIGTERM);
+ }
+ break;
}
-
default:
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_fuse_mt_end + 1);
-
- if (ret != 0) {
- gf_log (this->name, GF_LOG_ERROR, "Memory accounting init"
- "failed");
- return ret;
- }
-
- return ret;
-}
-
-
-static fuse_handler_t *fuse_std_ops[FUSE_OP_HIGH] = {
- [FUSE_LOOKUP] = fuse_lookup,
- [FUSE_FORGET] = fuse_forget,
- [FUSE_GETATTR] = fuse_getattr,
- [FUSE_SETATTR] = fuse_setattr,
- [FUSE_READLINK] = fuse_readlink,
- [FUSE_SYMLINK] = fuse_symlink,
- [FUSE_MKNOD] = fuse_mknod,
- [FUSE_MKDIR] = fuse_mkdir,
- [FUSE_UNLINK] = fuse_unlink,
- [FUSE_RMDIR] = fuse_rmdir,
- [FUSE_RENAME] = fuse_rename,
- [FUSE_LINK] = fuse_link,
- [FUSE_OPEN] = fuse_open,
- [FUSE_READ] = fuse_readv,
- [FUSE_WRITE] = fuse_write,
- [FUSE_STATFS] = fuse_statfs,
- [FUSE_RELEASE] = fuse_release,
- [FUSE_FSYNC] = fuse_fsync,
- [FUSE_SETXATTR] = fuse_setxattr,
- [FUSE_GETXATTR] = fuse_getxattr,
- [FUSE_LISTXATTR] = fuse_listxattr,
- [FUSE_REMOVEXATTR] = fuse_removexattr,
- [FUSE_FLUSH] = fuse_flush,
- [FUSE_INIT] = fuse_init,
- [FUSE_OPENDIR] = fuse_opendir,
- [FUSE_READDIR] = fuse_readdir,
- [FUSE_RELEASEDIR] = fuse_releasedir,
- [FUSE_FSYNCDIR] = fuse_fsyncdir,
- [FUSE_GETLK] = fuse_getlk,
- [FUSE_SETLK] = fuse_setlk,
- [FUSE_SETLKW] = fuse_setlk,
- [FUSE_ACCESS] = fuse_access,
- [FUSE_CREATE] = fuse_create,
- /* [FUSE_INTERRUPT] */
- /* [FUSE_BMAP] */
- [FUSE_DESTROY] = fuse_destroy,
- /* [FUSE_IOCTL] */
- /* [FUSE_POLL] */
- /* [FUSE_NOTIFY_REPLY] */
-
-#if FUSE_KERNEL_MINOR_VERSION >= 16
- [FUSE_BATCH_FORGET]= fuse_batch_forget,
-#endif
-
-#if FUSE_KERNEL_MINOR_VERSION >= 19
-#ifdef FALLOC_FL_KEEP_SIZE
- [FUSE_FALLOCATE] = fuse_fallocate,
-#endif /* FALLOC_FL_KEEP_SIZE */
-#endif
-
-#if FUSE_KERNEL_MINOR_VERSION >= 21
- [FUSE_READDIRPLUS] = fuse_readdirp,
-#endif
-};
-
-
-static fuse_handler_t *fuse_dump_ops[FUSE_OP_HIGH];
-
-
-static void
-fuse_dumper (xlator_t *this, fuse_in_header_t *finh, void *msg)
-{
- fuse_private_t *priv = NULL;
- struct iovec diov[3];
- char r = 'R';
- int ret = 0;
-
- priv = this->private;
-
- diov[0].iov_base = &r;
- diov[0].iov_len = 1;
- diov[1].iov_base = finh;
- diov[1].iov_len = sizeof (*finh);
- diov[2].iov_base = msg;
- diov[2].iov_len = finh->len - sizeof (*finh);
-
- pthread_mutex_lock (&priv->fuse_dump_mutex);
- ret = writev (priv->fuse_dump_fd, diov, 3);
- pthread_mutex_unlock (&priv->fuse_dump_mutex);
- if (ret == -1)
- gf_log ("glusterfs-fuse", GF_LOG_ERROR,
- "failed to dump fuse message (R): %s",
- strerror (errno));
-
- priv->fuse_ops0[finh->opcode] (this, finh, msg);
+ return 0;
}
@@ -5275,19 +3345,11 @@ init (xlator_t *this_xl)
int ret = 0;
dict_t *options = NULL;
char *value_string = NULL;
- cmd_args_t *cmd_args = NULL;
char *fsname = NULL;
fuse_private_t *priv = NULL;
struct stat stbuf = {0,};
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;
- gf_boolean_t fopen_keep_cache = _gf_false;
- unsigned long mntflags = 0;
- char *mnt_args = NULL;
- eh_t *event = NULL;
if (this_xl == NULL)
return -1;
@@ -5295,14 +3357,10 @@ 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) {
- this_xl->name = gf_strdup ("fuse");
+ this_xl->name = strdup ("fuse");
if (!this_xl->name) {
gf_log ("glusterfs-fuse", GF_LOG_ERROR,
"Out of memory");
@@ -5312,7 +3370,7 @@ init (xlator_t *this_xl)
xl_name_allocated = 1;
}
- priv = GF_CALLOC (1, sizeof (*priv), gf_fuse_mt_fuse_private_t);
+ priv = CALLOC (1, sizeof (*priv));
if (!priv) {
gf_log ("glusterfs-fuse", GF_LOG_ERROR,
"Out of memory");
@@ -5322,12 +3380,10 @@ 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);
- if (ret == -1 || value_string == NULL) {
+ if (value_string == NULL) {
gf_log ("fuse", GF_LOG_ERROR,
"Mandatory option 'mountpoint' is not specified.");
goto cleanup_exit;
@@ -5358,7 +3414,7 @@ init (xlator_t *this_xl)
ZR_MOUNTPOINT_OPT, value_string);
goto cleanup_exit;
}
- priv->mount_point = gf_strdup (value_string);
+ priv->mount_point = strdup (value_string);
if (!priv->mount_point) {
gf_log ("glusterfs-fuse", GF_LOG_ERROR,
"Out of memory");
@@ -5366,221 +3422,103 @@ init (xlator_t *this_xl)
goto cleanup_exit;
}
- GF_OPTION_INIT (ZR_ATTR_TIMEOUT_OPT, priv->attribute_timeout, double,
- cleanup_exit);
-
- GF_OPTION_INIT (ZR_ENTRY_TIMEOUT_OPT, priv->entry_timeout, double,
- cleanup_exit);
-
- GF_OPTION_INIT (ZR_NEGATIVE_TIMEOUT_OPT, priv->negative_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 ("client-pid", priv->client_pid, int32, cleanup_exit);
- /* have to check & register the presence of client-pid manually */
- priv->client_pid_set = !!dict_get (this_xl->options, "client-pid");
+ ret = dict_get_double (options, "entry-timeout",
+ &priv->entry_timeout);
+ if (ret != 0)
+ priv->entry_timeout = 1.0; /* default */
- GF_OPTION_INIT ("uid-map-root", priv->uid_map_root, uint32,
- cleanup_exit);
priv->direct_io_mode = 2;
ret = dict_get_str (options, ZR_DIRECT_IO_OPT, &value_string);
- if (ret == 0) {
+ if (value_string) {
ret = gf_string2boolean (value_string, &priv->direct_io_mode);
- 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);
-
- GF_OPTION_INIT ("enable-ino32", priv->enable_ino32, bool, cleanup_exit);
-
- GF_OPTION_INIT ("use-readdirp", priv->use_readdirp, bool, cleanup_exit);
-
- priv->fuse_dump_fd = -1;
- ret = dict_get_str (options, "dump-fuse", &value_string);
- if (ret == 0) {
- ret = unlink (value_string);
- if (ret != -1 || errno == ENOENT)
- ret = open (value_string, O_RDWR|O_CREAT|O_EXCL,
- S_IRUSR|S_IWUSR);
- if (ret == -1) {
- gf_log ("glusterfs-fuse", GF_LOG_ERROR,
- "cannot open fuse dump file %s",
- value_string);
-
- goto cleanup_exit;
- }
- priv->fuse_dump_fd = ret;
- }
-
- sync_to_mount = _gf_false;
- ret = dict_get_str (options, "sync-to-mount", &value_string);
- if (ret == 0) {
+ priv->strict_volfile_check = 0;
+ ret = dict_get_str (options, ZR_STRICT_VOLFILE_CHECK, &value_string);
+ if (value_string) {
ret = gf_string2boolean (value_string,
- &sync_to_mount);
- GF_ASSERT (ret == 0);
+ &priv->strict_volfile_check);
}
- priv->fopen_keep_cache = 2;
- if (dict_get (options, "fopen-keep-cache")) {
- GF_OPTION_INIT("fopen-keep-cache", fopen_keep_cache, bool,
- cleanup_exit);
- priv->fopen_keep_cache = fopen_keep_cache;
- }
-
- GF_OPTION_INIT("gid-timeout", priv->gid_cache_timeout, int32,
- cleanup_exit);
-
- GF_OPTION_INIT ("fuse-mountopts", priv->fuse_mountopts, str, 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;
- }
+ fsname = this_xl->ctx->cmd_args.volume_file;
+ fsname = (fsname ? fsname : this_xl->ctx->cmd_args.volfile_server);
+ fsname = (fsname ? fsname : "glusterfs");
- /* default values seemed to work fine during testing */
- GF_OPTION_INIT ("background-qlen", priv->background_qlen, int32,
- cleanup_exit);
- GF_OPTION_INIT ("congestion-threshold", priv->congestion_threshold,
- int32, cleanup_exit);
-
- GF_OPTION_INIT("no-root-squash", priv->no_root_squash, bool,
- cleanup_exit);
- /* change the client_pid to no-root-squash pid only if the
- client is none of defrag process, hadoop access and gsyncd process.
- */
- if (!priv->client_pid_set) {
- if (priv->no_root_squash == _gf_true) {
- priv->client_pid_set = _gf_true;
- priv->client_pid = GF_CLIENT_PID_NO_ROOT_SQUASH;
- }
- }
-
- /* user has set only background-qlen, not congestion-threshold,
- use the fuse kernel driver formula to set congestion. ie, 75% */
- if (dict_get (this_xl->options, "background-qlen") &&
- !dict_get (this_xl->options, "congestion-threshold")) {
- priv->congestion_threshold = (priv->background_qlen * 3) / 4;
- gf_log (this_xl->name, GF_LOG_INFO,
- "setting congestion control as 75%% of "
- "background-queue length (ie, (.75 * %d) = %d",
- priv->background_qlen, priv->congestion_threshold);
- }
-
- /* congestion should not be higher than background queue length */
- if (priv->congestion_threshold > priv->background_qlen) {
- gf_log (this_xl->name, GF_LOG_INFO,
- "setting congestion control same as "
- "background-queue length (%d)",
- priv->background_qlen);
- priv->congestion_threshold = priv->background_qlen;
- }
-
- cmd_args = &this_xl->ctx->cmd_args;
- fsname = cmd_args->volfile;
- if (!fsname && cmd_args->volfile_server) {
- if (cmd_args->volfile_id) {
- fsname = GF_MALLOC (
- strlen (cmd_args->volfile_server) + 1 +
- strlen (cmd_args->volfile_id) + 1,
- gf_fuse_mt_fuse_private_t);
- if (!fsname) {
- gf_log ("glusterfs-fuse", GF_LOG_ERROR,
- "Out of memory");
- goto cleanup_exit;
- }
- fsname_allocated = 1;
- strcpy (fsname, cmd_args->volfile_server);
- strcat (fsname, ":");
- strcat (fsname, cmd_args->volfile_id);
- } else
- fsname = cmd_args->volfile_server;
- }
- 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;
- }
-
- if (priv->read_only)
- mntflags |= MS_RDONLY;
- gf_asprintf (&mnt_args, "%s%s%sallow_other,max_read=131072",
- priv->acl ? "" : "default_permissions,",
- priv->fuse_mountopts ? priv->fuse_mountopts : "",
- priv->fuse_mountopts ? "," : "");
- if (!mnt_args)
- goto cleanup_exit;
+ this_xl->itable = inode_table_new (0, this_xl);
+ if (!this_xl->itable) {
+ gf_log ("glusterfs-fuse", GF_LOG_ERROR,
+ "Out of memory");
- 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, mntflags, 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;
- event = eh_new (FUSE_EVENT_HISTORY_SIZE, _gf_false, NULL);
- if (!event) {
- gf_log (this_xl->name, GF_LOG_ERROR,
- "could not create a new event history");
- goto cleanup_exit;
- }
+ this_xl->ctx->top = this_xl;
+
+ priv->first_call = 2;
+
+ pthread_cond_init (&priv->child_up_cond, NULL);
+ pthread_mutex_init (&priv->child_up_mutex, NULL);
+ priv->child_up_value = 1;
+
+ for (i = 0; i < FUSE_713_OP_HIGH; i++)
+ fuse_ops[i] = fuse_enosys;
+ fuse_ops[FUSE_INIT] = fuse_init;
+ fuse_ops[FUSE_DESTROY] = fuse_destroy;
+ fuse_ops[FUSE_LOOKUP] = fuse_lookup;
+ fuse_ops[FUSE_FORGET] = fuse_forget;
+ fuse_ops[FUSE_GETATTR] = fuse_getattr;
+ fuse_ops[FUSE_SETATTR] = fuse_setattr;
+ fuse_ops[FUSE_OPENDIR] = fuse_opendir;
+ fuse_ops[FUSE_READDIR] = fuse_readdir;
+ fuse_ops[FUSE_RELEASEDIR] = fuse_releasedir;
+ fuse_ops[FUSE_ACCESS] = fuse_access;
+ fuse_ops[FUSE_READLINK] = fuse_readlink;
+ fuse_ops[FUSE_MKNOD] = fuse_mknod;
+ fuse_ops[FUSE_MKDIR] = fuse_mkdir;
+ fuse_ops[FUSE_UNLINK] = fuse_unlink;
+ fuse_ops[FUSE_RMDIR] = fuse_rmdir;
+ fuse_ops[FUSE_SYMLINK] = fuse_symlink;
+ fuse_ops[FUSE_RENAME] = fuse_rename;
+ fuse_ops[FUSE_LINK] = fuse_link;
+ fuse_ops[FUSE_CREATE] = fuse_create;
+ fuse_ops[FUSE_OPEN] = fuse_open;
+ fuse_ops[FUSE_READ] = fuse_readv;
+ fuse_ops[FUSE_WRITE] = fuse_write;
+ fuse_ops[FUSE_FLUSH] = fuse_flush;
+ fuse_ops[FUSE_RELEASE] = fuse_release;
+ fuse_ops[FUSE_FSYNC] = fuse_fsync;
+ fuse_ops[FUSE_FSYNCDIR] = fuse_fsyncdir;
+ fuse_ops[FUSE_STATFS] = fuse_statfs;
+ fuse_ops[FUSE_SETXATTR] = fuse_setxattr;
+ fuse_ops[FUSE_GETXATTR] = fuse_getxattr;
+ fuse_ops[FUSE_LISTXATTR] = fuse_listxattr;
+ fuse_ops[FUSE_REMOVEXATTR] = fuse_removexattr;
+ fuse_ops[FUSE_GETLK] = fuse_getlk;
+ fuse_ops[FUSE_SETLK] = fuse_setlk;
+ fuse_ops[FUSE_SETLKW] = fuse_setlk;
- this_xl->history = event;
-
- 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;
-
- for (i = 0; i < FUSE_OP_HIGH; i++) {
- if (!fuse_std_ops[i])
- fuse_std_ops[i] = fuse_enosys;
- if (!fuse_dump_ops[i])
- fuse_dump_ops[i] = fuse_dumper;
- }
- priv->fuse_ops = fuse_std_ops;
- if (priv->fuse_dump_fd != -1) {
- priv->fuse_ops0 = priv->fuse_ops;
- priv->fuse_ops = fuse_dump_ops;
- }
-
- if (fsname_allocated)
- GF_FREE (fsname);
- GF_FREE (mnt_args);
return 0;
cleanup_exit:
if (xl_name_allocated)
- GF_FREE (this_xl->name);
- if (fsname_allocated)
- GF_FREE (fsname);
+ FREE (this_xl->name);
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);
- GF_FREE (priv);
+ FREE (priv->mount_point);
+ close (priv->fd);
}
- GF_FREE (mnt_args);
+ FREE (priv);
return -1;
}
@@ -5601,120 +3539,46 @@ fini (xlator_t *this_xl)
mount_point = data_to_str (dict_get (this_xl->options,
ZR_MOUNTPOINT_OPT));
if (mount_point != NULL) {
- gf_log (this_xl->name, GF_LOG_INFO,
+ gf_log (this_xl->name, GF_LOG_NORMAL,
"Unmounting '%s'.", mount_point);
- gf_fuse_unmount (mount_point, priv->fd);
- close (priv->fuse_dump_fd);
dict_del (this_xl->options, ZR_MOUNTPOINT_OPT);
+ gf_fuse_unmount (mount_point, priv->fd);
}
- /* Process should terminate once fuse xlator is finished.
- * Required for AUTH_FAILED event.
- */
- kill (getpid (), SIGTERM);
}
-struct xlator_fops fops;
+struct xlator_fops fops = {
+};
struct xlator_cbks cbks = {
- .invalidate = fuse_invalidate,
- .forget = fuse_forget_cbk,
- .release = fuse_internal_release
};
+struct xlator_mops mops = {
+};
struct xlator_dumpops dumpops = {
.priv = fuse_priv_dump,
.inode = fuse_itable_dump,
- .history = fuse_history_dump,
};
struct volume_options options[] = {
{ .key = {"direct-io-mode"},
.type = GF_OPTION_TYPE_BOOL
},
- { .key = {ZR_MOUNTPOINT_OPT, "mount-point"},
- .type = GF_OPTION_TYPE_PATH
+ { .key = {"macfuse-local"},
+ .type = GF_OPTION_TYPE_BOOL
},
- { .key = {ZR_DUMP_FUSE, "fuse-dumpfile"},
+ { .key = {"mountpoint", "mount-point"},
.type = GF_OPTION_TYPE_PATH
},
- { .key = {ZR_ATTR_TIMEOUT_OPT},
- .type = GF_OPTION_TYPE_DOUBLE,
- .default_value = "1.0"
- },
- { .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"
- },
- { .key = {ZR_STRICT_VOLFILE_CHECK},
- .type = GF_OPTION_TYPE_BOOL,
- .default_value = "false"
+ { .key = {"attribute-timeout"},
+ .type = GF_OPTION_TYPE_DOUBLE
},
- { .key = {"client-pid"},
- .type = GF_OPTION_TYPE_INT
+ { .key = {"entry-timeout"},
+ .type = GF_OPTION_TYPE_DOUBLE
},
- { .key = {"uid-map-root"},
- .type = GF_OPTION_TYPE_INT
- },
- { .key = {"sync-to-mount"},
- .type = GF_OPTION_TYPE_BOOL
- },
- { .key = {"read-only"},
+ { .key = {"strict-volfile-check"},
.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 = "2"
- },
- { .key = {"acl"},
- .type = GF_OPTION_TYPE_BOOL,
- .default_value = "false"
- },
- { .key = {"selinux"},
- .type = GF_OPTION_TYPE_BOOL,
- .default_value = "false"
- },
- { .key = {"enable-ino32"},
- .type = GF_OPTION_TYPE_BOOL,
- .default_value = "false"
- },
- { .key = {"background-qlen"},
- .type = GF_OPTION_TYPE_INT,
- .default_value = "64",
- .min = 16,
- .max = (64 * GF_UNIT_KB),
- },
- { .key = {"congestion-threshold"},
- .type = GF_OPTION_TYPE_INT,
- .default_value = "48",
- .min = 12,
- .max = (64 * GF_UNIT_KB),
- },
- { .key = {"fuse-mountopts"},
- .type = GF_OPTION_TYPE_STR
- },
- { .key = {"use-readdirp"},
- .type = GF_OPTION_TYPE_BOOL,
- .default_value = "yes"
- },
- { .key = {"no-root-squash"},
- .type = GF_OPTION_TYPE_BOOL,
- .default_value = "false",
- .description = "This is the mount option for disabling the "
- "root squash for the client irrespective of whether the root-squash "
- "option for the volume is set or not. But this option is honoured "
- "only for the trusted clients. For non trusted clients this value "
- "does not have any affect and the volume option for root-squash is "
- "honoured.",
- },
{ .key = {NULL} },
};
diff --git a/xlators/mount/fuse/src/fuse-bridge.h b/xlators/mount/fuse/src/fuse-bridge.h
deleted file mode 100644
index bf1b77be666..00000000000
--- a/xlators/mount/fuse/src/fuse-bridge.h
+++ /dev/null
@@ -1,412 +0,0 @@
-/*
- Copyright (c) 2006-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 _GF_FUSE_BRIDGE_H_
-#define _GF_FUSE_BRIDGE_H_
-
-#include <stdint.h>
-#include <signal.h>
-#include <pthread.h>
-#include <stddef.h>
-#include <dirent.h>
-#include <sys/mount.h>
-#include <sys/time.h>
-#include <fnmatch.h>
-
-#ifndef _CONFIG_H
-#define _CONFIG_H
-#include "config.h"
-#endif /* _CONFIG_H */
-
-#include "glusterfs.h"
-#include "logging.h"
-#include "xlator.h"
-#include "defaults.h"
-#include "common-utils.h"
-#include "statedump.h"
-
-#ifdef GF_DARWIN_HOST_OS
-#include "fuse_kernel_macfuse.h"
-#else
-#include "fuse_kernel.h"
-#endif
-#include "fuse-misc.h"
-#include "fuse-mount.h"
-#include "fuse-mem-types.h"
-
-#include "list.h"
-#include "dict.h"
-#include "syncop.h"
-#include "gidcache.h"
-
-#if defined(GF_LINUX_HOST_OS) || defined(__FreeBSD__) || defined(__NetBSD__)
-#define FUSE_OP_HIGH (FUSE_READDIRPLUS + 1)
-#endif
-#ifdef GF_DARWIN_HOST_OS
-#define FUSE_OP_HIGH (FUSE_DESTROY + 1)
-#endif
-#define GLUSTERFS_XATTR_LEN_MAX 65536
-
-#define MAX_FUSE_PROC_DELAY 1
-
-typedef struct fuse_in_header fuse_in_header_t;
-typedef void (fuse_handler_t) (xlator_t *this, fuse_in_header_t *finh,
- void *msg);
-
-struct fuse_private {
- int fd;
- uint32_t proto_minor;
- char *volfile;
- size_t volfile_size;
- char *mount_point;
- struct iobuf *iobuf;
-
- pthread_t fuse_thread;
- char fuse_thread_started;
-
- uint32_t direct_io_mode;
- 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 init_recvd;
-
- gf_boolean_t strict_volfile_check;
-
- fuse_handler_t **fuse_ops;
- fuse_handler_t **fuse_ops0;
- pthread_mutex_t fuse_dump_mutex;
- int fuse_dump_fd;
-
- glusterfs_graph_t *next_graph;
- xlator_t *active_subvol;
-
- 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;
- int32_t fopen_keep_cache;
- int32_t gid_cache_timeout;
- gf_boolean_t enable_ino32;
- /* This is the mount option for disabling the root-squash for the
- mount irrespective of whether the root-squash option for the
- volume is set or not. But this option is honoured only for
- thr trusted clients. For non trusted clients this value does
- not have any affect and the volume option for root-squash is
- honoured.
- */
- gf_boolean_t no_root_squash;
- fdtable_t *fdtable;
- gid_cache_t gid_cache;
- char *fuse_mountopts;
-
- /* 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];
-
- /* for fuse queue length and congestion threshold */
- int background_qlen;
- int congestion_threshold;
-
- /* for using fuse-kernel readdirp*/
- gf_boolean_t use_readdirp;
-};
-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 FUSE_EVENT_HISTORY_SIZE 1024
-
-#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))
-
-/* Use the same logic as the Linux NFS-client */
-#define GF_FUSE_SQUASH_INO(ino) (((uint32_t) ino) ^ (ino >> 32))
-
-#define FUSE_FOP(state, ret, op_num, fop, args ...) \
- do { \
- xlator_t *xl = NULL; \
- call_frame_t *frame = NULL; \
- \
- xl = state->active_subvol; \
- if (!xl) { \
- gf_log_callingfn (state->this->name, GF_LOG_ERROR, \
- "No active subvolume"); \
- send_fuse_err (state->this, state->finh, ENOENT); \
- free_fuse_state (state); \
- break; \
- } \
- \
- frame = get_call_frame_for_req (state); \
- if (!frame) { \
- /* This is not completely clean, as some \
- * earlier allocations might remain unfreed \
- * if we return at this point, but still \
- * better than trying to go on with a NULL \
- * frame ... \
- */ \
- send_fuse_err (state->this, state->finh, ENOMEM); \
- free_fuse_state (state); \
- /* ideally, need to 'return', but let the */ \
- /* calling function take care of it */ \
- break; \
- } \
- \
- frame->root->state = state; \
- frame->root->op = op_num; \
- frame->op = op_num; \
- \
- if (state->this->history) \
- gf_log_eh ("%"PRIu64", %s, path: (%s), gfid: " \
- "(%s)", frame->root->unique, \
- gf_fop_list[frame->root->op], \
- state->loc.path, \
- (state->fd == NULL)? \
- uuid_utoa (state->loc.gfid): \
- uuid_utoa (state->fd->inode->gfid)); \
- STACK_WIND (frame, ret, xl, xl->fops->fop, args); \
- } while (0)
-
-#define GF_SELECT_LOG_LEVEL(_errno) \
- (((_errno == ENOENT) || (_errno == ESTALE))? \
- GF_LOG_DEBUG)
-
-#define GET_STATE(this, finh, state) \
- do { \
- state = get_fuse_state (this, finh); \
- if (!state) { \
- gf_log ("glusterfs-fuse", \
- GF_LOG_ERROR, \
- "FUSE message unique %"PRIu64" opcode %d:" \
- " state allocation failed", \
- finh->unique, finh->opcode); \
- \
- send_fuse_err (this, finh, ENOMEM); \
- GF_FREE (finh); \
- \
- return; \
- } \
- } while (0)
-
-#define FUSE_ENTRY_CREATE(this, priv, finh, state, fci, op) \
- do { \
- 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, \
- "%s failed to allocate " \
- "a param dictionary", op); \
- send_fuse_err (this, finh, ENOMEM); \
- free_fuse_state (state); \
- return; \
- } \
- state->umask = fci->umask; \
- \
-/* TODO: remove this after 3.4.0 release. keeping it for the \
- sake of backward compatibility with old (3.3.[01]) \
- releases till then. */ \
- ret = dict_set_int16 (state->xdata, "umask", \
- fci->umask); \
- if (ret < 0) { \
- gf_log ("glusterfs-fuse", \
- GF_LOG_WARNING, \
- "%s Failed adding umask"\
- " to request", op); \
- 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, \
- "%s Failed adding mode " \
- "to request", op); \
- dict_destroy (state->xdata); \
- send_fuse_err (this, finh, ENOMEM); \
- free_fuse_state (state); \
- return; \
- } \
- } \
- } while (0)
-
-#define fuse_log_eh_fop(this, state, frame, op_ret, op_errno) \
- do { \
- if (this->history) { \
- if (state->fd) \
- gf_log_eh ("op_ret: %d, op_errno: %d, " \
- "%"PRIu64", %s () => %p, gfid: %s", \
- op_ret, op_errno, \
- frame->root->unique, \
- gf_fop_list[frame->root->op], \
- state->fd, \
- uuid_utoa (state->fd->inode->gfid)); \
- else \
- gf_log_eh ("op_ret: %d, op_errno: %d, " \
- "%"PRIu64", %s () => %s, gfid: %s", \
- op_ret, op_errno, \
- frame->root->unique, \
- gf_fop_list[frame->root->op], \
- state->loc.path, \
- uuid_utoa (state->loc.gfid)); \
- } \
- } while(0)
-
-#define fuse_log_eh(this, args...) \
- do { \
- if (this->history) \
- gf_log_eh(args); \
- } while (0)
-
-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,
- RESOLVE_MAY,
- RESOLVE_DONTCARE,
- RESOLVE_EXACT
-} fuse_resolve_type_t;
-
-
-typedef struct {
- fuse_resolve_type_t type;
- fd_t *fd;
- char *path;
- char *bname;
- u_char gfid[16];
- inode_t *hint;
- u_char pargfid[16];
- inode_t *parhint;
- int op_ret;
- int op_errno;
- loc_t resolve_loc;
-} fuse_resolve_t;
-
-
-typedef struct {
- void *pool;
- xlator_t *this;
- xlator_t *active_subvol;
- inode_table_t *itable;
- loc_t loc;
- loc_t loc2;
- fuse_in_header_t *finh;
- int32_t flags;
- off_t off;
- size_t size;
- unsigned long nlookup;
- fd_t *fd;
- dict_t *xattr;
- dict_t *xdata;
- char *name;
- char is_revalidate;
- gf_boolean_t truncate_needed;
- gf_lock_t lock;
- uint64_t lk_owner;
-
- /* used within resolve_and_resume */
- /* */
- fuse_resolve_t resolve;
- fuse_resolve_t resolve2;
-
- loc_t *loc_now;
- fuse_resolve_t *resolve_now;
-
- void *resume_fn;
-
- int valid;
- 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 {
- uint32_t open_flags;
- char migration_failed;
- fd_t *activefd;
-} fuse_fd_ctx_t;
-
-typedef void (*fuse_resume_fn_t) (fuse_state_t *state);
-
-GF_MUST_CHECK int32_t
-fuse_loc_fill (loc_t *loc, fuse_state_t *state, ino_t ino,
- ino_t par, const char *name);
-call_frame_t *get_call_frame_for_req (fuse_state_t *state);
-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,
- gf_boolean_t enable_ino32);
-void gf_fuse_fill_dirent (gf_dirent_t *entry, struct fuse_dirent *fde,
- gf_boolean_t enable_ino32);
-uint64_t inode_to_fuse_nodeid (inode_t *inode);
-xlator_t *fuse_active_subvol (xlator_t *fuse);
-inode_t *fuse_ino_to_inode (uint64_t ino, xlator_t *fuse);
-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);
-void fuse_fop_resume (fuse_state_t *state);
-int dump_history_fuse (circular_buffer_t *cb, void *data);
-#endif /* _GF_FUSE_BRIDGE_H_ */
diff --git a/xlators/mount/fuse/src/fuse-helpers.c b/xlators/mount/fuse/src/fuse-helpers.c
deleted file mode 100644
index 6dd8107fb83..00000000000
--- a/xlators/mount/fuse/src/fuse-helpers.c
+++ /dev/null
@@ -1,610 +0,0 @@
-/*
- Copyright (c) 2010-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.
-*/
-#ifdef __NetBSD__
-#define _KMEMUSER
-#endif
-
-#if defined(GF_SOLARIS_HOST_OS)
-#include <sys/procfs.h>
-#elif defined(__FreeBSD__)
-#include <sys/types.h>
-#include <libutil.h>
-#include <sys/user.h>
-#elif defined(CTL_KERN)
-#include <sys/sysctl.h>
-#endif
-
-#include "fuse-bridge.h"
-
-static void
-fuse_resolve_wipe (fuse_resolve_t *resolve)
-{
- GF_FREE ((void *)resolve->path);
-
- GF_FREE ((void *)resolve->bname);
-
- if (resolve->fd)
- fd_unref (resolve->fd);
-
- loc_wipe (&resolve->resolve_loc);
-
- if (resolve->hint) {
- inode_unref (resolve->hint);
- resolve->hint = 0;
- }
-
- if (resolve->parhint) {
- inode_unref (resolve->parhint);
- resolve->parhint = 0;
- }
-}
-
-
-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->xattr)
- dict_unref (state->xattr);
-
- if (state->name) {
- GF_FREE (state->name);
- state->name = NULL;
- }
- if (state->fd) {
- fd_unref (state->fd);
- state->fd = (void *)0xfdfdfdfd;
- }
- if (state->finh) {
- GF_FREE (state->finh);
- state->finh = NULL;
- }
-
- 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
- GF_FREE (state);
- state = NULL;
-}
-
-
-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;
-
- 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;
-
- LOCK_INIT (&state->lock);
-
- return state;
-}
-
-
-#define FUSE_MAX_AUX_GROUPS 32 /* We can get only up to 32 aux groups from /proc */
-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;
-
- if (call_stack_alloc_groups (frame->root, FUSE_MAX_AUX_GROUPS) != 0)
- 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 == FUSE_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;
- int ngrps;
-
- 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) {
- ngrps = MIN(prcred->pr_ngroups,
- FUSE_MAX_AUX_GROUPS);
- if (call_stack_alloc_groups (frame->root,
- ngrps) != 0)
- return;
- }
- 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, NGROUPS_MAX);
- if (call_stack_alloc_groups (frame->root, ngroups) != 0)
- return;
- 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 (-1 == priv->gid_cache_timeout) {
- frame->root->ngrps = 0;
- return;
- }
-
- if (!priv->gid_cache_timeout) {
- frame_fill_groups(frame);
- return;
- }
-
- gl = gid_cache_lookup(&priv->gid_cache, frame->root->pid,
- frame->root->uid, frame->root->gid);
- if (gl) {
- if (call_stack_alloc_groups (frame->root, gl->gl_count) != 0)
- return;
- 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_uid = frame->root->uid;
- agl.gl_gid = frame->root->gid;
- 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)
-{
- call_pool_t *pool = NULL;
- fuse_in_header_t *finh = NULL;
- call_frame_t *frame = NULL;
- xlator_t *this = NULL;
- fuse_private_t *priv = NULL;
-
- pool = state->pool;
- finh = state->finh;
- this = state->this;
- priv = this->private;
-
- frame = create_frame (this, pool);
- if (!frame)
- return NULL;
-
- if (finh) {
- frame->root->uid = finh->uid;
- frame->root->gid = finh->gid;
- frame->root->pid = finh->pid;
- 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;
-
- frame->root->type = GF_OP_TYPE_FOP;
-
- return frame;
-}
-
-
-inode_t *
-fuse_ino_to_inode (uint64_t ino, xlator_t *fuse)
-{
- inode_t *inode = NULL;
- xlator_t *active_subvol = NULL;
-
- if (ino == 1) {
- active_subvol = fuse_active_subvol (fuse);
- if (active_subvol)
- inode = active_subvol->itable->root;
- } else {
- inode = (inode_t *) (unsigned long) ino;
- inode_ref (inode);
- }
-
- return inode;
-}
-
-uint64_t
-inode_to_fuse_nodeid (inode_t *inode)
-{
- if (!inode)
- return 0;
- if (__is_root_gfid (inode->gfid))
- return 1;
-
- return (unsigned long) inode;
-}
-
-
-GF_MUST_CHECK int32_t
-fuse_loc_fill (loc_t *loc, fuse_state_t *state, ino_t ino,
- ino_t par, const char *name)
-{
- inode_t *inode = NULL;
- 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() */
-
- if (name) {
- parent = loc->parent;
- if (!parent) {
- parent = fuse_ino_to_inode (par, state->this);
- loc->parent = parent;
- if (parent)
- uuid_copy (loc->pargfid, parent->gfid);
- }
-
- inode = loc->inode;
- if (!inode) {
- inode = inode_grep (parent->table, parent, name);
- loc->inode = inode;
- }
-
- 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);
- goto fail;
- }
- loc->path = path;
- } else {
- inode = loc->inode;
- 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);
- 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");
- goto fail;
- }
- loc->path = path;
- }
-
- if (loc->path) {
- loc->name = strrchr (loc->path, '/');
- if (loc->name)
- loc->name++;
- else
- loc->name = "";
- }
-
- if ((ino != 1) && (parent == NULL)) {
- gf_log ("fuse-bridge", GF_LOG_DEBUG,
- "failed to search parent for %"PRId64"/%s (%"PRId64")",
- (ino_t)par, name, (ino_t)ino);
- ret = -1;
- goto fail;
- }
- 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;
-}
-
-/* courtesy of folly */
-void
-gf_fuse_stat2attr (struct iatt *st, struct fuse_attr *fa, gf_boolean_t enable_ino32)
-{
- if (enable_ino32)
- fa->ino = GF_FUSE_SQUASH_INO(st->ia_ino);
- else
- fa->ino = st->ia_ino;
-
- fa->size = st->ia_size;
- fa->blocks = st->ia_blocks;
- fa->atime = st->ia_atime;
- fa->mtime = st->ia_mtime;
- fa->ctime = st->ia_ctime;
- fa->atimensec = st->ia_atime_nsec;
- fa->mtimensec = st->ia_mtime_nsec;
- fa->ctimensec = st->ia_ctime_nsec;
- fa->mode = st_mode_from_ia (st->ia_prot, st->ia_type);
- fa->nlink = st->ia_nlink;
- fa->uid = st->ia_uid;
- fa->gid = st->ia_gid;
- fa->rdev = makedev (ia_major (st->ia_rdev),
- ia_minor (st->ia_rdev));
-#if FUSE_KERNEL_MINOR_VERSION >= 9
- fa->blksize = st->ia_blksize;
-#endif
-#ifdef GF_DARWIN_HOST_OS
- fa->crtime = (uint64_t)-1;
- fa->crtimensec = (uint32_t)-1;
- fa->flags = 0;
-#endif
-}
-
-void
-gf_fuse_fill_dirent (gf_dirent_t *entry, struct fuse_dirent *fde, gf_boolean_t enable_ino32)
-{
- if (enable_ino32)
- fde->ino = GF_FUSE_SQUASH_INO(entry->d_ino);
- else
- 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);
-}
-
-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 ("*.glusterfs.*.xtime", key, FNM_PERIOD) == 0)
- || (fnmatch ("*.glusterfs.volume-mark",
- key, FNM_PERIOD) == 0)
- || (fnmatch ("*.glusterfs.volume-mark.*",
- key, FNM_PERIOD) == 0)
- || (fnmatch ("glusterfs.gfid.newfile",
- 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
deleted file mode 100644
index 28b4dfbdd04..00000000000
--- a/xlators/mount/fuse/src/fuse-mem-types.h
+++ /dev/null
@@ -1,28 +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 __FUSE_MEM_TYPES_H__
-#define __FUSE_MEM_TYPES_H__
-
-#include "mem-types.h"
-
-enum gf_fuse_mem_types_ {
- gf_fuse_mt_iovec = gf_common_mt_end + 1,
- gf_fuse_mt_fuse_private_t,
- 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
deleted file mode 100644
index 25abe162e6c..00000000000
--- a/xlators/mount/fuse/src/fuse-resolve.c
+++ /dev/null
@@ -1,718 +0,0 @@
-/*
- Copyright (c) 2010-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 "fuse-bridge.h"
-
-static int
-fuse_resolve_all (fuse_state_t *state);
-
-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);
-
-fuse_fd_ctx_t *
-fuse_fd_ctx_get (xlator_t *this, fd_t *fd);
-
-gf_boolean_t fuse_inode_needs_lookup (inode_t *inode, xlator_t *this);
-
-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;
-
- resolve = state->resolve_now;
- loc = state->loc_now;
-
- if (!loc->path) {
- if (loc->parent && resolve->bname) {
- 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,
- "return value inode_path %d", ret);
- loc->path = path;
- }
-
- 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)
-{
- fuse_state_t *state = NULL;
- fuse_resolve_t *resolve = NULL;
- inode_t *link_inode = NULL;
- loc_t *resolve_loc = NULL;
-
- 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_errno = op_errno;
- goto out;
- }
-
- link_inode = inode_link (inode, resolve_loc->parent,
- resolve_loc->name, buf);
-
- state->loc_now->inode = link_inode;
-
-out:
- loc_wipe (resolve_loc);
-
- fuse_resolve_continue (state);
- return 0;
-}
-
-
-int
-fuse_resolve_entry (fuse_state_t *state)
-{
- fuse_resolve_t *resolve = NULL;
- loc_t *resolve_loc = NULL;
-
- resolve = state->resolve_now;
- resolve_loc = &resolve->resolve_loc;
-
- 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);
-
- inode_path (resolve_loc->parent, resolve_loc->name,
- (char **) &resolve_loc->path);
-
- FUSE_FOP (state, fuse_resolve_entry_cbk, GF_FOP_LOOKUP,
- lookup, resolve_loc, NULL);
-
- 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)
-{
- fuse_state_t *state = NULL;
- fuse_resolve_t *resolve = NULL;
- inode_t *link_inode = NULL;
- loc_t *loc_now = NULL;
-
- state = frame->root->state;
- resolve = state->resolve_now;
- loc_now = state->loc_now;
-
- 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 can have 3 values: 0, -1, -2.
- * 0 : resolution was successful.
- * -1: parent inode could not be resolved.
- * -2: entry (inode corresponding to path) could not be resolved
- */
-
- if (uuid_is_null (resolve->gfid)) {
- resolve->op_ret = -1;
- } else {
- resolve->op_ret = -2;
- }
-
- resolve->op_errno = op_errno;
- goto out;
- }
-
- link_inode = inode_link (inode, NULL, NULL, buf);
-
- loc_wipe (&resolve->resolve_loc);
-
- if (!link_inode)
- goto out;
-
- if (!uuid_is_null (resolve->gfid)) {
- loc_now->inode = link_inode;
- goto out;
- }
-
- loc_now->parent = link_inode;
- uuid_copy (loc_now->pargfid, link_inode->gfid);
-
- fuse_resolve_entry (state);
-
- return 0;
-out:
- fuse_resolve_continue (state);
- return 0;
-}
-
-
-int
-fuse_resolve_gfid (fuse_state_t *state)
-{
- fuse_resolve_t *resolve = NULL;
- loc_t *resolve_loc = NULL;
- int ret = 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);
- }
-
- /* inode may already exist in case we are looking up an inode which was
- linked through readdirplus */
- resolve_loc->inode = inode_find (state->itable, resolve_loc->gfid);
- if (!resolve_loc->inode)
- resolve_loc->inode = inode_new (state->itable);
- ret = loc_path (resolve_loc, NULL);
-
- if (ret <= 0) {
- gf_log (THIS->name, GF_LOG_WARNING,
- "failed to get the path for inode %s",
- uuid_utoa (resolve->gfid));
- }
-
- FUSE_FOP (state, fuse_resolve_gfid_cbk, GF_FOP_LOOKUP,
- lookup, resolve_loc, NULL);
-
- 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)
-{
- fuse_resolve_t *resolve = NULL;
- loc_t *loc = NULL;
- inode_t *parent = NULL;
- inode_t *inode = NULL;
-
- resolve = state->resolve_now;
- loc = state->loc_now;
-
- loc->name = resolve->bname;
-
- parent = resolve->parhint;
- if (parent->table == state->itable) {
- if (fuse_inode_needs_lookup (parent, THIS))
- return 1;
-
- /* no graph switches since */
- loc->parent = inode_ref (parent);
- uuid_copy (loc->pargfid, parent->gfid);
- loc->inode = inode_grep (state->itable, parent, loc->name);
-
- /* nodeid for root is 1 and we blindly take the latest graph's
- * table->root as the parhint and because of this there is
- * ambiguity whether the entry should have existed or not, and
- * we took the conservative approach of assuming entry should
- * have been there even though it need not have (bug #804592).
- */
- if ((loc->inode == NULL)
- && __is_root_gfid (parent->gfid)) {
- /* non decisive result - entry missing */
- return -1;
- }
-
- /* decisive result - resolution success */
- return 0;
- }
-
- parent = inode_find (state->itable, resolve->pargfid);
- if (!parent) {
- /* non decisive result - parent missing */
- return 1;
- }
- if (fuse_inode_needs_lookup (parent, THIS)) {
- inode_unref (parent);
- 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;
-}
-
-
-int
-fuse_resolve_parent (fuse_state_t *state)
-{
- int ret = 0;
-
- ret = fuse_resolve_parent_simple (state);
- if (ret > 0) {
- fuse_resolve_gfid (state);
- return 0;
- }
-
- if (ret < 0) {
- fuse_resolve_entry (state);
- return 0;
- }
-
- fuse_resolve_continue (state);
-
- return 0;
-}
-
-
-int
-fuse_resolve_inode_simple (fuse_state_t *state)
-{
- fuse_resolve_t *resolve = NULL;
- loc_t *loc = NULL;
- inode_t *inode = NULL;
-
- resolve = state->resolve_now;
- loc = state->loc_now;
-
- inode = resolve->hint;
- if (inode->table == state->itable)
- inode_ref (inode);
- else
- inode = inode_find (state->itable, resolve->gfid);
-
- if (inode) {
- if (!fuse_inode_needs_lookup (inode, THIS))
- goto found;
- /* inode was linked through readdirplus */
- inode_unref (inode);
- }
-
- return 1;
-found:
- loc->inode = inode;
- return 0;
-}
-
-
-int
-fuse_resolve_inode (fuse_state_t *state)
-{
- int ret = 0;
-
- ret = fuse_resolve_inode_simple (state);
-
- if (ret > 0) {
- fuse_resolve_gfid (state);
- return 0;
- }
-
- fuse_resolve_continue (state);
-
- return 0;
-}
-
-
-int
-fuse_migrate_fd_task (void *data)
-{
- int ret = -1;
- fuse_state_t *state = NULL;
- fd_t *basefd = NULL, *oldfd = NULL;
- fuse_fd_ctx_t *basefd_ctx = NULL;
- xlator_t *old_subvol = NULL;
-
- state = data;
- if (state == NULL) {
- goto out;
- }
-
- basefd = state->fd;
-
- basefd_ctx = fuse_fd_ctx_get (state->this, basefd);
- if (!basefd_ctx)
- goto out;
-
- LOCK (&basefd->lock);
- {
- oldfd = basefd_ctx->activefd ? basefd_ctx->activefd : basefd;
- fd_ref (oldfd);
- }
- UNLOCK (&basefd->lock);
-
- old_subvol = oldfd->inode->table->xl;
-
- ret = fuse_migrate_fd (state->this, basefd, old_subvol,
- state->active_subvol);
-
- LOCK (&basefd->lock);
- {
- if (ret < 0) {
- basefd_ctx->migration_failed = 1;
- } else {
- basefd_ctx->migration_failed = 0;
- }
- }
- UNLOCK (&basefd->lock);
-
- ret = 0;
-
-out:
- if (oldfd)
- fd_unref (oldfd);
-
- return ret;
-}
-
-
-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;
- }
- }
-
- return error;
-}
-
-#define FUSE_FD_GET_ACTIVE_FD(activefd, basefd) \
- do { \
- LOCK (&basefd->lock); \
- { \
- activefd = basefd_ctx->activefd ? \
- basefd_ctx->activefd : basefd; \
- if (activefd != basefd) { \
- fd_ref (activefd); \
- } \
- } \
- UNLOCK (&basefd->lock); \
- \
- if (activefd == basefd) { \
- fd_ref (activefd); \
- } \
- } while (0);
-
-
-static int
-fuse_resolve_fd (fuse_state_t *state)
-{
- fuse_resolve_t *resolve = NULL;
- fd_t *basefd = NULL, *activefd = NULL;
- xlator_t *active_subvol = NULL, *this = NULL;
- int ret = 0;
- char fd_migration_error = 0;
- fuse_fd_ctx_t *basefd_ctx = NULL;
-
- resolve = state->resolve_now;
-
- this = state->this;
-
- basefd = resolve->fd;
- basefd_ctx = fuse_fd_ctx_get (this, basefd);
- if (basefd_ctx == NULL) {
- gf_log (state->this->name, GF_LOG_WARNING,
- "fdctx is NULL for basefd (ptr:%p inode-gfid:%s), "
- "resolver erroring out with errno EINVAL",
- basefd, uuid_utoa (basefd->inode->gfid));
- resolve->op_ret = -1;
- resolve->op_errno = EINVAL;
- goto resolve_continue;
- }
-
- FUSE_FD_GET_ACTIVE_FD (activefd, basefd);
-
- active_subvol = activefd->inode->table->xl;
-
- fd_migration_error = fuse_migrate_fd_error (state->this, basefd);
- 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,
- basefd);
- fd_unref (activefd);
-
- FUSE_FD_GET_ACTIVE_FD (activefd, basefd);
- active_subvol = activefd->inode->table->xl;
-
- if ((ret == -1) || fd_migration_error
- || (state->active_subvol != active_subvol)) {
- if (ret == -1) {
- gf_log (state->this->name, GF_LOG_WARNING,
- "starting sync-task to migrate "
- "basefd (ptr:%p inode-gfid:%s) failed "
- "(old-subvolume:%s-%d "
- "new-subvolume:%s-%d)",
- basefd,
- uuid_utoa (basefd->inode->gfid),
- active_subvol->name,
- active_subvol->graph->id,
- state->active_subvol->name,
- state->active_subvol->graph->id);
- } else {
- gf_log (state->this->name, GF_LOG_WARNING,
- "fd migration of basefd "
- "(ptr:%p inode-gfid:%s) failed "
- "(old-subvolume:%s-%d "
- "new-subvolume:%s-%d)",
- basefd,
- uuid_utoa (basefd->inode->gfid),
- active_subvol->name,
- active_subvol->graph->id,
- state->active_subvol->name,
- state->active_subvol->graph->id);
- }
-
- resolve->op_ret = -1;
- resolve->op_errno = EBADF;
- } else {
- gf_log (state->this->name, GF_LOG_DEBUG,
- "basefd (ptr:%p inode-gfid:%s) migrated "
- "successfully in resolver "
- "(old-subvolume:%s-%d new-subvolume:%s-%d)",
- basefd, uuid_utoa (basefd->inode->gfid),
- active_subvol->name, active_subvol->graph->id,
- state->active_subvol->name,
- state->active_subvol->graph->id);
- }
- }
-
- if ((resolve->op_ret == -1) && (resolve->op_errno == EBADF)) {
- gf_log ("fuse-resolve", GF_LOG_WARNING,
- "migration of basefd (ptr:%p inode-gfid:%s) "
- "did not complete, failing fop with EBADF "
- "(old-subvolume:%s-%d new-subvolume:%s-%d)", basefd,
- uuid_utoa (basefd->inode->gfid),
- active_subvol->name, active_subvol->graph->id,
- state->active_subvol->name,
- state->active_subvol->graph->id);
- }
-
- if (activefd != basefd) {
- state->fd = fd_ref (activefd);
- fd_unref (basefd);
- }
-
- /* state->active_subvol = active_subvol; */
-
-resolve_continue:
- if (activefd != NULL) {
- fd_unref (activefd);
- }
-
- fuse_resolve_continue (state);
-
- return 0;
-}
-
-
-int
-fuse_gfid_set (fuse_state_t *state)
-{
- int ret = 0;
-
- if (uuid_is_null (state->gfid))
- goto out;
-
- if (!state->xdata)
- state->xdata = dict_new ();
-
- if (!state->xdata) {
- ret = -1;
- goto out;
- }
-
- ret = dict_set_static_bin (state->xdata, "gfid-req",
- state->gfid, sizeof (state->gfid));
-out:
- return ret;
-}
-
-
-int
-fuse_resolve_entry_init (fuse_state_t *state, fuse_resolve_t *resolve,
- ino_t par, char *name)
-{
- inode_t *parent = NULL;
-
- parent = fuse_ino_to_inode (par, state->this);
- uuid_copy (resolve->pargfid, parent->gfid);
- resolve->parhint = parent;
- resolve->bname = gf_strdup (name);
-
- return 0;
-}
-
-
-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;
-}
-
-
-static int
-fuse_resolve (fuse_state_t *state)
-{
- fuse_resolve_t *resolve = NULL;
-
- resolve = state->resolve_now;
-
- if (resolve->fd) {
-
- fuse_resolve_fd (state);
-
- } else if (!uuid_is_null (resolve->pargfid)) {
-
- fuse_resolve_parent (state);
-
- } else if (!uuid_is_null (resolve->gfid)) {
-
- fuse_resolve_inode (state);
-
- } else {
- fuse_resolve_all (state);
- }
-
- return 0;
-}
-
-static int
-fuse_resolve_done (fuse_state_t *state)
-{
- fuse_fop_resume (state);
- 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
-fuse_resolve_all (fuse_state_t *state)
-{
- if (state->resolve_now == NULL) {
-
- state->resolve_now = &state->resolve;
- state->loc_now = &state->loc;
-
- fuse_resolve (state);
-
- } else if (state->resolve_now == &state->resolve) {
-
- state->resolve_now = &state->resolve2;
- state->loc_now = &state->loc2;
-
- fuse_resolve (state);
-
- } else if (state->resolve_now == &state->resolve2) {
-
- fuse_resolve_done (state);
-
- } else {
- gf_log ("fuse-resolve", GF_LOG_ERROR,
- "Invalid pointer for state->resolve_now");
- }
-
- return 0;
-}
-
-
-int
-fuse_resolve_continue (fuse_state_t *state)
-{
- fuse_resolve_loc_touchup (state);
-
- fuse_resolve_all (state);
-
- return 0;
-}
-
-int
-fuse_resolve_and_resume (fuse_state_t *state, fuse_resume_fn_t fn)
-{
- fuse_gfid_set (state);
-
- state->resume_fn = fn;
-
- fuse_resolve_all (state);
-
- return 0;
-}
diff --git a/xlators/mount/fuse/utils/Makefile.am b/xlators/mount/fuse/utils/Makefile.am
index fdad27ad103..c626e2769fe 100644
--- a/xlators/mount/fuse/utils/Makefile.am
+++ b/xlators/mount/fuse/utils/Makefile.am
@@ -1,9 +1,10 @@
utildir = @mountutildir@
-if GF_LINUX_HOST_OS
-util_SCRIPTS = mount.glusterfs
-else
+if GF_DARWIN_HOST_OS
util_SCRIPTS = mount_glusterfs
+else
+util_SCRIPTS = mount.glusterfs
endif
-CLEANFILES =
+CLEANFILES =
+
diff --git a/xlators/mount/fuse/utils/mount.glusterfs.in b/xlators/mount/fuse/utils/mount.glusterfs.in
index 4348533b1a2..bf43525ec00 100755
--- a/xlators/mount/fuse/utils/mount.glusterfs.in
+++ b/xlators/mount/fuse/utils/mount.glusterfs.in
@@ -1,19 +1,20 @@
-#!/bin/sh
-#
-# Copyright (c) 2013 Red Hat, Inc. <http://www.redhat.com>
-# Copyright (c) 2015 ungleich GmbH <http://www.ungleich.ch>
-#
-# 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.
-
-warn ()
-{
- echo "$@" >&2
-}
+#!/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
+# 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.
+#
+# You should have received a copy of the GNU General Public
+# License along with this program; if not, write to the Free
+# Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+# Boston, MA 02110-1301 USA
_init ()
{
@@ -22,626 +23,216 @@ _init ()
LOG_CRITICAL=CRITICAL;
LOG_ERROR=ERROR;
LOG_WARNING=WARNING;
- LOG_INFO=INFO
+ LOG_NORMAL=NORMAL
LOG_DEBUG=DEBUG;
LOG_TRACE=TRACE;
- HOST_NAME_MAX=64;
-
+ # set default log level to NORMAL
+ log_level=$LOG_NORMAL;
prefix="@prefix@";
exec_prefix=@exec_prefix@;
cmd_line=$(echo "@sbindir@/glusterfs");
-
- # check whether getfattr exists
- export PATH
- getfattr=$(which getfattr 2>/dev/null);
- if [ $? -ne 0 ]; then
- warn "WARNING: getfattr not found, certain checks will be skipped.."
- fi
-
- mounttab=/proc/mounts
- uname_s=`uname -s`
- case ${uname_s} in
- NetBSD)
- getinode="stat -f %i"
- getdev="stat -f %d"
- lgetinode="${getinode} -L"
- lgetdev="${getdev} -L"
- ;;
- Linux)
- getinode="stat -c %i"
- getdev="stat -c %d"
- lgetinode="${getinode} -L"
- lgetdev="${getdev} -L"
- ;;
- esac
-
- UPDATEDBCONF=/etc/updatedb.conf
-}
-
-is_valid_hostname ()
-{
- local server=$1
-
- length=$(echo $server | wc -c)
- if [ ${length} -gt ${HOST_NAME_MAX} ]; then
- return 1
- fi
-}
-
-parse_backup_volfile_servers ()
-{
- local server_list=$1
- local servers=""
- local new_servers=""
-
- servers=$(echo ${server_list} | sed 's/\:/ /g')
- for server in ${servers}; do
- is_valid_hostname ${server}
- if [ $? -eq 1 ]; then
- continue
- fi
- new_servers=$(echo "${new_servers} ${server}")
- done
-
- echo ${new_servers}
-}
-
-parse_volfile_servers ()
-{
- local server_list=$1
- local servers=""
- local new_servers=""
-
- servers=$(echo ${server_list} | sed 's/,/ /g')
- for server in ${servers}; do
- is_valid_hostname ${server}
- if [ $? -eq 1 ]; then
- continue
- fi
- new_servers=$(echo "${new_servers} ${server}")
- done
-
- echo ${new_servers}
}
start_glusterfs ()
{
if [ -n "$log_level_str" ]; then
- case "$( echo $log_level_str | awk '{print toupper($0)}')" in
- "ERROR")
- log_level=$LOG_ERROR;
- ;;
- "INFO")
- log_level=$LOG_INFO;
- ;;
- "DEBUG")
- log_level=$LOG_DEBUG;
- ;;
- "CRITICAL")
- log_level=$LOG_CRITICAL;
- ;;
- "WARNING")
- log_level=$LOG_WARNING;
+ case "$log_level_str" in
+ "ERROR")
+ log_level=$LOG_ERROR;
+ ;;
+ "NORMAL")
+ log_level=$LOG_NORMAL
;;
- "TRACE")
- log_level=$LOG_TRACE;
- ;;
- "NONE")
- log_level=$LOG_NONE;
- ;;
- *)
- warn "invalid log level $log_level_str, using INFO";
- log_level=$LOG_INFO;
- ;;
- esac
- fi
-
- # options without values start here
- 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 "$enable_ino32" ]; then
- cmd_line=$(echo "$cmd_line --enable-ino32");
- fi
-
- if [ -n "$worm" ]; then
- cmd_line=$(echo "$cmd_line --worm");
- fi
- if [ -n "$volfile_max_fetch_attempts" ]; then
- cmd_line=$(echo "$cmd_line --volfile-max-fetch-attempts=$volfile_max_fetch_attempts")
- fi
-
- if [ -n "$fopen_keep_cache" ]; then
- cmd_line=$(echo "$cmd_line --fopen-keep-cache");
+ "DEBUG")
+ log_level=$LOG_DEBUG;
+ ;;
+ "CRITICAL")
+ log_level=$LOG_CRITICAL;
+ ;;
+ "WARNING")
+ log_level=$LOG_WARNING;
+ ;;
+ "TRACE")
+ log_level=$LOG_TRACE;
+ ;;
+ "NONE")
+ log_level=$LOG_NONE;
+ ;;
+ *)
+ echo "invalid log level $log_level_str, using NORMAL";
+ log_level=$LOG_NORMAL;
+ ;;
+ esac
+ fi
+ cmd_line=$(echo "$cmd_line --log-level=$log_level");
+
+ if [ -n "$log_file" ]; then
+ cmd_line=$(echo "$cmd_line --log-file=$log_file");
fi
if [ -n "$volfile_check" ]; then
- cmd_line=$(echo "$cmd_line --volfile-check");
- fi
-
- if [ -n "$mem_accounting" ]; then
- cmd_line=$(echo "$cmd_line --mem-accounting");
- fi
-
- if [ -n "$aux_gfid_mount" ]; then
- cmd_line=$(echo "$cmd_line --aux-gfid-mount");
- fi
-
- if [ -n "$no_root_squash" ]; then
- cmd_line=$(echo "$cmd_line --no-root-squash");
- fi
-
-#options with values start here
- if [ -n "$log_level" ]; then
- cmd_line=$(echo "$cmd_line --log-level=$log_level");
- fi
-
- if [ -n "$log_file" ]; then
- cmd_line=$(echo "$cmd_line --log-file=$log_file");
+ cmd_line=$(echo "$cmd_line --volfile-check");
fi
if [ -n "$direct_io_mode" ]; then
- cmd_line=$(echo "$cmd_line --direct-io-mode=$direct_io_mode");
- fi
-
- if [ -n "$use_readdirp" ]; then
- cmd_line=$(echo "$cmd_line --use-readdirp=$use_readdirp");
+ cmd_line=$(echo "$cmd_line --disable-direct-io-mode");
fi
if [ -n "$volume_name" ]; then
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 "$bg_qlen" ]; then
- cmd_line=$(echo "$cmd_line --background-qlen=$bg_qlen");
- fi
-
- if [ -n "$cong_threshold" ]; then
- cmd_line=$(echo "$cmd_line --congestion-threshold=$cong_threshold");
- fi
-
- if [ -n "$fuse_mountopts" ]; then
- cmd_line=$(echo "$cmd_line --fuse-mountopts=$fuse_mountopts");
- fi
-
- if [ -n "$xlator_option" ]; then
- cmd_line=$(echo "$cmd_line --xlator-option=$xlator_option");
+
+ 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
- # if trasnport type is specified, we have to append it to
- # volume name, so that it fetches the right client vol file
-
if [ -z "$volfile_loc" ]; then
if [ -n "$server_ip" ]; then
-
- servers=$(parse_volfile_servers ${server_ip});
- if [ -n "$servers" ]; then
- for i in $(echo ${servers}); do
- cmd_line=$(echo "$cmd_line --volfile-server=$i");
- done
- else
- warn "ERROR: No valid servers found on command line.. exiting"
- print_usage
- exit 1
- fi
-
- if [ -n "$backupvolfile_server" ]; then
- if [ -z "$backup_volfile_servers" ]; then
- is_valid_hostname ${backupvolfile_server};
- if [ $? -eq 1 ]; then
- warn "ERROR: Invalid backup server specified.. exiting"
- exit 1
- fi
- cmd_line=$(echo "$cmd_line --volfile-server=$backupvolfile_server");
- fi
+ cmd_line=$(echo "$cmd_line --volfile-server-port=$server_port");
+ if [ -n "$transport" ]; then
+ cmd_line=$(echo "$cmd_line --volfile-server-transport=$transport");
fi
-
- if [ -n "$backup_volfile_servers" ]; then
- backup_servers=$(parse_backup_volfile_servers ${backup_volfile_servers})
- for i in $(echo ${backup_servers}); do
- cmd_line=$(echo "$cmd_line --volfile-server=$i");
- done
+ if [ -n "$volume_id" ]; then
+ cmd_line=$(echo "$cmd_line --volfile-id=$volume_id");
fi
- if [ -n "$server_port" ]; then
- cmd_line=$(echo "$cmd_line --volfile-server-port=$server_port");
+ if [ -n "$backupvolfile_server" ]; then
+ cmd_line1=$(echo "$cmd_line --volfile-server=$backupvolfile_server");
fi
- if [ -n "$volume_id" ]; then
- if [ -n "$transport" ]; then
- volume_id="$volume_id.$transport";
- cmd_line=$(echo "$cmd_line --volfile-server-transport=$transport");
- fi
- cmd_line=$(echo "$cmd_line --volfile-id=$volume_id");
- fi
+ cmd_line=$(echo "$cmd_line --volfile-server=$server_ip");
fi
else
cmd_line=$(echo "$cmd_line --volfile=$volfile_loc");
fi
-
- if [ -n "$fuse_mountopts" ]; then
- cmd_line=$(echo "$cmd_line --fuse-mountopts=$fuse_mountopts");
- fi
-
+
cmd_line=$(echo "$cmd_line $mount_point");
$cmd_line;
- if [ $? -ne 0 ]; then
- warn "Mount failed. Please check the log file for more details."
- exit 1;
- fi
-
- inode=$( ${getinode} $mount_point 2>/dev/null);
- # this is required if the stat returns error
- if [ $? -ne 0 ]; then
- warn "Mount failed. Please check the log file for more details."
- umount $mount_point > /dev/null 2>&1;
- exit 1;
+ # retry the failover
+ if [ $? != "0" ]; then
+ if [ -n "$cmd_line1" ]; then
+ cmd_line1=$(echo "$cmd_line1 $mount_point");
+ $cmd_line1
+ fi
fi
-}
-print_usage ()
-{
-cat << EOF
-Usage: $0 <volumeserver>:<volumeid/volumeport> -o<options> <mountpoint>
-Options:
-man 8 $0
-To display the version number of the mount helper: $0 -V
-EOF
}
-# check for recursive mounts. i.e, mounting over an existing brick
-check_recursive_mount ()
+usage ()
{
- if [ $1 = "/" ]; then
- warn "Cannot mount over root";
- exit 2;
- fi
- # GFID check first
- # remove trailing / from mount point
- mnt_dir=${1%/};
+echo "Usage: mount.glusterfs <volumeserver>:<volumeid/volumeport> -o <options> <mountpoint>
+Options:
+man 8 mount.glusterfs
- if [ -n "${getfattr}" ]; then
- ${getfattr} -n trusted.gfid $mnt_dir 2>/dev/null | grep -iq "trusted.gfid=";
- if [ $? -eq 0 ]; then
- warn "ERROR: $mnt_dir is in use as a brick of a gluster volume";
- exit 2;
- fi
- fi
+To display the version number of the mount helper:
+mount.glusterfs --version"
- # check if the mount point is a brick's parent directory
- GLUSTERD_WORKDIR="@GLUSTERD_WORKDIR@";
+}
- ls -L "${GLUSTERD_WORKDIR}"/vols/*/bricks/* > /dev/null 2>&1;
- if [ $? -ne 0 ]; then
- return;
- fi
+main ()
+{
+ helper=$(echo "$@" | sed -n 's/.*\--[ ]*\([^ ]*\).*/\1/p');
- brick_path=`grep ^path "$GLUSTERD_WORKDIR"/vols/*/bricks/* 2>/dev/null | 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
+ options=$(echo "$@" | sed -n 's/.*\-o[ ]*\([^ ]*\).*/\1/p');
- if [ -n "${getfattr}" ]; then
- ${getfattr} -n trusted.gfid "$brick" 2>/dev/null | grep -iq "trusted.gfid=";
- if [ $? -eq 0 ]; then
- # 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
- warn "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;
- else
- continue;
- fi
- else
- continue;
- fi
- done;
-}
+ new_log_level=$(echo "$options" | sed -n 's/.*log-level=\([^,]*\).*/\1/p');
+
+ [ -n "$new_log_level" ] && {
+ log_level_str="$new_log_level";
+ }
-with_options()
-{
- local key=$1
- local value=$2
-
- # 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
- ;;
- "attribute-timeout")
- attribute_timeout=$value
- ;;
- "entry-timeout")
- entry_timeout=$value
- ;;
- "negative-timeout")
- negative_timeout=$value
- ;;
- "gid-timeout")
- gid_timeout=$value
- ;;
- "background-qlen")
- bg_qlen=$value
- ;;
- "backup-volfile-servers")
- backup_volfile_servers=$value
- ;;
- "backupvolfile-server")
- backupvolfile_server=$value
- ;;
- "fetch-attempts")
- volfile_max_fetch_attempts=$value
- ;;
- "congestion-threshold")
- cong_threshold=$value
- ;;
- "xlator-option")
- xlator_option=$value
- ;;
- "fuse-mountopts")
- fuse_mountopts=$value
- ;;
- "use-readdirp")
- use_readdirp=$value
- ;;
- "no-root-squash")
- if [ $value = "yes" ] ||
- [ $value = "on" ] ||
- [ $value = "enable" ] ||
- [ $value = "true" ] ; then
- no_root_squash=1;
- fi ;;
- "root-squash")
- if [ $value = "no" ] ||
- [ $value = "off" ] ||
- [ $value = "disable" ] ||
- [ $value = "false" ] ; then
- no_root_squash=1;
- fi ;;
- *)
- warn "Invalid option: $key"
- exit 1
- ;;
- esac
-}
+ log_file=$(echo "$options" | sed -n 's/.*log-file=\([^,]*\).*/\1/p');
-without_options()
-{
- local option=$1
- # Handle options without values.
- case "$option" in
- "ro")
- read_only=1
- ;;
- "acl")
- acl=1
- ;;
- "selinux")
- selinux=1
- ;;
- "worm")
- worm=1
- ;;
- "fopen-keep-cache")
- fopen_keep_cache=1
- ;;
- "enable-ino32")
- enable_ino32=1
- ;;
- "mem-accounting")
- mem_accounting=1
- ;;
- "aux-gfid-mount")
- if [ ${uname_s} = "Linux" ]; then
- aux_gfid_mount=1
- fi
- ;;
- # "mount -t glusterfs" sends this, but it's useless.
- "rw")
- ;;
- # these ones are interpreted during system initialization
- "noauto")
- ;;
- "_netdev")
- ;;
- *)
- warn "Invalid option $option";
- exit 1
- ;;
- esac
-}
+ transport=$(echo "$options" | sed -n 's/.*transport=\([^,]*\).*/\1/p');
-parse_options()
-{
- local optarg=${1}
- for pair in $(echo ${optarg}|sed 's/,/ /g'); do
- key=$(echo "$pair" | cut -f1 -d'=');
- value=$(echo "$pair" | cut -f2- -d'=');
- if [ "$key" = "$value" ]; then
- without_options $pair;
- else
- with_options $key $value;
- fi
- done
-}
+ direct_io_mode=$(echo "$options" | sed -n 's/.*direct-io-mode=\([^,]*\).*/\1/p');
-update_updatedb()
-{
- # Append fuse.glusterfs to PRUNEFS variable in updatedb.conf(5).
- # updatedb(8) should not index files under GlusterFS, indexing
- # GlusterFS is not necessary and should be avoided.
- # Following code disables updatedb crawl on 'glusterfs'
- test -f $UPDATEDBCONF && {
- if ! grep -q 'glusterfs' $UPDATEDBCONF; then
- sed 's/\(PRUNEFS.*\)"/\1 fuse.glusterfs"/' $UPDATEDBCONF \
- > ${UPDATEDBCONF}.bak
- mv -f ${UPDATEDBCONF}.bak $UPDATEDBCONF
- fi
- }
-}
+ volume_name=$(echo "$options" | sed -n 's/.*volume-name=\([^,]*\).*/\1/p');
-main ()
-{
- if [ "x${uname_s}" = "xLinux" ] ; then
- volfile_loc=$1
- mount_point=$2
+ volume_id=$(echo "$options" | sed -n 's/.*volume_id=\([^,]*\).*/\1/p');
- ## `mount` specifies options as a last argument
- shift 2;
- fi
- while getopts "Vo:hn" opt; do
- case "${opt}" in
- o)
- parse_options ${OPTARG};
- shift 2;
- ;;
- n)
- shift 1;
- ;;
- V)
- ${cmd_line} -V;
- exit 0;
- ;;
- h)
- print_usage;
- exit 0;
- ;;
- ?)
- print_usage;
- exit 0;
- ;;
- esac
- done
+ volfile_check=$(echo "$options" | sed -n 's/.*volfile-check=\([^,]*\).*/\1/p');
- if [ "x${uname_s}" = "xNetBSD" ] ; then
- volfile_loc=$1
- mount_point=$2
- fi
+ 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');
- volume_str=$(echo "$volfile_loc" | sed -n 's/.*:\([^ ]*\).*/\1/p');
- [ -n "$volume_str" ] && {
- volume_id="$volume_str";
- }
- volfile_loc="";
+ server_ip=$(echo "$volfile_loc" | sed -n 's/\([^\:]*\).*/\1/p');
+ test_str=$(echo "$volfile_loc" | sed -n 's/.*:\([^ ]*\).*/\1/p');
+ [ -n "$test_str" ] && {
+ # Backward compatibility
+ test_str1=$(echo "$test_str" | sed -e 's/[0-9]//g');
+ [ -n "$test_str1" ] && {
+ volume_id="$test_str";
+ } || {
+ server_port=$test_str;
+ }
+ }
+ volfile_loc="";
}
- [ -z "$volume_id" -o -z "$server_ip" ] && {
- cat <<EOF >&2
-ERROR: Server name/volume name unspecified cannot proceed further..
-Please specify correct format
-Usage:
-man 8 $0
-EOF
- exit 1;
+ [ -n "$server_port" ] || {
+ server_port="6996";
}
- grep_ret=$(echo ${mount_point} | grep '^\-o');
- [ "x" != "x${grep_ret}" ] && {
- cat <<EOF >&2
-ERROR: -o options cannot be specified in either first two arguments..
-Please specify correct style
-Usage:
-man 8 $0
-EOF
- exit 1;
+ 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/[,]*log-server-port=[^,]*//');
+
+ #
+ [ -n "$helper" ] && {
+ cmd_line=$(echo "$cmd_line --$helper");
+ exec $cmd_line;
+ 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" ] && {
- cat <<EOF >&2
-ERROR: Mount point does not exist
-Please specify a mount point
-Usage:
-man 8 $0
-EOF
- exit 1;
+ 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 "[[:space:]+]${mount_point}[[:space:]+]fuse" $mounttab; then
- warn "$0: according to mtab, GlusterFS is already mounted on" \
- "$mount_point"
- exit 32;
+ 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
- #Snapshot volumes are mounted read only
- case $volume_id in
- /snaps/* ) read_only=1
- esac
-
- check_recursive_mount "$mount_point";
-
- update_updatedb;
-
+ fs_options=$(echo "$fs_options,$new_fs_options");
+
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 50a301c26a8..0f808c14bbd 100755
--- a/xlators/mount/fuse/utils/mount_glusterfs.in
+++ b/xlators/mount/fuse/utils/mount_glusterfs.in
@@ -1,540 +1,194 @@
#!/bin/sh
-# (C) 2014 Red Hat Inc. <http://www.redhat.com>
-# (C) 2015 ungleich GmbH <http://www.ungleich.ch>
-#
+# (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
# 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.
-#
+#
# You should have received a copy of the GNU General Public
# License along with this program; if not, write to the Free
# Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301 USA
-warn ()
-{
- echo "$@" >&2
-}
_init ()
{
-
# log level definitions
LOG_NONE=NONE;
LOG_CRITICAL=CRITICAL;
LOG_ERROR=ERROR;
LOG_WARNING=WARNING;
- LOG_INFO=INFO
+ LOG_NORMAL=NORMAL;
LOG_DEBUG=DEBUG;
- LOG_TRACE=TRACE;
-
- HOST_NAME_MAX=64;
-
- prefix="@prefix@";
- exec_prefix=@exec_prefix@;
- cmd_line=$(echo "@sbindir@/glusterfs");
- alias lsL='ls -L'
- uname_s=`uname -s`
- case ${uname_s} in
- Darwin)
- getinode="stat -f %i"
- getdev="stat -f %d"
- ;;
- esac
-}
-
-is_valid_hostname ()
-{
- local server=$1
-
- length=$(echo $server | wc -c)
- if [ ${length} -gt ${HOST_NAME_MAX} ]; then
- return 1
- fi
-}
-
-parse_backup_volfile_servers ()
-{
- local server_list=$1
- local servers=""
- local new_servers=""
-
- servers=$(echo ${server_list} | sed 's/\:/ /g')
- for server in ${servers}; do
- is_valid_hostname ${server}
- if [ $? -eq 1 ]; then
- continue
- fi
- new_servers=$(echo "${new_servers} ${server}")
- done
-
- echo ${new_servers}
-}
-
-parse_volfile_servers ()
-{
- local server_list=$1
- local servers=""
- local new_servers=""
-
- servers=$(echo ${server_list} | sed 's/,/ /g')
- for server in ${servers}; do
- is_valid_hostname ${server}
- if [ $? -eq 1 ]; then
- continue
- fi
- new_servers=$(echo "${new_servers} ${server}")
- done
-
- echo ${new_servers}
+ # set default log level to ERROR
+ log_level=$LOG_NORMAL;
}
start_glusterfs ()
{
+ prefix="@prefix@";
+ exec_prefix=@exec_prefix@;
+ cmd_line=$(echo "@sbindir@/glusterfs");
+
if [ -n "$log_level_str" ]; then
- case "$( echo $log_level_str | awk '{print toupper($0)}')" in
- "ERROR")
- log_level=$LOG_ERROR;
- ;;
- "INFO")
- log_level=$LOG_INFO;
- ;;
- "DEBUG")
- log_level=$LOG_DEBUG;
- ;;
- "CRITICAL")
- log_level=$LOG_CRITICAL;
+ case "$log_level_str" in
+ "ERROR")
+ log_level=$LOG_ERROR;
+ ;;
+ "NORMAL")
+ log_level=$LOG_NORMAL;
;;
- "WARNING")
- log_level=$LOG_WARNING;
- ;;
- "TRACE")
- log_level=$LOG_TRACE;
- ;;
- "NONE")
- log_level=$LOG_NONE;
- ;;
- *)
- warn "invalid log level $log_level_str, using INFO";
- log_level=$LOG_INFO;
- ;;
- esac
- fi
-
- # options without values start here
- 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 "$enable_ino32" ]; then
- cmd_line=$(echo "$cmd_line --enable-ino32");
- fi
-
- if [ -n "$worm" ]; then
- cmd_line=$(echo "$cmd_line --worm");
- fi
- if [ -n "$volfile_max_fetch_attempts" ]; then
- cmd_line=$(echo "$cmd_line --volfile-max-fetch-attempts=$volfile_max_fetch_attempts")
- fi
-
- if [ -n "$fopen_keep_cache" ]; then
- cmd_line=$(echo "$cmd_line --fopen-keep-cache");
+ "DEBUG")
+ log_level=$LOG_DEBUG;
+ ;;
+ "CRITICAL")
+ log_level=$LOG_CRITICAL;
+ ;;
+ "WARNING")
+ log_level=$LOG_WARNING;
+ ;;
+ "NONE")
+ log_level=$LOG_NONE;
+ ;;
+ *)
+ echo "invalid log level $log_level_str, using NORMAL";
+ log_level=$LOG_NORMAL;
+ ;;
+ esac
+ fi
+ cmd_line=$(echo "$cmd_line --log-level=$log_level");
+
+ if [ -n "$log_file" ]; then
+ cmd_line=$(echo "$cmd_line --log-file=$log_file");
fi
if [ -n "$volfile_check" ]; then
- cmd_line=$(echo "$cmd_line --volfile-check");
- fi
-
- if [ -n "$mem_accounting" ]; then
- cmd_line=$(echo "$cmd_line --mem-accounting");
- fi
-
- if [ -n "$aux_gfid_mount" ]; then
- cmd_line=$(echo "$cmd_line --aux-gfid-mount");
- fi
-
- if [ -n "$no_root_squash" ]; then
- cmd_line=$(echo "$cmd_line --no-root-squash");
- fi
-
-#options with values start here
- if [ -n "$log_level" ]; then
- cmd_line=$(echo "$cmd_line --log-level=$log_level");
- fi
-
- if [ -n "$log_file" ]; then
- cmd_line=$(echo "$cmd_line --log-file=$log_file");
+ cmd_line=$(echo "$cmd_line --volfile-check");
fi
if [ -n "$direct_io_mode" ]; then
- cmd_line=$(echo "$cmd_line --direct-io-mode=$direct_io_mode");
+ cmd_line=$(echo "$cmd_line --disable-direct-io-mode");
fi
-
- if [ -n "$mac_compat" ]; then
- cmd_line=$(echo "$cmd_line --mac-compat=$mac_compat");
- fi
-
- if [ -n "$use_readdirp" ]; then
- cmd_line=$(echo "$cmd_line --use-readdirp=$use_readdirp");
+
+ if [ -z "$volfile_loc" ]; then
+ if [ -n "$transport" ]; then
+ cmd_line=$(echo "$cmd_line \
+--volfile-server=$server_ip \
+--volfile-server-port=$server_port \
+--volfile-server-transport=$transport");
+ else
+ cmd_line=$(echo "$cmd_line \
+--volfile-server=$server_ip \
+--volfile-server-port=$server_port");
+ fi
+ else
+ cmd_line=$(echo "$cmd_line --volfile=$volfile_loc");
fi
if [ -n "$volume_name" ]; then
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 "$bg_qlen" ]; then
- cmd_line=$(echo "$cmd_line --background-qlen=$bg_qlen");
- fi
-
- if [ -n "$cong_threshold" ]; then
- cmd_line=$(echo "$cmd_line --congestion-threshold=$cong_threshold");
- fi
-
- if [ -n "$fuse_mountopts" ]; then
- cmd_line=$(echo "$cmd_line --fuse-mountopts=$fuse_mountopts");
- fi
-
- if [ -n "$xlator_option" ]; then
- cmd_line=$(echo "$cmd_line --xlator-option=$xlator_option");
- 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
-
- servers=$(parse_volfile_servers ${server_ip});
- if [ -n "$servers" ]; then
- for i in $(echo ${servers}); do
- cmd_line=$(echo "$cmd_line --volfile-server=$i");
- done
- else
- warn "ERROR: No valid servers found on command line.. exiting"
- print_usage
- exit 1
- fi
-
- if [ -n "$backupvolfile_server" ]; then
- if [ -z "$backup_volfile_servers" ]; then
- is_valid_hostname ${backupvolfile_server};
- if [ $? -eq 1 ]; then
- warn "ERROR: Invalid backup server specified.. exiting"
- exit 1
- fi
- cmd_line=$(echo "$cmd_line --volfile-server=$backupvolfile_server");
- fi
- fi
-
- if [ -n "$backup_volfile_servers" ]; then
- backup_servers=$(parse_backup_volfile_servers ${backup_volfile_servers})
- for i in $(echo ${backup_servers}); do
- cmd_line=$(echo "$cmd_line --volfile-server=$i");
- done
- fi
-
- if [ -n "$server_port" ]; then
- cmd_line=$(echo "$cmd_line --volfile-server-port=$server_port");
- 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
- fi
- else
- cmd_line=$(echo "$cmd_line --volfile=$volfile_loc");
- fi
-
- if [ -n "$fuse_mountopts" ]; then
- cmd_line=$(echo "$cmd_line --fuse-mountopts=$fuse_mountopts");
+
+ if [ -n "$volume_id" ]; then
+ cmd_line=$(echo "$cmd_line --volfile-id=$volume_id");
fi
cmd_line=$(echo "$cmd_line $mount_point");
- $cmd_line;
-
- if [ $? -ne 0 ]; then
- exit 1;
- fi
+ exec $cmd_line;
}
-print_usage ()
-{
-cat << EOF >&2
-Usage: $0 <volumeserver>:<volumeid/volumeport> -o<options> <mountpoint>
-Options:
-man 8 $0
-To display the version number of the mount helper: $0 -V
-EOF
-}
-
-with_options()
-{
- local key=$1
- local value=$2
-
- # 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
- ;;
- "mac-compat")
- mac_compat=$value
- ;;
- "volume-name")
- volume_name=$value
- ;;
- "volume-id")
- volume_id=$value
- ;;
- "volfile-check")
- volfile_check=$value
- ;;
- "server-port")
- server_port=$value
- ;;
- "attribute-timeout")
- attribute_timeout=$value
- ;;
- "entry-timeout")
- entry_timeout=$value
- ;;
- "negative-timeout")
- negative_timeout=$value
- ;;
- "gid-timeout")
- gid_timeout=$value
- ;;
- "background-qlen")
- bg_qlen=$value
- ;;
- "backup-volfile-servers")
- backup_volfile_servers=$value
- ;;
- "backupvolfile-server")
- backupvolfile_server=$value
- ;;
- "fetch-attempts")
- volfile_max_fetch_attempts=$value
- ;;
- "congestion-threshold")
- cong_threshold=$value
- ;;
- "xlator-option")
- xlator_option=$value
- ;;
- "fuse-mountopts")
- fuse_mountopts=$value
- ;;
- "use-readdirp")
- use_readdirp=$value
- ;;
- "no-root-squash")
- if [ $value = "yes" ] ||
- [ $value = "on" ] ||
- [ $value = "enable" ] ||
- [ $value = "true" ] ; then
- no_root_squash=1;
- fi ;;
- "root-squash")
- if [ $value = "no" ] ||
- [ $value = "off" ] ||
- [ $value = "disable" ] ||
- [ $value = "false" ] ; then
- no_root_squash=1;
- fi ;;
- *)
- warn "Invalid option: $key"
- exit 1
- ;;
- esac
-}
-
-without_options()
-{
- local option=$1
- # Handle options without values.
- case "$option" in
- "ro")
- read_only=1
- ;;
- "acl")
- acl=1
- ;;
- "selinux")
- selinux=1
- ;;
- "worm")
- worm=1
- ;;
- "fopen-keep-cache")
- fopen_keep_cache=1
- ;;
- "enable-ino32")
- enable_ino32=1
- ;;
- "mem-accounting")
- mem_accounting=1
- ;;
- "aux-gfid-mount")
- if [ ${uname_s} = "Linux" ]; then
- aux_gfid_mount=1
- fi
- ;;
- # "mount -t glusterfs" sends this, but it's useless.
- "rw")
- ;;
- # these ones are interpreted during system initialization
- "noauto")
- ;;
- "_netdev")
- ;;
- *)
- warn "Invalid option $option";
- exit 1
- ;;
- esac
-}
-
-parse_options()
-{
- local optarg=${1}
- for pair in $(echo $optarg | sed 's/,/ /g'); do
- key=$(echo "$pair" | cut -f1 -d'=');
- value=$(echo "$pair" | cut -f2- -d'=');
- if [ "$key" = "$value" ]; then
- without_options $pair;
- else
- with_options $key $value;
- fi
- done
-}
main ()
{
- ## `mount` on OSX specifies options as first argument
- echo $1|grep -q -- "-o"
- if [ $? -eq 0 ]; then
- volfile_loc=$3
- mount_point=$4
- else
- volfile_loc=$1
- mount_point=$2
- fi
-
- while getopts "Vo:h" opt; do
- case "${opt}" in
- o)
- parse_options ${OPTARG};
- ;;
- V)
- ${cmd_line} -V;
- exit 0;
- ;;
- h)
- print_usage;
- exit 0;
- ;;
- ?)
- print_usage;
- exit 0;
- ;;
- esac
+
+ new_log_level=""
+ log_file=""
+ transport=""
+ direct_io_mode=""
+ volume_name=""
+ new_fs_options=""
+ volfile_check=""
+
+ while getopts o: opt; do
+ case "$opt" in
+ o)
+ options=$(echo $OPTARG | sed -n 's/.*\-o[ ]*\([^ ]*\).*/\1/p');
+ [ -z $new_log_level ] && {
+ new_log_level=$(echo "$options" | sed -n 's/.*log-level=\([^,]*\).*/\1/p');
+ }
+
+ [ -z $log_file ] && {
+ log_file=$(echo "$options" | sed -n 's/.*log-file=\([^,]*\).*/\1/p');
+ }
+
+ [ -z $transport ] && {
+ transport=$(echo "$options" | sed -n 's/.*transport=\([^,]*\).*/\1/p');
+ }
+
+ [ -z $direct_io_mode ] && {
+ direct_io_mode=$(echo "$options" | sed -n 's/.*direct-io-mode=\([^,]*\).*/\1/p');
+ }
+
+ [ -z $volfile_check ] && {
+ volfile_check=$(echo "$options" | sed -n 's/.*volfile-check=\([^,]*\).*/\1/p');
+ }
+
+ [ -z $volume_name ] && {
+ volume_name=$(echo "$options" | sed -n 's/.*volume-name=\([^,]*\).*/\1/p');
+ }
+
+ [ -z $volume_id ] && {
+ volume_id=$(echo "$options" | sed -n 's/.*volume-id=\([^,]*\).*/\1/p');
+ }
+
+ this_option=$(echo "$options" | sed -e 's/[,]*log-file=[^,]*//' \
+ -e 's/[,]*log-level=[^,]*//' \
+ -e 's/[,]*volume-name=[^,]*//' \
+ -e 's/[,]*volfile-check=[^,]*//' \
+ -e 's/[,]*direct-io-mode=[^,]*//' \
+ -e 's/[,]*transport=[^,]*//' \
+ -e 's/[,]*volume-id=[^,]*//');
+ new_fs_options="$new_fs_options $this_option";
+ ;;
+ esac
done
- [ -r "$volfile_loc" ] || {
- server_ip=$(echo "$volfile_loc" | sed -n 's/\([a-zA-Z0-9:.\-]*\):.*/\1/p');
- volume_str=$(echo "$volfile_loc" | sed -n 's/.*:\([^ ]*\).*/\1/p');
- [ -n "$volume_str" ] && {
- volume_id="$volume_str";
- }
- volfile_loc="";
- }
-
- [ -z "$volume_id" -o -z "$server_ip" ] && {
- cat <<EOF >&2
-ERROR: Server name/volume name unspecified cannot proceed further..
-Please specify correct format
-Usage:
-man 8 $0
-EOF
- exit 1;
+ [ -n "$new_log_level" ] && {
+ log_level_str="$new_log_level";
}
- grep_ret=$(echo ${mount_point} | grep '^\-o');
- [ "x" != "x${grep_ret}" ] && {
- cat <<EOF >&2
-ERROR: -o options cannot be specified in either first two arguments..
-Please specify correct style
-Usage:
-man 8 $0
-EOF
- exit 1;
- }
+ # TODO: use getopt. This is very much darwin specific
+ volfile_loc="$1";
+ while [ "$volfile_loc" == "-o" ] ; do
+ shift ;
+ shift ;
+ volfile_loc="$1";
+ done
+
+ [ -r "$volfile_loc" ] || {
+ server_ip=$(echo "$volfile_loc" | sed -n 's/\([^\:]*\).*/\1/p');
+ server_port=$(echo "$volfile_loc" | sed -n 's/.*:\([^ ]*\).*/\1/p');
+ [ -n "$server_port" ] || {
+ server_port="6996";
+ }
- # No need to do a ! -d test, it is taken care while initializing the
- # variable mount_point
- [ -z "$mount_point" -o ! -d "$mount_point" ] && {
- cat <<EOF >&2
-ERROR: Mount point does not exist
-Please specify a mount point
-Usage:
-man 8 $0
-EOF
- exit 1;
+ volfile_loc="";
}
+ # following line is product of love towards sed
+ # $2=$(echo "$@" | sed -n 's/[^ ]* \([^ ]*\).*/\1/p');
+
+ mount_point="$2";
+ fs_options=$(echo "$fs_options,$new_fs_options");
+
start_glusterfs;
}
diff --git a/xlators/nfs/Makefile.am b/xlators/nfs/Makefile.am
deleted file mode 100644
index 8771032f6c6..00000000000
--- a/xlators/nfs/Makefile.am
+++ /dev/null
@@ -1,3 +0,0 @@
-SUBDIRS = server
-
-CLEANFILES =
diff --git a/xlators/nfs/server/Makefile.am b/xlators/nfs/server/Makefile.am
deleted file mode 100644
index a985f42a877..00000000000
--- a/xlators/nfs/server/Makefile.am
+++ /dev/null
@@ -1,3 +0,0 @@
-SUBDIRS = src
-
-CLEANFILES =
diff --git a/xlators/nfs/server/src/Makefile.am b/xlators/nfs/server/src/Makefile.am
deleted file mode 100644
index 32d93812b50..00000000000
--- a/xlators/nfs/server/src/Makefile.am
+++ /dev/null
@@ -1,24 +0,0 @@
-xlator_LTLIBRARIES = server.la
-xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/nfs
-nfsrpclibdir = $(top_srcdir)/rpc/rpc-lib/src
-server_la_LDFLAGS = -module -avoid-version
-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 acl3.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 \
- acl3.h
-
-AM_CPPFLAGS = $(GF_CPPFLAGS) \
- -DLIBDIR=\"$(libdir)/glusterfs/$(PACKAGE_VERSION)/auth\" \
- -I$(top_srcdir)/libglusterfs/src \
- -I$(nfsrpclibdir) -I$(CONTRIBDIR)/rbtree \
- -I$(top_srcdir)/rpc/xdr/src/ -DDATADIR=\"$(localstatedir)\"
-
-AM_CFLAGS = -Wall $(GF_CFLAGS)
-
-AM_LDFLAGS = -L$(xlatordir)
-
-CLEANFILES =
diff --git a/xlators/nfs/server/src/acl3.c b/xlators/nfs/server/src/acl3.c
deleted file mode 100644
index 09923a07631..00000000000
--- a/xlators/nfs/server/src/acl3.c
+++ /dev/null
@@ -1,920 +0,0 @@
-/*
- * Copyright (c) 2012-2013 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 "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 "nfs3.h"
-#include "nfs-mem-types.h"
-#include "nfs3-helpers.h"
-#include "nfs3-fh.h"
-#include "nfs-generics.h"
-#include "acl3.h"
-#include "byte-order.h"
-#include "compat-errno.h"
-
-static int
-acl3_nfs_acl_to_xattr (aclentry *ace, void *xattrbuf,
- int aclcount, int defacl);
-
-static int
-acl3_nfs_acl_from_xattr (aclentry *ace, void *xattrbuf,
- int bufsize, int defacl);
-
-typedef ssize_t (*acl3_serializer) (struct iovec outmsg, void *args);
-
-extern void nfs3_call_state_wipe (nfs3_call_state_t *cs);
-
-extern nfs3_call_state_t *
-nfs3_call_state_init (struct nfs3_state *s, rpcsvc_request_t *req, xlator_t *v);
-
-extern int
-nfs3_fh_validate (struct nfs3_fh *fh);
-
-extern fattr3
-nfs3_stat_to_fattr3 (struct iatt *buf);
-
-#define acl3_validate_nfs3_state(request, state, status, label, retval) \
- do { \
- state = rpcsvc_request_program_private (request); \
- if (!state) { \
- gf_log (GF_ACL, GF_LOG_ERROR, "NFSv3 state " \
- "missing from RPC request"); \
- rpcsvc_request_seterr (req, SYSTEM_ERR); \
- status = NFS3ERR_SERVERFAULT; \
- goto label; \
- } \
- } while (0); \
-
-#define acl3_validate_gluster_fh(handle, status, errlabel) \
- do { \
- if (!nfs3_fh_validate (handle)) { \
- gf_log (GF_ACL, GF_LOG_ERROR, "Bad Handle"); \
- status = NFS3ERR_BADHANDLE; \
- goto errlabel; \
- } \
- } while (0) \
-
-
-extern xlator_t *
-nfs3_fh_to_xlator (struct nfs3_state *nfs3, struct nfs3_fh *fh);
-
-#define acl3_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_ACL, GF_LOG_ERROR, "Failed to map " \
- "FH to vol: client=%s, exportid=%s, gfid=%s",\
- trans->peerinfo.identifier, exportid, \
- gfid); \
- gf_log (GF_ACL, GF_LOG_ERROR, \
- "Stale nfs client %s must be trying to "\
- "connect to a deleted volume, please " \
- "unmount it.", trans->peerinfo.identifier);\
- status = NFS3ERR_STALE; \
- goto label; \
- } else { \
- gf_log (GF_ACL, GF_LOG_TRACE, "FH to Volume: %s"\
- ,volume->name); \
- rpcsvc_request_set_private (req, volume); \
- } \
- } while (0); \
-
-#define acl3_volume_started_check(nfs3state, vlm, rtval, erlbl) \
- do { \
- if ((!nfs_subvolume_started (nfs_state (nfs3state->nfsx), vlm))){\
- gf_log (GF_ACL, GF_LOG_ERROR, "Volume is disabled: %s",\
- vlm->name); \
- rtval = RPCSVC_ACTOR_IGNORE; \
- goto erlbl; \
- } \
- } while (0) \
-
-#define acl3_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); \
- snprintf (buf, sizeof (buf), "(%s) %s : %s", \
- trans->peerinfo.identifier, \
- xlatorp ? xlatorp->name : "ERR", \
- gfid); \
- gf_log (GF_ACL, GF_LOG_ERROR, "Unable to resolve FH"\
- ": %s", buf); \
- nfstat = nfs3_errno_to_nfsstat3 (cst->resolve_errno);\
- goto erlabl; \
- } \
- } while (0) \
-
-#define acl3_handle_call_state_init(nfs3state, calls, rq, v, opstat, errlabel)\
- do { \
- calls = nfs3_call_state_init ((nfs3state), (rq), v); \
- if (!calls) { \
- gf_log (GF_ACL, GF_LOG_ERROR, "Failed to " \
- "init call state"); \
- opstat = NFS3ERR_SERVERFAULT; \
- rpcsvc_request_seterr (req, SYSTEM_ERR); \
- goto errlabel; \
- } \
- } while (0) \
-
-
-int
-acl3svc_submit_reply (rpcsvc_request_t *req, void *arg, acl3_serializer sfunc)
-{
- struct iovec outmsg = {0, };
- struct iobuf *iob = NULL;
- struct nfs3_state *nfs3 = NULL;
- int ret = -1;
- ssize_t msglen = 0;
- struct iobref *iobref = NULL;
-
- if (!req)
- return -1;
-
- nfs3 = (struct nfs3_state *)rpcsvc_request_program_private (req);
- if (!nfs3) {
- gf_log (GF_ACL, 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_ACL, 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.
- */
- msglen = sfunc (outmsg, arg);
- if (msglen < 0) {
- gf_log (GF_ACL, GF_LOG_ERROR, "Failed to encode message");
- goto ret;
- }
- outmsg.iov_len = msglen;
-
- iobref = iobref_new ();
- if (iobref == NULL) {
- gf_log (GF_ACL, GF_LOG_ERROR, "Failed to get iobref");
- goto ret;
- }
-
- ret = iobref_add (iobref, iob);
- if (ret) {
- gf_log (GF_ACL, GF_LOG_ERROR, "Failed to add iob to iobref");
- goto ret;
- }
-
- /* Then, submit the message for transmission. */
- ret = rpcsvc_submit_message (req, &outmsg, 1, NULL, 0, iobref);
- if (ret == -1) {
- gf_log (GF_ACL, GF_LOG_ERROR, "Reply submission failed");
- goto ret;
- }
-
- ret = 0;
-ret:
- if (iob)
- iobuf_unref (iob);
- if (iobref)
- iobref_unref (iobref);
-
- return ret;
-}
-
-
-int
-acl3svc_null (rpcsvc_request_t *req)
-{
- struct iovec dummyvec = {0, };
-
- if (!req) {
- gf_log (GF_ACL, GF_LOG_ERROR, "Got NULL request!");
- return 0;
- }
- rpcsvc_submit_generic (req, &dummyvec, 1, NULL, 0, NULL);
- return 0;
-}
-
-int
-acl3_getacl_reply (rpcsvc_request_t *req, getaclreply *reply)
-{
- acl3svc_submit_reply (req, (void *)reply,
- (acl3_serializer)xdr_serialize_getaclreply);
- return 0;
-}
-
-int
-acl3_setacl_reply (rpcsvc_request_t *req, setaclreply *reply)
-{
- acl3svc_submit_reply (req, (void *)reply,
- (acl3_serializer)xdr_serialize_setaclreply);
- return 0;
-}
-
-/* acl3_getacl_cbk: fetch and decode the ACL in the POSIX_ACL_ACCESS_XATTR
- *
- * The POSIX_ACL_ACCESS_XATTR can be set on files and directories.
- */
-int
-acl3_getacl_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *dict,
- dict_t *xdata)
-{
- nfsstat3 stat = NFS3ERR_SERVERFAULT;
- nfs3_call_state_t *cs = NULL;
- data_t *data = NULL;
- getaclreply *getaclreply = NULL;
- int aclcount = 0;
- int defacl = 1; /* DEFAULT ACL */
-
- if (!frame->local) {
- gf_log (GF_ACL, GF_LOG_ERROR, "Invalid argument,"
- " frame->local NULL");
- return -EINVAL;
- }
- cs = frame->local;
- getaclreply = &cs->args.getaclreply;
- if ((op_ret < 0) && (op_errno != ENODATA && op_errno != ENOATTR)) {
- stat = nfs3_cbk_errno_status (op_ret, op_errno);
- goto err;
- } else if (!dict) {
- /* no ACL has been set */
- stat = NFS3_OK;
- goto err;
- }
-
- getaclreply->aclentry.aclentry_val = cs->aclentry;
-
- /* getfacl: NFS USER ACL */
- data = dict_get (dict, POSIX_ACL_ACCESS_XATTR);
- if (data && data->data) {
- aclcount = acl3_nfs_acl_from_xattr (cs->aclentry,
- data->data,
- data->len,
- !defacl);
- if (aclcount < 0) {
- gf_log (GF_ACL, GF_LOG_ERROR,
- "Failed to get USER ACL");
- stat = nfs3_errno_to_nfsstat3 (-aclcount);
- goto err;
- }
- getaclreply->aclcount = aclcount;
- getaclreply->aclentry.aclentry_len = aclcount;
- }
-
- acl3_getacl_reply (cs->req, getaclreply);
- nfs3_call_state_wipe (cs);
- return 0;
-
-err:
- if (getaclreply)
- getaclreply->status = stat;
- acl3_getacl_reply (cs->req, getaclreply);
- nfs3_call_state_wipe (cs);
- return 0;
-}
-
-/* acl3_default_getacl_cbk: fetch and decode the ACL set in the
- * POSIX_ACL_DEFAULT_XATTR xattr.
- *
- * The POSIX_ACL_DEFAULT_XATTR xattr is only set on directories, not on files.
- *
- * When done with POSIX_ACL_DEFAULT_XATTR, we also need to get and decode the
- * ACL that can be set in POSIX_ACL_DEFAULT_XATTR.
- */
-int
-acl3_default_getacl_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *dict,
- dict_t *xdata)
-{
- nfsstat3 stat = NFS3ERR_SERVERFAULT;
- nfs3_call_state_t *cs = NULL;
- data_t *data = NULL;
- getaclreply *getaclreply = NULL;
- int aclcount = 0;
- int defacl = 1; /* DEFAULT ACL */
- nfs_user_t nfu = {0, };
- int ret = -1;
-
- if (!frame->local) {
- gf_log (GF_ACL, GF_LOG_ERROR, "Invalid argument,"
- " frame->local NULL");
- return -EINVAL;
- }
- cs = frame->local;
- getaclreply = &cs->args.getaclreply;
- if ((op_ret < 0) && (op_errno != ENODATA && op_errno != ENOATTR)) {
- stat = nfs3_cbk_errno_status (op_ret, op_errno);
- goto err;
- } else if (!dict) {
- /* no ACL has been set */
- stat = NFS3_OK;
- goto err;
- }
-
- getaclreply->daclentry.daclentry_val = cs->daclentry;
-
- /* getfacl: NFS DEFAULT ACL */
- data = dict_get (dict, POSIX_ACL_DEFAULT_XATTR);
- if (data && data->data) {
- aclcount = acl3_nfs_acl_from_xattr (cs->daclentry,
- data->data,
- data->len,
- defacl);
- if (aclcount < 0) {
- gf_log (GF_ACL, GF_LOG_ERROR,
- "Failed to get DEFAULT ACL");
- stat = nfs3_errno_to_nfsstat3 (-aclcount);
- goto err;
- }
-
- getaclreply->daclcount = aclcount;
- getaclreply->daclentry.daclentry_len = aclcount;
- }
-
- getaclreply->attr_follows = TRUE;
- nfs_request_user_init (&nfu, cs->req);
- ret = nfs_getxattr (cs->nfsx, cs->vol, &nfu, &cs->resolvedloc,
- POSIX_ACL_ACCESS_XATTR, NULL, acl3_getacl_cbk, cs);
- if (ret < 0) {
- stat = nfs3_errno_to_nfsstat3 (-ret);
- goto err;
- }
-
- return 0;
-
-err:
- if (getaclreply)
- getaclreply->status = stat;
- acl3_getacl_reply (cs->req, getaclreply);
- nfs3_call_state_wipe (cs);
- return 0;
-}
-
-
-int
-acl3_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)
-{
- nfsstat3 stat = NFS3ERR_SERVERFAULT;
- nfs3_call_state_t *cs = NULL;
- getaclreply *getaclreply = NULL;
- int ret = -1;
- nfs_user_t nfu = {0, };
- uint64_t deviceid = 0;
-
- if (!frame->local) {
- gf_log (GF_ACL, GF_LOG_ERROR, "Invalid argument,"
- " frame->local NULL");
- return EINVAL;
- }
-
- cs = frame->local;
- getaclreply = &cs->args.getaclreply;
-
- if (op_ret == -1) {
- stat = nfs3_cbk_errno_status (op_ret, op_errno);
- goto err;
- }
-
- /* Fill the attrs before xattrs */
- getaclreply->attr_follows = TRUE;
- deviceid = nfs3_request_xlator_deviceid (cs->req);
- nfs3_map_deviceid_to_statdev (buf, deviceid);
- getaclreply->attr = nfs3_stat_to_fattr3 (buf);
-
- nfs_request_user_init (&nfu, cs->req);
- if (buf->ia_type == IA_IFDIR) {
- ret = nfs_getxattr (cs->nfsx, cs->vol, &nfu, &cs->resolvedloc,
- POSIX_ACL_DEFAULT_XATTR, NULL,
- acl3_default_getacl_cbk, cs);
- } else {
- ret = nfs_getxattr (cs->nfsx, cs->vol, &nfu, &cs->resolvedloc,
- POSIX_ACL_ACCESS_XATTR, NULL,
- acl3_getacl_cbk, cs);
- }
-
- if (ret < 0) {
- stat = nfs3_errno_to_nfsstat3 (-ret);
- goto err;
- }
-
- return 0;
-err:
- getaclreply->status = stat;
- acl3_getacl_reply (cs->req, getaclreply);
- nfs3_call_state_wipe (cs);
- return 0;
-}
-
-
-int
-acl3_getacl_resume (void *carg)
-{
- int ret = -1;
- nfs3_call_state_t *cs = NULL;
- nfsstat3 stat = NFS3ERR_SERVERFAULT;
- nfs_user_t nfu = {0, };
-
- if (!carg)
- return ret;
-
- cs = (nfs3_call_state_t *)carg;
- acl3_check_fh_resolve_status (cs, stat, acl3err);
- nfs_request_user_init (&nfu, cs->req);
-
- ret = nfs_stat (cs->nfsx, cs->vol, &nfu, &cs->resolvedloc,
- acl3_stat_cbk, cs);
- stat = -ret;
-acl3err:
- if (ret < 0) {
- gf_log (GF_ACL, GF_LOG_ERROR, "unable to open_and_resume");
- cs->args.getaclreply.status = nfs3_errno_to_nfsstat3 (stat);
- acl3_getacl_reply (cs->req, &cs->args.getaclreply);
- nfs3_call_state_wipe (cs);
- }
-
- return ret;
-}
-
-
-int
-acl3svc_getacl (rpcsvc_request_t *req)
-{
- xlator_t *vol = NULL;
- struct nfs_state *nfs = NULL;
- nfs3_state_t *nfs3 = NULL;
- nfs3_call_state_t *cs = NULL;
- int ret = RPCSVC_ACTOR_ERROR;
- nfsstat3 stat = NFS3ERR_SERVERFAULT;
- struct nfs3_fh fh, *fhp = NULL;
- getaclargs getaclargs;
- getaclreply getaclreply;
-
- if (!req)
- return ret;
-
- acl3_validate_nfs3_state (req, nfs3, stat, rpcerr, ret);
- nfs = nfs_state (nfs3->nfsx);
- memset (&getaclargs, 0, sizeof (getaclargs));
- memset (&getaclreply, 0, sizeof (getaclreply));
- getaclargs.fh.n_bytes = (char *)&fh;
- if (xdr_to_getaclargs(req->msg[0], &getaclargs) <= 0) {
- gf_log (GF_ACL, GF_LOG_ERROR, "Error decoding args");
- rpcsvc_request_seterr (req, GARBAGE_ARGS);
- goto rpcerr;
- }
-
- /* Validate ACL mask */
- if (getaclargs.mask & ~(NFS_ACL|NFS_ACLCNT|NFS_DFACL|NFS_DFACLCNT)) {
- stat = NFS3ERR_INVAL;
- goto acl3err;
- }
-
- fhp = &fh;
- acl3_validate_gluster_fh (&fh, stat, acl3err);
- acl3_map_fh_to_volume (nfs->nfs3state, fhp, req, vol, stat, acl3err);
- acl3_volume_started_check (nfs3, vol, ret, rpcerr);
- acl3_handle_call_state_init (nfs->nfs3state, cs, req,
- vol, stat, acl3err);
-
- cs->vol = vol;
- cs->args.getaclreply.mask = getaclargs.mask;
-
- ret = nfs3_fh_resolve_and_resume (cs, fhp, NULL, acl3_getacl_resume);
- stat = nfs3_errno_to_nfsstat3 (-ret);
-
-acl3err:
- if (ret < 0) {
- gf_log (GF_ACL, GF_LOG_ERROR, "unable to resolve and resume");
- getaclreply.status = stat;
- acl3_getacl_reply (req, &getaclreply);
- nfs3_call_state_wipe (cs);
- return 0;
- }
-
-rpcerr:
- return ret;
-}
-
-int
-acl3_setacl_cbk (call_frame_t *frame, void *cookie,
- xlator_t *this, int32_t op_ret, int32_t op_errno,
- dict_t *xdata)
-{
- nfs3_call_state_t *cs = NULL;
- cs = frame->local;
- if (op_ret < 0) {
- nfsstat3 status = nfs3_cbk_errno_status (op_ret, op_errno);
- cs->args.setaclreply.status = status;
- }
-
- acl3_setacl_reply (cs->req, &cs->args.setaclreply);
-
- nfs3_call_state_wipe (cs);
-
- return 0;
-}
-
-int
-acl3_setacl_resume (void *carg)
-{
- int ret = -1;
- nfs3_call_state_t *cs = NULL;
- nfsstat3 stat = NFS3ERR_SERVERFAULT;
- nfs_user_t nfu = {0, };
- dict_t *xattr = NULL;
-
- if (!carg)
- return ret;
- cs = (nfs3_call_state_t *)carg;
- acl3_check_fh_resolve_status (cs, stat, acl3err);
- nfs_request_user_init (&nfu, cs->req);
- xattr = dict_new();
- if (cs->aclcount)
- ret = dict_set_static_bin (xattr, POSIX_ACL_ACCESS_XATTR,
- cs->aclxattr,
- posix_acl_xattr_size (cs->aclcount));
- if (cs->daclcount)
- ret = dict_set_static_bin (xattr, POSIX_ACL_DEFAULT_XATTR,
- cs->daclxattr,
- posix_acl_xattr_size (cs->daclcount));
-
- ret = nfs_setxattr (cs->nfsx, cs->vol, &nfu, &cs->resolvedloc, xattr,
- 0, NULL, acl3_setacl_cbk, cs);
- dict_unref (xattr);
-
-acl3err:
- if (ret < 0) {
- stat = -ret;
- gf_log (GF_ACL, GF_LOG_ERROR, "unable to open_and_resume");
- cs->args.setaclreply.status = nfs3_errno_to_nfsstat3 (stat);
- acl3_setacl_reply (cs->req, &cs->args.setaclreply);
- nfs3_call_state_wipe (cs);
- }
-
- return ret;
-}
-
-
-int
-acl3svc_setacl (rpcsvc_request_t *req)
-{
- xlator_t *vol = NULL;
- struct nfs_state *nfs = NULL;
- nfs3_state_t *nfs3 = NULL;
- nfs3_call_state_t *cs = NULL;
- int ret = RPCSVC_ACTOR_ERROR;
- nfsstat3 stat = NFS3ERR_SERVERFAULT;
- struct nfs3_fh fh;
- struct nfs3_fh *fhp = NULL;
- setaclargs setaclargs;
- setaclreply setaclreply;
- aclentry *daclentry = NULL;
- aclentry *aclentry = NULL;
- int aclerrno = 0;
- int defacl = 1;
-
- if (!req)
- return ret;
- aclentry = GF_CALLOC (NFS_ACL_MAX_ENTRIES, sizeof(*aclentry),
- gf_nfs_mt_arr);
- if (!aclentry) {
- goto rpcerr;
- }
- daclentry = GF_CALLOC (NFS_ACL_MAX_ENTRIES, sizeof(*daclentry),
- gf_nfs_mt_arr);
- if (!daclentry) {
- goto rpcerr;
- }
-
- acl3_validate_nfs3_state (req, nfs3, stat, rpcerr, ret);
- nfs = nfs_state (nfs3->nfsx);
- memset (&setaclargs, 0, sizeof (setaclargs));
- memset (&setaclreply, 0, sizeof (setaclreply));
- memset (&fh, 0, sizeof (fh));
- setaclargs.fh.n_bytes = (char *)&fh;
- setaclargs.aclentry.aclentry_val = aclentry;
- setaclargs.daclentry.daclentry_val = daclentry;
- if (xdr_to_setaclargs(req->msg[0], &setaclargs) <= 0) {
- gf_log (GF_ACL, GF_LOG_ERROR, "Error decoding args");
- rpcsvc_request_seterr (req, GARBAGE_ARGS);
- goto rpcerr;
- }
-
- /* Validate ACL mask */
- if (setaclargs.mask & ~(NFS_ACL|NFS_ACLCNT|NFS_DFACL|NFS_DFACLCNT)) {
- stat = NFS3ERR_INVAL;
- goto acl3err;
- }
-
- fhp = &fh;
- acl3_validate_gluster_fh (fhp, stat, acl3err);
- acl3_map_fh_to_volume (nfs->nfs3state, fhp, req, vol, stat, acl3err);
- acl3_volume_started_check (nfs3, vol, ret, rpcerr);
- acl3_handle_call_state_init (nfs->nfs3state, cs, req,
- vol, stat, acl3err);
-
- cs->vol = vol;
- cs->aclcount = setaclargs.aclcount;
- cs->daclcount = setaclargs.daclcount;
-
- /* setfacl: NFS USER ACL */
- aclerrno = acl3_nfs_acl_to_xattr (aclentry,
- cs->aclxattr,
- cs->aclcount,
- !defacl);
- if (aclerrno < 0) {
- gf_log (GF_ACL, GF_LOG_ERROR, "Failed to set USER ACL");
- stat = nfs3_errno_to_nfsstat3 (-aclerrno);
- goto acl3err;
- }
-
- /* setfacl: NFS DEFAULT ACL */
- aclerrno = acl3_nfs_acl_to_xattr (daclentry,
- cs->daclxattr,
- cs->daclcount,
- defacl);
- if (aclerrno < 0) {
- gf_log (GF_ACL, GF_LOG_ERROR, "Failed to set DEFAULT ACL");
- stat = nfs3_errno_to_nfsstat3 (-aclerrno);
- goto acl3err;
- }
-
- ret = nfs3_fh_resolve_and_resume (cs, fhp, NULL, acl3_setacl_resume);
- stat = nfs3_errno_to_nfsstat3 (-ret);
-
-acl3err:
- if (ret < 0) {
- gf_log (GF_ACL, GF_LOG_ERROR, "unable to resolve and resume");
- setaclreply.status = stat;
- acl3_setacl_reply (req, &setaclreply);
- nfs3_call_state_wipe (cs);
- GF_FREE(aclentry);
- GF_FREE(daclentry);
- return 0;
- }
-
-rpcerr:
- if (ret < 0)
- nfs3_call_state_wipe (cs);
- if (aclentry)
- GF_FREE (aclentry);
- if (daclentry)
- GF_FREE (daclentry);
- return ret;
-}
-
-
-
-rpcsvc_actor_t acl3svc_actors[ACL3_PROC_COUNT] = {
- {"NULL", ACL3_NULL, acl3svc_null, NULL, 0, DRC_NA},
- {"GETACL", ACL3_GETACL, acl3svc_getacl, NULL, 0, DRC_NA},
- {"SETACL", ACL3_SETACL, acl3svc_setacl, NULL, 0, DRC_NA},
-};
-
-rpcsvc_program_t acl3prog = {
- .progname = "ACL3",
- .prognum = ACL_PROGRAM,
- .progver = ACLV3_VERSION,
- .progport = GF_NFS3_PORT,
- .actors = acl3svc_actors,
- .numactors = ACL3_PROC_COUNT,
- .min_auth = AUTH_NULL,
-};
-
-rpcsvc_program_t *
-acl3svc_init(xlator_t *nfsx)
-{
- struct nfs3_state *ns = NULL;
- struct nfs_state *nfs = NULL;
- dict_t *options = NULL;
- int ret = -1;
- char *portstr = NULL;
- static gf_boolean_t acl3_inited = _gf_false;
-
- /* Already inited */
- if (acl3_inited)
- return &acl3prog;
-
- nfs = (struct nfs_state*)nfsx->private;
-
- ns = nfs->nfs3state;
- if (!ns) {
- gf_log (GF_ACL, GF_LOG_ERROR, "ACL3 init failed");
- goto err;
- }
- acl3prog.private = ns;
-
- options = dict_new ();
-
- ret = gf_asprintf (&portstr, "%d", GF_ACL3_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_ACL, 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_ACL, 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_ACL, GF_LOG_ERROR, "dict_set_str error");
- goto err;
- }
- }
-
- ret = dict_set_str (options, "transport.address-family", "inet");
- if (ret == -1) {
- gf_log (GF_ACL, GF_LOG_ERROR, "dict_set_str error");
- goto err;
- }
-
- ret = rpcsvc_create_listeners (nfs->rpcsvc, options, "ACL");
- if (ret == -1) {
- gf_log (GF_ACL, GF_LOG_ERROR, "Unable to create listeners");
- dict_unref (options);
- goto err;
- }
-
- acl3_inited = _gf_true;
- return &acl3prog;
-err:
- return NULL;
-}
-
-static int
-acl3_nfs_acl_to_xattr (aclentry *ace, /* ACL entries to be read */
- void *xattrbuf, /* XATTR buf to be populated */
- int aclcount, /* No of ACLs to be read */
- int defacl) /* 1 if DEFAULT ACL */
-{
- int idx = 0;
- posix_acl_xattr_header *xheader = NULL;
- posix_acl_xattr_entry *xentry = NULL;
-
- if ((!ace) || (!xattrbuf))
- return (-EINVAL);
-
- /* ACL count is ZERO, nothing to do */
- if (!aclcount)
- return (0);
-
- if ((aclcount < 0) || (aclcount > NFS_ACL_MAX_ENTRIES))
- return (-EINVAL);
-
- xheader = (posix_acl_xattr_header *) (xattrbuf);
- xentry = (posix_acl_xattr_entry *) (xheader + 1);
-
- /*
- * For "default ACL", NFSv3 handles the 'type' differently
- * i.e. by logical OR'ing 'type' with NFS_ACL_DEFAULT.
- * Which the backend File system does not understand and
- * that needs to be masked OFF.
- */
- xheader->version = POSIX_ACL_XATTR_VERSION;
-
- for (idx = 0; idx < aclcount; idx++) {
- xentry->tag = ace->type;
- if (defacl)
- xentry->tag &= ~NFS_ACL_DEFAULT;
- xentry->perm = ace->perm;
-
- switch (xentry->tag) {
- case POSIX_ACL_USER:
- case POSIX_ACL_GROUP:
- if (xentry->perm & ~S_IRWXO)
- return (-EINVAL);
- xentry->id = ace->uid;
- break;
- case POSIX_ACL_USER_OBJ:
- case POSIX_ACL_GROUP_OBJ:
- case POSIX_ACL_OTHER:
- if (xentry->perm & ~S_IRWXO)
- return (-EINVAL);
- xentry->id = POSIX_ACL_UNDEFINED_ID;
- break;
- case POSIX_ACL_MASK:
- /* Solaris sometimes sets additional bits in
- * the mask.
- */
- xentry->perm &= S_IRWXO;
- xentry->id = POSIX_ACL_UNDEFINED_ID;
- break;
- default:
- return (-EINVAL);
- }
-
- xentry++;
- ace++;
- }
-
- /* SUCCESS */
- return (0);
-}
-
-static int
-acl3_nfs_acl_from_xattr (aclentry *ace, /* ACL entries to be filled */
- void *xattrbuf, /* XATTR buf to be read */
- int bufsize, /* Size of XATTR buffer */
- int defacl) /* 1 if DEFAULT ACL */
-{
- int idx = 0;
- ssize_t aclcount = 0;
- posix_acl_xattr_header *xheader = NULL;
- posix_acl_xattr_entry *xentry = NULL;
-
- if ((!xattrbuf) || (!ace))
- return (-EINVAL);
-
- aclcount = posix_acl_xattr_count (bufsize);
- if ((aclcount < 0) || (aclcount > NFS_ACL_MAX_ENTRIES))
- return (-EINVAL);
-
- xheader = (posix_acl_xattr_header *) (xattrbuf);
- xentry = (posix_acl_xattr_entry *) (xheader + 1);
-
- /* Check for supported POSIX ACL xattr version */
- if (xheader->version != POSIX_ACL_XATTR_VERSION)
- return (-ENOSYS);
-
- for (idx = 0; idx < (int)aclcount; idx++) {
- ace->type = xentry->tag;
- if (defacl) {
- /*
- * SET the NFS_ACL_DEFAULT flag for default
- * ACL which was masked OFF during setfacl().
- */
- ace->type |= NFS_ACL_DEFAULT;
- }
- ace->perm = (xentry->perm & S_IRWXO);
-
- switch (xentry->tag) {
- case POSIX_ACL_USER:
- case POSIX_ACL_GROUP:
- ace->uid = xentry->id;
- break;
- case POSIX_ACL_USER_OBJ:
- case POSIX_ACL_GROUP_OBJ:
- case POSIX_ACL_MASK:
- case POSIX_ACL_OTHER:
- ace->uid = POSIX_ACL_UNDEFINED_ID;
- break;
- default:
- return (-EINVAL);
- }
-
-
- xentry++;
- ace++;
- }
-
- /* SUCCESS: ACL count */
- return aclcount;
-}
diff --git a/xlators/nfs/server/src/acl3.h b/xlators/nfs/server/src/acl3.h
deleted file mode 100644
index 220bc9e78df..00000000000
--- a/xlators/nfs/server/src/acl3.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (c) 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 _ACL3_H
-#define _ACL3_H
-
-#include "glusterfs-acl.h"
-
-#define ACL3_NULL 0
-#define ACL3_GETACL 1
-#define ACL3_SETACL 2
-#define ACL3_PROC_COUNT 3
-
-#define GF_ACL3_PORT 38469
-#define GF_ACL GF_NFS"-ACL"
-
-/* Flags for the getacl/setacl mode */
-#define NFS_ACL 0x0001
-#define NFS_ACLCNT 0x0002
-#define NFS_DFACL 0x0004
-#define NFS_DFACLCNT 0x0008
-
-/*
- * NFSv3, identifies the default ACL by NFS_ACL_DEFAULT. Gluster
- * NFS needs to mask it OFF before sending it upto POSIX layer
- * or File system layer.
- */
-#define NFS_ACL_DEFAULT 0x1000
-
-#define NFS_ACL_MAX_ENTRIES 1024
-
-rpcsvc_program_t *
-acl3svc_init(xlator_t *nfsx);
-
-#endif
diff --git a/xlators/nfs/server/src/mount3.c b/xlators/nfs/server/src/mount3.c
deleted file mode 100644
index 43a77f888cd..00000000000
--- a/xlators/nfs/server/src/mount3.c
+++ /dev/null
@@ -1,2813 +0,0 @@
-/*
- Copyright (c) 2010-2011 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.
-*/
-
-#ifndef _CONFIG_H
-#define _CONFIG_H
-#include "config.h"
-#endif
-
-#include "rpcsvc.h"
-#include "dict.h"
-#include "xlator.h"
-#include "mount3.h"
-#include "xdr-nfs3.h"
-#include "msg-nfs3.h"
-#include "iobuf.h"
-#include "nfs-common.h"
-#include "nfs3-fh.h"
-#include "nfs-fops.h"
-#include "nfs-inodes.h"
-#include "nfs-generics.h"
-#include "locking.h"
-#include "iatt.h"
-#include "nfs-mem-types.h"
-#include "nfs.h"
-#include "common-utils.h"
-#include "store.h"
-
-#include <errno.h>
-#include <sys/socket.h>
-#include <sys/uio.h>
-
-
-/* This macro will assist in freeing up entire link list
- * of host_auth_spec structure.
- */
-#define FREE_HOSTSPEC(exp) do { \
- struct host_auth_spec *host= exp->hostspec; \
- while (NULL != host){ \
- struct host_auth_spec* temp = host; \
- host = host->next; \
- if (NULL != temp->host_addr) { \
- GF_FREE (temp->host_addr); \
- } \
- GF_FREE (temp); \
- } \
- exp->hostspec = NULL; \
- } while (0)
-
-typedef ssize_t (*mnt3_serializer) (struct iovec outmsg, void *args);
-
-extern void *
-mount3udp_thread (void *argv);
-
-static inline void
-mnt3_export_free (struct mnt3_export *exp)
-{
- if (!exp)
- return;
-
- if (exp->exptype == MNT3_EXPTYPE_DIR)
- FREE_HOSTSPEC (exp);
- GF_FREE (exp->expname);
- GF_FREE (exp);
-}
-
-/* Generic reply function for MOUNTv3 specific replies. */
-int
-mnt3svc_submit_reply (rpcsvc_request_t *req, void *arg, mnt3_serializer sfunc)
-{
- struct iovec outmsg = {0, };
- struct iobuf *iob = NULL;
- struct mount3_state *ms = NULL;
- int ret = -1;
- ssize_t msglen = 0;
- struct iobref *iobref = NULL;
-
- if (!req)
- return -1;
-
- ms = (struct mount3_state *)rpcsvc_request_program_private (req);
- if (!ms) {
- gf_log (GF_MNT, GF_LOG_ERROR, "mount state not found");
- goto ret;
- }
-
- /* 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");
- 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.
- */
- msglen = sfunc (outmsg, arg);
- if (msglen < 0) {
- gf_log (GF_MNT, GF_LOG_ERROR, "Failed to encode message");
- goto ret;
- }
- outmsg.iov_len = msglen;
-
- iobref = iobref_new ();
- if (iobref == NULL) {
- gf_log (GF_MNT, GF_LOG_ERROR, "Failed to get iobref");
- goto ret;
- }
-
- ret = iobref_add (iobref, iob);
- if (ret) {
- gf_log (GF_MNT, GF_LOG_ERROR, "Failed to add iob to iobref");
- goto ret;
- }
-
- /* Then, submit the message for transmission. */
- ret = rpcsvc_submit_message (req, &outmsg, 1, NULL, 0, iobref);
- if (ret == -1) {
- gf_log (GF_MNT, GF_LOG_ERROR, "Reply submission failed");
- goto ret;
- }
-
- ret = 0;
-ret:
- if (NULL != iob)
- iobuf_unref (iob);
- if (NULL != iobref)
- iobref_unref (iobref);
-
- return ret;
-}
-
-
-/* Generic error reply function, just pass the err status
- * and it will do the rest, including transmission.
- */
-int
-mnt3svc_mnt_error_reply (rpcsvc_request_t *req, int mntstat)
-{
- mountres3 res;
-
- if (!req)
- return -1;
-
- res.fhs_status = mntstat;
- mnt3svc_submit_reply (req, (void *)&res,
- (mnt3_serializer)xdr_serialize_mountres3);
-
- return 0;
-}
-
-
-mountstat3
-mnt3svc_errno_to_mnterr (int32_t errnum)
-{
- mountstat3 stat;
-
- switch (errnum) {
-
- case 0:
- stat = MNT3_OK;
- break;
- case ENOENT:
- stat = MNT3ERR_NOENT;
- break;
- case EPERM:
- stat = MNT3ERR_PERM;
- break;
- case EIO:
- stat = MNT3ERR_IO;
- break;
- case EACCES:
- stat = MNT3ERR_ACCES;
- break;
- case ENOTDIR:
- stat = MNT3ERR_NOTDIR;
- break;
- case EINVAL:
- stat = MNT3ERR_INVAL;
- break;
- case ENOSYS:
- stat = MNT3ERR_NOTSUPP;
- break;
- case ENOMEM:
- stat = MNT3ERR_SERVERFAULT;
- break;
- default:
- stat = MNT3ERR_SERVERFAULT;
- break;
- }
-
- return stat;
-}
-
-
-mountres3
-mnt3svc_set_mountres3 (mountstat3 stat, struct nfs3_fh *fh, int *authflavor,
- u_int aflen)
-{
- mountres3 res = {0, };
- uint32_t fhlen = 0;
-
- res.fhs_status = stat;
- fhlen = nfs3_fh_compute_size (fh);
- res.mountres3_u.mountinfo.fhandle.fhandle3_len = fhlen;
- res.mountres3_u.mountinfo.fhandle.fhandle3_val = (char *)fh;
- res.mountres3_u.mountinfo.auth_flavors.auth_flavors_val = authflavor;
- res.mountres3_u.mountinfo.auth_flavors.auth_flavors_len = aflen;
-
- return res;
-}
-
-/* Read the rmtab from the store_handle and append (or not) the entries to the
- * mountlist.
- *
- * Requires the store_handle to be locked.
- */
-static int
-__mount_read_rmtab (gf_store_handle_t *sh, struct list_head *mountlist,
- gf_boolean_t append)
-{
- int ret = 0;
- unsigned int idx = 0;
- struct mountentry *me = NULL, *tmp = NULL;
- /* me->hostname is a char[MNTPATHLEN] */
- char key[MNTPATHLEN + 11];
-
- GF_ASSERT (sh && mountlist);
-
- if (!gf_store_locked_local (sh)) {
- gf_log (GF_MNT, GF_LOG_WARNING, "Not reading unlocked %s",
- sh->path);
- return -1;
- }
-
- if (!append) {
- list_for_each_entry_safe (me, tmp, mountlist, mlist) {
- list_del (&me->mlist);
- GF_FREE (me);
- }
- me = NULL;
- }
-
- for (;;) {
- char *value = NULL;
-
- if (me && append) {
- /* do not add duplicates */
- list_for_each_entry (tmp, mountlist, mlist) {
- if (!strcmp(tmp->hostname, me->hostname) &&
- !strcmp(tmp->exname, me->exname)) {
- GF_FREE (me);
- goto dont_add;
- }
- }
- list_add_tail (&me->mlist, mountlist);
- } else if (me) {
- list_add_tail (&me->mlist, mountlist);
- }
-
-dont_add:
- me = GF_CALLOC (1, sizeof (*me), gf_nfs_mt_mountentry);
- if (!me) {
- gf_log (GF_MNT, GF_LOG_ERROR, "Out of memory");
- ret = -1;
- goto out;
- }
-
- INIT_LIST_HEAD (&me->mlist);
-
- snprintf (key, 9 + MNTPATHLEN, "hostname-%d", idx);
- ret = gf_store_retrieve_value (sh, key, &value);
- if (ret)
- break;
- strncpy (me->hostname, value, MNTPATHLEN);
- GF_FREE (value);
-
- snprintf (key, 11 + MNTPATHLEN, "mountpoint-%d", idx);
- ret = gf_store_retrieve_value (sh, key, &value);
- if (ret)
- break;
- strncpy (me->exname, value, MNTPATHLEN);
- GF_FREE (value);
-
- idx++;
- gf_log (GF_MNT, GF_LOG_TRACE, "Read entries %s:%s", me->hostname, me->exname);
- }
- gf_log (GF_MNT, GF_LOG_DEBUG, "Read %d entries from '%s'", idx, sh->path);
- GF_FREE (me);
-out:
- return ret;
-}
-
-/* Overwrite the contents of the rwtab with te in-memory client list.
- * Fail gracefully if the stora_handle is not locked.
- */
-static void
-__mount_rewrite_rmtab(struct mount3_state *ms, gf_store_handle_t *sh)
-{
- struct mountentry *me = NULL;
- char key[16];
- int fd, ret;
- unsigned int idx = 0;
-
- if (!gf_store_locked_local (sh)) {
- gf_log (GF_MNT, GF_LOG_WARNING, "Not modifying unlocked %s",
- sh->path);
- return;
- }
-
- fd = gf_store_mkstemp (sh);
- if (fd == -1) {
- gf_log (GF_MNT, GF_LOG_ERROR, "Failed to open %s", sh->path);
- return;
- }
-
- list_for_each_entry (me, &ms->mountlist, mlist) {
- snprintf (key, 16, "hostname-%d", idx);
- ret = gf_store_save_value (fd, key, me->hostname);
- if (ret)
- goto fail;
-
- snprintf (key, 16, "mountpoint-%d", idx);
- ret = gf_store_save_value (fd, key, me->exname);
- if (ret)
- goto fail;
-
- idx++;
- }
-
- gf_log (GF_MNT, GF_LOG_DEBUG, "Updated rmtab with %d entries", idx);
-
- if (gf_store_rename_tmppath (sh))
- gf_log (GF_MNT, GF_LOG_ERROR, "Failed to overwrite rwtab %s",
- sh->path);
-
- return;
-
-fail:
- gf_log (GF_MNT, GF_LOG_ERROR, "Failed to update %s", sh->path);
- gf_store_unlink_tmppath (sh);
-}
-
-static gf_boolean_t
-mount_open_rmtab (const char *rmtab, gf_store_handle_t **sh)
-{
- int ret = -1;
-
- /* updating the rmtab is disabled, use in-memory only */
- if (!rmtab || rmtab[0] == '\0')
- return _gf_false;
-
- ret = gf_store_handle_new (rmtab, sh);
- if (ret) {
- gf_log (GF_MNT, GF_LOG_WARNING, "Failed to open '%s'", rmtab);
- return _gf_false;
- }
-
- return _gf_true;
-}
-
-
-/* Read the rmtab into a clean ms->mountlist.
- */
-static void
-mount_read_rmtab (struct mount3_state *ms)
-{
- gf_store_handle_t *sh = NULL;
- struct nfs_state *nfs = NULL;
- gf_boolean_t read_rmtab = _gf_false;
-
- nfs = (struct nfs_state *)ms->nfsx->private;
-
- read_rmtab = mount_open_rmtab (nfs->rmtab, &sh);
- if (!read_rmtab)
- return;
-
- if (gf_store_lock (sh)) {
- gf_log (GF_MNT, GF_LOG_WARNING, "Failed to lock '%s'",
- nfs->rmtab);
- goto out;
- }
-
- __mount_read_rmtab (sh, &ms->mountlist, _gf_false);
- gf_store_unlock (sh);
-
-out:
- gf_store_handle_destroy (sh);
-}
-
-/* Write the ms->mountlist to the rmtab.
- *
- * The rmtab could be empty, or it can exists and have been updated by a
- * different storage server without our knowing.
- *
- * 0. if opening the nfs->rmtab fails, return gracefully
- * 1. takes the store_handle lock on the current rmtab
- * - blocks if an other storage server rewrites the rmtab at the same time
- * 2. [if new_rmtab] takes the store_handle lock on the new rmtab
- * 3. reads/merges the entries from the current rmtab
- * 4. [if new_rmtab] reads/merges the entries from the new rmtab
- * 5. [if new_rmtab] writes the new rmtab
- * 6. [if not new_rmtab] writes the current rmtab
- * 7 [if new_rmtab] replaces nfs->rmtab to point to the new location
- * 8. [if new_rmtab] releases the store_handle lock of the new rmtab
- * 9. releases the store_handle lock of the old rmtab
- */
-void
-mount_rewrite_rmtab (struct mount3_state *ms, char *new_rmtab)
-{
- gf_store_handle_t *sh = NULL, *nsh = NULL;
- struct nfs_state *nfs = NULL;
- int ret;
- char *rmtab = NULL;
- gf_boolean_t got_old_rmtab = _gf_false;
-
- nfs = (struct nfs_state *)ms->nfsx->private;
-
- got_old_rmtab = mount_open_rmtab (nfs->rmtab, &sh);
- if (!got_old_rmtab && !new_rmtab)
- return;
-
- if (got_old_rmtab && gf_store_lock (sh)) {
- gf_log (GF_MNT, GF_LOG_WARNING, "Not rewriting '%s'",
- nfs->rmtab);
- goto free_sh;
- }
-
- if (new_rmtab) {
- ret = gf_store_handle_new (new_rmtab, &nsh);
- if (ret) {
- gf_log (GF_MNT, GF_LOG_WARNING, "Failed to open '%s'",
- new_rmtab);
- goto unlock_sh;
- }
-
- if (gf_store_lock (nsh)) {
- gf_log (GF_MNT, GF_LOG_WARNING, "Not rewriting '%s'",
- new_rmtab);
- goto free_nsh;
- }
- }
-
- /* always read the currently used rmtab */
- if (got_old_rmtab)
- __mount_read_rmtab (sh, &ms->mountlist, _gf_true);
-
- if (new_rmtab) {
- /* read the new rmtab and write changes to the new location */
- __mount_read_rmtab (nsh, &ms->mountlist, _gf_true);
- __mount_rewrite_rmtab (ms, nsh);
-
- /* replace the nfs->rmtab reference to the new rmtab */
- rmtab = gf_strdup(new_rmtab);
- if (rmtab == NULL) {
- gf_log (GF_MNT, GF_LOG_ERROR, "Out of memory, keeping "
- "%s as rmtab", nfs->rmtab);
- } else {
- GF_FREE (nfs->rmtab);
- nfs->rmtab = rmtab;
- }
-
- gf_store_unlock (nsh);
- } else {
- /* rewrite the current (unchanged location) rmtab */
- __mount_rewrite_rmtab (ms, sh);
- }
-
-free_nsh:
- if (new_rmtab)
- gf_store_handle_destroy (nsh);
-unlock_sh:
- if (got_old_rmtab)
- gf_store_unlock (sh);
-free_sh:
- if (got_old_rmtab)
- gf_store_handle_destroy (sh);
-}
-
-/* Add a new NFS-client to the ms->mountlist and update the rmtab if we can.
- *
- * A NFS-client will only be removed from the ms->mountlist in case the
- * NFS-client sends a unmount request. It is possible that a NFS-client
- * crashed/rebooted had network loss or something else prevented the NFS-client
- * to unmount cleanly. In this case, a duplicate entry would be added to the
- * ms->mountlist, which is wrong and we should prevent.
- *
- * It is fully acceptible that the ms->mountlist is not 100% correct, this is a
- * common issue for all(?) NFS-servers.
- */
-int
-mnt3svc_update_mountlist (struct mount3_state *ms, rpcsvc_request_t *req,
- char *expname)
-{
- struct mountentry *me = NULL;
- struct mountentry *cur = NULL;
- int ret = -1;
- char *colon = NULL;
- struct nfs_state *nfs = NULL;
- gf_store_handle_t *sh = NULL;
- gf_boolean_t update_rmtab = _gf_false;
-
- if ((!ms) || (!req) || (!expname))
- return -1;
-
- me = (struct mountentry *)GF_CALLOC (1, sizeof (*me),
- gf_nfs_mt_mountentry);
- if (!me)
- return -1;
-
- nfs = (struct nfs_state *)ms->nfsx->private;
-
- update_rmtab = mount_open_rmtab (nfs->rmtab, &sh);
-
- strncpy (me->exname, expname, MNTPATHLEN);
-
- INIT_LIST_HEAD (&me->mlist);
- /* 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);
- if (ret == -1)
- goto free_err;
-
- colon = strrchr (me->hostname, ':');
- if (colon) {
- *colon = '\0';
- }
- LOCK (&ms->mountlock);
- {
- /* in case locking fails, we just don't write the rmtab */
- if (update_rmtab && gf_store_lock (sh)) {
- gf_log (GF_MNT, GF_LOG_WARNING, "Failed to lock '%s'"
- ", changes will not be written", nfs->rmtab);
- } else if (update_rmtab) {
- __mount_read_rmtab (sh, &ms->mountlist, _gf_false);
- }
-
- /* do not add duplicates */
- list_for_each_entry (cur, &ms->mountlist, mlist) {
- if (!strcmp(cur->hostname, me->hostname) &&
- !strcmp(cur->exname, me->exname)) {
- GF_FREE (me);
- goto dont_add;
- }
- }
- list_add_tail (&me->mlist, &ms->mountlist);
-
- /* only write the rmtab in case it was locked */
- if (update_rmtab && gf_store_locked_local (sh))
- __mount_rewrite_rmtab (ms, sh);
- }
-dont_add:
- if (update_rmtab && gf_store_locked_local (sh))
- gf_store_unlock (sh);
-
- UNLOCK (&ms->mountlock);
-
-free_err:
- if (update_rmtab)
- gf_store_handle_destroy (sh);
-
- if (ret == -1)
- GF_FREE (me);
-
- return ret;
-}
-
-
-int
-__mnt3_get_volume_id (struct mount3_state *ms, xlator_t *mntxl,
- uuid_t volumeid)
-{
- int ret = -1;
- struct mnt3_export *exp = NULL;
-
- if ((!ms) || (!mntxl))
- return ret;
-
- LOCK (&ms->mountlock);
- list_for_each_entry (exp, &ms->exportlist, explist) {
- if (exp->vol == mntxl) {
- uuid_copy (volumeid, exp->volumeid);
- ret = 0;
- goto out;
- }
- }
-
-out:
- UNLOCK (&ms->mountlock);
- return ret;
-}
-
-
-int32_t
-mnt3svc_lookup_mount_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)
-{
- mountres3 res = {0, };
- rpcsvc_request_t *req = NULL;
- struct nfs3_fh fh = {{0}, };
- struct mount3_state *ms = NULL;
- mountstat3 status = 0;
- int autharr[10];
- int autharrlen = 0;
- rpcsvc_t *svc = NULL;
- xlator_t *mntxl = NULL;
- uuid_t volumeid = {0, };
- char fhstr[1024], *path = NULL;
-
- req = (rpcsvc_request_t *)frame->local;
-
- if (!req)
- return -1;
-
- mntxl = (xlator_t *)cookie;
- ms = (struct mount3_state *)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));
- status = mnt3svc_errno_to_mnterr (op_errno);
- }
- if (status != MNT3_OK)
- goto xmit_res;
-
- path = GF_CALLOC (PATH_MAX, sizeof (char), gf_nfs_mt_char);
- if (!path) {
- gf_log (GF_MNT, GF_LOG_ERROR, "Out of memory");
- goto xmit_res;
- }
-
- snprintf (path, PATH_MAX, "/%s", mntxl->name);
- mnt3svc_update_mountlist (ms, req, path);
- GF_FREE (path);
- if (gf_nfs_dvm_off (nfs_state (ms->nfsx))) {
- fh = nfs3_fh_build_indexed_root_fh (ms->nfsx->children, mntxl);
- goto xmit_res;
- }
-
- __mnt3_get_volume_id (ms, mntxl, volumeid);
- fh = nfs3_fh_build_uuid_root_fh (volumeid);
-
-xmit_res:
- nfs3_fh_to_str (&fh, fhstr, sizeof (fhstr));
- 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);
- }
-
- res = mnt3svc_set_mountres3 (status, &fh, autharr, autharrlen);
- mnt3svc_submit_reply (req, (void *)&res,
- (mnt3_serializer)xdr_serialize_mountres3);
-
- return 0;
-}
-
-
-int
-mnt3_match_dirpath_export (char *expname, char *dirpath)
-{
- int ret = 0;
- size_t dlen;
-
- if ((!expname) || (!dirpath))
- return 0;
-
- /* Some clients send a dirpath for mount that includes the slash at the
- * end. String compare for searching the export will fail because our
- * exports list does not include that slash. Remove the slash to
- * compare.
- */
- dlen = strlen (dirpath);
- if (dlen && dirpath [dlen - 1] == '/')
- dirpath [dlen - 1] = '\0';
-
- if (dirpath[0] != '/')
- expname++;
-
- if (strcmp (expname, dirpath) == 0)
- ret = 1;
-
- return ret;
-}
-
-
-int
-mnt3svc_mount_inode (rpcsvc_request_t *req, struct mount3_state *ms,
- xlator_t * xl, inode_t *exportinode)
-{
- int ret = -EFAULT;
- nfs_user_t nfu = {0, };
- loc_t exportloc = {0, };
-
- if ((!req) || (!xl) || (!ms) || (!exportinode))
- return ret;
-
- ret = nfs_inode_loc_fill (exportinode, &exportloc, NFS_RESOLVE_EXIST);
- 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);
- goto err;
- }
-
- /* To service the mount request, all we need to do
- * is to send a lookup fop that returns the stat
- * for the root of the child volume. This is
- * used to build the root fh sent to the client.
- */
- nfs_request_user_init (&nfu, req);
- ret = nfs_lookup (ms->nfsx, xl, &nfu, &exportloc,
- mnt3svc_lookup_mount_cbk, (void *)req);
-
- nfs_loc_wipe (&exportloc);
-err:
- return ret;
-}
-
-
-/* For a volume mount request, we just have to create loc on the root inode,
- * and send a lookup. In the lookup callback the mount reply is send along with
- * the file handle.
- */
-int
-mnt3svc_volume_mount (rpcsvc_request_t *req, struct mount3_state *ms,
- struct mnt3_export *exp)
-{
- inode_t *exportinode = NULL;
- int ret = -EFAULT;
- uuid_t rootgfid = {0, };
-
- if ((!req) || (!exp) || (!ms))
- return ret;
-
- rootgfid[15] = 1;
- exportinode = inode_find (exp->vol->itable, rootgfid);
- if (!exportinode) {
- gf_log (GF_MNT, GF_LOG_ERROR, "Failed to get root inode");
- ret = -ENOENT;
- goto err;
- }
-
- ret = mnt3svc_mount_inode (req, ms, exp->vol, exportinode);
- inode_unref (exportinode);
-
-err:
- return ret;
-}
-
-
-/* The catch with directory exports is that the first component of the export
- * name will be the name of the volume.
- * Any lookup that needs to be performed to build the directory's file handle
- * needs to start from the directory path from the root of the volume. For that
- * we need to strip out the volume name first.
- */
-char *
-__volume_subdir (char *dirpath, char **volname)
-{
- char *subdir = NULL;
- int volname_len = 0;
-
- if (!dirpath)
- return NULL;
-
- if (dirpath[0] == '/')
- dirpath++;
-
- subdir = index (dirpath, (int)'/');
- if (!subdir)
- goto out;
-
- if (!volname)
- goto out;
-
- if (!*volname)
- goto out;
-
- /* subdir points to the first / after the volume name while dirpath
- * points to the first char of the volume name.
- */
- volname_len = subdir - dirpath;
- strncpy (*volname, dirpath, volname_len);
- *(*volname + volname_len) = '\0';
-out:
- return subdir;
-}
-
-
-void
-mnt3_resolve_state_wipe (mnt3_resolve_t *mres)
-{
- if (!mres)
- return;
-
- nfs_loc_wipe (&mres->resolveloc);
- GF_FREE (mres);
-
-}
-
-
-/* Sets up the component argument to contain the next component in the path and
- * sets up path as an absolute path starting from the next component.
- */
-static char *
-setup_next_component (char *path, size_t plen, char *component, size_t clen)
-{
- char *comp = NULL;
- char *nextcomp = NULL;
-
- if ((!path) || (!component))
- return NULL;
-
- strncpy (component, path, clen);
- comp = index (component, (int)'/');
- if (!comp)
- goto err;
-
- comp++;
- nextcomp = index (comp, (int)'/');
- if (nextcomp) {
- strncpy (path, nextcomp, plen);
- *nextcomp = '\0';
- } else
- path[0] = '\0';
-
-err:
- return comp;
-}
-
-int32_t
-mnt3_resolve_subdir_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);
-
-/* There are multiple components in the directory export path and each one
- * needs to be looked up one after the other.
- */
-int
-__mnt3_resolve_export_subdir_comp (mnt3_resolve_t *mres)
-{
- char dupsubdir[MNTPATHLEN];
- char *nextcomp = NULL;
- int ret = -EFAULT;
- nfs_user_t nfu = {0, };
- uuid_t gfid = {0, };
-
- if (!mres)
- return ret;
-
- nextcomp = setup_next_component (mres->remainingdir,
- sizeof (mres->remainingdir),
- dupsubdir, sizeof (dupsubdir));
- if (!nextcomp)
- goto err;
-
- /* Wipe the contents of the previous component */
- uuid_copy (gfid, mres->resolveloc.inode->gfid);
- nfs_loc_wipe (&mres->resolveloc);
- ret = nfs_entry_loc_fill (mres->exp->vol->itable, gfid, nextcomp,
- &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 (gfid), nextcomp);
- ret = -EFAULT;
- goto err;
- }
-
- nfs_request_user_init (&nfu, mres->req);
- ret = nfs_lookup (mres->mstate->nfsx, mres->exp->vol, &nfu,
- &mres->resolveloc, mnt3_resolve_subdir_cbk, mres);
-
-err:
- return ret;
-}
-
-
-int32_t
-mnt3_resolve_subdir_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)
-{
- mnt3_resolve_t *mres = NULL;
- mountstat3 mntstat = MNT3ERR_SERVERFAULT;
- struct nfs3_fh fh = {{0}, };
- int autharr[10];
- int autharrlen = 0;
- rpcsvc_t *svc = NULL;
- mountres3 res = {0, };
- xlator_t *mntxl = NULL;
- char *path = NULL;
-
- 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;
- }
-
- inode_link (mres->resolveloc.inode, mres->resolveloc.parent,
- mres->resolveloc.name, buf);
-
- nfs3_fh_build_child_fh (&mres->parentfh, buf, &fh);
- if (strlen (mres->remainingdir) <= 0) {
- op_ret = -1;
- mntstat = MNT3_OK;
- path = GF_CALLOC (PATH_MAX, sizeof (char), gf_nfs_mt_char);
- if (!path) {
- gf_log (GF_MNT, GF_LOG_ERROR, "Memory allocation "
- "failed");
- goto err;
- }
- snprintf (path, PATH_MAX, "/%s%s", mres->exp->vol->name,
- mres->resolveloc.path);
- mnt3svc_update_mountlist (mres->mstate, mres->req,
- path);
- GF_FREE (path);
- } else {
- mres->parentfh = fh;
- op_ret = __mnt3_resolve_export_subdir_comp (mres);
- if (op_ret < 0)
- mntstat = mnt3svc_errno_to_mnterr (-op_ret);
- }
-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);
-
- res = mnt3svc_set_mountres3 (mntstat, &fh, autharr, autharrlen);
- mnt3svc_submit_reply (mres->req, (void *)&res,
- (mnt3_serializer)xdr_serialize_mountres3);
- mnt3_resolve_state_wipe (mres);
- }
-
- return 0;
-}
-
-
-
-/* We will always have to perform a hard lookup on all the components of a
- * directory export for a mount request because in the mount reply we need the
- * file handle of the directory. Our file handle creation code is designed with
- * the assumption that to build a child file/dir fh, we'll always have the
- * parent dir's fh available so that we may copy the hash array of the previous
- * dir levels.
- *
- * Since we do not store the file handles anywhere, for every mount request we
- * must resolve the file handles of every component so that the parent dir file
- * of the exported directory can be built.
- */
-int
-__mnt3_resolve_subdir (mnt3_resolve_t *mres)
-{
- char dupsubdir[MNTPATHLEN];
- char *firstcomp = NULL;
- int ret = -EFAULT;
- nfs_user_t nfu = {0, };
- uuid_t rootgfid = {0, };
-
- if (!mres)
- return ret;
-
- firstcomp = setup_next_component (mres->remainingdir,
- sizeof (mres->remainingdir),
- dupsubdir, sizeof (dupsubdir));
- if (!firstcomp)
- goto err;
-
- rootgfid[15] = 1;
- ret = nfs_entry_loc_fill (mres->exp->vol->itable, rootgfid, firstcomp,
- &mres->resolveloc, NFS_RESOLVE_CREATE);
- if ((ret < 0) && (ret != -2)) {
- gf_log (GF_MNT, GF_LOG_ERROR, "Failed to resolve and create "
- "inode for volume root: %s", mres->exp->vol->name);
- ret = -EFAULT;
- goto err;
- }
-
- nfs_request_user_init (&nfu, mres->req);
- ret = nfs_lookup (mres->mstate->nfsx, mres->exp->vol, &nfu,
- &mres->resolveloc, mnt3_resolve_subdir_cbk, mres);
-
-err:
- return ret;
-}
-
-
-static gf_boolean_t
-mnt3_match_subnet_v4 (struct addrinfo *ai, uint32_t saddr, uint32_t mask)
-{
- for (; ai; ai = ai->ai_next) {
- struct sockaddr_in *sin = (struct sockaddr_in *)ai->ai_addr;
-
- if (sin->sin_family != AF_INET)
- continue;
-
- if (mask_match (saddr, sin->sin_addr.s_addr, mask))
- return _gf_true;
- }
-
- return _gf_false;
-}
-
-
-/**
- * This function will verify if the client is allowed to mount
- * the directory or not. Client's IP address will be compared with
- * allowed IP list or range present in mnt3_export structure.
- *
- * @param req - RPC request. This structure contains client's IP address.
- * @param export - mnt3_export structure. Contains allowed IP list/range.
- *
- * @return 0 - on Success and -EACCES on failure.
- *
- * TODO: Support IPv6 subnetwork
- */
-int
-mnt3_verify_auth (rpcsvc_request_t *req, struct mnt3_export *export)
-{
- int retvalue = -EACCES;
- int ret = 0;
- struct host_auth_spec *host = NULL;
- struct sockaddr_in *client_addr = NULL;
- struct sockaddr_in *allowed_addr = NULL;
- struct addrinfo *allowed_addrinfo = NULL;
-
- struct addrinfo hint = {
- .ai_family = AF_INET,
- .ai_protocol = (int)IPPROTO_TCP,
- .ai_flags = AI_CANONNAME,
- };
-
- /* Sanity check */
- if ((NULL == req) ||
- (NULL == req->trans) ||
- (NULL == export) ||
- (NULL == export->hostspec)) {
- gf_log (GF_MNT, GF_LOG_ERROR, "Invalid argument");
- return retvalue;
- }
-
- host = export->hostspec;
-
- /* Client's IP address. */
- client_addr = (struct sockaddr_in *)(&(req->trans->peerinfo.sockaddr));
-
- /*
- * Currently IPv4 subnetwork is supported i.e. AF_INET.
- * TODO: IPv6 subnetwork i.e. AF_INET6.
- */
- if (client_addr->sin_family != AF_INET) {
- gf_log (GF_MNT, GF_LOG_ERROR,
- "Only IPv4 is supported for subdir-auth");
- return retvalue;
- }
-
- /* Try to see if the client IP matches the allowed IP list.*/
- while (NULL != host){
- GF_ASSERT (host->host_addr);
-
- if (NULL != allowed_addrinfo) {
- freeaddrinfo (allowed_addrinfo);
- allowed_addrinfo = NULL;
- }
-
- /* Get the addrinfo for the allowed host (host_addr). */
- ret = getaddrinfo (host->host_addr, NULL,
- &hint, &allowed_addrinfo);
- if (0 != ret){
- /*
- * getaddrinfo() FAILED for the host IP addr. Continue
- * to search other allowed hosts in the hostspec list.
- */
- gf_log (GF_MNT, GF_LOG_DEBUG,
- "getaddrinfo: %s\n", gai_strerror (ret));
- host = host->next;
- continue;
- }
-
- allowed_addr = (struct sockaddr_in *)(allowed_addrinfo->ai_addr);
- if (NULL == allowed_addr) {
- gf_log (GF_MNT, GF_LOG_ERROR, "Invalid structure");
- break;
- }
-
- /* Check if the network addr of both IPv4 socket match */
- if (mnt3_match_subnet_v4 (allowed_addrinfo,
- client_addr->sin_addr.s_addr,
- host->netmask)) {
- retvalue = 0;
- break;
- }
-
- /* No match yet, continue the search */
- host = host->next;
- }
-
- /* FREE the dynamic memory allocated by getaddrinfo() */
- if (NULL != allowed_addrinfo) {
- freeaddrinfo (allowed_addrinfo);
- }
-
- return retvalue;
-}
-
-int
-mnt3_resolve_subdir (rpcsvc_request_t *req, struct mount3_state *ms,
- struct mnt3_export *exp, char *subdir)
-{
- mnt3_resolve_t *mres = NULL;
- int ret = -EFAULT;
- struct nfs3_fh pfh = GF_NFS3FH_STATIC_INITIALIZER;
-
- if ((!req) || (!ms) || (!exp) || (!subdir))
- return ret;
-
- /* Need to check AUTH */
- if (NULL != exp->hostspec) {
- ret = mnt3_verify_auth (req, exp);
- if (0 != ret) {
- gf_log (GF_MNT,GF_LOG_ERROR,
- "AUTH verification failed");
- return ret;
- }
- }
-
- mres = GF_CALLOC (1, sizeof (mnt3_resolve_t), gf_nfs_mt_mnt3_resolve);
- if (!mres) {
- gf_log (GF_MNT, GF_LOG_ERROR, "Memory allocation failed");
- goto err;
- }
-
- mres->exp = exp;
- mres->mstate = ms;
- mres->req = req;
- strncpy (mres->remainingdir, subdir, MNTPATHLEN);
- if (gf_nfs_dvm_off (nfs_state (ms->nfsx)))
- pfh = nfs3_fh_build_indexed_root_fh (mres->mstate->nfsx->children, mres->exp->vol);
- else
- pfh = nfs3_fh_build_uuid_root_fh (exp->volumeid);
-
- mres->parentfh = pfh;
- ret = __mnt3_resolve_subdir (mres);
- if (ret < 0) {
- gf_log (GF_MNT, GF_LOG_ERROR, "Failed to resolve export dir: %s"
- , mres->exp->expname);
- GF_FREE (mres);
- }
-
-err:
- return ret;
-}
-
-
-int
-mnt3_resolve_export_subdir (rpcsvc_request_t *req, struct mount3_state *ms,
- struct mnt3_export *exp)
-{
- char *volume_subdir = NULL;
- int ret = -EFAULT;
-
- if ((!req) || (!ms) || (!exp))
- return ret;
-
- volume_subdir = __volume_subdir (exp->expname, NULL);
- if (!volume_subdir)
- goto err;
-
- ret = mnt3_resolve_subdir (req, ms, exp, volume_subdir);
- if (ret < 0) {
- gf_log (GF_MNT, GF_LOG_ERROR, "Failed to resolve export dir: %s"
- , exp->expname);
- goto err;
- }
-
-err:
- return ret;
-}
-
-
-int
-mnt3svc_mount (rpcsvc_request_t *req, struct mount3_state *ms,
- struct mnt3_export *exp)
-{
- int ret = -EFAULT;
-
- if ((!req) || (!ms) || (!exp))
- return ret;
-
- if (exp->exptype == MNT3_EXPTYPE_VOLUME)
- ret = mnt3svc_volume_mount (req, ms, exp);
- else if (exp->exptype == MNT3_EXPTYPE_DIR)
- ret = mnt3_resolve_export_subdir (req, ms, exp);
-
- return ret;
-}
-
-
-/* mnt3_mntpath_to_xlator sets this to 1 if the mount is for a full
-* volume or 2 for a subdir in the volume.
-*/
-struct mnt3_export *
-mnt3_mntpath_to_export (struct mount3_state *ms, char *dirpath)
-{
- struct mnt3_export *exp = NULL;
- struct mnt3_export *found = NULL;
-
- if ((!ms) || (!dirpath))
- return NULL;
-
- LOCK (&ms->mountlock);
- list_for_each_entry (exp, &ms->exportlist, explist) {
-
- /* Search for the an exact match with the volume */
- if (mnt3_match_dirpath_export (exp->expname, dirpath)) {
- found = exp;
- gf_log (GF_MNT, GF_LOG_DEBUG, "Found export volume: "
- "%s", exp->vol->name);
- goto foundexp;
- }
- }
-
- gf_log (GF_MNT, GF_LOG_DEBUG, "Export not found");
-foundexp:
- UNLOCK (&ms->mountlock);
- return found;
-}
-
-
-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;
-
- 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_auth_check (svc, targetxl->name, trans);
- if (ret == RPCSVC_AUTH_REJECT) {
- gf_log (GF_MNT, GF_LOG_INFO, "Peer %s not allowed", peer);
- goto err;
- }
-
- ret = rpcsvc_transport_privport_check (svc, targetxl->name,
- rpcsvc_request_transport (req));
- if (ret == RPCSVC_AUTH_REJECT) {
- gf_log (GF_MNT, GF_LOG_INFO, "Peer %s rejected. Unprivileged "
- "port not allowed", peer);
- goto err;
- }
-
- ret = 0;
-err:
- return ret;
-}
-
-
-int
-mnt3_parse_dir_exports (rpcsvc_request_t *req, struct mount3_state *ms,
- char *subdir)
-{
- char volname[1024];
- struct mnt3_export *exp = NULL;
- char *volname_ptr = NULL;
- int ret = -ENOENT;
- struct nfs_state *nfs = NULL;
-
- if ((!ms) || (!subdir))
- return -1;
-
- volname_ptr = volname;
- subdir = __volume_subdir (subdir, &volname_ptr);
- if (!subdir)
- goto err;
-
- exp = mnt3_mntpath_to_export (ms, volname);
- if (!exp)
- goto err;
-
- nfs = (struct nfs_state *)ms->nfsx->private;
- if (!nfs)
- goto err;
-
- if (!nfs_subvolume_started (nfs, exp->vol)) {
- gf_log (GF_MNT, GF_LOG_DEBUG,
- "Volume %s not started", exp->vol->name);
- goto err;
- }
-
- if (mnt3_check_client_net (ms, req, exp->vol) == RPCSVC_AUTH_REJECT) {
- gf_log (GF_MNT, GF_LOG_DEBUG, "Client mount not allowed");
- ret = -EACCES;
- goto err;
- }
-
- ret = mnt3_resolve_subdir (req, ms, exp, subdir);
- if (ret < 0) {
- gf_log (GF_MNT, GF_LOG_ERROR,
- "Failed to resolve export dir: %s", subdir);
- goto err;
- }
-
-err:
- return ret;
-}
-
-
-int
-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;
-
- if ((!req) || (!path) || (!e))
- return -1;
-
- ms = (struct mount3_state *) rpcsvc_request_program_private (req);
- if (!ms) {
- gf_log (GF_MNT, GF_LOG_ERROR, "Mount state not present");
- rpcsvc_request_seterr (req, SYSTEM_ERR);
- goto err;
- }
-
- gf_log (GF_MNT, GF_LOG_DEBUG, "dirpath: %s", path);
- exp = mnt3_mntpath_to_export (ms, path);
- if (exp) {
- ret = 0;
- *e = exp;
- goto err;
- }
-
- if (!gf_mnt3_export_dirs(ms)) {
- ret = -1;
- goto err;
- }
-
- ret = mnt3_parse_dir_exports (req, ms, path);
-
-err:
- return ret;
-}
-
-
-int
-mnt3svc_mnt (rpcsvc_request_t *req)
-{
- struct iovec pvec = {0, };
- char path[MNTPATHLEN];
- int ret = -1;
- struct mount3_state *ms = NULL;
- mountstat3 mntstat = MNT3ERR_SERVERFAULT;
- struct mnt3_export *exp = NULL;
- struct nfs_state *nfs = NULL;
-
- if (!req)
- return -1;
-
- pvec.iov_base = path;
- pvec.iov_len = MNTPATHLEN;
- ret = xdr_to_mountpath (pvec, req->msg[0]);
- if (ret == -1) {
- gf_log (GF_MNT, GF_LOG_ERROR, "Failed to decode args");
- rpcsvc_request_seterr (req, GARBAGE_ARGS);
- goto rpcerr;
- }
-
- ms = (struct mount3_state *)rpcsvc_request_program_private (req);
- if (!ms) {
- gf_log (GF_MNT, GF_LOG_ERROR, "Mount state not present");
- rpcsvc_request_seterr (req, SYSTEM_ERR);
- ret = -1;
- goto rpcerr;
- }
-
- nfs = (struct nfs_state *)ms->nfsx->private;
- gf_log (GF_MNT, GF_LOG_DEBUG, "dirpath: %s", path);
- ret = mnt3_find_export (req, path, &exp);
- if (ret < 0) {
- mntstat = mnt3svc_errno_to_mnterr (-ret);
- goto mnterr;
- } else if (!exp) {
- /*
- * SPECIAL CASE: exp is NULL if "path" is subdir in
- * call to mnt3_find_export().
- *
- * This is subdir mount, we are already DONE!
- * nfs_subvolume_started() and mnt3_check_client_net()
- * validation are done in mnt3_parse_dir_exports()
- * which is invoked through mnt3_find_export().
- *
- * TODO: All mount should happen thorugh mnt3svc_mount()
- * It needs more clean up.
- */
- return (0);
- }
-
- if (!nfs_subvolume_started (nfs, exp->vol)) {
- gf_log (GF_MNT, GF_LOG_DEBUG, "Volume %s not started",
- exp->vol->name);
- ret = -1;
- mntstat = MNT3ERR_NOENT;
- goto mnterr;
- }
-
- ret = mnt3_check_client_net (ms, req, exp->vol);
- if (ret == RPCSVC_AUTH_REJECT) {
- mntstat = MNT3ERR_ACCES;
- gf_log (GF_MNT, GF_LOG_DEBUG, "Client mount not allowed");
- ret = -1;
- goto mnterr;
- }
-
- ret = mnt3svc_mount (req, ms, exp);
- if (ret < 0)
- mntstat = mnt3svc_errno_to_mnterr (-ret);
-mnterr:
- if (ret < 0) {
- mnt3svc_mnt_error_reply (req, mntstat);
- ret = 0;
- }
-
-rpcerr:
- return ret;
-}
-
-
-int
-mnt3svc_null (rpcsvc_request_t *req)
-{
- struct iovec dummyvec = {0, };
-
- if (!req) {
- gf_log (GF_MNT, GF_LOG_ERROR, "Got NULL request!");
- return 0;
- }
- rpcsvc_submit_generic (req, &dummyvec, 1, NULL, 0, NULL);
- return 0;
-}
-
-
-mountlist
-__build_mountlist (struct mount3_state *ms, int *count)
-{
- struct mountbody *mlist = NULL;
- struct mountbody *prev = NULL;
- struct mountbody *first = NULL;
- size_t namelen = 0;
- int ret = -1;
- struct mountentry *me = NULL;
-
- if ((!ms) || (!count))
- return NULL;
-
- /* read rmtab, other peers might have updated it */
- mount_read_rmtab(ms);
-
- *count = 0;
- gf_log (GF_MNT, GF_LOG_DEBUG, "Building mount list:");
- list_for_each_entry (me, &ms->mountlist, mlist) {
- namelen = strlen (me->exname);
- mlist = GF_CALLOC (1, sizeof (*mlist), gf_nfs_mt_mountbody);
- if (!mlist) {
- gf_log (GF_MNT, GF_LOG_ERROR, "Memory allocation"
- " failed");
- goto free_list;
- }
- if (!first)
- first = mlist;
-
- mlist->ml_directory = GF_CALLOC (namelen + 2, sizeof (char),
- gf_nfs_mt_char);
- if (!mlist->ml_directory) {
- gf_log (GF_MNT, GF_LOG_ERROR, "Memory allocation"
- " failed");
- goto free_list;
- }
-
- strcpy (mlist->ml_directory, me->exname);
-
- namelen = strlen (me->hostname);
- mlist->ml_hostname = GF_CALLOC (namelen + 2, sizeof (char),
- gf_nfs_mt_char);
- if (!mlist->ml_hostname) {
- gf_log (GF_MNT, GF_LOG_ERROR, "Memory allocation"
- " failed");
- goto free_list;
- }
-
- strcat (mlist->ml_hostname, me->hostname);
-
- gf_log (GF_MNT, GF_LOG_DEBUG, "mount entry: dir: %s, host: %s",
- mlist->ml_directory, mlist->ml_hostname);
- if (prev) {
- prev->ml_next = mlist;
- prev = mlist;
- } else
- prev = mlist;
-
- (*count)++;
- }
-
- ret = 0;
-
-free_list:
- if (ret == -1) {
- xdr_free_mountlist (first);
- first = NULL;
- }
-
- return first;
-}
-
-
-mountlist
-mnt3svc_build_mountlist (struct mount3_state *ms, int *count)
-{
- struct mountbody *first = NULL;
-
- LOCK (&ms->mountlock);
- {
- first = __build_mountlist (ms, count);
- }
- UNLOCK (&ms->mountlock);
-
- return first;
-}
-
-
-int
-mnt3svc_dump (rpcsvc_request_t *req)
-{
- int ret = -1;
- struct mount3_state *ms = NULL;
- mountlist mlist;
- mountstat3 mstat = 0;
- mnt3_serializer sfunc = NULL;
- void *arg = NULL;
-
-
- if (!req)
- return -1;
-
- ms = (struct mount3_state *)rpcsvc_request_program_private (req);
- if (!ms) {
- rpcsvc_request_seterr (req, SYSTEM_ERR);
- goto rpcerr;
- }
-
- sfunc = (mnt3_serializer)xdr_serialize_mountlist;
- mlist = mnt3svc_build_mountlist (ms, &ret);
- arg = &mlist;
-
- if (!mlist) {
- if (ret != 0) {
- rpcsvc_request_seterr (req, SYSTEM_ERR);
- ret = -1;
- goto rpcerr;
- } else {
- arg = &mstat;
- sfunc = (mnt3_serializer)xdr_serialize_mountstat3;
- }
- }
-
- mnt3svc_submit_reply (req, arg, sfunc);
-
- xdr_free_mountlist (mlist);
- ret = 0;
-
-rpcerr:
- return ret;
-}
-
-
-int
-mnt3svc_umount (struct mount3_state *ms, char *dirpath, char *hostname)
-{
- struct mountentry *me = NULL;
- int ret = -1;
- gf_store_handle_t *sh = NULL;
- struct nfs_state *nfs = NULL;
- gf_boolean_t update_rmtab = _gf_false;
-
- if ((!ms) || (!dirpath) || (!hostname))
- return -1;
-
- nfs = (struct nfs_state *)ms->nfsx->private;
-
- update_rmtab = mount_open_rmtab (nfs->rmtab, &sh);
- if (update_rmtab) {
- ret = gf_store_lock (sh);
- if (ret)
- goto out_free;
- }
-
- LOCK (&ms->mountlock);
- {
- if (update_rmtab)
- __mount_read_rmtab (sh, &ms->mountlist, _gf_false);
-
- if (list_empty (&ms->mountlist)) {
- ret = 0;
- goto out_unlock;
- }
-
- ret = -1;
- list_for_each_entry (me, &ms->mountlist, mlist) {
- if ((strcmp (me->exname, dirpath) == 0) &&
- (strcmp (me->hostname, hostname) == 0)) {
- ret = 0;
- break;
- }
- }
-
- /* Need this check here because at the end of the search me
- * might still be pointing to the last entry, which may not be
- * the one we're looking for.
- */
- if (ret == -1) {/* Not found in list. */
- gf_log (GF_MNT, GF_LOG_TRACE, "Export not found");
- goto out_unlock;
- }
-
- if (!me)
- goto out_unlock;
-
- gf_log (GF_MNT, GF_LOG_DEBUG, "Unmounting: dir %s, host: %s",
- me->exname, me->hostname);
-
- list_del (&me->mlist);
- GF_FREE (me);
-
- if (update_rmtab)
- __mount_rewrite_rmtab (ms, sh);
- }
-out_unlock:
- UNLOCK (&ms->mountlock);
-
- if (update_rmtab)
- gf_store_unlock (sh);
-
-out_free:
- if (update_rmtab)
- gf_store_handle_destroy (sh);
-
- return ret;
-}
-
-
-int
-mnt3svc_umnt (rpcsvc_request_t *req)
-{
- char hostname[MNTPATHLEN];
- char dirpath[MNTPATHLEN];
- struct iovec pvec = {0, };
- int ret = -1;
- struct mount3_state *ms = NULL;
- mountstat3 mstat = MNT3_OK;
- char *colon = NULL;
-
- if (!req)
- return -1;
-
- /* Remove the mount point from the exports list. */
- pvec.iov_base = dirpath;
- pvec.iov_len = MNTPATHLEN;
- ret = xdr_to_mountpath (pvec, req->msg[0]);
- if (ret == -1) {
- gf_log (GF_MNT, GF_LOG_ERROR, "Failed decode args");
- rpcsvc_request_seterr (req, GARBAGE_ARGS);
- goto rpcerr;
- }
-
- ms = (struct mount3_state *)rpcsvc_request_program_private (req);
- if (!ms) {
- gf_log (GF_MNT, GF_LOG_ERROR, "Mount state not present");
- rpcsvc_request_seterr (req, SYSTEM_ERR);
- ret = -1;
- goto rpcerr;
- }
-
- ret = rpcsvc_transport_peername (req->trans, hostname, MNTPATHLEN);
- if (ret != 0) {
- gf_log (GF_MNT, GF_LOG_ERROR, "Failed to get remote name: %s",
- gai_strerror (ret));
- goto rpcerr;
- }
-
- 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;
- }
- /* FIXME: also take care of the corner case where the
- * client was resolvable at mount but not at the umount - vice-versa.
- */
- mnt3svc_submit_reply (req, &mstat,
- (mnt3_serializer)xdr_serialize_mountstat3);
-
-rpcerr:
- return ret;
-}
-
-
-int
-__mnt3svc_umountall (struct mount3_state *ms)
-{
- struct mountentry *me = NULL;
- struct mountentry *tmp = NULL;
-
- if (!ms)
- return -1;
-
- if (list_empty (&ms->mountlist))
- return 0;
-
- list_for_each_entry_safe (me, tmp, &ms->mountlist, mlist) {
- list_del (&me->mlist);
- GF_FREE (me);
- }
-
- return 0;
-}
-
-
-int
-mnt3svc_umountall (struct mount3_state *ms)
-{
- int ret = -1;
- if (!ms)
- return -1;
-
- LOCK (&ms->mountlock);
- {
- ret = __mnt3svc_umountall (ms);
- }
- UNLOCK (&ms->mountlock);
-
- return ret;
-}
-
-
-int
-mnt3svc_umntall (rpcsvc_request_t *req)
-{
- int ret = RPCSVC_ACTOR_ERROR;
- struct mount3_state *ms = NULL;
- mountstat3 mstat = MNT3_OK;
-
- if (!req)
- return ret;
-
- ms = (struct mount3_state *)rpcsvc_request_program_private (req);
- if (!ms) {
- gf_log (GF_MNT, GF_LOG_ERROR, "Mount state not present");
- rpcsvc_request_seterr (req, SYSTEM_ERR);
- goto rpcerr;
- }
-
- mnt3svc_umountall (ms);
- mnt3svc_submit_reply (req, &mstat,
- (mnt3_serializer)xdr_serialize_mountstat3);
-
- ret = RPCSVC_ACTOR_SUCCESS;
-rpcerr:
- return ret;
-}
-
-
-exports
-mnt3_xlchildren_to_exports (rpcsvc_t *svc, struct mount3_state *ms)
-{
- struct exportnode *elist = NULL;
- struct exportnode *prev = NULL;
- struct exportnode *first = NULL;
- size_t namelen = 0;
- int ret = -1;
- char *addrstr = NULL;
- struct mnt3_export *ent = NULL;
- struct nfs_state *nfs = NULL;
-
- if ((!ms) || (!svc))
- return NULL;
-
- nfs = (struct nfs_state *)ms->nfsx->private;
- if (!nfs)
- return NULL;
-
- LOCK (&ms->mountlock);
- list_for_each_entry(ent, &ms->exportlist, explist) {
-
- /* If volume is not started yet, do not list it for tools like
- * showmount.
- */
- if (!nfs_subvolume_started (nfs, ent->vol))
- continue;
-
- namelen = strlen (ent->expname) + 1;
- elist = GF_CALLOC (1, sizeof (*elist), gf_nfs_mt_exportnode);
- if (!elist) {
- gf_log (GF_MNT, GF_LOG_ERROR, "Memory allocation"
- " failed");
- goto free_list;
- }
- if (!first)
- first = elist;
- elist->ex_dir = GF_CALLOC (namelen + 2, sizeof (char),
- gf_nfs_mt_char);
- if (!elist->ex_dir) {
- gf_log (GF_MNT, GF_LOG_ERROR, "Memory allocation"
- " failed");
- goto free_list;
- }
- strcpy (elist->ex_dir, ent->expname);
-
- addrstr = rpcsvc_volume_allowed (svc->options,
- ent->vol->name);
- elist->ex_groups = GF_CALLOC (1, sizeof (struct groupnode),
- gf_nfs_mt_groupnode);
- if (!elist->ex_groups) {
- gf_log (GF_MNT, GF_LOG_ERROR, "Memory allocation"
- " failed");
- goto free_list;
- }
- /*This check has to be done after checking
- * elist->ex_groups allocation check to avoid resource leak;
- */
- if (addrstr)
- addrstr = gf_strdup (addrstr);
- else
- addrstr = gf_strdup ("No Access");
-
- if (!addrstr) {
- goto free_list;
- }
- elist->ex_groups->gr_name = addrstr;
- if (prev) {
- prev->ex_next = elist;
- prev = elist;
- } else
- prev = elist;
- }
-
- ret = 0;
-
-free_list:
- UNLOCK (&ms->mountlock);
- if (ret == -1) {
- xdr_free_exports_list (first);
- first = NULL;
- }
-
- return first;
-}
-
-
-int
-mnt3svc_export (rpcsvc_request_t *req)
-{
- struct mount3_state *ms = NULL;
- exports elist = NULL;
- int ret = -1;
-
- if (!req)
- return -1;
-
- ms = (struct mount3_state *)rpcsvc_request_program_private (req);
- if (!ms) {
- gf_log (GF_MNT, GF_LOG_ERROR, "mount state not found");
- 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),
- 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
- * and confusing the user.
- if (!elist) {
- gf_log (GF_MNT, GF_LOG_ERROR, "Failed to build exports list");
- nfs_rpcsvc_request_seterr (req, SYSTEM_ERR);
- goto err;
- }
- */
-
- /* Note how the serializer is passed to the generic reply function. */
- mnt3svc_submit_reply (req, &elist,
- (mnt3_serializer)xdr_serialize_exports);
-
- xdr_free_exports_list (elist);
- ret = 0;
-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++;
-
- strncpy (me->exname, export, MNTPATHLEN);
- strncpy (me->hostname, host, MNTPATHLEN);
- INIT_LIST_HEAD (&me->mlist);
- LOCK (&ms->mountlock);
- {
- list_add_tail (&me->mlist, &ms->mountlist);
- mount_rewrite_rmtab(ms, NULL);
- }
- 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;
-}
-
-/**
- * This function will parse the hostip (IP addres, IP range, or hostname)
- * and fill the host_auth_spec structure.
- *
- * @param hostspec - struct host_auth_spec
- * @param hostip - IP address, IP range (CIDR format) or hostname
- *
- * @return 0 - on success and -1 on failure
- *
- * NB: This does not support IPv6 currently.
- */
-int
-mnt3_export_fill_hostspec (struct host_auth_spec* hostspec, const char* hostip)
-{
- char *ipdupstr = NULL;
- char *savptr = NULL;
- char *endptr = NULL;
- char *ip = NULL;
- char *token = NULL;
- int ret = -1;
- long prefixlen = IPv4_ADDR_SIZE; /* default */
- uint32_t shiftbits = 0;
- size_t length = 0;
-
- /* Create copy of the string so that the source won't change
- */
- ipdupstr = gf_strdup (hostip);
- if (NULL == ipdupstr) {
- gf_log (GF_MNT, GF_LOG_ERROR, "Memory allocation failed");
- goto err;
- }
-
- ip = strtok_r (ipdupstr, "/", &savptr);
- /* Validate the Hostname or IPv4 address
- * TODO: IPv6 support for subdir auth.
- */
- length = strlen (ip);
- if ((!valid_ipv4_address (ip, (int)length, _gf_false)) &&
- (!valid_host_name (ip, (int)length))) {
- gf_log (GF_MNT, GF_LOG_ERROR,
- "Invalid hostname or IPv4 address: %s", ip);
- goto err;
- }
-
- hostspec->host_addr = gf_strdup (ip);
- if (NULL == hostspec->host_addr) {
- gf_log (GF_MNT, GF_LOG_ERROR, "Memory allocation failed");
- goto err;
- }
-
- /**
- * User provided CIDR address (xx.xx.xx.xx/n format) is split
- * into HOST (IP addr or hostname) and network prefix(n) from
- * which netmask would be calculated. This CIDR address may
- * denote a single, distinct interface address or the beginning
- * address of an entire network.
- *
- * e.g. the IPv4 block 192.168.100.0/24 represents the 256
- * IPv4 addresses from 192.168.100.0 to 192.168.100.255.
- * Therefore to check if an IP matches 192.168.100.0/24
- * we should mask the IP with FFFFFF00 and compare it with
- * host address part of CIDR.
- *
- * Refer: mask_match() in common-utils.c.
- */
- token = strtok_r (NULL, "/", &savptr);
- if (token != NULL) {
- prefixlen = strtol (token, &endptr, 10);
- if ((errno != 0) || (*endptr != '\0') ||
- (prefixlen < 0) || (prefixlen > IPv4_ADDR_SIZE)) {
- gf_log (THIS->name, GF_LOG_WARNING,
- "Invalid IPv4 subnetwork mask");
- goto err;
- }
- }
-
- /*
- * 1. Calculate the network mask address.
- * 2. Convert it into Big-Endian format.
- * 3. Store it in hostspec netmask.
- */
- shiftbits = IPv4_ADDR_SIZE - prefixlen;
- hostspec->netmask = htonl ((uint32_t)~0 << shiftbits);
-
- ret = 0; /* SUCCESS */
-err:
- if (NULL != ipdupstr) {
- GF_FREE (ipdupstr);
- }
- return ret;
-}
-
-
-/**
- * This function will parse the AUTH parameter passed along with
- * "export-dir" option. If AUTH parameter is present then it will be
- * stripped from exportpath and stored in mnt3_export (exp) structure.
- *
- * @param exp - mnt3_export structure. Holds information needed for mount.
- * @param exportpath - Value of "export-dir" key. Holds both export path
- * and AUTH parameter for the path.
- * exportpath format: <abspath>[(hostdesc[|hostspec|...])]
- *
- * @return This function will return 0 on success and -1 on failure.
- */
-int
-mnt3_export_parse_auth_param (struct mnt3_export* exp, char* exportpath)
-{
- char *token = NULL;
- char *savPtr = NULL;
- char *hostip = NULL;
- struct host_auth_spec *host = NULL;
- int ret = 0;
-
- /* Using exportpath directly in strtok_r because we want
- * to strip off AUTH parameter from exportpath. */
- token = strtok_r (exportpath, "(", &savPtr);
-
- /* Get the next token, which will be the AUTH parameter. */
- token = strtok_r (NULL, ")", &savPtr);
-
- if (NULL == token) {
- /* If AUTH is not present then we should return success. */
- return 0;
- }
-
- /* Free any previously allocated hostspec structure. */
- if (NULL != exp->hostspec) {
- GF_FREE (exp->hostspec);
- exp->hostspec = NULL;
- }
-
- exp->hostspec = GF_CALLOC (1,
- sizeof (*(exp->hostspec)),
- gf_nfs_mt_auth_spec);
- if (NULL == exp->hostspec){
- gf_log (GF_MNT, GF_LOG_ERROR, "Memory allocation failed");
- return -1;
- }
-
- /* AUTH parameter can have multiple entries. For each entry
- * a host_auth_spec structure is created. */
- host = exp->hostspec;
-
- hostip = strtok_r (token, "|", &savPtr);
-
- /* Parse all AUTH parameters separated by '|' */
- while (NULL != hostip){
- ret = mnt3_export_fill_hostspec (host, hostip);
- if (0 != ret) {
- gf_log(GF_MNT, GF_LOG_WARNING,
- "Failed to parse hostspec: %s", hostip);
- goto err;
- }
-
- hostip = strtok_r (NULL, "|", &savPtr);
- if (NULL == hostip) {
- break;
- }
-
- host->next = GF_CALLOC (1, sizeof (*(host)),
- gf_nfs_mt_auth_spec);
- if (NULL == host->next){
- gf_log (GF_MNT,GF_LOG_ERROR,
- "Memory allocation failed");
- goto err;
- }
- host = host->next;
- }
-
- /* In case of success return from here */
- return 0;
-err:
- /* In case of failure free up hostspec structure. */
- FREE_HOSTSPEC (exp);
-
- return -1;
-}
-
-/**
- * exportpath will also have AUTH options (ip address, subnet address or
- * hostname) mentioned.
- * exportpath format: <abspath>[(hostdesc[|hostspec|...])]
- */
-struct mnt3_export *
-mnt3_init_export_ent (struct mount3_state *ms, xlator_t *xl, char *exportpath,
- uuid_t volumeid)
-{
- struct mnt3_export *exp = NULL;
- int alloclen = 0;
- int ret = -1;
-
- if ((!ms) || (!xl))
- return NULL;
-
- exp = GF_CALLOC (1, sizeof (*exp), gf_nfs_mt_mnt3_export);
- if (!exp) {
- gf_log (GF_MNT, GF_LOG_ERROR, "Memory allocation failed");
- return NULL;
- }
-
- if (NULL != exportpath) {
- /* If exportpath is not NULL then we should check if AUTH
- * parameter is present or not. If AUTH parameter is present
- * then it will be stripped and stored in mnt3_export (exp)
- * structure.
- */
- if (0 != mnt3_export_parse_auth_param (exp, exportpath)){
- gf_log (GF_MNT, GF_LOG_ERROR,
- "Failed to parse auth param");
- goto err;
- }
- }
-
-
- INIT_LIST_HEAD (&exp->explist);
- if (exportpath)
- alloclen = strlen (xl->name) + 2 + strlen (exportpath);
- else
- alloclen = strlen (xl->name) + 2;
-
- exp->expname = GF_CALLOC (alloclen, sizeof (char), gf_nfs_mt_char);
- if (!exp->expname) {
- gf_log (GF_MNT, GF_LOG_ERROR, "Memory allocation failed");
- goto err;
- }
-
- if (exportpath) {
- gf_log (GF_MNT, GF_LOG_TRACE, "Initing dir export: %s:%s",
- xl->name, exportpath);
- exp->exptype = MNT3_EXPTYPE_DIR;
- ret = snprintf (exp->expname, alloclen, "/%s%s", xl->name,
- exportpath);
- } else {
- gf_log (GF_MNT, GF_LOG_TRACE, "Initing volume export: %s",
- xl->name);
- exp->exptype = MNT3_EXPTYPE_VOLUME;
- ret = snprintf (exp->expname, alloclen, "/%s", xl->name);
- }
- if (ret < 0) {
- gf_log (xl->name, GF_LOG_ERROR,
- "Failed to set the export name");
- goto err;
- }
- /* 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.
- */
- uuid_copy (exp->volumeid, volumeid);
- exp->vol = xl;
-
- /* On success we should return from here*/
- return exp;
-err:
- /* On failure free exp and it's members.*/
- if (NULL != exp) {
- mnt3_export_free (exp);
- exp = NULL;
- }
-
- return exp;
-}
-
-
-int
-__mnt3_init_volume_direxports (struct mount3_state *ms, xlator_t *xlator,
- char *optstr, uuid_t volumeid)
-{
- struct mnt3_export *newexp = NULL;
- int ret = -1;
- char *savptr = NULL;
- char *dupopt = NULL;
- char *token = NULL;
-
- if ((!ms) || (!xlator) || (!optstr))
- return -1;
-
- dupopt = gf_strdup (optstr);
- if (!dupopt) {
- gf_log (GF_MNT, GF_LOG_ERROR, "gf_strdup failed");
- goto err;
- }
-
- token = strtok_r (dupopt, ",", &savptr);
- while (token) {
- newexp = mnt3_init_export_ent (ms, xlator, token, volumeid);
- if (!newexp) {
- gf_log (GF_MNT, GF_LOG_ERROR, "Failed to init dir "
- "export: %s", token);
- ret = -1;
- goto err;
- }
-
- list_add_tail (&newexp->explist, &ms->exportlist);
- token = strtok_r (NULL, ",", &savptr);
- }
-
- ret = 0;
-err:
- GF_FREE (dupopt);
-
- return ret;
-}
-
-
-int
-__mnt3_init_volume (struct mount3_state *ms, dict_t *opts, xlator_t *xlator)
-{
- struct mnt3_export *newexp = NULL;
- int ret = -1;
- char searchstr[1024];
- char *optstr = NULL;
- uuid_t volumeid = {0, };
-
- if ((!ms) || (!xlator) || (!opts))
- return -1;
-
- uuid_clear (volumeid);
- if (gf_nfs_dvm_off (nfs_state (ms->nfsx)))
- goto no_dvm;
-
- ret = snprintf (searchstr, 1024, "nfs3.%s.volume-id", xlator->name);
- if (ret < 0) {
- gf_log (GF_MNT, GF_LOG_ERROR, "snprintf failed");
- ret = -1;
- goto err;
- }
-
- if (dict_get (opts, searchstr)) {
- ret = dict_get_str (opts, searchstr, &optstr);
- if (ret < 0) {
- gf_log (GF_MNT, GF_LOG_ERROR, "Failed to read option"
- ": %s", searchstr);
- ret = -1;
- goto err;
- }
- } else {
- gf_log (GF_MNT, GF_LOG_ERROR, "DVM is on but volume-id not "
- "given for volume: %s", xlator->name);
- ret = -1;
- goto err;
- }
-
- if (optstr) {
- ret = uuid_parse (optstr, volumeid);
- if (ret < 0) {
- gf_log (GF_MNT, GF_LOG_ERROR, "Failed to parse volume "
- "UUID");
- ret = -1;
- goto err;
- }
- }
-
-no_dvm:
- ret = snprintf (searchstr, 1024, "nfs3.%s.export-dir", xlator->name);
- if (ret < 0) {
- gf_log (GF_MNT, GF_LOG_ERROR, "snprintf failed");
- ret = -1;
- goto err;
- }
-
- if (dict_get (opts, searchstr)) {
- ret = dict_get_str (opts, searchstr, &optstr);
- if (ret < 0) {
- gf_log (GF_MNT, GF_LOG_ERROR, "Failed to read option: "
- "%s", searchstr);
- ret = -1;
- goto err;
- }
-
- ret = __mnt3_init_volume_direxports (ms, xlator, optstr,
- volumeid);
- if (ret == -1) {
- gf_log (GF_MNT, GF_LOG_ERROR, "Dir export setup failed"
- " for volume: %s", xlator->name);
- goto err;
- }
- }
-
- if (ms->export_volumes) {
- newexp = mnt3_init_export_ent (ms, xlator, NULL, volumeid);
- if (!newexp) {
- ret = -1;
- goto err;
- }
-
- list_add_tail (&newexp->explist, &ms->exportlist);
- }
- ret = 0;
-
-
-err:
- return ret;
-}
-
-
-int
-__mnt3_init_volume_export (struct mount3_state *ms, dict_t *opts)
-{
- int ret = -1;
- char *optstr = NULL;
- /* On by default. */
- gf_boolean_t boolt = _gf_true;
-
- if ((!ms) || (!opts))
- return -1;
-
- if (!dict_get (opts, "nfs3.export-volumes")) {
- ret = 0;
- goto err;
- }
-
- ret = dict_get_str (opts, "nfs3.export-volumes", &optstr);
- if (ret < 0) {
- gf_log (GF_MNT, GF_LOG_ERROR, "Failed to read option: "
- "nfs3.export-volumes");
- ret = -1;
- goto err;
- }
-
- ret = gf_string2boolean (optstr, &boolt);
- if (ret < 0) {
- gf_log (GF_MNT, GF_LOG_ERROR, "Failed to convert"
- " string to boolean");
- }
-
-err:
- if (boolt == _gf_false) {
- gf_log (GF_MNT, GF_LOG_TRACE, "Volume exports disabled");
- ms->export_volumes = 0;
- } else {
- gf_log (GF_MNT, GF_LOG_TRACE, "Volume exports enabled");
- ms->export_volumes = 1;
- }
-
- return ret;
-}
-
-
-int
-__mnt3_init_dir_export (struct mount3_state *ms, dict_t *opts)
-{
- int ret = -1;
- char *optstr = NULL;
- /* On by default. */
- gf_boolean_t boolt = _gf_true;
-
- if ((!ms) || (!opts))
- return -1;
-
- if (!dict_get (opts, "nfs3.export-dirs")) {
- ret = 0;
- goto err;
- }
-
- ret = dict_get_str (opts, "nfs3.export-dirs", &optstr);
- if (ret < 0) {
- gf_log (GF_MNT, GF_LOG_ERROR, "Failed to read option: "
- "nfs3.export-dirs");
- ret = -1;
- goto err;
- }
-
- ret = gf_string2boolean (optstr, &boolt);
- if (ret < 0) {
- gf_log (GF_MNT, GF_LOG_ERROR, "Failed to convert"
- " string to boolean");
- }
-
-err:
- if (boolt == _gf_false) {
- gf_log (GF_MNT, GF_LOG_TRACE, "Dir exports disabled");
- ms->export_dirs = 0;
- } else {
- gf_log (GF_MNT, GF_LOG_TRACE, "Dir exports enabled");
- ms->export_dirs = 1;
- }
-
- return ret;
-}
-
-
-int
-mnt3_init_options (struct mount3_state *ms, dict_t *options)
-{
- xlator_list_t *volentry = NULL;
- int ret = -1;
-
- if ((!ms) || (!options))
- return -1;
-
- __mnt3_init_volume_export (ms, options);
- __mnt3_init_dir_export (ms, options);
- volentry = ms->nfsx->children;
- while (volentry) {
- gf_log (GF_MNT, GF_LOG_TRACE, "Initing options for: %s",
- volentry->xlator->name);
- ret = __mnt3_init_volume (ms, options, volentry->xlator);
- if (ret < 0) {
- gf_log (GF_MNT, GF_LOG_ERROR, "Volume init failed");
- goto err;
- }
-
- volentry = volentry->next;
- }
-
- ret = 0;
-err:
- return ret;
-}
-
-
-struct mount3_state *
-mnt3_init_state (xlator_t *nfsx)
-{
- struct mount3_state *ms = NULL;
- int ret = -1;
-
- if (!nfsx)
- return NULL;
-
- ms = GF_CALLOC (1, sizeof (*ms), gf_nfs_mt_mount3_state);
- if (!ms) {
- gf_log (GF_MNT, GF_LOG_ERROR, "Memory allocation failed");
- return NULL;
- }
-
- ms->iobpool = nfsx->ctx->iobuf_pool;
- ms->nfsx = nfsx;
- INIT_LIST_HEAD (&ms->exportlist);
- ret = mnt3_init_options (ms, nfsx->options);
- if (ret < 0) {
- gf_log (GF_MNT, GF_LOG_ERROR, "Options init failed");
- return NULL;
- }
-
- INIT_LIST_HEAD (&ms->mountlist);
- LOCK_INIT (&ms->mountlock);
-
- 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, 0, DRC_NA},
- {"MNT", MOUNT3_MNT, mnt3svc_mnt, NULL, 0, DRC_NA},
- {"DUMP", MOUNT3_DUMP, mnt3svc_dump, NULL, 0, DRC_NA},
- {"UMNT", MOUNT3_UMNT, mnt3svc_umnt, NULL, 0, DRC_NA},
- {"UMNTALL", MOUNT3_UMNTALL, mnt3svc_umntall, NULL, 0, DRC_NA},
- {"EXPORT", MOUNT3_EXPORT, mnt3svc_export, NULL, 0, DRC_NA}
-};
-
-
-
-/* Static init parts are assigned here, dynamic ones are done in
- * mnt3svc_init and mnt3_init_state.
- * Making MOUNT3 a synctask so that the blocking DNS calls during rpc auth
- * gets offloaded to syncenv, keeping the main/poll thread unblocked
- */
-rpcsvc_program_t mnt3prog = {
- .progname = "MOUNT3",
- .prognum = MOUNT_PROGRAM,
- .progver = MOUNT_V3,
- .progport = GF_MOUNTV3_PORT,
- .actors = mnt3svc_actors,
- .numactors = MOUNT3_PROC_COUNT,
- .min_auth = AUTH_NULL,
- .synctask = _gf_true,
-};
-
-
-
-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)
- 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;
- 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;
- }
- }
-
- ret= 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, nfsx);
- }
- return &mnt3prog;
-err:
- return NULL;
-}
-
-
-rpcsvc_actor_t mnt1svc_actors[MOUNT1_PROC_COUNT] = {
- {"NULL", MOUNT1_NULL, mnt3svc_null, NULL, 0, DRC_NA},
- {"MNT", MOUNT1_MNT, NULL, NULL, 0, DRC_NA },
- {"DUMP", MOUNT1_DUMP, mnt3svc_dump, NULL, 0, DRC_NA},
- {"UMNT", MOUNT1_UMNT, mnt3svc_umnt, NULL, 0, DRC_NA},
- {"UMNTALL", MOUNT1_UMNTALL, NULL, NULL, 0, DRC_NA},
- {"EXPORT", MOUNT1_EXPORT, mnt3svc_export, NULL, 0, DRC_NA}
-};
-
-rpcsvc_program_t mnt1prog = {
- .progname = "MOUNT1",
- .prognum = MOUNT_PROGRAM,
- .progver = MOUNT_V1,
- .progport = GF_MOUNTV1_PORT,
- .actors = mnt1svc_actors,
- .numactors = MOUNT1_PROC_COUNT,
- .min_auth = AUTH_NULL,
- .synctask = _gf_true,
-};
-
-
-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)
- 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;
- if (!mstate) {
- gf_log (GF_MNT, GF_LOG_ERROR, "Mount v3 state init failed");
- goto err;
- }
-
- 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;
- }
- }
-
- ret = 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;
-}
-
-int
-mount_reconfigure_state (xlator_t *nfsx, dict_t *options)
-{
- int ret = -1;
- struct nfs_state *nfs = NULL;
- struct mount3_state *ms = NULL;
- struct mnt3_export *exp = NULL;
- struct mnt3_export *texp = NULL;
-
- if ((!nfsx) || (!options))
- return (-1);
-
- nfs = (struct nfs_state *)nfs_state (nfsx);
- if (!nfs)
- return (-1);
-
- ms = nfs->mstate;
- if (!ms)
- return (-1);
-
- /*
- * Free() up the old export list. mnt3_init_options() will
- * rebuild the export list from scratch. Do it with locking
- * to avoid unnecessary race conditions.
- */
- LOCK (&ms->mountlock);
- list_for_each_entry_safe (exp, texp, &ms->exportlist, explist) {
- list_del (&exp->explist);
- mnt3_export_free (exp);
- }
- ret = mnt3_init_options (ms, options);
- UNLOCK (&ms->mountlock);
-
- if (ret < 0) {
- gf_log (GF_MNT, GF_LOG_ERROR, "Options reconfigure failed");
- return (-1);
- }
-
- return (0);
-}
diff --git a/xlators/nfs/server/src/mount3.h b/xlators/nfs/server/src/mount3.h
deleted file mode 100644
index 8474244f191..00000000000
--- a/xlators/nfs/server/src/mount3.h
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- Copyright (c) 2010-2011 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.
-*/
-
-#ifndef _MOUNT3_H_
-#define _MOUNT3_H_
-
-#ifndef _CONFIG_H
-#define _CONFIG_H
-#include "config.h"
-#endif
-
-#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"
-
-/* Registered with portmap */
-#define GF_MOUNTV3_PORT 38465
-#define GF_MOUNTV3_IOB (2 * GF_UNIT_KB)
-#define GF_MOUNTV3_IOBPOOL (GF_MOUNTV3_IOB * 50)
-
-#define GF_MOUNTV1_PORT 38466
-#define GF_MNT GF_NFS"-mount"
-
-extern rpcsvc_program_t *
-mnt3svc_init (xlator_t *nfsx);
-
-extern rpcsvc_program_t *
-mnt1svc_init (xlator_t *nfsx);
-
-extern int
-mount_init_state (xlator_t *nfsx);
-
-extern int
-mount_reconfigure_state (xlator_t *nfsx, dict_t *options);
-
-void
-mount_rewrite_rmtab (struct mount3_state *ms, char *new_rmtab);
-
-/* Data structure used to store the list of mounts points currently
- * in use by NFS clients.
- */
-struct mountentry {
- /* Links to mount3_state->mountlist. */
- struct list_head mlist;
-
- /* The export name */
- char exname[MNTPATHLEN];
- char hostname[MNTPATHLEN];
-};
-
-#define MNT3_EXPTYPE_VOLUME 1
-#define MNT3_EXPTYPE_DIR 2
-
-/* Structure to hold export-dir AUTH parameter */
-struct host_auth_spec {
- char *host_addr; /* Allowed IP or host name */
- uint32_t netmask; /* Network mask (Big-Endian) */
- struct host_auth_spec *next; /* Pointer to next AUTH struct */
-};
-
-struct mnt3_export {
- struct list_head explist;
-
- /* The string that may contain either the volume name if the full volume
- * is exported or the subdirectory in the volume.
- */
- char *expname;
- /*
- * IP address, hostname or subnets who are allowed to connect to expname
- * subvolume or subdirectory
- */
- struct host_auth_spec* hostspec;
- xlator_t *vol;
- int exptype;
-
- /* Extracted from nfs volume options if nfs.dynamicvolumes is on.
- */
- uuid_t volumeid;
-};
-
-struct mount3_state {
- xlator_t *nfsx;
-
- /* The buffers for all network IO are got from this pool. */
- struct iobuf_pool *iobpool;
-
- /* List of exports, can be volumes or directories in those volumes. */
- struct list_head exportlist;
-
- /* List of current mount points over all the exports from this
- * server.
- */
- struct list_head mountlist;
-
- /* Used to protect the mountlist. */
- gf_lock_t mountlock;
-
- /* Set to 0 if exporting full volumes is disabled. On by default. */
- gf_boolean_t export_volumes;
- gf_boolean_t export_dirs;
-};
-
-#define gf_mnt3_export_dirs(mst) ((mst)->export_dirs)
-
-struct mount3_resolve_state {
- struct mnt3_export *exp;
- struct mount3_state *mstate;
- rpcsvc_request_t *req;
-
- char remainingdir[MNTPATHLEN];
- loc_t resolveloc;
- struct nfs3_fh parentfh;
-};
-
-typedef struct mount3_resolve_state mnt3_resolve_t;
-
-#endif
diff --git a/xlators/nfs/server/src/mount3udp_svc.c b/xlators/nfs/server/src/mount3udp_svc.c
deleted file mode 100644
index 70aead67edb..00000000000
--- 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.
-
- 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 "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)
-{
- xlator_t *nfsx = argv;
- register SVCXPRT *transp = NULL;
-
- GF_ASSERT (nfsx);
-
- if (glusterfs_this_set(nfsx)) {
- gf_log (GF_MNT, GF_LOG_ERROR, "failed to set xlator, "
- "nfs.mount-udp will not work");
- return 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
deleted file mode 100644
index f942d37d6e1..00000000000
--- a/xlators/nfs/server/src/nfs-common.c
+++ /dev/null
@@ -1,465 +0,0 @@
-/*
- Copyright (c) 2010-2011 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.
-*/
-
-#ifndef _CONFIG_H
-#define _CONFIG_H
-#include "config.h"
-#endif
-
-#include "rpcsvc.h"
-#include "dict.h"
-#include "xlator.h"
-#include "xdr-nfs3.h"
-#include "msg-nfs3.h"
-#include "iobuf.h"
-#include "nfs-common.h"
-#include "nfs-fops.h"
-#include "nfs-mem-types.h"
-#include "rpcsvc.h"
-#include "iatt.h"
-
-#include <libgen.h>
-
-xlator_t *
-nfs_xlid_to_xlator (xlator_list_t *cl, uint8_t xlid)
-{
- xlator_t *xl = NULL;
- uint8_t id = 0;
-
- while (id <= xlid) {
- if (!cl) {
- xl = NULL;
- break;
- }
-
- xl = cl->xlator;
- cl = cl->next;
- id++;
- }
-
- return xl;
-}
-
-
-xlator_t *
-nfs_path_to_xlator (xlator_list_t *cl, char *path)
-{
- return NULL;
-}
-
-
-uint16_t
-nfs_xlator_to_xlid (xlator_list_t *cl, xlator_t *xl)
-{
- uint16_t xlid = 0;
-
- if ((!cl) || (!xl))
- return 0;
-
- while (cl) {
- if (xl == cl->xlator)
- break;
- cl = cl->next;
- ++xlid;
- }
-
- return xlid;
-}
-
-
-xlator_t *
-nfs_mntpath_to_xlator (xlator_list_t *cl, char *path)
-{
- char *volname = NULL;
- char *volptr = NULL;
- size_t pathlen;
- xlator_t *targetxl = NULL;
-
- if ((!cl) || (!path))
- return NULL;
-
- volname = strdupa (path);
- pathlen = strlen (volname);
- gf_log (GF_NFS, GF_LOG_TRACE, "Subvolume search: %s", path);
- if (volname[0] == '/')
- volptr = &volname[1];
- else
- volptr = &volname[0];
-
- if (pathlen && volname[pathlen - 1] == '/')
- volname[pathlen - 1] = '\0';
-
- while (cl) {
- if (strcmp (volptr, cl->xlator->name) == 0) {
- targetxl = cl->xlator;
- break;
- }
-
- cl = cl->next;
- }
-
- return targetxl;
-
-}
-
-
-/* Returns 1 if the stat seems to be filled with zeroes. */
-int
-nfs_zero_filled_stat (struct iatt *buf)
-{
- if (!buf)
- return 1;
-
- /* Do not use st_dev because it is transformed to store the xlator id
- * in place of the device number. Do not use st_ino because by this time
- * 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))
- return 1;
-
- return 0;
-}
-
-
-void
-nfs_loc_wipe (loc_t *loc)
-{
- loc_wipe (loc);
-}
-
-
-int
-nfs_loc_copy (loc_t *dst, loc_t *src)
-{
- int ret = -1;
-
- ret = loc_copy (dst, src);
-
- return ret;
-}
-
-
-int
-nfs_loc_fill (loc_t *loc, inode_t *inode, inode_t *parent, char *path)
-{
- int ret = -EFAULT;
-
- if (!loc)
- return ret;
-
- if (inode) {
- loc->inode = inode_ref (inode);
- if (!uuid_is_null (inode->gfid))
- uuid_copy (loc->gfid, inode->gfid);
- }
-
- 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++;
- }
-
- ret = 0;
-loc_wipe:
- if (ret < 0)
- nfs_loc_wipe (loc);
-
- return ret;
-}
-
-
-int
-nfs_inode_loc_fill (inode_t *inode, loc_t *loc, int how)
-{
- char *resolvedpath = NULL;
- inode_t *parent = NULL;
- int ret = -EFAULT;
-
- 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 (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);
- } else {
- parent = inode_parent (inode, loc->pargfid, NULL);
- }
-
- ret = nfs_loc_fill (loc, inode, parent, resolvedpath);
- if (ret < 0) {
- gf_log (GF_NFS, GF_LOG_ERROR, "loc fill resolution failed %s",
- resolvedpath);
- goto err;
- }
-
- ret = 0;
-err:
- if (parent)
- inode_unref (parent);
-
- GF_FREE (resolvedpath);
-
- return ret;
-}
-
-int
-nfs_gfid_loc_fill (inode_table_t *itable, uuid_t gfid, loc_t *loc, int how)
-{
- int ret = -EFAULT;
- inode_t *inode = NULL;
-
- if (!loc)
- return ret;
-
- 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 = 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;
- }
-
-err:
- if (inode)
- inode_unref (inode);
- return ret;
-}
-
-
-int
-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);
-}
-
-
-
-int
-nfs_parent_inode_loc_fill (inode_t *parent, inode_t *entryinode, char *entry,
- loc_t *loc)
-{
- int ret = -EFAULT;
- char *path = NULL;
-
- if ((!parent) || (!entry) || (!loc) || (!entryinode))
- return ret;
-
- ret = inode_path (parent, entry, &path);
- if (ret < 0) {
- gf_log (GF_NFS, GF_LOG_ERROR, "path resolution failed %s",
- path);
- goto err;
- }
-
- ret = nfs_loc_fill (loc, entryinode, parent, path);
- GF_FREE (path);
-err:
- return ret;
-}
-
-
-/* Returns -1 if parent is not available, return -2 if the entry is not
- * available. In case the return is going to be -2, and how = NFS_RESOLVE_CREATE
- * it does however fill in the loc so that it can be used to perform a lookup
- * fop for the entry.
- * On other errors, return -3. 0 on success.
- */
-int
-nfs_entry_loc_fill (inode_table_t *itable, uuid_t pargfid, char *entry,
- loc_t *loc, int how)
-{
- inode_t *parent = NULL;
- inode_t *entryinode = NULL;
- int ret = -3;
- char *resolvedpath = NULL;
- int pret = -3;
-
- if ((!itable) || (!entry) || (!loc))
- return ret;
-
- parent = inode_find (itable, pargfid);
-
- ret = -1;
- /* Will need hard resolution now */
- if (!parent)
- goto err;
-
- uuid_copy (loc->pargfid, pargfid);
-
- ret = -2;
- entryinode = inode_grep (itable, parent, entry);
- if (!entryinode) {
- if (how == NFS_RESOLVE_CREATE) {
- /* Even though we'll create the inode and the loc for
- * a missing inode, we still need to return -2 so
- * that the caller can use the filled loc to call
- * lookup.
- */
- entryinode = inode_new (itable);
- /* Cannot change ret because that must
- * continue to have -2.
- */
- pret = nfs_parent_inode_loc_fill (parent, entryinode,
- entry, loc);
- /* Only if parent loc fill fails, should we notify error
- * through ret, otherwise, we still need to force a
- * lookup by returning -2.
- */
- if (pret < 0)
- ret = -3;
- }
- goto err;
- }
-
- 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);
- ret = -3;
- }
-
-err:
- if (parent)
- inode_unref (parent);
-
- if (entryinode)
- inode_unref (entryinode);
-
- GF_FREE (resolvedpath);
-
- return ret;
-}
-
-
-uint32_t
-nfs_hash_gfid (uuid_t gfid)
-{
- uint32_t hash = 0;
- uint64_t msb64 = 0;
- uint64_t lsb64 = 0;
- uint32_t a1 = 0;
- uint32_t a2 = 0;
- uint32_t a3 = 0;
- uint32_t a4 = 0;
- uint32_t b1 = 0;
- uint32_t b2 = 0;
-
- if (__is_root_gfid (gfid))
- return 0x1;
-
- memcpy (&msb64, &gfid[8], 8);
- memcpy (&lsb64, &gfid[0], 8);
-
- a1 = (msb64 << 32);
- a2 = (msb64 >> 32);
- a3 = (lsb64 << 32);
- a4 = (lsb64 >> 32);
-
- b1 = a1 ^ a4;
- b2 = a2 ^ a3;
-
- hash = b1 ^ b2;
-
- return hash;
-}
-
-
-void
-nfs_fix_generation (xlator_t *this, inode_t *inode)
-{
- uint64_t raw_ctx = 0;
- struct nfs_inode_ctx *ictx = NULL;
- struct nfs_state *priv = NULL;
- int ret = -1;
-
- if (!inode) {
- return;
- }
- priv = this->private;
-
- if (inode_ctx_get(inode,this,&raw_ctx) == 0) {
- ictx = (struct nfs_inode_ctx *)raw_ctx;
- ictx->generation = priv->generation;
- }
- else {
- ictx = GF_CALLOC (1, sizeof (struct nfs_inode_ctx),
- gf_nfs_mt_inode_ctx);
- if (!ictx) {
- gf_log (this->name, GF_LOG_ERROR,
- "could not allocate nfs inode ctx");
- return;
- }
- INIT_LIST_HEAD(&ictx->shares);
- ictx->generation = priv->generation;
- ret = inode_ctx_put (inode, this, (uint64_t)ictx);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "could not store nfs inode ctx");
- return;
- }
- }
-}
diff --git a/xlators/nfs/server/src/nfs-common.h b/xlators/nfs/server/src/nfs-common.h
deleted file mode 100644
index 2e97f1563c9..00000000000
--- a/xlators/nfs/server/src/nfs-common.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- Copyright (c) 2010-2011 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.
-*/
-
-#ifndef _NFS_COMMON_H_
-#define _NFS_COMMON_H_
-
-#ifndef _CONFIG_H
-#define _CONFIG_H
-#include "config.h"
-#endif
-
-#include <unistd.h>
-
-#include "xlator.h"
-#include "rpcsvc.h"
-#include "iatt.h"
-#include "uuid.h"
-
-//NFS_PATH_MAX hard-coded to 4096 as a work around for bug 2476.
-//nfs server crashes when path received is longer than PATH_MAX
-#define NFS_PATH_MAX 4096
-#define NFS_NAME_MAX NAME_MAX
-
-#define NFS_DEFAULT_CREATE_MODE 0600
-
-extern xlator_t *
-nfs_xlid_to_xlator (xlator_list_t *cl, uint8_t xlid);
-
-extern uint16_t
-nfs_xlator_to_xlid (xlator_list_t *cl, xlator_t *xl);
-
-extern xlator_t *
-nfs_path_to_xlator (xlator_list_t *cl, char *path);
-
-extern xlator_t *
-nfs_mntpath_to_xlator (xlator_list_t *cl, char *path);
-
-extern int
-nfs_zero_filled_stat (struct iatt *buf);
-
-extern void
-nfs_loc_wipe (loc_t *loc);
-
-extern int
-nfs_loc_copy (loc_t *dst, loc_t *src);
-
-extern int
-nfs_loc_fill (loc_t *loc, inode_t *inode, inode_t *parent, char *path);
-
-#define NFS_RESOLVE_EXIST 1
-#define NFS_RESOLVE_CREATE 2
-
-extern int
-nfs_inode_loc_fill (inode_t *inode, loc_t *loc, int how);
-
-extern int
-nfs_ino_loc_fill (inode_table_t *itable, uuid_t gfid, loc_t *l);
-
-extern int
-nfs_entry_loc_fill (inode_table_t *itable, uuid_t pargfid, char *entry,
- loc_t *loc, int how);
-
-extern int
-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);
-
-void
-nfs_fix_generation (xlator_t *this, inode_t *inode);
-#endif
diff --git a/xlators/nfs/server/src/nfs-fops.c b/xlators/nfs/server/src/nfs-fops.c
deleted file mode 100644
index 56d4cba47c6..00000000000
--- a/xlators/nfs/server/src/nfs-fops.c
+++ /dev/null
@@ -1,1697 +0,0 @@
-/*
- Copyright (c) 2010-2011 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.
-*/
-
-#ifndef _CONFIG_H
-#define _CONFIG_H
-#include "config.h"
-#endif
-
-#include <grp.h>
-#include <pwd.h>
-
-#include "dict.h"
-#include "xlator.h"
-#include "iobuf.h"
-#include "call-stub.h"
-#include "stack.h"
-#include "nfs.h"
-#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>
-
-static int gf_auth_max_groups_nfs_log = 0;
-
-void
-nfs_fix_groups (xlator_t *this, call_stack_t *root)
-{
- struct passwd mypw;
- char mystrs[1024];
- struct passwd *result;
-#ifdef GF_DARWIN_HOST_OS
- /* BSD/DARWIN does not correctly uses gid_t in getgrouplist */
- int mygroups[GF_MAX_AUX_GROUPS];
-#else
- gid_t mygroups[GF_MAX_AUX_GROUPS];
-#endif
- int ngroups;
- int i;
- int max_groups;
- struct nfs_state *priv = this->private;
- const gid_list_t *agl;
- gid_list_t gl;
-
- if (!priv->server_aux_gids) {
- return;
- }
-
- /* RPC enforces the GF_AUTH_GLUSTERFS_MAX_GROUPS limit */
- max_groups = GF_AUTH_GLUSTERFS_MAX_GROUPS(root->lk_owner.len);
-
- agl = gid_cache_lookup(&priv->gid_cache, root->uid, 0, 0);
- if (agl) {
- if (agl->gl_count > max_groups) {
- GF_LOG_OCCASIONALLY (gf_auth_max_groups_nfs_log,
- this->name, GF_LOG_WARNING,
- "too many groups, reducing %d -> %d",
- agl->gl_count, max_groups);
- }
-
- for (ngroups = 0; ngroups < agl->gl_count
- && ngroups <= max_groups; 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_uid = 0;
- gl.gl_gid = 0;
- 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);
- }
-
- /* RPC enforces the GF_AUTH_GLUSTERFS_MAX_GROUPS limit */
- if (ngroups > max_groups) {
- GF_LOG_OCCASIONALLY (gf_auth_max_groups_nfs_log,
- this->name, GF_LOG_WARNING,
- "too many groups, reducing %d -> %d",
- ngroups, max_groups);
-
- ngroups = max_groups;
- }
-
- /* 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)
-{
- struct nfs_fop_local *l = NULL;
-
- if (!nfsx)
- return NULL;
-
- l = mem_get (nfs_fop_mempool (nfsx));
-
- memset (l, 0, sizeof (*l));
- return l;
-}
-
-void
-nfs_fop_local_wipe (xlator_t *nfsx, struct nfs_fop_local *l)
-{
- if ((!nfsx) || (!l))
- return;
-
- if (l->iobref)
- iobref_unref (l->iobref);
-
- if (l->parent)
- inode_unref (l->parent);
-
- if (l->inode)
- inode_unref (l->inode);
-
- if (l->newparent)
- inode_unref (l->newparent);
-
- if (l->dictgfid)
- dict_unref (l->dictgfid);
-
- mem_put (l);
-
- return;
-}
-
-#define nfs_stack_destroy(nfl, fram) \
- do { \
- nfs_fop_local_wipe ((nfl)->nfsx, nfl); \
- (fram)->local = NULL; \
- STACK_DESTROY ((fram)->root); \
- } while (0) \
-
-
-pthread_mutex_t ctr = PTHREAD_MUTEX_INITIALIZER;
-unsigned int cval = 1;
-
-
-int
-nfs_frame_getctr ()
-{
- uint64_t val = 0;
-
- pthread_mutex_lock (&ctr);
- {
- if (cval == 0)
- cval = 1;
- val = cval;
- cval++;
- }
- pthread_mutex_unlock (&ctr);
-
- return val;
-}
-
-
-call_frame_t *
-nfs_create_frame (xlator_t *xl, nfs_user_t *nfu)
-{
- call_frame_t *frame = NULL;
- int x = 0;
- int y = 0;
-
- if ((!xl) || (!nfu) || (nfu->ngrps > NFS_NGROUPS))
- return NULL;
-
- frame = create_frame (xl, (call_pool_t *)xl->ctx->pool);
- if (!frame)
- goto err;
- if (call_stack_alloc_groups (frame->root, nfu->ngrps) != 0) {
- STACK_DESTROY (frame->root);
- frame = NULL;
- goto err;
- }
-
- 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) {
- 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];
- }
- }
-
- /*
- * 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);
-
-err:
- return frame;
-}
-
-#define nfs_fop_handle_frame_create(fram, xla, nfuser, retval, errlabel) \
- do { \
- fram = nfs_create_frame (xla, (nfuser)); \
- if (!fram) { \
- retval = (-ENOMEM); \
- gf_log (GF_NFS, GF_LOG_ERROR,"Frame creation failed");\
- goto errlabel; \
- } \
- } while (0) \
-
-/* Look into the inode and parent inode of a loc and save enough state
- * 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)
-
-/* 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)
-
-
-/* Use the state saved by the previous macro to funge the ino in the appropriate
- * structure.
- */
-#define nfs_fop_restore_root_ino(locl, fopret, preattr, postattr, prepar, postpar) \
- do { \
- if (fopret == -1) \
- break; \
- if ((locl)->rootinode) { \
- if ((preattr)) { \
- ((struct iatt *)(preattr))->ia_ino = 1; \
- ((struct iatt *)(preattr))->ia_dev = 0; \
- } \
- if ((postattr)) { \
- ((struct iatt *)(postattr))->ia_ino = 1; \
- ((struct iatt *)(postattr))->ia_dev = 0; \
- } \
- } else if ((locl)->rootparentinode) { \
- if ((prepar)) { \
- ((struct iatt *)(prepar))->ia_ino = 1; \
- ((struct iatt *)(prepar))->ia_dev = 0; \
- } \
- if ((postpar)) { \
- ((struct iatt *)(postpar))->ia_ino = 1; \
- ((struct iatt *)(postpar))->ia_dev = 0; \
- } \
- } \
- } while (0) \
-
-/* 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_restore_root_ino(locl, fopret, preattr, postattr, prepar, postpar) \
- do { \
- if (fopret == -1) \
- break; \
- \
- if ((locl)->newrootinode) { \
- if ((preattr)) \
- ((struct iatt *)(preattr))->ia_ino = 1; \
- if ((postattr)) \
- ((struct iatt *)(postattr))->ia_ino = 1; \
- } else if ((locl)->newrootparentinode) { \
- if ((prepar)) \
- ((struct iatt *)(prepar))->ia_ino = 1; \
- if ((postpar)) \
- ((struct iatt *)(postpar))->ia_ino = 1; \
- } \
- } while (0) \
-
-dict_t *
-nfs_gfid_dict (inode_t *inode)
-{
- uuid_t newgfid = {0, };
- char *dyngfid = NULL;
- dict_t *dictgfid = NULL;
- int ret = -1;
- uuid_t rootgfid = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1};
-
- dyngfid = GF_CALLOC (1, sizeof (uuid_t), gf_common_mt_char);
- if (dyngfid == NULL)
- return (NULL);
-
- uuid_generate (newgfid);
-
- if (uuid_compare (inode->gfid, rootgfid) == 0)
- memcpy (dyngfid, rootgfid, sizeof (uuid_t));
- else
- memcpy (dyngfid, newgfid, sizeof (uuid_t));
-
- dictgfid = dict_new ();
- if (!dictgfid) {
- gf_log (GF_NFS, GF_LOG_ERROR, "Failed to create gfid dict");
- GF_FREE (dyngfid);
- return (NULL);
- }
-
- ret = dict_set_bin (dictgfid, "gfid-req", dyngfid, sizeof (uuid_t));
- if (ret < 0) {
- GF_FREE (dyngfid);
- dict_unref (dictgfid);
- return (NULL);
- }
-
- return dictgfid;
-}
-
-#define nfs_fop_gfid_setup(nflcl, inode, retval, erlbl) \
- do { \
- if (nflcl) { \
- (nflcl)->dictgfid = nfs_gfid_dict (inode); \
- \
- if (!((nflcl)->dictgfid)) { \
- retval = -EFAULT; \
- goto erlbl; \
- } \
- } \
- } while (0) \
-
-/* Fops Layer Explained
- * The fops layer has three types of functions. They can all be identified by
- * their names. Here are the three patterns:
- *
- * nfs_fop_<fopname>
- * This is the lowest level function that knows nothing about states and
- * callbacks. At most this is required to create a frame and call the
- * fop. The idea here is to provide a convenient way to call fops than
- * directly use STACK_WINDs. If this type of interface is used, the caller's
- * callback is responsible for doing the relevant GlusterFS state
- * maintenance operations on the data returned in the callbacks.
- *
- * nfs_<fopname>
- * Unlike the nfs_fop_<fopname> variety, this is the stateful type of fop, in
- * that it silently performs all the relevant GlusterFS state maintenance
- * operations on the data returned to the callbacks, leaving the caller's
- * callback to just use the data returned for whatever it needs to do with that
- * data, for eg. the nfs_lookup, will take care of looking up the inodes,
- * revalidating them if needed and linking new inodes into the table, while
- * the caller's callback, for eg, the NFSv3 LOOKUP callback can just use
- * the stat bufs returned to create file handle, map the file handle into the
- * fh cache and finally encode the fh and the stat bufs into a NFS reply.
- *
- */
-
-int32_t
-nfs_fop_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)
-{
- struct nfs_fop_local *local = NULL;
- fop_lookup_cbk_t progcbk;
-
- if (op_ret == 0) {
- nfs_fix_generation(this,inode);
- }
-
- nfl_to_prog_data (local, progcbk, frame);
- nfs_fop_restore_root_ino (local, op_ret, buf, NULL, NULL, postparent);
- if (progcbk)
- progcbk (frame, cookie, this, op_ret, op_errno, inode, buf,
- xattr, postparent);
-
- nfs_stack_destroy (local, frame);
- return 0;
-}
-
-
-int
-nfs_fop_lookup (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *loc,
- fop_lookup_cbk_t cbk, void *local)
-{
- call_frame_t *frame = NULL;
- int ret = -EFAULT;
- struct nfs_fop_local *nfl = NULL;
-
- if ((!xl) || (!loc) || (!nfu))
- return ret;
-
- gf_log (GF_NFS, GF_LOG_TRACE, "Lookup: %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);
- nfs_fop_gfid_setup (nfl, loc->inode, ret, err);
-
- STACK_WIND_COOKIE (frame, nfs_fop_lookup_cbk, xl, xl,
- xl->fops->lookup, loc, nfl->dictgfid);
-
- ret = 0;
-err:
- if (ret < 0) {
- if (frame)
- nfs_stack_destroy (nfl, frame);
- }
-
- 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)
-{
- struct nfs_fop_local *nfl = NULL;
- fop_stat_cbk_t progcbk = NULL;
-
- 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);
-
- nfs_stack_destroy (nfl, frame);
- return 0;
-}
-
-
-int
-nfs_fop_stat (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *loc,
- fop_stat_cbk_t cbk, void *local)
-{
- call_frame_t *frame = NULL;
- int ret = -EFAULT;
- struct nfs_fop_local *nfl = NULL;
-
- if ((!xl) || (!loc) || (!nfu))
- return ret;
-
- gf_log (GF_NFS, GF_LOG_TRACE, "Stat: %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);
-
- STACK_WIND_COOKIE (frame, nfs_fop_stat_cbk, xl, xl, xl->fops->stat,
- loc, NULL);
- ret = 0;
-err:
- if (ret < 0) {
- if (frame)
- nfs_stack_destroy (nfl, frame);
- }
-
- return ret;
-}
-
-
-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)
-{
- struct nfs_fop_local *nfl = NULL;
- fop_fstat_cbk_t progcbk = NULL;
-
- 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);
-
- nfs_stack_destroy (nfl, frame);
- return 0;
-}
-
-
-int
-nfs_fop_fstat (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, fd_t *fd,
- fop_fstat_cbk_t cbk, void *local)
-{
- call_frame_t *frame = NULL;
- int ret = -EFAULT;
- struct nfs_fop_local *nfl = NULL;
-
- if ((!nfsx) || (!xl) || (!fd) || (!nfu))
- return ret;
-
- gf_log (GF_NFS, GF_LOG_TRACE, "FStat");
- 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);
-
- STACK_WIND_COOKIE (frame, nfs_fop_fstat_cbk, xl, xl, xl->fops->fstat,
- fd, NULL);
-
- ret = 0;
-err:
- if (ret < 0) {
- if (frame)
- nfs_stack_destroy (nfl, frame);
- }
-
- return ret;
-}
-
-
-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)
-{
- 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);
- nfs_stack_destroy (nfl, frame);
- return 0;
-}
-
-
-int
-nfs_fop_opendir (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *pathloc,
- fd_t *dirfd, fop_opendir_cbk_t cbk, void *local)
-{
- call_frame_t *frame = NULL;
- int ret = -EFAULT;
- struct nfs_fop_local *nfl = NULL;
-
- if ((!nfsx) || (!xl) || (!pathloc) || (!dirfd) || (!nfu))
- return ret;
-
- gf_log (GF_NFS, GF_LOG_TRACE, "Opendir: %s", pathloc->path);
- nfs_fop_handle_frame_create (frame, nfsx, nfu, ret, err);
- 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);
- ret = 0;
-
-err:
- if (ret < 0) {
- if (frame)
- nfs_stack_destroy (nfl, frame);
- }
-
- return ret;
-}
-
-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)
-{
- 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);
-
- nfs_stack_destroy (nfl, frame);
- return 0;
-}
-
-
-int
-nfs_fop_flush (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, fd_t *fd,
- fop_flush_cbk_t cbk, void *local)
-{
- call_frame_t *frame = NULL;
- int ret = -EFAULT;
- struct nfs_fop_local *nfl = NULL;
-
- if ((!nfsx) || (!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);
-
- STACK_WIND_COOKIE (frame, nfs_fop_flush_cbk, xl, xl, xl->fops->flush,
- fd, NULL);
- ret = 0;
-err:
- if (ret < 0) {
- if (frame)
- nfs_stack_destroy (nfl, frame);
- }
-
- return ret;
-}
-
-
-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)
-{
- 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);
-
- nfs_stack_destroy (nfl, frame);
-
- return 0;
-}
-
-
-int
-nfs_fop_readdirp (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, fd_t *dirfd,
- size_t bufsize, off_t offset, fop_readdirp_cbk_t cbk,
- void *local)
-{
- call_frame_t *frame = NULL;
- int ret = -EFAULT;
- struct nfs_fop_local *nfl = NULL;
-
- if ((!nfsx) || (!xl) || (!dirfd) || (!nfu))
- return ret;
-
- gf_log (GF_NFS, GF_LOG_TRACE, "readdir");
- nfs_fop_handle_frame_create (frame, nfsx, nfu, ret, err);
- 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);
-
- ret = 0;
-err:
- if (ret < 0) {
- if (frame)
- nfs_stack_destroy (nfl, frame);
- }
-
- return ret;
-}
-
-
-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)
-{
-
- struct nfs_fop_local *nfl = NULL;
- fop_statfs_cbk_t progcbk = NULL;
-
- nfl_to_prog_data (nfl, progcbk, frame);
- if (progcbk)
- progcbk (frame, cookie, this, op_ret, op_errno, buf, xdata);
-
- nfs_stack_destroy (nfl, frame);
- return 0;
-}
-
-
-int
-nfs_fop_statfs (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *pathloc,
- fop_statfs_cbk_t cbk, void *local)
-{
- call_frame_t *frame = NULL;
- int ret = -EFAULT;
- struct nfs_fop_local *nfl = NULL;
-
- if ((!nfsx) || (!xl) || (!pathloc) || (!nfu))
- return ret;
-
- gf_log (GF_NFS, GF_LOG_TRACE, "Statfs: %s", pathloc->path);
- nfs_fop_handle_frame_create (frame, nfsx, nfu, ret, err);
- 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);
- ret = 0;
-err:
- if (ret < 0) {
- if (frame)
- nfs_stack_destroy (nfl, frame);
- }
-
- return ret;
-}
-
-
-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 nfs_fop_local *nfl = NULL;
- fop_create_cbk_t progcbk = NULL;
-
- if (op_ret == 0) {
- nfs_fix_generation(this,inode);
- }
-
- nfl_to_prog_data (nfl, progcbk, frame);
- nfs_fop_restore_root_ino (nfl, op_ret, buf, NULL, preparent,
- postparent);
- if (progcbk)
- progcbk (frame, cookie, this, op_ret, op_errno, fd, inode, buf,
- preparent, postparent, NULL);
-
- nfs_stack_destroy (nfl, frame);
- return 0;
-}
-
-
-int
-nfs_fop_create (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *pathloc,
- int flags, mode_t mode, fd_t *fd, fop_create_cbk_t cbk,
- void *local)
-{
- call_frame_t *frame = NULL;
- int ret = -EFAULT;
- struct nfs_fop_local *nfl = NULL;
-
- if ((!nfsx) || (!xl) || (!pathloc) || (!nfu))
- return ret;
-
- gf_log (GF_NFS, GF_LOG_TRACE, "Create: %s", pathloc->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, 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);
-
- ret = 0;
-err:
- if (ret < 0) {
- if (frame)
- nfs_stack_destroy (nfl, frame);
- }
-
- return ret;
-}
-
-
-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 nfs_fop_local *nfl = NULL;
- fop_setattr_cbk_t progcbk = NULL;
-
- 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);
- nfs_stack_destroy (nfl, frame);
- return 0;
-}
-
-
-
-int
-nfs_fop_setattr (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *pathloc,
- struct iatt *buf, int32_t valid, fop_setattr_cbk_t cbk,
- void *local)
-{
- call_frame_t *frame = NULL;
- int ret = -EFAULT;
- struct nfs_fop_local *nfl = NULL;
-
- if ((!nfsx) || (!xl) || (!pathloc) || (!nfu))
- return ret;
-
- gf_log (GF_NFS, GF_LOG_TRACE, "Setattr: %s", pathloc->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, pathloc);
-
- STACK_WIND_COOKIE (frame, nfs_fop_setattr_cbk, xl, xl,
- xl->fops->setattr, pathloc, buf, valid, NULL);
- ret = 0;
-err:
- if (ret < 0) {
- if (frame)
- nfs_stack_destroy (nfl, frame);
- }
-
- return ret;
-}
-
-
-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 nfs_fop_local *nfl = NULL;
- fop_mkdir_cbk_t progcbk = NULL;
-
- if (op_ret == 0) {
- nfs_fix_generation(this,inode);
- }
-
- nfl_to_prog_data (nfl, progcbk, frame);
- 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);
- nfs_stack_destroy (nfl, frame);
- return 0;
-}
-
-
-int
-nfs_fop_mkdir (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *pathloc,
- mode_t mode, fop_mkdir_cbk_t cbk, void *local)
-{
- call_frame_t *frame = NULL;
- int ret = -EFAULT;
- struct nfs_fop_local *nfl = NULL;
-
- if ((!nfsx) || (!xl) || (!pathloc) || (!nfu))
- return ret;
-
- gf_log (GF_NFS, GF_LOG_TRACE, "Mkdir: %s", pathloc->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, 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);
- ret = 0;
-err:
- if (ret < 0) {
- if (frame)
- nfs_stack_destroy (nfl, frame);
- }
-
- return ret;
-}
-
-
-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 nfs_fop_local *nfl = NULL;
- fop_symlink_cbk_t progcbk = NULL;
-
- if (op_ret == 0) {
- nfs_fix_generation(this,inode);
- }
-
- nfl_to_prog_data (nfl, progcbk, frame);
- 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);
- nfs_stack_destroy (nfl, frame);
- return 0;
-}
-
-int
-nfs_fop_symlink (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, char *target,
- loc_t *pathloc, fop_symlink_cbk_t cbk, void *local)
-{
- call_frame_t *frame = NULL;
- int ret = -EFAULT;
- struct nfs_fop_local *nfl = NULL;
-
- if ((!nfsx) || (!xl) || (!pathloc) || (!target) || (!nfu))
- return ret;
-
- gf_log (GF_NFS, GF_LOG_TRACE, "Symlink: %s", pathloc->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, pathloc);
- 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);
- ret = 0;
-err:
- if (ret < 0) {
- if (frame)
- nfs_stack_destroy (nfl, frame);
- }
-
- return ret;
-}
-
-
-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 nfs_fop_local *nfl = NULL;
- fop_readlink_cbk_t progcbk = NULL;
-
- 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);
- nfs_stack_destroy (nfl, frame);
- return 0;
-}
-
-
-int
-nfs_fop_readlink (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *pathloc,
- size_t size, fop_readlink_cbk_t cbk, void *local)
-{
- call_frame_t *frame = NULL;
- int ret = -EFAULT;
- struct nfs_fop_local *nfl = NULL;
-
- if ((!nfsx) || (!xl) || (!pathloc) || (!nfu))
- return ret;
-
- gf_log (GF_NFS, GF_LOG_TRACE, "Readlink: %s", pathloc->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, pathloc);
-
- STACK_WIND_COOKIE (frame, nfs_fop_readlink_cbk, xl, xl,
- xl->fops->readlink, pathloc, size, NULL);
- ret = 0;
-err:
- if (ret < 0) {
- if (frame)
- nfs_stack_destroy (nfl, frame);
- }
-
- return ret;
-}
-
-
-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 nfs_fop_local *nfl = NULL;
- fop_mknod_cbk_t progcbk = NULL;
-
- if (op_ret == 0) {
- nfs_fix_generation(this,inode);
- }
-
- nfl_to_prog_data (nfl, progcbk, frame);
- 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);
- nfs_stack_destroy (nfl, frame);
- return 0;
-}
-
-
-int
-nfs_fop_mknod (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *pathloc,
- mode_t mode, dev_t dev, fop_mknod_cbk_t cbk, void *local)
-{
- call_frame_t *frame = NULL;
- int ret = -EFAULT;
- struct nfs_fop_local *nfl = NULL;
-
- if ((!nfsx) || (!xl) || (!pathloc) || (!nfu))
- return ret;
-
- gf_log (GF_NFS, GF_LOG_TRACE, "Mknod: %s", pathloc->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, 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);
- ret = 0;
-err:
- if (ret < 0) {
- if (frame)
- nfs_stack_destroy (nfl, frame);
- }
-
- return ret;
-}
-
-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 nfs_fop_local *nfl = frame->local;
- fop_rmdir_cbk_t progcbk = NULL;
-
- nfl_to_prog_data (nfl, progcbk, frame);
- nfs_fop_restore_root_ino (nfl, op_ret, NULL, NULL, preparent,
- postparent);
- if (progcbk)
- progcbk (frame, cookie, this, op_ret, op_errno, preparent,
- postparent, NULL);
- nfs_stack_destroy (nfl, frame);
- return 0;
-}
-
-
-
-int
-nfs_fop_rmdir (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *pathloc,
- fop_rmdir_cbk_t cbk, void *local)
-{
- call_frame_t *frame = NULL;
- int ret = -EFAULT;
- struct nfs_fop_local *nfl = NULL;
-
- if ((!nfsx) || (!xl) || (!pathloc) || (!nfu))
- return ret;
-
- gf_log (GF_NFS, GF_LOG_TRACE, "Rmdir: %s", pathloc->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, pathloc);
-
- STACK_WIND_COOKIE (frame, nfs_fop_rmdir_cbk, xl, xl, xl->fops->rmdir,
- pathloc, 0, NULL);
- ret = 0;
-err:
- if (ret < 0) {
- if (frame)
- nfs_stack_destroy (nfl, frame);
- }
-
- return ret;
-
-}
-
-
-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 nfs_fop_local *nfl = frame->local;
- fop_unlink_cbk_t progcbk = NULL;
-
- nfl_to_prog_data (nfl, progcbk, frame);
- nfs_fop_restore_root_ino (nfl, op_ret, NULL, NULL, preparent,
- postparent);
- if (progcbk)
- progcbk (frame, cookie, this, op_ret, op_errno, preparent,
- postparent, xdata);
- nfs_stack_destroy (nfl, frame);
- return 0;
-}
-
-
-int
-nfs_fop_unlink (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *pathloc,
- fop_unlink_cbk_t cbk, void *local)
-{
- call_frame_t *frame = NULL;
- int ret = -EFAULT;
- struct nfs_fop_local *nfl = NULL;
-
- if ((!nfsx) || (!xl) || (!pathloc) || (!nfu))
- return ret;
-
- gf_log (GF_NFS, GF_LOG_TRACE, "Unlink: %s", pathloc->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, pathloc);
-
- STACK_WIND_COOKIE (frame, nfs_fop_unlink_cbk, xl, xl,
- xl->fops->unlink, pathloc, 0, NULL);
- ret = 0;
-err:
- if (ret < 0) {
- if (frame)
- nfs_stack_destroy (nfl, frame);
- }
-
- return ret;
-
-}
-
-
-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 nfs_fop_local *nfl = NULL;
- fop_link_cbk_t progcbk = NULL;
-
- if (op_ret == 0) {
- nfs_fix_generation(this,inode);
- }
-
- nfl_to_prog_data (nfl, progcbk, frame);
- 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);
-
- nfs_stack_destroy (nfl, frame);
- return 0;
-}
-
-
-int
-nfs_fop_link (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *oldloc,
- loc_t *newloc, fop_link_cbk_t cbk, void *local)
-{
- call_frame_t *frame = NULL;
- int ret = -EFAULT;
- struct nfs_fop_local *nfl = NULL;
-
- if ((!nfsx) || (!xl) || (!oldloc) || (!newloc) || (!nfu))
- return ret;
-
- gf_log (GF_NFS, GF_LOG_TRACE, "Link: %s -> %s", newloc->path,
- oldloc->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, newloc);
-
- STACK_WIND_COOKIE (frame, nfs_fop_link_cbk, xl, xl, xl->fops->link,
- oldloc, newloc, NULL);
- ret = 0;
-err:
- if (ret < 0) {
- if (frame)
- nfs_stack_destroy (nfl, frame);
- }
-
- return ret;
-}
-
-
-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 nfs_fop_local *nfl = NULL;
- fop_rename_cbk_t progcbk = NULL;
-
- 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.
- */
- nfs_fop_restore_root_ino (nfl, op_ret, NULL, NULL, preoldparent,
- postoldparent);
- nfs_fop_newloc_restore_root_ino (nfl, op_ret, buf, NULL, prenewparent,
- postnewparent);
- if (progcbk)
- progcbk (frame, cookie, this, op_ret, op_errno, buf,
- preoldparent, postoldparent, prenewparent,
- postnewparent, xdata);
- nfs_stack_destroy (nfl, frame);
- return 0;
-}
-
-
-int
-nfs_fop_rename (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *oldloc,
- loc_t *newloc, fop_rename_cbk_t cbk, void *local)
-{
- call_frame_t *frame = NULL;
- int ret = -EFAULT;
- struct nfs_fop_local *nfl = NULL;
-
- if ((!nfsx) || (!xl) || (!oldloc) || (!newloc) || (!nfu))
- return ret;
-
- gf_log (GF_NFS, GF_LOG_TRACE, "Rename: %s -> %s", oldloc->path,
- newloc->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, 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);
- ret = 0;
-err:
- if (ret < 0) {
- if (frame)
- nfs_stack_destroy (nfl, frame);
- }
-
- return ret;
-}
-
-
-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)
-{
- 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);
- nfs_stack_destroy (nfl, frame);
-
- return 0;
-}
-
-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,
- void *local)
-{
- call_frame_t *frame = NULL;
- int ret = -EFAULT;
- struct nfs_fop_local *nfl = NULL;
-
- if ((!nfsx) || (!xl) || (!loc) || (!fd) || (!nfu))
- return ret;
-
- gf_log (GF_NFS, GF_LOG_TRACE, "Open: %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);
-
- STACK_WIND_COOKIE (frame, nfs_fop_open_cbk, xl, xl, xl->fops->open,
- loc, flags, fd, NULL);
- ret = 0;
-err:
- if (ret < 0) {
- if (frame)
- nfs_stack_destroy (nfl, frame);
- }
-
- return ret;
-}
-
-
-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 nfs_fop_local *nfl = NULL;
- fop_writev_cbk_t progcbk = NULL;
-
- 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);
-
- nfs_stack_destroy (nfl, frame);
-
- return 0;
-}
-
-
-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,
- 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))
- 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");
- ret = -ENOMEM;
- goto err;
- }
-
- iobref_add (nfl->iobref, srciob);
-*/
- STACK_WIND_COOKIE (frame, nfs_fop_writev_cbk, xl, xl,xl->fops->writev,
- fd, vector, count, offset, fd->flags, srciobref, NULL);
- ret = 0;
-err:
- if (ret < 0) {
- if (frame)
- nfs_stack_destroy (nfl, frame);
- }
-
- return ret;
-}
-
-
-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 nfs_fop_local *nfl = NULL;
- fop_fsync_cbk_t progcbk = NULL;
-
- 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);
-
- nfs_stack_destroy (nfl, frame);
- return 0;
-}
-
-
-
-int
-nfs_fop_fsync (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, fd_t *fd,
- int32_t datasync, fop_fsync_cbk_t cbk, void *local)
-{
- call_frame_t *frame = NULL;
- int ret = -EFAULT;
- struct nfs_fop_local *nfl = NULL;
-
- if ((!nfsx) || (!xl) || (!fd))
- 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);
-
- STACK_WIND_COOKIE (frame, nfs_fop_fsync_cbk, xl, xl,
- xl->fops->fsync, fd, datasync, NULL);
- ret = 0;
-err:
- if (ret < 0) {
- if (frame)
- nfs_stack_destroy (nfl, frame);
- }
-
- return ret;
-}
-
-
-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)
-{
- struct nfs_fop_local *nfl = NULL;
- fop_readv_cbk_t progcbk = NULL;
-
- nfl_to_prog_data (nfl, progcbk, frame);
- 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);
-
- nfs_stack_destroy (nfl, frame);
- return 0;
-}
-
-
-int
-nfs_fop_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)
-{
- 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);
- 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);
- ret = 0;
-err:
- if (ret < 0) {
- if (frame)
- nfs_stack_destroy (nfl, frame);
- }
-
- return ret;
-}
-
-int32_t
-nfs_fop_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)
-{
- struct nfs_fop_local *nfl = NULL;
- fop_getxattr_cbk_t progcbk = NULL;
-
- nfl_to_prog_data (nfl, progcbk, frame);
-
- if (progcbk)
- progcbk (frame, cookie, this, op_ret, op_errno, dict, xdata);
-
- nfs_stack_destroy (nfl, frame);
- return 0;
-}
-
-
-int
-nfs_fop_getxattr (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *loc,
- char *name, dict_t *xdata, fop_getxattr_cbk_t cbk, void *local)
-{
- call_frame_t *frame = NULL;
- int ret = -EFAULT;
- struct nfs_fop_local *nfl = NULL;
-
- if ((!xl) || (!loc) || (!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);
-
- STACK_WIND_COOKIE (frame, nfs_fop_getxattr_cbk, xl, xl, xl->fops->getxattr,
- loc, name, NULL);
- ret = 0;
-err:
- if (ret < 0) {
- if (frame)
- nfs_stack_destroy (nfl, frame);
- }
-
- return ret;
-}
-
-
-int32_t
-nfs_fop_setxattr_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_setxattr_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_setxattr (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu,
- loc_t *loc, dict_t *dict, int32_t flags, dict_t *xdata,
- fop_setxattr_cbk_t cbk, void *local)
-{
- call_frame_t *frame = NULL;
- int ret = -EFAULT;
- struct nfs_fop_local *nfl = NULL;
-
- if ((!xl) || (!loc) || (!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);
-
- STACK_WIND_COOKIE (frame, nfs_fop_setxattr_cbk, xl, xl, xl->fops->setxattr,
- loc, dict, flags, xdata);
- ret = 0;
-err:
- if (ret < 0) {
- if (frame)
- nfs_stack_destroy (nfl, frame);
- }
-
- return ret;
-}
-
-
-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 nfs_fop_local *nfl = NULL;
- fop_truncate_cbk_t progcbk = NULL;
-
- 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);
-
- nfs_stack_destroy (nfl, frame);
- return 0;
-}
-
-
-int
-nfs_fop_truncate (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *loc,
- off_t offset, fop_truncate_cbk_t cbk, void *local)
-{
- call_frame_t *frame = NULL;
- int ret = -EFAULT;
- struct nfs_fop_local *nfl = NULL;
-
- if ((!nfsx) || (!xl) || (!loc) || (!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);
- nfs_fop_save_root_ino (nfl, loc);
-
- STACK_WIND_COOKIE (frame, nfs_fop_truncate_cbk, xl, xl,
- xl->fops->truncate, loc, offset, NULL);
-
- ret = 0;
-err:
- if (ret < 0) {
- if (frame)
- nfs_stack_destroy (nfl, frame);
- }
-
- return ret;
-}
diff --git a/xlators/nfs/server/src/nfs-fops.h b/xlators/nfs/server/src/nfs-fops.h
deleted file mode 100644
index 44e99c66b06..00000000000
--- a/xlators/nfs/server/src/nfs-fops.h
+++ /dev/null
@@ -1,248 +0,0 @@
-/*
- Copyright (c) 2010-2011 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.
-*/
-
-#ifndef _NFS_FOPS_H_
-#define _NFS_FOPS_H_
-
-#ifndef _CONFIG_H
-#define _CONFIG_H
-#include "config.h"
-#endif
-
-#include "dict.h"
-#include "xlator.h"
-#include "iobuf.h"
-#include "call-stub.h"
-#include "stack.h"
-#include "nfs.h"
-#include "nfs-common.h"
-#include <semaphore.h>
-
-/* This structure used to communicate state between a fop and its callback.
- * The problem is, when we're calling a fop in the nfs op handler, the callback
- * is the NFS protocol's callback and we have to perform all GlusterFS
- * inode, inode table, fd_ts and fd table operations in the NFS callback. That
- * approach soon gets extremely complicated and confusing because, then we have
- * to try and separate in our heads which source lines in those callbacks are
- * required for serving the NFS op and which ones are needed for satisfying
- * GlusterFS requirements. This structure allows us avoid performing GlusterFS
- * state maintenance operations inside the fops layer itself. Now, before
- * we call the callback registered by the NFS operation, a hidden fops-layer
- * specific callback is called which performs the state maintenance and then
- * calls the NFS callback.
- *
- * These are allocated from a mem-pool stored in the nfs xlator's state.
- * i.e. struct nfs_state.
- * That is initiated in nfs_init_subvolumes in nfs.c.
- */
-struct nfs_fop_local {
- /* The local sent along by the user of the fop. */
- void *proglocal;
-
- /* The address of the callback supplied by the user. After our
- * callback is executed this one is called.
- * The exact cast destination of this pointer will depend on the
- * fop that is being called.
- */
- void *progcbk;
-
- /* Used only for write requests. */
- struct iobref *iobref;
-
- inode_t *parent;
- inode_t *newparent;
- inode_t *inode;
-
- /* Set to 1 by nfs-inodes layer, which uses this to decide whether to
- * link the newly allocated inode into the itable, in case the fop was
- * successful.
- */
- int newinode;
-
- /* Used by nfs-fops layer in order to determine whether to funge the
- * ino in a dir's stbuf. This funging of root ino is needed to ensure
- * that the root ino remains 1 even when the NFS server has been
- * restarted. Note that in distribute, a fresh lookup and a revalidate
- * on the root inode returns two different inode numbers and this we
- * need to handle by ourself.
- */
- int rootinode;
-
- /* This member is used to determine whether the new parent of a file
- * being renamed is the root directory. If yes, the ino is funged.
- */
- int newrootinode;
- int newrootparentinode;
-
- /* Determines whether to funge the ino in the post and pre parent
- * stbufs for a file/dir where the parent directory could be the root
- * dir. Needed here because of the same reason as above.
- */
- int rootparentinode;
-
- char path[NFS_NAME_MAX + 1];
- char newpath[NFS_NAME_MAX + 1];
- xlator_t *nfsx;
- dict_t *dictgfid;
-
- fd_t *fd;
- int cmd;
- struct gf_flock flock;
-};
-
-extern struct nfs_fop_local *
-nfs_fop_local_init (xlator_t *xl);
-
-extern void
-nfs_fop_local_wipe (xlator_t *xl, struct nfs_fop_local *l);
-
-#define nfs_state(nfsxl) (nfsxl)->private
-#define nfs_fop_mempool(nfxl) (((struct nfs_state *)nfs_state(nfxl))->foppool)
-
-#define prog_data_to_nfl(nf,nflocal, fram, pcbk, plocal) \
- do { \
- nflocal = nfs_fop_local_init (nf); \
- if (nflocal) { \
- nflocal->proglocal = plocal; \
- nflocal->progcbk = *VOID(&pcbk); \
- nflocal->nfsx = nf; \
- if (fram) \
- ((call_frame_t *)fram)->local = nflocal;\
- } \
- } while (0) \
-
-
-
-#define nfl_to_prog_data(nflocal, pcbk, fram) \
- do { \
- nflocal = fram->local; \
- fram->local = nflocal->proglocal; \
- pcbk = nflocal->progcbk; \
- } while (0) \
-
-#define nfs_fop_handle_local_init(fram,nfx, nfloc, cbck,prgloc,retval,lab) \
- do { \
- prog_data_to_nfl (nfx, nfloc, fram, cbck, prgloc); \
- if (!nfloc) { \
- gf_log (GF_NFS,GF_LOG_ERROR,"Failed to init local");\
- retval = -ENOMEM; \
- goto lab; \
- } \
- } while (0) \
-
-extern int
-nfs_fop_fstat (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, fd_t *fd,
- fop_stat_cbk_t cbk, void *local);
-
-extern int
-nfs_fop_readdirp (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, fd_t *dirfd,
- size_t bufsize, off_t offset, fop_readdir_cbk_t cbk,
- void *local);
-extern int
-nfs_fop_lookup (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *loc,
- fop_lookup_cbk_t cbk, void *local);
-
-extern int
-nfs_fop_create (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *pathloc,
- int flags, mode_t mode, fd_t *fd, fop_create_cbk_t cbk,
- void *local);
-extern int
-nfs_fop_flush (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, fd_t *fd,
- fop_flush_cbk_t cbk, void *local);
-
-extern int
-nfs_fop_mkdir (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *pathloc,
- mode_t mode, fop_mkdir_cbk_t cbk, void *local);
-
-extern int
-nfs_fop_truncate (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *loc,
- off_t offset, fop_truncate_cbk_t cbk, void *local);
-
-extern int
-nfs_fop_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);
-
-extern int
-nfs_fop_fsync (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, fd_t *fd,
- int32_t datasync, fop_fsync_cbk_t cbk, void *local);
-
-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,
- 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,
- void *local);
-
-extern int
-nfs_fop_rename (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *oldloc,
- loc_t *newloc, fop_rename_cbk_t cbk, void *local);
-
-extern int
-nfs_fop_link (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *oldloc,
- loc_t *newloc, fop_link_cbk_t cbk, void *local);
-
-extern int
-nfs_fop_unlink (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *pathloc,
- fop_unlink_cbk_t cbk, void *local);
-
-extern int
-nfs_fop_rmdir (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *pathloc,
- fop_rmdir_cbk_t cbk, void *local);
-
-extern int
-nfs_fop_mknod (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *pathloc,
- mode_t mode, dev_t dev, fop_mknod_cbk_t cbk, void *local);
-
-extern int
-nfs_fop_readlink (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *pathloc,
- size_t size, fop_readlink_cbk_t cbk, void *local);
-
-extern int
-nfs_fop_symlink (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, char *target,
- loc_t *pathloc, fop_symlink_cbk_t cbk, void *local);
-
-extern int
-nfs_fop_setattr (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *pathloc,
- struct iatt *buf, int32_t valid, fop_setattr_cbk_t cbk,
- void *local);
-
-extern int
-nfs_fop_statfs (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *pathloc,
- fop_statfs_cbk_t cbk, void *local);
-
-extern int
-nfs_fop_opendir (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *pathloc,
- fd_t *dirfd, fop_opendir_cbk_t cbk, void *local);
-
-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);
-
-extern int
-nfs_fop_getxattr (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *loc,
- char *name, dict_t *xdata, fop_getxattr_cbk_t cbk, void *local);
-
-extern int
-nfs_fop_setxattr (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu,
- loc_t *loc, dict_t *dict, int32_t flags, dict_t *xdata,
- fop_setxattr_cbk_t cbk, void *local);
-
-#endif
diff --git a/xlators/nfs/server/src/nfs-generics.c b/xlators/nfs/server/src/nfs-generics.c
deleted file mode 100644
index cb32b7f1bab..00000000000
--- a/xlators/nfs/server/src/nfs-generics.c
+++ /dev/null
@@ -1,345 +0,0 @@
-/*
- Copyright (c) 2010-2011 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.
-*/
-
-#ifndef _CONFIG_H
-#define _CONFIG_H
-#include "config.h"
-#endif
-
-
-#include "string.h"
-
-#include "inode.h"
-#include "nfs.h"
-#include "nfs-fops.h"
-#include "nfs-inodes.h"
-#include "nfs-generics.h"
-#include "xlator.h"
-
-
-int
-nfs_fstat (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, fd_t *fd,
- fop_stat_cbk_t cbk, void *local)
-{
- int ret = -EFAULT;
-
- if ((!nfsx) || (!xl) || (!fd) || (!nfu))
- return ret;
-
- ret = nfs_fop_fstat (nfsx, xl, nfu, fd, cbk, local);
- 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,
- fop_stat_cbk_t cbk, void *local)
-{
- int ret = -EFAULT;
-
- if ((!nfsx) || (!xl) || (!pathloc) || (!nfu))
- return ret;
-
- ret = nfs_fop_stat (nfsx, xl, nfu, pathloc, cbk, local);
-
- return ret;
-}
-
-
-int
-nfs_readdirp (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, fd_t *dirfd,
- size_t bufsize, off_t offset, fop_readdir_cbk_t cbk, void *local)
-{
- if ((!nfsx) || (!xl) || (!dirfd) || (!nfu))
- return -EFAULT;
-
- return nfs_fop_readdirp (nfsx, xl, nfu, dirfd, bufsize, offset, cbk,
- local);
-}
-
-
-int
-nfs_lookup (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *pathloc,
- fop_lookup_cbk_t cbk, void *local)
-{
- int ret = -EFAULT;
-
- if ((!nfsx) || (!xl) || (!pathloc) || (!nfu))
- return ret;
-
- ret = nfs_fop_lookup (nfsx, xl, nfu, pathloc, cbk, local);
- return ret;
-}
-
-int
-nfs_create (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *pathloc,
- int flags, mode_t mode, fop_create_cbk_t cbk, void *local)
-{
- int ret = -EFAULT;
-
- if ((!nfsx) || (!xl) || (!pathloc) || (!nfu))
- return ret;
-
- ret = nfs_inode_create (nfsx, xl, nfu, pathloc, flags, mode, cbk,local);
- return ret;
-}
-
-
-int
-nfs_flush (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, fd_t *fd,
- fop_flush_cbk_t cbk, void *local)
-{
- return nfs_fop_flush (nfsx, xl, nfu, fd, cbk, local);
-}
-
-
-
-int
-nfs_mkdir (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *pathloc,
- mode_t mode, fop_mkdir_cbk_t cbk, void *local)
-{
- int ret = -EFAULT;
-
- if ((!nfsx) || (!xl) || (!pathloc) || (!nfu))
- return ret;
-
- ret = nfs_inode_mkdir (nfsx, xl, nfu, pathloc, mode, cbk, local);
- return ret;
-}
-
-
-
-int
-nfs_truncate (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *pathloc,
- off_t offset, fop_truncate_cbk_t cbk, void *local)
-{
- int ret = -EFAULT;
-
- if ((!xl) || (!pathloc) || (!nfu))
- return ret;
-
- ret = nfs_fop_truncate (nfsx, xl, nfu, pathloc, offset, cbk, local);
- 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)
-{
- 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_getxattr (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *loc,
- char *name, dict_t *xdata, fop_getxattr_cbk_t cbk, void *local)
-{
- return nfs_fop_getxattr (nfsx, xl, nfu, loc, name, xdata, cbk, local);
-}
-
-int
-nfs_setxattr (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu,
- loc_t *loc, dict_t *dict, int32_t flags, dict_t *xdata,
- fop_setxattr_cbk_t cbk, void *local)
-{
- return nfs_fop_setxattr (nfsx, xl, nfu, loc, dict, flags, xdata, cbk,
- local);
-}
-
-int
-nfs_fsync (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, fd_t *fd,
- int32_t datasync, fop_fsync_cbk_t cbk, void *local)
-{
- return nfs_fop_fsync (nfsx, xl, nfu, fd, datasync, cbk, local);
-}
-
-
-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,
- off_t offset, fop_writev_cbk_t cbk, void *local)
-{
- return nfs_fop_write (nfsx, xl, nfu, fd, srciobref, vector, count,
- offset, cbk, local);
-}
-
-
-int
-nfs_open (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *pathloc,
- int32_t flags, fop_open_cbk_t cbk, void *local)
-{
- int ret = -EFAULT;
-
- if ((!nfsx) || (!xl) || (!pathloc) || (!nfu))
- return ret;
-
- ret = nfs_inode_open (nfsx, xl, nfu, pathloc, flags, cbk,
- local);
- return ret;
-}
-
-
-int
-nfs_rename (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *oldloc,
- loc_t *newloc, fop_rename_cbk_t cbk, void *local)
-{
- int ret = -EFAULT;
-
- if ((!nfsx) || (!xl) || (!oldloc) || (!newloc) || (!nfu))
- return ret;
-
- ret = nfs_inode_rename (nfsx, xl, nfu, oldloc, newloc, cbk, local);
- return ret;
-}
-
-
-int
-nfs_link (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *oldloc,
- loc_t *newloc, fop_link_cbk_t cbk, void *local)
-{
- int ret = -EFAULT;
-
- if ((!nfsx) || (!xl) || (!oldloc) || (!newloc) || (!nfu))
- return ret;
-
- ret = nfs_inode_link (nfsx, xl, nfu, oldloc, newloc, cbk, local);
- return ret;
-}
-
-
-int
-nfs_unlink (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *pathloc,
- fop_unlink_cbk_t cbk, void *local)
-{
- int ret = -EFAULT;
-
- if ((!xl) || (!pathloc) || (!nfu))
- return ret;
-
- ret = nfs_inode_unlink (nfsx, xl, nfu, pathloc, cbk, local);
- return ret;
-}
-
-
-int
-nfs_rmdir (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *path,
- fop_rmdir_cbk_t cbk, void *local)
-{
- int ret = -EFAULT;
-
- if ((!nfsx) || (!xl) || (!path) || (!nfu))
- return ret;
-
- ret = nfs_inode_rmdir (nfsx, xl, nfu, path, cbk, local);
- return ret;
-}
-
-
-int
-nfs_mknod (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *pathloc,
- mode_t mode, dev_t dev, fop_mknod_cbk_t cbk, void *local)
-{
- int ret = -EFAULT;
-
- if ((!nfsx) || (!xl) || (!pathloc) || (!nfu))
- return ret;
-
- ret = nfs_inode_mknod (nfsx, xl, nfu, pathloc, mode, dev, cbk, local);
- return ret;
-}
-
-
-int
-nfs_readlink (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *linkloc,
- fop_readlink_cbk_t cbk, void *local)
-{
- int ret = -EFAULT;
-
- if ((!nfsx) || (!xl) || (!linkloc) || (!nfu))
- return ret;
-
- ret = nfs_fop_readlink (nfsx, xl, nfu, linkloc, NFS_PATH_MAX, cbk,
- local);
- return ret;
-}
-
-
-int
-nfs_symlink (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, char *target,
- loc_t *linkloc, fop_symlink_cbk_t cbk, void *local)
-{
- int ret = -EFAULT;
-
- if ((!nfsx) || (!xl) || (!linkloc) || (!target) || (!nfu))
- return ret;
-
- ret = nfs_inode_symlink (nfsx, xl, nfu, target, linkloc, cbk, local);
- return ret;
-}
-
-
-
-int
-nfs_setattr (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *pathloc,
- struct iatt *buf, int32_t valid, fop_setattr_cbk_t cbk,
- void *local)
-{
- int ret = -EFAULT;
-
- if ((!nfsx) || (!xl) || (!pathloc) || (!nfu))
- return ret;
-
- ret = nfs_fop_setattr (nfsx, xl, nfu, pathloc, buf, valid, cbk, local);
- return ret;
-}
-
-
-int
-nfs_statfs (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *pathloc,
- fop_statfs_cbk_t cbk, void *local)
-{
- int ret = -EFAULT;
-
- if ((!nfsx) || (!xl) || (!pathloc) || (!nfu))
- return ret;
-
- ret = nfs_fop_statfs (nfsx, xl, nfu, pathloc, cbk, local);
- return ret;
-}
-
-int
-nfs_opendir (xlator_t *nfsx, xlator_t *fopxl, nfs_user_t *nfu, loc_t *pathloc,
- fop_opendir_cbk_t cbk, void *local)
-{
- if ((!nfsx) || (!fopxl) || (!pathloc) || (!nfu))
- return -EFAULT;
-
- 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
deleted file mode 100644
index 01876d68e2b..00000000000
--- a/xlators/nfs/server/src/nfs-generics.h
+++ /dev/null
@@ -1,168 +0,0 @@
-/*
- Copyright (c) 2010-2011 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.
-*/
-
-#ifndef _NFS_GENERICS_H_
-#define _NFS_GENERICS_H_
-
-#ifndef _CONFIG_H
-#define _CONFIG_H
-#include "config.h"
-#endif
-
-#include "nfs.h"
-#include "xlator.h"
-#include "nfs-fops.h"
-#include "nfs-inodes.h"
-
-struct nfs_direntcache {
- gf_dirent_t entries; /* Head of list of cached dirents. */
- gf_dirent_t *next; /* Pointer to the next entry that
- * should be sent by readdir */
- uint64_t prev_off; /* Offset where the next read will
- * happen.
- */
-};
-
-/* WE're trying to abstract the fops interface from the NFS xlator so that
- * 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.
- */
-typedef struct nfs_fop_fdcontext {
- pthread_mutex_t lock;
- size_t dirent_bufsize;
- off_t offset;
- struct nfs_direntcache *dcache;
- xlator_t *dirvol;
-} nfs_fdctx_t;
-
-extern int
-nfs_fstat (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, fd_t *fd,
- fop_stat_cbk_t cbk, void *local);
-
-extern int
-nfs_readdirp (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, fd_t *dirfd,
- size_t bufsize, off_t offset, fop_readdir_cbk_t cbk, void *local);
-
-
-extern int
-nfs_lookup (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *pathloc,
- fop_lookup_cbk_t cbk, void *local);
-
-extern int
-nfs_create (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *pathloc,
- int flags, mode_t mode, fop_create_cbk_t cbk, void *local);
-
-extern int
-nfs_flush (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, fd_t *fd,
- fop_flush_cbk_t cbk, void *local);
-
-extern int
-nfs_mkdir (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *pathloc,
- mode_t mode, fop_mkdir_cbk_t cbk, void *local);
-
-extern int
-nfs_truncate (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *pathloc,
- off_t offset, fop_truncate_cbk_t cbk, void *local);
-
-extern 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);
-
-extern int
-nfs_fsync (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, fd_t *fd,
- int32_t datasync, fop_fsync_cbk_t cbk, void *local);
-
-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,
- off_t offset, fop_writev_cbk_t cbk, void *local);
-
-extern int
-nfs_open (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *pathloc,
- int32_t flags, fop_open_cbk_t cbk, void *local);
-
-extern int
-nfs_rename (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *oldloc,
- loc_t *newloc, fop_rename_cbk_t cbk, void *local);
-
-extern int
-nfs_link (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *oldloc,
- loc_t *newloc, fop_link_cbk_t cbk, void *local);
-
-extern int
-nfs_unlink (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *pathloc,
- fop_unlink_cbk_t cbk, void *local);
-
-extern int
-nfs_rmdir (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *pathloc,
- fop_rmdir_cbk_t cbk, void *local);
-
-extern int
-nfs_mknod (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *pathloc,
- mode_t mode, dev_t dev, fop_mknod_cbk_t cbk, void *local);
-
-extern int
-nfs_readlink (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *linkloc,
- fop_readlink_cbk_t cbk, void *local);
-
-extern int
-nfs_setattr (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *pathloc,
- struct iatt *buf, int32_t valid, fop_setattr_cbk_t cbk,
- void *local);
-
-extern int
-nfs_statfs (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *pathloc,
- fop_statfs_cbk_t cbk, void *local);
-
-extern int
-nfs_stat (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *pathloc,
- fop_stat_cbk_t cbk, void *local);
-
-extern int
-nfs_symlink (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, char *target,
- loc_t *linkloc, fop_symlink_cbk_t cbk, void *local);
-
-/* Synchronous equivalents */
-
-extern call_stub_t *
-nfs_open_sync (xlator_t *xl, nfs_user_t *nfu, loc_t *pathloc,
- int32_t flags);
-
-extern call_stub_t *
-nfs_write_sync (xlator_t *xl, nfs_user_t *nfu, fd_t *fd, struct iobuf *srciob,
- struct iovec *vec, int count, off_t offset);
-
-extern call_stub_t *
-nfs_read_sync (xlator_t *xl, nfs_user_t *nfu, fd_t *fd, size_t size,
- off_t offset);
-
-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);
-
-extern int
-nfs_getxattr (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *loc,
- char *name, dict_t *xdata, fop_getxattr_cbk_t cbk, void *local);
-
-extern int
-nfs_setxattr (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu,
- loc_t *loc, dict_t *dict, int32_t flags, dict_t *xdata,
- fop_setxattr_cbk_t cbk, void *local);
-
-#endif
diff --git a/xlators/nfs/server/src/nfs-inodes.c b/xlators/nfs/server/src/nfs-inodes.c
deleted file mode 100644
index 63d5e8a198b..00000000000
--- a/xlators/nfs/server/src/nfs-inodes.c
+++ /dev/null
@@ -1,608 +0,0 @@
-/*
- Copyright (c) 2010-2011 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.
-*/
-
-#ifndef _CONFIG_H
-#define _CONFIG_H
-#include "config.h"
-#endif
-
-#include "string.h"
-
-#include "inode.h"
-#include "nfs.h"
-#include "nfs-inodes.h"
-#include "nfs-fops.h"
-#include "xlator.h"
-
-#include <libgen.h>
-
-#define inodes_nfl_to_prog_data(nflocal, pcbk, fram) \
- do { \
- nflocal = fram->local; \
- fram->local = nflocal->proglocal; \
- *VOID(&pcbk) = nflocal->progcbk; \
- nfs_fop_local_wipe (nflocal->nfsx, nflocal); \
- } while (0) \
-
-void
-nfl_inodes_init (struct nfs_fop_local *nfl, inode_t *inode, inode_t *parent,
- inode_t *newparent, const char *name, const char *newname)
-{
- if (!nfl)
- return;
-
- if (inode)
- nfl->inode = inode_ref (inode);
-
- if (parent)
- nfl->parent = inode_ref (parent);
-
- if (newparent)
- nfl->newparent = inode_ref (newparent);
-
- if (name)
- strncpy (nfl->path, name, NFS_NAME_MAX);
-
- if (newname)
- strncpy (nfl->newpath, newname, NFS_NAME_MAX);
-
- return;
-}
-
-
-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 nfs_fop_local *nfl = frame->local;
- fop_create_cbk_t progcbk = NULL;
- inode_t *linked_inode = NULL;
-
- if (op_ret == -1)
- goto do_not_link;
-
- linked_inode = inode_link (inode, nfl->parent, nfl->path, buf);
-
-do_not_link:
- /* NFS does not need it, upper layers should not expect the pointer to
- * be a valid fd.
- */
- fd_unref (fd);
-
- inodes_nfl_to_prog_data (nfl, progcbk, frame);
- if (progcbk)
- progcbk (frame, cookie, this, op_ret, op_errno, fd, inode, buf,
- preparent, postparent, xdata);
-
- if (linked_inode) {
- inode_lookup (linked_inode);
- inode_unref (linked_inode);
- }
-
- return 0;
-}
-
-
-int
-nfs_inode_create (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu,
- loc_t *pathloc, int flags, int mode, fop_create_cbk_t cbk,
- void *local)
-{
- struct nfs_fop_local *nfl = NULL;
- int ret = -EFAULT;
- fd_t *newfd = NULL;
-
- if ((!nfsx) || (!xl) || (!pathloc) || (!nfu))
- return ret;
-
- nfs_fop_handle_local_init (NULL, nfsx, nfl, cbk, local, ret, err);
-
- newfd = fd_create (pathloc->inode, 0);
- if (!newfd) {
- gf_log (GF_NFS, GF_LOG_ERROR, "Failed to create new fd");
- ret = -ENOMEM;
- goto wipe_nfl;
- }
-
- /* The parent and base name will be needed to link the new inode
- * into the inode table.
- */
- nfl_inodes_init (nfl, pathloc->inode, pathloc->parent, NULL,
- pathloc->name, NULL);
- ret = nfs_fop_create (nfsx, xl, nfu, pathloc, flags, mode, newfd,
- nfs_inode_create_cbk, nfl);
-wipe_nfl:
- if (ret < 0)
- nfs_fop_local_wipe (xl, nfl);
-
-err:
- return ret;
-}
-
-
-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 nfs_fop_local *nfl = frame->local;
- fop_mkdir_cbk_t progcbk = NULL;
- inode_t *linked_inode = NULL;
-
- if (op_ret == -1)
- goto do_not_link;
-
- linked_inode = inode_link (inode, nfl->parent, nfl->path, buf);
-
-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);
-
- if (linked_inode) {
- inode_lookup (linked_inode);
- inode_unref (linked_inode);
- }
-
- return 0;
-}
-
-
-int
-nfs_inode_mkdir (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *pathloc,
- int mode, fop_mkdir_cbk_t cbk, void *local)
-{
- struct nfs_fop_local *nfl = NULL;
- int ret = -EFAULT;
-
- if ((!nfsx) || (!xl) || (!pathloc) || (!nfu))
- return ret;
-
- nfs_fop_handle_local_init (NULL, nfsx, nfl, cbk, local, ret, err);
- nfl_inodes_init (nfl, pathloc->inode, pathloc->parent, NULL,
- pathloc->name, NULL);
- ret = nfs_fop_mkdir (nfsx, xl, nfu, pathloc, mode, nfs_inode_mkdir_cbk,
- nfl);
- if (ret < 0)
- nfs_fop_local_wipe (nfsx, nfl);
-
-err:
- return ret;
-}
-
-
-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)
-{
-
- struct nfs_fop_local *nfl = NULL;
- fop_open_cbk_t progcbk = NULL;
-
- if ((op_ret == -1) && (fd))
- fd_unref (fd);
- /* Not needed here since the fd is cached in higher layers and the bind
- * must happen atomically when the fd gets added to the fd LRU.
- */
-/* else
- fd_bind (fd);
-*/
- inodes_nfl_to_prog_data (nfl, progcbk, frame);
- if (progcbk)
- progcbk (frame, cookie, this, op_ret, op_errno, fd, xdata);
- 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)
-{
- struct nfs_fop_local *nfl = NULL;
- fd_t *newfd = NULL;
- int ret = -EFAULT;
-
- if ((!nfsx) || (!xl) || (!loc) || (!nfu))
- return ret;
-
- newfd = fd_create (loc->inode, 0);
- if (!newfd) {
- gf_log (GF_NFS, GF_LOG_ERROR, "Failed to create fd");
- ret = -ENOMEM;
- goto err;
- }
-
- nfs_fop_handle_local_init (NULL, nfsx, nfl, cbk, local, ret, fd_err);
- ret = nfs_fop_open (nfsx, xl, nfu, loc, flags, newfd,
- nfs_inode_open_cbk, nfl);
-
- if (ret < 0)
- nfs_fop_local_wipe (xl, nfl);
-
-fd_err:
- if (ret < 0)
- if (newfd)
- fd_unref (newfd);
-
-err:
-
- return ret;
-}
-
-
-
-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 nfs_fop_local *nfl = NULL;
- fop_rename_cbk_t progcbk = NULL;
-
- nfl = frame->local;
- if (op_ret == -1)
- goto do_not_link;
-
- inode_rename (this->itable, nfl->parent, nfl->path, nfl->newparent,
- nfl->newpath, nfl->inode, buf);
-
-do_not_link:
- inodes_nfl_to_prog_data (nfl, progcbk, frame);
- if (progcbk)
- progcbk (frame, cookie, this, op_ret, op_errno, buf,
- preoldparent, postoldparent, prenewparent,
- postnewparent, xdata);
- return 0;
-}
-
-
-int
-nfs_inode_rename (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *oldloc,
- loc_t *newloc, fop_rename_cbk_t cbk, void *local)
-{
- struct nfs_fop_local *nfl = NULL;
- int ret = -EFAULT;
-
- if ((!nfsx) || (!xl) || (!oldloc) || (!newloc))
- return ret;
-
- nfs_fop_handle_local_init (NULL, nfsx, nfl, cbk, local, ret, err);
- nfl_inodes_init (nfl, oldloc->inode, oldloc->parent, newloc->parent,
- oldloc->name, newloc->name);
- ret = nfs_fop_rename (nfsx,xl, nfu, oldloc, newloc, nfs_inode_rename_cbk
- , nfl);
-
-err:
- if (ret < 0)
- nfs_fop_local_wipe (xl, nfl);
-
- return ret;
-}
-
-
-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 nfs_fop_local *nfl = NULL;
- fop_link_cbk_t progcbk = NULL;
- inode_t *linked_inode = NULL;
-
- if (op_ret == -1)
- goto do_not_link;
-
- nfl = frame->local;
- linked_inode = inode_link (inode, nfl->newparent, nfl->path, buf);
-
-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);
-
- if (linked_inode) {
- inode_lookup (linked_inode);
- inode_unref (linked_inode);
- }
-
- return 0;
-}
-
-
-int
-nfs_inode_link (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *oldloc,
- loc_t *newloc, fop_link_cbk_t cbk, void *local)
-{
- struct nfs_fop_local *nfl = NULL;
- int ret = -EFAULT;
-
- if ((!nfsx) || (!xl) || (!oldloc) || (!newloc) || (!nfu))
- return -EFAULT;
-
- nfs_fop_handle_local_init (NULL, nfsx, nfl, cbk, local, ret, err);
- nfl_inodes_init (nfl, NULL, NULL, newloc->parent, newloc->name, NULL);
- ret = nfs_fop_link (nfsx, xl, nfu, oldloc, newloc, nfs_inode_link_cbk,
- nfl);
-
-err:
- if (ret < 0)
- nfs_fop_local_wipe (xl, nfl);
-
- return ret;
-}
-
-
-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 nfs_fop_local *nfl = NULL;
- fop_unlink_cbk_t progcbk = NULL;
-
- nfl = frame->local;
-
- if (op_ret == -1)
- goto do_not_unlink;
-
- inode_unlink (nfl->inode, nfl->parent, nfl->path);
- inode_forget (nfl->inode, 0);
-
-do_not_unlink:
- inodes_nfl_to_prog_data (nfl, progcbk, frame);
- if (progcbk)
- progcbk (frame, cookie, this, op_ret, op_errno, preparent,
- postparent, xdata);
- return 0;
-}
-
-
-int
-nfs_inode_unlink (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *pathloc,
- fop_unlink_cbk_t cbk, void *local)
-{
- struct nfs_fop_local *nfl = NULL;
- int ret = -EFAULT;
-
- if ((!nfsx) || (!xl) || (!pathloc) || (!nfu))
- return -EFAULT;
-
- nfs_fop_handle_local_init (NULL, nfsx, nfl, cbk, local, ret, err);
- nfl_inodes_init (nfl, pathloc->inode, pathloc->parent, NULL,
- pathloc->name, NULL);
- ret = nfs_fop_unlink (nfsx, xl, nfu, pathloc, nfs_inode_unlink_cbk,nfl);
-
-err:
- if (ret < 0)
- nfs_fop_local_wipe (xl, nfl);
-
- return ret;
-}
-
-
-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 nfs_fop_local *nfl = NULL;
- fop_rmdir_cbk_t progcbk = NULL;
-
- nfl = frame->local;
-
- if (op_ret == -1)
- goto do_not_unlink;
-
- inode_unlink (nfl->inode, nfl->parent, nfl->path);
- inode_forget (nfl->inode, 0);
-
-do_not_unlink:
- inodes_nfl_to_prog_data (nfl, progcbk, frame);
- if (progcbk)
- progcbk (frame, cookie, this, op_ret, op_errno, preparent,
- postparent, xdata);
-
- return 0;
-}
-
-
-int
-nfs_inode_rmdir (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *pathloc,
- fop_rmdir_cbk_t cbk, void *local)
-{
- struct nfs_fop_local *nfl = NULL;
- int ret = -EFAULT;
-
- if ((!nfsx) || (!xl) || (!pathloc) || (!nfu))
- return ret;
-
- nfs_fop_handle_local_init (NULL, nfsx, nfl, cbk, local, ret, err);
- nfl_inodes_init (nfl, pathloc->inode, pathloc->parent, NULL,
- pathloc->name, NULL);
-
- ret = nfs_fop_rmdir (nfsx, xl, nfu, pathloc, nfs_inode_rmdir_cbk, nfl);
-
-err:
- if (ret < 0)
- nfs_fop_local_wipe (xl, nfl);
- return ret;
-}
-
-
-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 nfs_fop_local *nfl = NULL;
- fop_mknod_cbk_t progcbk = NULL;
- inode_t *linked_inode = NULL;
-
- nfl = frame->local;
-
- if (op_ret == -1)
- goto do_not_link;
-
- linked_inode = inode_link (inode, nfl->parent, nfl->path, buf);
-
-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);
-
- if (linked_inode) {
- inode_lookup (linked_inode);
- inode_unref (linked_inode);
- }
-
- return 0;
-}
-
-
-int
-nfs_inode_mknod (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *pathloc,
- mode_t mode, dev_t dev, fop_mknod_cbk_t cbk, void *local)
-{
- struct nfs_fop_local *nfl = NULL;
- int ret = -EFAULT;
-
- if ((!nfsx) || (!xl) || (!pathloc) || (!nfu))
- return ret;
-
- nfs_fop_handle_local_init (NULL, nfsx, nfl, cbk, local, ret, err);
- nfl_inodes_init (nfl, pathloc->inode, pathloc->parent, NULL,
- pathloc->name, NULL);
-
- ret = nfs_fop_mknod (nfsx, xl, nfu, pathloc, mode, dev,
- nfs_inode_mknod_cbk, nfl);
-
-err:
- if (ret < 0)
- nfs_fop_local_wipe (xl, nfl);
-
- return ret;
-}
-
-
-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 nfs_fop_local *nfl = NULL;
- fop_symlink_cbk_t progcbk = NULL;
- inode_t *linked_inode = NULL;
-
- nfl = frame->local;
- if (op_ret == -1)
- goto do_not_link;
-
- linked_inode = inode_link (inode, nfl->parent, nfl->path, buf);
-
-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);
-
- if (linked_inode) {
- inode_lookup (linked_inode);
- inode_unref (linked_inode);
- }
-
- return 0;
-}
-
-
-int
-nfs_inode_symlink (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, char *target,
- loc_t *pathloc, fop_symlink_cbk_t cbk, void *local)
-{
- struct nfs_fop_local *nfl = NULL;
- int ret = -EFAULT;
-
- if ((!nfsx) || (!xl) || (!target) || (!pathloc) || (!nfu))
- return ret;
-
- nfs_fop_handle_local_init (NULL, nfsx, nfl, cbk, local, ret, err);
- nfl_inodes_init (nfl, pathloc->inode, pathloc->parent, NULL,
- pathloc->name, NULL);
- ret = nfs_fop_symlink (nfsx, xl, nfu, target, pathloc,
- nfs_inode_symlink_cbk, nfl);
-
-err:
- if (ret < 0)
- nfs_fop_local_wipe (xl, nfl);
-
- return ret;
-}
-
-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)
-{
-
- struct nfs_fop_local *nfl = NULL;
- fop_open_cbk_t progcbk = NULL;
-
- if (op_ret != -1)
- fd_bind (fd);
-
- inodes_nfl_to_prog_data (nfl, progcbk, frame);
-
- if (progcbk)
- progcbk (frame, cookie, this, op_ret, op_errno, fd, xdata);
-
- return 0;
-}
-
-
-int
-nfs_inode_opendir (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *loc,
- fop_opendir_cbk_t cbk, void *local)
-{
- struct nfs_fop_local *nfl = NULL;
- fd_t *newfd = NULL;
- int ret = -EFAULT;
-
- if ((!nfsx) || (!xl) || (!loc) || (!nfu))
- return ret;
-
- newfd = fd_create (loc->inode, 0);
- if (!newfd) {
- gf_log (GF_NFS, GF_LOG_ERROR, "Failed to create fd");
- ret = -ENOMEM;
- goto err;
- }
-
- nfs_fop_handle_local_init (NULL, nfsx, nfl, cbk, local, ret, err);
- ret = nfs_fop_opendir (nfsx, xl, nfu, loc, newfd,
- nfs_inode_opendir_cbk, nfl);
-
-err:
- if (ret < 0) {
- if (newfd)
- fd_unref (newfd);
- nfs_fop_local_wipe (xl, nfl);
- }
-
- return ret;
-}
diff --git a/xlators/nfs/server/src/nfs-inodes.h b/xlators/nfs/server/src/nfs-inodes.h
deleted file mode 100644
index ba7a5712418..00000000000
--- a/xlators/nfs/server/src/nfs-inodes.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- Copyright (c) 2010-2011 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.
-*/
-
-#ifndef _NFS_INODES_H_
-#define _NFS_INODES_H_
-
-#ifndef _CONFIG_H
-#define _CONFIG_H
-#include "config.h"
-#endif
-
-#include "dict.h"
-#include "xlator.h"
-#include "iobuf.h"
-#include "call-stub.h"
-#include "stack.h"
-#include "nfs-fops.h"
-
-
-extern int
-nfs_link_inode (inode_t *newi, inode_t *parent, char *name,
- struct iatt *newstat);
-
-extern int
-nfs_inode_create (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu,
- loc_t *pathloc, int flags, int mode, fop_create_cbk_t cbk,
- void *local);
-
-extern int
-nfs_inode_mkdir (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *pathloc,
- int mode, fop_mkdir_cbk_t cbk, void *local);
-
-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,
- void *local);
-
-extern int
-nfs_inode_rename (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *oldloc,
- loc_t *newloc, fop_rename_cbk_t cbk, void *local);
-
-extern int
-nfs_inode_link (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *oldloc,
- loc_t *newloc, fop_link_cbk_t cbk, void *local);
-
-extern int
-nfs_inode_unlink (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *pathloc,
- fop_unlink_cbk_t cbk, void *local);
-
-extern int
-nfs_inode_rmdir (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *pathloc,
- fop_rmdir_cbk_t cbk, void *local);
-
-extern int
-nfs_inode_symlink (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, char *target,
- loc_t *pathloc, fop_symlink_cbk_t cbk, void *local);
-
-extern int
-nfs_inode_opendir (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *loc,
- fop_opendir_cbk_t cbk, void *local);
-
-extern int
-nfs_inode_mknod (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *pathloc,
- mode_t mode, dev_t dev, fop_mknod_cbk_t cbk, void *local);
-
-extern int
-nfs_inode_lookup (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *pathloc,
- fop_lookup_cbk_t cbk, void *local);
-#endif
diff --git a/xlators/nfs/server/src/nfs-mem-types.h b/xlators/nfs/server/src/nfs-mem-types.h
deleted file mode 100644
index 450b6f2feab..00000000000
--- a/xlators/nfs/server/src/nfs-mem-types.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- Copyright (c) 2008-2011 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.
-*/
-
-
-#ifndef __NFS_MEM_TYPES_H__
-#define __NFS_MEM_TYPES_H__
-
-#include "mem-types.h"
-
-enum gf_nfs_mem_types_ {
- gf_nfs_mt_mountentry = gf_common_mt_end + 1,
- gf_nfs_mt_mountbody,
- gf_nfs_mt_nfs_state,
- gf_nfs_mt_char,
- gf_nfs_mt_exportnode,
- gf_nfs_mt_groupnode,
- gf_nfs_mt_mount3_state,
- gf_nfs_mt_write3args,
- gf_nfs_mt_nfs3_export,
- gf_nfs_mt_nfs3_state,
- 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_inode_ctx,
- gf_nfs_mt_auth_spec,
- gf_nfs_mt_arr,
- gf_nfs_mt_end
-};
-#endif
-
diff --git a/xlators/nfs/server/src/nfs.c b/xlators/nfs/server/src/nfs.c
deleted file mode 100644
index e3258abf023..00000000000
--- a/xlators/nfs/server/src/nfs.c
+++ /dev/null
@@ -1,1924 +0,0 @@
-/*
- Copyright (c) 2010-2011 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.
-*/
-
-/* This is the primary translator source for NFS.
- * Every other protocol version gets initialized from here.
- */
-
-
-#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 "nlm4.h"
-#include "options.h"
-#include "acl3.h"
-#include "rpc-drc.h"
-#include "syscall.h"
-
-#define OPT_SERVER_AUX_GIDS "nfs.server-aux-gids"
-#define OPT_SERVER_GID_CACHE_TIMEOUT "nfs.server.aux-gid-timeout"
-#define OPT_SERVER_RPC_STATD "nfs.rpc-statd"
-#define OPT_SERVER_RPC_STATD_PIDFILE "nfs.rpc-statd-pidfile"
-#define OPT_SERVER_RPC_STATD_NOTIFY_PIDFILE "nfs.rpc-statd-notify-pidfile"
-
-#define NFS_DATADIR GLUSTERD_DEFAULT_WORKDIR "/nfs"
-
-/* Forward declaration */
-int nfs_add_initer (struct list_head *list, nfs_version_initer_t init);
-
-static int
-nfs_init_version (xlator_t *this, nfs_version_initer_t init)
-{
- int ret = -1;
- struct nfs_initer_list *version = NULL;
- struct nfs_initer_list *tmp = NULL;
- rpcsvc_program_t *prog = NULL;
- struct list_head *versions = NULL;
- struct nfs_state *nfs = NULL;
- gf_boolean_t found = _gf_false;
-
- if ((!this) || (!this->private) || (!init))
- return (-1);
-
- nfs = (struct nfs_state *)this->private;
-
- ret = nfs_add_initer (&nfs->versions, init);
- if (ret == -1) {
- gf_log (GF_NFS, GF_LOG_ERROR,
- "Failed to add protocol initializer");
- goto err;
- }
-
- versions = &nfs->versions;
- list_for_each_entry_safe (version, tmp, versions, list) {
- prog = version->program;
- if (version->init == init) {
- prog = init(this);
- if (!prog) {
- ret = -1;
- goto err;
- }
- version->program = prog;
- found = _gf_true;
- break;
- }
- }
-
- /* program not added */
- if (!found) {
- gf_log (GF_NFS, GF_LOG_ERROR,
- "Program: %s NOT found", prog->progname);
- goto err;
- }
-
- /* Check if nfs.port is configured */
- 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);
- if (ret == -1) {
- gf_log (GF_NFS, GF_LOG_ERROR, "Program: %s init failed",
- prog->progname);
- goto err;
- }
-
- /* Registration with portmapper is disabled, Nothing to do */
- if (!nfs->register_portmap)
- goto err;
-
- ret = rpcsvc_program_register_portmap (prog, prog->progport);
- if (ret == -1) {
- gf_log (GF_NFS, GF_LOG_ERROR,
- "Program %s registration failed",
- prog->progname);
- goto err;
- }
- ret = 0; /* All well */
-err:
- return ret;
-}
-
-static int
-nfs_deinit_version (struct nfs_state *nfs, nfs_version_initer_t init)
-{
- int ret = -1;
- struct nfs_initer_list *version = NULL;
- struct nfs_initer_list *tmp = NULL;
- rpcsvc_program_t *prog = NULL;
- struct list_head *versions = NULL;
-
- if ((!nfs) || (!init))
- return (-1);
-
- versions = &nfs->versions;
- list_for_each_entry_safe (version, tmp, versions, list) {
- prog = version->program;
- if (version->init == init) {
- prog = version->program;
- ret = rpcsvc_program_unregister (nfs->rpcsvc, prog);
- if (ret != 0)
- return (-1);
- list_del (&version->list);
- GF_FREE (version);
- return (0);
- }
- }
-
- return (-1);
-}
-
-static int
-nfs_reconfigure_acl3 (xlator_t *this)
-{
- struct nfs_state *nfs = NULL;
-
- if ((!this) || (!this->private))
- return (-1);
-
- nfs = (struct nfs_state *)this->private;
-
- /* ACL is enabled */
- if (nfs->enable_acl)
- return nfs_init_version (this, acl3svc_init);
-
- /* ACL is disabled */
- return nfs_deinit_version (nfs, acl3svc_init);
-}
-
-static int
-nfs_reconfigure_nlm4 (xlator_t *this)
-{
- struct nfs_state *nfs = NULL;
-
- if ((!this) || (!this->private))
- return (-1);
-
- nfs = (struct nfs_state *)this->private;
-
- /* NLM is enabled */
- if (nfs->enable_nlm)
- return nfs_init_version (this, nlm4svc_init);
-
- /* NLM is disabled */
- return nfs_deinit_version (nfs, nlm4svc_init);
-}
-
-static int
-nfs_program_register_portmap_all (struct nfs_state *nfs)
-{
- struct list_head *versions = NULL;
- struct nfs_initer_list *version = NULL;
- struct nfs_initer_list *tmp = NULL;
- rpcsvc_program_t *prog = NULL;
-
- if (nfs == NULL)
- return (-1);
-
- versions = &nfs->versions;
- list_for_each_entry_safe (version, tmp, versions, list) {
- prog = version->program;
- if (prog == NULL)
- continue;
- if (nfs->override_portnum)
- prog->progport = nfs->override_portnum;
- (void) rpcsvc_program_register_portmap (prog, prog->progport);
- }
-
- return (0);
-}
-
-static int
-nfs_program_unregister_portmap_all (struct nfs_state *nfs)
-{
- struct list_head *versions = NULL;
- struct nfs_initer_list *version = NULL;
- struct nfs_initer_list *tmp = NULL;
- rpcsvc_program_t *prog = NULL;
-
- if (nfs == NULL)
- return (-1);
-
- versions = &nfs->versions;
- list_for_each_entry_safe (version, tmp, versions, list) {
- prog = version->program;
- if (prog == NULL)
- continue;
- (void) rpcsvc_program_unregister_portmap (prog);
- }
-
- return (0);
-}
-
-/* Every NFS version must call this function with the init function
- * for its particular version.
- */
-int
-nfs_add_initer (struct list_head *list, nfs_version_initer_t init)
-{
- struct nfs_initer_list *new = NULL;
- if ((!list) || (!init))
- return -1;
-
- new = GF_CALLOC (1, sizeof (*new), gf_nfs_mt_nfs_initer_list);
- if (!new) {
- gf_log (GF_NFS, GF_LOG_ERROR, "Memory allocation failed");
- return -1;
- }
-
- new->init = init;
- list_add_tail (&new->list, list);
- return 0;
-}
-
-
-int
-nfs_deinit_versions (struct list_head *versions, xlator_t *this)
-{
- struct nfs_initer_list *version = NULL;
- struct nfs_initer_list *tmp = NULL;
- struct nfs_state *nfs = NULL;
-
- if ((!versions) || (!this))
- return -1;
-
- nfs = (struct nfs_state *)this->private;
- list_for_each_entry_safe (version, tmp, versions, list) {
- /* TODO: Add version specific destructor.
- * if (!version->deinit)
- goto err;
-
- version->deinit (this);
- */
- if (version->program)
- rpcsvc_program_unregister (nfs->rpcsvc,
- (version->program));
-
- list_del (&version->list);
- GF_FREE (version);
- }
-
- return 0;
-}
-
-int
-nfs_init_versions (struct nfs_state *nfs, xlator_t *this)
-{
- struct nfs_initer_list *version = NULL;
- struct nfs_initer_list *tmp = NULL;
- rpcsvc_program_t *prog = NULL;
- int ret = -1;
- struct list_head *versions = NULL;
-
- if ((!nfs) || (!this))
- return -1;
-
- gf_log (GF_NFS, GF_LOG_DEBUG, "Initing protocol versions");
- versions = &nfs->versions;
- list_for_each_entry_safe (version, tmp, versions, list) {
- if (!version->init) {
- ret = -1;
- goto err;
- }
-
- prog = version->init (this);
- if (!prog) {
- ret = -1;
- goto err;
- }
-
- 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);
- if (ret == -1) {
- gf_log (GF_NFS, GF_LOG_ERROR, "Program: %s init failed",
- prog->progname);
- goto err;
- }
- if (nfs->register_portmap) {
- ret = rpcsvc_program_register_portmap (prog,
- prog->progport);
- if (ret == -1) {
- gf_log (GF_NFS, GF_LOG_ERROR,
- "Program %s registration failed",
- prog->progname);
- goto err;
- }
- }
-
- }
-
- ret = 0;
-err:
- return ret;
-}
-
-
-int
-nfs_add_all_initiators (struct nfs_state *nfs)
-{
- int ret = 0;
-
- /* Add the initializers for all versions. */
- ret = nfs_add_initer (&nfs->versions, mnt3svc_init);
- if (ret == -1) {
- gf_log (GF_NFS, GF_LOG_ERROR, "Failed to add "
- "MOUNT3 protocol initializer");
- goto ret;
- }
-
- ret = nfs_add_initer (&nfs->versions, mnt1svc_init);
- if (ret == -1) {
- gf_log (GF_NFS, GF_LOG_ERROR, "Failed to add "
- "MOUNT1 protocol initializer");
- goto ret;
- }
-
- ret = nfs_add_initer (&nfs->versions, nfs3svc_init);
- if (ret == -1) {
- gf_log (GF_NFS, GF_LOG_ERROR, "Failed to add "
- "NFS3 protocol initializer");
- 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;
- }
- }
-
- if (nfs->enable_acl == _gf_true) {
- ret = nfs_add_initer (&nfs->versions, acl3svc_init);
- if (ret == -1) {
- gf_log (GF_NFS, GF_LOG_ERROR, "Failed to add "
- "ACL protocol initializer");
- goto ret;
- }
- }
-
- ret = 0;
-ret:
- return ret;
-}
-
-
-int
-nfs_subvolume_started (struct nfs_state *nfs, xlator_t *xl)
-{
- int x = 0;
- int started = 0;
-
- if ((!nfs) || (!xl))
- return 1;
-
- LOCK (&nfs->svinitlock);
- {
- for (;x < nfs->allsubvols; ++x) {
- if (nfs->initedxl[x] == xl) {
- started = 1;
- goto unlock;
- }
- }
- }
-unlock:
- UNLOCK (&nfs->svinitlock);
-
- return started;
-}
-
-
-int
-nfs_subvolume_set_started (struct nfs_state *nfs, xlator_t *xl)
-{
- int x = 0;
-
- if ((!nfs) || (!xl))
- return 1;
-
- LOCK (&nfs->svinitlock);
- {
- for (;x < nfs->allsubvols; ++x) {
- if (nfs->initedxl[x] == xl) {
- gf_log (GF_NFS, GF_LOG_DEBUG,
- "Volume already started %s",
- xl->name);
- break;
- }
-
- if (nfs->initedxl[x] == NULL) {
- nfs->initedxl[x] = xl;
- ++nfs->upsubvols;
- gf_log (GF_NFS, GF_LOG_DEBUG, "Starting up: %s "
- ", vols started till now: %d", xl->name,
- nfs->upsubvols);
- goto unlock;
- }
- }
- }
-unlock:
- UNLOCK (&nfs->svinitlock);
-
- return 0;
-}
-
-
-int32_t
-nfs_start_subvol_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)
-{
- if (op_ret == -1) {
- gf_log (GF_NFS, GF_LOG_CRITICAL, "Failed to lookup root: %s",
- strerror (op_errno));
- goto err;
- }
-
- nfs_subvolume_set_started (this->private, ((xlator_t *)cookie));
- gf_log (GF_NFS, GF_LOG_TRACE, "Started %s", ((xlator_t *)cookie)->name);
-err:
- return 0;
-}
-
-
-int
-nfs_startup_subvolume (xlator_t *nfsx, xlator_t *xl)
-{
- int ret = -1;
- loc_t rootloc = {0, };
- nfs_user_t nfu = {0, };
-
- if ((!nfsx) || (!xl))
- return -1;
-
- if (nfs_subvolume_started (nfsx->private, xl)) {
- gf_log (GF_NFS,GF_LOG_TRACE, "Subvolume already started: %s",
- xl->name);
- ret = 0;
- goto err;
- }
-
- ret = nfs_root_loc_fill (xl->itable, &rootloc);
- if (ret == -1) {
- gf_log (GF_NFS, GF_LOG_CRITICAL, "Failed to init root loc");
- goto err;
- }
-
- nfs_user_root_create (&nfu);
- ret = nfs_fop_lookup (nfsx, xl, &nfu, &rootloc,
- nfs_start_subvol_lookup_cbk,
- (void *)nfsx->private);
- if (ret < 0) {
- gf_log (GF_NFS, GF_LOG_CRITICAL, "Failed to lookup root: %s",
- strerror (-ret));
- goto err;
- }
-
- nfs_loc_wipe (&rootloc);
-
-err:
- return ret;
-}
-
-int
-nfs_startup_subvolumes (xlator_t *nfsx)
-{
- int ret = -1;
- xlator_list_t *cl = NULL;
- struct nfs_state *nfs = NULL;
-
- if (!nfsx)
- return -1;
-
- nfs = nfsx->private;
- cl = nfs->subvols;
- while (cl) {
- gf_log (GF_NFS, GF_LOG_DEBUG, "Starting subvolume: %s",
- cl->xlator->name);
- ret = nfs_startup_subvolume (nfsx, cl->xlator);
- if (ret == -1) {
- gf_log (GF_NFS, GF_LOG_CRITICAL, "Failed to start-up "
- "xlator: %s", cl->xlator->name);
- goto err;
- }
- cl = cl->next;
- }
-
- ret = 0;
-err:
- return ret;
-}
-
-
-int
-nfs_init_subvolume (struct nfs_state *nfs, xlator_t *xl)
-{
- unsigned int lrusize = 0;
- int ret = -1;
-
- if ((!nfs) || (!xl))
- return -1;
-
- lrusize = nfs->memfactor * GF_NFS_INODE_LRU_MULT;
- xl->itable = inode_table_new (lrusize, xl);
- if (!xl->itable) {
- gf_log (GF_NFS, GF_LOG_CRITICAL, "Failed to allocate "
- "inode table");
- goto err;
- }
- ret = 0;
-err:
- return ret;
-}
-
-int
-nfs_init_subvolumes (struct nfs_state *nfs, xlator_list_t *cl)
-{
- int ret = -1;
- unsigned int lrusize = 0;
- int svcount = 0;
-
- if ((!nfs) || (!cl))
- return -1;
-
- lrusize = nfs->memfactor * GF_NFS_INODE_LRU_MULT;
- nfs->subvols = cl;
- gf_log (GF_NFS, GF_LOG_TRACE, "inode table lru: %d", lrusize);
-
- while (cl) {
- gf_log (GF_NFS, GF_LOG_DEBUG, "Initing subvolume: %s",
- cl->xlator->name);
- ret = nfs_init_subvolume (nfs, cl->xlator);
- if (ret == -1) {
- gf_log (GF_NFS, GF_LOG_CRITICAL, "Failed to init "
- "xlator: %s", cl->xlator->name);
- goto err;
- }
- ++svcount;
- cl = cl->next;
- }
-
- LOCK_INIT (&nfs->svinitlock);
- 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");
- ret = -1;
- goto err;
- }
-
- gf_log (GF_NFS, GF_LOG_TRACE, "Inited volumes: %d", svcount);
- nfs->allsubvols = svcount;
- ret = 0;
-err:
- return ret;
-}
-
-
-int
-nfs_user_root_create (nfs_user_t *newnfu)
-{
- if (!newnfu)
- return -1;
-
- newnfu->uid = 0;
- newnfu->gids[0] = 0;
- newnfu->ngrps = 1;
-
- return 0;
-}
-
-
-int
-nfs_user_create (nfs_user_t *newnfu, uid_t uid, gid_t gid, gid_t *auxgids,
- int auxcount)
-{
- int x = 1;
- int y = 0;
-
- /* We test for GF_REQUEST_MAXGROUPS instead of NFS_FOP_NGROUPS because
- * the latter accounts for the @gid being in @auxgids, which is not the
- * case here.
- */
- if ((!newnfu) || (auxcount > GF_REQUEST_MAXGROUPS))
- return -1;
-
- newnfu->uid = uid;
- newnfu->gids[0] = gid;
- newnfu->ngrps = 1;
-
- gf_log (GF_NFS, GF_LOG_TRACE, "uid: %d, gid %d, gids: %d", uid, gid,
- auxcount);
-
- if (!auxgids)
- return 0;
-
- for (; y < auxcount; ++x,++y) {
- newnfu->gids[x] = auxgids[y];
- ++newnfu->ngrps;
- gf_log (GF_NFS, GF_LOG_TRACE, "gid: %d", auxgids[y]);
- }
-
- return 0;
-}
-
-
-void
-nfs_request_user_init (nfs_user_t *nfu, rpcsvc_request_t *req)
-{
- gid_t *gidarr = NULL;
- int gids = 0;
-
- 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);
-
- 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)
-{
- int ret = -1;
-
- if (!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");
- return ret;
- }
-
- return ret;
-}
-
-
-struct nfs_state *
-nfs_init_state (xlator_t *this)
-{
- struct nfs_state *nfs = NULL;
- int ret = -1;
- unsigned int fopspoolsize = 0;
- char *optstr = NULL;
- gf_boolean_t boolt = _gf_false;
- struct stat stbuf = {0,};
-
- if (!this)
- return NULL;
-
- if (!this->children) {
- gf_log (GF_NFS, GF_LOG_INFO,
- "NFS is manually disabled: Exiting");
- /* Nothing for nfs process to do, exit cleanly */
- kill (getpid (), SIGTERM);
- }
-
- nfs = GF_CALLOC (1, sizeof (*nfs), gf_nfs_mt_nfs_state);
- if (!nfs) {
- gf_log (GF_NFS, GF_LOG_ERROR, "memory allocation failed");
- return NULL;
- }
-
- 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;
- }
-
- ret = gf_string2uint (optstr, &nfs->memfactor);
- if (ret < 0) {
- gf_log (GF_NFS, GF_LOG_ERROR, "Failed to parse uint "
- "string");
- goto free_rpcsvc;
- }
- }
-
- fopspoolsize = nfs->memfactor * GF_NFS_CONCURRENT_OPS_MULT;
- /* FIXME: Really saddens me to see this as xlator wide. */
- nfs->foppool = mem_pool_new (struct nfs_fop_local, fopspoolsize);
- if (!nfs->foppool) {
- gf_log (GF_NFS, GF_LOG_CRITICAL, "Failed to allocate fops "
- "local pool");
- goto free_rpcsvc;
- }
-
- nfs->dynamicvolumes = GF_NFS_DVM_OFF;
- if (dict_get (this->options, "nfs.dynamic-volumes")) {
- ret = dict_get_str (this->options, "nfs.dynamic-volumes",
- &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_true)
- nfs->dynamicvolumes = GF_NFS_DVM_ON;
- }
-
- nfs->enable_nlm = _gf_true;
- ret = dict_get_str_boolean (this->options, "nfs.nlm", _gf_true);
- if (ret == _gf_false) {
- gf_log (GF_NFS, GF_LOG_INFO, "NLM is manually disabled");
- nfs->enable_nlm = _gf_false;
- }
-
- nfs->enable_acl = _gf_true;
- ret = dict_get_str_boolean (this->options, "nfs.acl", _gf_true);
- if (ret == _gf_false) {
- gf_log (GF_NFS, GF_LOG_INFO, "ACL is manually disabled");
- nfs->enable_acl = _gf_false;
- }
-
- nfs->enable_ino32 = 0;
- if (dict_get (this->options, "nfs.enable-ino32")) {
- ret = dict_get_str (this->options, "nfs.enable-ino32",
- &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_true)
- nfs->enable_ino32 = 1;
- }
-
- if (dict_get (this->options, "nfs.port")) {
- ret = dict_get_str (this->options, "nfs.port",
- &optstr);
- if (ret < 0) {
- gf_log (GF_NFS, GF_LOG_ERROR, "Failed to parse dict");
- goto free_foppool;
- }
-
- ret = gf_string2uint (optstr, &nfs->override_portnum);
- if (ret < 0) {
- gf_log (GF_NFS, GF_LOG_ERROR, "Failed to parse uint "
- "string");
- goto free_foppool;
- }
- }
-
- 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;
- }
- }
-
- /* Right only socket support exists between nfs client and
- * gluster nfs, so we can set default value as socket
- */
- 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;
- }
-
- nfs->rmtab = gf_strdup (NFS_DATADIR "/rmtab");
- if (dict_get(this->options, "nfs.mount-rmtab")) {
- ret = dict_get_str (this->options, "nfs.mount-rmtab", &nfs->rmtab);
- if (ret == -1) {
- gf_log (GF_NFS, GF_LOG_ERROR, "Failed to parse dict");
- goto free_foppool;
- }
-
- /* check if writing the rmtab is disabled*/
- if (nfs->rmtab && strcmp ("/-", nfs->rmtab) == 0) {
- GF_FREE (nfs->rmtab);
- nfs->rmtab = NULL;
- }
- }
-
- /* 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_RPC_STATD, nfs->rpc_statd, path, free_foppool);
-
- GF_OPTION_INIT (OPT_SERVER_RPC_STATD_PIDFILE, nfs->rpc_statd_pid_file, path, 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;
- }
-
- ret = sys_access (nfs->rpc_statd, X_OK);
- if (ret) {
- gf_log (GF_NFS, GF_LOG_WARNING, "%s not enough permissions to"
- " access. Disabling NLM", nfs->rpc_statd);
- nfs->enable_nlm = _gf_false;
- }
-
- ret = sys_stat (nfs->rpc_statd, &stbuf);
- if (ret || !S_ISREG (stbuf.st_mode)) {
- gf_log (GF_NFS, GF_LOG_WARNING, "%s not a regular file."
- " Disabling NLM", nfs->rpc_statd);
- nfs->enable_nlm = _gf_false;
- }
-
- nfs->rpcsvc = rpcsvc_init (this, this->ctx,
- this->options, fopspoolsize);
- if (!nfs->rpcsvc) {
- ret = -1;
- gf_log (GF_NFS, GF_LOG_ERROR, "RPC service init failed");
- goto free_foppool;
- }
-
- ret = rpcsvc_set_outstanding_rpc_limit (nfs->rpcsvc,
- this->options,
- RPCSVC_DEF_NFS_OUTSTANDING_RPC_LIMIT);
- if (ret < 0) {
- gf_log (GF_NFS, GF_LOG_ERROR,
- "Failed to configure outstanding-rpc-limit");
- goto free_foppool;
- }
-
- nfs->register_portmap = rpcsvc_register_portmap_enabled (nfs->rpcsvc);
-
- this->private = (void *)nfs;
- INIT_LIST_HEAD (&nfs->versions);
- nfs->generation = 1965;
-
- ret = 0;
-
-free_foppool:
- if (ret < 0)
- mem_pool_destroy (nfs->foppool);
-
-free_rpcsvc:
- /*
- * rpcsvc_deinit */
- if (ret < 0) {
- GF_FREE (nfs);
- nfs = NULL;
- }
-
- return nfs;
-}
-
-int
-nfs_drc_init (xlator_t *this)
-{
- int ret = -1;
- rpcsvc_t *svc = NULL;
-
- GF_VALIDATE_OR_GOTO (GF_NFS, this, out);
- GF_VALIDATE_OR_GOTO (GF_NFS, this->private, out);
-
- svc = ((struct nfs_state *)(this->private))->rpcsvc;
- if (!svc)
- goto out;
-
- ret = rpcsvc_drc_init (svc, this->options);
-
- out:
- return ret;
-}
-
-int
-nfs_reconfigure_state (xlator_t *this, dict_t *options)
-{
- int ret = 0;
- int keyindx = 0;
- char *rmtab = NULL;
- char *rpc_statd = NULL;
- gf_boolean_t optbool;
- uint32_t optuint32;
- struct nfs_state *nfs = NULL;
- char *blacklist_keys[] = {
- "nfs.port",
- "nfs.transport-type",
- "nfs.mem-factor",
- NULL};
-
- GF_VALIDATE_OR_GOTO (GF_NFS, this, out);
- GF_VALIDATE_OR_GOTO (GF_NFS, this->private, out);
- GF_VALIDATE_OR_GOTO (GF_NFS, options, out);
-
- nfs = (struct nfs_state *)this->private;
-
- /* Black listed options can't be reconfigured, they need
- * NFS to be restarted. There are two cases 1. SET 2. UNSET.
- * 1. SET */
- while (blacklist_keys[keyindx]) {
- if (dict_get (options, blacklist_keys[keyindx])) {
- gf_log (GF_NFS, GF_LOG_ERROR,
- "Reconfiguring %s needs NFS restart",
- blacklist_keys[keyindx]);
- goto out;
- }
- keyindx ++;
- }
-
- /* UNSET for nfs.mem-factor */
- if ((!dict_get (options, "nfs.mem-factor")) &&
- (nfs->memfactor != GF_NFS_DEFAULT_MEMFACTOR)) {
- gf_log (GF_NFS, GF_LOG_INFO,
- "Reconfiguring nfs.mem-factor needs NFS restart");
- goto out;
- }
-
- /* UNSET for nfs.port */
- if ((!dict_get (options, "nfs.port")) &&
- (nfs->override_portnum)) {
- gf_log (GF_NFS, GF_LOG_ERROR,
- "Reconfiguring nfs.port needs NFS restart");
- goto out;
- }
-
- /* reconfig nfs.rpc-statd... */
- rpc_statd = GF_RPC_STATD_PROG;
- if (dict_get (options, OPT_SERVER_RPC_STATD_PIDFILE)) {
- ret = dict_get_str (options, "nfs.rpc-statd", &rpc_statd);
- if (ret < 0) {
- gf_log (GF_NFS, GF_LOG_ERROR, "Failed to read "
- "reconfigured option: nfs.rpc-statd");
- goto out;
- }
- }
-
- if (strcmp(nfs->rpc_statd, rpc_statd) != 0) {
- gf_log (GF_NFS, GF_LOG_INFO,
- "Reconfiguring nfs.rpc-statd needs NFS restart");
- goto out;
- }
-
- /* reconfig nfs.mount-rmtab */
- rmtab = NFS_DATADIR "/rmtab";
- if (dict_get (options, "nfs.mount-rmtab")) {
- ret = dict_get_str (options, "nfs.mount-rmtab", &rmtab);
- if (ret < 0) {
- gf_log (GF_NFS, GF_LOG_ERROR, "Failed to read "
- "reconfigured option: nfs.mount-rmtab");
- goto out;
- }
- gf_path_strip_trailing_slashes (rmtab);
- }
- /* check if writing the rmtab is disabled*/
- if (strcmp ("/-", rmtab) == 0) {
- GF_FREE (nfs->rmtab);
- nfs->rmtab = NULL;
- gf_log (GF_NFS, GF_LOG_INFO,
- "Disabled writing of nfs.mount-rmtab");
- } else if (!nfs->rmtab || strcmp (nfs->rmtab, rmtab) != 0) {
- mount_rewrite_rmtab (nfs->mstate, rmtab);
- gf_log (GF_NFS, GF_LOG_INFO,
- "Reconfigured nfs.mount-rmtab path: %s",
- nfs->rmtab);
- }
-
- GF_OPTION_RECONF (OPT_SERVER_AUX_GIDS, optbool,
- options, bool, out);
- if (nfs->server_aux_gids != optbool) {
- nfs->server_aux_gids = optbool;
- gf_log(GF_NFS, GF_LOG_INFO, "Reconfigured %s with value %d",
- OPT_SERVER_AUX_GIDS, optbool);
- }
-
- GF_OPTION_RECONF (OPT_SERVER_GID_CACHE_TIMEOUT, optuint32,
- options, uint32, out);
- if (nfs->server_aux_gids_max_age != optuint32) {
- nfs->server_aux_gids_max_age = optuint32;
- gid_cache_reconf (&nfs->gid_cache, optuint32);
- gf_log(GF_NFS, GF_LOG_INFO, "Reconfigured %s with value %d",
- OPT_SERVER_GID_CACHE_TIMEOUT, optuint32);
- }
-
- /* reconfig nfs.dynamic-volumes */
- ret = dict_get_str_boolean (options, "nfs.dynamic-volumes",
- GF_NFS_DVM_OFF);
- switch (ret) {
- case GF_NFS_DVM_ON:
- case GF_NFS_DVM_OFF:
- optbool = ret;
- break;
- default:
- optbool = GF_NFS_DVM_OFF;
- break;
- }
- if (nfs->dynamicvolumes != optbool) {
- nfs->dynamicvolumes = optbool;
- gf_log(GF_NFS, GF_LOG_INFO, "Reconfigured nfs.dynamic-volumes"
- " with value %d", optbool);
- }
-
- optbool = _gf_false;
- if (dict_get (options, "nfs.enable-ino32")) {
- ret = dict_get_str_boolean (options, "nfs.enable-ino32",
- _gf_false);
- if (ret < 0) {
- gf_log (GF_NFS, GF_LOG_ERROR,
- "Failed to read reconfigured option: "
- "nfs.enable-ino32");
- goto out;
- }
- optbool = ret;
- }
- if (nfs->enable_ino32 != optbool) {
- nfs->enable_ino32 = optbool;
- gf_log(GF_NFS, GF_LOG_INFO, "Reconfigured nfs.enable-ino32"
- " with value %d", optbool);
- }
-
- /* nfs.nlm is enabled by default */
- ret = dict_get_str_boolean (options, "nfs.nlm", _gf_true);
- if (ret < 0) {
- optbool = _gf_true;
- } else {
- optbool = ret;
- }
- if (nfs->enable_nlm != optbool) {
- gf_log (GF_NFS, GF_LOG_INFO, "NLM is manually %s",
- (optbool ? "enabled":"disabled"));
- nfs->enable_nlm = optbool;
- nfs_reconfigure_nlm4 (this);
- }
-
- /* nfs.acl is enabled by default */
- ret = dict_get_str_boolean (options, "nfs.acl", _gf_true);
- if (ret < 0) {
- optbool = _gf_true;
- } else {
- optbool = ret;
- }
- if (nfs->enable_acl != optbool) {
- gf_log (GF_NFS, GF_LOG_INFO, "ACL is manually %s",
- (optbool ? "enabled":"disabled"));
- nfs->enable_acl = optbool;
- nfs_reconfigure_acl3 (this);
- }
-
- ret = 0;
-out:
- return ret;
-}
-
-
-/*
- * reconfigure() for NFS server xlator.
- */
-int
-reconfigure (xlator_t *this, dict_t *options)
-{
- int ret = 0;
- struct nfs_state *nfs = NULL;
- gf_boolean_t regpmap = _gf_true;
-
- if ((!this) || (!this->private) || (!options))
- return (-1);
-
- nfs = (struct nfs_state *)this->private;
-
- /* Reconfigure nfs options */
- ret = nfs_reconfigure_state(this, options);
- if (ret) {
- gf_log (GF_NFS, GF_LOG_ERROR,
- "nfs reconfigure state failed");
- return (-1);
- }
-
- /* Reconfigure nfs3 options */
- ret = nfs3_reconfigure_state(this, options);
- if (ret) {
- gf_log (GF_NFS, GF_LOG_ERROR,
- "nfs3 reconfigure state failed");
- return (-1);
- }
-
- /* Reconfigure mount options */
- ret = mount_reconfigure_state(this, options);
- if (ret) {
- gf_log (GF_NFS, GF_LOG_ERROR,
- "mount reconfigure state failed");
- return (-1);
- }
-
- /* Reconfigure rpc layer */
- ret = rpcsvc_reconfigure_options (nfs->rpcsvc, options);
- if (ret) {
- gf_log (GF_NFS, GF_LOG_ERROR,
- "rpcsvc reconfigure options failed");
- return (-1);
- }
-
- /* Reconfigure rpc.outstanding-rpc-limit */
- ret = rpcsvc_set_outstanding_rpc_limit (nfs->rpcsvc,
- options,
- RPCSVC_DEF_NFS_OUTSTANDING_RPC_LIMIT);
- if (ret < 0) {
- gf_log (GF_NFS, GF_LOG_ERROR,
- "Failed to reconfigure outstanding-rpc-limit");
- return (-1);
- }
-
- regpmap = rpcsvc_register_portmap_enabled(nfs->rpcsvc);
- if (nfs->register_portmap != regpmap) {
- nfs->register_portmap = regpmap;
- if (regpmap) {
- (void) nfs_program_register_portmap_all (nfs);
- } else {
- (void) nfs_program_unregister_portmap_all (nfs);
- }
- }
-
- /* Reconfigure drc */
- ret = rpcsvc_drc_reconfigure (nfs->rpcsvc, options);
- if (ret) {
- gf_log (GF_NFS, GF_LOG_ERROR,
- "rpcsvc DRC reconfigure failed");
- return (-1);
- }
-
- return (0);
-}
-
-/* Main init() routine for NFS server xlator. It inits NFS v3 protocol
- * and its dependent protocols e.g. ACL, MOUNT v3 (mount3), NLM and
- * DRC.
- *
- * Usage: glusterfsd:
- * glusterfs_process_volfp() =>
- * glusterfs_graph_activate() =>
- * glusterfs_graph_init() =>
- * xlator_init () => NFS init() routine
- *
- * If init() routine fails, the glusterfsd cleans up the NFS process
- * by invoking cleanup_and_exit().
- *
- * RETURN:
- * 0 (SUCCESS) if all protocol specific inits PASS.
- * -1 (FAILURE) if any of them FAILS.
- */
-int
-init (xlator_t *this) {
-
- struct nfs_state *nfs = NULL;
- int ret = -1;
-
- if (!this)
- return (-1);
-
- nfs = nfs_init_state (this);
- if (!nfs) {
- gf_log (GF_NFS, GF_LOG_ERROR, "Failed to init nfs option");
- return (-1);
- }
-
- ret = nfs_add_all_initiators (nfs);
- if (ret) {
- gf_log (GF_NFS, GF_LOG_ERROR, "Failed to add initiators");
- return (-1);
- }
-
- ret = nfs_init_subvolumes (nfs, this->children);
- if (ret) {
- gf_log (GF_NFS, GF_LOG_CRITICAL, "Failed to init NFS exports");
- return (-1);
- }
-
- ret = mount_init_state (this);
- if (ret) {
- gf_log (GF_NFS, GF_LOG_CRITICAL, "Failed to init Mount state");
- return (-1);
- }
-
- ret = nlm4_init_state (this);
- if (ret) {
- gf_log (GF_NFS, GF_LOG_CRITICAL, "Failed to init NLM state");
- return (-1);
- }
-
- ret = nfs_init_versions (nfs, this);
- if (ret) {
- gf_log (GF_NFS, GF_LOG_ERROR, "Failed to initialize protocols");
- return (-1);
- }
-
- ret = nfs_drc_init (this);
- if (ret) {
- gf_log (GF_NFS, GF_LOG_ERROR, "Failed to initialize DRC");
- return (-1);
- }
-
- gf_log (GF_NFS, GF_LOG_INFO, "NFS service started");
- return (0); /* SUCCESS */
-}
-
-
-int
-notify (xlator_t *this, int32_t event, void *data, ...)
-{
- xlator_t *subvol = NULL;
- struct nfs_state *priv = NULL;
-
- subvol = (xlator_t *)data;
-
- gf_log (GF_NFS, GF_LOG_TRACE, "Notification received: %d",
- event);
-
- switch (event) {
- case GF_EVENT_CHILD_UP:
- nfs_startup_subvolume (this, subvol);
- break;
-
- case GF_EVENT_CHILD_MODIFIED:
- priv = this->private;
- ++(priv->generation);
- break;
-
- case GF_EVENT_PARENT_UP:
- default_notify (this, GF_EVENT_PARENT_UP, data);
- break;
- }
-
- return 0;
-}
-
-
-int
-fini (xlator_t *this)
-{
-
- struct nfs_state *nfs = NULL;
-
- nfs = (struct nfs_state *)this->private;
- gf_log (GF_NFS, GF_LOG_DEBUG, "NFS service going down");
- nfs_deinit_versions (&nfs->versions, this);
- return 0;
-}
-
-int32_t
-nfs_forget (xlator_t *this, inode_t *inode)
-{
- uint64_t ctx = 0;
- struct nfs_inode_ctx *ictx = NULL;
-
- if (inode_ctx_del (inode, this, &ctx))
- return -1;
-
- ictx = (struct nfs_inode_ctx *)ctx;
- GF_FREE (ictx);
-
- 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)
-{
- int32_t ret = -1;
-
- /* DRC needs the global drc structure, xl is of no use to it. */
- ret = rpcsvc_drc_priv (((struct nfs_state *)(this->private))->rpcsvc->drc);
- if (ret) {
- gf_log (this->name, GF_LOG_DEBUG, "Statedump of DRC failed");
- goto out;
- }
-
- ret = nlm_priv (this);
- if (ret) {
- gf_log (this->name, GF_LOG_DEBUG, "Statedump of NLM failed");
- goto out;
- }
- out:
- return ret;
-}
-
-
-struct xlator_cbks cbks = {
- .forget = nfs_forget,
-};
-
-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
-+ * can be and may need these options to be specified separately.
-+ */
-struct volume_options options[] = {
- { .key = {"nfs3.read-size"},
- .type = GF_OPTION_TYPE_SIZET,
- .min = GF_NFS3_RTMIN,
- .max = GF_NFS3_RTMAX,
- .default_value = TOSTRING(GF_NFS3_RTPREF),
- .description = "Size in which the client should issue read requests "
- "to the Gluster NFSv3 server. Must be a multiple of "
- "4KB (4096). Min and Max supported values are 4KB "
- "(4096) and 1MB (1048576) respectively. If the "
- "specified value is within the supported range but "
- "not a multiple of 4096, it is rounded up to the "
- "nearest multiple of 4096."
- },
- { .key = {"nfs3.write-size"},
- .type = GF_OPTION_TYPE_SIZET,
- .min = GF_NFS3_WTMIN,
- .max = GF_NFS3_WTMAX,
- .default_value = TOSTRING(GF_NFS3_WTPREF),
- .description = "Size in which the client should issue write requests "
- "to the Gluster NFSv3 server. Must be a multiple of "
- "1KB (1024). Min and Max supported values are "
- "4KB (4096) and 1MB(1048576) respectively. If the "
- "specified value is within the supported range but "
- "not a multiple of 4096, it is rounded up to the "
- "nearest multiple of 4096."
- },
- { .key = {"nfs3.readdir-size"},
- .type = GF_OPTION_TYPE_SIZET,
- .min = GF_NFS3_DTMIN,
- .max = GF_NFS3_DTMAX,
- .default_value = TOSTRING(GF_NFS3_DTPREF),
- .description = "Size in which the client should issue directory "
- "reading requests to the Gluster NFSv3 server. Must "
- "be a multiple of 1KB (1024). Min and Max supported "
- "values are 4KB (4096) and 1MB (1048576) respectively."
- "If the specified value is within the supported range "
- "but not a multiple of 4096, it is rounded up to the "
- "nearest multiple of 4096."
- },
- { .key = {"nfs3.*.volume-access"},
- .type = GF_OPTION_TYPE_STR,
- .value = {"read-only", "read-write"},
- .default_value = "read-write",
- .description = "Type of access desired for this subvolume: "
- " read-only, read-write(default)"
- },
- { .key = {"nfs3.*.trusted-write"},
- .type = GF_OPTION_TYPE_BOOL,
- .default_value = "off",
- .description = "On an UNSTABLE write from client, return STABLE flag"
- " to force client to not send a COMMIT request. In "
- "some environments, combined with a replicated "
- "GlusterFS setup, this option can improve write "
- "performance. This flag allows user to trust Gluster"
- " replication logic to sync data to the disks and "
- "recover when required. COMMIT requests if received "
- "will be handled in a default manner by fsyncing."
- " STABLE writes are still handled in a sync manner. "
- "Off by default."
-
- },
- { .key = {"nfs3.*.trusted-sync"},
- .type = GF_OPTION_TYPE_BOOL,
- .default_value = "off",
- .description = "All writes and COMMIT requests are treated as async."
- " This implies that no write requests are guaranteed"
- " to be on server disks when the write reply is "
- "received at the NFS client. Trusted sync includes "
- " trusted-write behaviour. Off by default."
-
- },
- { .key = {"nfs3.*.export-dir"},
- .type = GF_OPTION_TYPE_PATH,
- .default_value = "",
- .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 "
- "be exported separately. This option can also be used "
- "in conjunction with nfs3.export-volumes option to "
- "restrict exports only to the subdirectories specified"
- " through this option. Must be an absolute path. Along"
- " with path allowed list of IPs/hostname can be "
- "associated with each subdirectory. If provided "
- "connection will allowed only from these IPs. By "
- "default connections from all IPs are allowed. "
- "Format: <dir>[(hostspec[|hostspec|...])][,...]. Where"
- " hostspec can be an IP address, hostname or an IP "
- "range in CIDR notation. "
- "e.g. /foo(192.168.1.0/24|host1|10.1.1.8),/host2."
- " NOTE: Care must be taken while configuring this "
- "option as invalid entries and/or unreachable DNS "
- "servers can introduce unwanted delay in all the mount"
- " calls."
- },
- { .key = {"nfs3.export-dirs"},
- .type = GF_OPTION_TYPE_BOOL,
- .default_value = "on",
- .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 "
- "be exported separately. Enabling this option allows "
- "any directory on a volumes to be exported separately."
- "Directory exports are enabled by default."
- },
- { .key = {"nfs3.export-volumes"},
- .type = GF_OPTION_TYPE_BOOL,
- .default_value = "on",
- .description = "Enable or disable exporting whole volumes, instead "
- "if used in conjunction with nfs3.export-dir, can "
- "allow setting up only subdirectories as exports. On "
- "by default."
- },
- { .key = {"rpc-auth.auth-unix"},
- .type = GF_OPTION_TYPE_BOOL,
- .default_value = "on",
- .description = "Disable or enable the AUTH_UNIX authentication type."
- "Must always be enabled for better interoperability. "
- "However, can be disabled if needed. Enabled by "
- "default"
- },
- { .key = {"rpc-auth.auth-null"},
- .type = GF_OPTION_TYPE_BOOL,
- .default_value = "on",
- .description = "Disable or enable the AUTH_NULL authentication type."
- "Must always be enabled. This option is here only to"
- " avoid unrecognized option warnings"
- },
- { .key = {"rpc-auth.auth-unix.*"},
- .type = GF_OPTION_TYPE_BOOL,
- .default_value = "on",
- .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,
- .default_value = "on",
- .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-null.*"},
- .type = GF_OPTION_TYPE_BOOL,
- .default_value = "on",
- .description = "Disable or enable the AUTH_NULL authentication type "
- "for a particular exported volume overriding 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_CLIENT_AUTH_ADDR,
- .default_value = "all",
- .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 "
- "define a general rule for all exported volumes."
- },
- { .key = {"rpc-auth.addr.reject"},
- .type = GF_OPTION_TYPE_CLIENT_AUTH_ADDR,
- .default_value = "none",
- .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"
- "define a general rule for all exported volumes."
- },
- { .key = {"rpc-auth.addr.*.allow"},
- .type = GF_OPTION_TYPE_CLIENT_AUTH_ADDR,
- .default_value = "all",
- .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 "
- "define a rule for a specific exported volume."
- },
- { .key = {"rpc-auth.addr.*.reject"},
- .type = GF_OPTION_TYPE_CLIENT_AUTH_ADDR,
- .default_value = "none",
- .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 "
- "define a rule for a specific exported volume."
- },
- { .key = {"rpc-auth.ports.insecure"},
- .type = GF_OPTION_TYPE_BOOL,
- .default_value = "off",
- .description = "Allow client connections from unprivileged ports. By "
- "default only privileged ports are allowed. This is a"
- "global setting in case insecure ports are to be "
- "enabled for all exports using a single option."
- },
- { .key = {"rpc-auth.ports.*.insecure"},
- .type = GF_OPTION_TYPE_BOOL,
- .default_value = "off",
- .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 set by the previous option."
- },
- { .key = {"rpc-auth.addr.namelookup"},
- .type = GF_OPTION_TYPE_BOOL,
- .default_value = "off",
- .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 nfs.rpc-auth-* filters. 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"
- },
- { .key = {"nfs.dynamic-volumes"},
- .type = GF_OPTION_TYPE_BOOL,
- .default_value = "off",
- .description = "Internal option set to tell gnfs to use a different"
- " scheme for encoding file handles when DVM is being"
- " used."
- },
- { .key = {"nfs3.*.volume-id"},
- .type = GF_OPTION_TYPE_STR,
- .default_value = "",
- .description = "When nfs.dynamic-volumes is set, gnfs expects every "
- "subvolume to have this option set for it, so that "
- "gnfs can use this option to identify the volume. "
- "If all subvolumes do not have this option set, an "
- "error is reported."
- },
- { .key = {"nfs.enable-ino32"},
- .type = GF_OPTION_TYPE_BOOL,
- .default_value = "no",
- .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."
- },
- { .key = {"rpc.register-with-portmap"},
- .type = GF_OPTION_TYPE_BOOL,
- .default_value = "on",
- .description = "For systems that need to run multiple nfs servers, "
- "only one registration is possible with "
- "portmap service. Use this option to turn off portmap "
- "registration for Gluster NFS. On by default"
- },
- { .key = {"rpc.outstanding-rpc-limit"},
- .type = GF_OPTION_TYPE_INT,
- .min = RPCSVC_MIN_OUTSTANDING_RPC_LIMIT,
- .max = RPCSVC_MAX_OUTSTANDING_RPC_LIMIT,
- .default_value = TOSTRING(RPCSVC_DEF_NFS_OUTSTANDING_RPC_LIMIT),
- .description = "Parameter to throttle the number of incoming RPC "
- "requests from a client. 0 means no limit (can "
- "potentially run out of memory)"
- },
- { .key = {"nfs.port"},
- .type = GF_OPTION_TYPE_INT,
- .min = 1,
- .max = 0xffff,
- .default_value = TOSTRING(GF_NFS3_PORT),
- .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,
- .default_value = TOSTRING(GF_NFS_DEFAULT_MEMFACTOR),
- .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. "
- "Default value is 15. Increase to use more memory in "
- "order to improve performance for certain use cases."
- "Please consult gluster-users list before using this "
- "option."
- },
- { .key = {"nfs.*.disable"},
- .type = GF_OPTION_TYPE_BOOL,
- .default_value = "false",
- .description = "This option is used to start or stop the NFS server "
- "for individual volumes."
- },
- { .key = {"nfs-ganesha.*.host"},
- .type = GF_OPTION_TYPE_INTERNET_ADDRESS_LIST,
- .default_value = "none",
- .description = "Set nfs-ganesha host IP"
- },
- { .key = {"nfs-ganesha.*.enable"},
- .type = GF_OPTION_TYPE_BOOL,
- .default_value = "off",
- .description = "This option, if set to 'on', enables exports via nfs-ganesha "
- },
-
- { .key = {"nfs.nlm"},
- .type = GF_OPTION_TYPE_BOOL,
- .default_value = "on",
- .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,
- .default_value = "off",
- .description = "set the option to 'on' to enable mountd on UDP. "
- "Required for some Solaris and AIX NFS clients. "
- "The need for enabling this option often depends "
- "on the usage of NLM."
- },
- { .key = {"nfs.mount-rmtab"},
- .type = GF_OPTION_TYPE_PATH,
- .default_value = NFS_DATADIR "/rmtab",
- .description = "Set the location of the cache file that is used to "
- "list all the NFS-clients that have connected "
- "through the MOUNT protocol. If this is on shared "
- "storage, all GlusterFS servers will update and "
- "output (with 'showmount') the same list. Set to "
- "\"/-\" to disable."
- },
- { .key = {OPT_SERVER_RPC_STATD},
- .type = GF_OPTION_TYPE_PATH,
- .default_value = GF_RPC_STATD_PROG,
- .description = "The executable of RPC statd utility. "
- "Defaults to " GF_RPC_STATD_PROG
- },
- { .key = {OPT_SERVER_RPC_STATD_PIDFILE},
- .type = GF_OPTION_TYPE_PATH,
- .default_value = GF_RPC_STATD_PIDFILE,
- .description = "The pid file of RPC statd utility. "
- "Defaults to " GF_RPC_STATD_PIDFILE
- },
- { .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 = {"nfs.acl"},
- .type = GF_OPTION_TYPE_BOOL,
- .default_value = "on",
- .description = "This option is used to control ACL support for NFS."
- },
- { .key = {"nfs.drc"},
- .type = GF_OPTION_TYPE_STR,
- .default_value = "off",
- .description = "Enable Duplicate Request Cache in gNFS server to "
- "improve correctness of non-idempotent operations like "
- "write, delete, link, et al"
- },
- { .key = {"nfs.drc-size"},
- .type = GF_OPTION_TYPE_INT,
- .default_value = "0x20000",
- .description = "Sets the number of non-idempotent "
- "requests to cache in drc"
- },
- { .key = {NULL} },
-};
diff --git a/xlators/nfs/server/src/nfs.h b/xlators/nfs/server/src/nfs.h
deleted file mode 100644
index fc745fbbdc4..00000000000
--- a/xlators/nfs/server/src/nfs.h
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- Copyright (c) 2010-2011 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.
-*/
-
-#ifndef __NFS_H__
-#define __NFS_H__
-
-#ifndef _CONFIG_H
-#define _CONFIG_H
-#include "config.h"
-#endif
-
-#include "rpcsvc.h"
-#include "dict.h"
-#include "xlator.h"
-#include "lkowner.h"
-#include "gidcache.h"
-
-#define GF_NFS "nfs"
-
-#define GF_NFS_CONCURRENT_OPS_MULT 15
-
-#define GF_NFS_INODE_LRU_MULT 6000
-
-#define GF_RPC_MIN_THREADS 1
-#define GF_RPC_MAX_THREADS 16
-
-#define GF_NFS_DEFAULT_MEMFACTOR 15
-#define GF_NFS_MIN_MEMFACTOR 1
-#define GF_NFS_MAX_MEMFACTOR 30
-
-#define GF_NFS_DVM_ON 1
-#define GF_NFS_DVM_OFF 0
-
-/* 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.
- */
-typedef rpcsvc_program_t *(*nfs_version_initer_t) (xlator_t *nfsx);
-
-/* List of version-specific protocol initiators */
-struct nfs_initer_list {
- struct list_head list;
- nfs_version_initer_t init;
- 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;
-
- gf_lock_t svinitlock;
- int allsubvols;
- int upsubvols;
- xlator_t **initedxl;
- int subvols_started;
- int dynamicvolumes;
- int enable_ino32;
- unsigned int override_portnum;
- int allow_insecure;
- int enable_nlm;
- int enable_acl;
- int mount_udp;
- char *rmtab;
- struct rpc_clnt *rpc_clnt;
- gf_boolean_t server_aux_gids;
- uint32_t server_aux_gids_max_age;
- gid_cache_t gid_cache;
- uint32_t generation;
- gf_boolean_t register_portmap;
- char *rpc_statd;
- char *rpc_statd_pid_file;
-};
-
-struct nfs_inode_ctx {
- struct list_head shares;
- uint32_t generation;
-};
-
-#define gf_nfs_dvm_on(nfsstt) (((struct nfs_state *)nfsstt)->dynamicvolumes == GF_NFS_DVM_ON)
-#define gf_nfs_dvm_off(nfsstt) (((struct nfs_state *)nfsstt)->dynamicvolumes == GF_NFS_DVM_OFF)
-#define __gf_nfs_enable_ino32(nfsstt) (((struct nfs_state *)nfsstt)->enable_ino32)
-#define gf_nfs_this_private ((struct nfs_state *)((xlator_t *)THIS)->private)
-#define gf_nfs_enable_ino32() (__gf_nfs_enable_ino32(gf_nfs_this_private))
-
-/* We have one gid more than the glusterfs maximum since we pass the primary
- * gid as the first element of the array.
- */
-#define NFS_NGROUPS (GF_REQUEST_MAXGROUPS + 1)
-
-/* Index of the primary gid */
-#define NFS_PRIMGID_IDX 0
-
-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
-nfs_user_root_create (nfs_user_t *newnfu);
-
-extern int
-nfs_user_create (nfs_user_t *newnfu, uid_t uid, gid_t gid, gid_t *auxgids,
- int auxcount);
-
-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
deleted file mode 100644
index e199c56dc40..00000000000
--- a/xlators/nfs/server/src/nfs3-fh.c
+++ /dev/null
@@ -1,188 +0,0 @@
-/*
- Copyright (c) 2010-2011 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.
-*/
-
-#ifndef _CONFIG_H
-#define _CONFIG_H
-#include "config.h"
-#endif
-
-#include "rpcsvc.h"
-#include "dict.h"
-#include "xlator.h"
-#include "xdr-nfs3.h"
-#include "msg-nfs3.h"
-#include "iobuf.h"
-#include "nfs3-fh.h"
-#include "nfs-common.h"
-#include "iatt.h"
-#include "common-utils.h"
-
-
-int
-nfs3_fh_validate (struct nfs3_fh *fh)
-{
- if (!fh)
- return 0;
-
- if (fh->ident[0] != GF_NFSFH_IDENT0)
- return 0;
-
- if (fh->ident[1] != GF_NFSFH_IDENT1)
- return 0;
-
- if (fh->ident[2] != GF_NFSFH_IDENT2)
- return 0;
-
- if (fh->ident[3] != GF_NFSFH_IDENT3)
- return 0;
-
- return 1;
-}
-
-
-void
-nfs3_fh_init (struct nfs3_fh *fh, struct iatt *buf)
-{
- if ((!fh) || (!buf))
- return;
-
- fh->ident[0] = GF_NFSFH_IDENT0;
- fh->ident[1] = GF_NFSFH_IDENT1;
- fh->ident[2] = GF_NFSFH_IDENT2;
- fh->ident[3] = GF_NFSFH_IDENT3;
-
- uuid_copy (fh->gfid, buf->ia_gfid);
-}
-
-
-struct nfs3_fh
-nfs3_fh_build_indexed_root_fh (xlator_list_t *cl, xlator_t *xl)
-{
- struct nfs3_fh fh = {{0}, };
- struct iatt buf = {0, };
- uuid_t root = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1};
-
- if ((!cl) || (!xl))
- return fh;
-
- uuid_copy (buf.ia_gfid, root);
- nfs3_fh_init (&fh, &buf);
- fh.exportid [15] = nfs_xlator_to_xlid (cl, xl);
-
- return fh;
-}
-
-
-struct nfs3_fh
-nfs3_fh_build_uuid_root_fh (uuid_t volumeid)
-{
- struct nfs3_fh fh = {{0}, };
- struct iatt buf = {0, };
- uuid_t root = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1};
-
- uuid_copy (buf.ia_gfid, root);
- nfs3_fh_init (&fh, &buf);
- uuid_copy (fh.exportid, volumeid);
-
- return fh;
-}
-
-
-int
-nfs3_fh_is_root_fh (struct nfs3_fh *fh)
-{
- uuid_t rootgfid = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1};
-
- if (!fh)
- return 0;
-
- if (uuid_compare (fh->gfid, rootgfid) == 0)
- return 1;
-
- return 0;
-}
-
-
-void
-nfs3_fh_to_str (struct nfs3_fh *fh, char *str, size_t len)
-{
- char gfid[GF_UUID_BUF_SIZE];
- char exportid[GF_UUID_BUF_SIZE];
-
- if ((!fh) || (!str))
- return;
-
- snprintf (str, len, "FH: exportid %s, gfid %s",
- uuid_utoa_r (fh->exportid, exportid),
- uuid_utoa_r (fh->gfid, gfid));
-}
-
-void
-nfs3_log_fh (struct nfs3_fh *fh)
-{
- char gfidstr[512];
- char exportidstr[512];
-
- if (!fh)
- return;
-
- gf_log ("nfs3-fh", GF_LOG_TRACE, "filehandle: exportid "
- "0x%s, gfid 0x%s",
- uuid_utoa_r (fh->exportid, exportidstr),
- uuid_utoa_r (fh->gfid, gfidstr));
-}
-
-int
-nfs3_fh_build_parent_fh (struct nfs3_fh *child, struct iatt *newstat,
- struct nfs3_fh *newfh)
-{
- if ((!child) || (!newstat) || (!newfh))
- return -1;
-
- nfs3_fh_init (newfh, newstat);
- uuid_copy (newfh->exportid, child->exportid);
-
- return 0;
-}
-
-int
-nfs3_build_fh (inode_t *inode, uuid_t exportid, struct nfs3_fh *newfh)
-{
- if (!newfh || !inode)
- return -1;
-
- newfh->ident[0] = GF_NFSFH_IDENT0;
- newfh->ident[1] = GF_NFSFH_IDENT1;
- newfh->ident[2] = GF_NFSFH_IDENT2;
- newfh->ident[3] = GF_NFSFH_IDENT3;
- 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)
-{
- if ((!parent) || (!newstat) || (!newfh))
- return -1;
-
- nfs3_fh_init (newfh, newstat);
- uuid_copy (newfh->exportid, parent->exportid);
-
- return 0;
-}
-
-
-uint32_t
-nfs3_fh_compute_size (struct nfs3_fh *fh)
-{
- return GF_NFSFH_STATIC_SIZE;
-}
diff --git a/xlators/nfs/server/src/nfs3-fh.h b/xlators/nfs/server/src/nfs3-fh.h
deleted file mode 100644
index 1049cdc9621..00000000000
--- a/xlators/nfs/server/src/nfs3-fh.h
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- Copyright (c) 2010-2011 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.
-*/
-
-#ifndef _NFS_FH_H_
-#define _NFS_FH_H_
-
-#ifndef _CONFIG_H
-#define _CONFIG_H
-#include "config.h"
-#endif
-
-#include "xlator.h"
-#include "xdr-nfs3.h"
-#include "iatt.h"
-#include <sys/types.h>
-#include "uuid.h"
-
-/* BIG FAT WARNING: The file handle code is tightly coupled to NFSv3 file
- * handles for now. This will change if and when we need v4. */
-#define GF_NFSFH_IDENT0 ':'
-#define GF_NFSFH_IDENT1 'O'
-#define GF_NFSFH_IDENT2 'G'
-#define GF_NFSFH_IDENT3 'L'
-#define GF_NFSFH_IDENT_SIZE (sizeof(char) * 4)
-#define GF_NFSFH_STATIC_SIZE (GF_NFSFH_IDENT_SIZE + (2*sizeof (uuid_t)))
-
-#define nfs3_fh_exportid_to_index(exprtid) ((uint16_t)exprtid[15])
-/* ATTENTION: Change in size of the structure below should be reflected in the
- * GF_NFSFH_STATIC_SIZE.
- */
-struct nfs3_fh {
-
- /* Used to ensure that a bunch of bytes are actually a GlusterFS NFS
- * file handle. Should contain ":OGL"
- */
- char ident[4];
-
- /* UUID that identifies an export. The value stored in exportid
- * depends on the usage of gluster nfs. If the DVM is enabled using
- * the nfs.dynamic-volumes option then exportid will contain the UUID
- * of the volume so that gnfs is able to identify volumes uniquely
- * through volume additions,deletions,migrations, etc.
- *
- * When not using dvm, exportid contains the index of the volume
- * based on the position of the volume in the list of subvolumes
- * for gnfs.
- */
- uuid_t exportid;
-
- /* File/dir gfid. */
- uuid_t gfid;
- /* This structure must be exactly NFS3_FHSIZE (64) bytes long.
- Having the structure shorter results in buffer overflows
- during XDR decoding.
- */
- unsigned char padding[NFS3_FHSIZE - GF_NFSFH_STATIC_SIZE];
-} __attribute__((__packed__));
-
-#define GF_NFS3FH_STATIC_INITIALIZER {{0},}
-
-extern uint32_t
-nfs3_fh_compute_size (struct nfs3_fh *fh);
-
-extern uint16_t
-nfs3_fh_hash_entry (uuid_t gfid);
-
-extern int
-nfs3_fh_validate (struct nfs3_fh *fh);
-
-extern struct nfs3_fh
-nfs3_fh_build_indexed_root_fh (xlator_list_t *cl, xlator_t *xl);
-
-extern int
-nfs3_fh_is_root_fh (struct nfs3_fh *fh);
-
-extern int
-nfs3_fh_build_child_fh (struct nfs3_fh *parent, struct iatt *newstat,
- struct nfs3_fh *newfh);
-
-extern void
-nfs3_log_fh (struct nfs3_fh *fh);
-
-extern void
-nfs3_fh_to_str (struct nfs3_fh *fh, char *str, size_t len);
-
-extern int
-nfs3_fh_build_parent_fh (struct nfs3_fh *child, struct iatt *newstat,
- struct nfs3_fh *newfh);
-
-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
deleted file mode 100644
index f67cccf1a9b..00000000000
--- a/xlators/nfs/server/src/nfs3-helpers.c
+++ /dev/null
@@ -1,3881 +0,0 @@
-/*
- Copyright (c) 2010-2011 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.
-*/
-
-#ifndef _CONFIG_H
-#define _CONFIG_H
-#include "config.h"
-#endif
-
-#include <inttypes.h>
-
-#include "xlator.h"
-#include "nfs3.h"
-#include "nfs3-fh.h"
-#include "msg-nfs3.h"
-#include "rbthash.h"
-#include "nfs-fops.h"
-#include "nfs-inodes.h"
-#include "nfs-generics.h"
-#include "nfs3-helpers.h"
-#include "nfs-mem-types.h"
-#include "iatt.h"
-#include "common-utils.h"
-#include <string.h>
-
-extern int
-nfs3_set_root_looked_up (struct nfs3_state *nfs3, struct nfs3_fh *rootfh);
-
-extern int
-nfs3_is_root_looked_up (struct nfs3_state *nfs3, struct nfs3_fh *rootfh);
-
-
-#define nfs3_call_resume(cst) \
- do { \
- if (((cst)) && (cst)->resume_fn) \
- (cst)->resume_fn (cst); \
- } while (0) \
-
-#define nfs3_call_resume_estale(csta) \
- do { \
- (csta)->resolve_ret = -1; \
- (csta)->resolve_errno = ESTALE; \
- nfs3_call_resume (csta); \
- } while (0) \
-
-struct nfs3stat_strerror {
- nfsstat3 stat;
- char strerror[100];
-};
-
-
-struct nfs3stat_strerror nfs3stat_strerror_table[] = {
- { NFS3_OK, "Call completed successfully." },
- { NFS3ERR_PERM, "Not owner" },
- { NFS3ERR_NOENT, "No such file or directory" },
- { NFS3ERR_IO, "I/O error" },
- { NFS3ERR_NXIO, "I/O error" },
- { NFS3ERR_ACCES, "Permission denied" },
- { NFS3ERR_EXIST, "File exists" },
- { NFS3ERR_XDEV, "Attempt to do a cross-device hard link"},
- { NFS3ERR_NODEV, "No such device" },
- { NFS3ERR_NOTDIR, "Not a directory" },
- { NFS3ERR_ISDIR, "Is a directory" },
- { NFS3ERR_INVAL, "Invalid argument for operation" },
- { NFS3ERR_FBIG, "File too large" },
- { NFS3ERR_NOSPC, "No space left on device" },
- { NFS3ERR_ROFS, "Read-only file system" },
- { NFS3ERR_MLINK, "Too many hard links" },
- { NFS3ERR_NAMETOOLONG, "Filename in operation was too long" },
- { NFS3ERR_NOTEMPTY, "Directory not empty" },
- { NFS3ERR_DQUOT, "Resource (quota) hard limit exceeded" },
- { NFS3ERR_STALE, "Invalid file handle" },
- { NFS3ERR_REMOTE, "Too many levels of remote in path" },
- { NFS3ERR_BADHANDLE, "Illegal NFS file handle" },
- { NFS3ERR_NOT_SYNC, "Update synchronization mismatch detected" },
- { NFS3ERR_BAD_COOKIE, "READDIR or READDIRPLUS cookie is stale"},
- { NFS3ERR_NOTSUPP, "Operation is not supported" },
- { NFS3ERR_TOOSMALL, "Buffer or request is too small" },
- { NFS3ERR_SERVERFAULT, "Error occurred on the server or IO Error" },
- { NFS3ERR_BADTYPE, "Type not supported by the server" },
- { NFS3ERR_JUKEBOX, "Cannot complete server initiated request" },
- { NFS3ERR_END_OF_LIST, "IO Error" },
-
-};
-
-
-uint64_t
-nfs3_iatt_gfid_to_ino (struct iatt *buf)
-{
- uint64_t ino = 0;
-
- if (!buf)
- return 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;
-
-hashout:
- return ino;
-}
-
-
-void
-nfs3_map_deviceid_to_statdev (struct iatt *ia, uint64_t deviceid)
-{
- if (!ia)
- return;
-
- ia->ia_dev = deviceid;
-}
-
-
-struct nfs3_fh
-nfs3_extract_nfs3_fh (nfs_fh3 fh)
-{
- struct nfs3_fh gfh;
-
- memcpy (&gfh, fh.data.data_val, fh.data.data_len);
- return gfh;
-}
-
-
-struct nfs3_fh
-nfs3_extract_lookup_fh (lookup3args *args)
-{
- return nfs3_extract_nfs3_fh(args->what.dir);
-}
-
-
-char *
-nfs3_extract_lookup_name (lookup3args *args)
-{
- return args->what.name;
-}
-
-
-nfsstat3
-nfs3_errno_to_nfsstat3 (int errnum)
-{
- nfsstat3 stat = NFS3_OK;
-
- switch (errnum) {
-
- case 0:
- stat = NFS3_OK;
- break;
-
- case EPERM:
- stat = NFS3ERR_PERM;
- break;
-
- case ENOENT:
- stat = NFS3ERR_NOENT;
- break;
-
- case EACCES:
- stat = NFS3ERR_ACCES;
- break;
-
- case EEXIST:
- stat = NFS3ERR_EXIST;
- break;
-
- case EXDEV:
- stat = NFS3ERR_XDEV;
- break;
-
- case ENODEV:
- stat = NFS3ERR_NODEV;
- break;
-
- case EIO:
- stat = NFS3ERR_IO;
- break;
-
- case ENXIO:
- stat = NFS3ERR_NXIO;
- break;
-
- case ENOTDIR:
- stat = NFS3ERR_NOTDIR;
- break;
-
- case EISDIR:
- stat = NFS3ERR_ISDIR;
- break;
-
- case EINVAL:
- stat = NFS3ERR_INVAL;
- break;
-
- case ENOSPC:
- stat = NFS3ERR_NOSPC;
- break;
-
- case EROFS:
- stat = NFS3ERR_ROFS;
- break;
-
- case EFBIG:
- stat = NFS3ERR_FBIG;
- break;
-
- case EMLINK:
- stat = NFS3ERR_MLINK;
- break;
-
- case ENAMETOOLONG:
- stat = NFS3ERR_NAMETOOLONG;
- break;
-
- case ENOTEMPTY:
- stat = NFS3ERR_NOTEMPTY;
- break;
-
- case EFAULT:
- stat = NFS3ERR_SERVERFAULT;
- break;
-
- case ENOSYS:
- stat = NFS3ERR_NOTSUPP;
- break;
-
- case EBADF:
- stat = NFS3ERR_BADTYPE;
- break;
-
- case ESTALE:
- stat = NFS3ERR_STALE;
- break;
-
- case ENOTCONN:
- stat = NFS3ERR_IO;
- break;
-
- case EDQUOT:
- stat = NFS3ERR_DQUOT;
- break;
-
- default:
- stat = NFS3ERR_SERVERFAULT;
- break;
- }
-
- return stat;
-}
-
-/*
- * Special case: If op_ret is -1, it's very unusual op_errno being
- * 0 which means something came wrong from upper layer(s). If it
- * happens by any means, then set NFS3 status to NFS3ERR_SERVERFAULT.
- */
-inline nfsstat3
-nfs3_cbk_errno_status (int32_t op_ret, int32_t op_errno)
-{
- if ((op_ret == -1) && (op_errno == 0)) {
- return NFS3ERR_SERVERFAULT;
- }
-
- return nfs3_errno_to_nfsstat3 (op_errno);
-}
-
-void
-nfs3_fill_lookup3res_error (lookup3res *res, nfsstat3 stat,
- struct iatt *dirstat)
-{
-
- memset (res, 0, sizeof (*res));
- res->status = stat;
- if (!dirstat) {
- res->lookup3res_u.resfail.dir_attributes.attributes_follow = FALSE;
- }
-
-}
-
-fattr3
-nfs3_stat_to_fattr3 (struct iatt *buf)
-{
- fattr3 fa = {0, };
-
- if (buf == NULL)
- goto out;
-
- if (IA_ISDIR (buf->ia_type))
- fa.type = NF3DIR;
- else if (IA_ISREG (buf->ia_type))
- fa.type = NF3REG;
- else if (IA_ISCHR (buf->ia_type))
- fa.type = NF3CHR;
- else if (IA_ISBLK (buf->ia_type))
- fa.type = NF3BLK;
- else if (IA_ISFIFO (buf->ia_type))
- fa.type = NF3FIFO;
- else if (IA_ISLNK (buf->ia_type))
- fa.type = NF3LNK;
- else if (IA_ISSOCK (buf->ia_type))
- fa.type = NF3SOCK;
-
- if (IA_PROT_RUSR (buf->ia_prot))
- fa.mode |= NFS3MODE_ROWNER;
- if (IA_PROT_WUSR (buf->ia_prot))
- fa.mode |= NFS3MODE_WOWNER;
- if (IA_PROT_XUSR (buf->ia_prot))
- fa.mode |= NFS3MODE_XOWNER;
-
- if (IA_PROT_RGRP (buf->ia_prot))
- fa.mode |= NFS3MODE_RGROUP;
- if (IA_PROT_WGRP (buf->ia_prot))
- fa.mode |= NFS3MODE_WGROUP;
- if (IA_PROT_XGRP (buf->ia_prot))
- fa.mode |= NFS3MODE_XGROUP;
-
- if (IA_PROT_ROTH (buf->ia_prot))
- fa.mode |= NFS3MODE_ROTHER;
- if (IA_PROT_WOTH (buf->ia_prot))
- fa.mode |= NFS3MODE_WOTHER;
- if (IA_PROT_XOTH (buf->ia_prot))
- fa.mode |= NFS3MODE_XOTHER;
-
- if (IA_PROT_SUID (buf->ia_prot))
- fa.mode |= NFS3MODE_SETXUID;
- if (IA_PROT_SGID (buf->ia_prot))
- fa.mode |= NFS3MODE_SETXGID;
- if (IA_PROT_STCKY (buf->ia_prot))
- fa.mode |= NFS3MODE_SAVESWAPTXT;
-
- fa.nlink = buf->ia_nlink;
- fa.uid = buf->ia_uid;
- fa.gid = buf->ia_gid;
- fa.size = buf->ia_size;
- fa.used = (buf->ia_blocks * 512);
-
- if ((IA_ISCHR (buf->ia_type) || IA_ISBLK (buf->ia_type))) {
- fa.rdev.specdata1 = ia_major (buf->ia_rdev);
- fa.rdev.specdata2 = ia_minor (buf->ia_rdev);
- } else {
- fa.rdev.specdata1 = 0;
- fa.rdev.specdata2 = 0;
- }
-
- fa.fsid = buf->ia_dev;
- fa.fileid = nfs3_iatt_gfid_to_ino (buf);
-
- fa.atime.seconds = buf->ia_atime;
- fa.atime.nseconds = buf->ia_atime_nsec;
-
- 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;
-
-out:
- return fa;
-}
-
-
-post_op_attr
-nfs3_stat_to_post_op_attr (struct iatt *buf)
-{
- post_op_attr attr = {0, };
- if (!buf)
- return attr;
-
- /* Some performance translators return zero-filled stats when they
- * do not have up-to-date attributes. Need to handle this by not
- * returning these zeroed out attrs.
- */
- attr.attributes_follow = FALSE;
- if (nfs_zero_filled_stat (buf))
- goto out;
-
- attr.post_op_attr_u.attributes = nfs3_stat_to_fattr3 (buf);
- attr.attributes_follow = TRUE;
-
-out:
- return attr;
-}
-
-
-pre_op_attr
-nfs3_stat_to_pre_op_attr (struct iatt *pre)
-{
- pre_op_attr poa = {0, };
-
- /* Some performance translators return zero-filled stats when they
- * do not have up-to-date attributes. Need to handle this by not
- * returning these zeroed out attrs.
- */
- poa.attributes_follow = FALSE;
- if (nfs_zero_filled_stat (pre))
- goto out;
-
- 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;
- 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;
-}
-
-void
-nfs3_fill_lookup3res_success (lookup3res *res, nfsstat3 stat,
- struct nfs3_fh *fh, struct iatt *buf,
- struct iatt *postparent)
-{
- post_op_attr obj, dir;
- uint32_t fhlen = 0;
-
- res->status = stat;
- if (fh) {
- res->lookup3res_u.resok.object.data.data_val = (void *)fh;
- fhlen = nfs3_fh_compute_size (fh);
- res->lookup3res_u.resok.object.data.data_len = fhlen;
- }
-
- obj.attributes_follow = FALSE;
- dir.attributes_follow = FALSE;
- obj = nfs3_stat_to_post_op_attr (buf);
- dir = nfs3_stat_to_post_op_attr (postparent);
-
- res->lookup3res_u.resok.obj_attributes = obj;
- res->lookup3res_u.resok.dir_attributes = dir;
-}
-
-
-void
-nfs3_fill_lookup3res (lookup3res *res, nfsstat3 stat, struct nfs3_fh *newfh,
- struct iatt *buf, struct iatt *postparent,
- uint64_t deviceid)
-{
-
- memset (res, 0, sizeof (*res));
- nfs3_map_deviceid_to_statdev (buf, deviceid);
- nfs3_map_deviceid_to_statdev (postparent, deviceid);
- if (stat != NFS3_OK)
- nfs3_fill_lookup3res_error (res, stat, postparent);
- else
- nfs3_fill_lookup3res_success (res, stat, newfh, buf,
- postparent);
-}
-
-struct nfs3_fh
-nfs3_extract_getattr_fh (getattr3args *args)
-{
- return nfs3_extract_nfs3_fh(args->object);
-}
-
-
-void
-nfs3_fill_getattr3res (getattr3res *res, nfsstat3 stat, struct iatt *buf,
- uint64_t deviceid)
-{
-
- memset (res, 0, sizeof (*res));
- res->status = stat;
- if (stat != NFS3_OK)
- return;
-
- nfs3_map_deviceid_to_statdev (buf, deviceid);
- res->getattr3res_u.resok.obj_attributes = nfs3_stat_to_fattr3 (buf);
-
-}
-
-
-struct nfs3_fh
-nfs3_extract_fsinfo_fh (fsinfo3args *args)
-{
- return nfs3_extract_nfs3_fh (args->fsroot);
-}
-
-
-void
-nfs3_fill_fsinfo3res (struct nfs3_state *nfs3, fsinfo3res *res,
- nfsstat3 status, struct iatt *fsroot, uint64_t deviceid)
-{
- fsinfo3resok resok = {{0}, };
- nfstime3 tdelta = GF_NFS3_TIMEDELTA_SECS;
-
- memset (res, 0, sizeof (*res));
- res->status = status;
- if (status != NFS3_OK)
- return;
-
- nfs3_map_deviceid_to_statdev (fsroot, deviceid);
- resok.obj_attributes = nfs3_stat_to_post_op_attr (fsroot);
- resok.rtmax = nfs3->readsize;
- resok.rtpref = nfs3->readsize;
- resok.rtmult = GF_NFS3_RTMULT;
- resok.wtmax = nfs3->writesize;
- resok.wtpref = nfs3->writesize;
- resok.wtmult = GF_NFS3_WTMULT;
- resok.dtpref = nfs3->readdirsize;
- resok.maxfilesize = GF_NFS3_MAXFILESIZE;
- resok.time_delta = tdelta;
- resok.properties = GF_NFS3_FS_PROP;
-
- res->fsinfo3res_u.resok = resok;
-
-}
-
-
-void
-nfs3_prep_lookup3args (lookup3args *args, struct nfs3_fh *fh, char *name)
-{
- memset (args, 0, sizeof (*args));
- args->what.dir.data.data_val = (void *)fh;
- args->what.name = name;
-}
-
-
-void
-nfs3_prep_getattr3args (getattr3args *args, struct nfs3_fh *fh)
-{
- memset (args, 0, sizeof (*args));
- args->object.data.data_val = (void *)fh;
-}
-
-
-void
-nfs3_prep_fsinfo3args (fsinfo3args *args, struct nfs3_fh *root)
-{
- memset (args, 0, sizeof (*args));
- args->fsroot.data.data_val = (void *)root;
-}
-
-
-char *
-nfsstat3_strerror(int stat)
-{
- int i;
- for(i = 0; nfs3stat_strerror_table[i].stat != NFS3ERR_END_OF_LIST ; i++) {
- if (nfs3stat_strerror_table[i].stat == stat)
- return nfs3stat_strerror_table[i].strerror;
- }
-
- return nfs3stat_strerror_table[i].strerror;
-}
-
-
-
-void
-nfs3_prep_access3args (access3args *args, struct nfs3_fh *fh)
-{
- memset (args, 0, sizeof (*args));
- 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)
-{
- uint32_t accresult = 0;
-
- if (accbits & POSIX_READ)
- accresult |= ACCESS3_READ;
-
- if (accbits & POSIX_WRITE)
- accresult |= (ACCESS3_MODIFY | ACCESS3_EXTEND | ACCESS3_DELETE);
-
- /* lookup on directory allowed only in case of execute permission */
- if (accbits & POSIX_EXEC)
- accresult |= (ACCESS3_EXECUTE | ACCESS3_LOOKUP);
-
- return accresult;
-}
-
-uint32_t
-nfs3_request_to_accessbits (int32_t accbits)
-{
- uint32_t acc_request = 0;
-
- if (accbits & ACCESS3_READ)
- acc_request |= POSIX_READ;
-
- if (accbits & (ACCESS3_MODIFY | ACCESS3_EXTEND | ACCESS3_DELETE))
- acc_request |= POSIX_WRITE;
-
- /* For lookup on directory check for execute permission */
- if (accbits & (ACCESS3_EXECUTE | ACCESS3_LOOKUP))
- acc_request |= POSIX_EXEC;
-
- return acc_request;
-}
-void
-nfs3_fill_access3res (access3res *res, nfsstat3 status, int32_t accbits,
- int32_t reqaccbits)
-{
- uint32_t accres = 0;
-
- memset (res, 0, sizeof (*res));
- res->status = status;
- if (status != NFS3_OK)
- return;
-
- accres = nfs3_accessbits (accbits);
-
- /* do not answer what was not asked */
- res->access3res_u.resok.access = accres & reqaccbits;
-}
-
-void
-nfs3_prep_readdir3args (readdir3args *ra, struct nfs3_fh *fh)
-{
- memset (ra, 0, sizeof (*ra));
- ra->dir.data.data_val = (void *)fh;
-}
-
-
-int
-nfs3_is_dot_entry (char *entry)
-{
- int ret = 0;
-
- if (!entry)
- return 0;
-
- if (strcmp (entry, ".") == 0)
- ret = 1;
-
- return ret;
-}
-
-
-int
-nfs3_is_parentdir_entry (char *entry)
-{
- int ret = 0;
-
- if (!entry)
- return 0;
-
- if (strcmp (entry, "..") == 0)
- ret = 1;
-
- return ret;
-}
-
-
-void
-nfs3_funge_root_dotdot_dirent (gf_dirent_t *ent, struct nfs3_fh *dfh)
-{
- if ((!ent) || (!dfh))
- return;
-
- if (nfs3_fh_is_root_fh (dfh) &&
- nfs3_is_parentdir_entry (ent->d_name)) {
- ent->d_ino = 1;
- ent->d_stat.ia_ino = 1;
- }
-
- if (nfs3_fh_is_root_fh (dfh) &&
- nfs3_is_dot_entry (ent->d_name)) {
- ent->d_ino = 1;
- ent->d_stat.ia_ino = 1;
- }
-
-}
-
-
-entry3 *
-nfs3_fill_entry3 (gf_dirent_t *entry, struct nfs3_fh *dfh)
-{
- entry3 *ent = NULL;
- if ((!entry) || (!dfh))
- return NULL;
-
- ent = GF_CALLOC (1, sizeof (*ent), gf_nfs_mt_entry3);
- if (!ent)
- return NULL;
-
- gf_log (GF_NFS3, GF_LOG_TRACE, "Entry: %s", entry->d_name);
-
- /* 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
- * command: "stat /.."
- */
- entry->d_ino = nfs3_iatt_gfid_to_ino (&entry->d_stat);
- nfs3_funge_root_dotdot_dirent (entry, dfh);
- ent->fileid = entry->d_ino;
- ent->cookie = entry->d_off;
- ent->name = GF_CALLOC ((strlen (entry->d_name) + 1), sizeof (char),
- gf_nfs_mt_char);
- if (!ent->name) {
- GF_FREE (ent);
- ent = NULL;
- goto err;
- }
- strcpy (ent->name, entry->d_name);
-
-err:
- return ent;
-}
-
-
-void
-nfs3_fill_post_op_fh3 (struct nfs3_fh *fh, post_op_fh3 *pfh)
-{
- uint32_t fhlen = 0;
-
- if ((!fh) || (!pfh))
- return;
-
- pfh->handle_follows = 1;
- fhlen = nfs3_fh_compute_size (fh);
- pfh->post_op_fh3_u.handle.data.data_val = (void *)fh;
- pfh->post_op_fh3_u.handle.data.data_len = fhlen;
-}
-
-
-post_op_fh3
-nfs3_fh_to_post_op_fh3 (struct nfs3_fh *fh)
-{
- post_op_fh3 pfh = {0, };
- char *fhp = NULL;
-
- if (!fh)
- return pfh;
-
- pfh.handle_follows = 1;
-
- fhp = GF_CALLOC (1, sizeof (*fh), gf_nfs_mt_char);
- if (!fhp)
- return pfh;
-
- memcpy (fhp, fh, sizeof (*fh));
- nfs3_fill_post_op_fh3 ((struct nfs3_fh *)fhp, &pfh);
- return pfh;
-}
-
-
-entryp3 *
-nfs3_fill_entryp3 (gf_dirent_t *entry, struct nfs3_fh *dirfh, uint64_t devid)
-{
- entryp3 *ent = NULL;
- struct nfs3_fh newfh = {{0}, };
-
- if ((!entry) || (!dirfh))
- return NULL;
-
- /* 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
- * command: "stat /.."
- */
- entry->d_ino = nfs3_iatt_gfid_to_ino (&entry->d_stat);
- nfs3_funge_root_dotdot_dirent (entry, dirfh);
- gf_log (GF_NFS3, GF_LOG_TRACE, "Entry: %s, ino: %"PRIu64,
- entry->d_name, entry->d_ino);
- ent = GF_CALLOC (1, sizeof (*ent), gf_nfs_mt_entryp3);
- if (!ent)
- return NULL;
-
- ent->fileid = entry->d_ino;
- ent->cookie = entry->d_off;
- ent->name = GF_CALLOC ((strlen (entry->d_name) + 1), sizeof (char),
- gf_nfs_mt_char);
- if (!ent->name) {
- GF_FREE (ent);
- ent = NULL;
- goto err;
- }
- strcpy (ent->name, entry->d_name);
-
- nfs3_fh_build_child_fh (dirfh, &entry->d_stat, &newfh);
- nfs3_map_deviceid_to_statdev (&entry->d_stat, devid);
- ent->name_attributes = nfs3_stat_to_post_op_attr (&entry->d_stat);
- ent->name_handle = nfs3_fh_to_post_op_fh3 (&newfh);
-err:
- return ent;
-}
-
-
-void
-nfs3_fill_readdir3res (readdir3res *res, nfsstat3 stat, struct nfs3_fh *dirfh,
- uint64_t cverf, struct iatt *dirstat,
- gf_dirent_t *entries, count3 count, int is_eof,
- uint64_t deviceid)
-{
- post_op_attr dirattr;
- entry3 *ent = NULL;
- entry3 *headentry = NULL;
- entry3 *preventry = NULL;
- count3 filled = 0;
- gf_dirent_t *listhead = NULL;
-
- memset (res, 0, sizeof (*res));
- res->status = stat;
- if (stat != NFS3_OK)
- return;
-
- nfs3_map_deviceid_to_statdev (dirstat, deviceid);
- dirattr = nfs3_stat_to_post_op_attr (dirstat);
- res->readdir3res_u.resok.dir_attributes = dirattr;
- res->readdir3res_u.resok.reply.eof = (bool_t)is_eof;
- memcpy (res->readdir3res_u.resok.cookieverf, &cverf, sizeof (cverf));
-
- filled = NFS3_READDIR_RESOK_SIZE;
- /* First entry is just the list head */
- listhead = entries;
- entries = entries->next;
- while (((entries) && (entries != listhead)) && (filled < count)) {
- /*
- if ((strcmp (entries->d_name, ".") == 0) ||
- (strcmp (entries->d_name, "..") == 0))
- goto nextentry;
- */
- ent = nfs3_fill_entry3 (entries, dirfh);
- if (!ent)
- break;
-
- if (!headentry)
- headentry = ent;
-
- if (preventry) {
- preventry->nextentry = ent;
- preventry = ent;
- } else
- preventry = ent;
-
- filled += NFS3_ENTRY3_FIXED_SIZE + strlen (ent->name);
-//nextentry:
- entries = entries->next;
- }
-
- res->readdir3res_u.resok.reply.entries = headentry;
-
- return;
-}
-
-
-void
-nfs3_fill_readdirp3res (readdirp3res *res, nfsstat3 stat,
- struct nfs3_fh *dirfh, uint64_t cverf,
- struct iatt *dirstat, gf_dirent_t *entries,
- count3 dircount, count3 maxcount, int is_eof,
- uint64_t deviceid)
-{
- post_op_attr dirattr;
- entryp3 *ent = NULL;
- entryp3 *headentry = NULL;
- entryp3 *preventry = NULL;
- count3 filled = 0;
- gf_dirent_t *listhead = NULL;
- int fhlen = 0;
-
- memset (res, 0, sizeof (*res));
- res->status = stat;
- if (stat != NFS3_OK)
- return;
-
- nfs3_map_deviceid_to_statdev (dirstat, deviceid);
- dirattr = nfs3_stat_to_post_op_attr (dirstat);
- res->readdirp3res_u.resok.dir_attributes = dirattr;
- res->readdirp3res_u.resok.reply.eof = (bool_t)is_eof;
- memcpy (res->readdirp3res_u.resok.cookieverf, &cverf, sizeof (cverf));
-
- filled = NFS3_READDIR_RESOK_SIZE;
- /* First entry is just the list head */
- listhead = entries;
- entries = entries->next;
- while (((entries) && (entries != listhead)) && (filled < maxcount)) {
- /* Linux does not display . and .. entries unless we provide
- * these entries here.
- */
-/* if ((strcmp (entries->d_name, ".") == 0) ||
- (strcmp (entries->d_name, "..") == 0))
- goto nextentry;
- */
- ent = nfs3_fill_entryp3 (entries, dirfh, deviceid);
- if (!ent)
- break;
-
- if (!headentry)
- headentry = ent;
-
- if (preventry) {
- preventry->nextentry = ent;
- preventry = ent;
- } else
- preventry = ent;
-
- fhlen = ent->name_handle.post_op_fh3_u.handle.data.data_len;
- filled += NFS3_ENTRYP3_FIXED_SIZE + fhlen + strlen (ent->name);
-//nextentry:
- entries = entries->next;
- }
-
- res->readdirp3res_u.resok.reply.entries = headentry;
-
- return;
-}
-
-
-void
-nfs3_prep_readdirp3args (readdirp3args *ra, struct nfs3_fh *fh)
-{
- memset (ra, 0, sizeof (*ra));
- ra->dir.data.data_val = (void *)fh;
-}
-
-void
-nfs3_free_readdirp3res (readdirp3res *res)
-{
- entryp3 *ent = NULL;
- entryp3 *next = NULL;
-
- if (!res)
- return;
-
- ent = res->readdirp3res_u.resok.reply.entries;
- while (ent) {
-
- next = ent->nextentry;
- GF_FREE (ent->name);
- GF_FREE (ent->name_handle.post_op_fh3_u.handle.data.data_val);
- GF_FREE (ent);
- ent = next;
- }
-
- return;
-}
-
-
-void
-nfs3_free_readdir3res (readdir3res *res)
-{
- entry3 *ent = NULL;
- entry3 *next = NULL;
-
- if (!res)
- return;
-
- ent = res->readdir3res_u.resok.reply.entries;
- while (ent) {
-
- next = ent->nextentry;
- GF_FREE (ent->name);
- GF_FREE (ent);
- ent = next;
- }
-
- return;
-}
-
-void
-nfs3_prep_fsstat3args (fsstat3args *args, struct nfs3_fh *fh)
-{
- memset (args, 0, sizeof (*args));
- args->fsroot.data.data_val = (char *)fh;
-}
-
-
-void
-nfs3_fill_fsstat3res (fsstat3res *res, nfsstat3 stat, struct statvfs *fsbuf,
- struct iatt *postbuf, uint64_t deviceid)
-{
- post_op_attr poa;
- fsstat3resok resok;
-
- memset (res, 0, sizeof (*res));
- res->status = stat;
- if (stat != NFS3_OK)
- return;
-
- nfs3_map_deviceid_to_statdev (postbuf, deviceid);
- poa = nfs3_stat_to_post_op_attr (postbuf);
- resok.tbytes = (size3)(fsbuf->f_frsize * fsbuf->f_blocks);
- resok.fbytes = (size3)(fsbuf->f_frsize * fsbuf->f_bfree);
- resok.abytes = (size3)(fsbuf->f_frsize * fsbuf->f_bavail);
- resok.tfiles = (size3)(fsbuf->f_files);
- resok.ffiles = (size3)(fsbuf->f_ffree);
- resok.afiles = (size3)(fsbuf->f_favail);
- resok.invarsec = 0;
-
- resok.obj_attributes = poa;
- res->fsstat3res_u.resok = resok;
-}
-
-
-int32_t
-nfs3_sattr3_to_setattr_valid (sattr3 *sattr, struct iatt *buf, mode_t *omode)
-{
- int32_t valid = 0;
- ia_prot_t prot = {0, };
- mode_t mode = 0;
-
- if (!sattr)
- return 0;
-
- if (sattr->mode.set_it) {
- valid |= GF_SET_ATTR_MODE;
-
- if (sattr->mode.set_mode3_u.mode & NFS3MODE_ROWNER) {
- mode |= S_IRUSR;
- prot.owner.read = 1;
- }
- if (sattr->mode.set_mode3_u.mode & NFS3MODE_WOWNER) {
- mode |= S_IWUSR;
- prot.owner.write = 1;
- }
- if (sattr->mode.set_mode3_u.mode & NFS3MODE_XOWNER) {
- mode |= S_IXUSR;
- prot.owner.exec = 1;
- }
-
- if (sattr->mode.set_mode3_u.mode & NFS3MODE_RGROUP) {
- mode |= S_IRGRP;
- prot.group.read = 1;
- }
- if (sattr->mode.set_mode3_u.mode & NFS3MODE_WGROUP) {
- mode |= S_IWGRP;
- prot.group.write = 1;
- }
- if (sattr->mode.set_mode3_u.mode & NFS3MODE_XGROUP) {
- mode |= S_IXGRP;
- prot.group.exec = 1;
- }
-
- if (sattr->mode.set_mode3_u.mode & NFS3MODE_ROTHER) {
- mode |= S_IROTH;
- prot.other.read = 1;
- }
- if (sattr->mode.set_mode3_u.mode & NFS3MODE_WOTHER) {
- mode |= S_IWOTH;
- prot.other.write = 1;
- }
- if (sattr->mode.set_mode3_u.mode & NFS3MODE_XOTHER) {
- mode |= S_IXOTH;
- prot.other.exec = 1;
- }
-
- if (sattr->mode.set_mode3_u.mode & NFS3MODE_SETXUID) {
- mode |= S_ISUID;
- prot.suid = 1;
- }
- if (sattr->mode.set_mode3_u.mode & NFS3MODE_SETXGID) {
- mode |= S_ISGID;
- prot.sgid = 1;
- }
- if (sattr->mode.set_mode3_u.mode & NFS3MODE_SAVESWAPTXT) {
- mode |= S_ISVTX;
- prot.sticky = 1;
- }
-
- if (buf)
- buf->ia_prot = prot;
- /* Create fop still requires the old mode_t style argument. */
- if (omode)
- *omode = mode;
- }
-
- if (sattr->uid.set_it) {
- valid |= GF_SET_ATTR_UID;
- if (buf)
- buf->ia_uid = sattr->uid.set_uid3_u.uid;
- }
-
- if (sattr->gid.set_it) {
- valid |= GF_SET_ATTR_GID;
- if (buf)
- buf->ia_gid = sattr->gid.set_gid3_u.gid;
- }
-
- if (sattr->size.set_it) {
- valid |= GF_SET_ATTR_SIZE;
- if (buf)
- buf->ia_size = sattr->size.set_size3_u.size;
- }
-
- if (sattr->atime.set_it == SET_TO_CLIENT_TIME) {
- valid |= GF_SET_ATTR_ATIME;
- if (buf)
- buf->ia_atime = sattr->atime.set_atime_u.atime.seconds;
- }
-
- if (sattr->atime.set_it == SET_TO_SERVER_TIME) {
- valid |= GF_SET_ATTR_ATIME;
- if (buf)
- buf->ia_atime = time (NULL);
- }
-
- if (sattr->mtime.set_it == SET_TO_CLIENT_TIME) {
- valid |= GF_SET_ATTR_MTIME;
- if (buf)
- buf->ia_mtime = sattr->mtime.set_mtime_u.mtime.seconds;
- }
-
- if (sattr->mtime.set_it == SET_TO_SERVER_TIME) {
- valid |= GF_SET_ATTR_MTIME;
- if (buf)
- buf->ia_mtime = time (NULL);
- }
-
- return valid;
-}
-
-
-wcc_data
-nfs3_stat_to_wcc_data (struct iatt *pre, struct iatt *post)
-{
- wcc_data wd = {{0}, };
-
- if (post)
- wd.after = nfs3_stat_to_post_op_attr (post);
- if (pre)
- wd.before = nfs3_stat_to_pre_op_attr (pre);
-
- return wd;
-}
-
-void
-nfs3_fill_create3res (create3res *res, nfsstat3 stat, struct nfs3_fh *newfh,
- struct iatt *newbuf, struct iatt *preparent,
- struct iatt *postparent, uint64_t deviceid)
-{
- post_op_attr poa = {0, };
- wcc_data dirwcc = {{0}, };
-
- memset (res, 0, sizeof (*res));
- res->status = stat;
- if (stat != NFS3_OK)
- return;
-
- nfs3_fill_post_op_fh3 (newfh, &res->create3res_u.resok.obj);
- nfs3_map_deviceid_to_statdev (newbuf, deviceid);
- poa = nfs3_stat_to_post_op_attr (newbuf);
- res->create3res_u.resok.obj_attributes = poa;
- nfs3_map_deviceid_to_statdev (preparent, deviceid);
- nfs3_map_deviceid_to_statdev (postparent, deviceid);
- dirwcc = nfs3_stat_to_wcc_data (preparent, postparent);
-
- res->create3res_u.resok.dir_wcc = dirwcc;
-}
-
-void
-nfs3_prep_create3args (create3args *args, struct nfs3_fh *fh, char *name)
-{
-
- memset (args, 0, sizeof (*args));
- args->where.dir.data.data_val = (void *)fh;
- args->where.name = name;
-}
-
-void
-nfs3_prep_setattr3args (setattr3args *args, struct nfs3_fh *fh)
-{
- memset (args, 0, sizeof (*args));
- args->object.data.data_val = (void *)fh;
-}
-
-
-void
-nfs3_fill_setattr3res (setattr3res *res, nfsstat3 stat, struct iatt *preop,
- struct iatt *postop, uint64_t deviceid)
-{
- wcc_data wcc;
- memset (res, 0, sizeof (*res));
- res->status = stat;
- if (stat != NFS3_OK)
- return;
-
- nfs3_map_deviceid_to_statdev (preop, deviceid);
- nfs3_map_deviceid_to_statdev (postop, deviceid);
- wcc = nfs3_stat_to_wcc_data (preop, postop);
- res->setattr3res_u.resok.obj_wcc = wcc;
-}
-
-
-void
-nfs3_prep_mkdir3args (mkdir3args *args, struct nfs3_fh *dirfh, char *name)
-{
-
- memset (args, 0, sizeof (*args));
- args->where.dir.data.data_val = (void *)dirfh;
- args->where.name = name;
-}
-
-
-void
-nfs3_fill_mkdir3res (mkdir3res *res, nfsstat3 stat, struct nfs3_fh *fh,
- struct iatt *buf, struct iatt *preparent,
- struct iatt *postparent, uint64_t deviceid)
-{
- wcc_data dirwcc;
- post_op_attr poa;
-
- memset (res, 0, sizeof (*res));
- res->status = stat;
- if (stat != NFS3_OK)
- return;
-
- nfs3_fill_post_op_fh3 (fh, &res->mkdir3res_u.resok.obj);
- nfs3_map_deviceid_to_statdev (buf, deviceid);
- poa = nfs3_stat_to_post_op_attr (buf);
- nfs3_map_deviceid_to_statdev (preparent, deviceid);
- nfs3_map_deviceid_to_statdev (postparent, deviceid);
- dirwcc = nfs3_stat_to_wcc_data (preparent, postparent);
- res->mkdir3res_u.resok.obj_attributes = poa;
- res->mkdir3res_u.resok.dir_wcc = dirwcc;
-
-}
-
-
-void
-nfs3_prep_symlink3args (symlink3args *args, struct nfs3_fh *dirfh, char *name,
- char *target)
-{
- memset (args, 0, sizeof (*args));
- args->where.dir.data.data_val = (void *)dirfh;
- args->where.name = name;
- args->symlink.symlink_data = target;
-}
-
-
-void
-nfs3_fill_symlink3res (symlink3res *res, nfsstat3 stat, struct nfs3_fh *fh,
- struct iatt *buf, struct iatt *preparent,
- struct iatt *postparent, uint64_t deviceid)
-{
- wcc_data dirwcc;
- post_op_attr poa;
-
- memset (res, 0, sizeof (*res));
- res->status = stat;
- if (stat != NFS3_OK)
- return;
-
- nfs3_fill_post_op_fh3 (fh, &res->symlink3res_u.resok.obj);
- nfs3_map_deviceid_to_statdev (buf, deviceid);
- poa = nfs3_stat_to_post_op_attr (buf);
- nfs3_map_deviceid_to_statdev (postparent, deviceid);
- nfs3_map_deviceid_to_statdev (preparent, deviceid);
- dirwcc = nfs3_stat_to_wcc_data (preparent, postparent);
- res->symlink3res_u.resok.obj_attributes = poa;
- res->symlink3res_u.resok.dir_wcc = dirwcc;
-
-}
-
-
-void
-nfs3_prep_readlink3args (readlink3args *args, struct nfs3_fh *fh)
-{
-
- memset (args, 0, sizeof (*args));
- args->symlink.data.data_val = (void *)fh;
-}
-
-
-void
-nfs3_fill_readlink3res (readlink3res *res, nfsstat3 stat, char *path,
- struct iatt *buf, uint64_t deviceid)
-{
- post_op_attr poa;
-
- memset (res, 0, sizeof (*res));
- res->status = stat;
-
- if (stat != NFS3_OK)
- return;
-
- nfs3_map_deviceid_to_statdev (buf, deviceid);
- poa = nfs3_stat_to_post_op_attr (buf);
- res->readlink3res_u.resok.data = (void *)path;
- res->readlink3res_u.resok.symlink_attributes = poa;
-}
-
-
-void
-nfs3_prep_mknod3args (mknod3args *args, struct nfs3_fh *fh, char *name)
-{
- memset (args, 0, sizeof (*args));
- args->where.dir.data.data_val = (void *)fh;
- args->where.name = name;
-
-}
-
-void
-nfs3_fill_mknod3res (mknod3res *res, nfsstat3 stat, struct nfs3_fh *fh,
- struct iatt *buf, struct iatt *preparent,
- struct iatt *postparent, uint64_t deviceid)
-{
- post_op_attr poa;
- wcc_data wccdir;
-
- memset (res, 0, sizeof (*res));
- res->status = stat;
- if (stat != NFS3_OK)
- return;
-
- nfs3_fill_post_op_fh3 (fh, &res->mknod3res_u.resok.obj);
- nfs3_map_deviceid_to_statdev (buf, deviceid);
- poa = nfs3_stat_to_post_op_attr (buf);
- nfs3_map_deviceid_to_statdev (preparent, deviceid);
- nfs3_map_deviceid_to_statdev (postparent, deviceid);
- wccdir = nfs3_stat_to_wcc_data (preparent, postparent);
- res->mknod3res_u.resok.obj_attributes = poa;
- res->mknod3res_u.resok.dir_wcc = wccdir;
-
-}
-
-
-void
-nfs3_fill_remove3res (remove3res *res, nfsstat3 stat, struct iatt *preparent,
- struct iatt *postparent, uint64_t deviceid)
-{
- wcc_data dirwcc;
-
- memset (res, 0, sizeof (*res));
- res->status = stat;
- if (stat != NFS3_OK)
- return;
-
- nfs3_map_deviceid_to_statdev (preparent, deviceid);
- nfs3_map_deviceid_to_statdev (postparent, deviceid);
- dirwcc = nfs3_stat_to_wcc_data (preparent, postparent);
- res->remove3res_u.resok.dir_wcc = dirwcc;
-}
-
-
-void
-nfs3_prep_remove3args (remove3args *args, struct nfs3_fh *fh, char *name)
-{
- memset (args, 0, sizeof (*args));
- args->object.dir.data.data_val = (void *)fh;
- args->object.name = name;
-}
-
-
-void
-nfs3_prep_rmdir3args (rmdir3args *args, struct nfs3_fh *fh, char *name)
-{
- memset (args, 0, sizeof (*args));
- args->object.dir.data.data_val = (void *)fh;
- args->object.name = name;
-}
-
-
-void
-nfs3_fill_rmdir3res (rmdir3res *res, nfsstat3 stat, struct iatt *preparent,
- struct iatt *postparent, uint64_t deviceid)
-{
- wcc_data dirwcc;
- memset (res, 0, sizeof (*res));
- res->status = stat;
-
- if (stat != NFS3_OK)
- return;
-
- nfs3_map_deviceid_to_statdev (postparent, deviceid);
- nfs3_map_deviceid_to_statdev (preparent, deviceid);
- dirwcc = nfs3_stat_to_wcc_data (preparent, postparent);
- res->rmdir3res_u.resok.dir_wcc = dirwcc;
-}
-
-
-void
-nfs3_prep_link3args (link3args *args, struct nfs3_fh *target,
- struct nfs3_fh * dirfh, char *name)
-{
- memset (args, 0, sizeof (*args));
- args->file.data.data_val = (void *)target;
- args->link.dir.data.data_val = (void *)dirfh;
- args->link.name = name;
-}
-
-
-void
-nfs3_fill_link3res (link3res *res, nfsstat3 stat, struct iatt *buf,
- struct iatt *preparent, struct iatt *postparent,
- uint64_t deviceid)
-{
- post_op_attr poa;
- wcc_data dirwcc;
-
- memset (res, 0, sizeof (*res));
- res->status = stat;
- if (stat != NFS3_OK)
- return;
-
- nfs3_map_deviceid_to_statdev (preparent, deviceid);
- nfs3_map_deviceid_to_statdev (postparent, deviceid);
- nfs3_map_deviceid_to_statdev (buf,deviceid);
- poa = nfs3_stat_to_post_op_attr (buf);
- dirwcc = nfs3_stat_to_wcc_data (preparent, postparent);
- res->link3res_u.resok.file_attributes = poa;
- res->link3res_u.resok.linkdir_wcc = dirwcc;
-}
-
-
-
-void
-nfs3_prep_rename3args (rename3args *args, struct nfs3_fh *olddirfh,
- char *oldname, struct nfs3_fh *newdirfh, char *newname)
-{
- memset (args, 0, sizeof (*args));
-
- args->from.name = oldname;
- args->from.dir.data.data_val = (void *)olddirfh;
- args->to.name = newname;
- args->to.dir.data.data_val = (void *)newdirfh;
-
-}
-
-
-void
-nfs3_fill_rename3res (rename3res *res, nfsstat3 stat, struct iatt *buf,
- struct iatt *preoldparent, struct iatt *postoldparent,
- struct iatt *prenewparent, struct iatt *postnewparent,
- uint64_t deviceid)
-
-{
- wcc_data dirwcc;
-
- memset (res, 0, sizeof (*res));
- res->status = stat;
- if (stat != NFS3_OK)
- return;
-
- nfs3_map_deviceid_to_statdev (preoldparent, deviceid);
- nfs3_map_deviceid_to_statdev (postoldparent, deviceid);
- nfs3_map_deviceid_to_statdev (prenewparent, deviceid);
- nfs3_map_deviceid_to_statdev (postnewparent, deviceid);
- nfs3_map_deviceid_to_statdev (buf, deviceid);
- dirwcc = nfs3_stat_to_wcc_data (preoldparent, postoldparent);
- res->rename3res_u.resok.fromdir_wcc = dirwcc;
- dirwcc = nfs3_stat_to_wcc_data (prenewparent, postnewparent);
- res->rename3res_u.resok.todir_wcc = dirwcc;
-}
-
-
-void
-nfs3_prep_write3args (write3args *args, struct nfs3_fh *fh)
-{
- memset (args, 0, sizeof (*args));
- args->file.data.data_val = (void *)fh;
-}
-
-
-void
-nfs3_fill_write3res (write3res *res, nfsstat3 stat, count3 count,
- stable_how stable, uint64_t wverf, struct iatt *prestat,
- struct iatt *poststat, uint64_t deviceid)
-{
- write3resok resok;
- memset (res, 0, sizeof (*res));
- res->status = stat;
- if (stat != NFS3_OK)
- return;
-
- nfs3_map_deviceid_to_statdev (prestat, deviceid);
- nfs3_map_deviceid_to_statdev (poststat, deviceid);
- resok.file_wcc = nfs3_stat_to_wcc_data (prestat, poststat);
- resok.count = count;
- resok.committed = stable;
- memcpy (resok.verf, &wverf, sizeof (wverf));
-
- res->write3res_u.resok = resok;
-}
-
-
-void
-nfs3_prep_commit3args (commit3args *args, struct nfs3_fh *fh)
-{
- memset (args, 0, sizeof (*args));
- args->file.data.data_val = (void *)fh;
-}
-
-
-void
-nfs3_fill_commit3res (commit3res *res, nfsstat3 stat, uint64_t wverf,
- struct iatt *prestat, struct iatt *poststat,
- uint64_t deviceid)
-{
- memset (res, 0, sizeof (*res));
- res->status = stat;
- if (stat != NFS3_OK)
- return;
-
- nfs3_map_deviceid_to_statdev (poststat, deviceid);
- nfs3_map_deviceid_to_statdev (prestat, deviceid);
- res->commit3res_u.resok.file_wcc = nfs3_stat_to_wcc_data (prestat,
- poststat);
- memcpy (res->commit3res_u.resok.verf, &wverf, sizeof (wverf));
-}
-
-void
-nfs3_fill_read3res (read3res *res, nfsstat3 stat, count3 count,
- struct iatt *poststat, int is_eof, uint64_t deviceid)
-{
- post_op_attr poa;
-
- memset (res, 0, sizeof (*res));
- res->status = stat;
- if (stat != NFS3_OK)
- return;
-
- nfs3_map_deviceid_to_statdev (poststat, deviceid);
- poa = nfs3_stat_to_post_op_attr (poststat);
- res->read3res_u.resok.file_attributes = poa;
- res->read3res_u.resok.count = count;
- res->read3res_u.resok.eof = is_eof;
- res->read3res_u.resok.data.data_len = count;
-}
-
-
-void
-nfs3_prep_read3args (read3args *args, struct nfs3_fh *fh)
-{
- memset (args, 0, sizeof (*args));
- args->file.data.data_val = (void *)fh;
-}
-
-
-void
-nfs3_fill_pathconf3res (pathconf3res *res, nfsstat3 stat, struct iatt *buf,
- uint64_t deviceid)
-{
- pathconf3resok resok;
-
- memset (res, 0, sizeof (*res));
- res->status = stat;
- if (stat != NFS3_OK)
- return;
-
- nfs3_map_deviceid_to_statdev (buf, deviceid);
- resok.obj_attributes = nfs3_stat_to_post_op_attr (buf);
- resok.linkmax = 256;
- resok.name_max = NFS_NAME_MAX;
- resok.no_trunc = TRUE;
- resok.chown_restricted = FALSE;
- resok.case_insensitive = FALSE;
- resok.case_preserving = TRUE;
-
- res->pathconf3res_u.resok = resok;
-}
-
-
-void
-nfs3_prep_pathconf3args (pathconf3args *args, struct nfs3_fh *fh)
-{
- memset (args, 0, sizeof (*args));
- args->object.data.data_val = (void *)fh;
-}
-
-
-int
-nfs3_verify_dircookie (struct nfs3_state *nfs3, fd_t *dirfd, cookie3 cookie,
- uint64_t cverf, nfsstat3 *stat)
-{
- int ret = -1;
-
- if ((!nfs3) || (!dirfd))
- return -1;
-
- /* Can assume that this is first read on the dir, so cookie check
- * is successful by default.
- */
- if (cookie == 0)
- return 0;
-
- gf_log (GF_NFS3, GF_LOG_TRACE, "Verifying cookie: cverf: %"PRIu64
- ", cookie: %"PRIu64, cverf, cookie);
- /* The cookie bad, no way cverf will be zero with a non-zero cookie. */
- if ((cverf == 0) && (cookie != 0)) {
- gf_log (GF_NFS3, GF_LOG_TRACE, "Bad cookie requested");
- if (stat)
- *stat = NFS3ERR_BAD_COOKIE;
- goto err;
- }
-
- /* Yes, its true, our cookie is simply the fd_t address.
- * NOTE: We used have the check for cookieverf but VMWare client sends
- * a readdirp requests even after we've told it that EOF has been
- * reached on the directory. This causes a problem because we close a
- * dir fd_t after reaching EOF. The next readdirp sent by VMWare
- * contains the address of the closed fd_t as cookieverf. Since we
- * closed that fd_t, this readdirp results in a new opendir which will
- * give an fd_t that will fail this check below.
- */
-/* if ((cverf != (uint64_t)dirfd)) {
- gf_log (GF_NFS3, GF_LOG_TRACE, "Cookieverf does not match");
- if (stat)
- *stat = NFS3ERR_BAD_COOKIE;
- goto err;
- }
-*/
- gf_log (GF_NFS3, GF_LOG_TRACE, "Cookie verified");
- if (stat)
- *stat = NFS3_OK;
- ret = 0;
-err:
- return ret;
-}
-
-
-void
-nfs3_stat_to_errstr (uint32_t xid, char *op, nfsstat3 stat, int pstat,
- char *errstr, size_t len)
-{
- if ((!op) || (!errstr))
- return;
-
- snprintf (errstr, len, "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 (THIS->ctx->log.loglevel < GF_LOG_DEBUG)
- return;
-
- nfs3_fh_to_str (fh, fhstr, sizeof (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)
-{
- char fhstr[1024];
-
- if (THIS->ctx->log.loglevel < GF_LOG_DEBUG)
- return;
- nfs3_fh_to_str (fh, fhstr, sizeof (fhstr));
- gf_log (GF_NFS3, GF_LOG_DEBUG, "XID: %x, %s: args: %s, name: %s", xid,
- op, fhstr, name);
-}
-
-
-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 (THIS->ctx->log.loglevel < GF_LOG_DEBUG)
- return;
- nfs3_fh_to_str (src, sfhstr, sizeof (sfhstr));
- nfs3_fh_to_str (dst, dfhstr, sizeof (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);
-}
-
-
-
-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";
-
- if (THIS->ctx->log.loglevel < GF_LOG_DEBUG)
- return;
- nfs3_fh_to_str (fh, fhstr, sizeof (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);
-}
-
-
-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 (THIS->ctx->log.loglevel < GF_LOG_DEBUG)
- return;
- nfs3_fh_to_str (fh, fhstr, sizeof (fhstr));
- if (type == NF3CHR)
- modestr = chr;
- else if (type == NF3BLK)
- modestr = blk;
- else if (type == NF3SOCK)
- modestr = sock;
- else
- modestr = fifo;
-
- gf_log (GF_NFS3, GF_LOG_DEBUG, "XID: %x, MKNOD: args: %s, name: %s,"
- " type: %s", xid, fhstr, name, modestr);
-}
-
-
-
-void
-nfs3_log_symlink_call (uint32_t xid, struct nfs3_fh *fh, char *name, char *tgt)
-{
- char fhstr[1024];
-
- if (THIS->ctx->log.loglevel < GF_LOG_DEBUG)
- return;
- nfs3_fh_to_str (fh, fhstr, sizeof (fhstr));
- gf_log (GF_NFS3, GF_LOG_DEBUG, "XID: %x, SYMLINK: args: %s, name: %s,"
- " target: %s", xid, fhstr, name, tgt);
-}
-
-
-void
-nfs3_log_link_call (uint32_t xid, struct nfs3_fh *fh, char *name,
- struct nfs3_fh *tgt)
-{
- char dfhstr[1024];
- char tfhstr[1024];
-
- if (THIS->ctx->log.loglevel < GF_LOG_DEBUG)
- return;
- nfs3_fh_to_str (fh, dfhstr, sizeof (dfhstr));
- nfs3_fh_to_str (tgt, tfhstr, sizeof (tfhstr));
- gf_log (GF_NFS3, GF_LOG_DEBUG, "XID: %x, LINK: args: %s, name: %s,"
- " target: %s", xid, dfhstr, name, tfhstr);
-}
-
-
-void
-nfs3_log_rw_call (uint32_t xid, char *op, struct nfs3_fh *fh, offset3 offt,
- count3 count, int stablewrite)
-{
- char fhstr[1024];
-
- if (THIS->ctx->log.loglevel < GF_LOG_DEBUG)
- return;
- nfs3_fh_to_str (fh, fhstr, sizeof (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");
-
-}
-
-
-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;
-
- case NFS3ERR_DQUOT:
- ll = GF_LOG_WARNING;
- break;
-
- default:
- ll = GF_LOG_DEBUG;
- break;
- }
-
- 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;
-
- 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;
-}
-
-
-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;
-
- default:
- ll = GF_LOG_DEBUG;
- break;
- }
-
- return ll;
-}
-
-
-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;
-
- case NFS3ERR_DQUOT:
- ll = GF_LOG_WARNING;
- break;
-
- default:
- ll = GF_LOG_DEBUG;
- break;
- }
-
- return ll;
-}
-
-
-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;
-
- case NFS3ERR_DQUOT:
- ll = GF_LOG_WARNING;
- break;
-
- default:
- ll = GF_LOG_DEBUG;
- break;
- }
-
- 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;
-
- default:
- ll = GF_LOG_DEBUG;
- break;
- }
-
- return ll;
-}
-
-
-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;
-
- case NFS3ERR_DQUOT:
- ll = GF_LOG_WARNING;
- break;
-
- default:
- ll = GF_LOG_DEBUG;
- break;
- }
-
- return ll;
-}
-
-
-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;
-
- default:
- ll = GF_LOG_DEBUG;
- break;
- }
-
- return ll;
-}
-
-
-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;
-
- default:
- ll = GF_LOG_DEBUG;
- break;
- }
-
- return ll;
-}
-
-
-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;
-
- case NFS3ERR_DQUOT:
- ll = GF_LOG_WARNING;
- break;
-
- default:
- ll = GF_LOG_DEBUG;
- break;
- }
-
- return ll;
-}
-
-
-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;
-
- 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;
-
- default:
- ll = GF_LOG_DEBUG;
- break;
- }
-
- return ll;
-}
-
-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;
-
- default:
- ll = GF_LOG_DEBUG;
- break;
- }
-
- return ll;
-}
-
-
-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;
-
- 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;
-
- default:
- ll = GF_LOG_DEBUG;
- break;
- }
-
- return ll;
-}
-
-
-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;
-
- 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;
-}
-
-
-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;
-
- default:
- ll = GF_LOG_DEBUG;
- break;
- }
-
- return ll;
-}
-
-
-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;
-
- case NFS3ERR_DQUOT:
- ll = GF_LOG_WARNING;
- break;
-
- default:
- ll = GF_LOG_DEBUG;
- break;
- }
-
- return ll;
-}
-
-
-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;
-
- 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;
-}
-
-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) {
-
- int ll = GF_LOG_DEBUG;
-
- switch (nfs_op) {
- case NFS3_GETATTR:
- ll = nfs3_getattr_loglevel (stat);
- break;
-
- case NFS3_SETATTR:
- ll = nfs3_setattr_loglevel (stat);
- break;
-
- case NFS3_LOOKUP:
- ll = nfs3_lookup_loglevel (stat);
- break;
-
- 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;
-
- case NFS3_WRITE:
- ll = nfs3_write_loglevel (stat);
- break;
-
- case NFS3_CREATE:
- ll = nfs3_create_loglevel (stat);
- break;
-
- case NFS3_MKDIR:
- ll = nfs3_mkdir_loglevel (stat);
- break;
-
- case NFS3_SYMLINK:
- ll = nfs3_symlink_loglevel (stat);
- break;
-
- case NFS3_MKNOD:
- ll = nfs3_mknod_loglevel (stat);
- break;
-
- case NFS3_REMOVE:
- ll = nfs3_remove_loglevel (stat);
- break;
-
- 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;
-
- case NFS3_READDIR:
- ll = nfs3_readdir_loglevel (stat);
- break;
-
- case NFS3_READDIRP:
- ll = nfs3_readdir_loglevel (stat);
- break;
-
- case NFS3_FSSTAT:
- ll = nfs3_fsstat_loglevel (stat);
- break;
-
- case NFS3_FSINFO:
- ll = nfs3_fsstat_loglevel (stat);
- break;
-
- case NFS3_PATHCONF:
- ll = nfs3_fsstat_loglevel (stat);
- break;
-
- case NFS3_COMMIT:
- ll = nfs3_write_loglevel (stat);
- break;
-
- default:
- ll = GF_LOG_DEBUG;
- break;
- }
-
- return ll;
-}
-
-void
-nfs3_log_common_res (uint32_t xid, int op, nfsstat3 stat, int pstat)
-{
- char errstr[1024];
- int ll = nfs3_loglevel (op, stat);
-
- if (THIS->ctx->log.loglevel < ll)
- return;
- nfs3_stat_to_errstr (xid, nfs3op_strings[op].str, stat, pstat, errstr, sizeof (errstr));
- gf_log (GF_NFS3, ll, "%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 (THIS->ctx->log.loglevel < ll)
- return;
-
- nfs3_stat_to_errstr (xid, "READLINK", stat, pstat, errstr, sizeof (errstr));
- gf_log (GF_NFS3, ll, "%s, target: %s",
- errstr, linkpath);
-
-}
-
-void
-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 (THIS->ctx->log.loglevel < ll)
- return;
- nfs3_stat_to_errstr (xid, "READ", stat, pstat, errstr, sizeof (errstr));
- if (vec)
- gf_log (GF_NFS3, ll, "%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:"
- " %d", errstr, count, is_eof);
-}
-
-
-void
-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 (THIS->ctx->log.loglevel < ll)
- return;
-
- nfs3_stat_to_errstr (xid, "WRITE", stat, pstat, errstr, sizeof (errstr));
- gf_log (GF_NFS3, ll, "%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,
- struct nfs3_fh *newfh)
-{
- char errstr[1024];
- char fhstr[1024];
- int ll = nfs3_loglevel (op, stat);
-
- if (THIS->ctx->log.loglevel < ll)
- return;
- nfs3_stat_to_errstr (xid, nfs3op_strings[op].str, stat, pstat, errstr, sizeof (errstr));
- nfs3_fh_to_str (newfh, fhstr, sizeof (fhstr));
-
- gf_log (GF_NFS3, nfs3_loglevel (op, stat), "%s, %s", errstr, fhstr);
-}
-
-
-void
-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 (THIS->ctx->log.loglevel < ll)
- return;
- nfs3_stat_to_errstr (xid, "READDIR", stat, pstat, errstr, sizeof (errstr));
- gf_log (GF_NFS3, ll, "%s, count: %"PRIu32", cverf: %"PRIu64
- ", is_eof: %d", errstr, count, cverf, is_eof);
-}
-
-
-void
-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 (THIS->ctx->log.loglevel < ll)
- return;
- nfs3_stat_to_errstr (xid, "READDIRPLUS", stat, pstat, errstr, sizeof (errstr));
- gf_log (GF_NFS3, ll, "%s, dircount: %"PRIu32", maxcount: %"
- PRIu32", cverf: %"PRIu64", is_eof: %d", errstr, dircount,
- maxcount, cverf, is_eof);
-}
-
-
-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 (THIS->ctx->log.loglevel < ll)
- return;
- nfs3_stat_to_errstr (xid, "COMMIT", stat, pstat, errstr, sizeof (errstr));
- gf_log (GF_NFS3, ll, "%s, wverf: %"PRIu64, errstr, wverf);
-}
-
-
-void
-nfs3_log_readdir_call (uint32_t xid, struct nfs3_fh *fh, count3 dircount,
- count3 maxcount)
-{
- char fhstr[1024];
-
- if (THIS->ctx->log.loglevel < GF_LOG_DEBUG)
- return;
-
- nfs3_fh_to_str (fh, fhstr, sizeof (fhstr));
-
- if (maxcount == 0)
- gf_log (GF_NFS3, GF_LOG_DEBUG, "XID: %x, READDIR: args: %s,"
- " count: %d", xid, fhstr, (uint32_t)dircount);
- else
- gf_log (GF_NFS3, GF_LOG_DEBUG, "XID: %x, READDIRPLUS: args: %s,"
- " dircount: %d, maxcount: %d", xid, fhstr,
- (uint32_t)dircount, (uint32_t)maxcount);
-}
-
-
-int
-nfs3_fh_resolve_inode_done (nfs3_call_state_t *cs, inode_t *inode)
-{
- int ret = -EFAULT;
-
- if ((!cs) || (!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");
- goto err;
- }
-
- nfs3_call_resume (cs);
-
-err:
- return ret;
-}
-
-
-int32_t
-nfs3_fh_resolve_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)
-{
- nfs3_call_state_t *cs = NULL;
- 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, (op_errno == ENOENT ? GF_LOG_TRACE : GF_LOG_ERROR),
- "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) {
- inode_lookup (linked_inode);
- inode_unref (cs->resolvedloc.inode);
- cs->resolvedloc.inode = linked_inode;
- }
-err:
- nfs3_call_resume (cs);
- return 0;
-}
-
-
-int32_t
-nfs3_fh_resolve_inode_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;
- 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, (op_errno == ENOENT ? GF_LOG_TRACE : GF_LOG_ERROR),
- "Lookup failed: %s: %s",
- cs->resolvedloc.path, strerror (op_errno));
- nfs3_call_resume (cs);
- goto err;
- }
-
- 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;
- }
-
- /* 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)
- nfs3_fh_resolve_entry_hard (cs);
- else
- nfs3_call_resume (cs);
-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.
- */
-int
-nfs3_fh_resolve_inode_hard (nfs3_call_state_t *cs)
-{
- int ret = -EFAULT;
- nfs_user_t nfu = {0, };
-
- 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;
- 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));
- goto out;
- }
-
- nfs_user_root_create (&nfu);
- ret = nfs_lookup (cs->nfsx, cs->vol, &nfu, &cs->resolvedloc,
- nfs3_fh_resolve_inode_lookup_cbk, cs);
-
-out:
- return ret;
-}
-
-
-int
-nfs3_fh_resolve_entry_hard (nfs3_call_state_t *cs)
-{
- int ret = -EFAULT;
- nfs_user_t nfu = {0, };
-
- if (!cs)
- return ret;
-
- 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);
-
- ret = nfs_entry_loc_fill (cs->vol->itable, cs->resolvefh.gfid,
- cs->resolventry, &cs->resolvedloc,
- NFS_RESOLVE_CREATE);
-
- 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))) {
- cs->lookuptype = GF_NFS3_FRESH;
- cs->resolve_ret = 0;
- nfs3_call_resume (cs);
- } else {
- cs->hardresolved = 1;
- 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",
- cs->resolvedloc.path);
- ret = nfs3_fh_resolve_inode_hard (cs);
- } else if (ret == 0) {
- cs->resolve_ret = 0;
- nfs3_call_resume (cs);
- }
-
- return ret;
-}
-
-int
-nfs3_fh_resolve_inode (nfs3_call_state_t *cs)
-{
- inode_t *inode = NULL;
- int ret = -EFAULT;
-
- if (!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);
- else
- ret = nfs3_fh_resolve_inode_done (cs, inode);
-
- if (inode)
- inode_unref (inode);
-
- return ret;
-}
-
-int
-nfs3_fh_resolve_entry (nfs3_call_state_t *cs)
-{
- int ret = -EFAULT;
-
- if (!cs)
- return ret;
-
- return nfs3_fh_resolve_entry_hard (cs);
-}
-
-
-int
-nfs3_fh_resolve_resume (nfs3_call_state_t *cs)
-{
- int ret = -EFAULT;
-
- if (!cs)
- return ret;
-
- if (cs->resolve_ret < 0)
- goto err_resume_call;
-
- if (!cs->resolventry)
- ret = nfs3_fh_resolve_inode (cs);
- else
- ret = nfs3_fh_resolve_entry (cs);
-
-err_resume_call:
- if (ret < 0) {
- cs->resolve_ret = -1;
- cs->resolve_errno = EFAULT;
- nfs3_call_resume (cs);
- ret = 0;
- }
-
- return ret;
-}
-
-
-int32_t
-nfs3_fh_resolve_root_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;
-
- cs = frame->local;
- cs->resolve_ret = op_ret;
- cs->resolve_errno = op_errno;
-
- if (op_ret == -1) {
- gf_log (GF_NFS3, GF_LOG_ERROR, "Root lookup failed: %s",
- strerror (op_errno));
- goto err;
- } else
- gf_log (GF_NFS3, GF_LOG_TRACE, "Root looked up: %s",
- cs->resolvedloc.path);
-
- nfs3_set_root_looked_up (cs->nfs3state, &cs->resolvefh);
-err:
- nfs3_fh_resolve_resume (cs);
- return 0;
-}
-
-
-int
-nfs3_fh_resolve_root (nfs3_call_state_t *cs)
-{
- int ret = -EFAULT;
- nfs_user_t nfu = {0, };
-
- if (!cs)
- return ret;
-
- if (nfs3_is_root_looked_up (cs->nfs3state, &cs->resolvefh)) {
- ret = nfs3_fh_resolve_resume (cs);
- goto out;
- }
-
- 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);
-
-out:
- return ret;
-}
-
-
-int
-nfs3_fh_resolve_and_resume (nfs3_call_state_t *cs, struct nfs3_fh *fh,
- char *entry, nfs3_resume_fn_t resum_fn)
-{
- int ret = -EFAULT;
-
- if ((!cs) || (!fh))
- return ret;
-
- cs->resume_fn = resum_fn;
- cs->resolvefh = *fh;
- cs->hashidx = 0;
-
- /* Check if the resolution is:
- * a. fh resolution
- *
- * or
- *
- * b. (fh, basename) resolution
- */
- if (entry) { /* b */
- cs->resolventry = gf_strdup (entry);
- if (!cs->resolventry)
- goto err;
- }
-
- ret = nfs3_fh_resolve_root (cs);
-err:
- return ret;
-}
diff --git a/xlators/nfs/server/src/nfs3-helpers.h b/xlators/nfs/server/src/nfs3-helpers.h
deleted file mode 100644
index eada242210d..00000000000
--- a/xlators/nfs/server/src/nfs3-helpers.h
+++ /dev/null
@@ -1,340 +0,0 @@
-/*
- Copyright (c) 2010-2011 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.
-*/
-
-#ifndef _NFS3_HELPER_H_
-#define _NFS3_HELPER_H_
-#ifndef _CONFIG_H
-#define _CONFIG_H
-#include "config.h"
-#endif
-
-
-#include "xlator.h"
-#include "nfs3.h"
-#include "nfs3-fh.h"
-#include "msg-nfs3.h"
-#include "xdr-nfs3.h"
-
-#include <sys/statvfs.h>
-
-#define GF_NFS3_FD_CACHED 0xcaced
-
-extern struct nfs3_fh
-nfs3_extract_lookup_fh (lookup3args *args);
-
-extern char *
-nfs3_extract_lookup_name (lookup3args *args);
-
-extern nfsstat3
-nfs3_errno_to_nfsstat3 (int errnum);
-
-extern nfsstat3
-nfs3_cbk_errno_status (int32_t, int32_t);
-
-extern void
-nfs3_fill_lookup3res (lookup3res *res, nfsstat3 stat, struct nfs3_fh *newfh,
- struct iatt *stbuf, struct iatt *postparent,
- uint64_t deviceid);
-
-extern post_op_attr
-nfs3_stat_to_post_op_attr (struct iatt *buf);
-
-extern struct nfs3_fh
-nfs3_extract_getattr_fh (getattr3args *args);
-
-extern void
-nfs3_fill_getattr3res (getattr3res *res, nfsstat3 stat, struct iatt *buf,
- uint64_t deviceid);
-
-extern struct nfs3_fh
-nfs3_extract_fsinfo_fh (fsinfo3args *args);
-
-extern void
-nfs3_fill_fsinfo3res (struct nfs3_state *nfs3, fsinfo3res *res,
- nfsstat3 status, struct iatt *fsroot,uint64_t deviceid);
-
-/* Functions containing _prep_ are used specifically to work around
- * the memory allocations that happen inside Sun RPC library.
- * In that library, there are numerous places where every NFS request
- * can result in really tiny malloc calls. I fear the memory fragmentation
- * that will follow. After studying the points at and the way in which malloc
- * is called in Sun RPC, I've come up with this work-around. It is based on
- * the idea that if the user/caller of the xdr_to_XXXXargs functions can provide
- * already allocated memory or provide references to memory areas on its stack
- * just for the short-term purpose of decoding the message from XDR format, we
- * can avoid the memory allocations in Sun RPC. This is based on the fact
- * that Sun RPC first checks whether structure members which require memory
- * are NULL or not and only then calls malloc. In this case, if the caller
- * provided references are non-NULL, then the if-branches containing malloc
- * in Sun RPC will be avoided.
- * PS: You're not expected to understand this unless you've spent some time
- * looking through the glibc/sunrpc sources.
- */
-extern void
-nfs3_prep_lookup3args (lookup3args *args, struct nfs3_fh *fh, char *name);
-
-extern void
-nfs3_prep_getattr3args (getattr3args *args, struct nfs3_fh *fh);
-
-extern void
-nfs3_prep_fsinfo3args (fsinfo3args *args, struct nfs3_fh *root);
-
-extern char *
-nfsstat3_strerror(int stat);
-
-extern void
-nfs3_prep_access3args (access3args *args, struct nfs3_fh *fh);
-
-extern void
-nfs3_fill_access3res (access3res *res, nfsstat3 status, int32_t accbits,
- int32_t reqaccbits);
-
-extern char *
-nfs3_fhcache_getpath (struct nfs3_state *nfs3, struct nfs3_fh *fh);
-
-extern int
-nfs3_fhcache_putpath (struct nfs3_state *nfs3, struct nfs3_fh *fh, char *path);
-
-extern void
-nfs3_prep_readdir3args (readdir3args *ra, struct nfs3_fh *fh);
-
-extern void
-nfs3_fill_readdir3res (readdir3res *res, nfsstat3 stat, struct nfs3_fh *dfh,
- uint64_t cverf, struct iatt *dirstat,
- gf_dirent_t *entries, count3 count, int is_eof,
- uint64_t deviceid);
-
-extern void
-nfs3_prep_readdirp3args (readdirp3args *ra, struct nfs3_fh *fh);
-
-extern void
-nfs3_fill_readdirp3res (readdirp3res *res, nfsstat3 stat,
- struct nfs3_fh *dirfh, uint64_t cverf,
- struct iatt *dirstat, gf_dirent_t *entries,
- count3 dircount, count3 maxcount, int is_eof,
- uint64_t deviceid);
-
-extern void
-nfs3_free_readdirp3res (readdirp3res *res);
-
-extern void
-nfs3_free_readdir3res (readdir3res *res);
-
-extern void
-nfs3_prep_fsstat3args (fsstat3args *args, struct nfs3_fh *fh);
-
-extern void
-nfs3_fill_fsstat3res (fsstat3res *res, nfsstat3 stat, struct statvfs *fsbuf,
- struct iatt *postbuf, uint64_t deviceid);
-
-extern int32_t
-nfs3_sattr3_to_setattr_valid (sattr3 *sattr, struct iatt *buf, mode_t *omode);
-extern void
-nfs3_fill_create3res (create3res *res, nfsstat3 stat, struct nfs3_fh *newfh,
- struct iatt *newbuf, struct iatt *preparent,
- struct iatt *postparent, uint64_t deviceid);
-
-extern void
-nfs3_prep_create3args (create3args *args, struct nfs3_fh *fh, char *name);
-
-extern void
-nfs3_prep_setattr3args (setattr3args *args, struct nfs3_fh *fh);
-
-extern void
-nfs3_fill_setattr3res (setattr3res *res, nfsstat3 stat, struct iatt *preop,
- struct iatt *postop, uint64_t deviceid);
-
-extern void
-nfs3_prep_mkdir3args (mkdir3args *args, struct nfs3_fh *dirfh, char *name);
-
-extern void
-nfs3_fill_mkdir3res (mkdir3res *res, nfsstat3 stat, struct nfs3_fh *fh,
- struct iatt *buf, struct iatt *preparent,
- struct iatt *postparent, uint64_t deviceid);
-
-extern void
-nfs3_prep_symlink3args (symlink3args *args, struct nfs3_fh *dirfh, char *name,
- char *target);
-
-extern void
-nfs3_fill_symlink3res (symlink3res *res, nfsstat3 stat, struct nfs3_fh *fh,
- struct iatt *buf, struct iatt *preparent,
- struct iatt *postparent, uint64_t deviceid);
-
-extern void
-nfs3_prep_readlink3args (readlink3args *args, struct nfs3_fh *fh);
-
-extern void
-nfs3_fill_readlink3res (readlink3res *res, nfsstat3 stat, char *path,
- struct iatt *buf, uint64_t deviceid);
-
-extern void
-nfs3_prep_mknod3args (mknod3args *args, struct nfs3_fh *fh, char *name);
-
-extern void
-nfs3_fill_mknod3res (mknod3res *res, nfsstat3 stat, struct nfs3_fh *fh,
- struct iatt *buf, struct iatt *preparent,
- struct iatt *postparent, uint64_t deviceid);
-
-extern void
-nfs3_fill_remove3res (remove3res *res, nfsstat3 stat, struct iatt *preparent,
- struct iatt *postparent, uint64_t deviceid);
-extern void
-nfs3_prep_remove3args (remove3args *args, struct nfs3_fh *fh, char *name);
-
-extern void
-nfs3_fill_rmdir3res (rmdir3res *res, nfsstat3 stat, struct iatt *preparent,
- struct iatt *postparent, uint64_t deviceid);
-
-extern void
-nfs3_prep_rmdir3args (rmdir3args *args, struct nfs3_fh *fh, char *name);
-
-extern void
-nfs3_fill_link3res (link3res *res, nfsstat3 stat, struct iatt *buf,
- struct iatt *preparent, struct iatt *postparent,
- uint64_t deviceid);
-
-extern void
-nfs3_prep_link3args (link3args *args, struct nfs3_fh *target,
- struct nfs3_fh * dirfh, char *name);
-
-extern void
-nfs3_prep_rename3args (rename3args *args, struct nfs3_fh *olddirfh,
- char *oldname, struct nfs3_fh *newdirfh,
- char *newname);
-
-extern void
-nfs3_fill_rename3res (rename3res *res, nfsstat3 stat, struct iatt *buf,
- struct iatt *preoldparent, struct iatt *postoldparent,
- struct iatt *prenewparent, struct iatt *postnewparent,
- uint64_t deviceid);
-
-extern void
-nfs3_prep_write3args (write3args *args, struct nfs3_fh *fh);
-
-extern void
-nfs3_fill_write3res (write3res *res, nfsstat3 stat, count3 count,
- stable_how stable, uint64_t wverf, struct iatt *prestat,
- struct iatt *poststat, uint64_t deviceid);
-
-extern void
-nfs3_prep_commit3args (commit3args *args, struct nfs3_fh *fh);
-
-extern void
-nfs3_fill_commit3res (commit3res *res, nfsstat3 stat, uint64_t wverf,
- struct iatt *prestat, struct iatt *poststat,
- uint64_t deviceid);
-
-extern void
-nfs3_fill_read3res (read3res *res, nfsstat3 stat, count3 count,
- struct iatt *poststat, int is_eof, uint64_t deviceid);
-
-extern void
-nfs3_prep_read3args (read3args *args, struct nfs3_fh *fh);
-
-extern void
-nfs3_prep_pathconf3args (pathconf3args *args, struct nfs3_fh *fh);
-
-extern void
-nfs3_fill_pathconf3res (pathconf3res *res, nfsstat3 stat, struct iatt *buf,
- uint64_t deviceid);
-
-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);
-
-extern void
-nfs3_log_readlink_res (uint32_t xid, nfsstat3 stat, int pstat, char *linkpath);
-
-extern void
-nfs3_log_read_res (uint32_t xid, nfsstat3 stat, int pstat, count3 count,
- int is_eof, struct iovec *vec, int32_t vcount);
-
-extern void
-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,
- struct nfs3_fh *newfh);
-
-extern void
-nfs3_log_readdir_res (uint32_t xid, nfsstat3 stat, int pstat, uint64_t cverf,
- count3 count, int is_eof);
-
-extern void
-nfs3_log_readdirp_res (uint32_t xid, nfsstat3 stat, int pstat, uint64_t cverf,
- count3 dircount, count3 maxcount, int is_eof);
-
-extern void
-nfs3_log_commit_res (uint32_t xid, nfsstat3 stat, int pstat, uint64_t wverf);
-
-extern void
-nfs3_log_common_call (uint32_t xid, char *op, struct nfs3_fh *fh);
-
-extern void
-nfs3_log_fh_entry_call (uint32_t xid, char *op, struct nfs3_fh *fh,
- char *name);
-
-extern void
-nfs3_log_rw_call (uint32_t xid, char *op, struct nfs3_fh *fh, offset3 offt,
- count3 count, int stablewrite);
-
-extern void
-nfs3_log_create_call (uint32_t xid, struct nfs3_fh *fh, char *name,
- createmode3 mode);
-
-extern void
-nfs3_log_symlink_call (uint32_t xid, struct nfs3_fh *fh, char *name, char *tgt);
-
-extern void
-nfs3_log_mknod_call (uint32_t xid, struct nfs3_fh *fh, char *name, int type);
-
-extern void
-nfs3_log_rename_call (uint32_t xid, struct nfs3_fh *src, char *sname,
- struct nfs3_fh *dst, char *dname);
-
-extern void
-nfs3_log_link_call (uint32_t xid, struct nfs3_fh *fh, char *name,
- struct nfs3_fh *tgt);
-
-extern void
-nfs3_log_readdir_call (uint32_t xid, struct nfs3_fh *fh, count3 dircount,
- count3 maxcount);
-
-extern int
-nfs3_fh_resolve_entry_hard (nfs3_call_state_t *cs);
-
-extern int
-nfs3_fh_resolve_inode (nfs3_call_state_t *cs);
-
-extern int
-nfs3_fh_resolve_entry (nfs3_call_state_t *cs);
-
-extern int
-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_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);
-
-void
-nfs3_map_deviceid_to_statdev (struct iatt *ia, uint64_t deviceid);
-
-#endif
diff --git a/xlators/nfs/server/src/nfs3.c b/xlators/nfs/server/src/nfs3.c
deleted file mode 100644
index 2df775abb5c..00000000000
--- a/xlators/nfs/server/src/nfs3.c
+++ /dev/null
@@ -1,5633 +0,0 @@
-/*
- Copyright (c) 2010-2011 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.
-*/
-
-#ifndef _CONFIG_H
-#define _CONFIG_H
-#include "config.h"
-#endif
-
-#include "rpcsvc.h"
-#include "dict.h"
-#include "xlator.h"
-#include "mount3.h"
-#include "xdr-nfs3.h"
-#include "msg-nfs3.h"
-#include "iobuf.h"
-#include "nfs3.h"
-#include "mem-pool.h"
-#include "logging.h"
-#include "nfs-common.h"
-#include "nfs-fops.h"
-#include "nfs-inodes.h"
-#include "nfs-generics.h"
-#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>
-#include <sys/statvfs.h>
-#include <time.h>
-
-#define nfs3_validate_strlen_or_goto(str, len, label, status, retval) \
- do { \
- if ((str)) { \
- if (strlen ((str)) > (len)) { \
- gf_log (GF_NFS3, GF_LOG_ERROR, "strlen "\
- "too long"); \
- status = NFS3ERR_NAMETOOLONG; \
- retval = -ENAMETOOLONG; \
- goto label; \
- } \
- } \
- } while (0); \
-
-#define nfs3_validate_nfs3_state(request, state, status, label, retval) \
- do { \
- state = rpcsvc_request_program_private (request); \
- if (!state) { \
- gf_log (GF_NFS3, GF_LOG_ERROR, "NFSv3 state " \
- "missing from RPC request"); \
- status = NFS3ERR_SERVERFAULT; \
- ret = -EFAULT; \
- goto label; \
- } \
- } while (0); \
-
-
-struct nfs3_export *
-__nfs3_get_export_by_index (struct nfs3_state *nfs3, uuid_t exportid)
-{
- struct nfs3_export *exp = NULL;
- int index = 0;
- int searchindex = 0;
-
- searchindex = nfs3_fh_exportid_to_index (exportid);
- list_for_each_entry (exp, &nfs3->exports, explist) {
- if (searchindex == index)
- goto found;
-
- ++index;
- }
-
- exp = NULL;
- gf_log (GF_NFS, GF_LOG_ERROR, "searchindex=%d not found", searchindex);
-found:
- return exp;
-}
-
-
-struct nfs3_export *
-__nfs3_get_export_by_volumeid (struct nfs3_state *nfs3, uuid_t exportid)
-{
- struct nfs3_export *exp = NULL;
-
- list_for_each_entry (exp, &nfs3->exports, explist) {
- if (!uuid_compare (exportid, exp->volumeid))
- goto found;
- }
-
- exp = NULL;
-found:
- return exp;
-}
-
-
-struct nfs3_export *
-__nfs3_get_export_by_exportid (struct nfs3_state *nfs3, uuid_t exportid)
-{
- struct nfs3_export *exp = NULL;
-
- if (!nfs3)
- return exp;
-
- if (gf_nfs_dvm_off (nfs_state(nfs3->nfsx)))
- exp = __nfs3_get_export_by_index (nfs3, exportid);
- else
- exp = __nfs3_get_export_by_volumeid (nfs3, exportid);
-
- return exp;
-}
-
-
-int
-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);
-
- exp = __nfs3_get_export_by_exportid (nfs3, exportid);
-
- if (!exp) {
- gf_log (GF_NFS3, GF_LOG_ERROR, "Failed to get export by ID");
- goto err;
- }
-
- ret = exp->access;
-
-err:
- return ret;
-}
-
-#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");\
- status = NFS3ERR_ROFS; \
- goto label; \
- } \
- } while (0) \
-
-
-
-xlator_t *
-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);
-
- exp = __nfs3_get_export_by_exportid (nfs3, fh->exportid);
- if (!exp)
- goto out;
-
- vol = exp->subvol;
-out:
- return vol;
-}
-
-
-int
-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);
-
- exp = __nfs3_get_export_by_exportid (nfs3, rootfh->exportid);
- if (!exp)
- goto out;
-
- ret = exp->rootlookedup;
-out:
- return ret;
-}
-
-
-int
-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);
-
- exp = __nfs3_get_export_by_exportid (nfs3, rootfh->exportid);
- if (!exp)
- goto out;
-
- exp->rootlookedup = 1;
-out:
- return ret;
-}
-
-
-#define nfs3_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_OCCASIONALLY (nfs3state->occ_logger, \
- GF_NFS3, GF_LOG_ERROR, "Failed to map " \
- "FH to vol: client=%s, exportid=%s, " \
- "gfid=%s", trans->peerinfo.identifier, \
- exportid, gfid); \
- GF_LOG_OCCASIONALLY (nfs3state->occ_logger, \
- GF_NFS3, GF_LOG_ERROR, "Stale nfs " \
- "client %s must be trying to connect to"\
- " a deleted volume, please unmount it.",\
- trans->peerinfo.identifier); \
- 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); \
- } \
- } while (0); \
-
-
-#define nfs3_validate_gluster_fh(handle, status, errlabel) \
- do { \
- if (!nfs3_fh_validate (handle)) { \
- gf_log (GF_NFS3, GF_LOG_ERROR, "Bad Handle"); \
- status = NFS3ERR_BADHANDLE; \
- goto errlabel; \
- } \
- } while (0) \
-
-#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); \
- snprintf (buf, sizeof (buf), "(%s) %s : %s", \
- trans->peerinfo.identifier, \
- xlatorp ? xlatorp->name : "ERR", \
- gfid ); \
- gf_log (GF_NFS3, GF_LOG_ERROR, "%s: %s", \
- strerror(cst->resolve_errno), buf); \
- nfstat = nfs3_errno_to_nfsstat3 (cst->resolve_errno);\
- goto erlabl; \
- } \
- } while (0) \
-
-#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); \
- snprintf (buf, sizeof (buf), "(%s) %s : %s", \
- trans->peerinfo.identifier, \
- xlatorp ? xlatorp->name : "ERR", \
- gfid); \
- gf_log (GF_NFS3, GF_LOG_ERROR, "%s: %s", \
- strerror(cst->resolve_errno), buf); \
- nfstat = nfs3_errno_to_nfsstat3 (cs->resolve_errno);\
- goto erlabl; \
- } \
- } while (0) \
-
-
-int
-__nfs3_get_volume_id (struct nfs3_state *nfs3, xlator_t *xl,
- uuid_t volumeid)
-{
- int ret = -1;
- struct nfs3_export *exp = NULL;
-
- GF_VALIDATE_OR_GOTO (GF_NFS3, nfs3, out);
- GF_VALIDATE_OR_GOTO (GF_NFS3, xl, out);
-
- list_for_each_entry (exp, &nfs3->exports, explist) {
- if (exp->subvol == xl) {
- uuid_copy (volumeid, exp->volumeid);
- ret = 0;
- goto out;
- }
- }
-
-out:
- return ret;
-}
-
-
-#define nfs3_funge_solaris_zerolen_fh(nfs3st, fhd, enam, nfsst, erl) \
- do { \
- xlator_t *fungexl = NULL; \
- uuid_t zero = {0, }; \
- fungexl =nfs_mntpath_to_xlator ((nfs3st)->exportslist,enam);\
- if (!fungexl) { \
- (nfsst) = NFS3ERR_NOENT; \
- goto erl; \
- } \
- \
- uuid_copy ((fhd)->gfid, zero); \
- (fhd)->gfid[15] = 1; \
- (enam) = NULL; \
- if ((gf_nfs_dvm_off (nfs_state (nfs3st->nfsx)))) \
- (fhd)->exportid[15] = nfs_xlator_to_xlid ((nfs3st)->exportslist, fungexl); \
- else { \
- if(__nfs3_get_volume_id ((nfs3st), fungexl, (fhd)->exportid) < 0) { \
- (nfsst) = NFS3ERR_STALE; \
- goto erl; \
- } \
- } \
- } while (0) \
-
-
-#define nfs3_volume_started_check(nf3stt, vlm, rtval, erlbl) \
- do { \
- if ((!nfs_subvolume_started (nfs_state (nf3stt->nfsx), vlm))){\
- gf_log (GF_NFS3, GF_LOG_ERROR, "Volume is disabled: %s",\
- vlm->name); \
- rtval = RPCSVC_ACTOR_IGNORE; \
- goto erlbl; \
- } \
- } while (0) \
-
-
-int
-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);
-
- exp = __nfs3_get_export_by_exportid (nfs3, exportid);
- if (!exp)
- goto err;
-
- ret = exp->trusted_sync;
-err:
- return ret;
-}
-
-
-int
-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);
-
- exp = __nfs3_get_export_by_exportid (nfs3, exportid);
- if (!exp)
- goto err;
-
- ret = exp->trusted_write;
-err:
- return ret;
-}
-
-int
-nfs3_solaris_zerolen_fh (struct nfs3_fh *fh, int fhlen)
-{
- if (!fh)
- return 0;
-
- if (nfs3_fh_validate (fh))
- return 0;
-
- if (fhlen == 0)
- return 1;
-
- return 0;
-}
-
-
-/* Function pointer that represents the generic prototypes of functions used
- * to serialize NFS3 message structures into the XDR format.
- * For usage, see the nfs3svc_XXX_cbk functions.
- */
-typedef ssize_t (*nfs3_serializer) (struct iovec outmsg, void *args);
-
-nfs3_call_state_t *
-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);
-
- cs = (nfs3_call_state_t *) mem_get (s->localpool);
- if (!cs) {
- gf_log (GF_NFS3, GF_LOG_ERROR, "out of memory");
- 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->vol = v;
- cs->nfsx = s->nfsx;
- cs->nfs3state = s;
-err:
- return cs;
-}
-
-void
-nfs3_call_state_wipe (nfs3_call_state_t *cs)
-{
- if (!cs)
- return;
-
- 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);
-
- GF_FREE (cs->pathname);
-
- if (!list_empty (&cs->entries.list))
- gf_dirent_free (&cs->entries);
-
- nfs_loc_wipe (&cs->oploc);
- 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);
- /* Already refd by fd_lookup, so no need to ref again. */
-}
-
-
-#define nfs3_handle_call_state_init(nfs3state, calls, rq, vl ,opstat, errlabel)\
- do { \
- calls = nfs3_call_state_init ((nfs3state), (rq), (vl)); \
- if (!calls) { \
- gf_log (GF_NFS3, GF_LOG_ERROR, "Failed to " \
- "init call state"); \
- opstat = NFS3ERR_SERVERFAULT; \
- goto errlabel; \
- } \
- } while (0) \
-
-
-
-struct iobuf *
-nfs3_serialize_reply (rpcsvc_request_t *req, void *arg, nfs3_serializer sfunc,
- struct iovec *outmsg)
-{
- struct nfs3_state *nfs3 = NULL;
- struct iobuf *iob = NULL;
- ssize_t retlen = -1;
-
- nfs3 = (struct nfs3_state *)rpcsvc_request_program_private (req);
- if (!nfs3) {
- gf_log (GF_NFS3, GF_LOG_ERROR, "NFSv3 state not found in RPC"
- " request");
- goto ret;
- }
-
- /* 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");
- 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) {
- gf_log (GF_NFS3, GF_LOG_ERROR, "Failed to encode message");
- goto ret;
- }
-
- outmsg->iov_len = retlen;
-ret:
- if (retlen == -1) {
- iobuf_unref (iob);
- iob = NULL;
- }
-
- return iob;
-}
-
-
-
-/* Generic reply function for NFSv3 specific replies. */
-int
-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;
-
- iob = nfs3_serialize_reply (req, arg, sfunc, &outmsg);
- if (!iob) {
- gf_log (GF_NFS3, GF_LOG_ERROR, "Failed to serialize reply");
- goto ret;
- }
-
- iobref = iobref_new ();
- if (!iobref) {
- gf_log (GF_NFS3, GF_LOG_ERROR, "failed on iobref_new()");
- goto ret;
- }
-
- ret = iobref_add (iobref, iob);
- if (ret) {
- gf_log (GF_NFS3, GF_LOG_ERROR, "Failed to add iob to iobref");
- goto ret;
- }
-
- /* Then, submit the message for transmission. */
- ret = rpcsvc_submit_message (req, &outmsg, 1, NULL, 0, iobref);
- if (ret == -1) {
- gf_log (GF_NFS3, GF_LOG_ERROR, "Reply submission failed");
- goto ret;
- }
-
- ret = 0;
-ret:
- /* 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.
- */
- if (NULL != iob)
- iobuf_unref (iob);
- if (NULL != iobref)
- iobref_unref (iobref);
- return ret;
-}
-
-
-int
-nfs3svc_submit_vector_reply (rpcsvc_request_t *req, void *arg,
- nfs3_serializer sfunc, struct iovec *payload,
- int vcount, struct iobref *iobref)
-{
- struct iovec outmsg = {0, };
- struct iobuf *iob = NULL;
- int ret = -1;
- int new_iobref = 0;
-
- if (!req)
- return -1;
-
- 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;
- }
-
- ret = iobref_add (iobref, iob);
- if (ret) {
- gf_log (GF_NFS3, GF_LOG_ERROR, "Failed to add iob to iobref");
- goto ret;
- }
-
- /* Then, submit the message for transmission. */
- ret = rpcsvc_submit_message (req, &outmsg, 1, payload, vcount, iobref);
- if (ret == -1) {
- gf_log (GF_NFS3, GF_LOG_ERROR, "Reply submission failed");
- goto ret;
- }
-
- ret = 0;
-ret:
- /* 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.
- */
- if (NULL != iob)
- iobuf_unref (iob);
- if (new_iobref)
- iobref_unref (iobref);
- return ret;
-}
-
-uint64_t
-nfs3_request_xlator_deviceid (rpcsvc_request_t *rq)
-{
- struct nfs3_state *nfs3 = NULL;
- xlator_t *xl = NULL;
- uint64_t devid = 0;
- uuid_t volumeid = {0, };
-
- if (!rq)
- return 0;
-
- xl = rpcsvc_request_private (rq);
- nfs3 = 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 {
- __nfs3_get_volume_id (nfs3, xl, volumeid);
- memcpy (&devid, &volumeid[8], sizeof (devid));
- }
-
- return devid;
-}
-
-
-int
-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);
- return RPCSVC_ACTOR_SUCCESS;
-}
-
-
-int
-nfs3_getattr_reply (rpcsvc_request_t *req, nfsstat3 status, struct iatt *buf)
-{
- getattr3res res;
- uint64_t deviceid = 0;
-
- deviceid = nfs3_request_xlator_deviceid (req);
- nfs3_fill_getattr3res (&res, status, buf, deviceid);
- nfs3svc_submit_reply (req, &res,
- (nfs3_serializer)xdr_serialize_getattr3res);
-
- return 0;
-}
-
-
-int32_t
-nfs3svc_getattr_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)
-{
- nfsstat3 status = NFS3_OK;
- nfs3_call_state_t *cs = NULL;
-
- cs = frame->local;
-
- /*
- * Somewhat counter-intuitively, we don't need to look for sh-failed
- * here. Failing this getattr will generate a new lookup from the
- * client, and nfs_fop_lookup_cbk will detect any self-heal failures.
- */
-
- 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_cbk_errno_status (op_ret, op_errno);
- }
- else {
- nfs_fix_generation(this,inode);
- }
-
- nfs3_log_common_res (rpcsvc_request_xid (cs->req), NFS3_GETATTR,
- status, op_errno);
-
- nfs3_getattr_reply (cs->req, status, buf);
- nfs3_call_state_wipe (cs);
-
- return 0;
-}
-
-
-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)
-{
- 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));
- status = nfs3_cbk_errno_status (op_ret, op_errno);
- }
-
- nfs3_log_common_res (rpcsvc_request_xid (cs->req), NFS3_GETATTR,
- status, op_errno);
-
- nfs3_getattr_reply (cs->req, status, buf);
- nfs3_call_state_wipe (cs);
-
- return 0;
-}
-
-
-int
-nfs3_getattr_resume (void *carg)
-{
- nfsstat3 stat = NFS3ERR_SERVERFAULT;
- int ret = -EFAULT;
- nfs_user_t nfu = {0, };
- nfs3_call_state_t *cs = NULL;
- uint64_t raw_ctx = 0;
- struct nfs_inode_ctx *ictx = NULL;
- struct nfs_state *priv = NULL;
-
- if (!carg)
- return ret;
-
- cs = (nfs3_call_state_t *)carg;
- nfs3_check_fh_resolve_status (cs, stat, nfs3err);
- nfs_request_user_init (&nfu, cs->req);
- /* If inode which is to be getattr'd is the root, we need to do a
- * lookup instead because after a server reboot, it is not necessary
- * 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))
- 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;
- }
-
- /*
- * If brick state changed, we need to force a proper lookup cycle (as
- * would happen in native protocol) to do self-heal checks. We detect
- * this by comparing the generation number for the last successful
- * creation/lookup on the inode to the current number, so inodes that
- * haven't been validated since the state change are affected.
- */
- if (inode_ctx_get(cs->resolvedloc.inode,cs->nfsx,&raw_ctx) == 0) {
- ictx = (struct nfs_inode_ctx *)raw_ctx;
- priv = cs->nfsx->private;
- if (ictx->generation != priv->generation) {
- ret = nfs_lookup (cs->nfsx, cs->vol, &nfu,
- &cs->resolvedloc,
- nfs3svc_getattr_lookup_cbk, cs);
- goto check_err;
- }
- }
-
- ret = nfs_stat (cs->nfsx, cs->vol, &nfu, &cs->resolvedloc,
- nfs3svc_getattr_stat_cbk, cs);
-
-check_err:
- if (ret < 0) {
- gf_log (GF_NFS3, GF_LOG_ERROR, "Stat fop failed: %s: %s",
- cs->oploc.path, strerror (-ret));
- stat = nfs3_errno_to_nfsstat3 (-ret);
- }
-
-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_call_state_wipe (cs);
- ret = 0;
- }
-
- return ret;
-}
-
-
-int
-nfs3_getattr (rpcsvc_request_t *req, struct nfs3_fh *fh)
-{
- xlator_t *vol = NULL;
- nfsstat3 stat = NFS3ERR_SERVERFAULT;
- int ret = -EFAULT;
- 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);
-
- nfs3_log_common_call (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);
- nfs3_volume_started_check (nfs3, vol, ret, out);
- nfs3_handle_call_state_init (nfs3, cstate, req, vol, stat, nfs3err);
-
- ret = nfs3_fh_resolve_and_resume (cstate, fh, NULL,nfs3_getattr_resume);
- if (ret < 0)
- stat = nfs3_errno_to_nfsstat3 (-ret);
-
-nfs3err:
- if (ret < 0) {
- nfs3_log_common_res (rpcsvc_request_xid (req), NFS3_GETATTR,
- stat, -ret);
- nfs3_getattr_reply (req, stat, NULL);
- ret = 0;
- nfs3_call_state_wipe (cstate);
- }
-out:
- return ret;
-}
-
-
-int
-nfs3svc_getattr (rpcsvc_request_t *req)
-{
- struct nfs3_fh fh = {{0}, };
- getattr3args args;
- int ret = RPCSVC_ACTOR_ERROR;
-
- if (!req)
- return ret;
-
- nfs3_prep_getattr3args (&args, &fh);
- if (xdr_to_getattr3args (req->msg[0], &args) <= 0) {
- gf_log (GF_NFS3, GF_LOG_ERROR, "Error decoding args");
- 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);
- ret = RPCSVC_ACTOR_ERROR;
- }
-
-rpcerr:
- return ret;
-}
-
-
-int
-nfs3_setattr_reply (rpcsvc_request_t *req, nfsstat3 stat, struct iatt *preop,
- struct iatt *postop)
-{
- setattr3res res = {0, };
- uint64_t deviceid = 0;
-
- deviceid = nfs3_request_xlator_deviceid (req);
- nfs3_fill_setattr3res (&res, stat, preop, postop, deviceid);
- nfs3svc_submit_reply (req, (void *)&res,
- (nfs3_serializer) xdr_serialize_setattr3res);
- return 0;
-}
-
-
-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)
-{
- nfsstat3 stat = NFS3ERR_SERVERFAULT;
- struct iatt *prestat = NULL;
- 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_cbk_errno_status (op_ret, op_errno);
- goto nfs3err;
- }
-
- /* If the first stat was got from the guarded setattr callback, or
- * from an earlier setattr call then we'll need to use that stat
- * instead of the preop returned here.
- */
- if (cs->preparent.ia_ino != 0)
- prestat = &cs->preparent;
- else
- prestat = prebuf;
-
- stat = NFS3_OK;
-nfs3err:
- nfs3_log_common_res (rpcsvc_request_xid (cs->req), NFS3_SETATTR, stat,
- op_errno);
- nfs3_setattr_reply (cs->req, stat, prestat, postbuf);
- nfs3_call_state_wipe (cs);
-
- return 0;
-}
-
-
-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)
-{
- nfsstat3 stat = NFS3ERR_SERVERFAULT;
- int ret = -1;
- struct iatt *prebuf = NULL;
- nfs_user_t nfu = {0, };
- 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_cbk_errno_status (op_ret, 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.
- */
- 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.
- */
- if ((gf_attr_size_set (cs->setattr_valid)) &&
- (!IA_ISDIR (postop->ia_type)) &&
- (preop->ia_size != cs->stbuf.ia_size)) {
- nfs_request_user_init (&nfu, cs->req);
- ret = nfs_truncate (cs->nfsx, cs->vol, &nfu, &cs->resolvedloc,
- cs->stbuf.ia_size, nfs3svc_truncate_cbk,cs);
-
- if (ret < 0)
- stat = nfs3_errno_to_nfsstat3 (-ret);
- } else {
- ret = -1; /* Force a reply in the branch below. */
- stat = NFS3_OK;
- }
-
-nfs3err:
- if (ret < 0) {
- nfs3_log_common_res (rpcsvc_request_xid (cs->req),
- NFS3_SETATTR, stat, op_errno);
- nfs3_setattr_reply (cs->req, stat, prebuf, postop);
- nfs3_call_state_wipe (cs);
- }
-
- return 0;
-}
-
-
-
-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)
-{
-
- int ret = -EFAULT;
- nfsstat3 stat = NFS3ERR_SERVERFAULT;
- nfs_user_t nfu = {0, };
- 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_cbk_errno_status (op_ret, op_errno);
- goto nfs3err;
- }
-
- if (buf->ia_ctime != cs->timestamp.seconds) {
- gf_log (GF_NFS3, GF_LOG_ERROR, "Timestamps not in sync");
- stat = NFS3ERR_NOT_SYNC;
- goto nfs3err;
- }
-
- /* Not a clean way but no motivation to add a new member to local. */
- cs->preparent = *buf;
- 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 (ret < 0)
- stat = nfs3_errno_to_nfsstat3 (-ret);
-
-nfs3err:
- if (ret < 0) {
- nfs3_log_common_res (rpcsvc_request_xid (cs->req),
- NFS3_SETATTR, stat, op_errno);
- nfs3_setattr_reply (cs->req, stat, NULL, NULL);
- nfs3_call_state_wipe (cs);
- }
-
- return 0;
-}
-
-
-int
-nfs3_setattr_resume (void *carg)
-{
- nfsstat3 stat = NFS3ERR_SERVERFAULT;
- int ret = -EFAULT;
- nfs_user_t nfu = {0, };
- nfs3_call_state_t *cs = NULL;
-
- if (!carg)
- return ret;
-
- 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 (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_setattr_reply (cs->req, stat, NULL, NULL);
- nfs3_call_state_wipe (cs);
- }
-
- return ret;
-}
-
-
-int
-nfs3_setattr (rpcsvc_request_t *req, struct nfs3_fh *fh, sattr3 *sattr,
- sattrguard3 *guard)
-{
- xlator_t *vol = NULL;
- nfsstat3 stat = NFS3ERR_SERVERFAULT;
- int ret = -EFAULT;
- 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);
-
- nfs3_log_common_call (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);
- nfs3_volume_started_check (nfs3, vol, ret, out);
- nfs3_check_rw_volaccess (nfs3, fh->exportid, stat, nfs3err);
- nfs3_handle_call_state_init (nfs3, cs, req, vol, stat, nfs3err);
-
- cs->setattr_valid = nfs3_sattr3_to_setattr_valid (sattr, &cs->stbuf,
- NULL);
- if (guard->check) {
- gf_log (GF_NFS3, GF_LOG_TRACE, "Guard check required");
- cs->timestamp = guard->sattrguard3_u.obj_ctime;
- cs->sattrguardcheck = 1;
- } else {
- gf_log (GF_NFS3, GF_LOG_TRACE, "Guard check not required");
- cs->sattrguardcheck = 0;
- }
-
- 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;
- }
-
- ret = nfs3_fh_resolve_and_resume (cs, fh, NULL, nfs3_setattr_resume);
- if (ret < 0)
- stat = nfs3_errno_to_nfsstat3 (-ret);
-
-nfs3err:
- if (ret < 0) {
- nfs3_log_common_res (rpcsvc_request_xid (req), NFS3_SETATTR,
- stat, -ret);
- nfs3_setattr_reply (req, stat, NULL, NULL);
- nfs3_call_state_wipe (cs);
- /* Ret must be 0 after this so that the caller does not
- * also send an RPC reply.
- */
- ret = 0;
- }
-out:
- return ret;
-}
-
-
-
-int
-nfs3svc_setattr (rpcsvc_request_t *req)
-{
- struct nfs3_fh fh = {{0}, };
- setattr3args args;
- int ret = RPCSVC_ACTOR_ERROR;
-
- GF_VALIDATE_OR_GOTO (GF_NFS3, req, rpcerr);
-
- nfs3_prep_setattr3args (&args, &fh);
- if (xdr_to_setattr3args (req->msg[0], &args) <= 0) {
- gf_log (GF_NFS3, GF_LOG_ERROR, "Error decoding args");
- 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);
- ret = RPCSVC_ACTOR_ERROR;
- }
-
-rpcerr:
- return ret;
-
-}
-
-
-int
-nfs3_lookup_reply (rpcsvc_request_t *req, nfsstat3 stat, struct nfs3_fh *newfh,
- struct iatt *stbuf, struct iatt *postparent)
-{
- lookup3res res = {0, };
- uint64_t deviceid = 0;
-
- deviceid = nfs3_request_xlator_deviceid (req);
- nfs3_fill_lookup3res (&res, stat, newfh, stbuf, postparent, deviceid);
- return nfs3svc_submit_reply (req, &res,
- (nfs3_serializer)xdr_serialize_lookup3res);
-}
-
-int
-nfs3_lookup_resume (void *carg);
-
-
-int
-nfs3_fresh_lookup (nfs3_call_state_t *cs)
-{
- int ret = -EFAULT;
- char *oldresolventry = NULL;
-
- GF_VALIDATE_OR_GOTO (GF_NFS3, cs, err);
- gf_log (GF_NFS3, GF_LOG_DEBUG, "inode needs fresh lookup");
- inode_unlink (cs->resolvedloc.inode, cs->resolvedloc.parent,
- cs->resolventry);
- nfs_loc_wipe (&cs->resolvedloc);
-
- /* Store pointer to currently allocated resolventry because it gets over
- * written in fh_resolve_and_resume.
- */
- oldresolventry = cs->resolventry;
- cs->lookuptype = GF_NFS3_FRESH;
- ret = nfs3_fh_resolve_and_resume (cs, &cs->resolvefh, cs->resolventry,
- nfs3_lookup_resume);
- /* Allocated in the previous call to fh_resolve_and_resume using the
- * same call_state.
- */
- GF_FREE (oldresolventry);
-err:
- return ret;
-}
-
-int
-nfs3svc_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)
-{
- struct nfs3_fh newfh = {{0}, };
- nfsstat3 status = NFS3_OK;
- nfs3_call_state_t *cs = NULL;
- inode_t *oldinode = NULL;
-
- 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_cbk_errno_status (op_ret, 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);
-xmit_res:
- /* Only send fresh lookup if it was a revalidate that failed. */
- if ((op_ret == -1) && (nfs3_is_revalidate_lookup (cs))) {
- op_ret = nfs3_fresh_lookup (cs);
- goto out;
- }
-
- nfs3_log_newfh_res (rpcsvc_request_xid (cs->req), NFS3_LOOKUP, status,
- op_errno, &newfh);
- nfs3_lookup_reply (cs->req, status, &newfh, buf, postparent);
- nfs3_call_state_wipe (cs);
-out:
- if (oldinode) {
- inode_lookup (oldinode);
- inode_unref (oldinode);
- }
- return 0;
-}
-
-
-int
-nfs3svc_lookup_parentdir_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)
-{
- struct nfs3_fh newfh = {{0}, };
- nfsstat3 status = NFS3_OK;
- nfs3_call_state_t *cs = NULL;
- uuid_t volumeid = {0, };
- 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));
- status = nfs3_cbk_errno_status (op_ret, op_errno);
- goto xmit_res;
- }
-
- nfs3 = cs->nfs3state;
- /* If the buf inode shows that this is a root dir's buf, then the file
- * handle needs to be specially crafted, in all other cases, we'll just
- * create the handle normally using the buffer of the parent dir.
- */
- if (buf->ia_ino != 1) {
- nfs3_fh_build_parent_fh (&cs->fh, buf, &newfh);
- goto xmit_res;
- }
-
- if (gf_nfs_dvm_off (nfs_state (nfs3->nfsx)))
- newfh = nfs3_fh_build_indexed_root_fh (nfs3->exportslist,
- cs->vol);
- else {
- __nfs3_get_volume_id (nfs3, cs->vol, volumeid);
- newfh = nfs3_fh_build_uuid_root_fh (volumeid);
- }
-
-xmit_res:
- nfs3_log_newfh_res (rpcsvc_request_xid (cs->req), NFS3_LOOKUP, status,
- op_errno, &newfh);
- nfs3_lookup_reply (cs->req, status, &newfh, buf, postparent);
- nfs3_call_state_wipe (cs);
-
- return 0;
-}
-
-
-
-int
-nfs3_lookup_parentdir_resume (void *carg)
-{
- nfsstat3 stat = NFS3ERR_SERVERFAULT;
- int ret = -EFAULT;
- nfs_user_t nfu = {0, };
- nfs3_call_state_t *cs = NULL;
- inode_t *parent = NULL;
-
- if (!carg) {
- gf_log (GF_NFS3, GF_LOG_ERROR, "Invalid argument,"
- " carg value NULL");
- return EINVAL;
- }
-
- cs = (nfs3_call_state_t *)carg;
- nfs3_check_fh_resolve_status (cs, stat, nfs3err);
-
- /* At this point now, the loc in cs is for the directory file handle
- * sent by the client. This loc needs to be transformed into a loc that
- * represents the parent dir of cs->resolvedloc.inode.
- *
- * EXCEPT in the case where the .. is a parent of the root directory.
- * In this case we'll be returning the file handle and attributes of the
- * root itself.
- */
- nfs_request_user_init (&nfu, cs->req);
-
- /* Save the file handle from the LOOKUP request. We'll use this to
- * build the file handle of the parent directory in case the parent is
- * not root dir.
- */
- cs->fh = cs->resolvefh;
-
- /* If fh is that of the root, the resolvedloc will already contain
- * the loc for root. After that, we'll send lookup for the root dir
- * itself since we cannot send the lookup on the parent of root.
- *
- * For all other cases, we'll send the lookup on the parent of the
- * given directory file handle.
- */
- 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);
-
- if (ret < 0) {
- gf_log (GF_NFS3, GF_LOG_ERROR, "nfs_inode_loc_fill"
- " error");
- goto errtostat;
- }
- }
-
- ret = nfs_lookup (cs->nfsx, cs->vol, &nfu, &cs->resolvedloc,
- nfs3svc_lookup_parentdir_cbk, cs);
-errtostat:
- if (ret < 0)
- stat = nfs3_errno_to_nfsstat3 (-ret);
-
-nfs3err:
- if (ret < 0) {
- nfs3_log_common_res (rpcsvc_request_xid (cs->req), NFS3_LOOKUP,
- stat, -ret);
- nfs3_lookup_reply (cs->req, stat, NULL, NULL, NULL);
- nfs3_call_state_wipe (cs);
- }
-
- if (parent)
- inode_unref (parent);
-
- return ret;
-}
-
-
-int
-nfs3_lookup_resume (void *carg)
-{
- nfsstat3 stat = NFS3ERR_SERVERFAULT;
- int ret = -EFAULT;
- nfs_user_t nfu = {0, };
- nfs3_call_state_t *cs = NULL;
- struct nfs3_fh newfh = {{0},};
-
- if (!carg) {
- gf_log (GF_NFS3, GF_LOG_ERROR, "Invalid argument,"
- " carg value NULL");
- return EINVAL;
- }
-
- 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);
- ret = nfs_lookup (cs->nfsx, cs->vol, &nfu, &cs->resolvedloc,
- nfs3svc_lookup_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_LOOKUP,
- stat, -ret);
- nfs3_lookup_reply (cs->req, stat, &newfh, &cs->stbuf,
- &cs->postparent);
- nfs3_call_state_wipe (cs);
- }
-
- return ret;
-}
-
-
-int
-nfs3_lookup (rpcsvc_request_t *req, struct nfs3_fh *fh, int fhlen, char *name)
-{
- xlator_t *vol = NULL;
- nfsstat3 stat = NFS3ERR_SERVERFAULT;
- int ret = -EFAULT;
- 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);
-
- nfs3_log_fh_entry_call (rpcsvc_request_xid (req), "LOOKUP", fh,
- name);
- nfs3_validate_nfs3_state (req, nfs3, stat, nfs3err, ret);
- if (nfs3_solaris_zerolen_fh (fh, fhlen))
- nfs3_funge_solaris_zerolen_fh (nfs3, fh, name, stat, nfs3err);
- else
- nfs3_validate_gluster_fh (fh, stat, nfs3err);
- nfs3_validate_strlen_or_goto (name, NFS_NAME_MAX, nfs3err, stat, ret);
- nfs3_map_fh_to_volume (nfs3, fh, req, vol, stat, nfs3err);
- nfs3_volume_started_check (nfs3, vol, ret, out);
- 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 (ret < 0) {
- gf_log (GF_NFS, GF_LOG_ERROR, "failed to start hard reslove");
- stat = nfs3_errno_to_nfsstat3 (-ret);
- }
-
-nfs3err:
- if (ret < 0) {
- nfs3_log_common_res (rpcsvc_request_xid (req), NFS3_LOOKUP,
- stat,
- -ret);
- nfs3_lookup_reply (req, stat, NULL, NULL, NULL);
- nfs3_call_state_wipe (cs);
- /* Ret must be 0 after this so that the caller does not
- * also send an RPC reply.
- */
- ret = 0;
- }
-out:
- return ret;
-}
-
-
-int
-nfs3svc_lookup (rpcsvc_request_t *req)
-{
- char name[NFS_PATH_MAX];
- struct nfs3_fh fh = {{0}, };
- lookup3args args;
- int ret = RPCSVC_ACTOR_ERROR;
-
- GF_VALIDATE_OR_GOTO (GF_NFS, req, rpcerr);
-
- nfs3_prep_lookup3args (&args, &fh, name);
- if (xdr_to_lookup3args (req->msg[0], &args) <= 0) {
- gf_log (GF_NFS3, GF_LOG_ERROR, "Error decoding args");
- 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);
- ret = RPCSVC_ACTOR_ERROR;
- }
-
-rpcerr:
- return ret;
-}
-
-
-int
-nfs3_access_reply (rpcsvc_request_t *req, nfsstat3 status, int32_t accbits,
- int32_t reqaccbits)
-{
- access3res res;
-
- nfs3_fill_access3res (&res, status, accbits, reqaccbits);
- nfs3svc_submit_reply (req, &res,
- (nfs3_serializer)xdr_serialize_access3res);
- return 0;
-}
-
-
-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)
-{
- 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));
- status = nfs3_cbk_errno_status (op_ret, op_errno);
- }
- nfs3_log_common_res (rpcsvc_request_xid (cs->req), NFS3_ACCESS, status,
- op_errno);
- nfs3_access_reply (cs->req, status, op_errno, cs->accessbits);
- nfs3_call_state_wipe (cs);
-
- return 0;
-}
-
-int
-nfs3_access_resume (void *carg)
-{
- nfsstat3 stat = NFS3ERR_SERVERFAULT;
- int ret = -EFAULT;
- nfs_user_t nfu = {0, };
- nfs3_call_state_t *cs = NULL;
-
- if (!carg) {
- gf_log (GF_NFS3, GF_LOG_ERROR, "Invalid argument,"
- " carg value NULL");
- return EINVAL;
- }
-
- 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);
- if (ret < 0)
- stat = nfs3_errno_to_nfsstat3 (-ret);
-
-nfs3err:
- if (ret < 0) {
- nfs3_log_common_res (rpcsvc_request_xid (cs->req), NFS3_ACCESS,
- stat, -ret);
- nfs3_access_reply (cs->req, stat, 0, 0);
- nfs3_call_state_wipe (cs);
- ret = 0;
- }
-
- return ret;
-}
-
-
-int
-nfs3_access (rpcsvc_request_t *req, struct nfs3_fh *fh, uint32_t accbits)
-{
- xlator_t *vol = NULL;
- struct nfs3_state *nfs3 = NULL;
- nfsstat3 stat = NFS3ERR_SERVERFAULT;
- 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);
- 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);
- nfs3_volume_started_check (nfs3, vol, ret, out);
- nfs3_handle_call_state_init (nfs3, cs, req, vol, stat, nfs3err);
- cs->accessbits = accbits;
-
- ret = nfs3_fh_resolve_and_resume (cs, fh, NULL, nfs3_access_resume);
- if (ret < 0)
- stat = nfs3_errno_to_nfsstat3 (-ret);
-
-nfs3err:
- if (ret < 0) {
- nfs3_log_common_res (rpcsvc_request_xid (req), NFS3_ACCESS,
- stat, -ret);
- nfs3_access_reply (req, stat, 0, 0);
- nfs3_call_state_wipe (cs);
- ret = 0;
- }
-out:
- return ret;
-}
-
-
-int
-nfs3svc_access (rpcsvc_request_t *req)
-{
- struct nfs3_fh fh = {{0}, };
- access3args args;
- int ret = RPCSVC_ACTOR_ERROR;
-
- if (!req)
- return ret;
-
- nfs3_prep_access3args (&args, &fh);
- if (xdr_to_access3args (req->msg[0], &args) <= 0) {
- gf_log (GF_NFS3, GF_LOG_ERROR, "Error decoding args");
- 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);
- ret = RPCSVC_ACTOR_ERROR;
- }
-
-rpcerr:
- return ret;
-}
-
-
-int
-nfs3_readlink_reply (rpcsvc_request_t *req, nfsstat3 stat, char *path,
- struct iatt *buf)
-{
- readlink3res res = {0, };
- uint64_t deviceid = 0;
-
- deviceid = nfs3_request_xlator_deviceid (req);
- nfs3_fill_readlink3res (&res, stat, path, buf, deviceid);
- nfs3svc_submit_reply (req, (void *)&res,
- (nfs3_serializer)xdr_serialize_readlink3res);
-
- return 0;
-}
-
-
-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)
-{
- 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_cbk_errno_status (op_ret, op_errno);
- goto nfs3err;
- }
-
- stat = NFS3_OK;
-
-nfs3err:
- nfs3_log_readlink_res (rpcsvc_request_xid (cs->req), stat, op_errno,
- (char *)path);
- nfs3_readlink_reply (cs->req, stat, (char *)path, buf);
- nfs3_call_state_wipe (cs);
-
- return 0;
-}
-
-
-int
-nfs3_readlink_resume (void *carg)
-{
- nfsstat3 stat = NFS3ERR_SERVERFAULT;
- int ret = -EFAULT;
- nfs3_call_state_t *cs = NULL;
- nfs_user_t nfu = {0, };
-
- if (!carg)
- return ret;
-
- cs = (nfs3_call_state_t *)carg;
- nfs3_check_fh_resolve_status (cs, stat, nfs3err);
- nfs_request_user_init (&nfu, cs->req);
- ret = nfs_readlink (cs->nfsx, cs->vol, &nfu, &cs->resolvedloc,
- nfs3svc_readlink_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_READLINK, stat, -ret);
- nfs3_readlink_reply (cs->req, stat, NULL, NULL);
- nfs3_call_state_wipe (cs);
- }
-
- return ret;
-}
-
-
-int
-nfs3_readlink (rpcsvc_request_t *req, struct nfs3_fh *fh)
-{
- xlator_t *vol = NULL;
- nfsstat3 stat = NFS3ERR_SERVERFAULT;
- int ret = -EFAULT;
- struct nfs3_state *nfs3 = NULL;
- nfs3_call_state_t *cs = NULL;
-
- if ((!req) || (!fh)) {
- gf_log (GF_NFS3, GF_LOG_ERROR, "Bad arguments");
- return -1;
- }
-
- nfs3_log_common_call (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);
- nfs3_volume_started_check (nfs3, vol, ret, out);
- nfs3_handle_call_state_init (nfs3, cs, req, vol, stat, nfs3err);
-
- ret = nfs3_fh_resolve_and_resume (cs, fh, NULL, nfs3_readlink_resume);
- if (ret < 0)
- stat = nfs3_errno_to_nfsstat3 (-ret);
-
-nfs3err:
- if (ret < 0) {
- nfs3_log_common_res (rpcsvc_request_xid (req), NFS3_READLINK,
- stat, -ret);
- nfs3_readlink_reply (req, stat, NULL, NULL);
- nfs3_call_state_wipe (cs);
- /* Ret must be 0 after this so that the caller does not
- * also send an RPC reply.
- */
- ret = 0;
- }
-out:
- return ret;
-}
-
-
-int
-nfs3svc_readlink (rpcsvc_request_t *req)
-{
- struct nfs3_fh fh = {{0}, };
- readlink3args args;
- int ret = RPCSVC_ACTOR_ERROR;
-
- if (!req)
- return ret;
-
- nfs3_prep_readlink3args (&args, &fh);
- if (xdr_to_readlink3args (req->msg[0], &args) <= 0) {
- gf_log (GF_NFS3, GF_LOG_ERROR, "Error decoding args");
- 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);
- ret = RPCSVC_ACTOR_ERROR;
- }
-
-rpcerr:
- return ret;
-}
-
-
-int
-nfs3_read_reply (rpcsvc_request_t *req, nfsstat3 stat, count3 count,
- struct iovec *vec, int vcount, struct iobref *iobref,
- struct iatt *poststat, int is_eof)
-{
- read3res res = {0, };
- uint64_t deviceid = 0;
-
- 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);
- /* 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,
- (nfs3_serializer)
- xdr_serialize_read3res_nocopy);
- } else
- nfs3svc_submit_reply (req, (void *)&res,
- (nfs3_serializer)
- xdr_serialize_read3res_nocopy);
-
- return 0;
-}
-
-
-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)
-{
- nfsstat3 stat = NFS3ERR_SERVERFAULT;
- int is_eof = 0;
- 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_cbk_errno_status (op_ret, op_errno);
- goto err;
- } else
- stat = NFS3_OK;
-
- if (op_errno == ENOENT)
- is_eof = 1;
-
-err:
- nfs3_log_read_res (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);
- nfs3_call_state_wipe (cs);
-
- return 0;
-}
-
-
-int
-nfs3_read_fd_resume (void *carg)
-{
- nfsstat3 stat = NFS3ERR_SERVERFAULT;
- int ret = -EFAULT;
- nfs_user_t nfu = {0, };
- nfs3_call_state_t *cs = NULL;
-
- if (!carg)
- return ret;
-
- cs = (nfs3_call_state_t *)carg;
- nfs3_check_fh_resolve_status (cs, stat, nfs3err);
- nfs_request_user_init (&nfu, cs->req);
- ret = nfs_read (cs->nfsx, cs->vol, &nfu, cs->fd, cs->datacount,
- cs->dataoffset, nfs3svc_read_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_READ,
- stat, -ret);
- nfs3_read_reply (cs->req, stat, 0, NULL, 0, NULL, NULL, 0);
- nfs3_call_state_wipe (cs);
- }
-
- return ret;
-}
-
-
-int
-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;
- }
-
- 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,
- stat, -ret);
- nfs3_read_reply (cs->req, stat, 0, NULL,0, NULL, NULL, 0);
- nfs3_call_state_wipe (cs);
- }
-
- return ret;
-}
-
-int
-nfs3_read (rpcsvc_request_t *req, struct nfs3_fh *fh, offset3 offset,
- count3 count)
-{
- xlator_t *vol = NULL;
- nfsstat3 stat = NFS3ERR_SERVERFAULT;
- int ret = -EFAULT;
- struct nfs3_state *nfs3 = NULL;
- nfs3_call_state_t *cs = NULL;
-
- if ((!req) || (!fh)) {
- gf_log (GF_NFS3, GF_LOG_ERROR, "Bad arguments");
- return -1;
- }
-
- nfs3_log_rw_call (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);
- nfs3_map_fh_to_volume (nfs3, fh, req, vol, stat, nfs3err);
- nfs3_volume_started_check (nfs3, vol, ret, out);
- nfs3_handle_call_state_init (nfs3, cs, req, vol, stat, nfs3err);
-
- cs->datacount = count;
- cs->dataoffset = offset;
- ret = nfs3_fh_resolve_and_resume (cs, fh, NULL, nfs3_read_resume);
- if (ret < 0)
- stat = nfs3_errno_to_nfsstat3 (-ret);
-
-nfs3err:
- if (ret < 0) {
- nfs3_log_common_res (rpcsvc_request_xid (req), NFS3_READ, stat,
- -ret);
- nfs3_read_reply (req, stat, 0, NULL,0, NULL, NULL, 0);
- nfs3_call_state_wipe (cs);
- ret = 0;
- }
-out:
- return ret;
-}
-
-
-int
-nfs3svc_read (rpcsvc_request_t *req)
-{
- struct nfs3_fh fh = {{0}, };
- read3args args;
- int ret = RPCSVC_ACTOR_ERROR;
-
- if (!req)
- return ret;
-
- nfs3_prep_read3args (&args, &fh);
- if (xdr_to_read3args (req->msg[0], &args) <= 0) {
- gf_log (GF_NFS3, GF_LOG_ERROR, "Error decoding args");
- 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);
- ret = RPCSVC_ACTOR_ERROR;
- }
-
-rpcerr:
- return ret;
-}
-
-
-int
-nfs3_write_reply (rpcsvc_request_t *req, nfsstat3 stat, count3 count,
- stable_how stable, uint64_t wverf, struct iatt *prestat,
- struct iatt *poststat)
-{
- write3res res = {0, };
- uint64_t deviceid = 0;
-
- deviceid = nfs3_request_xlator_deviceid (req);
- nfs3_fill_write3res (&res, stat, count, stable, wverf, prestat,
- poststat, deviceid);
- nfs3svc_submit_reply (req, (void *)&res,
- (nfs3_serializer)xdr_serialize_write3res);
-
- return 0;
-}
-
-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 nfs3_state *nfs3 = NULL;
- nfsstat3 stat = NFS3ERR_SERVERFAULT;
- nfs3_call_state_t *cs = NULL;
-
- cs = frame->local;
- nfs3 = 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_cbk_errno_status (op_ret, op_errno);
- } else
- stat = NFS3_OK;
-
- nfs3_log_write_res (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);
- nfs3_call_state_wipe (cs);
- return 0;
-}
-
-
-
-/*
- * Before going into the write reply logic, here is a matrix that shows the
- * requirements for a write reply as given by RFC1813.
- *
- * Requested Write Type || Possible Returns
- * ==============================================
- * FILE_SYNC || FILE_SYNC
- * DATA_SYNC || DATA_SYNC or FILE_SYNC
- * UNSTABLE || DATA_SYNC or FILE_SYNC or UNSTABLE
- *
- * Write types other than UNSTABLE are together called STABLE.
- * RS - Return Stable
- * RU - Return Unstable
- * WS - Write Stable
- * WU - Write Unstable
- *
- *+============================================+
- *| Vol Opts -> || trusted-write| trusted-sync |
- *| Write Type || | |
- *|-------------||--------------|--------------|
- *| STABLE || WS | WU |
- *| || RS | RS |
- *|-------------||--------------|--------------|
- *| UNSTABLE || WU | WU |
- *| || RS | RS |
- *|-------------||--------------|--------------|
- *| COMMIT || fsync | getattr |
- *+============================================+
- *
- *
- */
-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)
-{
- nfsstat3 stat = NFS3ERR_SERVERFAULT;
- nfs3_call_state_t *cs = NULL;
- struct nfs3_state *nfs3 = NULL;
-
- cs = frame->local;
- nfs3 = 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_cbk_errno_status (op_ret, op_errno);
- goto err;
- }
-
- stat = NFS3_OK;
- cs->maxcount = op_ret;
-
-err:
- nfs3_log_write_res (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, prebuf,
- postbuf);
- nfs3_call_state_wipe (cs);
-
- return 0;
-}
-
-
-int
-__nfs3_write_resume (nfs3_call_state_t *cs)
-{
- int ret = -EFAULT;
- nfs_user_t nfu = {0, };
-
- if (!cs)
- return ret;
-
- nfs_request_user_init (&nfu, cs->req);
- /* It is possible that the RPC record contains more bytes than
- * than the size of write requested in this request. This means,
- * that in the RPC message buffer, there could be more bytes
- * beyind the @count bytes. Since @payload is referring to the write
- * data directly inside the RPC request buffer(..since we performed a
- * no-copy deXDRing..), we might end up writing more data than
- * requested, because till now payload.iov_len accounts for all the
- * bytes not just the write request bytes. These extra bytes are present
- * as a requirement of the XDR encoding to round up the all string and
- * 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);
-
- return ret;
-}
-
-
-int
-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. */
-
-/*
- enum stable_how {
- UNSTABLE = 0,
- DATA_SYNC = 1,
- FILE_SYNC = 2,
- };
-*/
- switch (cs->writetype) {
- case UNSTABLE:
- break;
- case DATA_SYNC:
- fd->flags |= O_DSYNC;
- break;
- case FILE_SYNC:
- fd->flags |= O_SYNC;
- break;
- }
-
- 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,
- 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)
-{
- xlator_t *vol = NULL;
- nfsstat3 stat = NFS3ERR_SERVERFAULT;
- int ret = -EFAULT;
- struct nfs3_state *nfs3 = NULL;
- nfs3_call_state_t *cs = NULL;
-
- if ((!req) || (!fh) || (!payload.iov_base)) {
- gf_log (GF_NFS3, GF_LOG_ERROR, "Bad arguments");
- return -1;
- }
-
- nfs3_log_rw_call (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);
- nfs3_map_fh_to_volume (nfs3, fh, req, vol, stat, nfs3err);
- nfs3_volume_started_check (nfs3, vol, ret, out);
- nfs3_check_rw_volaccess (nfs3, fh->exportid, stat, nfs3err);
- nfs3_handle_call_state_init (nfs3, cs, req, vol, stat, nfs3err);
- cs->datacount = count;
- cs->dataoffset = offset;
- cs->writetype = stable;
- cs->iobref = iobref;
- cs->datavec = payload;
-
-
- ret = nfs3_fh_resolve_and_resume (cs, fh, NULL, nfs3_write_resume);
- if (ret < 0)
- stat = nfs3_errno_to_nfsstat3 (-ret);
-
-nfs3err:
- if (ret < 0) {
- nfs3_log_common_res (rpcsvc_request_xid (req), NFS3_WRITE,
- stat, -ret);
- nfs3_write_reply (req, stat, 0, stable, 0, NULL, NULL);
- nfs3_call_state_wipe (cs);
- ret = 0;
- }
-out:
- return ret;
-}
-
-#define NFS3_VECWRITE_READFHLEN 1
-#define NFS3_VECWRITE_READFH 2
-#define NFS3_VECWRITE_READREST 3
-
-#define NFS3_WRITE_POSTFH_SIZE 20
-
-
-int
-nfs3svc_write_vecsizer (int state, ssize_t *readsize, char *base_addr,
- char *curr_addr)
-{
- int ret = 0;
- uint32_t fhlen = 0;
- uint32_t fhlen_n = 0;
-
- if (state == 0) {
- ret = NFS3_VECWRITE_READFHLEN;
- *readsize = 4;
- } else if (state == NFS3_VECWRITE_READFHLEN) {
- fhlen_n = *(uint32_t *)(curr_addr - 4);
- fhlen = ntohl (fhlen_n);
- *readsize = xdr_length_round_up (fhlen, NFS3_FHSIZE);
- ret = NFS3_VECWRITE_READFH;
- } else if (state == NFS3_VECWRITE_READFH) {
- *readsize = NFS3_WRITE_POSTFH_SIZE;
- ret = NFS3_VECWRITE_READREST;
- } else if (state == NFS3_VECWRITE_READREST) {
- ret = 0;
- *readsize = 0;
- } else
- gf_log ("nfs", GF_LOG_ERROR, "state wrong");
-
- return ret;
-}
-
-
-int
-nfs3svc_write (rpcsvc_request_t *req)
-{
- struct nfs3_fh fh = {{0}, };
- write3args args;
- int ret = RPCSVC_ACTOR_ERROR;
-
- if (!req)
- return ret;
- nfs3_prep_write3args (&args, &fh);
- if (xdr_to_write3args (req->msg[0], &args) <= 0) {
- gf_log (GF_NFS3, GF_LOG_ERROR, "Error decoding args");
- rpcsvc_request_seterr (req, GARBAGE_ARGS);
- goto rpcerr;
- }
-
- /* To ensure that the iobuf for the current record does not
- * get returned to the iobpool, we need to keep a reference for
- * 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.
- */
-
- ret = nfs3_write (req, &fh, args.offset, args.count, args.stable,
- req->msg[1], rpcsvc_request_iobref_ref (req));
- if ((ret < 0) && (ret != RPCSVC_ACTOR_IGNORE)) {
- gf_log (GF_NFS3, GF_LOG_ERROR, "WRITE procedure failed");
- rpcsvc_request_seterr (req, SYSTEM_ERR);
- ret = RPCSVC_ACTOR_ERROR;
- }
-
-rpcerr:
- return ret;
-}
-
-
-int
-nfs3_create_reply (rpcsvc_request_t *req, nfsstat3 stat, struct nfs3_fh *newfh,
- struct iatt *newbuf, struct iatt *preparent,
- struct iatt *postparent)
-{
- create3res res = {0, };
- uint64_t deviceid = 0;
-
- deviceid = nfs3_request_xlator_deviceid (req);
- nfs3_fill_create3res (&res, stat, newfh, newbuf, preparent, postparent,
- deviceid);
- nfs3svc_submit_reply (req, (void *)&res,
- (nfs3_serializer)xdr_serialize_create3res);
- return 0;
-}
-
-
-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)
-{
- 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_cbk_errno_status (op_ret, op_errno);
- goto nfs3err;
- }
-
- stat = NFS3_OK;
-nfs3err:
- nfs3_log_newfh_res (rpcsvc_request_xid (cs->req), NFS3_CREATE, stat,
- op_errno, &cs->fh);
- nfs3_create_reply (cs->req, stat, &cs->fh, postop, &cs->preparent,
- &cs->postparent);
- nfs3_call_state_wipe (cs);
-
- return 0;
-}
-
-
-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)
-{
- 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_cbk_errno_status (op_ret, 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) {
- stat = NFS3_OK;
- ret = -1;
- goto nfs3err;
- }
-
- 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,
- stat, op_errno, &cs->fh);
- nfs3_create_reply (cs->req, stat, &cs->fh, buf, preparent,
- postparent);
- nfs3_call_state_wipe (cs);
- }
-
- return 0;
-}
-
-int
-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
- flags = O_RDWR;
-
- 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);
- /* 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.
- */
- 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,
- flags, cs->mode, nfs3svc_create_cbk, cs);
- } else
- ret = nfs_create (cs->nfsx, cs->vol, &nfu, &cs->resolvedloc,
- flags, NFS_DEFAULT_CREATE_MODE,
- nfs3svc_create_cbk, cs);
-
- return ret;
-}
-
-
-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)
-{
- int ret = -EFAULT;
- nfsstat3 stat = NFS3ERR_SERVERFAULT;
- nfs_user_t nfu = {0, };
- nfs3_call_state_t *cs = NULL;
-
- 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_cbk_errno_status (op_ret, op_errno);
- goto nfs3err;
- }
-
- 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",
- 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,
- buf->ia_mtime, buf->ia_atime);
- stat = NFS3ERR_EXIST;
- }
-
-nfs3err:
- if (ret < 0) {
- nfs3_log_common_res (rpcsvc_request_xid (cs->req), NFS3_CREATE,
- stat, op_errno);
- nfs3_create_reply (cs->req, stat, &cs->fh, buf, NULL, NULL);
- nfs3_call_state_wipe (cs);
- }
-
- return 0;
-}
-
-
-int
-nfs3_create_exclusive (nfs3_call_state_t *cs)
-{
- int ret = -EFAULT;
- nfs_user_t nfu = {0, };
-
- if (!cs)
- return ret;
-
- /* 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->setattr_valid |= GF_SET_ATTR_ATIME;
- cs->setattr_valid |= GF_SET_ATTR_MTIME;
- nfs_request_user_init (&nfu, cs->req);
-
- /* If the file already existed we need to get that attributes so we can
- * compare and check whether a previous create operation was
- * interrupted due to server failure or dropped packets.
- */
- if ((cs->resolve_ret == 0) ||
- ((cs->resolve_ret == -1) && (cs->resolve_errno != ENOENT))) {
- ret = nfs_stat (cs->nfsx, cs->vol, &nfu, &cs->resolvedloc,
- nfs3svc_create_stat_cbk, cs);
- goto nfs3err;
- }
-
- ret = nfs3_create_common (cs);
-nfs3err:
- return ret;
-}
-
-
-int
-nfs3_create_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_new_fh_resolve_status (cs, stat, nfs3err);
- if (cs->createmode == EXCLUSIVE)
- ret = nfs3_create_exclusive (cs);
- else
- ret = nfs3_create_common (cs);
-
- /* Handle a failure return from either of the create functions above. */
- if (ret < 0)
- stat = nfs3_errno_to_nfsstat3 (-ret);
-
-nfs3err:
- if (ret < 0) {
- nfs3_log_common_res (rpcsvc_request_xid (cs->req), NFS3_CREATE,
- stat, -ret);
- nfs3_create_reply (cs->req, stat, NULL, NULL, NULL, NULL);
- nfs3_call_state_wipe (cs);
- }
-
- return ret;
-}
-
-int
-nfs3_create (rpcsvc_request_t *req, struct nfs3_fh *dirfh, char *name,
- createmode3 mode, sattr3 *sattr, uint64_t cverf)
-{
- xlator_t *vol = NULL;
- nfsstat3 stat = NFS3ERR_SERVERFAULT;
- int ret = -EFAULT;
- struct nfs3_state *nfs3 = NULL;
- nfs3_call_state_t *cs = NULL;
-
- if ((!req) || (!dirfh) || (!name) || (!sattr))
- return -1;
-
- nfs3_log_create_call (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);
- nfs3_map_fh_to_volume (nfs3, dirfh, req, vol, stat, nfs3err);
- nfs3_volume_started_check (nfs3, vol, ret, out);
- nfs3_check_rw_volaccess (nfs3, dirfh->exportid, stat, nfs3err);
- 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->createmode = mode;
- cs->parent = *dirfh;
-
- ret = nfs3_fh_resolve_and_resume (cs, dirfh, name, nfs3_create_resume);
- if (ret < 0)
- stat = nfs3_errno_to_nfsstat3 (-ret);
-
-nfs3err:
- if (ret < 0) {
- nfs3_log_common_res (rpcsvc_request_xid (req), NFS3_CREATE,
- stat, -ret);
- nfs3_create_reply (req, stat, NULL, NULL, NULL, NULL);
- nfs3_call_state_wipe (cs);
- ret = 0;
- }
-out:
- return ret;
-}
-
-
-int
-nfs3svc_create (rpcsvc_request_t *req)
-{
- char name[NFS_PATH_MAX];
- struct nfs3_fh dirfh = {{0}, };
- create3args args;
- int ret = RPCSVC_ACTOR_ERROR;
- uint64_t cverf = 0;
- uint64_t *cval;
-
- if (!req)
- return ret;
-
- nfs3_prep_create3args (&args, &dirfh, name);
- if (xdr_to_create3args (req->msg[0], &args) <= 0) {
- gf_log (GF_NFS3, GF_LOG_ERROR, "Error decoding args");
- rpcsvc_request_seterr (req, GARBAGE_ARGS);
- goto rpcerr;
- }
-
- cval = (uint64_t *)args.how.createhow3_u.verf;
- cverf = *cval;
-
- ret = nfs3_create (req, &dirfh, name, args.how.mode,
- &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);
- ret = RPCSVC_ACTOR_ERROR;
- }
-
-rpcerr:
- return ret;
-}
-
-
-int
-nfs3_mkdir_reply (rpcsvc_request_t *req, nfsstat3 stat, struct nfs3_fh *fh,
- struct iatt *buf, struct iatt *preparent,
- struct iatt *postparent)
-{
- mkdir3res res = {0, };
- uint64_t deviceid = 0;
-
- deviceid = nfs3_request_xlator_deviceid (req);
- nfs3_fill_mkdir3res (&res, stat, fh, buf, preparent, postparent,
- deviceid);
- nfs3svc_submit_reply (req, &res,
- (nfs3_serializer)xdr_serialize_mkdir3res);
- return 0;
-}
-
-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)
-{
- 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_cbk_errno_status (op_ret, op_errno);
- goto nfs3err;
- }
-
- stat = NFS3_OK;
-nfs3err:
- nfs3_log_newfh_res (rpcsvc_request_xid (cs->req), NFS3_MKDIR, stat,
- op_errno, &cs->fh);
- nfs3_mkdir_reply (cs->req, stat, &cs->fh, postop, &cs->preparent,
- &cs->postparent);
- nfs3_call_state_wipe (cs);
-
- return 0;
-}
-
-
-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)
-{
- nfsstat3 stat = NFS3ERR_SERVERFAULT;
- int ret = -EFAULT;
- nfs_user_t nfu = {0, };
- 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_cbk_errno_status (op_ret, op_errno);
- goto nfs3err;
- }
-
- nfs3_fh_build_child_fh (&cs->parent, buf, &cs->fh);
-
- /* Means no attributes were required to be set. */
- if (!cs->setattr_valid) {
- stat = NFS3_OK;
- goto nfs3err;
- }
-
- cs->preparent = *preparent;
- cs->postparent = *postparent;
- nfs_request_user_init (&nfu, cs->req);
- ret = nfs_setattr (cs->nfsx, cs->vol, &nfu, &cs->resolvedloc,&cs->stbuf,
- cs->setattr_valid, nfs3svc_mkdir_setattr_cbk, cs);
- if (ret < 0)
- stat = nfs3_errno_to_nfsstat3 (-ret);
-
-nfs3err:
- if (ret < 0) {
- nfs3_log_newfh_res (rpcsvc_request_xid (cs->req), NFS3_MKDIR,
- stat, op_errno, &cs->fh);
- nfs3_mkdir_reply (cs->req, stat, &cs->fh, buf, preparent,
- postparent);
- nfs3_call_state_wipe (cs);
- }
-
- return 0;
-}
-
-
-int
-nfs3_mkdir_resume (void *carg)
-{
- nfsstat3 stat = NFS3ERR_SERVERFAULT;
- int ret = -EFAULT;
- nfs_user_t nfu = {0, };
- nfs3_call_state_t *cs = NULL;
-
- if (!carg)
- return ret;
-
- cs = (nfs3_call_state_t *)carg;
- nfs3_check_new_fh_resolve_status (cs, stat, nfs3err);
- nfs_request_user_init (&nfu, cs->req);
-
- if (gf_attr_mode_set (cs->setattr_valid)) {
- cs->setattr_valid &= ~GF_SET_ATTR_MODE;
- ret = nfs_mkdir (cs->nfsx, cs->vol, &nfu, &cs->resolvedloc,
- cs->mode, nfs3svc_mkdir_cbk, cs);
- } else
- ret = nfs_mkdir (cs->nfsx, cs->vol, &nfu, &cs->resolvedloc,
- cs->mode, nfs3svc_mkdir_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_MKDIR,
- stat, -ret);
- nfs3_mkdir_reply (cs->req, stat, NULL, NULL, NULL, NULL);
- nfs3_call_state_wipe (cs);
- }
-
- return 0;
-}
-
-
-
-int
-nfs3_mkdir (rpcsvc_request_t *req, struct nfs3_fh *dirfh, char *name,
- sattr3 *sattr)
-{
- xlator_t *vol = NULL;
- nfsstat3 stat = NFS3ERR_SERVERFAULT;
- int ret = -EFAULT;
- struct nfs3_state *nfs3 = NULL;
- nfs3_call_state_t *cs = NULL;
-
- if ((!req) || (!dirfh) || (!name) || (!sattr)) {
- gf_log (GF_NFS3, GF_LOG_ERROR, "Bad arguments");
- return -1;
- }
-
- nfs3_log_fh_entry_call (rpcsvc_request_xid (req), "MKDIR", dirfh,
- name);
- 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);
- nfs3_map_fh_to_volume (nfs3, dirfh, req, vol, stat, nfs3err);
- nfs3_volume_started_check (nfs3, vol, ret, out);
- nfs3_check_rw_volaccess (nfs3, dirfh->exportid, stat, nfs3err);
- nfs3_handle_call_state_init (nfs3, cs, req, vol, stat, nfs3err);
-
- cs->parent = *dirfh;
- cs->setattr_valid = nfs3_sattr3_to_setattr_valid (sattr, &cs->stbuf,
- &cs->mode);
- ret = nfs3_fh_resolve_and_resume (cs, dirfh, name, nfs3_mkdir_resume);
- if (ret < 0)
- stat = nfs3_errno_to_nfsstat3 (-ret);
-
-nfs3err:
- if (ret < 0) {
- nfs3_log_common_res (rpcsvc_request_xid (req), NFS3_MKDIR,
- stat, -ret);
- nfs3_mkdir_reply (req, stat, NULL, NULL, NULL, NULL);
- nfs3_call_state_wipe (cs);
- ret = 0;
- }
-out:
- return ret;
-}
-
-
-int
-nfs3svc_mkdir (rpcsvc_request_t *req)
-{
- char name[NFS_PATH_MAX];
- struct nfs3_fh dirfh = {{0}, };
- mkdir3args args;
- int ret = RPCSVC_ACTOR_ERROR;
-
- if (!req)
- return ret;
- nfs3_prep_mkdir3args (&args, &dirfh, name);
- if (xdr_to_mkdir3args (req->msg[0], &args) <= 0) {
- gf_log (GF_NFS3, GF_LOG_ERROR, "Error decoding args");
- 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);
- ret = RPCSVC_ACTOR_ERROR;
- }
-
-rpcerr:
- return ret;
-}
-
-
-int
-nfs3_symlink_reply (rpcsvc_request_t *req, nfsstat3 stat, struct nfs3_fh *fh,
- struct iatt *buf, struct iatt *preparent,
- struct iatt *postparent)
-{
- symlink3res res = {0, };
- uint64_t deviceid = 0;
-
- deviceid = nfs3_request_xlator_deviceid (req);
- nfs3_fill_symlink3res (&res, stat, fh, buf, preparent, postparent,
- deviceid);
- nfs3svc_submit_reply (req, (void *)&res,
- (nfs3_serializer)xdr_serialize_symlink3res);
-
- return 0;
-}
-
-
-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)
-{
- 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_cbk_errno_status (op_ret, op_errno);
- goto nfs3err;
- }
-
- nfs3_fh_build_child_fh (&cs->parent, buf, &cs->fh);
- stat = NFS3_OK;
-
-nfs3err:
- nfs3_log_newfh_res (rpcsvc_request_xid (cs->req), NFS3_SYMLINK, stat,
- op_errno, &cs->fh);
- nfs3_symlink_reply (cs->req, stat, &cs->fh, buf, preparent,
- postparent);
- nfs3_call_state_wipe (cs);
- return 0;
-}
-
-
-int
-nfs3_symlink_resume (void *carg)
-{
- nfsstat3 stat = NFS3ERR_SERVERFAULT;
- int ret = -EFAULT;
- nfs3_call_state_t *cs = NULL;
- nfs_user_t nfu = {0, };
-
- if (!carg)
- return ret;
-
- cs = (nfs3_call_state_t *)carg;
- nfs3_check_new_fh_resolve_status (cs, stat, nfs3err);
- nfs_request_user_init (&nfu, cs->req);
- ret = nfs_symlink (cs->nfsx, cs->vol, &nfu, cs->pathname,
- &cs->resolvedloc, nfs3svc_symlink_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_SYMLINK, stat, -ret);
- nfs3_symlink_reply (cs->req, stat, NULL, NULL, NULL, NULL);
- nfs3_call_state_wipe (cs);
- }
-
- return ret;
-}
-
-
-int
-nfs3_symlink (rpcsvc_request_t *req, struct nfs3_fh *dirfh, char *name,
- char *target, sattr3 *sattr)
-{
- xlator_t *vol = NULL;
- nfsstat3 stat = NFS3ERR_SERVERFAULT;
- int ret = -EFAULT;
- struct nfs3_state *nfs3 = NULL;
- nfs3_call_state_t *cs = NULL;
-
- if ((!req) || (!dirfh) || (!name) || (!target) || (!sattr)) {
- gf_log (GF_NFS3, GF_LOG_ERROR, "Bad arguments");
- return -1;
- }
-
- nfs3_log_symlink_call (rpcsvc_request_xid (req), dirfh, name,
- target);
- 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);
- nfs3_map_fh_to_volume (nfs3, dirfh, req, vol, stat, nfs3err);
- nfs3_volume_started_check (nfs3, vol, ret, out);
- nfs3_check_rw_volaccess (nfs3, dirfh->exportid, stat, nfs3err);
- nfs3_handle_call_state_init (nfs3, cs, req, vol, stat, nfs3err);
-
- cs->parent = *dirfh;
- cs->pathname = gf_strdup (target);
- if (!cs->pathname) {
- ret = -1;
- stat = NFS3ERR_SERVERFAULT;
- goto nfs3err;
- }
-
- ret = nfs3_fh_resolve_and_resume (cs, dirfh, name, nfs3_symlink_resume);
- if (ret < 0)
- stat = nfs3_errno_to_nfsstat3 (-ret);
-
-nfs3err:
- if (ret < 0) {
- nfs3_log_common_res (rpcsvc_request_xid (req), NFS3_SYMLINK,
- stat, -ret);
- nfs3_symlink_reply (req, stat, NULL, NULL, NULL, NULL);
- nfs3_call_state_wipe (cs);
- /* Ret must be 0 after this so that the caller does not
- * also send an RPC reply.
- */
- ret = 0;
- }
-out:
- return ret;
-}
-
-
-int
-nfs3svc_symlink (rpcsvc_request_t *req)
-{
- char name[NFS_PATH_MAX];
- struct nfs3_fh dirfh = {{0}, };
- char target[NFS_PATH_MAX];
- symlink3args args;
- int ret = RPCSVC_ACTOR_ERROR;
-
- if (!req)
- return ret;
- nfs3_prep_symlink3args (&args, &dirfh, name, target);
- if (xdr_to_symlink3args (req->msg[0], &args) <= 0) {
- gf_log (GF_NFS3, GF_LOG_ERROR, "Error decoding args");
- rpcsvc_request_seterr (req, GARBAGE_ARGS);
- goto rpcerr;
- }
-
- ret = nfs3_symlink (req, &dirfh, name, target,
- &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);
- ret = RPCSVC_ACTOR_ERROR;
- }
-
-rpcerr:
- return ret;
-}
-
-
-static int
-nfs3_mknod_reply (rpcsvc_request_t *req, nfsstat3 stat, struct nfs3_fh *fh,
- struct iatt *buf, struct iatt *preparent,
- struct iatt *postparent)
-{
- mknod3res res = {0, };
- uint64_t deviceid = 0;
-
- deviceid = nfs3_request_xlator_deviceid (req);
- nfs3_fill_mknod3res (&res, stat, fh, buf, preparent, postparent,
- deviceid);
- nfs3svc_submit_reply (req, (void *)&res,
- (nfs3_serializer)xdr_serialize_mknod3res);
-
- return 0;
-}
-
-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)
-{
- 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_cbk_errno_status (op_ret, op_errno);
- goto nfs3err;
- }
-
- stat = NFS3_OK;
-nfs3err:
- nfs3_log_newfh_res (rpcsvc_request_xid (cs->req), NFS3_MKNOD, stat,
- op_errno, &cs->fh);
- nfs3_mknod_reply (cs->req, stat, &cs->fh, postop, &cs->preparent,
- &cs->postparent);
- nfs3_call_state_wipe (cs);
- return 0;
-}
-
-
-
-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)
-{
- nfsstat3 stat = NFS3ERR_SERVERFAULT;
- int ret = -1;
- nfs_user_t nfu = {0, };
- 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_cbk_errno_status (op_ret, op_errno);
- goto nfs3err;
- }
-
- nfs3_fh_build_child_fh (&cs->parent, buf, &cs->fh);
-
- /* Means no attributes were required to be set. */
- if (!cs->setattr_valid) {
- stat = NFS3_OK;
- ret = -1;
- goto nfs3err;
- }
-
- cs->preparent = *preparent;
- cs->postparent = *postparent;
- nfs_request_user_init (&nfu, cs->req);
- ret = nfs_setattr (cs->nfsx, cs->vol, &nfu, &cs->resolvedloc,&cs->stbuf,
- cs->setattr_valid, nfs3svc_mknod_setattr_cbk, cs);
- if (ret < 0)
- stat = nfs3_errno_to_nfsstat3 (-ret);
-nfs3err:
- if (ret < 0) {
- nfs3_log_newfh_res (rpcsvc_request_xid (cs->req), NFS3_MKNOD,
- stat,
- op_errno, &cs->fh);
- nfs3_mknod_reply (cs->req, stat, &cs->fh, buf, preparent,
- postparent);
- nfs3_call_state_wipe (cs);
- }
-
- return 0;
-}
-
-
-static int
-nfs3_mknod_device (nfs3_call_state_t *cs)
-{
- int ret = -EFAULT;
- dev_t devnum = 0;
- mode_t mode = 0;
- nfs_user_t nfu = {0, };
-
- if (!cs)
- return ret;
-
- devnum = makedev (cs->devnums.specdata1, cs->devnums.specdata2);
- if (cs->mknodtype == NF3CHR)
- mode = S_IFCHR;
- else
- mode = S_IFBLK;
-
- nfs_request_user_init (&nfu, cs->req);
- if (gf_attr_mode_set (cs->setattr_valid)) {
- cs->setattr_valid &= ~GF_SET_ATTR_MODE;
- mode |= cs->mode;
- ret = nfs_mknod (cs->nfsx, cs->vol, &nfu, &cs->resolvedloc,
- mode, devnum, nfs3svc_mknod_cbk, cs);
- } else
- ret = nfs_mknod (cs->nfsx, cs->vol, &nfu, &cs->resolvedloc,
- mode, devnum, nfs3svc_mknod_cbk, cs);
-
- return ret;
-}
-
-
-static int
-nfs3_mknod_fifo (nfs3_call_state_t *cs, mode_t mode)
-{
- int ret = -EFAULT;
- nfs_user_t nfu = {0, };
-
- if (!cs)
- return ret;
-
- nfs_request_user_init (&nfu, cs->req);
- if (gf_attr_mode_set (cs->setattr_valid)) {
- cs->setattr_valid &= ~GF_SET_ATTR_MODE;
- mode |= cs->mode;
- ret = nfs_mknod (cs->nfsx, cs->vol, &nfu, &cs->resolvedloc,
- mode, 0, nfs3svc_mknod_cbk, cs);
- } else
- ret = nfs_mknod (cs->nfsx, cs->vol, &nfu, &cs->resolvedloc,
- mode, 0, nfs3svc_mknod_cbk, cs);
-
- return ret;
-}
-
-
-static int
-nfs3_mknod_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_new_fh_resolve_status (cs, stat, nfs3err);
- switch (cs->mknodtype) {
-
- case NF3CHR:
- case NF3BLK:
- ret = nfs3_mknod_device (cs);
- break;
- case NF3SOCK:
- ret = nfs3_mknod_fifo (cs, S_IFSOCK);
- break;
- case NF3FIFO:
- ret = nfs3_mknod_fifo (cs, S_IFIFO);
- break;
- default:
- ret = -EBADF;
- break;
- }
-
- if (ret < 0)
- stat = nfs3_errno_to_nfsstat3 (-ret);
-
-nfs3err:
- if (ret < 0) {
- nfs3_log_common_res (rpcsvc_request_xid (cs->req), NFS3_MKNOD,
- stat, -ret);
- nfs3_mknod_reply (cs->req, stat, NULL, NULL, NULL, NULL);
- nfs3_call_state_wipe (cs);
- }
-
- return ret;
-}
-
-
-
-int
-nfs3_mknod (rpcsvc_request_t *req, struct nfs3_fh *fh, char *name,
- mknoddata3 *nodedata)
-{
- xlator_t *vol = NULL;
- nfsstat3 stat = NFS3ERR_SERVERFAULT;
- int ret = -EFAULT;
- struct nfs3_state *nfs3 = NULL;
- nfs3_call_state_t *cs = NULL;
- sattr3 *sattr = NULL;
-
- if ((!req) || (!fh) || (!name) || (!nodedata)) {
- gf_log (GF_NFS3, GF_LOG_ERROR, "Bad arguments");
- return -1;
- }
-
- nfs3_log_mknod_call (rpcsvc_request_xid (req), fh, name,
- nodedata->type);
- nfs3_validate_gluster_fh (fh, stat, nfs3err);
- nfs3_validate_nfs3_state (req, nfs3, stat, nfs3err, ret);
- nfs3_validate_strlen_or_goto (name, NFS_NAME_MAX, nfs3err, stat, ret);
- nfs3_map_fh_to_volume (nfs3, fh, req, vol, stat, nfs3err);
- nfs3_volume_started_check (nfs3, vol, ret, out);
- nfs3_check_rw_volaccess (nfs3, fh->exportid, stat, nfs3err);
- nfs3_handle_call_state_init (nfs3, cs, req, vol, stat, nfs3err);
-
- cs->mknodtype = nodedata->type;
- switch (nodedata->type) {
- case NF3CHR:
- 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->mode);
- break;
- case NF3SOCK:
- case NF3FIFO:
- sattr = &nodedata->mknoddata3_u.pipe_attributes;
- cs->setattr_valid = nfs3_sattr3_to_setattr_valid (sattr,
- &cs->stbuf,
- &cs->mode);
- break;
- default:
- ret = -EBADF;
- break;
- }
-
- cs->parent = *fh;
- ret = nfs3_fh_resolve_and_resume (cs, fh, name, nfs3_mknod_resume);
- if (ret < 0)
- stat = nfs3_errno_to_nfsstat3 (-ret);
-
-nfs3err:
- if (ret < 0) {
- nfs3_log_common_res (rpcsvc_request_xid (req), NFS3_MKNOD,
- stat, -ret);
- nfs3_mknod_reply (req, stat, NULL, NULL, NULL, NULL);
- /* Ret must be 0 after this so that the caller does not
- * also send an RPC reply.
- */
- nfs3_call_state_wipe (cs);
- ret = 0;
- }
-out:
- return ret;
-}
-
-
-int
-nfs3svc_mknod (rpcsvc_request_t *req)
-{
- char name[NFS_PATH_MAX];
- struct nfs3_fh fh = {{0}, };
- mknod3args args;
- int ret = RPCSVC_ACTOR_ERROR;
-
- if (!req)
- return ret;
- nfs3_prep_mknod3args (&args, &fh, name);
- if (xdr_to_mknod3args (req->msg[0], &args) <= 0) {
- gf_log (GF_NFS3, GF_LOG_ERROR, "Error decoding args");
- 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);
- ret = RPCSVC_ACTOR_ERROR;
- }
-
-rpcerr:
- return ret;
-}
-
-int
-nfs3_remove_reply (rpcsvc_request_t *req, nfsstat3 stat, struct iatt *preparent
- , struct iatt *postparent)
-{
- remove3res res = {0, };
- uint64_t deviceid = 0;
-
- deviceid = nfs3_request_xlator_deviceid (req);
- nfs3_fill_remove3res (&res, stat, preparent, postparent, deviceid);
- nfs3svc_submit_reply (req, (void *)&res,
- (nfs3_serializer)xdr_serialize_remove3res);
- return 0;
-}
-
-
-
-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)
-{
- 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_cbk_errno_status (op_ret, op_errno);
- }
-
- if (op_ret == 0)
- stat = NFS3_OK;
-
- nfs3_log_common_res (rpcsvc_request_xid (cs->req), NFS3_REMOVE, stat,
- op_errno);
- nfs3_remove_reply (cs->req, stat, preparent, postparent);
- nfs3_call_state_wipe (cs);
-
- return 0;
-}
-
-
-int
-__nfs3_remove (nfs3_call_state_t *cs)
-{
- int ret = -EFAULT;
- nfs_user_t nfu = {0, };
- ia_type_t type = 0;
-
- if (!cs)
- return ret;
- type = cs->resolvedloc.inode->ia_type;
- nfs_request_user_init (&nfu, cs->req);
- if (IA_ISDIR (type))
- ret = nfs_rmdir (cs->nfsx, cs->vol, &nfu, &cs->resolvedloc,
- nfs3svc_remove_cbk, cs);
- else
- ret = nfs_unlink (cs->nfsx, cs->vol, &nfu, &cs->resolvedloc,
- nfs3svc_remove_cbk, cs);
-
- return ret;
-}
-
-
-int
-nfs3_remove_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_remove (cs);
- if (ret < 0)
- stat = nfs3_errno_to_nfsstat3 (-ret);
-
-nfs3err:
- if (ret < 0) {
- nfs3_log_common_res (rpcsvc_request_xid (cs->req), NFS3_REMOVE,
- stat, -ret);
- nfs3_remove_reply (cs->req, stat, NULL, NULL);
- nfs3_call_state_wipe (cs);
- }
-
- return ret;
-}
-
-
-int
-nfs3_remove (rpcsvc_request_t *req, struct nfs3_fh *fh, char *name)
-{
- xlator_t *vol = NULL;
- nfsstat3 stat = NFS3ERR_SERVERFAULT;
- int ret = -EFAULT;
- struct nfs3_state *nfs3 = NULL;
- nfs3_call_state_t *cs = NULL;
-
- if ((!req) || (!fh) || (!name)) {
- gf_log (GF_NFS3, GF_LOG_ERROR, "Bad arguments");
- return -1;
- }
-
- nfs3_log_fh_entry_call (rpcsvc_request_xid (req), "REMOVE", fh,
- name);
- nfs3_validate_gluster_fh (fh, stat, nfs3err);
- nfs3_validate_nfs3_state (req, nfs3, stat, nfs3err, ret);
- nfs3_validate_strlen_or_goto (name, NFS_NAME_MAX, nfs3err, stat, ret);
- nfs3_map_fh_to_volume (nfs3, fh, req, vol, stat, nfs3err);
- nfs3_volume_started_check (nfs3, vol, ret, out);
- nfs3_check_rw_volaccess (nfs3, fh->exportid, stat, nfs3err);
- nfs3_handle_call_state_init (nfs3, cs, req, vol, stat, nfs3err);
-
- ret = nfs3_fh_resolve_and_resume (cs, fh, name, nfs3_remove_resume);
- if (ret < 0)
- stat = nfs3_errno_to_nfsstat3 (-ret);
-
-nfs3err:
- if (ret < 0) {
- nfs3_log_common_res (rpcsvc_request_xid (req), NFS3_REMOVE,
- stat, -ret);
- nfs3_remove_reply (req, stat, NULL, NULL);
- nfs3_call_state_wipe (cs);
- /* Ret must be 0 after this so that the caller does not
- * also send an RPC reply.
- */
- ret = 0;
- }
-out:
- return ret;
-}
-
-
-int
-nfs3svc_remove (rpcsvc_request_t *req)
-{
- char name[NFS_PATH_MAX];
- struct nfs3_fh fh = {{0}, };
- remove3args args;
- int ret = RPCSVC_ACTOR_ERROR;
-
- if (!req)
- return ret;
- nfs3_prep_remove3args (&args, &fh, name);
- if (xdr_to_remove3args (req->msg[0], &args) <= 0) {
- gf_log (GF_NFS3, GF_LOG_ERROR, "Error decoding args");
- 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);
- ret = RPCSVC_ACTOR_ERROR;
- }
-
-rpcerr:
- return ret;
-}
-
-
-int
-nfs3_rmdir_reply (rpcsvc_request_t *req, nfsstat3 stat, struct iatt *preparent,
- struct iatt *postparent)
-{
- rmdir3res res = {0, };
- uint64_t deviceid = 0;
-
- deviceid = nfs3_request_xlator_deviceid (req);
- nfs3_fill_rmdir3res (&res, stat, preparent, postparent, deviceid);
- nfs3svc_submit_reply (req, (void *)&res,
- (nfs3_serializer)xdr_serialize_rmdir3res);
- return 0;
-}
-
-
-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)
-{
- 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_cbk_errno_status (op_ret, op_errno);
- } else {
- stat = NFS3_OK;
- }
-
- nfs3_log_common_res (rpcsvc_request_xid (cs->req), NFS3_RMDIR, stat,
- op_errno);
- nfs3_rmdir_reply (cs->req, stat, preparent, postparent);
- nfs3_call_state_wipe (cs);
-
- return 0;
-}
-
-int
-nfs3_rmdir_resume (void *carg)
-{
- nfsstat3 stat = NFS3ERR_SERVERFAULT;
- int ret = -EFAULT;
- nfs3_call_state_t *cs = NULL;
- nfs_user_t nfu = {0, };
-
- if (!carg)
- return ret;
-
- cs = (nfs3_call_state_t *)carg;
- nfs3_check_fh_resolve_status (cs, stat, nfs3err);
- nfs_request_user_init (&nfu, cs->req);
- ret = nfs_rmdir (cs->nfsx, cs->vol, &nfu, &cs->resolvedloc,
- nfs3svc_rmdir_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_RMDIR,
- stat, -ret);
- nfs3_rmdir_reply (cs->req, stat, NULL, NULL);
- nfs3_call_state_wipe (cs);
- }
-
- return ret;
-}
-
-
-
-int
-nfs3_rmdir (rpcsvc_request_t *req, struct nfs3_fh *fh, char *name)
-{
- xlator_t *vol = NULL;
- nfsstat3 stat = NFS3ERR_SERVERFAULT;
- int ret = -EFAULT;
- struct nfs3_state *nfs3 = NULL;
- nfs3_call_state_t *cs = NULL;
-
- if ((!req) || (!fh) || (!name)) {
- gf_log (GF_NFS3, GF_LOG_ERROR, "Bad arguments");
- return -1;
- }
-
- nfs3_log_fh_entry_call (rpcsvc_request_xid (req), "RMDIR", fh,
- name);
- nfs3_validate_gluster_fh (fh, stat, nfs3err);
- nfs3_validate_nfs3_state (req, nfs3, stat, nfs3err, ret);
- nfs3_validate_strlen_or_goto (name, NFS_NAME_MAX, nfs3err, stat, ret);
- nfs3_map_fh_to_volume (nfs3, fh, req, vol, stat, nfs3err);
- nfs3_volume_started_check (nfs3, vol, ret, out);
- nfs3_check_rw_volaccess (nfs3, fh->exportid, stat, nfs3err);
- nfs3_handle_call_state_init (nfs3, cs, req, vol, stat, nfs3err);
-
- ret = nfs3_fh_resolve_and_resume (cs, fh, name, nfs3_rmdir_resume);
- if (ret < 0)
- stat = nfs3_errno_to_nfsstat3 (-ret);
-
-nfs3err:
- if (ret < 0) {
- nfs3_log_common_res (rpcsvc_request_xid (req), NFS3_RMDIR,
- stat, -ret);
- nfs3_rmdir_reply (req, stat, NULL, NULL);
- nfs3_call_state_wipe (cs);
- /* Ret must be 0 after this so that the caller does not
- * also send an RPC reply.
- */
- ret = 0;
- }
-out:
- return ret;
-}
-
-
-int
-nfs3svc_rmdir (rpcsvc_request_t *req)
-{
- char name[NFS_PATH_MAX];
- struct nfs3_fh fh = {{0}, };
- rmdir3args args;
- int ret = RPCSVC_ACTOR_ERROR;
-
- if (!req)
- return ret;
- nfs3_prep_rmdir3args (&args, &fh, name);
- if (xdr_to_rmdir3args (req->msg[0], &args) <= 0) {
- gf_log (GF_NFS3, GF_LOG_ERROR, "Error decoding args");
- 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);
- ret = RPCSVC_ACTOR_ERROR;
- }
-
-rpcerr:
- return ret;
-}
-
-
-int
-nfs3_rename_reply (rpcsvc_request_t *req, nfsstat3 stat, struct iatt *buf,
- struct iatt *preoldparent, struct iatt *postoldparent,
- struct iatt *prenewparent, struct iatt *postnewparent)
-{
- rename3res res = {0, };
- uint64_t deviceid = 0;
-
- deviceid = nfs3_request_xlator_deviceid (req);
- nfs3_fill_rename3res (&res, stat, buf, preoldparent, postoldparent,
- prenewparent, postnewparent, deviceid);
-
- nfs3svc_submit_reply (req, (void *)&res,
- (nfs3_serializer) xdr_serialize_rename3res);
-
- return 0;
-}
-
-
-
-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)
-{
- int ret = -EFAULT;
- 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: rename %s -> %s => -1 (%s)",
- rpcsvc_request_xid (cs->req), cs->oploc.path,
- cs->resolvedloc.path, strerror (op_errno));
- stat = nfs3_cbk_errno_status (op_ret, op_errno);
- goto nfs3err;
- }
-
- stat = NFS3_OK;
-nfs3err:
- nfs3_log_common_res (rpcsvc_request_xid (cs->req), NFS3_RENAME, stat,
- -ret);
- nfs3_rename_reply (cs->req, stat, buf, preoldparent, postoldparent,
- prenewparent, postnewparent);
- nfs3_call_state_wipe (cs);
- return 0;
-}
-
-
-int
-nfs3_rename_resume_dst (void *carg)
-{
- nfsstat3 stat = NFS3ERR_SERVERFAULT;
- int ret = -EFAULT;
- nfs3_call_state_t *cs = NULL;
- nfs_user_t nfu = {0, };
-
- if (!carg)
- return ret;
-
- cs = (nfs3_call_state_t *)carg;
- nfs3_check_new_fh_resolve_status (cs, stat, nfs3err);
- cs->parent = cs->resolvefh;
- nfs_request_user_init (&nfu, cs->req);
- ret = nfs_rename (cs->nfsx, cs->vol, &nfu, &cs->oploc, &cs->resolvedloc,
- nfs3svc_rename_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_RENAME,
- stat, -ret);
- nfs3_rename_reply (cs->req, stat, NULL, NULL, NULL, NULL, NULL);
- nfs3_call_state_wipe (cs);
- }
-
- return ret;
-}
-
-
-
-int
-nfs3_rename_resume_src (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);
- /* Copy the resolved loc for the source file into another loc
- * for safekeeping till we resolve the dest loc.
- */
- 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);
- if (ret < 0)
- stat = nfs3_errno_to_nfsstat3 (-ret);
-
-nfs3err:
- if (ret < 0) {
- nfs3_log_common_res (rpcsvc_request_xid (cs->req), NFS3_RENAME,
- stat, -ret);
- nfs3_rename_reply (cs->req, stat, NULL, NULL, NULL, NULL, NULL);
- nfs3_call_state_wipe (cs);
- }
-
- return ret;
-}
-
-
-int
-nfs3_rename (rpcsvc_request_t *req, struct nfs3_fh *olddirfh, char *oldname,
- struct nfs3_fh *newdirfh, char *newname)
-{
- xlator_t *vol = NULL;
- nfsstat3 stat = NFS3ERR_SERVERFAULT;
- int ret = -EFAULT;
- struct nfs3_state *nfs3 = NULL;
- nfs3_call_state_t *cs = NULL;
-
- if ((!req) || (!olddirfh) || (!oldname) || (!newdirfh) || (!newname)) {
- gf_log (GF_NFS3, GF_LOG_ERROR, "Bad arguments");
- return -1;
- }
-
- nfs3_log_rename_call (rpcsvc_request_xid (req), olddirfh, oldname,
- newdirfh, newname);
- nfs3_validate_gluster_fh (olddirfh, stat, nfs3err);
- nfs3_validate_gluster_fh (newdirfh, stat, nfs3err);
- nfs3_validate_nfs3_state (req, nfs3, stat, nfs3err, ret);
- nfs3_validate_strlen_or_goto(oldname, NFS_NAME_MAX, nfs3err, stat, ret);
- nfs3_validate_strlen_or_goto(newname, NFS_NAME_MAX, nfs3err, stat, ret);
- nfs3_map_fh_to_volume (nfs3, olddirfh, req, vol, stat, nfs3err);
- nfs3_volume_started_check (nfs3, vol, ret, out);
- nfs3_check_rw_volaccess (nfs3, olddirfh->exportid, stat, nfs3err);
- nfs3_handle_call_state_init (nfs3, cs, req, vol, stat, nfs3err);
-
- /* While we resolve the source (fh, name) pair, we need to keep a copy
- * of the dest (fh,name) pair.
- */
- cs->fh = *newdirfh;
- cs->pathname = gf_strdup (newname);
- if (!cs->pathname) {
- stat = NFS3ERR_SERVERFAULT;
- ret = -1;
- goto nfs3err;
- }
-
- ret = nfs3_fh_resolve_and_resume (cs, olddirfh, oldname,
- nfs3_rename_resume_src);
- if (ret < 0)
- stat = nfs3_errno_to_nfsstat3 (-ret);
-
-nfs3err:
- if (ret < 0) {
- nfs3_log_common_res (rpcsvc_request_xid (req), NFS3_RENAME,
- stat, -ret);
- nfs3_rename_reply (req, stat, NULL, NULL, NULL, NULL, NULL);
- nfs3_call_state_wipe (cs);
- /* Ret must be 0 after this so that the caller does not
- * also send an RPC reply.
- */
- ret = 0;
- }
-out:
- return ret;
-}
-
-
-int
-nfs3svc_rename (rpcsvc_request_t *req)
-{
- char newname[NFS_PATH_MAX];
- char oldname[NFS_PATH_MAX];
- struct nfs3_fh olddirfh = {{0}, };
- struct nfs3_fh newdirfh = {{0}, };
- rename3args args;
- int ret = RPCSVC_ACTOR_ERROR;
-
- if (!req)
- return ret;
- nfs3_prep_rename3args (&args, &olddirfh, oldname, &newdirfh, newname);
- if (xdr_to_rename3args (req->msg[0], &args) <= 0) {
- gf_log (GF_NFS3, GF_LOG_ERROR, "Error decoding args");
- 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);
- ret = RPCSVC_ACTOR_ERROR;
- }
-
-rpcerr:
- return ret;
-}
-
-
-int
-nfs3_link_reply (rpcsvc_request_t *req, nfsstat3 stat, struct iatt *buf,
- struct iatt *preparent, struct iatt *postparent)
-{
- link3res res = {0, };
- uint64_t deviceid = 0;
-
- deviceid = nfs3_request_xlator_deviceid (req);
- nfs3_fill_link3res (&res, stat, buf, preparent, postparent, deviceid);
- nfs3svc_submit_reply (req, (void *)&res,
- (nfs3_serializer)xdr_serialize_link3res);
-
- return 0;
-}
-
-
-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)
-{
- 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));
- stat = nfs3_cbk_errno_status (op_ret, op_errno);
- } else
- stat = NFS3_OK;
-
- nfs3_log_common_res (rpcsvc_request_xid (cs->req), NFS3_LINK, stat,
- op_errno);
- nfs3_link_reply (cs->req, stat, buf, preparent, postparent);
- nfs3_call_state_wipe (cs);
-
- return 0;
-}
-
-
-int
-nfs3_link_resume_lnk (void *carg)
-{
- nfsstat3 stat = NFS3ERR_SERVERFAULT;
- int ret = -EFAULT;
- nfs3_call_state_t *cs = NULL;
- nfs_user_t nfu = {0, };
-
- if (!carg)
- return ret;
-
- cs = (nfs3_call_state_t *)carg;
- nfs3_check_new_fh_resolve_status (cs, stat, nfs3err);
-
- nfs_request_user_init (&nfu, cs->req);
- ret = nfs_link (cs->nfsx, cs->vol, &nfu, &cs->oploc, &cs->resolvedloc,
- nfs3svc_link_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_LINK,
- stat, -ret);
- nfs3_link_reply (cs->req, stat, NULL, NULL, NULL);
- nfs3_call_state_wipe (cs);
- }
- return ret;
-}
-
-
-int
-nfs3_link_resume_tgt (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);
- nfs_loc_copy (&cs->oploc, &cs->resolvedloc);
- nfs_loc_wipe (&cs->resolvedloc);
-
- ret = nfs3_fh_resolve_and_resume (cs, &cs->fh, cs->pathname,
- nfs3_link_resume_lnk);
- if (ret < 0)
- stat = nfs3_errno_to_nfsstat3 (-ret);
-
-nfs3err:
- if (ret < 0) {
- nfs3_log_common_res (rpcsvc_request_xid (cs->req), NFS3_LINK,
- stat, -ret);
- nfs3_link_reply (cs->req, stat, NULL, NULL, NULL);
- nfs3_call_state_wipe (cs);
- }
-
- return ret;
-}
-
-
-int
-nfs3_link (rpcsvc_request_t *req, struct nfs3_fh *targetfh,
- struct nfs3_fh *dirfh, char *newname)
-{
- xlator_t *vol = NULL;
- nfsstat3 stat = NFS3ERR_SERVERFAULT;
- int ret = -EFAULT;
- struct nfs3_state *nfs3 = NULL;
- nfs3_call_state_t *cs = NULL;
-
- if ((!req) || (!targetfh) || (!dirfh) || (!newname)) {
- gf_log (GF_NFS3, GF_LOG_ERROR, "Bad arguments");
- return -1;
- }
-
- nfs3_validate_gluster_fh (dirfh, stat, nfs3err);
- nfs3_validate_gluster_fh (targetfh, stat, nfs3err);
- nfs3_validate_nfs3_state (req, nfs3, stat, nfs3err, ret);
- nfs3_validate_strlen_or_goto(newname, NFS_NAME_MAX, nfs3err, stat, ret);
- nfs3_map_fh_to_volume (nfs3, dirfh, req, vol, stat, nfs3err);
- nfs3_volume_started_check (nfs3, vol, ret, out);
- nfs3_check_rw_volaccess (nfs3, dirfh->exportid, stat, nfs3err);
- nfs3_handle_call_state_init (nfs3, cs, req, vol, stat, nfs3err);
-
- cs->fh = *dirfh;
- cs->pathname = gf_strdup (newname);
- if (!cs->pathname) {
- stat = NFS3ERR_SERVERFAULT;
- ret = -1;
- goto nfs3err;
- }
-
- ret = nfs3_fh_resolve_and_resume (cs, targetfh, NULL,
- nfs3_link_resume_tgt);
- if (ret < 0)
- stat = nfs3_errno_to_nfsstat3 (-ret);
-
-nfs3err:
- if (ret < 0) {
- nfs3_log_common_res (rpcsvc_request_xid (req), NFS3_LINK, stat,
- -ret);
- nfs3_link_reply (req, stat, NULL, NULL, NULL);
- nfs3_call_state_wipe (cs);
- /* Ret must be 0 after this so that the caller does not
- * also send an RPC reply.
- */
- ret = 0;
- }
-out:
- return ret;
-}
-
-int
-nfs3svc_link (rpcsvc_request_t *req)
-{
- char newpath[NFS_PATH_MAX];
- struct nfs3_fh dirfh = {{0}, };
- struct nfs3_fh targetfh = {{0}, };
- link3args args;
- int ret = RPCSVC_ACTOR_ERROR;
-
- if (!req)
- return ret;
- nfs3_prep_link3args (&args, &targetfh, &dirfh, newpath);
- if (xdr_to_link3args (req->msg[0], &args) <= 0) {
- gf_log (GF_NFS3, GF_LOG_ERROR, "Error decoding args");
- 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);
- ret = RPCSVC_ACTOR_ERROR;
- }
-
-rpcerr:
- return ret;
-}
-
-
-int
-nfs3_readdirp_reply (rpcsvc_request_t *req, nfsstat3 stat,struct nfs3_fh *dirfh,
- uint64_t cverf, struct iatt *dirstat, gf_dirent_t *entries,
- count3 dircount, count3 maxcount, int is_eof)
-{
- readdirp3res res = {0, };
- uint64_t deviceid = 0;
-
- deviceid = nfs3_request_xlator_deviceid (req);
- nfs3_fill_readdirp3res (&res, stat, dirfh, cverf, dirstat, entries,
- dircount, maxcount, is_eof, deviceid);
- nfs3svc_submit_reply (req, (void *)&res,
- (nfs3_serializer) xdr_serialize_readdirp3res);
- nfs3_free_readdirp3res (&res);
-
- return 0;
-}
-
-
-int
-nfs3_readdir_reply (rpcsvc_request_t *req, nfsstat3 stat, struct nfs3_fh *dirfh,
- uint64_t cverf, struct iatt *dirstat, gf_dirent_t *entries,
- count3 count, int is_eof)
-{
- readdir3res res = {0, };
- uint64_t deviceid = 0;
-
- deviceid = nfs3_request_xlator_deviceid (req);
- nfs3_fill_readdir3res (&res, stat, dirfh, cverf, dirstat, entries, count
- , is_eof, deviceid);
- nfs3svc_submit_reply (req, (void *)&res,
- (nfs3_serializer) xdr_serialize_readdir3res);
- nfs3_free_readdir3res (&res);
-
- return 0;
-}
-
-
-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)
-{
- nfsstat3 stat = NFS3ERR_SERVERFAULT;
- int is_eof = 0;
- 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_cbk_errno_status (op_ret, op_errno);
- goto nfs3err;
- }
-
- /* Check whether we encountered a end of directory stream while
- * readdir'ing.
- */
- if (cs->operrno == ENOENT) {
- gf_log (GF_NFS3, GF_LOG_TRACE, "Reached end-of-directory");
- is_eof = 1;
- }
-
- stat = NFS3_OK;
-
- /* do inode linking here */
- gf_link_inodes_from_dirent (this, cs->fd->inode, &cs->entries);
-
-nfs3err:
- if (cs->maxcount == 0) {
- nfs3_log_readdir_res (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,
- op_errno, (uintptr_t)cs->fd,
- cs->dircount, cs->maxcount, is_eof);
- nfs3_readdirp_reply (cs->req, stat, &cs->parent,
- (uintptr_t)cs->fd, buf,
- &cs->entries, cs->dircount,
- cs->maxcount, is_eof);
- }
-
- if (is_eof) {
- /* do nothing */
- }
-
- nfs3_call_state_wipe (cs);
- return 0;
-}
-
-
-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)
-{
- nfsstat3 stat = NFS3ERR_SERVERFAULT;
- int ret = -EFAULT;
- nfs_user_t nfu = {0, };
- 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_cbk_errno_status (op_ret, op_errno);
- goto err;
- }
-
- cs->operrno = op_errno;
- list_splice_init (&entries->list, &cs->entries.list);
- nfs_request_user_init (&nfu, cs->req);
- ret = nfs_fstat (cs->nfsx, cs->vol, &nfu, cs->fd,
- nfs3svc_readdir_fstat_cbk, cs);
- if (ret < 0) {
- op_ret = -1;
- stat = nfs3_errno_to_nfsstat3 (-ret);
- op_errno = -ret;
- }
-
-err:
- if (op_ret >= 0)
- goto ret;
-
- if (cs->maxcount == 0) {
- nfs3_log_common_res (rpcsvc_request_xid (cs->req),
- NFS3_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_readdirp_reply (cs->req, stat, NULL, 0, NULL, NULL,
- 0, 0, 0);
- }
-
- /* For directories, we force a purge from the fd cache on close
- * so that next time the dir is read, we'll get any changed directory
- * entries.
- */
- nfs3_call_state_wipe (cs);
-ret:
- return 0;
-}
-
-int
-nfs3_readdir_process (nfs3_call_state_t *cs)
-{
- int ret = -EFAULT;
- nfs_user_t nfu = {0, };
-
- if (!cs)
- return ret;
-
- nfs_request_user_init (&nfu, cs->req);
- ret = nfs_readdirp (cs->nfsx, cs->vol, &nfu, cs->fd, cs->dircount,
- cs->cookie, nfs3svc_readdir_cbk, cs);
- return ret;
-}
-
-
-int
-nfs3_readdir_read_resume (void *carg)
-{
- nfsstat3 stat = NFS3ERR_SERVERFAULT;
- int ret = -EFAULT;
- nfs3_call_state_t *cs = NULL;
- struct nfs3_state *nfs3 = NULL;
-
- if (!carg)
- return ret;
-
- cs = (nfs3_call_state_t *)carg;
- nfs3_check_fh_resolve_status (cs, stat, nfs3err);
- nfs3 = 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. */
- goto nfs3err;
-
- ret = nfs3_readdir_process (cs);
- 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_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_readdirp_reply (cs->req, stat, NULL, 0, NULL, NULL,
- 0, 0, 0);
- }
- nfs3_call_state_wipe (cs);
- }
-
- return 0;
-}
-
-
-int32_t
-nfs3svc_readdir_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)
-{
- /*
- * We don't really need this, it's just an artifact of forcing the
- * opendir to happen.
- */
- if (fd) {
- fd_unref(fd);
- }
-
- return 0;
-}
-
-
-int
-nfs3_readdir_open_resume (void *carg)
-{
- nfsstat3 stat = NFS3ERR_SERVERFAULT;
- int ret = -EFAULT;
- nfs3_call_state_t *cs = NULL;
- nfs_user_t nfu = {0, };
-
- if (!carg)
- return ret;
-
- 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;
- }
-
- /*
- * NFS client will usually send us a readdirp without an opendir,
- * which would cause us to skip our usual self-heal checks which occur
- * in opendir for native protocol. To make sure those checks do happen,
- * our most reliable option is to do our own opendir for any readdirp
- * at the beginning of the directory.
- */
- if (cs->cookie == 0) {
- nfs_request_user_init (&nfu, cs->req);
- ret = nfs_opendir (cs->nfsx, cs->vol, &nfu, &cs->resolvedloc,
- nfs3svc_readdir_opendir_cbk, cs);
- if (ret < 0) {
- gf_log (GF_NFS3, GF_LOG_ERROR, "auto-opendir failed");
- }
- }
-
- ret = nfs3_readdir_read_resume (cs);
- 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_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_readdirp_reply (cs->req, stat, NULL, 0, NULL, NULL,
- 0, 0, 0);
- }
- nfs3_call_state_wipe (cs);
- }
-
- return ret;
-}
-
-
-
-int
-nfs3_readdir (rpcsvc_request_t *req, struct nfs3_fh *fh, cookie3 cookie,
- uint64_t cverf, count3 dircount, count3 maxcount)
-{
- xlator_t *vol = NULL;
- nfsstat3 stat = NFS3ERR_SERVERFAULT;
- int ret = -EFAULT;
- struct nfs3_state *nfs3 = NULL;
- nfs3_call_state_t *cs = NULL;
-
- if ((!req) || (!fh)) {
- gf_log (GF_NFS3, GF_LOG_ERROR, "Bad arguments");
- return -1;
- }
-
- nfs3_log_readdir_call (rpcsvc_request_xid (req), fh, dircount,
- maxcount);
- 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);
- nfs3_volume_started_check (nfs3, vol, ret, out);
- nfs3_handle_call_state_init (nfs3, cs, req, vol, stat, nfs3err);
-
- cs->cookieverf = cverf;
- cs->dircount = dircount;
- cs->maxcount = maxcount;
- cs->cookie = cookie;
- cs->parent = *fh;
- ret = nfs3_fh_resolve_and_resume (cs, fh, NULL,
- nfs3_readdir_open_resume);
- if (ret < 0)
- stat = nfs3_errno_to_nfsstat3 (-ret);
-
-nfs3err:
- if (ret < 0) {
- if (maxcount == 0) {
- nfs3_log_common_res (rpcsvc_request_xid (req),
- NFS3_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_readdirp_reply (req, stat, NULL, 0, NULL, NULL, 0,
- 0, 0);
- }
- /* Ret must be NULL after this so that the caller does not
- * also send an RPC reply.
- */
- ret = 0;
- nfs3_call_state_wipe (cs);
- }
-out:
- return ret;
-}
-
-
-int
-nfs3svc_readdir (rpcsvc_request_t *req)
-{
- readdir3args ra;
- struct nfs3_fh fh = {{0},};
- int ret = RPCSVC_ACTOR_ERROR;
- uint64_t verf = 0;
- uint64_t *cval;
-
- if (!req)
- return ret;
- nfs3_prep_readdir3args (&ra, &fh);
- if (xdr_to_readdir3args (req->msg[0], &ra) <= 0) {
- gf_log (GF_NFS3, GF_LOG_ERROR, "Error decoding args");
- rpcsvc_request_seterr (req, GARBAGE_ARGS);
- goto rpcerr;
- }
- cval = (uint64_t *) ra.cookieverf;
- verf = *cval;
-
- 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);
- ret = RPCSVC_ACTOR_ERROR;
- }
-
-rpcerr:
- return ret;
-}
-
-
-int
-nfs3svc_readdirp (rpcsvc_request_t *req)
-{
- readdirp3args ra;
- struct nfs3_fh fh = {{0},};
- int ret = RPCSVC_ACTOR_ERROR;
- uint64_t cverf = 0;
- uint64_t *cval;
-
- if (!req)
- return ret;
- nfs3_prep_readdirp3args (&ra, &fh);
- if (xdr_to_readdirp3args (req->msg[0], &ra) <= 0) {
- gf_log (GF_NFS3, GF_LOG_ERROR, "Error decoding args");
- rpcsvc_request_seterr (req, GARBAGE_ARGS);
- goto rpcerr;
- }
- cval = (uint64_t *) ra.cookieverf;
- cverf = *cval;
-
- ret = nfs3_readdir (req, &fh, ra.cookie, cverf, ra.dircount,
- 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);
- ret = RPCSVC_ACTOR_ERROR;
- }
-
-rpcerr:
- return ret;
-}
-
-
-int
-nfs3_fsstat_reply (rpcsvc_request_t *req, nfsstat3 stat, struct statvfs *fsbuf,
- struct iatt *postbuf)
-{
- fsstat3res res = {0, };
- uint64_t deviceid = 0;
-
- deviceid = nfs3_request_xlator_deviceid (req);
- nfs3_fill_fsstat3res (&res, stat, fsbuf, postbuf, deviceid);
- return nfs3svc_submit_reply (req, &res,
- (nfs3_serializer)xdr_serialize_fsstat3res);
-
-}
-
-
-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)
-{
- 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_cbk_errno_status (op_ret, op_errno);
- } else
- stat = NFS3_OK;
-
- nfs3_log_common_res (rpcsvc_request_xid (cs->req), NFS3_FSSTAT, stat,
- op_errno);
- nfs3_fsstat_reply (cs->req, stat, &cs->fsstat, buf);
- nfs3_call_state_wipe (cs);
- return 0;
-}
-
-
-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)
-{
- nfs_user_t nfu = {0, };
- int ret = -EFAULT;
- 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));
- ret = -op_errno;
- stat = nfs3_cbk_errno_status (op_ret, op_errno);
- goto err;
- }
-
- /* Then get the stat for the fs root in order to fill in the
- * post_op_attr.
- */
- cs->fsstat = *buf;
- nfs_request_user_init (&nfu, cs->req);
- ret = nfs_stat (cs->nfsx, cs->vol, &nfu, &cs->resolvedloc,
- nfs3_fsstat_stat_cbk, cs);
- if (ret < 0)
- stat = nfs3_errno_to_nfsstat3 (-ret);
-
-err:
- if (ret < 0) {
- nfs3_log_common_res (rpcsvc_request_xid (cs->req), NFS3_FSSTAT,
- stat, -ret);
- nfs3_fsstat_reply (cs->req, stat, NULL, NULL);
- nfs3_call_state_wipe (cs);
- }
-
- return 0;
-}
-
-
-int
-nfs3_fsstat_resume (void *carg)
-{
- nfsstat3 stat = NFS3ERR_SERVERFAULT;
- int ret = -EFAULT;
- nfs3_call_state_t *cs = NULL;
- nfs_user_t nfu = {0, };
-
- if (!carg)
- return ret;
-
- cs = (nfs3_call_state_t *)carg;
- nfs3_check_fh_resolve_status (cs, stat, nfs3err);
- nfs_request_user_init (&nfu, cs->req);
- /* First, we need to get the statvfs for the subvol */
- ret = nfs_statfs (cs->nfsx, cs->vol, &nfu, &cs->resolvedloc,
- nfs3_fsstat_statfs_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_FSSTAT,
- stat, -ret);
- nfs3_fsstat_reply (cs->req, stat, NULL, NULL);
- nfs3_call_state_wipe (cs);
- }
-
- return ret;
-}
-
-
-
-int
-nfs3_fsstat (rpcsvc_request_t *req, struct nfs3_fh *fh)
-{
- xlator_t *vol = NULL;
- nfsstat3 stat = NFS3ERR_SERVERFAULT;
- int ret = -EFAULT;
- struct nfs3_state *nfs3 = NULL;
- nfs3_call_state_t *cs = NULL;
-
- if ((!req) || (!fh)) {
- gf_log (GF_NFS3, GF_LOG_ERROR, "Bad arguments");
- return -1;
- }
-
- nfs3_log_common_call (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);
- nfs3_volume_started_check (nfs3, vol, ret, out);
- nfs3_handle_call_state_init (nfs3, cs, req, vol, stat, nfs3err);
-
- ret = nfs3_fh_resolve_and_resume (cs, fh, NULL, nfs3_fsstat_resume);
- if (ret < 0)
- stat = nfs3_errno_to_nfsstat3 (-ret);
-
-nfs3err:
- if (ret < 0) {
- nfs3_log_common_res (rpcsvc_request_xid (req), NFS3_FSSTAT,
- stat, -ret);
- nfs3_fsstat_reply (req, stat, NULL, NULL);
- nfs3_call_state_wipe (cs);
- /* Ret must be 0 after this so that the caller does not
- * also send an RPC reply.
- */
- ret = 0;
- }
-out:
- return ret;
-}
-
-
-int
-nfs3svc_fsstat (rpcsvc_request_t *req)
-{
- struct nfs3_fh fh = {{0}, };
- fsstat3args args;
- int ret = RPCSVC_ACTOR_ERROR;
-
- if (!req)
- return ret;
- nfs3_prep_fsstat3args (&args, &fh);
- if (xdr_to_fsstat3args (req->msg[0], &args) <= 0) {
- gf_log (GF_NFS3, GF_LOG_ERROR, "Error decoding args");
- 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);
- ret = RPCSVC_ACTOR_ERROR;
- }
-
-rpcerr:
- return ret;
-}
-
-
-int
-nfs3_fsinfo_reply (rpcsvc_request_t *req, nfsstat3 status, struct iatt *fsroot)
-{
- fsinfo3res res;
- struct nfs3_state *nfs3 = NULL;
- uint64_t deviceid = 0;
-
- deviceid = nfs3_request_xlator_deviceid (req);
- nfs3 = rpcsvc_request_program_private (req);
- nfs3_fill_fsinfo3res (nfs3, &res, status, fsroot, deviceid);
-
- nfs3svc_submit_reply (req, &res,
- (nfs3_serializer)xdr_serialize_fsinfo3res);
- return 0;
-}
-
-
-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)
-{
- 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));
- status = nfs3_cbk_errno_status (op_ret, op_errno);
- }else
- status = NFS3_OK;
-
- nfs3_log_common_res (rpcsvc_request_xid (cs->req), NFS3_FSINFO, status,
- op_errno);
-
- nfs3_fsinfo_reply (cs->req, status, buf);
- nfs3_call_state_wipe (cs);
-
- return 0;
-}
-
-
-int
-nfs3_fsinfo_resume (void *carg)
-{
- nfsstat3 stat = NFS3ERR_SERVERFAULT;
- int ret = -EFAULT;
- nfs_user_t nfu = {0, };
- nfs3_call_state_t *cs = NULL;
-
-
- if (!carg)
- return ret;
-
- cs = (nfs3_call_state_t *)carg;
- nfs3_check_fh_resolve_status (cs, stat, nfs3err);
- nfs_request_user_init (&nfu, cs->req);
-
- ret = nfs_stat (cs->nfsx, cs->vol, &nfu, &cs->resolvedloc,
- nfs3svc_fsinfo_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_FSINFO,
- stat, -ret);
- nfs3_fsinfo_reply (cs->req, stat, NULL);
- nfs3_call_state_wipe (cs);
- }
-
- return ret;
-}
-
-
-int
-nfs3_fsinfo (rpcsvc_request_t *req, struct nfs3_fh *fh)
-{
- xlator_t *vol = NULL;
- nfsstat3 stat = NFS3ERR_SERVERFAULT;
- int ret = -EFAULT;
- struct nfs3_state *nfs3 = NULL;
- nfs3_call_state_t *cs = NULL;
-
- if ((!req) || (!fh)) {
- gf_log (GF_NFS3, GF_LOG_ERROR, "Bad arguments");
- return -1;
- }
-
- nfs3_log_common_call (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);
- nfs3_volume_started_check (nfs3, vol, ret, out);
- nfs3_handle_call_state_init (nfs3, cs, req, vol, stat, nfs3err);
-
- ret = nfs3_fh_resolve_and_resume (cs, fh, NULL, nfs3_fsinfo_resume);
- if (ret < 0)
- stat = nfs3_errno_to_nfsstat3 (-ret);
-
-nfs3err:
- if (ret < 0) {
- nfs3_log_common_res (rpcsvc_request_xid (req), NFS3_FSINFO,
- stat, -ret);
- nfs3_fsinfo_reply (req, stat, NULL);
- nfs3_call_state_wipe (cs);
- ret = 0;
- }
-out:
- return ret;
-}
-
-
-int
-nfs3svc_fsinfo (rpcsvc_request_t *req)
-{
- int ret = RPCSVC_ACTOR_ERROR;
- fsinfo3args args;
- struct nfs3_fh root = {{0}, };
-
- if (!req)
- return ret;
-
- nfs3_prep_fsinfo3args (&args, &root);
- if (xdr_to_fsinfo3args (req->msg[0], &args) <= 0) {
- gf_log (GF_NFS3, GF_LOG_ERROR, "Error decoding arguments");
- 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);
- ret = RPCSVC_ACTOR_ERROR;
- }
-
-rpcerr:
- return ret;
-}
-
-
-int
-nfs3_pathconf_reply (rpcsvc_request_t *req, nfsstat3 stat, struct iatt *buf)
-{
- pathconf3res res = {0, };
- uint64_t deviceid = 0;
-
- deviceid = nfs3_request_xlator_deviceid (req);
- nfs3_fill_pathconf3res (&res, stat, buf, deviceid);
- nfs3svc_submit_reply (req, (void *)&res,
- (nfs3_serializer)xdr_serialize_pathconf3res);
- return 0;
-}
-
-
-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)
-{
- 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));
- stat = nfs3_cbk_errno_status (op_ret, op_errno);
- } else {
- /* If stat fop failed, we can still send the other components
- * in a pathconf reply.
- */
- sbuf = buf;
- stat = NFS3_OK;
- }
-
- nfs3_log_common_res (rpcsvc_request_xid (cs->req), NFS3_PATHCONF, stat,
- op_errno);
- nfs3_pathconf_reply (cs->req, stat, sbuf);
- nfs3_call_state_wipe (cs);
-
- return 0;
-}
-
-
-int
-nfs3_pathconf_resume (void *carg)
-{
- nfsstat3 stat = NFS3ERR_SERVERFAULT;
- int ret = -EFAULT;
- nfs_user_t nfu = {0, };
- nfs3_call_state_t *cs = NULL;
-
- if (!carg)
- return ret;
-
- cs = (nfs3_call_state_t *)carg;
- nfs3_check_fh_resolve_status (cs, stat, nfs3err);
- nfs_request_user_init (&nfu, cs->req);
- ret = nfs_stat (cs->nfsx, cs->vol, &nfu, &cs->resolvedloc,
- nfs3svc_pathconf_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_PATHCONF, stat, -ret);
- nfs3_pathconf_reply (cs->req, stat, NULL);
- nfs3_call_state_wipe (cs);
- }
-
- return ret;
-}
-
-int
-nfs3_pathconf (rpcsvc_request_t *req, struct nfs3_fh *fh)
-{
- xlator_t *vol = NULL;
- nfsstat3 stat = NFS3ERR_SERVERFAULT;
- int ret = -EFAULT;
- struct nfs3_state *nfs3 = NULL;
- nfs3_call_state_t *cs = NULL;
-
- if ((!req) || (!fh)) {
- gf_log (GF_NFS3, GF_LOG_ERROR, "Bad arguments");
- return -1;
- }
-
- nfs3_log_common_call (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);
- nfs3_volume_started_check (nfs3, vol, ret, out);
- nfs3_handle_call_state_init (nfs3, cs, req, vol, stat, nfs3err);
-
- ret = nfs3_fh_resolve_and_resume (cs, fh, NULL, nfs3_pathconf_resume);
- if (ret < 0)
- stat = nfs3_errno_to_nfsstat3 (-ret);
-
-nfs3err:
- if (ret < 0) {
- nfs3_log_common_res (rpcsvc_request_xid (req), NFS3_PATHCONF,
- stat, -ret);
- nfs3_pathconf_reply (req, stat, NULL);
- nfs3_call_state_wipe (cs);
- /* Ret must be 0 after this so that the caller does not
- * also send an RPC reply.
- */
- ret = 0;
- }
-out:
- return ret;
-}
-
-
-int
-nfs3svc_pathconf (rpcsvc_request_t *req)
-{
- struct nfs3_fh fh = {{0}, };
- pathconf3args args;
- int ret = RPCSVC_ACTOR_ERROR;
-
- if (!req)
- return ret;
- nfs3_prep_pathconf3args (&args, &fh);
- if (xdr_to_pathconf3args (req->msg[0], &args) <= 0) {
- gf_log (GF_NFS3, GF_LOG_ERROR, "Error decoding args");
- 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);
- ret = RPCSVC_ACTOR_ERROR;
- }
-
-rpcerr:
- return ret;
-}
-
-int
-nfs3_commit_reply (rpcsvc_request_t *req, nfsstat3 stat, uint64_t wverf,
- struct iatt *prestat, struct iatt *poststat)
-{
- commit3res res = {0, };
- uint64_t deviceid = 0;
-
- deviceid = nfs3_request_xlator_deviceid (req);
- nfs3_fill_commit3res (&res, stat, wverf, prestat, poststat, deviceid);
- nfs3svc_submit_reply (req, (void *)&res,
- (nfs3_serializer)xdr_serialize_commit3res);
-
- return 0;
-}
-
-
-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)
-{
- 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));
- stat = nfs3_cbk_errno_status (op_ret, op_errno);
- } else
- stat = NFS3_OK;
-
- nfs3 = rpcsvc_request_program_private (cs->req);
- nfs3_log_commit_res (rpcsvc_request_xid (cs->req), stat, op_errno,
- nfs3->serverstart);
- nfs3_commit_reply (cs->req, stat, nfs3->serverstart, NULL, NULL);
- nfs3_call_state_wipe (cs);
-
- return 0;
-}
-
-int
-nfs3_commit_resume (void *carg)
-{
- nfsstat3 stat = NFS3ERR_SERVERFAULT;
- int ret = -EFAULT;
- nfs_user_t nfu = {0, };
- nfs3_call_state_t *cs = NULL;
-
- if (!carg)
- return ret;
-
- cs = (nfs3_call_state_t *)carg;
- nfs3_check_fh_resolve_status (cs, stat, nfs3err);
-
- if (nfs3_export_sync_trusted (cs->nfs3state, cs->resolvefh.exportid)) {
- ret = -1;
- stat = NFS3_OK;
- goto nfs3err;
- }
-
- nfs_request_user_init (&nfu, cs->req);
- ret = nfs_flush (cs->nfsx, cs->vol, &nfu, cs->fd,
- 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,
- stat, -ret);
- nfs3_commit_reply (cs->req, stat, cs->nfs3state->serverstart,
- NULL, NULL);
- nfs3_call_state_wipe (cs);
- ret = 0;
- }
-
- return 0;
-}
-
-
-int
-nfs3_commit_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);
- 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);
- if (ret < 0)
- stat = nfs3_errno_to_nfsstat3 (-ret);
-nfs3err:
- if (ret < 0) {
- nfs3_log_common_res (rpcsvc_request_xid (cs->req), NFS3_COMMIT,
- stat, -ret);
- nfs3_commit_reply (cs->req, stat, 0, NULL, NULL);
- nfs3_call_state_wipe (cs);
- }
-
- return ret;
-}
-
-
-
-int
-nfs3_commit (rpcsvc_request_t *req, struct nfs3_fh *fh, offset3 offset,
- count3 count)
-{
- xlator_t *vol = NULL;
- nfsstat3 stat = NFS3ERR_SERVERFAULT;
- int ret = -EFAULT;
- struct nfs3_state *nfs3 = NULL;
- nfs3_call_state_t *cs = NULL;
-
- if ((!req) || (!fh)) {
- gf_log (GF_NFS3, GF_LOG_ERROR, "Bad arguments");
- return -1;
- }
-
- nfs3_log_rw_call (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);
- nfs3_map_fh_to_volume (nfs3, fh, req, vol, stat, nfs3err);
- nfs3_volume_started_check (nfs3, vol, ret, out);
- nfs3_check_rw_volaccess (nfs3, fh->exportid, stat, nfs3err);
- nfs3_handle_call_state_init (nfs3, cs, req, vol, stat, nfs3err);
-
- cs->datacount = count;
- cs->dataoffset = offset;
- ret = nfs3_fh_resolve_and_resume (cs, fh, NULL,
- nfs3_commit_open_resume);
- if (ret < 0)
- stat = nfs3_errno_to_nfsstat3 (-ret);
-
-nfs3err:
- if (ret < 0) {
- nfs3_log_common_res (rpcsvc_request_xid (req), NFS3_COMMIT,
- stat, -ret);
- nfs3_commit_reply (req, stat, 0, NULL, NULL);
- nfs3_call_state_wipe (cs);
- ret = 0;
- }
-out:
- return ret;
-}
-
-
-
-int
-nfs3svc_commit (rpcsvc_request_t *req)
-{
- struct nfs3_fh fh = {{0}, };
- commit3args args;
- int ret = RPCSVC_ACTOR_ERROR;
-
- if (!req)
- return ret;
- nfs3_prep_commit3args (&args, &fh);
- if (xdr_to_commit3args (req->msg[0], &args) <= 0) {
- gf_log (GF_NFS3, GF_LOG_ERROR, "Error decoding args");
- 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);
- ret = RPCSVC_ACTOR_ERROR;
- }
-
-rpcerr:
- return ret;
-}
-
-
-rpcsvc_actor_t nfs3svc_actors[NFS3_PROC_COUNT] = {
- {"NULL", NFS3_NULL, nfs3svc_null, NULL, 0, DRC_IDEMPOTENT},
- {"GETATTR", NFS3_GETATTR, nfs3svc_getattr, NULL, 0, DRC_IDEMPOTENT},
- {"SETATTR", NFS3_SETATTR, nfs3svc_setattr, NULL, 0, DRC_NON_IDEMPOTENT},
- {"LOOKUP", NFS3_LOOKUP, nfs3svc_lookup, NULL, 0, DRC_IDEMPOTENT},
- {"ACCESS", NFS3_ACCESS, nfs3svc_access, NULL, 0, DRC_IDEMPOTENT},
- {"READLINK", NFS3_READLINK, nfs3svc_readlink, NULL, 0, DRC_IDEMPOTENT},
- {"READ", NFS3_READ, nfs3svc_read, NULL, 0, DRC_IDEMPOTENT},
- {"WRITE", NFS3_WRITE, nfs3svc_write, nfs3svc_write_vecsizer, 0, DRC_NON_IDEMPOTENT},
- {"CREATE", NFS3_CREATE, nfs3svc_create, NULL, 0, DRC_NON_IDEMPOTENT},
- {"MKDIR", NFS3_MKDIR, nfs3svc_mkdir, NULL, 0, DRC_NON_IDEMPOTENT},
- {"SYMLINK", NFS3_SYMLINK, nfs3svc_symlink, NULL, 0, DRC_NON_IDEMPOTENT},
- {"MKNOD", NFS3_MKNOD, nfs3svc_mknod, NULL, 0, DRC_NON_IDEMPOTENT},
- {"REMOVE", NFS3_REMOVE, nfs3svc_remove, NULL, 0, DRC_NON_IDEMPOTENT},
- {"RMDIR", NFS3_RMDIR, nfs3svc_rmdir, NULL, 0, DRC_NON_IDEMPOTENT},
- {"RENAME", NFS3_RENAME, nfs3svc_rename, NULL, 0, DRC_NON_IDEMPOTENT},
- {"LINK", NFS3_LINK, nfs3svc_link, NULL, 0, DRC_NON_IDEMPOTENT},
- {"READDIR", NFS3_READDIR, nfs3svc_readdir, NULL, 0, DRC_IDEMPOTENT},
- {"READDIRPLUS", NFS3_READDIRP, nfs3svc_readdirp, NULL, 0, DRC_IDEMPOTENT},
- {"FSSTAT", NFS3_FSSTAT, nfs3svc_fsstat, NULL, 0, DRC_IDEMPOTENT},
- {"FSINFO", NFS3_FSINFO, nfs3svc_fsinfo, NULL, 0, DRC_IDEMPOTENT},
- {"PATHCONF", NFS3_PATHCONF, nfs3svc_pathconf, NULL, 0, DRC_IDEMPOTENT},
- {"COMMIT", NFS3_COMMIT, nfs3svc_commit, NULL, 0, DRC_IDEMPOTENT}
-};
-
-
-rpcsvc_program_t nfs3prog = {
- .progname = "NFS3",
- .prognum = NFS_PROGRAM,
- .progver = NFS_V3,
- .progport = GF_NFS3_PORT,
- .actors = nfs3svc_actors,
- .numactors = NFS3_PROC_COUNT,
-
- /* Requests like FSINFO are sent before an auth scheme
- * is inited by client. See RFC 2623, Section 2.3.2. */
- .min_auth = AUTH_NULL,
-};
-
-/*
- * This function rounds up the input value to multiple of 4096. Min and Max
- * supported I/O size limits are 4KB (GF_NFS3_FILE_IO_SIZE_MIN) and
- * 1MB (GF_NFS3_FILE_IO_SIZE_MAX).
- */
-void
-nfs3_iosize_roundup_4KB (uint64_t *ioszptr)
-{
- uint64_t iosize;
- uint64_t iopages;
-
- if (!ioszptr)
- return;
-
- iosize = *ioszptr;
- iopages = (iosize + GF_NFS3_IO_SIZE -1) >> GF_NFS3_IO_SHIFT;
- iosize = (iopages * GF_NFS3_IO_SIZE);
-
- /* Double check - boundary conditions */
- if (iosize < GF_NFS3_FILE_IO_SIZE_MIN) {
- iosize = GF_NFS3_FILE_IO_SIZE_MIN;
- } else if (iosize > GF_NFS3_FILE_IO_SIZE_MAX) {
- iosize = GF_NFS3_FILE_IO_SIZE_MAX;
- }
-
- *ioszptr = iosize;
-}
-
-int
-nfs3_init_options (struct nfs3_state *nfs3, dict_t *options)
-{
- int ret = -1;
- char *optstr = NULL;
- uint64_t size64 = 0;
-
- if ((!nfs3) || (!options))
- return -1;
-
- /* nfs3.read-size */
- nfs3->readsize = GF_NFS3_RTPREF;
- if (dict_get (options, "nfs3.read-size")) {
- ret = dict_get_str (options, "nfs3.read-size", &optstr);
- if (ret < 0) {
- gf_log (GF_NFS3, GF_LOG_ERROR, "Failed to read "
- " option: nfs3.read-size");
- ret = -1;
- goto err;
- }
-
- ret = gf_string2uint64 (optstr, &size64);
- if (ret == -1) {
- gf_log (GF_NFS3, GF_LOG_ERROR, "Failed to format"
- " option: nfs3.read-size");
- ret = -1;
- goto err;
- }
-
- nfs3_iosize_roundup_4KB (&size64);
- nfs3->readsize = size64;
- }
-
- /* nfs3.write-size */
- nfs3->writesize = GF_NFS3_WTPREF;
- if (dict_get (options, "nfs3.write-size")) {
- ret = dict_get_str (options, "nfs3.write-size", &optstr);
- if (ret < 0) {
- gf_log (GF_NFS3, GF_LOG_ERROR, "Failed to read "
- " option: nfs3.write-size");
- ret = -1;
- goto err;
- }
-
- ret = gf_string2uint64 (optstr, &size64);
- if (ret == -1) {
- gf_log (GF_NFS3, GF_LOG_ERROR, "Failed to format"
- " option: nfs3.write-size");
- ret = -1;
- goto err;
- }
-
- nfs3_iosize_roundup_4KB (&size64);
- nfs3->writesize = size64;
- }
-
- /* nfs3.readdir.size */
- nfs3->readdirsize = GF_NFS3_DTPREF;
- if (dict_get (options, "nfs3.readdir-size")) {
- ret = dict_get_str (options,"nfs3.readdir-size", &optstr);
- if (ret < 0) {
- gf_log (GF_NFS3, GF_LOG_ERROR, "Failed to read"
- " option: nfs3.readdir-size");
- ret = -1;
- goto err;
- }
-
- ret = gf_string2uint64 (optstr, &size64);
- if (ret == -1) {
- gf_log (GF_NFS3, GF_LOG_ERROR, "Failed to format"
- " option: nfs3.readdir-size");
- ret = -1;
- goto err;
- }
-
- nfs3_iosize_roundup_4KB (&size64);
- nfs3->readdirsize = size64;
- }
-
- /* We want to use the size of the biggest param for the io buffer size.
- */
- nfs3->iobsize = nfs3->readsize;
- if (nfs3->iobsize < nfs3->writesize)
- nfs3->iobsize = nfs3->writesize;
- if (nfs3->iobsize < nfs3->readdirsize)
- 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. */
- nfs3->iobsize = nfs3->iobsize * 2;
-
- ret = 0;
-err:
- return ret;
-}
-
-int
-nfs3_init_subvolume_options (xlator_t *nfsx,
- struct nfs3_export *exp,
- dict_t *options)
-{
- int ret = -1;
- char *optstr = NULL;
- char searchkey[1024];
- char *name = NULL;
- gf_boolean_t boolt = _gf_false;
- uuid_t volumeid = {0, };
-
- if ((!nfsx) || (!exp))
- return -1;
-
- /* For init, fetch options from xlator but for
- * reconfigure, take the parameter */
- if (!options)
- options = nfsx->options;
-
- if (!options)
- return (-1);
-
- uuid_clear (volumeid);
- if (gf_nfs_dvm_off (nfs_state (nfsx)))
- goto no_dvm;
-
- ret = snprintf (searchkey, 1024, "nfs3.%s.volume-id",exp->subvol->name);
- if (ret < 0) {
- gf_log (GF_MNT, GF_LOG_ERROR, "snprintf failed");
- ret = -1;
- goto err;
- }
-
- if (dict_get (options, searchkey)) {
- ret = dict_get_str (options, searchkey, &optstr);
- if (ret < 0) {
- gf_log (GF_MNT, GF_LOG_ERROR, "Failed to read option"
- ": %s", searchkey);
- ret = -1;
- goto err;
- }
- } else {
- gf_log (GF_MNT, GF_LOG_ERROR, "DVM is on but volume-id not "
- "given for volume: %s", exp->subvol->name);
- ret = -1;
- goto err;
- }
-
- if (optstr) {
- ret = uuid_parse (optstr, volumeid);
- if (ret < 0) {
- gf_log (GF_MNT, GF_LOG_ERROR, "Failed to parse volume "
- "UUID");
- ret = -1;
- goto err;
- }
- uuid_copy (exp->volumeid, volumeid);
- }
-
-no_dvm:
- /* Volume Access */
- name = exp->subvol->name;
- ret = snprintf (searchkey, 1024, "nfs3.%s.volume-access", name);
- if (ret < 0) {
- gf_log (GF_NFS3, GF_LOG_ERROR, "snprintf failed");
- ret = -1;
- goto err;
- }
-
- exp->access = GF_NFS3_DEFAULT_VOLACCESS;
- if (dict_get (options, searchkey)) {
- ret = dict_get_str (options, searchkey, &optstr);
- if (ret < 0) {
- gf_log (GF_NFS3, GF_LOG_ERROR, "Failed to read "
- " option: %s", searchkey);
- ret = -1;
- goto err;
- }
-
- if (strcmp (optstr, "read-only") == 0)
- exp->access = GF_NFS3_VOLACCESS_RO;
- }
-
- ret = snprintf (searchkey, 1024, "rpc-auth.%s.unix", name);
- if (ret < 0) {
- gf_log (GF_NFS3, GF_LOG_ERROR, "snprintf failed");
- ret = -1;
- goto err;
- }
-
- if (dict_get (options, searchkey)) {
- ret = dict_get_str (options, searchkey, &optstr);
- if (ret < 0) {
- gf_log (GF_NFS3, GF_LOG_ERROR, "Failed to read "
- " option: %s", searchkey);
- ret = -1;
- goto err;
- }
- }
-
- exp->trusted_sync = 0;
- ret = snprintf (searchkey, 1024, "nfs3.%s.trusted-sync", name);
- if (ret < 0) {
- gf_log (GF_NFS3, GF_LOG_ERROR, "snprintf failed");
- ret = -1;
- goto err;
- }
-
- if (dict_get (options, searchkey)) {
- ret = dict_get_str (options, searchkey, &optstr);
- if (ret < 0) {
- gf_log (GF_NFS3, GF_LOG_ERROR, "Failed to read "
- " option: %s", searchkey);
- ret = -1;
- goto err;
- }
-
- ret = gf_string2boolean (optstr, &boolt);
- if (ret < 0) {
- gf_log (GF_NFS3, GF_LOG_ERROR, "Failed to convert str "
- "to gf_boolean_t");
- ret = -1;
- goto err;
- }
-
- if (boolt == _gf_true)
- exp->trusted_sync = 1;
- }
-
- exp->trusted_write = 0;
- ret = snprintf (searchkey, 1024, "nfs3.%s.trusted-write", name);
- if (ret < 0) {
- gf_log (GF_NFS3, GF_LOG_ERROR, "snprintf failed");
- ret = -1;
- goto err;
- }
-
- if (dict_get (options, searchkey)) {
- ret = dict_get_str (options, searchkey, &optstr);
- if (ret < 0) {
- gf_log (GF_NFS3, GF_LOG_ERROR, "Failed to read "
- " option: %s", searchkey);
- ret = -1;
- goto err;
- }
-
- ret = gf_string2boolean (optstr, &boolt);
- if (ret < 0) {
- gf_log (GF_NFS3, GF_LOG_ERROR, "Failed to convert str "
- "to gf_boolean_t");
- ret = -1;
- goto err;
- }
-
- if (boolt == _gf_true)
- exp->trusted_write = 1;
- }
-
- /* If trusted-sync is on, then we also switch on trusted-write because
- * tw is included in ts. In write logic, we're then only checking for
- * tw.
- */
- if (exp->trusted_sync)
- exp->trusted_write = 1;
-
- gf_log (GF_NFS3, GF_LOG_TRACE, "%s: %s, %s, %s", exp->subvol->name,
- (exp->access == GF_NFS3_VOLACCESS_RO)?"read-only":"read-write",
- (exp->trusted_sync == 0)?"no trusted_sync":"trusted_sync",
- (exp->trusted_write == 0)?"no trusted_write":"trusted_write");
- ret = 0;
-err:
- return ret;
-}
-
-
-struct nfs3_export *
-nfs3_init_subvolume (struct nfs3_state *nfs3, xlator_t *subvol)
-{
- int ret = -1;
- struct nfs3_export *exp = NULL;
-
- if ((!nfs3) || (!subvol))
- return NULL;
-
- exp = GF_CALLOC (1, sizeof (*exp), gf_nfs_mt_nfs3_export);
- exp->subvol = subvol;
- INIT_LIST_HEAD (&exp->explist);
- gf_log (GF_NFS3, GF_LOG_TRACE, "Initing state: %s", exp->subvol->name);
-
- ret = nfs3_init_subvolume_options (nfs3->nfsx, exp, NULL);
- if (ret == -1) {
- gf_log (GF_NFS3, GF_LOG_ERROR, "Failed to init subvol");
- goto exp_free;
- }
-
- ret = 0;
-exp_free:
- if (ret < 0) {
- GF_FREE (exp);
- exp = NULL;
- }
-
- return exp;
-}
-
-
-int
-nfs3_init_subvolumes (struct nfs3_state *nfs3)
-{
- int ret = -1;
- struct xlator_list *xl_list = NULL;
- struct nfs3_export *exp = NULL;
-
- if (!nfs3)
- return -1;
-
- xl_list = nfs3->nfsx->children;
-
- while (xl_list) {
- exp = nfs3_init_subvolume (nfs3, xl_list->xlator);
- if (!exp) {
- gf_log (GF_NFS3, GF_LOG_ERROR, "Failed to init subvol: "
- "%s", xl_list->xlator->name);
- goto err;
- }
- list_add_tail (&exp->explist, &nfs3->exports);
- xl_list = xl_list->next;
- }
-
- ret = 0;
-err:
- return ret;
-}
-
-
-struct nfs3_state *
-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) || (!nfsx->private))
- return NULL;
-
- nfs3 = (struct nfs3_state *)GF_CALLOC (1, sizeof (*nfs3),
- gf_nfs_mt_nfs3_state);
- if (!nfs3) {
- gf_log (GF_NFS3, GF_LOG_ERROR, "Memory allocation failed");
- return NULL;
- }
-
- nfs = nfsx->private;
- ret = nfs3_init_options (nfs3, nfsx->options);
- if (ret == -1) {
- gf_log (GF_NFS3, GF_LOG_ERROR, "Failed to init options");
- goto ret;
- }
-
- nfs3->iobpool = nfsx->ctx->iobuf_pool;
-
- localpool = nfs->memfactor * GF_NFS_CONCURRENT_OPS_MULT;
- gf_log (GF_NFS3, GF_LOG_TRACE, "local pool: %d", localpool);
- nfs3->localpool = mem_pool_new (nfs3_call_state_t, localpool);
- if (!nfs3->localpool) {
- gf_log (GF_NFS3, GF_LOG_ERROR, "local mempool creation failed");
- ret = -1;
- goto ret;
- }
-
- nfs3->nfsx = nfsx;
- nfs3->exportslist = nfsx->children;
- INIT_LIST_HEAD (&nfs3->exports);
- ret = nfs3_init_subvolumes (nfs3);
- if (ret == -1) {
- gf_log (GF_NFS3, GF_LOG_ERROR, "Failed to init per-subvolume "
- "state");
- goto free_localpool;
- }
-
- nfs3->serverstart = (uint64_t)time (NULL);
- INIT_LIST_HEAD (&nfs3->fdlru);
- LOCK_INIT (&nfs3->fdlrulock);
- nfs3->fdcount = 0;
-
- ret = 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:
- if (ret == -1)
- mem_pool_destroy (nfs3->localpool);
-
-ret:
- if (ret == -1) {
- GF_FREE (nfs3);
- nfs3 = NULL;
- }
-
- return nfs3;
-}
-
-
-rpcsvc_program_t *
-nfs3svc_init (xlator_t *nfsx)
-{
- struct nfs3_state *nfs3 = NULL;
-
- if (!nfsx)
- return NULL;
-
- nfs3 = nfs3_init_state (nfsx);
- if (!nfs3) {
- gf_log (GF_NFS3, GF_LOG_ERROR, "NFSv3 state init failed");
- return NULL;
- }
-
- nfs3prog.private = nfs3;
-
- return &nfs3prog;
-}
-
-int
-nfs3_reconfigure_state (xlator_t *nfsx, dict_t *options)
-{
- int ret = -1;
- struct nfs3_export *exp = NULL;
- struct nfs_state *nfs = NULL;
- struct nfs3_state *nfs3 = NULL;
-
- if ((!nfsx) || (!nfsx->private) || (!options))
- goto out;
-
- nfs = (struct nfs_state *)nfsx->private;
- nfs3 = nfs->nfs3state;
- if (!nfs3)
- goto out;
-
- ret = nfs3_init_options (nfs3, options);
- if (ret) {
- gf_log (GF_NFS3, GF_LOG_ERROR,
- "Failed to reconfigure options");
- goto out;
- }
-
- list_for_each_entry (exp, &nfs3->exports, explist) {
- ret = nfs3_init_subvolume_options (nfsx, exp, options);
- if (ret) {
- gf_log (GF_NFS3, GF_LOG_ERROR,
- "Failed to reconfigure subvol options");
- goto out;
- }
- }
-
- ret = 0;
-out:
- return ret;
-}
diff --git a/xlators/nfs/server/src/nfs3.h b/xlators/nfs/server/src/nfs3.h
deleted file mode 100644
index e64ef9d1591..00000000000
--- a/xlators/nfs/server/src/nfs3.h
+++ /dev/null
@@ -1,287 +0,0 @@
-/*
- Copyright (c) 2010-2011 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.
-*/
-
-#ifndef _NFS3_H_
-#define _NFS3_H_
-
-#ifndef _CONFIG_H
-#define _CONFIG_H
-#include "config.h"
-#endif
-
-#include "rpcsvc.h"
-#include "dict.h"
-#include "xlator.h"
-#include "iobuf.h"
-#include "nfs.h"
-#include "nfs3-fh.h"
-#include "nfs-common.h"
-#include "xdr-nfs3.h"
-#include "mem-pool.h"
-#include "nlm4.h"
-#include "acl3-xdr.h"
-#include "acl3.h"
-#include <sys/statvfs.h>
-
-#define GF_NFS3 GF_NFS"-nfsv3"
-
-#define GF_NFS3_DEFAULT_MEMFACTOR 15
-#define GF_NFS3_IOBPOOL_MULT GF_NFS_CONCURRENT_OPS_MULT
-#define GF_NFS3_CLTABLE_BUCKETS_MULT 2
-#define GF_NFS3_FDTABLE_BUCKETS_MULT 2
-
-
-/* Static values used for FSINFO
- * To change the maximum rsize and wsize supported by the NFS client, adjust
- * GF_NFS3_FILE_IO_SIZE_MAX. The Gluster NFS server defaults to 1MB(1048576)
- * (same as kernel NFS server). For slower network, rsize/wsize can be trimmed
- * to 16/32/64-KB. rsize and wsize can be tuned through nfs.read-size and
- * nfs.write-size respectively.
- *
- * NB: For Kernel-NFS, NFS_MAX_FILE_IO_SIZE is 1048576U (1MB).
- */
-#define GF_NFS3_FILE_IO_SIZE_MAX (1 * GF_UNIT_MB) /* 1048576 */
-#define GF_NFS3_FILE_IO_SIZE_MIN (4 * GF_UNIT_KB) /* 4096 */
-
-#define GF_NFS3_FILE_IO_SIZE_DEF GF_NFS3_FILE_IO_SIZE_MAX
-
-#define GF_NFS3_RTMAX GF_NFS3_FILE_IO_SIZE_MAX
-#define GF_NFS3_RTMIN GF_NFS3_FILE_IO_SIZE_MIN
-#define GF_NFS3_RTPREF GF_NFS3_FILE_IO_SIZE_DEF
-#define GF_NFS3_RTMULT GF_NFS3_FILE_IO_SIZE_MIN
-
-#define GF_NFS3_WTMAX GF_NFS3_FILE_IO_SIZE_MAX
-#define GF_NFS3_WTMIN GF_NFS3_FILE_IO_SIZE_MIN
-#define GF_NFS3_WTPREF GF_NFS3_FILE_IO_SIZE_DEF
-#define GF_NFS3_WTMULT GF_NFS3_FILE_IO_SIZE_MIN
-
-/* This can be tuned through nfs.readdir-size */
-#define GF_NFS3_DTMAX GF_NFS3_FILE_IO_SIZE_MAX
-#define GF_NFS3_DTMIN GF_NFS3_FILE_IO_SIZE_MIN
-#define GF_NFS3_DTPREF GF_NFS3_FILE_IO_SIZE_DEF
-
-#define GF_NFS3_MAXFILESIZE (1 * GF_UNIT_PB)
-
-#define GF_NFS3_IO_SIZE 4096 /* 4-KB */
-#define GF_NFS3_IO_SHIFT 12 /* 2^12 = 4KB */
-
-/* FIXME: Handle time resolutions */
-#define GF_NFS3_TIMEDELTA_SECS {1,0}
-#define GF_NFS3_TIMEDELTA_NSECS {0,1}
-#define GF_NFS3_TIMEDELTA_MSECS {0,1000000}
-
-#define GF_NFS3_FS_PROP (FSF3_LINK | FSF3_SYMLINK | FSF3_HOMOGENEOUS | FSF3_CANSETTIME)
-
-#define GF_NFS3_DIRFD_VALID 1
-#define GF_NFS3_DIRFD_INVALID 0
-
-#define GF_NFS3_VOLACCESS_RW 1
-#define GF_NFS3_VOLACCESS_RO 2
-
-
-#define GF_NFS3_FDCACHE_SIZE 512
-/* This should probably be moved to a more generic layer so that if needed
- * different versions of NFS protocol can use the same thing.
- */
-struct nfs3_fd_entry {
- fd_t *cachedfd;
- struct list_head list;
-};
-
-/* Per subvolume nfs3 specific state */
-struct nfs3_export {
- struct list_head explist;
- xlator_t *subvol;
- uuid_t volumeid;
- int access;
- int trusted_sync;
- int trusted_write;
- int rootlookedup;
-};
-
-#define GF_NFS3_DEFAULT_VOLACCESS (GF_NFS3_VOLACCESS_RW)
-
-/* The NFSv3 protocol state */
-typedef struct nfs3_state {
-
- /* The NFS xlator pointer. The NFS xlator can be running
- * multiple versions of the NFS protocol.
- */
- xlator_t *nfsx;
-
- /* The iob pool from which memory allocations are made for receiving
- * and sending network messages.
- */
- struct iobuf_pool *iobpool;
-
- /* List of child subvolumes for the NFSv3 protocol.
- * Right now, is simply referring to the list of children in nfsx above.
- */
- xlator_list_t *exportslist;
-
- struct list_head exports;
- /* Mempool for allocations of struct nfs3_local */
- struct mem_pool *localpool;
-
- /* Server start-up timestamp, currently used for write verifier. */
- uint64_t serverstart;
-
- /* NFSv3 Protocol configurables */
- uint64_t readsize;
- uint64_t writesize;
- uint64_t readdirsize;
-
- /* Size of the iobufs used, depends on the sizes of the three params
- * above.
- */
- uint64_t iobsize;
-
- struct list_head fdlru;
- gf_lock_t fdlrulock;
- int fdcount;
- uint32_t occ_logger;
-} 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;
- getaclargs getaclargs;
- setaclargs setaclargs;
- getaclreply getaclreply;
- setaclreply setaclreply;
-} 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
- * dependent.
- *
- * I wish we could have a smaller structure for communicating state
- * between callers and callbacks. It could be broken into smaller parts
- * but I feel that will lead to a proliferation of types/structures and then
- * we'll just be tracking down which structure is used by which fop, not
- * to mention that having one type allows me to used a single mem-pool.
- * Imagine the chaos if we need a mem-pool for each one of those sub-structures.
- */
-struct nfs3_local {
- rpcsvc_request_t *req;
- xlator_t *vol;
- nfs3_resume_fn_t resume_fn;
- xlator_t *nfsx;
- struct nfs3_state *nfs3state;
-
- /* The list hook to attach this call state to the inode's queue till
- * the opening of the fd on the inode completes.
- */
- struct list_head openwait_q;
-
- /* Per-NFSv3 Op state */
- struct nfs3_fh parent;
- struct nfs3_fh fh;
- fd_t *fd;
- uint32_t accessbits;
- int operrno;
- count3 dircount;
- count3 maxcount;
- struct statvfs fsstat;
- gf_dirent_t entries;
- struct iatt stbuf;
- struct iatt preparent;
- struct iatt postparent;
- int32_t setattr_valid;
- nfstime3 timestamp;
- loc_t oploc;
- int writetype;
- count3 datacount;
- offset3 dataoffset;
- struct iobuf *iob;
- struct iobref *iobref;
- createmode3 createmode;
- uint64_t cookieverf;
- int sattrguardcheck;
- char *pathname;
- ftype3 mknodtype;
- specdata3 devnums;
- cookie3 cookie;
- struct iovec datavec;
- mode_t mode;
-
- /* NFSv3 FH resolver state */
- int hardresolved;
- struct nfs3_fh resolvefh;
- loc_t resolvedloc;
- int resolve_ret;
- int resolve_errno;
- int hashidx;
- 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;
-
- /* ACL */
- aclentry aclentry[NFS_ACL_MAX_ENTRIES];
- aclentry daclentry[NFS_ACL_MAX_ENTRIES];
- int aclcount;
- char aclxattr[NFS_ACL_MAX_ENTRIES*8 + 4];
- int daclcount;
- char daclxattr[NFS_ACL_MAX_ENTRIES*8 + 4];
-};
-
-#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)
-
-typedef struct nfs3_local nfs3_call_state_t;
-
-/* Queue of ops waiting for open fop to return. */
-struct inode_op_queue {
- struct list_head opq;
- pthread_mutex_t qlock;
-};
-
-extern rpcsvc_program_t *
-nfs3svc_init (xlator_t *nfsx);
-
-extern int
-nfs3_reconfigure_state (xlator_t *nfsx, dict_t *options);
-
-extern uint64_t
-nfs3_request_xlator_deviceid (rpcsvc_request_t *req);
-
-#endif
diff --git a/xlators/nfs/server/src/nlm4.c b/xlators/nfs/server/src/nlm4.c
deleted file mode 100644
index 4d0083fe2c5..00000000000
--- a/xlators/nfs/server/src/nlm4.c
+++ /dev/null
@@ -1,2546 +0,0 @@
-/*
- Copyright (c) 2012 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.
-*/
-
-#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 "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); \
- snprintf (buf, sizeof (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.nlm4_netobj_val = (void *)fh;
- args->alock.oh.nlm4_netobj_val = (void *)oh;
- args->cookie.nlm4_netobj_val = (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.nlm4_netobj_val = (void *)fh;
- args->alock.oh.nlm4_netobj_val = (void *)oh;
- args->cookie.nlm4_netobj_val = (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.nlm4_netobj_val = (void *)fh;
- args->alock.oh.nlm4_netobj_val = (void *)oh;
- args->cookie.nlm4_netobj_val = (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.nlm4_netobj_val = (void *)fh;
- args->alock.oh.nlm4_netobj_val = (void *)oh;
- args->cookie.nlm4_netobj_val = (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.nlm4_netobj_val = (void *)fh;
- args->share.oh.nlm4_netobj_val = (void *)oh;
- args->cookie.nlm4_netobj_val = (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, nlm4_netobj *src)
-{
- dst->len = src->nlm4_netobj_len;
- memcpy (dst->data, src->nlm4_netobj_val, dst->len);
-}
-
-int
-nlm_is_oh_same_lkowner (gf_lkowner_t *a, nlm4_netobj *b)
-{
- if (!a || !b) {
- gf_log (GF_NLM, GF_LOG_ERROR, "invalid args");
- return -1;
- }
-
- return (a->len == b->nlm4_netobj_len &&
- !memcmp (a->data, b->nlm4_netobj_val, a->len));
-}
-
-nlm4_stats
-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)
- 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;
- ssize_t msglen = 0;
- 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.
- */
- msglen = sfunc (outmsg, arg);
- if (msglen < 0) {
- gf_log (GF_NLM, GF_LOG_ERROR, "Failed to encode message");
- goto ret;
- }
- outmsg.iov_len = msglen;
-
- iobref = iobref_new ();
- if (iobref == NULL) {
- gf_log (GF_NLM, GF_LOG_ERROR, "Failed to get iobref");
- goto ret;
- }
-
- ret = iobref_add (iobref, iob);
- if (ret) {
- gf_log (GF_NLM, GF_LOG_ERROR, "Failed to add iob to iobref");
- goto ret;
- }
-
- /* 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;
- int flags = 0;
- nlm_client_t *nlmclnt = NULL;
- call_frame_t *frame = NULL;
-
- if (cs->args.nlm4_lockargs.exclusive == _gf_false)
- flags = O_RDONLY;
- else
- flags = O_WRONLY;
-
- 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 = rpcsvc_request_uid (cs->req);
- frame->root->gid = rpcsvc_request_gid (cs->req);
- frame->local = cs;
- nfs_fix_groups (cs->nfsx, frame->root);
-
- STACK_WIND_COOKIE (frame, nlm4_file_open_cbk, cs->vol, cs->vol,
- cs->vol->fops->open, &cs->resolvedloc, flags,
- cs->fd, NULL);
- ret = 0;
-err:
- return ret;
-}
-
-int
-nlm4_generic_reply (rpcsvc_request_t *req, nlm4_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;
-}
-
-void
-nlm4svc_send_granted (nfs3_call_state_t *cs);
-
-int
-nlm_rpcclnt_notify (struct rpc_clnt *rpc_clnt, void *mydata,
- rpc_clnt_event_t fn, void *data)
-{
- int ret = 0;
- char *caller_name = NULL;
- nfs3_call_state_t *cs = NULL;
-
- cs = mydata;
- caller_name = cs->args.nlm4_lockargs.alock.caller_name;
-
- switch (fn) {
- case RPC_CLNT_CONNECT:
- ret = nlm_set_rpc_clnt (rpc_clnt, caller_name);
- if (ret == -1) {
- gf_log (GF_NLM, GF_LOG_ERROR, "Failed to set rpc clnt");
- goto err;
- }
- rpc_clnt_unref (rpc_clnt);
- nlm4svc_send_granted (cs);
-
- break;
-
- case RPC_CLNT_MSG:
- break;
-
- case RPC_CLNT_DISCONNECT:
- nlm_unset_rpc_clnt (rpc_clnt);
- break;
- default:
- break;
- }
-
- err:
- return 0;
-}
-
-void *
-nlm4_establish_callback (void *csarg)
-{
- int ret = -1;
- nfs3_call_state_t *cs = NULL;
- union gf_sock_union sock_union;
- dict_t *options = NULL;
- char peerip[INET6_ADDRSTRLEN+1] = {0};
- char *portstr = NULL;
- char myip[INET6_ADDRSTRLEN+1] = {0};
- rpc_clnt_t *rpc_clnt = NULL;
- int port = -1;
-
-
- cs = (nfs3_call_state_t *) csarg;
- glusterfs_this_set (cs->nfsx);
-
- rpc_transport_get_peeraddr (cs->trans, NULL, 0, &sock_union.storage,
- sizeof (sock_union.storage));
-
- switch (sock_union.sa.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, &sock_union.sin.sin_addr, peerip,
- INET6_ADDRSTRLEN+1);
- inet_ntop (AF_INET, &(((struct sockaddr_in *)&cs->trans->myinfo.sockaddr)->sin_addr),
- myip, INET6_ADDRSTRLEN + 1);
-
- break;
- default:
- break;
- /* FIXME: handle the error */
- }
-
- /* looks like libc rpc supports only ipv4 */
- port = pmap_getport (&sock_union.sin, 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?"
- " OR Are RPC services running (rpcinfo -p)?");
- 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;
- }
-
- /* needed in case virtual IP is used */
- ret = dict_set_dynstr (options, "transport.socket.source-addr",
- gf_strdup (myip));
- if (ret == -1)
- 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;
- }
-
- ret = rpc_clnt_register_notify (rpc_clnt, nlm_rpcclnt_notify, cs);
- if (ret == -1) {
- gf_log (GF_NLM, GF_LOG_ERROR,"rpc_clnt_register_connect error");
- goto err;
- }
-
- /* After this connect succeeds, granted msg is sent in notify */
- ret = rpc_transport_connect (rpc_clnt->conn.trans, port);
-
- if (ret == -1 && EINPROGRESS == errno)
- ret = 0;
-
-err:
- if (ret == -1 && rpc_clnt) {
- rpc_clnt_unref (rpc_clnt);
- }
-
- return rpc_clnt;
-}
-
-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];
- union gf_sock_union sock_union;
-
- rpc_clnt = nlm_get_rpc_clnt (cs->args.nlm4_lockargs.alock.caller_name);
- if (rpc_clnt == NULL) {
- nlm4_establish_callback ((void*)cs);
- return;
- }
-
- rpc_transport_get_peeraddr (cs->trans, NULL, 0, &sock_union.storage,
- sizeof (sock_union.storage));
-
- switch (sock_union.sa.sa_family) {
- case AF_INET6:
- inet_ntop (AF_INET6, &sock_union.sin6.sin6_addr, peerip,
- INET6_ADDRSTRLEN+1);
- break;
- case AF_INET:
- inet_ntop (AF_INET, &sock_union.sin.sin_addr, peerip,
- INET6_ADDRSTRLEN+1);
- break;
- default:
- break;
- }
-
- 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;
- }
-
- ret = iobref_add (iobref, iobuf);
- if (ret) {
- gf_log (GF_NLM, GF_LOG_ERROR, "Failed to add iob to iobref");
- goto ret;
- }
-
- 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);
- frame->local = NULL;
- 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;
- struct nfs_inode_ctx *ictx = NULL;
- struct nfs_state *priv = NULL;
-
- this = THIS;
- priv = this->private;
- inode = share->inode;
- ret = inode_ctx_get (inode, this, &ctx);
-
- if (ret == -1) {
- ictx = GF_CALLOC (1, sizeof (struct nfs_inode_ctx),
- gf_nfs_mt_inode_ctx);
- if (!ictx ) {
- gf_log (this->name, GF_LOG_ERROR,
- "could not allocate nfs inode ctx");
- ret = -1;
- goto out;
- }
- ictx->generation = priv->generation;
-
- head = &ictx->shares;
- INIT_LIST_HEAD (head);
-
- ret = inode_ctx_put (inode, this, (uint64_t)ictx);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "could not store share list");
- goto out;
- }
- }
- else {
- ictx = (struct nfs_inode_ctx *)ctx;
- head = &ictx->shares;
- }
-
- 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;
- struct nfs_inode_ctx *ictx = NULL;
-
- if (!cs)
- goto out;
-
- inode = cs->resolvedloc.inode;
-
- ret = inode_ctx_get (inode, THIS, &ctx);
- if (ret) {
- ret = 0;
- goto out;
- }
- ictx = (struct nfs_inode_ctx *)ctx;
-
- head = &ictx->shares;
- 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;
- struct nfs_inode_ctx *ictx = 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;
- }
- ictx = (struct nfs_inode_ctx *)ctx;
-
- head = &ictx->shares;
- 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, 0, DRC_IDEMPOTENT},
- {"TEST", NLM4_TEST, nlm4svc_test, NULL, 0, DRC_IDEMPOTENT},
- {"LOCK", NLM4_LOCK, nlm4svc_lock, NULL, 0, DRC_NON_IDEMPOTENT},
- {"CANCEL", NLM4_CANCEL, nlm4svc_cancel, NULL, 0, DRC_NON_IDEMPOTENT},
- {"UNLOCK", NLM4_UNLOCK, nlm4svc_unlock, NULL, 0, DRC_NON_IDEMPOTENT},
- /* 5 */
- {"GRANTED", NLM4_GRANTED, NULL, NULL, 0, DRC_NA},
- {"TEST", NLM4_TEST_MSG, NULL, NULL, 0, DRC_NA},
- {"LOCK", NLM4_LOCK_MSG, NULL, NULL, 0, DRC_NA},
- {"CANCEL", NLM4_CANCEL_MSG, NULL, NULL, 0, DRC_NA},
- {"UNLOCK", NLM4_UNLOCK_MSG, NULL, NULL, 0, DRC_NA},
- /* 10 */
- {"GRANTED", NLM4_GRANTED_MSG, NULL, NULL, 0, DRC_NA},
- {"TEST", NLM4_TEST_RES, NULL, NULL, 0, DRC_NA},
- {"LOCK", NLM4_LOCK_RES, NULL, NULL, 0, DRC_NA},
- {"CANCEL", NLM4_CANCEL_RES, NULL, NULL, 0, DRC_NA},
- {"UNLOCK", NLM4_UNLOCK_RES, NULL, NULL, 0, DRC_NA},
- /* 15 ; procedures 17,18,19 are not defined by nlm */
- {"GRANTED", NLM4_GRANTED_RES, NULL, NULL, 0, DRC_NA},
- {"SM_NOTIFY", NLM4_SM_NOTIFY, NULL, NULL, 0, DRC_NA},
- {"SEVENTEEN", NLM4_SEVENTEEN, NULL, NULL, 0, DRC_NA},
- {"EIGHTEEN", NLM4_EIGHTEEN, NULL, NULL, 0, DRC_NA},
- {"NINETEEN", NLM4_NINETEEN, NULL, NULL, 0, DRC_NA},
- /* 20 */
- {"SHARE", NLM4_SHARE, nlm4svc_share, NULL, 0, DRC_NON_IDEMPOTENT},
- {"UNSHARE", NLM4_UNSHARE, nlm4svc_unshare, NULL, 0, DRC_NON_IDEMPOTENT},
- {"NM_LOCK", NLM4_NM_LOCK, nlm4svc_nm_lock, NULL, 0, DRC_NON_IDEMPOTENT},
- {"FREE_ALL", NLM4_FREE_ALL, nlm4svc_free_all, NULL, 0, DRC_IDEMPOTENT},
-};
-
-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 timespec timeout = {0,};
- FILE *pidfile = NULL;
- pid_t pid = -1;
- static gf_boolean_t nlm4_inited = _gf_false;
-
- /* Already inited */
- if (nlm4_inited)
- return &nlm4prog;
-
- 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;
- }
-
- ret = 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.
- */
-
- /* TODO:
- notify/rpc.statd is done differently on OSX
-
- On OSX rpc.statd is controlled by rpc.lockd and are part for launchd
- (unified service management framework)
-
- A runcmd() should be invoking "launchctl start com.apple.lockd"
- instead. This is still a theory but we need to thoroughly test it
- out. Until then NLM support is non-existent on OSX.
- */
- ret = unlink (GF_SM_NOTIFY_PIDFILE);
- if (ret == -1 && errno != ENOENT) {
- gf_log (GF_NLM, GF_LOG_ERROR, "unable to unlink %s: %d",
- GF_SM_NOTIFY_PIDFILE, errno);
- 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.
- */
-
- char *pid_file = GF_RPC_STATD_PIDFILE;
- if (nfs->rpc_statd_pid_file)
- pid_file = nfs->rpc_statd_pid_file;
- pidfile = fopen (pid_file, "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 from %s ", GF_RPC_STATD_PIDFILE);
- ret = runcmd ("killall", "-9", "rpc.statd", NULL);
- } else
- kill (pid, SIGKILL);
-
- fclose (pidfile);
- } else {
- gf_log (GF_NLM, GF_LOG_WARNING, "opening %s of "
- "rpc.statd failed (%s)", pid_file, 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 (GF_RPC_STATD_PIDFILE);
- if (ret == -1 && errno != ENOENT) {
- gf_log (GF_NLM, GF_LOG_ERROR, "unable to unlink %s", pid_file);
- goto err;
- }
-
- ret = runcmd (nfs->rpc_statd, NULL);
- if (ret == -1) {
- gf_log (GF_NLM, GF_LOG_ERROR, "unable to start %s",
- nfs->rpc_statd);
- goto err;
- }
-
-
- pthread_create (&thr, NULL, nsm_thread, (void*)NULL);
-
- timeout.tv_sec = nlm_grace_period;
- timeout.tv_nsec = 0;
-
- gf_timer_call_after (nfsx->ctx, timeout, nlm_grace_period_over, NULL);
- nlm4_inited = _gf_true;
- 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");
-
- if (TRY_LOCK (&nlm_client_list_lk))
- goto out;
-
- 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);
- ret = 0;
- UNLOCK (&nlm_client_list_lk);
-
- out:
- if (ret) {
- gf_proc_dump_build_key (key, "nlm", "statedump_error");
- gf_proc_dump_write (key, "Unable to dump nlm state because "
- "nlm_client_list_lk lock couldn't be acquired");
- }
-
- return ret;
-}
diff --git a/xlators/nfs/server/src/nlm4.h b/xlators/nfs/server/src/nlm4.h
deleted file mode 100644
index 05c847c7738..00000000000
--- a/xlators/nfs/server/src/nlm4.h
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- Copyright (c) 2012 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.
-*/
-
-#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"
-
-#define NLM4_NULL 0
-#define NLM4_TEST 1
-#define NLM4_LOCK 2
-#define NLM4_CANCEL 3
-#define NLM4_UNLOCK 4
-#define NLM4_GRANTED 5
-#define NLM4_TEST_MSG 6
-#define NLM4_LOCK_MSG 7
-#define NLM4_CANCEL_MSG 8
-#define NLM4_UNLOCK_MSG 9
-#define NLM4_GRANTED_MSG 10
-#define NLM4_TEST_RES 11
-#define NLM4_LOCK_RES 12
-#define NLM4_CANCEL_RES 13
-#define NLM4_UNLOCK_RES 14
-#define NLM4_GRANTED_RES 15
-#define NLM4_SM_NOTIFY 16
-#define NLM4_SEVENTEEN 17
-#define NLM4_EIGHTEEN 18
-#define NLM4_NINETEEN 19
-#define NLM4_SHARE 20
-#define NLM4_UNSHARE 21
-#define NLM4_NM_LOCK 22
-#define NLM4_FREE_ALL 23
-#define NLM4_PROC_COUNT 24
-
-/* Registered with portmap */
-#define GF_NLM4_PORT 38468
-#define GF_NLM GF_NFS"-NLM"
-#ifdef GF_DARWIN_HOST_OS
-#define GF_RPC_STATD_PROG "/usr/sbin/rpc.statd"
-#define GF_RPC_STATD_PIDFILE "/var/run/statd.pid"
-#define GF_SM_NOTIFY_PIDFILE "/var/run/statd.notify.pid"
-#else
-#define GF_RPC_STATD_PROG "/sbin/rpc.statd"
-#define GF_RPC_STATD_PIDFILE "/var/run/rpc.statd.pid"
-#define GF_SM_NOTIFY_PIDFILE "/var/run/sm-notify.pid"
-#endif
-
-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;
-
-#endif
diff --git a/xlators/nfs/server/src/nlmcbk_svc.c b/xlators/nfs/server/src/nlmcbk_svc.c
deleted file mode 100644
index 20d3728d031..00000000000
--- a/xlators/nfs/server/src/nlmcbk_svc.c
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- Copyright (c) 2012 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.
-*/
-
-/*
- * Please do not edit this file.
- * It was generated using rpcgen.
- */
-
-#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;
- int ret = 0;
-
- ret = pmap_unset (NLMCBK_PROGRAM, NLMCBK_V1);
- if (ret == 0) {
- gf_log (GF_NLM, GF_LOG_ERROR, "pmap_unset failed");
- return NULL;
- }
- 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 a494190baac..e91d5f6efc8 100644
--- a/xlators/performance/Makefile.am
+++ b/xlators/performance/Makefile.am
@@ -1,3 +1,3 @@
-SUBDIRS = write-behind read-ahead readdir-ahead io-threads io-cache symlink-cache quick-read md-cache open-behind
+SUBDIRS = write-behind read-ahead io-threads io-cache symlink-cache quick-read stat-prefetch
CLEANFILES =
diff --git a/xlators/performance/io-cache/src/Makefile.am b/xlators/performance/io-cache/src/Makefile.am
index 155be9988c9..e3d816f1542 100644
--- a/xlators/performance/io-cache/src/Makefile.am
+++ b/xlators/performance/io-cache/src/Makefile.am
@@ -1,16 +1,14 @@
xlator_LTLIBRARIES = io-cache.la
xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/performance
-io_cache_la_LDFLAGS = -module -avoid-version
+io_cache_la_LDFLAGS = -module -avoidversion
io_cache_la_SOURCES = io-cache.c page.c ioc-inode.c
io_cache_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la
-noinst_HEADERS = io-cache.h ioc-mem-types.h
+noinst_HEADERS = io-cache.h
-AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \
- -I$(CONTRIBDIR)/rbtree
-
-AM_CFLAGS = -Wall $(GF_CFLAGS)
+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/io-cache/src/io-cache.c b/xlators/performance/io-cache/src/io-cache.c
index facff5038a7..96aa8fdef7b 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-2009 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 General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that 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
@@ -18,7 +27,6 @@
#include "dict.h"
#include "xlator.h"
#include "io-cache.h"
-#include "ioc-mem-types.h"
#include "statedump.h"
#include <assert.h>
#include <sys/time.h>
@@ -28,10 +36,11 @@ 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);
-static inline uint32_t
+inline uint32_t
ioc_hashfn (void *data, int len)
{
off_t offset;
@@ -41,264 +50,189 @@ ioc_hashfn (void *data, int len)
return (offset >> ioc_log2_page_size);
}
-/* TODO: This function is not used, uncomment when we find a
- usage for this function.
-
-static inline ioc_inode_t *
+inline ioc_inode_t *
ioc_inode_reupdate (ioc_inode_t *ioc_inode)
{
- ioc_table_t *table = NULL;
+ ioc_table_t *table = ioc_inode->table;
- table = ioc_inode->table;
-
- list_add_tail (&ioc_inode->inode_lru,
- &table->inode_lru[ioc_inode->weight]);
-
- return ioc_inode;
+ list_add_tail (&ioc_inode->inode_lru,
+ &table->inode_lru[ioc_inode->weight]);
+
+ return ioc_inode;
}
-
-static inline ioc_inode_t *
+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;
-
- table = ioc_inode->table;
+ int8_t need_revalidate = 0;
+ struct timeval tv = {0,};
+ int32_t ret = -1;
+ ioc_table_t *table = ioc_inode->table;
- gettimeofday (&tv, NULL);
+ ret = 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;
}
/*
* __ioc_inode_flush - flush all the cached pages of the given inode
*
- * @ioc_inode:
+ * @ioc_inode:
*
* assumes lock is held
*/
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);
-
- if (ret != -1)
- destroy_size += ret;
- }
-
- return destroy_size;
+ ret = ioc_page_destroy (curr);
+
+ if (ret != -1)
+ destroy_size += ret;
+ }
+
+ 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 stat *preop, struct stat *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 stat *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 stat *stbuf, dict_t *dict, struct stat *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;
-
- local = frame->local;
- if (local == NULL) {
- op_ret = -1;
- op_errno = EINVAL;
- goto out;
- }
-
- if (!this || !this->private) {
- op_ret = -1;
- op_errno = EINVAL;
- goto out;
- }
-
- table = this->private;
-
- path = local->file_loc.path;
-
- LOCK (&inode->lock);
- {
- __inode_ctx_get (inode, this, &tmp_ioc_inode);
- ioc_inode = (ioc_inode_t *)(long)tmp_ioc_inode;
-
- if (!ioc_inode) {
- weight = ioc_get_priority (table, path);
-
- ioc_inode = ioc_inode_update (table, inode,
- weight);
-
- __inode_ctx_put (inode, this,
- (uint64_t)(long)ioc_inode);
- }
- }
- UNLOCK (&inode->lock);
-
- ioc_inode_lock (ioc_inode);
- {
- if (ioc_inode->cache.mtime == 0) {
- ioc_inode->cache.mtime = stbuf->ia_mtime;
- ioc_inode->cache.mtime_nsec = stbuf->ia_mtime_nsec;
- }
-
- ioc_inode->ia_size = stbuf->ia_size;
- }
- ioc_inode_unlock (ioc_inode);
-
- cache_still_valid = ioc_cache_still_valid (ioc_inode,
- stbuf);
-
- if (!cache_still_valid) {
- ioc_inode_flush (ioc_inode);
- }
-
- ioc_table_lock (ioc_inode->table);
- {
- list_move_tail (&ioc_inode->inode_lru,
- &table->inode_lru[ioc_inode->weight]);
- }
- ioc_table_unlock (ioc_inode->table);
-
+ ioc_inode_t *ioc_inode = NULL;
+ ioc_table_t *table = this->private;
+ uint8_t cache_still_valid = 0;
+ uint64_t tmp_ioc_inode = 0;
+
+ if (op_ret != 0)
+ goto out;
+
+ inode_ctx_get (inode, this, &tmp_ioc_inode);
+ ioc_inode = (ioc_inode_t *)(long)tmp_ioc_inode;
+ if (ioc_inode) {
+ ioc_inode_lock (ioc_inode);
+ {
+ if (ioc_inode->cache.mtime == 0) {
+ ioc_inode->cache.mtime = stbuf->st_mtime;
+ ioc_inode->cache.mtime_nsec = ST_MTIM_NSEC(stbuf);
+ }
+ }
+ ioc_inode_unlock (ioc_inode);
+
+ cache_still_valid = ioc_cache_still_valid (ioc_inode,
+ stbuf);
+
+ if (!cache_still_valid) {
+ ioc_inode_flush (ioc_inode);
+ }
+
+ ioc_table_lock (ioc_inode->table);
+ {
+ list_move_tail (&ioc_inode->inode_lru,
+ &table->inode_lru[ioc_inode->weight]);
+ }
+ ioc_table_unlock (ioc_inode->table);
+ }
+
out:
- if (frame->local != NULL) {
- local = frame->local;
- 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
+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;
- int32_t op_errno = -1, ret = -1;
-
- local = mem_get0 (this->local_pool);
- if (local == NULL) {
- op_errno = ENOMEM;
- gf_log (this->name, GF_LOG_ERROR, "out of memory");
- goto unwind;
- }
-
- ret = loc_copy (&local->file_loc, loc);
- if (ret != 0) {
- op_errno = ENOMEM;
- gf_log (this->name, GF_LOG_ERROR, "out of memory");
- goto unwind;
- }
-
- 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,
- NULL, NULL);
-
- return 0;
+ return 0;
}
/*
- * ioc_forget -
+ * ioc_forget -
*
* @frame:
* @this:
@@ -308,33 +242,19 @@ 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)
-{
- uint64_t ioc_addr = 0;
- ioc_inode_t *ioc_inode = NULL;
+ uint64_t ioc_inode = 0;
- inode_ctx_get(inode, this, (uint64_t *) &ioc_addr);
- ioc_inode = (void *) ioc_addr;
+ 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 -
+
+/*
+ * ioc_cache_validate_cbk -
*
* @frame:
* @cookie:
@@ -346,89 +266,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 stat *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 stat *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->st_mtime;
+ ioc_inode->cache.mtime_nsec = ST_MTIM_NSEC(stbuf);
}
- }
- 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 (op_ret < 0)
+ local_stbuf = NULL;
+
+ ioc_inode_lock (ioc_inode);
+ {
+ gettimeofday (&ioc_inode->cache.tv, NULL);
+ }
+ ioc_inode_unlock (ioc_inode);
+
+ 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);
+
+ STACK_DESTROY (frame->root);
- 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;
-
- ioc_inode_lock (ioc_inode);
- {
- gettimeofday (&ioc_inode->cache.tv, NULL);
- }
- ioc_inode_unlock (ioc_inode);
-
- 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);
-
- 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),
- gf_ioc_mt_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 = CALLOC (1, sizeof (ioc_waitq_t));
if (waiter == NULL) {
gf_log (ioc_inode->table->xl->name, GF_LOG_ERROR,
"out of memory");
@@ -436,13 +353,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;
+out:
+ return ret;
}
/*
@@ -455,15 +372,15 @@ 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 = CALLOC (1, sizeof (ioc_local_t));
if (validate_local == NULL) {
ret = -1;
local->op_ret = -1;
@@ -473,58 +390,59 @@ 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);
+ 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;
-
- STACK_WIND (validate_frame, ioc_cache_validate_cbk,
+ validate_local->fd = fd_ref (fd);
+ validate_local->inode = ioc_inode;
+ validate_frame->local = validate_local;
+
+ 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;
}
-static inline uint32_t
+inline uint32_t
is_match (const char *path, const char *pattern)
{
- int32_t ret = 0;
-
- ret = fnmatch (pattern, path, FNM_NOESCAPE);
+ int32_t ret = 0;
- return (ret == 0);
+ ret = fnmatch (pattern, path, FNM_NOESCAPE);
+
+ return (ret == 0);
}
uint32_t
ioc_get_priority (ioc_table_t *table, const char *path)
{
- uint32_t priority = 1;
- struct ioc_priority *curr = NULL;
-
- 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;
- }
-
- return priority;
+ uint32_t priority = 0;
+ struct ioc_priority *curr = NULL;
+
+ if (list_empty(&table->priority_list)) {
+ priority = 1;
+ }
+ else {
+ list_for_each_entry (curr, &table->priority_list, list) {
+ if (is_match (path, curr->pattern))
+ priority = curr->priority;
+ }
+ }
+
+ return priority;
}
-/*
+/*
* ioc_open_cbk - open callback for io cache
*
* @frame: call frame
@@ -537,74 +455,81 @@ 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;
+ inode_t *inode = NULL;
+ uint32_t weight = 0xffffffff;
+ const char *path = NULL;
local = frame->local;
- if (!this || !this->private) {
- op_ret = -1;
- op_errno = EINVAL;
- goto out;
- }
-
table = this->private;
+ inode = local->file_loc.inode;
+ path = local->file_loc.path;
- if (op_ret != -1) {
- inode_ctx_get (fd->inode, this, &tmp_ioc_inode);
- ioc_inode = (ioc_inode_t *)(long)tmp_ioc_inode;
-
- //TODO: see why inode context is NULL and handle it.
- if (!ioc_inode) {
- gf_log (this->name, GF_LOG_ERROR, "inode context is "
- "NULL (%s)", uuid_utoa (fd->inode->gfid));
- goto out;
- }
-
- ioc_table_lock (ioc_inode->table);
- {
- list_move_tail (&ioc_inode->inode_lru,
- &table->inode_lru[ioc_inode->weight]);
- }
- ioc_table_unlock (ioc_inode->table);
-
- ioc_inode_lock (ioc_inode);
- {
- if ((table->min_file_size > ioc_inode->ia_size)
- || ((table->max_file_size > 0)
- && (table->max_file_size < ioc_inode->ia_size))) {
- fd_ctx_set (fd, this, 1);
+ if (op_ret != -1) {
+ /* look for ioc_inode corresponding to this fd */
+ LOCK (&fd->inode->lock);
+ {
+ __inode_ctx_get (fd->inode, this, &tmp_ioc_inode);
+ ioc_inode = (ioc_inode_t *)(long)tmp_ioc_inode;
+
+ if (!ioc_inode) {
+ /*
+ this is the first time someone is opening
+ this file, assign weight
+ */
+ weight = ioc_get_priority (table, path);
+
+ ioc_inode = ioc_inode_update (table, inode,
+ weight);
+
+ __inode_ctx_put (fd->inode, this,
+ (uint64_t)(long)ioc_inode);
+ } else {
+ ioc_table_lock (ioc_inode->table);
+ {
+ list_move_tail (&ioc_inode->inode_lru,
+ &table->inode_lru[ioc_inode->weight]);
+ }
+ ioc_table_unlock (ioc_inode->table);
}
- }
- ioc_inode_unlock (ioc_inode);
-
- /* 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
- */
- 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);
- frame->local = NULL;
-
- STACK_UNWIND_STRICT (open, frame, op_ret, op_errno, fd, xdata);
+ }
+ UNLOCK (&fd->inode->lock);
+
+ /* If mandatory locking has been enabled on this file,
+ we disable caching on it */
+ if (((inode->st_mode & S_ISGID)
+ && !(inode->st_mode & S_IXGRP))) {
+ fd_ctx_set (fd, this, 1);
+ }
+
+ /* 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
+ */
+ 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);
+ }
+ }
+
+ FREE (local);
+ frame->local = NULL;
+
+ STACK_UNWIND_STRICT (open, frame, op_ret, op_errno, fd);
- return 0;
+ return 0;
}
/*
@@ -623,182 +548,71 @@ 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 stat *buf, struct stat *preparent,
+ struct stat *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;
local = frame->local;
- if (!this || !this->private) {
- op_ret = -1;
- op_errno = EINVAL;
- goto out;
- }
-
table = this->private;
path = local->file_loc.path;
- if (op_ret != -1) {
- /* assign weight */
- weight = ioc_get_priority (table, path);
-
- ioc_inode = ioc_inode_update (table, inode, weight);
-
- ioc_inode_lock (ioc_inode);
- {
- ioc_inode->cache.mtime = buf->ia_mtime;
- ioc_inode->cache.mtime_nsec = buf->ia_mtime_nsec;
- 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 < 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);
-
- 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) {
- /*
- * 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);
- }
-
- /* 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 (op_ret != -1) {
+ {
+ /* assign weight */
+ weight = ioc_get_priority (table, path);
- }
+ ioc_inode = ioc_inode_update (table, inode, weight);
-out:
- frame->local = NULL;
- mem_put (local);
+ ioc_inode_lock (ioc_inode);
+ {
+ ioc_inode->cache.mtime = buf->st_mtime;
+ ioc_inode->cache.mtime_nsec = ST_MTIM_NSEC(buf);
+ }
+ ioc_inode_unlock (ioc_inode);
+
+ inode_ctx_put (fd->inode, this,
+ (uint64_t)(long)ioc_inode);
+ }
+ /*
+ * If mandatory locking has been enabled on this file,
+ * we disable caching on it
+ */
+ if ((inode->st_mode & S_ISGID) &&
+ !(inode->st_mode & S_IXGRP)) {
+ fd_ctx_set (fd, this, 1);
+ }
+
+ /* 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
+ */
+ 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);
+ }
+ }
+
+ frame->local = NULL;
+ FREE (local);
STACK_UNWIND_STRICT (create, frame, op_ret, op_errno, fd, inode, buf,
- preparent, postparent, xdata);
-
- return 0;
-}
-
-
-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)
-{
- ioc_local_t *local = 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) {
- op_ret = -1;
- op_errno = EINVAL;
- goto out;
- }
-
- table = this->private;
- path = local->file_loc.path;
-
- if (op_ret != -1) {
- /* assign weight */
- weight = ioc_get_priority (table, path);
-
- ioc_inode = ioc_inode_update (table, inode, weight);
-
- ioc_inode_lock (ioc_inode);
- {
- ioc_inode->cache.mtime = buf->ia_mtime;
- ioc_inode->cache.mtime_nsec = buf->ia_mtime_nsec;
- ioc_inode->ia_size = buf->ia_size;
- }
- ioc_inode_unlock (ioc_inode);
-
- inode_ctx_put (inode, this,
- (uint64_t)(long)ioc_inode);
- }
-
-out:
- frame->local = NULL;
-
- loc_wipe (&local->file_loc);
- mem_put (local);
-
- STACK_UNWIND_STRICT (mknod, frame, op_ret, op_errno, inode, buf,
- preparent, postparent, xdata);
- 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)
-{
- ioc_local_t *local = NULL;
- int32_t op_errno = -1, ret = -1;
-
- local = mem_get0 (this->local_pool);
- if (local == NULL) {
- op_errno = ENOMEM;
- gf_log (this->name, GF_LOG_ERROR, "out of memory");
- goto unwind;
- }
-
- ret = loc_copy (&local->file_loc, loc);
- if (ret != 0) {
- op_errno = ENOMEM;
- gf_log (this->name, GF_LOG_ERROR, "out of memory");
- goto unwind;
- }
-
- frame->local = local;
+ preparent, postparent);
- STACK_WIND (frame, ioc_mknod_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->mknod,
- loc, mode, rdev, umask, xdata);
- return 0;
-
-unwind:
- if (local != NULL) {
- loc_wipe (&local->file_loc);
- mem_put (local);
- }
-
- STACK_UNWIND_STRICT (mknod, frame, -1, op_errno, NULL, NULL,
- NULL, NULL, NULL);
-
- return 0;
+ return 0;
}
-
/*
* ioc_open - open fop for io cache
* @frame:
@@ -809,34 +623,33 @@ 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 = CALLOC (1, sizeof (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;
-
- frame->local = local;
-
- STACK_WIND (frame, ioc_open_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->open, loc, flags, fd,
- xdata);
+ local->flags = flags;
+ local->file_loc.path = loc->path;
+ local->file_loc.inode = loc->inode;
+
+ frame->local = local;
+
+ STACK_WIND (frame, ioc_open_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->open, loc, flags, fd, wbflags);
- return 0;
+ return 0;
}
/*
* ioc_create - create fop for io cache
- *
+ *
* @frame:
* @this:
* @pathname:
@@ -846,27 +659,26 @@ 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)
{
- ioc_local_t *local = NULL;
+ ioc_local_t *local = NULL;
- local = mem_get0 (this->local_pool);
+ local = CALLOC (1, sizeof (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);
- return 0;
+ return 0;
}
@@ -874,7 +686,7 @@ ioc_create (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
/*
* ioc_release - release fop for io cache
- *
+ *
* @frame:
* @this:
* @fd:
@@ -883,11 +695,11 @@ 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;
}
-/*
- * ioc_readv_disabled_cbk
+/*
+ * ioc_readv_disabled_cbk
* @frame:
* @cookie:
* @this:
@@ -896,175 +708,164 @@ ioc_release (xlator_t *this, fd_t *fd)
* @vector:
* @count:
*
- */
+ */
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 stat *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;
}
/*
* ioc_dispatch_requests -
- *
+ *
* @frame:
* @inode:
*
- *
+ *
*/
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
- */
-
- 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");
+ 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 = ENOMEM;
+ local->op_errno = -ret;
+ need_validate = 0;
+
+ waitq = ioc_page_wakeup (trav);
ioc_inode_unlock (ioc_inode);
- 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_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);
@@ -1072,25 +873,25 @@ 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;
}
/*
* ioc_readv -
- *
+ *
* @frame:
* @this:
* @fd:
@@ -1100,29 +901,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,
- FIRST_CHILD (frame->this),
- FIRST_CHILD (frame->this)->fops->readv, fd, size,
- offset, flags, xdata);
- return 0;
- }
+ 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);
+ return 0;
+ }
table = this->private;
@@ -1133,14 +935,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);
+ = rbthash_table_init
+ (IOC_PAGE_TABLE_BUCKET_COUNT,
+ ioc_hashfn, NULL, 0,
+ table->mem_pool);
if (ioc_inode->cache.page_table == NULL) {
op_errno = ENOMEM;
@@ -1151,56 +976,55 @@ 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,
- FIRST_CHILD (frame->this),
- FIRST_CHILD (frame->this)->fops->readv, fd, size,
- offset, flags, xdata);
- return 0;
- }
+ 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);
+ return 0;
+ }
- local = mem_get0 (this->local_pool);
+ local = (ioc_local_t *) CALLOC (1, sizeof (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;
}
/*
* ioc_writev_cbk -
- *
+ *
* @frame:
* @cookie:
* @this:
@@ -1210,26 +1034,25 @@ 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 stat *prebuf,
+ struct stat *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);
-
- if (ioc_inode)
- ioc_inode_flush ((ioc_inode_t *)(long)ioc_inode);
+ inode_ctx_get (local->fd->inode, this, &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;
}
/*
* ioc_writev
- *
+ *
* @frame:
* @this:
* @fd:
@@ -1240,38 +1063,38 @@ 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 = CALLOC (1, sizeof (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;
}
/*
* ioc_truncate_cbk -
- *
+ *
* @frame:
* @cookie:
* @this:
@@ -1280,15 +1103,15 @@ ioc_writev (call_frame_t *frame, xlator_t *this, fd_t *fd,
* @buf:
*
*/
-int32_t
+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)
+ int32_t op_ret, int32_t op_errno, struct stat *prebuf,
+ struct stat *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;
}
@@ -1305,44 +1128,42 @@ 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 stat *prebuf,
+ struct stat *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;
}
/*
* ioc_truncate -
- *
+ *
* @frame:
* @this:
* @loc:
* @offset:
*
*/
-int32_t
-ioc_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset,
- dict_t *xdata)
+int32_t
+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;
}
/*
* ioc_ftruncate -
- *
+ *
* @frame:
* @this:
* @fd:
@@ -1350,470 +1171,246 @@ 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)
-{
- uint64_t ioc_inode = 0;
-
- inode_ctx_get (fd->inode, this, &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;
-}
-
-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)
-{
- STACK_UNWIND_STRICT (lk, frame, op_ret, op_errno, lock, xdata);
- 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)
-{
- 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_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;
-}
-
-static int32_t
-ioc_discard_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)
-{
- STACK_UNWIND_STRICT(discard, frame, op_ret, op_errno, pre, post, xdata);
- return 0;
-}
-
-static int32_t
-ioc_discard(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
- size_t len, dict_t *xdata)
+ioc_ftruncate (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset)
{
uint64_t ioc_inode = 0;
-
inode_ctx_get (fd->inode, this, &ioc_inode);
if (ioc_inode)
ioc_inode_flush ((ioc_inode_t *)(long)ioc_inode);
- STACK_WIND(frame, ioc_discard_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->discard, fd, offset, len, xdata);
- return 0;
+ STACK_WIND (frame, ioc_ftruncate_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->ftruncate, fd, offset);
+ return 0;
}
-static int32_t
-ioc_zerofill_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)
+int32_t
+ioc_lk_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret,
+ int32_t op_errno, struct flock *lock)
{
- STACK_UNWIND_STRICT(zerofill, frame, op_ret,
- op_errno, pre, post, xdata);
- return 0;
+ STACK_UNWIND_STRICT (lk, frame, op_ret, op_errno, lock);
+ return 0;
}
-static int32_t
-ioc_zerofill(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
- off_t len, dict_t *xdata)
+int32_t
+ioc_lk (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t cmd,
+ struct flock *lock)
{
- uint64_t ioc_inode = 0;
-
- inode_ctx_get (fd->inode, this, &ioc_inode);
+ 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);
- if (ioc_inode)
- ioc_inode_flush ((ioc_inode_t *)(long)ioc_inode);
-
- STACK_WIND(frame, ioc_zerofill_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->zerofill, fd, offset, len, xdata);
- 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;
-
- string = gf_strdup (opt_str);
+ 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 = strdup (opt_str);
if (string == NULL) {
max_pri = -1;
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),
- gf_ioc_mt_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 = CALLOC (1, sizeof (struct 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 = 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 = 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);
+ 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) {
+ free (string);
+ }
- GF_FREE (dup_str);
+ if (dup_str != NULL) {
+ free (dup_str);
+ }
if (max_pri == -1) {
list_for_each_entry_safe (curr, tmp, first, list) {
list_del_init (&curr->list);
- GF_FREE (curr->pattern);
- GF_FREE (curr);
+ free (curr->pattern);
+ free (curr);
}
}
- return max_pri;
-}
-
-int32_t
-mem_acct_init (xlator_t *this)
-{
- int ret = -1;
-
- if (!this)
- return ret;
-
- ret = xlator_mem_acct_init (this, gf_ioc_mt_end + 1);
-
- if (ret != 0) {
- gf_log (this->name, GF_LOG_ERROR, "Memory accounting init"
- "failed");
- return ret;
- }
-
- return ret;
-}
-
-
-static gf_boolean_t
-check_cache_size_ok (xlator_t *this, uint64_t cache_size)
-{
- 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");
- 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);
- goto out;
- }
-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;
- 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_uint64, unlock);
-
- GF_OPTION_RECONF ("min-file-size", table->min_file_size,
- options, size_uint64, unlock);
-
- if ((table->max_file_size <= UINT64_MAX) &&
- (table->min_file_size > table->max_file_size)) {
- gf_log (this->name, GF_LOG_ERROR, "minimum size (%"
- PRIu64") of a file that can be cached is "
- "greater than maximum size (%"PRIu64"). "
- "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_uint64, 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);
-out:
- return ret;
+ return max_pri;
}
-
/*
- * init -
+ * init -
* @this:
*
*/
-int32_t
+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;
+ int32_t ret = -1;
+ glusterfs_ctx_t *ctx = NULL;
+
+ 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 *) CALLOC (1, sizeof (*table));
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;
-
- GF_OPTION_INIT ("cache-size", table->cache_size, size_uint64, out);
-
- GF_OPTION_INIT ("cache-timeout", table->cache_timeout, int32, out);
-
- GF_OPTION_INIT ("min-file-size", table->min_file_size, size_uint64, out);
-
- GF_OPTION_INIT ("max-file-size", table->max_file_size, size_uint64, out);
-
- if (!check_cache_size_ok (this, table->cache_size)) {
- ret = -1;
- goto out;
- }
-
- 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);
-
- if (table->max_pri == -1) {
+
+ table->xl = this;
+ table->page_size = this->ctx->page_size;
+ table->cache_size = IOC_CACHE_SIZE;
+
+ 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,
+ &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_log (this->name, GF_LOG_TRACE,
+ "using cache-size %"PRIu64"", table->cache_size);
+ }
+
+ table->cache_timeout = 1;
+
+ if (dict_get (options, "cache-timeout")) {
+ table->cache_timeout =
+ data_to_uint32 (dict_get (options,
+ "cache-timeout"));
+ 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;
+ 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) {
goto out;
}
- }
- table->max_pri ++;
-
- INIT_LIST_HEAD (&table->inodes);
-
- if ((table->max_file_size <= UINT64_MAX)
- && (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;
- }
-
- table->inode_lru = GF_CALLOC (table->max_pri,
- sizeof (struct list_head),
- gf_ioc_mt_list_head);
+ }
+ table->max_pri ++;
+ INIT_LIST_HEAD (&table->inodes);
+
+ table->inode_lru = CALLOC (table->max_pri, sizeof (struct 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;
@@ -1822,343 +1419,106 @@ init (xlator_t *this)
out:
if (ret == -1) {
if (table != NULL) {
- GF_FREE (table->inode_lru);
- GF_FREE (table);
- }
- }
-
- 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)
-{
-
- int ret = -1;
-
- if (!page)
- return;
- /* ioc_page_lock can be used to hold the mutex. But in statedump
- * its better to use trylock to avoid deadlocks.
- */
- ret = pthread_mutex_trylock (&page->page_lock);
- if (ret)
- 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 ("ready", "%s", page->ready ? "yes" : "no");
- ioc_page_waitq_dump (page, prefix);
- }
- pthread_mutex_unlock (&page->page_lock);
-
-out:
- if (ret && page)
- gf_proc_dump_write ("Unable to dump the page information",
- "(Lock acquisition failed) %p", page);
-
- return;
-}
-
-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;
+ free (table->inode_lru);
+ free (table);
}
-
- sprintf (key, "inode.cache.page[%d]", i++);
- __ioc_page_dump (page, key);
}
-out:
- return;
-}
-
-int
-ioc_inode_dump (xlator_t *this, inode_t *inode)
-{
-
- char *path = NULL;
- int ret = -1;
- char key_prefix[GF_DUMP_MAX_BUF_LEN] = {0, };
- uint64_t tmp_ioc_inode = 0;
- ioc_inode_t *ioc_inode = NULL;
- gf_boolean_t section_added = _gf_false;
- char uuid_str[64] = {0,};
-
- if (this == NULL || inode == NULL)
- goto out;
-
- gf_proc_dump_build_key (key_prefix, "io-cache", "inode");
-
- inode_ctx_get (inode, this, &tmp_ioc_inode);
- ioc_inode = (ioc_inode_t *)(long)tmp_ioc_inode;
- if (ioc_inode == NULL)
- goto out;
-
- /* Similar to ioc_page_dump function its better to use
- * pthread_mutex_trylock and not to use gf_log in statedump
- * to avoid deadlocks.
- */
- ret = pthread_mutex_trylock (&ioc_inode->inode_lock);
- if (ret)
- goto out;
-
- {
- if (uuid_is_null (ioc_inode->inode->gfid))
- goto unlock;
-
- gf_proc_dump_add_section (key_prefix);
- section_added = _gf_true;
-
- __inode_path (ioc_inode->inode, NULL, &path);
-
- gf_proc_dump_write ("inode.weight", "%d", ioc_inode->weight);
-
- if (path) {
- gf_proc_dump_write ("path", "%s", path);
- GF_FREE (path);
- }
-
- gf_proc_dump_write ("uuid", "%s", uuid_utoa_r
- (ioc_inode->inode->gfid, uuid_str));
- __ioc_cache_dump (ioc_inode, key_prefix);
- __ioc_inode_waitq_dump (ioc_inode, key_prefix);
- }
-unlock:
- pthread_mutex_unlock (&ioc_inode->inode_lock);
-
-out:
- if (ret && ioc_inode) {
- if (section_added == _gf_false)
- gf_proc_dump_add_section (key_prefix);
- gf_proc_dump_write ("Unable to print the status of ioc_inode",
- "(Lock acquisition failed) %s",
- uuid_utoa (inode->gfid));
- }
- return ret;
+ return ret;
}
int
ioc_priv_dump (xlator_t *this)
{
- ioc_table_t *priv = NULL;
- char key_prefix[GF_DUMP_MAX_BUF_LEN] = {0, };
- int ret = -1;
- gf_boolean_t add_section = _gf_false;
-
- if (!this || !this->private)
- goto out;
+ ioc_table_t *priv = NULL;
+ char key_prefix[GF_DUMP_MAX_BUF_LEN];
+ char key[GF_DUMP_MAX_BUF_LEN];
+ assert (this);
priv = this->private;
- gf_proc_dump_build_key (key_prefix, "io-cache", "priv");
+ assert (priv);
+
+ gf_proc_dump_build_key (key_prefix, "xlator.performance.io-cache",
+ "priv");
gf_proc_dump_add_section (key_prefix);
- add_section = _gf_true;
- ret = pthread_mutex_trylock (&priv->table_lock);
- if (ret)
- goto out;
- {
- 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);
- }
- pthread_mutex_unlock (&priv->table_lock);
-out:
- if (ret && priv) {
- if (!add_section) {
- gf_proc_dump_build_key (key_prefix, "xlator."
- "performance.io-cache", "priv");
- gf_proc_dump_add_section (key_prefix);
- }
- gf_proc_dump_write ("Unable to dump the state of private "
- "structure of io-cache xlator", "(Lock "
- "acquisition failed) %s", this->name);
- }
+ 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);
return 0;
}
/*
* fini -
- *
+ *
* @this:
*
*/
void
fini (xlator_t *this)
{
- ioc_table_t *table = NULL;
- struct ioc_priority *curr = NULL, *tmp = NULL;
- int i = 0;
-
- table = this->private;
+ ioc_table_t *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);
+ 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,
- .setattr = ioc_setattr,
- .mknod = ioc_mknod,
-
- .readdirp = ioc_readdirp,
- .discard = ioc_discard,
- .zerofill = ioc_zerofill,
+ .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
+};
+
+struct xlator_mops mops = {
};
struct xlator_dumpops dumpops = {
.priv = ioc_priv_dump,
- .inodectx = ioc_inode_dump,
};
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 = {"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 = {"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 = {NULL} },
};
diff --git a/xlators/performance/io-cache/src/io-cache.h b/xlators/performance/io-cache/src/io-cache.h
index 46d758a6608..63c2609ec7f 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-2009 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 General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that 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 __IO_CACHE_H
@@ -40,134 +49,129 @@ struct ioc_page;
struct ioc_inode;
struct ioc_priority {
- struct list_head list;
- char *pattern;
- uint32_t priority;
+ struct list_head list;
+ char *pattern;
+ uint32_t priority;
};
/*
- * ioc_waitq - this structure is used to represents the waiting
+ * ioc_waitq - this structure is used to represents the waiting
* frames on a page
*
* @next: pointer to next object in waitq
* @data: pointer to the frame which is waiting
*/
struct ioc_waitq {
- struct ioc_waitq *next;
- void *data;
- off_t pending_offset;
- size_t pending_size;
+ struct ioc_waitq *next;
+ void *data;
+ off_t pending_offset;
+ size_t pending_size;
};
/*
- * ioc_fill -
+ * ioc_fill -
*
*/
struct ioc_fill {
- struct list_head list; /* list of ioc_fill structures of a frame */
- off_t offset;
- size_t size;
- struct iovec *vector;
- int32_t count;
- struct iobref *iobref;
+ struct list_head list; /* list of ioc_fill structures of a frame */
+ off_t offset;
+ size_t size;
+ struct iovec *vector;
+ int32_t count;
+ struct iobref *iobref;
};
struct ioc_local {
- mode_t mode;
- int32_t flags;
- loc_t file_loc;
- off_t offset;
- size_t size;
- int32_t op_ret;
- int32_t op_errno;
- struct list_head fill_list; /* list of ioc_fill structures */
- off_t pending_offset; /*
+ mode_t mode;
+ int32_t flags;
+ loc_t file_loc;
+ off_t offset;
+ size_t size;
+ int32_t op_ret;
+ int32_t op_errno;
+ struct list_head fill_list; /* list of ioc_fill structures */
+ off_t pending_offset; /*
* offset from this frame should
* continue
*/
- size_t pending_size; /*
+ size_t pending_size; /*
* size of data this frame is waiting
* on
*/
- struct ioc_inode *inode;
- int32_t wait_count;
- pthread_mutex_t local_lock;
- struct ioc_waitq *waitq;
- void *stub;
- fd_t *fd;
- int32_t need_xattr;
- dict_t *xattr_req;
+ struct ioc_inode *inode;
+ int32_t wait_count;
+ pthread_mutex_t local_lock;
+ struct ioc_waitq *waitq;
+ void *stub;
+ fd_t *fd;
+ int32_t need_xattr;
+ dict_t *xattr_req;
};
/*
- * ioc_page - structure to store page of data from file
+ * ioc_page - structure to store page of data from file
*
*/
struct ioc_page {
- struct list_head page_lru;
- struct ioc_inode *inode; /* inode this page belongs to */
- struct ioc_priority *priority;
- char dirty;
- char ready;
- struct iovec *vector;
- int32_t count;
- off_t offset;
- size_t size;
- struct ioc_waitq *waitq;
- struct iobref *iobref;
- pthread_mutex_t page_lock;
- int32_t op_errno;
- char stale;
+ struct list_head page_lru;
+ struct ioc_inode *inode; /* inode this page belongs to */
+ struct ioc_priority *priority;
+ char dirty;
+ char ready;
+ struct iovec *vector;
+ int32_t count;
+ off_t offset;
+ size_t size;
+ struct ioc_waitq *waitq;
+ struct iobref *iobref;
+ pthread_mutex_t page_lock;
};
struct ioc_cache {
rbthash_table_t *page_table;
struct list_head page_lru;
- time_t mtime; /*
- * seconds component of file mtime
+ uint32_t mtime; /*
+ * seconds component of file mtime on
+ * server
*/
- time_t mtime_nsec; /*
- * nanosecond component of file mtime
+ uint32_t mtime_nsec; /* nanosecond component of file mtime
+ * on server
*/
- struct timeval tv; /*
+ struct timeval tv; /*
* time-stamp at last re-validate
*/
};
struct ioc_inode {
- struct ioc_table *table;
- off_t ia_size;
- struct ioc_cache cache;
- struct list_head inode_list; /*
+ struct ioc_table *table;
+ struct ioc_cache cache;
+ struct list_head inode_list; /*
* list of inodes, maintained by
* io-cache translator
*/
- struct list_head inode_lru;
- struct ioc_waitq *waitq;
- pthread_mutex_t inode_lock;
- uint32_t weight; /*
+ struct list_head inode_lru;
+ struct ioc_waitq *waitq;
+ pthread_mutex_t inode_lock;
+ uint32_t weight; /*
* 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;
- struct list_head inodes; /* list of inodes cached */
- struct list_head active;
- struct list_head *inode_lru;
- struct list_head priority_list;
- int32_t readv_count;
- pthread_mutex_t table_lock;
- xlator_t *xl;
- uint32_t inode_count;
- int32_t cache_timeout;
- int32_t max_pri;
+ uint64_t page_size;
+ uint64_t cache_size;
+ uint64_t cache_used;
+ struct list_head inodes; /* list of inodes cached */
+ struct list_head active;
+ struct list_head *inode_lru;
+ struct list_head priority_list;
+ int32_t readv_count;
+ pthread_mutex_t table_lock;
+ xlator_t *xl;
+ uint32_t inode_count;
+ int32_t cache_timeout;
+ int32_t max_pri;
struct mem_pool *mem_pool;
};
@@ -184,33 +188,36 @@ str_to_ptr (char *string);
char *
ptr_to_str (void *ptr);
-int32_t
+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 op_ret, int32_t op_errno, struct iovec *vector,
+ int32_t count, struct stat *stbuf,
+ 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);
+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,
- size_t size);
+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,95 +227,95 @@ 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 { \
- gf_log (ioc_inode->table->xl->name, GF_LOG_TRACE, \
- "locked inode(%p)", ioc_inode); \
- pthread_mutex_lock (&ioc_inode->inode_lock); \
- } while (0)
+#define ioc_inode_lock(ioc_inode) \
+ do { \
+ gf_log (ioc_inode->table->xl->name, GF_LOG_TRACE, \
+ "locked inode(%p)", ioc_inode); \
+ pthread_mutex_lock (&ioc_inode->inode_lock); \
+ } while (0)
-#define ioc_inode_unlock(ioc_inode) \
- do { \
- gf_log (ioc_inode->table->xl->name, GF_LOG_TRACE, \
- "unlocked inode(%p)", ioc_inode); \
- pthread_mutex_unlock (&ioc_inode->inode_lock); \
- } while (0)
+#define ioc_inode_unlock(ioc_inode) \
+ do { \
+ gf_log (ioc_inode->table->xl->name, GF_LOG_TRACE, \
+ "unlocked inode(%p)", ioc_inode); \
+ pthread_mutex_unlock (&ioc_inode->inode_lock); \
+ } while (0)
-#define ioc_table_lock(table) \
- do { \
- gf_log (table->xl->name, GF_LOG_TRACE, \
- "locked table(%p)", table); \
- pthread_mutex_lock (&table->table_lock); \
- } while (0)
+#define ioc_table_lock(table) \
+ do { \
+ gf_log (table->xl->name, GF_LOG_TRACE, \
+ "locked table(%p)", table); \
+ pthread_mutex_lock (&table->table_lock); \
+ } while (0)
-#define ioc_table_unlock(table) \
- do { \
- gf_log (table->xl->name, GF_LOG_TRACE, \
- "unlocked table(%p)", table); \
- pthread_mutex_unlock (&table->table_lock); \
- } while (0)
+#define ioc_table_unlock(table) \
+ do { \
+ gf_log (table->xl->name, GF_LOG_TRACE, \
+ "unlocked table(%p)", table); \
+ pthread_mutex_unlock (&table->table_lock); \
+ } while (0)
-#define ioc_local_lock(local) \
- do { \
- gf_log (local->inode->table->xl->name, GF_LOG_TRACE, \
- "locked local(%p)", local); \
- pthread_mutex_lock (&local->local_lock); \
- } while (0)
+#define ioc_local_lock(local) \
+ do { \
+ gf_log (local->inode->table->xl->name, GF_LOG_TRACE, \
+ "locked local(%p)", local); \
+ pthread_mutex_lock (&local->local_lock); \
+ } while (0)
-#define ioc_local_unlock(local) \
- do { \
- gf_log (local->inode->table->xl->name, GF_LOG_TRACE, \
- "unlocked local(%p)", local); \
- pthread_mutex_unlock (&local->local_lock); \
- } while (0)
+#define ioc_local_unlock(local) \
+ do { \
+ gf_log (local->inode->table->xl->name, GF_LOG_TRACE, \
+ "unlocked local(%p)", local); \
+ pthread_mutex_unlock (&local->local_lock); \
+ } while (0)
-#define ioc_page_lock(page) \
- do { \
- gf_log (page->inode->table->xl->name, GF_LOG_TRACE, \
- "locked page(%p)", page); \
- pthread_mutex_lock (&page->page_lock); \
- } while (0)
+#define ioc_page_lock(page) \
+ do { \
+ gf_log (page->inode->table->xl->name, GF_LOG_TRACE, \
+ "locked page(%p)", page); \
+ pthread_mutex_lock (&page->page_lock); \
+ } while (0)
-#define ioc_page_unlock(page) \
- do { \
- gf_log (page->inode->table->xl->name, GF_LOG_TRACE, \
- "unlocked page(%p)", page); \
- pthread_mutex_unlock (&page->page_lock); \
- } while (0)
+#define ioc_page_unlock(page) \
+ do { \
+ gf_log (page->inode->table->xl->name, GF_LOG_TRACE, \
+ "unlocked page(%p)", page); \
+ pthread_mutex_unlock (&page->page_lock); \
+ } while (0)
static inline uint64_t
time_elapsed (struct timeval *now,
- struct timeval *then)
+ struct timeval *then)
{
- uint64_t sec = now->tv_sec - then->tv_sec;
-
- if (sec)
- return sec;
+ uint64_t sec = now->tv_sec - then->tv_sec;
- return 0;
+ if (sec)
+ return sec;
+
+ return 0;
}
ioc_inode_t *
ioc_inode_search (ioc_table_t *table, inode_t *inode);
-void
+void
ioc_inode_destroy (ioc_inode_t *ioc_inode);
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);
+int64_t
+ioc_page_destroy (ioc_page_t *page);
int64_t
__ioc_inode_flush (ioc_inode_t *ioc_inode);
@@ -318,10 +325,10 @@ ioc_inode_flush (ioc_inode_t *ioc_inode);
void
ioc_inode_wakeup (call_frame_t *frame, ioc_inode_t *ioc_inode,
- struct iatt *stbuf);
+ struct stat *stbuf);
int8_t
-ioc_cache_still_valid (ioc_inode_t *ioc_inode, struct iatt *stbuf);
+ioc_cache_still_valid (ioc_inode_t *ioc_inode, struct stat *stbuf);
int32_t
ioc_prune (ioc_table_t *table);
@@ -329,4 +336,6 @@ ioc_prune (ioc_table_t *table);
int32_t
ioc_need_prune (ioc_table_t *table);
+inline uint32_t
+ioc_hashfn (void *data, int len);
#endif /* __IO_CACHE_H */
diff --git a/xlators/performance/io-cache/src/ioc-inode.c b/xlators/performance/io-cache/src/ioc-inode.c
index 86a54bb14ca..74c657fe7c3 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-2009 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 General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that 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
@@ -14,7 +23,6 @@
#endif
#include "io-cache.h"
-#include "ioc-mem-types.h"
extern int ioc_log2_page_size;
@@ -26,14 +34,10 @@ extern int ioc_log2_page_size;
void *
str_to_ptr (char *string)
{
- void *ptr = NULL;
-
- GF_VALIDATE_OR_GOTO ("io-cache", string, out);
+ void *ptr = NULL;
ptr = (void *)strtoul (string, NULL, 16);
-
-out:
- return ptr;
+ return ptr;
}
@@ -46,126 +50,102 @@ char *
ptr_to_str (void *ptr)
{
int ret = 0;
- char *str = NULL;
-
- GF_VALIDATE_OR_GOTO ("io-cache", ptr, out);
-
- ret = gf_asprintf (&str, "%p", ptr);
+ char *str = NULL;
+ ret = asprintf (&str, "%p", ptr);
if (-1 == ret) {
- gf_log ("io-cache", GF_LOG_WARNING,
+ gf_log ("ioc", GF_LOG_ERROR,
"asprintf failed while converting ptr to str");
- str = NULL;
- goto out;
+ return NULL;
}
-
-out:
- return str;
+ return str;
}
-
void
-ioc_inode_wakeup (call_frame_t *frame, ioc_inode_t *ioc_inode,
- struct iatt *stbuf)
+ioc_inode_wakeup (call_frame_t *frame, ioc_inode_t *ioc_inode,
+ struct stat *stbuf)
{
- ioc_waitq_t *waiter = NULL, *waited = NULL;
- ioc_waitq_t *page_waitq = NULL;
- int8_t cache_still_valid = 1;
- ioc_local_t *local = NULL;
- int8_t need_fault = 0;
- ioc_page_t *waiter_page = NULL;
-
- GF_VALIDATE_OR_GOTO ("io-cache", frame, out);
+ ioc_waitq_t *waiter = NULL, *waited = NULL;
+ ioc_waitq_t *page_waitq = NULL;
+ int8_t cache_still_valid = 1;
+ ioc_local_t *local = NULL;
+ int8_t need_fault = 0;
+ ioc_page_t *waiter_page = NULL;
local = frame->local;
- GF_VALIDATE_OR_GOTO (frame->this->name, local, out);
-
- if (ioc_inode == NULL) {
- local->op_ret = -1;
- local->op_errno = EINVAL;
- gf_log (frame->this->name, GF_LOG_WARNING, "ioc_inode is NULL");
- goto out;
- }
-
- ioc_inode_lock (ioc_inode);
- {
- waiter = ioc_inode->waitq;
- ioc_inode->waitq = NULL;
- }
- ioc_inode_unlock (ioc_inode);
-
- if (stbuf)
- cache_still_valid = ioc_cache_still_valid (ioc_inode, stbuf);
- else
- cache_still_valid = 0;
-
- if (!waiter) {
- gf_log (frame->this->name, GF_LOG_WARNING,
- "cache validate called without any "
- "page waiting to be validated");
- }
-
- while (waiter) {
- waiter_page = waiter->data;
- page_waitq = NULL;
-
- if (waiter_page) {
- if (cache_still_valid) {
- /* cache valid, wake up page */
- ioc_inode_lock (ioc_inode);
- {
- page_waitq =
- __ioc_page_wakeup (waiter_page,
- waiter_page->op_errno);
- }
- ioc_inode_unlock (ioc_inode);
- if (page_waitq)
- ioc_waitq_return (page_waitq);
- } else {
- /* cache invalid, generate page fault and set
- * 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);
- }
- }
- ioc_inode_unlock (ioc_inode);
-
- if (need_fault) {
- need_fault = 0;
- ioc_page_fault (ioc_inode, frame,
- local->fd,
- waiter_page->offset);
- }
- }
- }
-
- waited = waiter;
- waiter = waiter->next;
-
- waited->data = NULL;
- GF_FREE (waited);
- }
-
-out:
- return;
+ ioc_inode_lock (ioc_inode);
+ {
+ waiter = ioc_inode->waitq;
+ ioc_inode->waitq = NULL;
+ }
+ ioc_inode_unlock (ioc_inode);
+
+ if (stbuf)
+ cache_still_valid = ioc_cache_still_valid (ioc_inode, stbuf);
+ else
+ cache_still_valid = 0;
+
+ if (!waiter) {
+ gf_log (frame->this->name, GF_LOG_DEBUG,
+ "cache validate called without any "
+ "page waiting to be validated");
+ }
+
+ while (waiter) {
+ waiter_page = waiter->data;
+ page_waitq = NULL;
+
+ if (waiter_page) {
+ if (cache_still_valid) {
+ /* cache valid, wake up page */
+ ioc_inode_lock (ioc_inode);
+ {
+ page_waitq =
+ ioc_page_wakeup (waiter_page);
+ }
+ ioc_inode_unlock (ioc_inode);
+ if (page_waitq)
+ ioc_waitq_return (page_waitq);
+ } else {
+ /* cache invalid, generate page fault and set
+ * 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);
+ }
+
+ ioc_inode_unlock (ioc_inode);
+
+ if (need_fault) {
+ need_fault = 0;
+ ioc_page_fault (ioc_inode, frame,
+ local->fd,
+ waiter_page->offset);
+ }
+ }
+ }
+
+ waited = waiter;
+ waiter = waiter->next;
+
+ waited->data = NULL;
+ free (waited);
+ }
}
-
-/*
- * ioc_inode_update - create a new ioc_inode_t structure and add it to
- * the table table. fill in the fields which are derived
+/*
+ * ioc_inode_update - create a new ioc_inode_t structure and add it to
+ * the table table. fill in the fields which are derived
* from inode_t corresponding to the file
- *
+ *
* @table: io-table structure
* @inode: inode structure
*
@@ -174,67 +154,64 @@ out:
ioc_inode_t *
ioc_inode_update (ioc_table_t *table, inode_t *inode, uint32_t weight)
{
- ioc_inode_t *ioc_inode = NULL;
+ ioc_inode_t *ioc_inode = NULL;
+ unsigned long no_of_pages = 0;
- GF_VALIDATE_OR_GOTO ("io-cache", table, out);
-
- ioc_inode = GF_CALLOC (1, sizeof (ioc_inode_t), gf_ioc_mt_ioc_inode_t);
+ ioc_inode = CALLOC (1, sizeof (ioc_inode_t));
if (ioc_inode == NULL) {
goto out;
}
+
+ ioc_inode->table = table;
- ioc_inode->inode = inode;
- ioc_inode->table = table;
- INIT_LIST_HEAD (&ioc_inode->cache.page_lru);
- pthread_mutex_init (&ioc_inode->inode_lock, NULL);
- ioc_inode->weight = weight;
-
- ioc_table_lock (table);
- {
- table->inode_count++;
- list_add (&ioc_inode->inode_list, &table->inodes);
- list_add_tail (&ioc_inode->inode_lru,
- &table->inode_lru[weight]);
- }
- ioc_table_unlock (table);
+ no_of_pages = (table->cache_size / table->page_size)
+ + ((table->cache_size % table->page_size) ? 1 : 0);
- gf_log (table->xl->name, GF_LOG_TRACE,
- "adding to inode_lru[%d]", weight);
+ INIT_LIST_HEAD (&ioc_inode->cache.page_lru);
+ ioc_table_lock (table);
+
+ table->inode_count++;
+ list_add (&ioc_inode->inode_list, &table->inodes);
+ list_add_tail (&ioc_inode->inode_lru, &table->inode_lru[weight]);
+
+ gf_log (table->xl->name,
+ GF_LOG_TRACE,
+ "adding to inode_lru[%d]", weight);
+
+ ioc_table_unlock (table);
+
+ pthread_mutex_init (&ioc_inode->inode_lock, NULL);
+ ioc_inode->weight = weight;
+
out:
- return ioc_inode;
+ return ioc_inode;
}
-/*
+/*
* ioc_inode_destroy - destroy an ioc_inode_t object.
*
* @inode: inode to destroy
*
- * to be called only from ioc_forget.
+ * to be called only from ioc_forget.
*/
void
ioc_inode_destroy (ioc_inode_t *ioc_inode)
{
- ioc_table_t *table = NULL;
-
- GF_VALIDATE_OR_GOTO ("io-cache", ioc_inode, out);
+ ioc_table_t *table = NULL;
table = ioc_inode->table;
- ioc_table_lock (table);
- {
- table->inode_count--;
- list_del (&ioc_inode->inode_list);
- list_del (&ioc_inode->inode_lru);
- }
- ioc_table_unlock (table);
-
- ioc_inode_flush (ioc_inode);
+ ioc_table_lock (table);
+ table->inode_count--;
+ list_del (&ioc_inode->inode_list);
+ list_del (&ioc_inode->inode_lru);
+ ioc_table_unlock (table);
+
+ ioc_inode_flush (ioc_inode);
rbthash_table_destroy (ioc_inode->cache.page_table);
- pthread_mutex_destroy (&ioc_inode->inode_lock);
- GF_FREE (ioc_inode);
-out:
- return;
+ pthread_mutex_destroy (&ioc_inode->inode_lock);
+ free (ioc_inode);
}
diff --git a/xlators/performance/io-cache/src/ioc-mem-types.h b/xlators/performance/io-cache/src/ioc-mem-types.h
deleted file mode 100644
index 9b68f9fce5f..00000000000
--- a/xlators/performance/io-cache/src/ioc-mem-types.h
+++ /dev/null
@@ -1,29 +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 __IOC_MT_H__
-#define __IOC_MT_H__
-
-#include "mem-types.h"
-
-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_waitq_t,
- gf_ioc_mt_ioc_priority,
- gf_ioc_mt_list_head,
- gf_ioc_mt_call_pool_t,
- gf_ioc_mt_ioc_inode_t,
- gf_ioc_mt_ioc_fill_t,
- gf_ioc_mt_ioc_newpage_t,
- gf_ioc_mt_end
-};
-#endif
diff --git a/xlators/performance/io-cache/src/page.c b/xlators/performance/io-cache/src/page.c
index 416cd5fe44e..964f8d01a09 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-2009 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 General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that 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
@@ -18,178 +27,80 @@
#include "dict.h"
#include "xlator.h"
#include "io-cache.h"
-#include "ioc-mem-types.h"
#include <assert.h>
#include <sys/time.h>
char
ioc_empty (struct ioc_cache *cache)
{
- char is_empty = -1;
-
- GF_VALIDATE_OR_GOTO ("io-cache", cache, out);
-
- is_empty = list_empty (&cache->page_lru);
-
-out:
- return is_empty;
+ return list_empty (&cache->page_lru);
}
-
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;
- off_t rounded_offset = 0;
-
- GF_VALIDATE_OR_GOTO ("io-cache", ioc_inode, out);
+ ioc_page_t *page = NULL;
+ ioc_table_t *table = NULL;
+ off_t rounded_offset = 0;
table = ioc_inode->table;
- GF_VALIDATE_OR_GOTO ("io-cache", ioc_inode, out);
-
rounded_offset = floor (offset, table->page_size);
-
+
page = rbthash_get (ioc_inode->cache.page_table, &rounded_offset,
sizeof (rounded_offset));
if (page != NULL) {
- /* push the page to the end of the lru list */
- list_move_tail (&page->page_lru, &ioc_inode->cache.page_lru);
- }
-
-out:
- return page;
-}
-
-
-ioc_page_t *
-ioc_page_get (ioc_inode_t *ioc_inode, off_t offset)
-{
- ioc_page_t *page = NULL;
+ /* push the page to the end of the lru list */
+ list_move_tail (&page->page_lru, &ioc_inode->cache.page_lru);
+ }
- 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;
+ 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;
-
- GF_VALIDATE_OR_GOTO ("io-cache", page, out);
+ int64_t page_size = 0;
- if (page->iobref)
- page_size = iobref_size (page->iobref);
+ page_size = iobref_size (page->iobref);
- if (page->waitq) {
- /* frames waiting on this page, do not destroy this page */
- page_size = -1;
- page->stale = 1;
- } else {
+ if (page->waitq) {
+ /* frames waiting on this page, do not destroy this page */
+ page_size = -1;
+ } else {
rbthash_remove (page->inode->cache.page_table, &page->offset,
sizeof (page->offset));
- list_del (&page->page_lru);
-
- gf_log (page->inode->table->xl->name, GF_LOG_TRACE,
- "destroying page = %p, offset = %"PRId64" "
- "&& inode = %p",
- page, page->offset, page->inode);
-
- if (page->vector){
- iobref_unref (page->iobref);
- GF_FREE (page->vector);
- page->vector = NULL;
- }
-
- page->inode = NULL;
- }
-
- if (page_size != -1) {
- pthread_mutex_destroy (&page->page_lock);
- GF_FREE (page);
- }
-
-out:
- return page_size;
-}
-
-
-int64_t
-ioc_page_destroy (ioc_page_t *page)
-{
- int64_t ret = 0;
- struct ioc_inode *inode = NULL;
-
- if (page == NULL) {
- goto out;
- }
-
- ioc_inode_lock (page->inode);
- {
- inode = page->inode;
- ret = __ioc_page_destroy (page);
- }
- ioc_inode_unlock (inode);
-
-out:
- return ret;
+ list_del (&page->page_lru);
+
+ gf_log (page->inode->table->xl->name, GF_LOG_TRACE,
+ "destroying page = %p, offset = %"PRId64" "
+ "&& inode = %p",
+ page, page->offset, page->inode);
+
+ if (page->vector){
+ iobref_unref (page->iobref);
+ free (page->vector);
+ page->vector = NULL;
+ }
+
+ page->inode = NULL;
+ }
+
+ if (page_size != -1) {
+ pthread_mutex_destroy (&page->page_lock);
+ free (page);
+ }
+
+ return page_size;
}
-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.
@@ -200,150 +111,161 @@ out:
int32_t
ioc_prune (ioc_table_t *table)
{
- ioc_inode_t *curr = NULL, *next_ioc_inode = NULL;
- int32_t index = 0;
- uint64_t size_to_prune = 0;
- uint64_t size_pruned = 0;
-
- GF_VALIDATE_OR_GOTO ("io-cache", table, out);
-
- ioc_table_lock (table);
- {
- size_to_prune = table->cache_used - table->cache_size;
- /* take out the least recently used inode */
- for (index=0; index < table->max_pri; index++) {
- list_for_each_entry_safe (curr, next_ioc_inode,
- &table->inode_lru[index],
- inode_lru) {
- /* 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);
- }
- ioc_inode_unlock (curr);
-
- if (size_pruned >= size_to_prune)
- break;
- } /* list_for_each_entry_safe (curr...) */
-
- if (size_pruned >= size_to_prune)
- break;
- } /* for(index=0;...) */
-
- } /* ioc_inode_table locked region end */
- ioc_table_unlock (table);
-
-out:
- return 0;
+ 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;
+
+ ioc_table_lock (table);
+ {
+ size_to_prune = table->cache_used - table->cache_size;
+ /* take out the least recently used inode */
+ for (index=0; index < table->max_pri; index++) {
+ list_for_each_entry_safe (curr, next_ioc_inode,
+ &table->inode_lru[index],
+ inode_lru) {
+ /* prune page-by-page for this inode, till
+ * we reach the equilibrium */
+ ioc_inode_lock (curr);
+ /* { */
+
+ 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)
+ break;
+ } /* list_for_each_entry_safe (curr...) */
+
+ if (size_pruned >= size_to_prune)
+ break;
+ } /* for(index=0;...) */
+
+ } /* ioc_inode_table locked region end */
+ ioc_table_unlock (table);
+
+ return 0;
}
/*
- * __ioc_page_create - create a new page.
+ * ioc_page_create - create a new page.
*
- * @ioc_inode:
+ * @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;
- off_t rounded_offset = 0;
- ioc_page_t *newpage = NULL;
-
- GF_VALIDATE_OR_GOTO ("io-cache", ioc_inode, out);
-
+ ioc_table_t *table = NULL;
+ ioc_page_t *page = NULL;
+ off_t rounded_offset = 0;
+ ioc_page_t *newpage = NULL;
+
table = ioc_inode->table;
- GF_VALIDATE_OR_GOTO ("io-cache", table, out);
-
rounded_offset = floor (offset, table->page_size);
- newpage = GF_CALLOC (1, sizeof (*newpage), gf_ioc_mt_ioc_newpage_t);
+ newpage = CALLOC (1, sizeof (*newpage));
if (newpage == NULL) {
goto out;
}
- if (!ioc_inode) {
- GF_FREE (newpage);
+ if (ioc_inode) {
+ table = ioc_inode->table;
+ } else {
+ free (newpage);
newpage = NULL;
goto out;
- }
-
- newpage->offset = rounded_offset;
- newpage->inode = ioc_inode;
- pthread_mutex_init (&newpage->page_lock, NULL);
+ }
+
+ newpage->offset = rounded_offset;
+ newpage->inode = ioc_inode;
+ pthread_mutex_init (&newpage->page_lock, NULL);
rbthash_insert (ioc_inode->cache.page_table, newpage, &rounded_offset,
sizeof (rounded_offset));
+
+ list_add_tail (&newpage->page_lru, &ioc_inode->cache.page_lru);
- list_add_tail (&newpage->page_lru, &ioc_inode->cache.page_lru);
+ page = newpage;
- page = newpage;
-
- gf_log ("io-cache", GF_LOG_TRACE,
- "returning new page %p", page);
+ gf_log ("io-cache", GF_LOG_TRACE,
+ "returning new page %p", page);
out:
- return page;
+ return page;
}
-/*
- * ioc_wait_on_page - pause a frame to wait till the arrival of a page.
- * here we need to handle the case when the frame who calls wait_on_page
- * himself has caused page_fault
+/*
+ * ioc_wait_on_page - pause a frame to wait till the arrival of a page.
+ * here we need to handle the case when the frame who calls wait_on_page
+ * himself has caused page_fault
*
* @page: page to wait on
* @frame: call frame who is waiting on page
*
*/
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;
-
- GF_VALIDATE_OR_GOTO ("io-cache", frame, out);
- local = frame->local;
-
- GF_VALIDATE_OR_GOTO (frame->this->name, local, out);
-
- if (page == NULL) {
- local->op_ret = -1;
- local->op_errno = ENOMEM;
- gf_log (frame->this->name, GF_LOG_WARNING,
- "asked to wait on a NULL page");
- goto out;
- }
+ ioc_waitq_t *waitq = NULL;
+ ioc_local_t *local = frame->local;
- waitq = GF_CALLOC (1, sizeof (*waitq), gf_ioc_mt_ioc_waitq_t);
+ waitq = CALLOC (1, sizeof (*waitq));
if (waitq == NULL) {
local->op_ret = -1;
local->op_errno = ENOMEM;
+ gf_log (frame->this->name, GF_LOG_ERROR, "out of memory");
goto out;
- }
-
- gf_log (frame->this->name, GF_LOG_TRACE,
- "frame(%p) waiting on page = %p, offset=%"PRId64", "
- "size=%"GF_PRI_SIZET"",
- frame, page, offset, size);
-
- waitq->data = frame;
- waitq->next = page->waitq;
- waitq->pending_offset = offset;
- waitq->pending_size = size;
- page->waitq = waitq;
- /* one frame can wait only once on a given page,
- * local->wait_count is number of pages a frame is waiting on */
- ioc_local_lock (local);
- {
- local->wait_count++;
- }
- ioc_local_unlock (local);
+ }
+
+ gf_log (frame->this->name, GF_LOG_TRACE,
+ "frame(%p) waiting on page = %p, offset=%"PRId64", "
+ "size=%"GF_PRI_SIZET"",
+ frame, page, offset, size);
+
+ waitq->data = frame;
+ waitq->next = page->waitq;
+ waitq->pending_offset = offset;
+ waitq->pending_size = size;
+ page->waitq = waitq;
+ /* one frame can wait only once on a given page,
+ * local->wait_count is number of pages a frame is waiting on */
+ ioc_local_lock (local);
+ {
+ local->wait_count++;
+ }
+ ioc_local_unlock (local);
out:
return;
@@ -351,7 +273,7 @@ out:
/*
- * ioc_cache_still_valid - see if cached pages ioc_inode are still valid
+ * ioc_cache_still_valid - see if cached pages ioc_inode are still valid
* against given stbuf
*
* @ioc_inode:
@@ -360,213 +282,204 @@ out:
* assumes ioc_inode is locked
*/
int8_t
-ioc_cache_still_valid (ioc_inode_t *ioc_inode, struct iatt *stbuf)
+ioc_cache_still_valid (ioc_inode_t *ioc_inode, struct stat *stbuf)
{
- int8_t cache_still_valid = 1;
-
- GF_VALIDATE_OR_GOTO ("io-cache", ioc_inode, out);
+ int8_t cache_still_valid = 1;
#if 0
- if (!stbuf || (stbuf->ia_mtime != ioc_inode->cache.mtime) ||
- (stbuf->st_mtim.tv_nsec != ioc_inode->stbuf.st_mtim.tv_nsec))
- cache_still_valid = 0;
+ if (!stbuf || (stbuf->st_mtime != ioc_inode->cache.mtime) ||
+ (stbuf->st_mtim.tv_nsec != ioc_inode->stbuf.st_mtim.tv_nsec))
+ cache_still_valid = 0;
#else
- if (!stbuf || (stbuf->ia_mtime != ioc_inode->cache.mtime)
- || (stbuf->ia_mtime_nsec != ioc_inode->cache.mtime_nsec))
- cache_still_valid = 0;
+ if (!stbuf || (stbuf->st_mtime != ioc_inode->cache.mtime)
+ || (ST_MTIM_NSEC(stbuf) != ioc_inode->cache.mtime_nsec))
+ cache_still_valid = 0;
#endif
#if 0
- /* talk with avati@gluster.com to enable this section */
- if (!ioc_inode->mtime && stbuf) {
- cache_still_valid = 1;
- ioc_inode->mtime = stbuf->ia_mtime;
- }
+ /* talk with avati@gluster.com to enable this section */
+ if (!ioc_inode->mtime && stbuf) {
+ cache_still_valid = 1;
+ ioc_inode->mtime = stbuf->st_mtime;
+ }
#endif
-out:
- return cache_still_valid;
+ return cache_still_valid;
}
void
ioc_waitq_return (ioc_waitq_t *waitq)
{
- ioc_waitq_t *trav = NULL;
- ioc_waitq_t *next = NULL;
- call_frame_t *frame = NULL;
+ ioc_waitq_t *trav = NULL;
+ ioc_waitq_t *next = NULL;
+ call_frame_t *frame = NULL;
- for (trav = waitq; trav; trav = next) {
- next = trav->next;
+ for (trav = waitq; trav; trav = next) {
+ next = trav->next;
- frame = trav->data;
- ioc_frame_return (frame);
- GF_FREE (trav);
- }
+ frame = trav->data;
+ ioc_frame_return (frame);
+ free (trav);
+ }
}
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 stat *stbuf, struct iobref *iobref)
{
- ioc_local_t *local = NULL;
- off_t offset = 0;
- ioc_inode_t *ioc_inode = NULL;
- ioc_table_t *table = NULL;
- ioc_page_t *page = NULL;
- int32_t destroy_size = 0;
- size_t page_size = 0;
- ioc_waitq_t *waitq = NULL;
- size_t iobref_page_size = 0;
- char zero_filled = 0;
-
- GF_ASSERT (frame);
+ ioc_local_t *local = NULL;
+ off_t offset = 0;
+ ioc_inode_t *ioc_inode = NULL;
+ ioc_table_t *table = NULL;
+ ioc_page_t *page = NULL;
+ off_t trav_offset = 0;
+ size_t payload_size = 0;
+ int32_t destroy_size = 0;
+ size_t page_size = 0;
+ ioc_waitq_t *waitq = NULL;
+ size_t iobref_page_size = 0;
+ char zero_filled = 0;
local = frame->local;
- GF_ASSERT (local);
-
offset = local->pending_offset;
ioc_inode = local->inode;
- GF_ASSERT (ioc_inode);
-
table = ioc_inode->table;
- GF_ASSERT (table);
-
- zero_filled = ((op_ret >=0) && (stbuf->ia_mtime == 0));
-
- ioc_inode_lock (ioc_inode);
- {
- if (op_ret == -1 || !(zero_filled ||
- ioc_cache_still_valid(ioc_inode,
- stbuf))) {
- gf_log (ioc_inode->table->xl->name, GF_LOG_TRACE,
- "cache for inode(%p) is invalid. flushing "
- "all pages", ioc_inode);
- destroy_size = __ioc_inode_flush (ioc_inode);
- }
- if ((op_ret >= 0) && !zero_filled) {
- ioc_inode->cache.mtime = stbuf->ia_mtime;
- ioc_inode->cache.mtime_nsec = stbuf->ia_mtime_nsec;
+ trav_offset = offset;
+ payload_size = op_ret;
+
+ zero_filled = ((op_ret >=0)
+ && (stbuf->st_mtime == 0));
+
+ ioc_inode_lock (ioc_inode);
+ {
+ if (op_ret == -1 ||
+ !(zero_filled ||
+ ioc_cache_still_valid(ioc_inode, stbuf))) {
+ gf_log (ioc_inode->table->xl->name, GF_LOG_TRACE,
+ "cache for inode(%p) is invalid. flushing "
+ "all pages", ioc_inode);
+ destroy_size = __ioc_inode_flush (ioc_inode);
+ }
+
+ if ((op_ret >= 0) && !zero_filled) {
+ ioc_inode->cache.mtime = stbuf->st_mtime;
+ ST_MTIM_NSEC_SET(stbuf, ioc_inode->cache.mtime_nsec);
}
- gettimeofday (&ioc_inode->cache.tv, NULL);
-
- if (op_ret < 0) {
- /* error, readv returned -1 */
- page = __ioc_page_get (ioc_inode, offset);
- if (page)
- 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);
- if (!page) {
- /* page was flushed */
- /* some serious bug ? */
- gf_log (frame->this->name, GF_LOG_WARNING,
- "wasted copy: %"PRId64"[+%"PRId64"] "
- "ioc_inode=%p", offset,
- table->page_size, ioc_inode);
- } else {
- if (page->vector) {
- iobref_unref (page->iobref);
- GF_FREE (page->vector);
- page->vector = NULL;
- page->iobref = NULL;
- }
-
- /* keep a copy of the page for our cache */
- page->vector = iov_dup (vector, count);
+ gettimeofday (&ioc_inode->cache.tv, NULL);
+
+ if (op_ret < 0) {
+ /* error, readv returned -1 */
+ page = ioc_page_get (ioc_inode, offset);
+ if (page)
+ 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);
+ if (!page) {
+ /* page was flushed */
+ /* some serious bug ? */
+ gf_log (this->name, GF_LOG_DEBUG,
+ "wasted copy: %"PRId64"[+%"PRId64"] "
+ "ioc_inode=%p", offset,
+ table->page_size, ioc_inode);
+ } else {
+ if (page->vector) {
+ iobref_unref (page->iobref);
+ free (page->vector);
+ page->vector = NULL;
+ }
+
+ /* 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);
+ op_ret = -1;
+ op_errno = ENOMEM;
goto unlock;
}
- page->count = count;
- if (iobref) {
- page->iobref = iobref_ref (iobref);
- } else {
- /* TODO: we have got a response to
- * our request and no data */
- gf_log (frame->this->name,
- GF_LOG_CRITICAL,
- "frame>root>rsp_refs is null");
- } /* if(frame->root->rsp_refs) */
-
- /* page->size should indicate exactly how
- * much the readv call to the child
- * translator returned. earlier op_ret
- * from child translator was used, which
- * gave rise to a bug where reads from
- * io-cached volume were resulting in 0
- * byte replies */
- page_size = iov_length(vector, count);
- page->size = page_size;
- page->op_errno = op_errno;
+ page->count = count;
+ if (iobref) {
+ page->iobref = iobref_ref (iobref);
+ } else {
+ /* TODO: we have got a response to
+ * our request and no data */
+ gf_log (this->name, GF_LOG_CRITICAL,
+ "frame>root>rsp_refs is null");
+ } /* if(frame->root->rsp_refs) */
+
+ /* page->size should indicate exactly how
+ * much the readv call to the child
+ * translator returned. earlier op_ret
+ * from child translator was used, which
+ * gave rise to a bug where reads from
+ * io-cached volume were resulting in 0
+ * byte replies */
+ page_size = iov_length(vector, count);
+
+ page->size = page_size;
iobref_page_size = iobref_size (page->iobref);
- if (page->waitq) {
- /* wake up all the frames waiting on
- * this page, including
- * the frame which triggered fault */
- waitq = __ioc_page_wakeup (page,
- op_errno);
- } /* if(page->waitq) */
- } /* if(!page)...else */
- } /* if(op_ret < 0)...else */
- } /* ioc_inode locked region end */
+ if (page->waitq) {
+ /* wake up all the frames waiting on
+ * this page, including
+ * the frame which triggered fault */
+ waitq = ioc_page_wakeup (page);
+ } /* if(page->waitq) */
+ } /* if(!page)...else */
+ } /* if(op_ret < 0)...else */
+ } /* ioc_inode locked region end */
unlock:
- ioc_inode_unlock (ioc_inode);
+ ioc_inode_unlock (ioc_inode);
- ioc_waitq_return (waitq);
+ ioc_waitq_return (waitq);
- if (iobref_page_size) {
- ioc_table_lock (table);
- {
- table->cache_used += iobref_page_size;
- }
- ioc_table_unlock (table);
- }
+ if (iobref_page_size) {
+ ioc_table_lock (table);
+ {
+ table->cache_used += iobref_page_size;
+ }
+ ioc_table_unlock (table);
+ }
- if (destroy_size) {
- ioc_table_lock (table);
- {
- table->cache_used -= destroy_size;
- }
- ioc_table_unlock (table);
- }
+ if (destroy_size) {
+ ioc_table_lock (table);
+ {
+ table->cache_used -= destroy_size;
+ }
+ ioc_table_unlock (table);
+ }
- if (ioc_need_prune (ioc_inode->table)) {
- ioc_prune (ioc_inode->table);
- }
+ if (ioc_need_prune (ioc_inode->table)) {
+ ioc_prune (ioc_inode->table);
+ }
- gf_log (frame->this->name, GF_LOG_TRACE, "fault frame %p returned",
- frame);
- pthread_mutex_destroy (&local->local_lock);
+ gf_log (this->name, GF_LOG_TRACE, "fault frame %p returned", frame);
+ pthread_mutex_destroy (&local->local_lock);
- fd_unref (local->fd);
+ fd_unref (local->fd);
- STACK_DESTROY (frame->root);
- return 0;
+ STACK_DESTROY (frame->root);
+ return 0;
}
-
/*
* ioc_page_fault -
- *
+ *
* @ioc_inode:
* @frame:
* @fd:
@@ -574,223 +487,201 @@ unlock:
*
*/
void
-ioc_page_fault (ioc_inode_t *ioc_inode, call_frame_t *frame, fd_t *fd,
- off_t offset)
+ioc_page_fault (ioc_inode_t *ioc_inode, call_frame_t *frame, fd_t *fd,
+ off_t offset)
{
- ioc_table_t *table = NULL;
- call_frame_t *fault_frame = NULL;
- ioc_local_t *fault_local = NULL;
- int32_t op_ret = -1, op_errno = -1;
- ioc_waitq_t *waitq = NULL;
- ioc_page_t *page = NULL;
-
- GF_ASSERT (ioc_inode);
- if (frame == NULL) {
- op_ret = -1;
- op_errno = EINVAL;
- gf_log ("io-cache", GF_LOG_WARNING,
- "page fault on a NULL frame");
- goto err;
- }
+ ioc_table_t *table = NULL;
+ call_frame_t *fault_frame = NULL;
+ ioc_local_t *fault_local = NULL;
+ int32_t op_ret = -1, op_errno = -1;
+ ioc_waitq_t *waitq = NULL;
+ ioc_page_t *page = NULL;
table = ioc_inode->table;
fault_frame = copy_frame (frame);
if (fault_frame == NULL) {
op_ret = -1;
op_errno = ENOMEM;
+ gf_log (ioc_inode->table->xl->name, GF_LOG_ERROR,
+ "out of memory");
goto err;
}
- fault_local = mem_get0 (THIS->local_pool);
+ fault_local = CALLOC (1, sizeof (ioc_local_t));
if (fault_local == NULL) {
op_ret = -1;
op_errno = ENOMEM;
STACK_DESTROY (fault_frame->root);
+ gf_log (ioc_inode->table->xl->name, GF_LOG_ERROR,
+ "out of memory");
goto err;
}
- /* NOTE: copy_frame() means, the frame the fop whose fd_ref we
- * are using till now won't be valid till we get reply from server.
- * we unref this fd, in fault_cbk */
- fault_local->fd = fd_ref (fd);
-
- fault_frame->local = fault_local;
- pthread_mutex_init (&fault_local->local_lock, NULL);
+ /* NOTE: copy_frame() means, the frame the fop whose fd_ref we
+ * are using till now won't be valid till we get reply from server.
+ * we unref this fd, in fault_cbk */
+ fault_local->fd = fd_ref (fd);
- INIT_LIST_HEAD (&fault_local->fill_list);
- fault_local->pending_offset = offset;
- fault_local->pending_size = table->page_size;
- fault_local->inode = ioc_inode;
+ fault_frame->local = fault_local;
+ pthread_mutex_init (&fault_local->local_lock, NULL);
- gf_log (frame->this->name, GF_LOG_TRACE,
- "stack winding page fault for offset = %"PRId64" with "
- "frame %p", offset, fault_frame);
+ INIT_LIST_HEAD (&fault_local->fill_list);
+ fault_local->pending_offset = offset;
+ fault_local->pending_size = table->page_size;
+ fault_local->inode = ioc_inode;
- 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);
- return;
+ gf_log (frame->this->name, GF_LOG_TRACE,
+ "stack winding page fault for offset = %"PRId64" with "
+ "frame %p", offset, fault_frame);
+
+ STACK_WIND (fault_frame, ioc_fault_cbk, FIRST_CHILD(fault_frame->this),
+ FIRST_CHILD(fault_frame->this)->fops->readv, fd,
+ 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;
- off_t src_offset = 0;
- off_t dst_offset = 0;
- ssize_t copy_size = 0;
- ioc_inode_t *ioc_inode = NULL;
- ioc_fill_t *new = NULL;
- int8_t found = 0;
- int32_t ret = -1;
-
- GF_VALIDATE_OR_GOTO ("io-cache", frame, out);
-
+ ioc_local_t *local = NULL;
+ ioc_fill_t *fill = NULL;
+ off_t src_offset = 0;
+ off_t dst_offset = 0;
+ ssize_t copy_size = 0;
+ ioc_inode_t *ioc_inode = NULL;
+ ioc_fill_t *new = NULL;
+ int8_t found = 0;
+ int32_t ret = 0;
+
local = frame->local;
- GF_VALIDATE_OR_GOTO (frame->this->name, local, out);
-
- if (page == NULL) {
- gf_log (frame->this->name, GF_LOG_WARNING,
- "NULL page has been provided to serve read request");
- local->op_ret = -1;
- local->op_errno = EINVAL;
- goto out;
- }
-
ioc_inode = page->inode;
- gf_log (frame->this->name, GF_LOG_TRACE,
- "frame (%p) offset = %"PRId64" && size = %"GF_PRI_SIZET" "
- "&& page->size = %"GF_PRI_SIZET" && wait_count = %d",
- frame, offset, size, page->size, local->wait_count);
-
- /* 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 (offset > page->offset)
- /* offset is offset in file, convert it to offset in
- * page */
- src_offset = offset - page->offset;
- /*FIXME: since offset is the offset within page is the
- * else case valid? */
- else
- /* local->pending_offset is in previous page. do not
- * fill until we have filled all previous pages */
- dst_offset = page->offset - offset;
-
- /* we have to copy from offset to either end of this page
- * or till the requested size */
- copy_size = min (page->size - src_offset,
- size - dst_offset);
-
- if (copy_size < 0) {
- /* if page contains fewer bytes and the required offset
- is beyond the page size in the page */
- copy_size = src_offset = 0;
- }
-
- gf_log (page->inode->table->xl->name, GF_LOG_TRACE,
- "copy_size = %"GF_PRI_SIZET" && src_offset = "
- "%"PRId64" && dst_offset = %"PRId64"",
- copy_size, src_offset, dst_offset);
-
- {
- new = GF_CALLOC (1, sizeof (*new),
- gf_ioc_mt_ioc_fill_t);
+ gf_log (frame->this->name, GF_LOG_TRACE,
+ "frame (%p) offset = %"PRId64" && size = %"GF_PRI_SIZET" "
+ "&& page->size = %"GF_PRI_SIZET" && wait_count = %d",
+ frame, offset, size, page->size, local->wait_count);
+
+ /* 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 && page->size) {
+ if (offset > page->offset)
+ /* offset is offset in file, convert it to offset in
+ * page */
+ src_offset = offset - page->offset;
+ /*FIXME: since offset is the offset within page is the
+ * else case valid? */
+ else
+ /* local->pending_offset is in previous page. do not
+ * fill until we have filled all previous pages */
+ dst_offset = page->offset - offset;
+
+ /* we have to copy from offset to either end of this page
+ * or till the requested size */
+ copy_size = min (page->size - src_offset,
+ size - dst_offset);
+
+ if (copy_size < 0) {
+ /* if page contains fewer bytes and the required offset
+ is beyond the page size in the page */
+ copy_size = src_offset = 0;
+ }
+
+ gf_log (page->inode->table->xl->name, GF_LOG_TRACE,
+ "copy_size = %"GF_PRI_SIZET" && src_offset = "
+ "%"PRId64" && dst_offset = %"PRId64"",
+ copy_size, src_offset, dst_offset);
+
+ {
+ new = CALLOC (1, sizeof (*new));
if (new == NULL) {
local->op_ret = -1;
local->op_errno = ENOMEM;
+ ret = -1;
+ gf_log (page->inode->table->xl->name,
+ GF_LOG_ERROR, "out of memory");
goto out;
}
- new->offset = page->offset;
- new->size = copy_size;
- new->iobref = iobref_ref (page->iobref);
- new->count = iov_subset (page->vector, page->count,
- src_offset,
- src_offset + copy_size,
- NULL);
-
- new->vector = GF_CALLOC (new->count,
- sizeof (struct iovec),
- gf_ioc_mt_iovec);
+ new->offset = page->offset;
+ new->size = copy_size;
+ new->iobref = iobref_ref (page->iobref);
+ new->count = iov_subset (page->vector,
+ page->count,
+ src_offset,
+ src_offset + copy_size,
+ NULL);
+
+ new->vector = CALLOC (new->count,
+ sizeof (struct iovec));
if (new->vector == NULL) {
local->op_ret = -1;
local->op_errno = ENOMEM;
iobref_unref (new->iobref);
- GF_FREE (new);
+ FREE (new);
+
+ ret = -1;
+ gf_log (page->inode->table->xl->name,
+ GF_LOG_ERROR, "out of memory");
goto out;
}
- new->count = iov_subset (page->vector, page->count,
- src_offset,
- src_offset + copy_size,
- new->vector);
-
- /* add the ioc_fill to fill_list for this frame */
- if (list_empty (&local->fill_list)) {
- /* if list is empty, then this is the first
- * time we are filling frame, add the
- * ioc_fill_t to the end of list */
- list_add_tail (&new->list, &local->fill_list);
- } else {
- found = 0;
- /* list is not empty, we need to look for
- * where this offset fits in list */
- list_for_each_entry (fill, &local->fill_list,
- list) {
- if (fill->offset > new->offset) {
- found = 1;
- break;
- }
- }
+ new->count = iov_subset (page->vector,
+ page->count,
+ src_offset,
+ src_offset + copy_size,
+ new->vector);
- if (found) {
- list_add_tail (&new->list,
- &fill->list);
- } else {
- list_add_tail (&new->list,
- &local->fill_list);
- }
- }
- }
- local->op_ret += copy_size;
- }
-done:
- ret = 0;
+ /* add the ioc_fill to fill_list for this frame */
+ if (list_empty (&local->fill_list)) {
+ /* if list is empty, then this is the first
+ * time we are filling frame, add the
+ * ioc_fill_t to the end of list */
+ list_add_tail (&new->list, &local->fill_list);
+ } else {
+ found = 0;
+ /* list is not empty, we need to look for
+ * where this offset fits in list */
+ list_for_each_entry (fill, &local->fill_list,
+ list) {
+ if (fill->offset > new->offset) {
+ found = 1;
+ break;
+ }
+ }
+
+ if (found) {
+ found = 0;
+ list_add_tail (&new->list,
+ &fill->list);
+ } else {
+ list_add_tail (&new->list,
+ &local->fill_list);
+ }
+ }
+ }
+ local->op_ret += copy_size;
+ }
+
out:
return ret;
}
/*
- * ioc_frame_unwind - frame unwinds only from here
+ * ioc_frame_unwind - frame unwinds only from here
*
* @frame: call frame to unwind
*
@@ -801,102 +692,84 @@ out:
static void
ioc_frame_unwind (call_frame_t *frame)
{
- ioc_local_t *local = NULL;
- ioc_fill_t *fill = NULL, *next = NULL;
- int32_t count = 0;
- struct iovec *vector = NULL;
- int32_t copied = 0;
- struct iobref *iobref = NULL;
- struct iatt stbuf = {0,};
- int32_t op_ret = 0, op_errno = 0;
-
- GF_ASSERT (frame);
+ ioc_local_t *local = NULL;
+ ioc_fill_t *fill = NULL, *next = NULL;
+ int32_t count = 0;
+ struct iovec *vector = NULL;
+ int32_t copied = 0;
+ struct iobref *iobref = NULL;
+ struct stat stbuf = {0,};
+ int32_t op_ret = 0, op_errno = 0;
local = frame->local;
- if (local == NULL) {
- gf_log (frame->this->name, GF_LOG_WARNING,
- "local is NULL");
- op_ret = -1;
- op_errno = ENOMEM;
- goto unwind;
- }
-
- if (local->op_ret < 0) {
- op_ret = local->op_ret;
- op_errno = local->op_errno;
- goto unwind;
- }
-
- // ioc_local_lock (local);
- iobref = iobref_new ();
+ // ioc_local_lock (local);
+ frame->local = NULL;
+ iobref = iobref_new ();
if (iobref == NULL) {
op_ret = -1;
op_errno = ENOMEM;
+ gf_log (frame->this->name, GF_LOG_ERROR, "out of memory");
}
- if (list_empty (&local->fill_list)) {
- gf_log (frame->this->name, GF_LOG_TRACE,
- "frame(%p) has 0 entries in local->fill_list "
- "(offset = %"PRId64" && size = %"GF_PRI_SIZET")",
- frame, local->offset, local->size);
- }
+ if (list_empty (&local->fill_list)) {
+ gf_log (frame->this->name, GF_LOG_TRACE,
+ "frame(%p) has 0 entries in local->fill_list "
+ "(offset = %"PRId64" && size = %"GF_PRI_SIZET")",
+ frame, local->offset, local->size);
+ }
- list_for_each_entry (fill, &local->fill_list, list) {
- count += fill->count;
- }
+ list_for_each_entry (fill, &local->fill_list, list) {
+ count += fill->count;
+ }
- vector = GF_CALLOC (count, sizeof (*vector), gf_ioc_mt_iovec);
+ vector = CALLOC (count, sizeof (*vector));
if (vector == NULL) {
op_ret = -1;
op_errno = ENOMEM;
+
+ gf_log (frame->this->name, GF_LOG_ERROR, "out of memory");
}
-
- list_for_each_entry_safe (fill, next, &local->fill_list, list) {
- if ((vector != NULL) && (iobref != NULL)) {
+
+ list_for_each_entry_safe (fill, next, &local->fill_list, list) {
+ if ((vector != NULL) && (iobref != NULL)) {
memcpy (((char *)vector) + copied,
fill->vector,
fill->count * sizeof (*vector));
-
+
copied += (fill->count * sizeof (*vector));
- if (iobref_merge (iobref, fill->iobref)) {
- op_ret = -1;
- op_errno = ENOMEM;
- }
+ iobref_merge (iobref, fill->iobref);
}
- list_del (&fill->list);
- iobref_unref (fill->iobref);
- GF_FREE (fill->vector);
- GF_FREE (fill);
- }
-
+ list_del (&fill->list);
+ iobref_unref (fill->iobref);
+ free (fill->vector);
+ free (fill);
+ }
+
if (op_ret != -1) {
op_ret = iov_length (vector, count);
}
-unwind:
- gf_log (frame->this->name, GF_LOG_TRACE,
- "frame(%p) unwinding with op_ret=%d", frame, op_ret);
+ gf_log (frame->this->name, GF_LOG_TRACE,
+ "frame(%p) unwinding with op_ret=%d", frame, op_ret);
- // ioc_local_unlock (local);
+ // ioc_local_unlock (local);
- frame->local = NULL;
- STACK_UNWIND_STRICT (readv, frame, op_ret, op_errno, vector,
- count, &stbuf, iobref, NULL);
+ STACK_UNWIND_STRICT (readv, frame, op_ret, local->op_errno, vector,
+ count, &stbuf, iobref);
if (iobref != NULL) {
iobref_unref (iobref);
}
-
+
if (vector != NULL) {
- GF_FREE (vector);
+ free (vector);
vector = NULL;
}
-
- pthread_mutex_destroy (&local->local_lock);
- if (local)
- mem_put (local);
+
+ pthread_mutex_destroy (&local->local_lock);
+ free (local);
return;
}
@@ -910,119 +783,60 @@ unwind:
void
ioc_frame_return (call_frame_t *frame)
{
- ioc_local_t *local = NULL;
- int32_t wait_count = 0;
-
- GF_ASSERT (frame);
+ ioc_local_t *local = NULL;
+ int32_t wait_count = 0;
local = frame->local;
- GF_ASSERT (local->wait_count > 0);
+ assert (local->wait_count > 0);
- ioc_local_lock (local);
- {
- wait_count = --local->wait_count;
- }
- ioc_local_unlock (local);
+ ioc_local_lock (local);
+ {
+ wait_count = --local->wait_count;
+ }
+ ioc_local_unlock (local);
- if (!wait_count) {
- ioc_frame_unwind (frame);
- }
+ if (!wait_count) {
+ ioc_frame_unwind (frame);
+ }
- return;
+ return;
}
-/*
+/*
* ioc_page_wakeup -
* @page:
*
* 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;
- int32_t ret = -1;
-
- GF_VALIDATE_OR_GOTO ("io-cache", page, out);
-
- waitq = page->waitq;
- page->waitq = NULL;
-
- page->ready = 1;
-
- gf_log (page->inode->table->xl->name, GF_LOG_TRACE,
- "page is %p && waitq = %p", page, waitq);
-
- for (trav = waitq; trav; trav = trav->next) {
- frame = trav->data;
- ret = __ioc_frame_fill (page, frame, trav->pending_offset,
- trav->pending_size, op_errno);
+ ioc_waitq_t *waitq = NULL, *trav = NULL;
+ call_frame_t *frame = NULL;
+ int32_t ret = -1;
+
+ waitq = page->waitq;
+ page->waitq = NULL;
+
+ trav = waitq;
+ page->ready = 1;
+
+ gf_log (page->inode->table->xl->name, GF_LOG_TRACE,
+ "page is %p && waitq = %p", page, waitq);
+
+ for (trav = waitq; trav; trav = trav->next) {
+ frame = trav->data;
+ 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;
+ }
+
+ 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, *trav = NULL;
- call_frame_t *frame = NULL;
- int64_t ret = 0;
- ioc_table_t *table = NULL;
- ioc_local_t *local = NULL;
-
- GF_VALIDATE_OR_GOTO ("io-cache", page, out);
-
- waitq = page->waitq;
- page->waitq = NULL;
-
- gf_log (page->inode->table->xl->name, GF_LOG_DEBUG,
- "page error for page = %p & waitq = %p", page, waitq);
-
- for (trav = waitq; trav; trav = trav->next) {
-
- frame = trav->data;
-
- local = frame->local;
- ioc_local_lock (local);
- {
- if (local->op_ret != -1) {
- local->op_ret = op_ret;
- local->op_errno = op_errno;
- }
- }
- ioc_local_unlock (local);
- }
-
- table = page->inode->table;
- ret = __ioc_page_destroy (page);
-
- if (ret != -1) {
- table->cache_used -= ret;
- }
-
-out:
- return waitq;
-}
-
/*
* ioc_page_error -
* @page:
@@ -1033,20 +847,39 @@ out:
ioc_waitq_t *
ioc_page_error (ioc_page_t *page, int32_t op_ret, int32_t op_errno)
{
- ioc_waitq_t *waitq = NULL;
- struct ioc_inode *inode = NULL;
+ ioc_waitq_t *waitq = NULL, *trav = NULL;
+ call_frame_t *frame = NULL;
+ int64_t ret = 0;
+ ioc_table_t *table = NULL;
+ ioc_local_t *local = NULL;
+
+ waitq = page->waitq;
+ page->waitq = NULL;
+
+ gf_log (page->inode->table->xl->name, GF_LOG_DEBUG,
+ "page error for page = %p & waitq = %p", page, waitq);
+
+ for (trav = waitq; trav; trav = trav->next) {
+
+ frame = trav->data;
+
+ local = frame->local;
+ ioc_local_lock (local);
+ {
+ if (local->op_ret != -1) {
+ local->op_ret = op_ret;
+ local->op_errno = op_errno;
+ }
+ }
+ ioc_local_unlock (local);
+ }
- if (page == NULL) {
- goto out;
- }
+ table = page->inode->table;
+ ret = ioc_page_destroy (page);
- ioc_inode_lock (page->inode);
- {
- inode = page->inode;
- waitq = __ioc_page_error (page, op_ret, op_errno);
- }
- ioc_inode_unlock (inode);
+ if (ret != -1) {
+ table->cache_used -= ret;
+ }
-out:
- return waitq;
+ return waitq;
}
diff --git a/xlators/performance/io-threads/src/Makefile.am b/xlators/performance/io-threads/src/Makefile.am
index d63042e7c05..38dea3eb7fc 100644
--- a/xlators/performance/io-threads/src/Makefile.am
+++ b/xlators/performance/io-threads/src/Makefile.am
@@ -1,15 +1,14 @@
xlator_LTLIBRARIES = io-threads.la
xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/performance
-io_threads_la_LDFLAGS = -module -avoid-version
+io_threads_la_LDFLAGS = -module -avoidversion
io_threads_la_SOURCES = io-threads.c
io_threads_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la
-noinst_HEADERS = io-threads.h iot-mem-types.h
+noinst_HEADERS = io-threads.h
-AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src
-
-AM_CFLAGS = -Wall $(GF_CFLAGS)
+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/performance/io-threads/src/io-threads.c b/xlators/performance/io-threads/src/io-threads.c
index 8201a95a4d0..e99012cc0d6 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-2009 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 General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that 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
@@ -14,7 +23,6 @@
#endif
#include "call-stub.h"
-#include "defaults.h"
#include "glusterfs.h"
#include "logging.h"
#include "dict.h"
@@ -25,911 +33,2703 @@
#include <time.h>
#include "locking.h"
-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[];
-
-#define IOT_FOP(name, frame, this, args ...) \
- do { \
- call_stub_t *__stub = NULL; \
- int __ret = -1; \
- \
- __stub = fop_##name##_stub(frame, default_##name##_resume, args); \
- if (!__stub) { \
- __ret = -ENOMEM; \
- goto out; \
- } \
- \
- __ret = iot_schedule (frame, this, __stub); \
- \
- out: \
- if (__ret < 0) { \
- default_##name##_failure_cbk (frame, -__ret); \
- if (__stub != NULL) { \
- call_stub_destroy (__stub); \
- } \
- } \
- } while (0)
+typedef void *(*iot_worker_fn)(void*);
-call_stub_t *
-__iot_dequeue (iot_conf_t *conf, int *pri, struct timespec *sleep)
-{
- call_stub_t *stub = NULL;
- int i = 0;
- struct timeval curtv = {0,}, difftv = {0,};
-
- *pri = -1;
- sleep->tv_sec = 0;
- sleep->tv_nsec = 0;
- for (i = 0; i < IOT_PRI_MAX; i++) {
- if (list_empty (&conf->reqs[i]) ||
- (conf->ac_iot_count[i] >= conf->ac_iot_limit[i]))
- continue;
-
- if (i == IOT_PRI_LEAST) {
- pthread_mutex_lock(&conf->throttle.lock);
- if (!conf->throttle.sample_time.tv_sec) {
- /* initialize */
- gettimeofday(&conf->throttle.sample_time, NULL);
- } else {
- /*
- * Maintain a running count of least priority
- * operations that are handled over a particular
- * time interval. The count is provided via
- * state dump and is used as a measure against
- * least priority op throttling.
- */
- gettimeofday(&curtv, NULL);
- timersub(&curtv, &conf->throttle.sample_time,
- &difftv);
- if (difftv.tv_sec >= IOT_LEAST_THROTTLE_DELAY) {
- conf->throttle.cached_rate =
- conf->throttle.sample_cnt;
- conf->throttle.sample_cnt = 0;
- conf->throttle.sample_time = curtv;
- }
-
- /*
- * If we're over the configured rate limit,
- * provide an absolute time to the caller that
- * represents the soonest we're allowed to
- * return another least priority request.
- */
- if (conf->throttle.rate_limit &&
- conf->throttle.sample_cnt >=
- conf->throttle.rate_limit) {
- struct timeval delay;
- delay.tv_sec = IOT_LEAST_THROTTLE_DELAY;
- delay.tv_usec = 0;
-
- timeradd(&conf->throttle.sample_time,
- &delay, &curtv);
- TIMEVAL_TO_TIMESPEC(&curtv, sleep);
-
- pthread_mutex_unlock(
- &conf->throttle.lock);
- break;
- }
- }
- conf->throttle.sample_cnt++;
- pthread_mutex_unlock(&conf->throttle.lock);
- }
-
- stub = list_entry (conf->reqs[i].next, call_stub_t, list);
- conf->ac_iot_count[i]++;
- *pri = i;
- break;
- }
-
- if (!stub)
- return NULL;
-
- conf->queue_size--;
- conf->queue_sizes[*pri]--;
- list_del_init (&stub->list);
-
- return stub;
+void
+iot_stop_worker (iot_worker_t *worker);
+
+void
+iot_stop_workers (iot_worker_t **workers, int start_idx, int count);
+
+void
+_iot_queue (iot_worker_t *worker, iot_request_t *req);
+
+iot_request_t *
+iot_init_request (iot_worker_t *conf, call_stub_t *stub);
+
+int
+iot_startup_workers (iot_worker_t **workers, int start_idx, int count,
+ iot_worker_fn workerfunc);
+
+void *
+iot_worker_unordered (void *arg);
+
+void *
+iot_worker_ordered (void *arg);
+
+int
+iot_startup_worker (iot_worker_t *worker, iot_worker_fn workerfunc);
+
+void
+iot_destroy_request (iot_worker_t *worker, iot_request_t * req);
+
+void
+iot_notify_worker (iot_worker_t *worker)
+{
+#ifndef HAVE_SPINLOCK
+ pthread_cond_broadcast (&worker->notifier);
+#else
+ sem_post (&worker->notifier);
+#endif
+
+ return;
}
+int
+iot_notify_wait (iot_worker_t *worker, int idletime)
+{
+ struct timeval tv;
+ struct timespec ts = {0, };
+ int waitres = 0;
+
+ gettimeofday (&tv, NULL);
+ /* Slightly skew the idle time for threads so that, we dont
+ * have all of them rushing to exit at the same time, if
+ * they've been idle.
+ */
+ ts.tv_sec = skew_sec_idle_time (tv.tv_sec + idletime);
+
+#ifndef HAVE_SPINLOCK
+ waitres = pthread_cond_timedwait (&worker->notifier, &worker->qlock,
+ &ts);
+#else
+ UNLOCK (&worker->qlock);
+ errno = 0;
+ waitres = sem_timedwait (&worker->notifier, &ts);
+ LOCK (&worker->qlock);
+ if (waitres < 0)
+ waitres = errno;
+#endif
+
+ return waitres;
+}
void
-__iot_enqueue (iot_conf_t *conf, call_stub_t *stub, int pri)
+iot_notify_init (iot_worker_t *worker)
{
- if (pri < 0 || pri >= IOT_PRI_MAX)
- pri = IOT_PRI_MAX-1;
+ if (worker == NULL)
+ return;
- list_add_tail (&stub->list, &conf->reqs[pri]);
+ LOCK_INIT (&worker->qlock);
- conf->queue_size++;
- conf->queue_sizes[pri]++;
+#ifndef HAVE_SPINLOCK
+ pthread_cond_init (&worker->notifier, NULL);
+#else
+ sem_init (&worker->notifier, 0, 0);
+#endif
return;
}
-
-void *
-iot_worker (void *data)
-{
- iot_conf_t *conf = NULL;
- xlator_t *this = NULL;
- call_stub_t *stub = NULL;
- struct timespec sleep_till = {0, };
- int ret = 0;
- int pri = -1;
- char timeout = 0;
- char bye = 0;
- struct timespec sleep = {0,};
-
- conf = data;
- this = conf->this;
- THIS = this;
-
- for (;;) {
- sleep_till.tv_sec = time (NULL) + conf->idle_time;
-
- pthread_mutex_lock (&conf->mutex);
- {
- if (pri != -1) {
- conf->ac_iot_count[pri]--;
- pri = -1;
- }
- while (conf->queue_size == 0) {
- conf->sleep_count++;
-
- ret = pthread_cond_timedwait (&conf->cond,
- &conf->mutex,
- &sleep_till);
- conf->sleep_count--;
-
- if (ret == ETIMEDOUT) {
- timeout = 1;
- break;
- }
+/* I know this function modularizes things a bit too much,
+ * but it is easier on the eyes to read this than see all that locking,
+ * queueing, and thread firing in the same curly block, as was the
+ * case before this function.
+ */
+int
+iot_request_queue_and_thread_fire (iot_worker_t *worker,
+ iot_worker_fn workerfunc, iot_request_t *req)
+{
+ int ret = -1;
+ LOCK (&worker->qlock);
+ {
+ if (iot_worker_active (worker)) {
+ _iot_queue (worker, req);
+ ret = 0;
+ }else {
+ ret = iot_startup_worker (worker, workerfunc);
+ if (ret < 0) {
+ goto unlock;
}
+ _iot_queue (worker, req);
+ }
+ }
+unlock:
+ UNLOCK (&worker->qlock);
- if (timeout) {
- if (conf->curr_count > IOT_MIN_THREADS) {
- conf->curr_count--;
- bye = 1;
- gf_log (conf->this->name, GF_LOG_DEBUG,
- "timeout, terminated. conf->curr_count=%d",
- conf->curr_count);
- } else {
- timeout = 0;
- }
- }
+ return ret;
+}
- stub = __iot_dequeue (conf, &pri, &sleep);
- if (!stub && (sleep.tv_sec || sleep.tv_nsec)) {
- pthread_cond_timedwait(&conf->cond,
- &conf->mutex, &sleep);
- pthread_mutex_unlock(&conf->mutex);
- continue;
- }
- }
- pthread_mutex_unlock (&conf->mutex);
- if (stub) /* guard against spurious wakeups */
- call_resume (stub);
+int
+iot_unordered_request_balancer (iot_conf_t *conf)
+{
+ long int rand = 0;
+ int idx = 0;
+
+ /* Decide which thread will service the request.
+ * FIXME: This should change into some form of load-balancing.
+ * */
+ rand = random ();
+
+ /* If scaling is on, we can choose from any thread
+ * that has been allocated upto, max_o_threads, but
+ * with scaling off, we'll never have threads more
+ * than min_o_threads.
+ */
+ if (iot_unordered_scaling_on (conf))
+ idx = (rand % conf->max_u_threads);
+ else
+ idx = (rand % conf->min_u_threads);
+
+ return idx;
+}
+
- if (bye)
- break;
+int
+iot_schedule_unordered (iot_conf_t *conf, inode_t *inode, call_stub_t *stub)
+{
+ int32_t idx = 0;
+ iot_worker_t *selected_worker = NULL;
+ iot_request_t *req = NULL;
+ int ret = -1;
+
+ idx = iot_unordered_request_balancer (conf);
+ selected_worker = conf->uworkers[idx];
+
+ req = iot_init_request (selected_worker, stub);
+ if (req == NULL) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ ret = iot_request_queue_and_thread_fire (selected_worker,
+ iot_worker_unordered, req);
+ if (ret < 0) {
+ iot_destroy_request (selected_worker, req);
}
+out:
+ return ret;
+}
+
+
+/* Only to be used with ordered requests.
+ */
+uint64_t
+iot_create_inode_worker_assoc (iot_conf_t * conf, inode_t * inode)
+{
+ long int rand = 0;
+ uint64_t idx = 0;
+
+ rand = random ();
+ /* If scaling is on, we can choose from any thread
+ * that has been allocated upto, max_o_threads, but
+ * with scaling off, we'll never have threads more
+ * than min_o_threads.
+ */
+ if (iot_ordered_scaling_on (conf))
+ idx = (rand % conf->max_o_threads);
+ else
+ idx = (rand % conf->min_o_threads);
+
+ __inode_ctx_put (inode, conf->this, idx);
+
+ return idx;
+}
- if (pri != -1) {
- pthread_mutex_lock (&conf->mutex);
- {
- conf->ac_iot_count[pri]--;
+
+/* Assumes inode lock is held. */
+int32_t
+iot_ordered_request_balancer (iot_conf_t *conf, inode_t *inode, uint64_t *idx)
+{
+ int ret = -1;
+
+ if (__inode_ctx_get (inode, conf->this, idx) < 0)
+ *idx = iot_create_inode_worker_assoc (conf, inode);
+ else {
+ /* Sanity check to ensure the idx received from the inode
+ * context is within bounds. We're a bit optimistic in
+ * assuming that if an index is within bounds, it is
+ * not corrupted. idx is uint so we dont check for less
+ * than 0.
+ */
+ if ((*idx >= (uint64_t)conf->max_o_threads)) {
+ gf_log (conf->this->name, GF_LOG_DEBUG,
+ "inode context returned insane thread index %"
+ PRIu64, *idx);
+ ret = -EINVAL;
+ goto out;
}
- pthread_mutex_unlock (&conf->mutex);
}
- return NULL;
+ ret = 0;
+out:
+ return ret;
}
int
-do_iot_schedule (iot_conf_t *conf, call_stub_t *stub, int pri)
+iot_schedule_ordered (iot_conf_t *conf, inode_t *inode, call_stub_t *stub)
{
- int ret = 0;
+ uint64_t idx = 0;
+ iot_worker_t *selected_worker = NULL;
+ iot_request_t *req = NULL;
+ int balstatus = 0, ret = -1;
+
+ if (inode == NULL) {
+ gf_log (conf->this->name, GF_LOG_DEBUG,
+ "Got NULL inode for ordered request");
+ ret = -EINVAL;
+ goto out;
+ }
- pthread_mutex_lock (&conf->mutex);
+ LOCK (&inode->lock);
{
- __iot_enqueue (conf, stub, pri);
-
- pthread_cond_signal (&conf->cond);
+ balstatus = iot_ordered_request_balancer (conf, inode, &idx);
+ if (balstatus < 0) {
+ gf_log (conf->this->name, GF_LOG_DEBUG,
+ "Insane worker index. Unwinding stack");
+ ret = -ECANCELED;
+ goto unlock_out;
+ }
+ /* inode lock once acquired, cannot be left here
+ * because other gluster main threads might be
+ * contending on it to append a request for this file.
+ * So we'll also leave the lock only after we've
+ * added the request to the worker queue.
+ */
+ selected_worker = conf->oworkers[idx];
+
+ req = iot_init_request (selected_worker, stub);
+ if (req == NULL) {
+ gf_log (conf->this->name, GF_LOG_ERROR,"out of memory");
+ ret = -ENOMEM;
+ goto unlock_out;
+ }
- ret = __iot_workers_scale (conf);
+ ret = iot_request_queue_and_thread_fire (selected_worker,
+ iot_worker_ordered,
+ req);
}
- pthread_mutex_unlock (&conf->mutex);
+unlock_out:
+ UNLOCK (&inode->lock);
+out:
+ if (ret < 0) {
+ if (req != NULL) {
+ iot_destroy_request (selected_worker, req);
+ }
+ }
return ret;
}
-char*
-iot_get_pri_meaning (iot_pri_t pri)
+
+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 stat *buf, dict_t *xattr,
+ struct stat *postparent)
+{
+ STACK_UNWIND_STRICT (lookup, frame, op_ret, op_errno, inode, buf, xattr,
+ postparent);
+ return 0;
+}
+
+
+int
+iot_lookup_wrapper (call_frame_t *frame, xlator_t *this, loc_t *loc,
+ dict_t *xattr_req)
{
- 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;
+ STACK_WIND (frame, iot_lookup_cbk,
+ FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->lookup,
+ loc, xattr_req);
+ return 0;
+}
+
+
+int
+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, xattr_req);
+ if (!stub) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "cannot create lookup stub (out of memory)");
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ ret = iot_schedule_unordered ((iot_conf_t *)this->private, loc->inode,
+ stub);
+
+out:
+ if (ret < 0) {
+ if (stub != NULL) {
+ call_stub_destroy (stub);
+ }
+ STACK_UNWIND_STRICT (lookup, frame, -1, -ret, NULL, NULL, NULL,
+ NULL);
}
- return name;
+
+ return 0;
+}
+
+
+int
+iot_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno,
+ struct stat *preop, struct stat *postop)
+{
+ 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 stat *stbuf, int32_t valid)
+{
+ STACK_WIND (frame, iot_setattr_cbk,
+ FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->setattr,
+ loc, stbuf, valid);
+ return 0;
}
+
int
-iot_schedule (call_frame_t *frame, xlator_t *this, call_stub_t *stub)
+iot_setattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
+ struct stat *stbuf, int32_t valid)
{
+ call_stub_t *stub = NULL;
int ret = -1;
- iot_pri_t pri = IOT_PRI_MAX - 1;
- iot_conf_t *conf = this->private;
- if ((frame->root->pid < GF_CLIENT_PID_MAX) && conf->least_priority) {
- pri = IOT_PRI_LEAST;
+ 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)");
+ ret = -ENOMEM;
goto out;
}
- 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;
-
- 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:
- case GF_FOP_FALLOCATE:
- case GF_FOP_DISCARD:
- case GF_FOP_ZEROFILL:
- 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;
- }
+ ret = iot_schedule_unordered ((iot_conf_t *)this->private,
+ loc->inode, stub);
+
out:
- gf_log (this->name, GF_LOG_DEBUG, "%s scheduled as %s fop",
- gf_fop_list[stub->fop], iot_get_pri_meaning (pri));
- ret = do_iot_schedule (this->private, stub, pri);
- return ret;
+ if (ret < 0) {
+ if (stub != NULL) {
+ call_stub_destroy (stub);
+ }
+
+ STACK_UNWIND_STRICT (setattr, frame, -1, -ret, NULL, NULL);
+ }
+
+ return 0;
}
+
int
-iot_lookup (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
+iot_fsetattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno,
+ struct stat *preop, struct stat *postop)
{
- IOT_FOP (lookup, frame, this, loc, xdata);
+ STACK_UNWIND_STRICT (fsetattr, frame, op_ret, op_errno, preop, postop);
return 0;
}
int
-iot_setattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
- struct iatt *stbuf, int32_t valid, dict_t *xdata)
+iot_fsetattr_wrapper (call_frame_t *frame, xlator_t *this,
+ fd_t *fd, struct stat *stbuf, int32_t valid)
{
- IOT_FOP (setattr, frame, this, loc, stbuf, valid, xdata);
+ STACK_WIND (frame, iot_fsetattr_cbk, FIRST_CHILD (this),
+ 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 stat *stbuf, int32_t valid)
{
- IOT_FOP (fsetattr, frame, this, fd, stbuf, valid, xdata);
+ call_stub_t *stub = NULL;
+ int ret = -1;
+
+ stub = fop_fsetattr_stub (frame, iot_fsetattr_wrapper, fd, stbuf,
+ valid);
+ if (!stub) {
+ gf_log (this->name, GF_LOG_ERROR, "cannot create fsetattr stub"
+ "(out of memory)");
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ ret = iot_schedule_ordered ((iot_conf_t *)this->private, fd->inode,
+ stub);
+
+out:
+ if (ret < 0) {
+ STACK_UNWIND_STRICT (fsetattr, frame, -1, -ret, NULL, NULL);
+ if (stub != NULL) {
+ call_stub_destroy (stub);
+ }
+ }
+ return 0;
+}
+
+
+int
+iot_access_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno)
+{
+ 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)
+{
+ STACK_WIND (frame, iot_access_cbk, FIRST_CHILD (this),
+ 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)
+{
+ call_stub_t *stub = NULL;
+ int ret = -1;
+
+ 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)");
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ ret = iot_schedule_unordered ((iot_conf_t *)this->private, loc->inode,
+ stub);
+out:
+ if (ret < 0) {
+ STACK_UNWIND_STRICT (access, frame, -1, -ret);
+
+ if (stub != NULL) {
+ call_stub_destroy (stub);
+ }
+ }
+ return 0;
+}
+
+
+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 stat *stbuf)
+{
+ 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)
+{
+ STACK_WIND (frame, iot_readlink_cbk,
+ FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->readlink,
+ loc, size);
+ return 0;
+}
+
+
+int
+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);
+ if (!stub) {
+ gf_log (this->name, GF_LOG_ERROR, "cannot create readlink stub"
+ "(out of memory)");
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ ret = iot_schedule_unordered ((iot_conf_t *)this->private, loc->inode,
+ stub);
+
+out:
+ if (ret < 0) {
+ STACK_UNWIND_STRICT (readlink, frame, -1, -ret, NULL, NULL);
+
+ if (stub != NULL) {
+ call_stub_destroy (stub);
+ }
+ }
+
return 0;
}
int
-iot_access (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t mask,
- dict_t *xdata)
+iot_mknod_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, inode_t *inode,
+ struct stat *buf, struct stat *preparent,
+ struct stat *postparent)
{
- IOT_FOP (access, frame, this, loc, mask, xdata);
+ STACK_UNWIND_STRICT (mknod, frame, op_ret, op_errno, inode, buf,
+ preparent, postparent);
return 0;
}
int
-iot_readlink (call_frame_t *frame, xlator_t *this, loc_t *loc, size_t size, dict_t *xdata)
+iot_mknod_wrapper (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
+ dev_t rdev)
{
- IOT_FOP (readlink, frame, this, loc, size, xdata);
+ STACK_WIND (frame, iot_mknod_cbk, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->mknod, loc, mode, rdev);
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)
{
- IOT_FOP (mknod, frame, this, loc, mode, rdev, umask, xdata);
+ call_stub_t *stub = NULL;
+ int ret = -1;
+
+ stub = fop_mknod_stub (frame, iot_mknod_wrapper, loc, mode, rdev);
+ if (!stub) {
+ gf_log (this->name, GF_LOG_ERROR, "cannot create mknod stub"
+ "(out of memory)");
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ ret = iot_schedule_unordered ((iot_conf_t *)this->private, loc->inode,
+ stub);
+
+out:
+ if (ret < 0) {
+ STACK_UNWIND_STRICT (mknod, frame, -1, -ret, NULL, NULL, NULL,
+ NULL);
+
+ if (stub != NULL) {
+ call_stub_destroy (stub);
+ }
+ }
return 0;
}
int
-iot_mkdir (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
- mode_t umask, dict_t *xdata)
+iot_mkdir_cbk (call_frame_t *frame, void * cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, inode_t *inode,
+ struct stat *buf, struct stat *preparent,
+ struct stat *postparent)
{
- IOT_FOP (mkdir, frame, this, loc, mode, umask, xdata);
+ STACK_UNWIND_STRICT (mkdir, frame, op_ret, op_errno, inode, buf,
+ preparent, postparent);
return 0;
}
int
-iot_rmdir (call_frame_t *frame, xlator_t *this, loc_t *loc, int flags, dict_t *xdata)
+iot_mkdir_wrapper (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode)
{
- IOT_FOP (rmdir, frame, this, loc, flags, xdata);
+ STACK_WIND (frame, iot_mkdir_cbk, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->mkdir, loc, mode);
return 0;
}
int
-iot_symlink (call_frame_t *frame, xlator_t *this, const char *linkname,
- loc_t *loc, mode_t umask, dict_t *xdata)
+iot_mkdir (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode)
{
- IOT_FOP (symlink, frame, this, linkname, loc, umask, xdata);
+ call_stub_t *stub = NULL;
+ int ret = -1;
+
+ stub = fop_mkdir_stub (frame, iot_mkdir_wrapper, loc, mode);
+ if (!stub) {
+ gf_log (this->name, GF_LOG_ERROR, "cannot create mkdir stub"
+ "(out of memory)");
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ ret = iot_schedule_unordered ((iot_conf_t *)this->private, loc->inode,
+ stub);
+
+out:
+ if (ret < 0) {
+ STACK_UNWIND_STRICT (mkdir, frame, -1, -ret, NULL, NULL, NULL,
+ NULL);
+
+ if (stub != NULL) {
+ call_stub_destroy (stub);
+ }
+ }
return 0;
}
int
-iot_rename (call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc,
- dict_t *xdata)
+iot_rmdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct stat *preparent,
+ struct stat *postparent)
{
- IOT_FOP (rename, frame, this, oldloc, newloc, xdata);
+ STACK_UNWIND_STRICT (rmdir, frame, op_ret, op_errno, preparent,
+ postparent);
return 0;
}
int
-iot_open (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
- fd_t *fd, dict_t *xdata)
+iot_rmdir_wrapper (call_frame_t *frame, xlator_t *this, loc_t *loc)
{
- IOT_FOP (open, frame, this, loc, flags, fd, xdata);
+ STACK_WIND (frame, iot_rmdir_cbk, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->rmdir, loc);
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)
+iot_rmdir (call_frame_t *frame, xlator_t *this, loc_t *loc)
+{
+ call_stub_t *stub = NULL;
+ int ret = -1;
+
+ stub = fop_rmdir_stub (frame, iot_rmdir_wrapper, loc);
+ if (!stub) {
+ gf_log (this->name, GF_LOG_ERROR, "cannot create rmdir stub"
+ "(out of memory)");
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ ret = iot_schedule_unordered ((iot_conf_t *)this->private, loc->inode,
+ stub);
+out:
+ if (ret < 0) {
+ STACK_UNWIND_STRICT (rmdir, frame, -1, -ret, NULL, NULL);
+
+ if (stub != NULL) {
+ call_stub_destroy (stub);
+ }
+ }
+ return 0;
+}
+
+
+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 stat *buf, struct stat *preparent,
+ struct stat *postparent)
{
- IOT_FOP (create, frame, this, loc, flags, mode, umask, fd, xdata);
+ STACK_UNWIND_STRICT (symlink, frame, op_ret, op_errno, inode, buf,
+ preparent, postparent);
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)
+iot_symlink_wrapper (call_frame_t *frame, xlator_t *this, const char *linkname,
+ loc_t *loc)
{
- IOT_FOP (readv, frame, this, fd, size, offset, flags, xdata);
+ STACK_WIND (frame, iot_symlink_cbk, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->symlink, linkname, loc);
+ return 0;
+}
+
+
+int
+iot_symlink (call_frame_t *frame, xlator_t *this, const char *linkname,
+ loc_t *loc)
+{
+ call_stub_t *stub = NULL;
+ int ret = -1;
+
+ stub = fop_symlink_stub (frame, iot_symlink_wrapper, linkname, loc);
+ if (!stub) {
+ gf_log (this->name, GF_LOG_ERROR, "cannot create symlink stub"
+ "(out of memory)");
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ ret = iot_schedule_unordered ((iot_conf_t *)this->private, loc->inode,
+ stub);
+
+out:
+ if (ret < 0) {
+ STACK_UNWIND_STRICT (symlink, frame, -1, -ret, NULL, NULL, NULL,
+ NULL);
+ if (stub != NULL) {
+ call_stub_destroy (stub);
+ }
+ }
+
return 0;
}
int
-iot_flush (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
+iot_rename_cbk (call_frame_t *frame, void * cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct stat *buf,
+ struct stat *preoldparent, struct stat *postoldparent,
+ struct stat *prenewparent, struct stat *postnewparent)
{
- IOT_FOP (flush, frame, this, fd, xdata);
+ STACK_UNWIND_STRICT (rename, frame, op_ret, op_errno, buf, preoldparent,
+ postoldparent, prenewparent, postnewparent);
return 0;
}
int
-iot_fsync (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t datasync,
- dict_t *xdata)
+iot_rename_wrapper (call_frame_t *frame, xlator_t *this, loc_t *oldloc,
+ loc_t *newloc)
{
- IOT_FOP (fsync, frame, this, fd, datasync, xdata);
+ STACK_WIND (frame, iot_rename_cbk, FIRST_CHILD (this),
+ 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)
+{
+ call_stub_t *stub = NULL;
+ int ret = -1;
+
+ 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)");
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ ret = iot_schedule_unordered ((iot_conf_t *)this->private,
+ oldloc->inode, stub);
+
+out:
+ if (ret < 0) {
+ STACK_UNWIND_STRICT (rename, frame, -1, -ret, NULL, NULL, NULL,
+ NULL, NULL);
+ if (stub != NULL) {
+ call_stub_destroy (stub);
+ }
+ }
+
+ return 0;
+}
+
+
+int
+iot_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;
+}
+
+
+int
+iot_open_wrapper (call_frame_t * frame, xlator_t * this, loc_t *loc,
+ 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, wbflags);
+ return 0;
+}
+
+
+int
+iot_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 = -1;
+
+ 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"
+ "(out of memory)");
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ ret = iot_schedule_unordered ((iot_conf_t *)this->private, loc->inode,
+ stub);
+
+out:
+ if (ret < 0) {
+ STACK_UNWIND_STRICT (open, frame, -1, -ret, NULL);
+
+ if (stub != NULL) {
+ call_stub_destroy (stub);
+ }
+ }
+
+ return 0;
+}
+
+
+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 stat *stbuf, struct stat *preparent,
+ struct stat *postparent)
+{
+ STACK_UNWIND_STRICT (create, frame, op_ret, op_errno, fd, inode, stbuf,
+ preparent, postparent);
+ return 0;
+}
+
+
+int
+iot_create_wrapper (call_frame_t *frame, xlator_t *this, loc_t *loc,
+ int32_t flags, mode_t mode, fd_t *fd)
+{
+ STACK_WIND (frame, iot_create_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->create,
+ loc, flags, mode, fd);
+ return 0;
+}
+
+
+int
+iot_create (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
+ mode_t mode, fd_t *fd)
+{
+ call_stub_t *stub = NULL;
+ int ret = -1;
+
+ stub = fop_create_stub (frame, iot_create_wrapper, loc, flags, mode,
+ fd);
+ if (!stub) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "cannot create \"create\" call stub"
+ "(out of memory)");
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ ret = iot_schedule_unordered ((iot_conf_t *)this->private, loc->inode,
+ stub);
+
+out:
+ if (ret < 0) {
+ STACK_UNWIND_STRICT (create, frame, -1, -ret, NULL, NULL, NULL,
+ NULL, NULL);
+
+ if (stub != NULL) {
+ call_stub_destroy (stub);
+ }
+ }
+
+ return 0;
+}
+
+
+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 stat *stbuf, struct iobref *iobref)
+{
+ STACK_UNWIND_STRICT (readv, frame, op_ret, op_errno, vector, count,
+ stbuf, iobref);
+
+ return 0;
+}
+
+
+int
+iot_readv_wrapper (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
+ off_t offset)
+{
+ STACK_WIND (frame, iot_readv_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->readv,
+ fd, size, offset);
+ return 0;
+}
+
+
+int
+iot_readv (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
+ off_t offset)
+{
+ call_stub_t *stub = NULL;
+ int ret = -1;
+
+ 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"
+ "(out of memory)");
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ ret = iot_schedule_ordered ((iot_conf_t *)this->private, fd->inode,
+ stub);
+
+out:
+ if (ret < 0) {
+ STACK_UNWIND_STRICT (readv, frame, -1, -ret, NULL, -1, NULL,
+ NULL);
+ if (stub != NULL) {
+ call_stub_destroy (stub);
+ }
+ }
+ return 0;
+}
+
+
+int
+iot_flush_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno)
+{
+ 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)
+{
+ STACK_WIND (frame, iot_flush_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->flush,
+ fd);
+ return 0;
+}
+
+
+int
+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);
+ if (!stub) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "cannot create flush_cbk call stub"
+ "(out of memory)");
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ ret = iot_schedule_ordered ((iot_conf_t *)this->private, fd->inode,
+ stub);
+out:
+ if (ret < 0) {
+ STACK_UNWIND_STRICT (flush, frame, -1, -ret);
+
+ if (stub != NULL) {
+ call_stub_destroy (stub);
+ }
+ }
+ return 0;
+}
+
+
+int
+iot_fsync_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct stat *prebuf,
+ struct stat *postbuf)
+{
+ 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)
+{
+ STACK_WIND (frame, iot_fsync_cbk,
+ FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->fsync,
+ fd, datasync);
+ return 0;
+}
+
+
+int
+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);
+ if (!stub) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "cannot create fsync_cbk call stub"
+ "(out of memory)");
+ ret = -1;
+ goto out;
+ }
+
+ ret = iot_schedule_ordered ((iot_conf_t *)this->private, fd->inode,
+ stub);
+
+out:
+ if (ret < 0) {
+ STACK_UNWIND_STRICT (fsync, frame, -1, -ret, NULL, NULL);
+
+ if (stub != NULL) {
+ call_stub_destroy (stub);
+ }
+ }
+ return 0;
+}
+
+
+int
+iot_writev_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct stat *prebuf,
+ struct stat *postbuf)
+{
+ STACK_UNWIND_STRICT (writev, frame, op_ret, op_errno, prebuf, postbuf);
+ return 0;
+}
+
+
+int
+iot_writev_wrapper (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, iot_writev_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->writev,
+ fd, vector, count, offset, iobref);
+ return 0;
+}
+
+
+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)
{
- IOT_FOP (writev, frame, this, fd, vector, count, offset,
- flags, iobref, xdata);
- return 0;
+ call_stub_t *stub = NULL;
+ int ret = -1;
+
+ stub = fop_writev_stub (frame, iot_writev_wrapper,
+ fd, vector, count, offset, iobref);
+
+ if (!stub) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "cannot create writev call stub"
+ "(out of memory)");
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ ret = iot_schedule_ordered ((iot_conf_t *)this->private, fd->inode,
+ stub);
+out:
+ if (ret < 0) {
+ STACK_UNWIND_STRICT (writev, frame, -1, -ret, NULL, NULL);
+
+ if (stub != NULL) {
+ call_stub_destroy (stub);
+ }
+ }
+
+ return 0;
+}
+
+
+int32_t
+iot_lk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct flock *flock)
+{
+ 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 flock *flock)
+{
+ STACK_WIND (frame, iot_lk_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->lk,
+ 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 flock *flock)
+{
+ call_stub_t *stub = NULL;
+ int ret = -1;
+
+ stub = fop_lk_stub (frame, iot_lk_wrapper, fd, cmd, flock);
+
+ if (!stub) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "cannot create fop_lk call stub"
+ "(out of memory)");
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ ret = iot_schedule_ordered ((iot_conf_t *)this->private, fd->inode,
+ stub);
+out:
+ if (ret < 0) {
+ STACK_UNWIND_STRICT (lk, frame, -1, -ret, NULL);
+
+ if (stub != NULL) {
+ call_stub_destroy (stub);
+ }
+ }
+ return 0;
+}
+
+
+int
+iot_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct stat *buf)
+{
+ 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)
+{
+ STACK_WIND (frame, iot_stat_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->stat,
+ loc);
+ return 0;
+}
+
+
+int
+iot_stat (call_frame_t *frame, xlator_t *this, loc_t *loc)
+{
+ call_stub_t *stub = NULL;
+ fd_t *fd = NULL;
+ int ret = -1;
+
+ stub = fop_stat_stub (frame, iot_stat_wrapper, loc);
+ if (!stub) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "cannot create fop_stat call stub"
+ "(out of memory)");
+ ret = -1;
+ goto out;
+ }
+
+ fd = fd_lookup (loc->inode, frame->root->pid);
+ /* File is not open, so we can send it through unordered pool.
+ */
+ if (fd == NULL)
+ ret = iot_schedule_unordered ((iot_conf_t *)this->private,
+ loc->inode, stub);
+ else {
+ ret = iot_schedule_ordered ((iot_conf_t *)this->private,
+ loc->inode, stub);
+ fd_unref (fd);
+ }
+
+out:
+ if (ret < 0) {
+ STACK_UNWIND_STRICT (stat, frame, -1, -ret, NULL);
+
+ if (stub != NULL) {
+ call_stub_destroy (stub);
+ }
+ }
+ return 0;
+}
+
+
+int
+iot_fstat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct stat *buf)
+{
+ 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)
+{
+ STACK_WIND (frame, iot_fstat_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->fstat,
+ fd);
+ return 0;
+}
+
+
+int
+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);
+ if (!stub) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "cannot create fop_fstat call stub"
+ "(out of memory)");
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ ret = iot_schedule_ordered ((iot_conf_t *)this->private, fd->inode,
+ stub);
+out:
+ if (ret < 0) {
+ STACK_UNWIND_STRICT (fstat, frame, -1, -ret, NULL);
+
+ if (stub != NULL) {
+ call_stub_destroy (stub);
+ }
+ }
+ return 0;
+}
+
+
+int
+iot_truncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct stat *prebuf,
+ struct stat *postbuf)
+{
+ STACK_UNWIND_STRICT (truncate, frame, op_ret, op_errno, prebuf,
+ postbuf);
+ return 0;
+}
+
+
+int
+iot_truncate_wrapper (call_frame_t *frame, xlator_t *this, loc_t *loc,
+ off_t offset)
+{
+ STACK_WIND (frame, iot_truncate_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->truncate,
+ loc, offset);
+ return 0;
+}
+
+
+int
+iot_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset)
+{
+ call_stub_t *stub;
+ fd_t *fd = NULL;
+ int ret = -1;
+
+ 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"
+ "(out of memory)");
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ fd = fd_lookup (loc->inode, frame->root->pid);
+ if (fd == NULL)
+ ret = iot_schedule_unordered ((iot_conf_t *)this->private,
+ loc->inode, stub);
+ else {
+ ret = iot_schedule_ordered ((iot_conf_t *)this->private,
+ loc->inode, stub);
+ fd_unref (fd);
+ }
+
+out:
+ if (ret < 0) {
+ STACK_UNWIND_STRICT (truncate, frame, -1, -ret, NULL, NULL);
+
+ if (stub != NULL) {
+ call_stub_destroy (stub);
+ }
+ }
+
+ return 0;
+}
+
+
+int
+iot_ftruncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct stat *prebuf,
+ struct stat *postbuf)
+{
+ STACK_UNWIND_STRICT (ftruncate, frame, op_ret, op_errno, prebuf,
+ postbuf);
+ return 0;
+}
+
+
+int
+iot_ftruncate_wrapper (call_frame_t *frame, xlator_t *this, fd_t *fd,
+ off_t offset)
+{
+ STACK_WIND (frame, iot_ftruncate_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->ftruncate,
+ fd, offset);
+ return 0;
+}
+
+
+int
+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);
+ if (!stub) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "cannot create fop_ftruncate call stub"
+ "(out of memory)");
+ ret = -ENOMEM;
+ goto out;
+ }
+ ret = iot_schedule_ordered ((iot_conf_t *)this->private, fd->inode,
+ stub);
+out:
+ if (ret < 0) {
+ STACK_UNWIND_STRICT (ftruncate, frame, -1, -ret, NULL, NULL);
+
+ if (stub != NULL) {
+ call_stub_destroy (stub);
+ }
+ }
+ return 0;
+}
+
+
+int
+iot_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)
+{
+ STACK_UNWIND_STRICT (checksum, frame, op_ret, op_errno, file_checksum,
+ dir_checksum);
+ return 0;
+}
+
+
+int
+iot_checksum_wrapper (call_frame_t *frame, xlator_t *this, loc_t *loc,
+ int32_t flags)
+{
+ STACK_WIND (frame, iot_checksum_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->checksum,
+ loc, flags);
+
+ return 0;
+}
+
+
+int
+iot_checksum (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags)
+{
+ call_stub_t *stub = NULL;
+ int ret = -1;
+
+ stub = fop_checksum_stub (frame, iot_checksum_wrapper, loc, flags);
+
+ if (!stub) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "cannot create fop_checksum call stub"
+ "(out of memory)");
+ ret = -ENOMEM;
+ goto out;
+ }
+ ret = iot_schedule_unordered ((iot_conf_t *)this->private, loc->inode,
+ stub);
+out:
+ if (ret < 0) {
+ STACK_UNWIND_STRICT (checksum, frame, -1, -ret, NULL, NULL);
+
+ if (stub != NULL) {
+ call_stub_destroy (stub);
+ }
+ }
+ return 0;
+}
+
+
+int
+iot_unlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct stat *preparent,
+ struct stat *postparent)
+{
+ STACK_UNWIND_STRICT (unlink, frame, op_ret, op_errno, preparent,
+ postparent);
+ return 0;
+}
+
+
+int
+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);
+
+ return 0;
+}
+
+
+int
+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);
+ if (!stub) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "cannot create fop_unlink call stub"
+ "(out of memory)");
+ ret = -1;
+ goto out;
+ }
+
+ ret = iot_schedule_unordered((iot_conf_t *)this->private, loc->inode,
+ stub);
+
+out:
+ if (ret < 0) {
+ STACK_UNWIND_STRICT (unlink, frame, -1, -ret, NULL, NULL);
+
+ if (stub != NULL) {
+ call_stub_destroy (stub);
+ }
+ }
+
+ return 0;
+}
+
+
+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 stat *buf, struct stat *preparent, struct stat *postparent)
{
- IOT_FOP (lk, frame, this, fd, cmd, flock, xdata);
+ STACK_UNWIND_STRICT (link, frame, op_ret, op_errno, inode, buf,
+ preparent, postparent);
return 0;
}
int
-iot_stat (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
+iot_link_wrapper (call_frame_t *frame, xlator_t *this, loc_t *old, loc_t *new)
{
- IOT_FOP (stat, frame, this, loc, xdata);
+ STACK_WIND (frame, iot_link_cbk, FIRST_CHILD (this),
+ 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)
+{
+ call_stub_t *stub = NULL;
+ int ret = -1;
+
+ 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)");
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ ret = iot_schedule_unordered ((iot_conf_t *)this->private,
+ oldloc->inode, stub);
+out:
+ if (ret < 0) {
+ STACK_UNWIND_STRICT (link, frame, -1, -ret, NULL, NULL, NULL,
+ NULL);
+
+ if (stub != NULL) {
+ call_stub_destroy (stub);
+ }
+ }
return 0;
}
int
-iot_fstat (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
+iot_opendir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, fd_t *fd)
{
- IOT_FOP (fstat, frame, this, 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)
+{
+ STACK_WIND (frame, iot_opendir_cbk, FIRST_CHILD (this),
+ 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)
+{
+ call_stub_t *stub = NULL;
+ int ret = -1;
+
+ 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)");
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ ret = iot_schedule_unordered ((iot_conf_t *)this->private, loc->inode,
+ stub);
+out:
+ if (ret < 0) {
+ STACK_UNWIND_STRICT (opendir, frame, -1, -ret, NULL);
+
+ if (stub != NULL) {
+ call_stub_destroy (stub);
+ }
+ }
return 0;
}
int
-iot_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset,
- dict_t *xdata)
+iot_fsyncdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno)
{
- IOT_FOP (truncate, frame, this, loc, offset, xdata);
+ STACK_UNWIND_STRICT (fsyncdir, frame, op_ret, op_errno);
return 0;
}
int
-iot_ftruncate (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
- dict_t *xdata)
+iot_fsyncdir_wrapper (call_frame_t *frame, xlator_t *this, fd_t *fd,
+ int datasync)
{
- IOT_FOP (ftruncate, frame, this, fd, offset, xdata);
+ STACK_WIND (frame, iot_fsyncdir_cbk, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->fsyncdir, fd, datasync);
return 0;
}
+int
+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);
+ if (!stub) {
+ gf_log (this->name, GF_LOG_ERROR, "cannot create fsyncdir stub"
+ "(out of memory)");
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ ret = iot_schedule_ordered ((iot_conf_t *)this->private, fd->inode,
+ stub);
+out:
+ if (ret < 0) {
+ STACK_UNWIND_STRICT (fsyncdir, frame, -1, -ret);
+
+ if (stub != NULL) {
+ call_stub_destroy (stub);
+ }
+ }
+ return 0;
+}
+
int
-iot_unlink (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t xflag,
- dict_t *xdata)
+iot_statfs_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct statvfs *buf)
{
- IOT_FOP (unlink, frame, this, loc, xflag, xdata);
+ STACK_UNWIND_STRICT (statfs, frame, op_ret, op_errno, buf);
return 0;
}
int
-iot_link (call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc,
- dict_t *xdata)
+iot_statfs_wrapper (call_frame_t *frame, xlator_t *this, loc_t *loc)
{
- IOT_FOP (link, frame, this, oldloc, newloc, xdata);
+ STACK_WIND (frame, iot_statfs_cbk, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->statfs, loc);
return 0;
}
int
-iot_opendir (call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd,
- dict_t *xdata)
+iot_statfs (call_frame_t *frame, xlator_t *this, loc_t *loc)
{
- IOT_FOP (opendir, frame, this, loc, fd, xdata);
+ call_stub_t *stub = NULL;
+ int ret = -1;
+
+ 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)");
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ ret = iot_schedule_unordered ((iot_conf_t *)this->private, loc->inode,
+ stub);
+out:
+ if (ret < 0) {
+ STACK_UNWIND_STRICT (statfs, frame, -1, -ret, NULL);
+
+ if (stub != NULL) {
+ call_stub_destroy (stub);
+ }
+ }
return 0;
}
int
-iot_fsyncdir (call_frame_t *frame, xlator_t *this, fd_t *fd, int datasync,
- dict_t *xdata)
+iot_setxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno)
{
- IOT_FOP (fsyncdir, frame, this, fd, datasync, xdata);
+ STACK_UNWIND_STRICT (setxattr, frame, op_ret, op_errno);
return 0;
}
int
-iot_statfs (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
+iot_setxattr_wrapper (call_frame_t *frame, xlator_t *this, loc_t *loc,
+ dict_t *dict, int32_t flags)
{
- IOT_FOP (statfs, frame, this, loc, xdata);
+ STACK_WIND (frame, iot_setxattr_cbk, FIRST_CHILD (this),
+ 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)
{
- IOT_FOP (setxattr, frame, this, loc, dict, flags, xdata);
+ call_stub_t *stub = NULL;
+ fd_t *fd = NULL;
+ int ret = -1;
+
+ stub = fop_setxattr_stub (frame, iot_setxattr_wrapper, loc, dict,
+ flags);
+ if (!stub) {
+ gf_log (this->name, GF_LOG_ERROR, "cannot create setxattr stub"
+ "(out of memory)");
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ fd = fd_lookup (loc->inode, frame->root->pid);
+ if (fd == NULL)
+ ret = iot_schedule_unordered ((iot_conf_t *)this->private,
+ loc->inode, stub);
+ else {
+ ret = iot_schedule_ordered ((iot_conf_t *)this->private,
+ loc->inode, stub);
+ fd_unref (fd);
+ }
+
+out:
+ if (ret < 0) {
+ STACK_UNWIND_STRICT (setxattr, frame, -1, -ret);
+
+ if (stub != NULL) {
+ call_stub_destroy (stub);
+ }
+ }
+ return 0;
+}
+
+
+int
+iot_getxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *dict)
+{
+ 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)
+{
+ STACK_WIND (frame, iot_getxattr_cbk, FIRST_CHILD (this),
+ 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;
+ fd_t *fd = NULL;
+ int ret = -1;
+
+ 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)");
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ fd = fd_lookup (loc->inode, frame->root->pid);
+ if (!fd)
+ ret = iot_schedule_unordered ((iot_conf_t *)this->private,
+ loc->inode, stub);
+ else {
+ ret = iot_schedule_ordered ((iot_conf_t *)this->private,
+ loc->inode, stub);
+ fd_unref (fd);
+ }
+
+out:
+ if (ret < 0) {
+ STACK_UNWIND_STRICT (getxattr, frame, -1, -ret, NULL);
+
+ if (stub != NULL) {
+ call_stub_destroy (stub);
+ }
+ }
+ return 0;
+}
+
+
+int
+iot_fgetxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *dict)
{
- IOT_FOP (getxattr, frame, this, loc, name, 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)
+{
+ STACK_WIND (frame, iot_fgetxattr_cbk, FIRST_CHILD (this),
+ 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);
+ if (!stub) {
+ gf_log (this->name, GF_LOG_ERROR, "cannot create fgetxattr stub"
+ "(out of memory)");
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ ret = iot_schedule_ordered ((iot_conf_t *)this->private, fd->inode,
+ stub);
+out:
+ if (ret < 0) {
+ STACK_UNWIND_STRICT (fgetxattr, frame, -1, -ret, NULL);
+
+ if (stub != NULL) {
+ call_stub_destroy (stub);
+ }
+ }
+ return 0;
+}
+
+
+int
+iot_fsetxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno)
+{
+ 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)
{
- IOT_FOP (fgetxattr, frame, this, fd, name, xdata);
+ STACK_WIND (frame, iot_fsetxattr_cbk, FIRST_CHILD (this),
+ 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)
{
- IOT_FOP (fsetxattr, frame, this, fd, dict, flags, xdata);
+ call_stub_t *stub = NULL;
+ int ret = -1;
+
+ stub = fop_fsetxattr_stub (frame, iot_fsetxattr_wrapper, fd, dict,
+ flags);
+ if (!stub) {
+ gf_log (this->name, GF_LOG_ERROR, "cannot create fsetxattr stub"
+ "(out of memory)");
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ ret = iot_schedule_ordered ((iot_conf_t *)this->private, fd->inode,
+ stub);
+out:
+ if (ret < 0) {
+ STACK_UNWIND_STRICT (fsetxattr, frame, -1, -ret);
+
+ if (stub != NULL) {
+ call_stub_destroy (stub);
+ }
+ }
return 0;
}
int
-iot_removexattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
- const char *name, dict_t *xdata)
+iot_removexattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno)
{
- IOT_FOP (removexattr, frame, this, loc, name, xdata);
+ STACK_UNWIND_STRICT (removexattr, frame, op_ret, op_errno);
return 0;
}
+
int
-iot_fremovexattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
- const char *name, dict_t *xdata)
+iot_removexattr_wrapper (call_frame_t *frame, xlator_t *this, loc_t *loc,
+ const char *name)
{
- IOT_FOP (fremovexattr, frame, this, fd, name, xdata);
+ STACK_WIND (frame, iot_removexattr_cbk, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->removexattr, loc, name);
return 0;
}
int
-iot_readdirp (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
- off_t offset, dict_t *xdata)
+iot_removexattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
+ const char *name)
{
- IOT_FOP (readdirp, frame, this, fd, size, offset, xdata);
+ call_stub_t *stub = NULL;
+ fd_t *fd = NULL;
+ int ret = -1;
+
+ stub = fop_removexattr_stub (frame, iot_removexattr_wrapper, loc,
+ name);
+ if (!stub) {
+ gf_log (this->name, GF_LOG_ERROR,"cannot get removexattr fop"
+ "(out of memory)");
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ fd = fd_lookup (loc->inode, frame->root->pid);
+ if (!fd)
+ ret = iot_schedule_unordered ((iot_conf_t *)this->private,
+ loc->inode, stub);
+ else {
+ ret = iot_schedule_ordered ((iot_conf_t *)this->private,
+ loc->inode, stub);
+ fd_unref (fd);
+ }
+
+out:
+ if (ret < 0) {
+ STACK_UNWIND_STRICT (removexattr, frame, -1, -ret);
+
+ if (stub != NULL) {
+ call_stub_destroy (stub);
+ }
+ }
return 0;
}
int
-iot_readdir (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
- off_t offset, dict_t *xdata)
+iot_readdirp_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, gf_dirent_t *entries)
{
- IOT_FOP (readdir, frame, this, fd, size, offset, xdata);
+ STACK_UNWIND_STRICT (readdirp, frame, op_ret, op_errno, entries);
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)
+iot_readdirp_wrapper (call_frame_t *frame, xlator_t *this, fd_t *fd,
+ size_t size, off_t offset)
{
- IOT_FOP (inodelk, frame, this, volume, loc, cmd, lock, xdata);
+ STACK_WIND (frame, iot_readdirp_cbk, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->readdirp, fd, size, offset);
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)
+iot_readdirp (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
+ off_t offset)
{
- IOT_FOP (finodelk, frame, this, volume, fd, cmd, lock, xdata);
+ call_stub_t *stub = NULL;
+ int ret = -1;
+
+ stub = fop_readdirp_stub (frame, iot_readdirp_wrapper, fd, size,
+ offset);
+ if (!stub) {
+ gf_log (this->private, GF_LOG_ERROR,"cannot get readdir stub"
+ "(out of memory)");
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ ret = iot_schedule_ordered ((iot_conf_t *)this->private, fd->inode,
+ stub);
+out:
+ if (ret < 0) {
+ STACK_UNWIND_STRICT (readdirp, frame, -1, -ret, NULL);
+
+ if (stub != NULL) {
+ call_stub_destroy (stub);
+ }
+ }
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)
+iot_readdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, gf_dirent_t *entries)
{
- IOT_FOP (entrylk, frame, this, volume, loc, basename, cmd, type, xdata);
+ STACK_UNWIND_STRICT (readdir, frame, op_ret, op_errno, entries);
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)
+iot_readdir_wrapper (call_frame_t *frame, xlator_t *this, fd_t *fd,
+ size_t size, off_t offset)
{
- IOT_FOP (fentrylk, frame, this, volume, fd, basename, cmd, type, xdata);
+ STACK_WIND (frame, iot_readdir_cbk, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->readdir, fd, size, offset);
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)
+iot_readdir (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
+ off_t offset)
{
- IOT_FOP (xattrop, frame, this, loc, optype, xattr, xdata);
+ call_stub_t *stub = NULL;
+ int ret = -1;
+
+ 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)");
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ ret = iot_schedule_ordered ((iot_conf_t *)this->private, fd->inode,
+ stub);
+out:
+ if (ret < 0) {
+ STACK_UNWIND_STRICT (readdir, frame, -1, -ret, NULL);
+
+ if (stub != NULL) {
+ call_stub_destroy (stub);
+ }
+ }
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)
+iot_xattrop_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xattr)
{
- IOT_FOP (fxattrop, frame, this, fd, optype, xattr, xdata);
+ STACK_UNWIND_STRICT (xattrop, frame, op_ret, op_errno, xattr);
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)
+int
+iot_xattrop_wrapper (call_frame_t *frame, xlator_t *this, loc_t *loc,
+ gf_xattrop_flags_t optype, dict_t *xattr)
{
- IOT_FOP (rchecksum, frame, this, fd, offset, len, xdata);
+ STACK_WIND (frame, iot_xattrop_cbk, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->xattrop, loc, optype, xattr);
return 0;
}
+
int
-iot_fallocate(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t mode,
- off_t offset, size_t len, dict_t *xdata)
+iot_xattrop (call_frame_t *frame, xlator_t *this, loc_t *loc,
+ gf_xattrop_flags_t optype, dict_t *xattr)
{
- IOT_FOP (fallocate, frame, this, fd, mode, offset, len, xdata);
+ call_stub_t *stub = NULL;
+ fd_t *fd = NULL;
+ int ret = -1;
+
+ stub = fop_xattrop_stub (frame, iot_xattrop_wrapper, loc, optype,
+ xattr);
+ if (!stub) {
+ gf_log (this->name, GF_LOG_ERROR, "cannot create xattrop stub"
+ "(out of memory)");
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ fd = fd_lookup (loc->inode, frame->root->pid);
+ if (!fd)
+ ret = iot_schedule_unordered ((iot_conf_t *)this->private,
+ loc->inode, stub);
+ else {
+ ret = iot_schedule_ordered ((iot_conf_t *)this->private,
+ loc->inode, stub);
+ fd_unref (fd);
+ }
+
+out:
+ if (ret < 0) {
+ STACK_UNWIND_STRICT (xattrop, frame, -1, -ret, NULL);
+
+ if (stub != NULL) {
+ call_stub_destroy (stub);
+ }
+ }
return 0;
}
+
int
-iot_discard(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
- size_t len, dict_t *xdata)
+iot_fxattrop_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xattr)
{
- IOT_FOP (discard, frame, this, fd, offset, len, xdata);
+ STACK_UNWIND_STRICT (fxattrop, frame, op_ret, op_errno, xattr);
return 0;
}
int
-iot_zerofill(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
- off_t len, dict_t *xdata)
+iot_fxattrop_wrapper (call_frame_t *frame, xlator_t *this, fd_t *fd,
+ gf_xattrop_flags_t optype, dict_t *xattr)
{
- IOT_FOP (zerofill, frame, this, fd, offset, len, xdata);
+ STACK_WIND (frame, iot_fxattrop_cbk, FIRST_CHILD (this),
+ 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)
+{
+ call_stub_t *stub = NULL;
+ int ret = -1;
+
+ stub = fop_fxattrop_stub (frame, iot_fxattrop_wrapper, fd, optype,
+ xattr);
+ if (!stub) {
+ gf_log (this->name, GF_LOG_ERROR, "cannot create fxattrop stub"
+ "(out of memory)");
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ ret = iot_schedule_ordered ((iot_conf_t *)this->private, fd->inode,
+ stub);
+out:
+ if (ret < 0) {
+ STACK_UNWIND_STRICT (fxattrop, frame, -1, -ret, NULL);
+ if (stub != NULL) {
+ call_stub_destroy (stub);
+ }
+ }
+ return 0;
+}
+
+
+/* Must be called with worker lock held */
+void
+_iot_queue (iot_worker_t *worker, iot_request_t *req)
+{
+ list_add_tail (&req->list, &worker->rqlist);
+
+ /* dq_cond */
+ worker->queue_size++;
+ iot_notify_worker(worker);
+}
+
+
+iot_request_t *
+iot_init_request (iot_worker_t *worker, call_stub_t *stub)
+{
+ iot_request_t *req = NULL;
+
+ req = mem_get (worker->req_pool);
+ if (req == NULL) {
+ goto out;
+ }
+
+ req->stub = stub;
+out:
+ return req;
+}
+
+
+void
+iot_destroy_request (iot_worker_t *worker, iot_request_t * req)
+{
+ if ((req == NULL) || (worker == NULL))
+ return;
+
+ mem_put (worker->req_pool, req);
+}
+
+
+/* Must be called with worker lock held. */
+gf_boolean_t
+iot_can_ordered_exit (iot_worker_t * worker)
+{
+ gf_boolean_t allow_exit = _gf_false;
+ iot_conf_t *conf = NULL;
+
+ conf = worker->conf;
+ /* We dont want this thread to exit if its index is
+ * below the min thread count.
+ */
+ if (worker->thread_idx >= conf->min_o_threads)
+ allow_exit = _gf_true;
+
+ return allow_exit;
+}
+
+/* Must be called with worker lock held. */
+gf_boolean_t
+iot_ordered_exit (int cond_waitres, iot_worker_t *worker)
+{
+ gf_boolean_t allow_exit = _gf_false;
+
+ if (worker->state == IOT_STATE_EXIT_REQUEST) {
+ allow_exit = _gf_true;
+ } else if (cond_waitres == ETIMEDOUT) {
+ allow_exit = iot_can_ordered_exit (worker);
+ }
+
+ if (allow_exit) {
+ worker->state = IOT_STATE_DEAD;
+ worker->thread = 0;
+ }
+
+ return allow_exit;
+}
+
int
-__iot_workers_scale (iot_conf_t *conf)
+iot_ordered_request_wait (iot_worker_t * worker)
{
- int scale = 0;
- int diff = 0;
- pthread_t thread;
- int ret = 0;
- int i = 0;
+ int waitres = 0;
+ int retstat = 0;
+
+ if (worker->state == IOT_STATE_EXIT_REQUEST) {
+ retstat = -1;
+ goto out;
+ }
+
+ waitres = iot_notify_wait (worker, worker->conf->o_idle_time);
+ if (iot_ordered_exit (waitres, worker)) {
+ retstat = -1;
+ }
+
+out:
+ return retstat;
+}
+
- for (i = 0; i < IOT_PRI_MAX; i++)
- scale += min (conf->queue_sizes[i], conf->ac_iot_limit[i]);
+call_stub_t *
+iot_dequeue_ordered (iot_worker_t *worker)
+{
+ call_stub_t *stub = NULL;
+ iot_request_t *req = NULL;
+ int waitstat = 0;
- if (scale < IOT_MIN_THREADS)
- scale = IOT_MIN_THREADS;
+ LOCK (&worker->qlock);
+ {
+ while (!worker->queue_size) {
+ waitstat = 0;
+ waitstat = iot_ordered_request_wait (worker);
+ /* We must've timed out and are now required to
+ * exit.
+ */
+ if (waitstat == -1)
+ goto out;
+ }
- if (scale > conf->max_count)
- scale = conf->max_count;
+ list_for_each_entry (req, &worker->rqlist, list)
+ break;
+ list_del (&req->list);
+ stub = req->stub;
- if (conf->curr_count < scale) {
- diff = scale - conf->curr_count;
+ worker->queue_size--;
}
+out:
+ UNLOCK (&worker->qlock);
+ iot_destroy_request (worker, req);
- while (diff) {
- diff --;
+ return stub;
+}
- ret = gf_thread_create (&thread, &conf->w_attr, iot_worker, conf);
- if (ret == 0) {
- conf->curr_count++;
- gf_log (conf->this->name, GF_LOG_DEBUG,
- "scaled threads to %d (queue_size=%d/%d)",
- conf->curr_count, conf->queue_size, scale);
- } else {
+
+void *
+iot_worker_ordered (void *arg)
+{
+ iot_worker_t *worker = arg;
+ call_stub_t *stub = NULL;
+
+ while (1) {
+
+ stub = iot_dequeue_ordered (worker);
+ /* If stub is NULL, we must've timed out waiting for a
+ * request and have now been allowed to exit.
+ */
+ if (!stub)
break;
- }
+ call_resume (stub);
+ }
+
+ return NULL;
+}
+
+
+/* Must be called with worker lock held. */
+gf_boolean_t
+iot_can_unordered_exit (iot_worker_t * worker)
+{
+ gf_boolean_t allow_exit = _gf_false;
+ iot_conf_t *conf = NULL;
+
+ conf = worker->conf;
+ /* We dont want this thread to exit if its index is
+ * below the min thread count.
+ */
+ if (worker->thread_idx >= conf->min_u_threads)
+ allow_exit = _gf_true;
+
+ return allow_exit;
+}
+
+
+/* Must be called with worker lock held. */
+gf_boolean_t
+iot_unordered_exit (int cond_waitres, iot_worker_t *worker)
+{
+ gf_boolean_t allow_exit = _gf_false;
+
+ if (worker->state == IOT_STATE_EXIT_REQUEST) {
+ allow_exit = _gf_true;
+ } else if (cond_waitres == ETIMEDOUT) {
+ allow_exit = iot_can_unordered_exit (worker);
}
- return diff;
+ if (allow_exit) {
+ worker->state = IOT_STATE_DEAD;
+ worker->thread = 0;
+ }
+
+ return allow_exit;
}
int
-iot_workers_scale (iot_conf_t *conf)
+iot_unordered_request_wait (iot_worker_t * worker)
{
- int ret = -1;
+ int waitres = 0;
+ int retstat = 0;
- if (conf == NULL) {
- ret = -EINVAL;
+ if (worker->state == IOT_STATE_EXIT_REQUEST) {
+ retstat = -1;
goto out;
}
- pthread_mutex_lock (&conf->mutex);
- {
- ret = __iot_workers_scale (conf);
+ waitres = iot_notify_wait (worker, worker->conf->u_idle_time);
+ if (iot_unordered_exit (waitres, worker)) {
+ retstat = -1;
}
- pthread_mutex_unlock (&conf->mutex);
out:
- return ret;
+ return retstat;
+}
+
+
+call_stub_t *
+iot_dequeue_unordered (iot_worker_t *worker)
+{
+ call_stub_t *stub= NULL;
+ iot_request_t *req = NULL;
+ int waitstat = 0;
+
+ LOCK (&worker->qlock);
+ {
+ while (!worker->queue_size) {
+ waitstat = 0;
+ waitstat = iot_unordered_request_wait (worker);
+ /* If -1, request wait must've timed
+ * out.
+ */
+ if (waitstat == -1)
+ goto out;
+ }
+
+ list_for_each_entry (req, &worker->rqlist, list)
+ break;
+ list_del (&req->list);
+ stub = req->stub;
+
+ worker->queue_size--;
+ }
+out:
+ UNLOCK (&worker->qlock);
+ iot_destroy_request (worker, req);
+
+ return stub;
+}
+
+
+void *
+iot_worker_unordered (void *arg)
+{
+ iot_worker_t *worker = arg;
+ call_stub_t *stub = NULL;
+
+ while (1) {
+
+ stub = iot_dequeue_unordered (worker);
+ /* If no request was received, we must've timed out,
+ * and can exit. */
+ if (!stub)
+ break;
+
+ call_resume (stub);
+ }
+
+ return NULL;
}
void
-set_stack_size (iot_conf_t *conf)
+deallocate_worker_array (iot_worker_t **workers)
{
- int err = 0;
- size_t stacksize = IOT_THREAD_STACK_SIZE;
- xlator_t *this = NULL;
+ FREE (workers);
+}
- this = THIS;
+void
+deallocate_workers (iot_worker_t **workers,
+ int start_alloc_idx, int count)
+{
+ int i;
+ int end_count;
+
+ end_count = count + start_alloc_idx;
+ for (i = start_alloc_idx; (i < end_count); i++) {
+ if (workers[i] != NULL) {
+ mem_pool_destroy (workers[i]->req_pool);
+ FREE (workers[i]);
+ workers[i] = NULL;
+ }
+ }
+
+}
- 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");
+
+iot_worker_t **
+allocate_worker_array (int count)
+{
+ iot_worker_t **warr = NULL;
+
+ warr = CALLOC (count, sizeof (iot_worker_t *));
+
+ return warr;
+}
+
+
+iot_worker_t *
+allocate_worker (iot_conf_t * conf)
+{
+ iot_worker_t *wrk = NULL;
+
+ wrk = CALLOC (1, sizeof (iot_worker_t));
+ if (wrk == NULL) {
+ gf_log (conf->this->name, GF_LOG_ERROR, "out of memory");
+ goto out;
}
- conf->stack_size = stacksize;
+ wrk->req_pool = mem_pool_new (iot_request_t, IOT_REQUEST_MEMPOOL_SIZE);
+ if (wrk->req_pool == NULL)
+ goto free_wrk;
+
+ INIT_LIST_HEAD (&wrk->rqlist);
+ wrk->conf = conf;
+ iot_notify_init (wrk);
+ wrk->state = IOT_STATE_DEAD;
+
+out:
+ return wrk;
+
+free_wrk:
+ FREE (wrk);
+ return NULL;
}
-int32_t
-mem_acct_init (xlator_t *this)
+int
+allocate_workers (iot_conf_t *conf, iot_worker_t **workers, int start_alloc_idx,
+ int count)
{
- int ret = -1;
+ int i;
+ int end_count, ret = -1;
+
+ end_count = count + start_alloc_idx;
+ for (i = start_alloc_idx; i < end_count; i++) {
+ workers[i] = allocate_worker (conf);
+ if (workers[i] == NULL) {
+ ret = -ENOMEM;
+ goto out;
+ }
+ workers[i]->thread_idx = i;
+ }
+ ret = 0;
+
+out:
+ return ret;
+}
+
+
+void
+iot_stop_worker (iot_worker_t *worker)
+{
+ LOCK (&worker->qlock);
+ {
+ worker->state = IOT_STATE_EXIT_REQUEST;
+ }
+ UNLOCK (&worker->qlock);
+
+ iot_notify_worker (worker);
+ pthread_join (worker->thread, NULL);
+}
+
+
+void
+iot_stop_workers (iot_worker_t **workers, int start_idx, int count)
+{
+ int i = 0;
+ int end_idx = 0;
- if (!this)
- return ret;
+ end_idx = start_idx + count;
+ for (i = start_idx; i < end_idx; i++) {
+ if (workers[i] != NULL) {
+ iot_stop_worker (workers[i]);
+ }
+ }
+}
- ret = xlator_mem_acct_init (this, gf_iot_mt_end + 1);
+int
+iot_startup_worker (iot_worker_t *worker, iot_worker_fn workerfunc)
+{
+ int ret = -1;
+ ret = pthread_create (&worker->thread, &worker->conf->w_attr,
+ workerfunc, worker);
if (ret != 0) {
- gf_log (this->name, GF_LOG_ERROR, "Memory accounting init"
- "failed");
- return ret;
+ gf_log (worker->conf->this->name, GF_LOG_ERROR,
+ "cannot start worker (%s)", strerror (errno));
+ ret = -ret;
+ } else {
+ worker->state = IOT_STATE_ACTIVE;
}
return ret;
}
+
int
-iot_priv_dump (xlator_t *this)
+iot_startup_workers (iot_worker_t **workers, int start_idx, int count,
+ iot_worker_fn workerfunc)
{
- iot_conf_t *conf = NULL;
- char key_prefix[GF_DUMP_MAX_BUF_LEN];
-
- if (!this)
- return 0;
+ int i = 0;
+ int end_idx = 0;
+ int ret = -1;
+
+ end_idx = start_idx + count;
+ for (i = start_idx; i < end_idx; i++) {
+ ret = iot_startup_worker (workers[i], workerfunc);
+ if (ret < 0) {
+ goto out;
+ }
+ }
- conf = this->private;
- if (!conf)
- return 0;
+ ret = 0;
+out:
+ return ret;
+}
- snprintf (key_prefix, GF_DUMP_MAX_BUF_LEN, "%s.%s", this->type,
- this->name);
- gf_proc_dump_add_section(key_prefix);
+void
+set_stack_size (iot_conf_t *conf)
+{
+ int err = 0;
+ size_t stacksize = IOT_THREAD_STACK_SIZE;
- 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]);
+ pthread_attr_init (&conf->w_attr);
+ err = pthread_attr_setstacksize (&conf->w_attr, stacksize);
+ if (err == EINVAL) {
+ gf_log (conf->this->name, GF_LOG_WARNING,
+ "Using default thread stack size");
+ }
+}
- gf_proc_dump_write("cached least rate", "%u",
- conf->throttle.cached_rate);
- gf_proc_dump_write("least rate limit", "%u", conf->throttle.rate_limit);
- return 0;
+void
+iot_cleanup_workers (iot_conf_t *conf)
+{
+ if (conf->uworkers != NULL) {
+ iot_stop_workers (conf->uworkers, 0,
+ conf->max_u_threads);
+
+ deallocate_workers (conf->uworkers, 0,
+ conf->max_u_threads);
+
+ deallocate_worker_array (conf->uworkers);
+ }
+
+ if (conf->oworkers != NULL) {
+ iot_stop_workers (conf->oworkers, 0,
+ conf->max_o_threads);
+
+ deallocate_workers (conf->oworkers, 0,
+ conf->max_o_threads);
+
+ deallocate_worker_array (conf->oworkers);
+ }
}
+
int
-reconfigure (xlator_t *this, dict_t *options)
+workers_init (iot_conf_t *conf)
{
- iot_conf_t *conf = NULL;
- int ret = -1;
+ int ret = -1;
- conf = this->private;
- if (!conf)
- goto out;
+ if (conf == NULL) {
+ ret = -EINVAL;
+ goto err;
+ }
+
+ /* Initialize un-ordered workers */
+ conf->uworkers = allocate_worker_array (conf->max_u_threads);
+ if (conf->uworkers == NULL) {
+ gf_log (conf->this->name, GF_LOG_ERROR, "out of memory");
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ ret = allocate_workers (conf, conf->uworkers, 0,
+ conf->max_u_threads);
+ if (ret < 0) {
+ gf_log (conf->this->name, GF_LOG_ERROR, "out of memory");
+ goto err;
+ }
- GF_OPTION_RECONF ("thread-count", conf->max_count, options, int32, out);
+ /* Initialize ordered workers */
+ conf->oworkers = allocate_worker_array (conf->max_o_threads);
+ if (conf->oworkers == NULL) {
+ gf_log (conf->this->name, GF_LOG_ERROR, "out of memory");
+ ret = -ENOMEM;
+ goto err;
+ }
- GF_OPTION_RECONF ("high-prio-threads",
- conf->ac_iot_limit[IOT_PRI_HI], options, int32, out);
+ ret = allocate_workers (conf, conf->oworkers, 0,
+ conf->max_o_threads);
+ if (ret < 0) {
+ gf_log (conf->this->name, GF_LOG_ERROR, "out of memory");
+ goto err;
+ }
- GF_OPTION_RECONF ("normal-prio-threads",
- conf->ac_iot_limit[IOT_PRI_NORMAL], options, int32,
- out);
+ set_stack_size (conf);
+ ret = iot_startup_workers (conf->oworkers, 0, conf->min_o_threads,
+ iot_worker_ordered);
+ if (ret == -1) {
+ /* logged inside iot_startup_workers */
+ goto err;
+ }
- GF_OPTION_RECONF ("low-prio-threads",
- conf->ac_iot_limit[IOT_PRI_LO], options, int32, out);
+ ret = iot_startup_workers (conf->uworkers, 0, conf->min_u_threads,
+ iot_worker_unordered);
+ if (ret == -1) {
+ /* logged inside iot_startup_workers */
+ goto err;
+ }
- 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);
+ return 0;
- GF_OPTION_RECONF("least-rate-limit", conf->throttle.rate_limit, options,
- int32, out);
+err:
+ if (conf != NULL) {
+ iot_cleanup_workers (conf);
+ }
- ret = 0;
-out:
- return ret;
+ return ret;
}
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;
+ gf_boolean_t autoscaling = IOT_SCALING_OFF;
+ char *scalestr = NULL;
+ int min_threads, max_threads, ret = -1;
+
if (!this->children || this->children->next) {
gf_log ("io-threads", GF_LOG_ERROR,
"FATAL: iot not configured with exactly one child");
@@ -941,74 +2741,117 @@ init (xlator_t *this)
"dangling volume. check volfile ");
}
- conf = (void *) GF_CALLOC (1, sizeof (*conf),
- gf_iot_mt_iot_conf_t);
+ conf = (void *) CALLOC (1, sizeof (*conf));
if (conf == NULL) {
gf_log (this->name, GF_LOG_ERROR,
"out of memory");
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 ((dict_get_str (options, "autoscaling", &scalestr)) == 0) {
+ if ((gf_string2boolean (scalestr, &autoscaling)) == -1) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "'autoscaling' option must be"
+ " boolean");
+ 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;
+ if (dict_get (options, "thread-count")) {
+ thread_count = data_to_int32 (dict_get (options,
+ "thread-count"));
+ if (scalestr != NULL)
+ gf_log (this->name, GF_LOG_WARNING,
+ "'thread-count' is specified with "
+ "'autoscaling' on. Ignoring"
+ "'thread-count' option.");
+ if (thread_count < 2)
+ thread_count = IOT_MIN_THREADS;
}
- 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);
-
- GF_OPTION_INIT ("least-prio-threads",
- conf->ac_iot_limit[IOT_PRI_LEAST], int32, out);
-
- GF_OPTION_INIT ("idle-time", conf->idle_time, int32, out);
- GF_OPTION_INIT ("enable-least-priority", conf->least_priority,
- bool, out);
-
- GF_OPTION_INIT("least-rate-limit", conf->throttle.rate_limit, int32,
- out);
- if ((ret = pthread_mutex_init(&conf->throttle.lock, NULL)) != 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "pthread_mutex_init failed (%d)", ret);
+ min_threads = IOT_DEFAULT_THREADS;
+ max_threads = IOT_MAX_THREADS;
+ if (dict_get (options, "min-threads"))
+ min_threads = data_to_int32 (dict_get (options,
+ "min-threads"));
+
+ if (dict_get (options, "max-threads"))
+ max_threads = data_to_int32 (dict_get (options,
+ "max-threads"));
+
+ if (min_threads > max_threads) {
+ gf_log (this->name, GF_LOG_ERROR, " min-threads must be less "
+ "than max-threads");
goto out;
}
- conf->this = this;
-
- for (i = 0; i < IOT_PRI_MAX; i++) {
- INIT_LIST_HEAD (&conf->reqs[i]);
- }
-
- ret = iot_workers_scale (conf);
+ /* If autoscaling is off, then adjust the min and max
+ * threads according to thread-count.
+ * This is based on the assumption that despite autoscaling
+ * being off, we still want to have separate pools for data
+ * and meta-data threads.
+ */
+ if (!autoscaling)
+ max_threads = min_threads = thread_count;
+
+ /* If user specifies an odd number of threads, increase it by
+ * one. The reason for having an even number of threads is
+ * explained later.
+ */
+ if (max_threads % 2)
+ max_threads++;
+
+ if(min_threads % 2)
+ min_threads++;
+
+ /* If the user wants to have only a single thread for
+ * some strange reason, make sure we set this count to
+ * 2. Explained later.
+ */
+ if (min_threads < IOT_MIN_THREADS)
+ min_threads = IOT_MIN_THREADS;
+
+ /* Again, have atleast two. Read on. */
+ if (max_threads < IOT_MIN_THREADS)
+ max_threads = IOT_MIN_THREADS;
+
+ /* This is why we need atleast two threads.
+ * We're dividing the specified thread pool into
+ * 2 halves, equally between ordered and unordered
+ * pools.
+ */
+
+ /* Init params for un-ordered workers. */
+ pthread_mutex_init (&conf->utlock, NULL);
+ conf->max_u_threads = max_threads / 2;
+ conf->min_u_threads = min_threads / 2;
+ conf->u_idle_time = IOT_DEFAULT_IDLE;
+ conf->u_scaling = autoscaling;
+
+ /* Init params for ordered workers. */
+ pthread_mutex_init (&conf->otlock, NULL);
+ conf->max_o_threads = max_threads / 2;
+ conf->min_o_threads = min_threads / 2;
+ conf->o_idle_time = IOT_DEFAULT_IDLE;
+ conf->o_scaling = autoscaling;
+
+ gf_log (this->name, GF_LOG_DEBUG,
+ "io-threads: Autoscaling: %s, "
+ "min_threads: %d, max_threads: %d",
+ (autoscaling) ? "on":"off", min_threads, max_threads);
+ conf->this = this;
+ ret = workers_init (conf);
if (ret == -1) {
gf_log (this->name, GF_LOG_ERROR,
"cannot initialize worker threads, exiting init");
+ FREE (conf);
goto out;
}
this->private = conf;
ret = 0;
out:
- if (ret)
- GF_FREE (conf);
-
return ret;
}
@@ -1018,129 +2861,88 @@ fini (xlator_t *this)
{
iot_conf_t *conf = this->private;
- GF_FREE (conf);
+ FREE (conf);
this->private = NULL;
return;
}
-struct xlator_dumpops dumpops = {
- .priv = iot_priv_dump,
+/*
+ * O - Goes to ordered threadpool.
+ * U - Goes to un-ordered threadpool.
+ * V - Variable, depends on whether the file is open.
+ * If it is, then goes to ordered, otherwise to
+ * un-ordered.
+ */
+struct xlator_fops fops = {
+ .open = iot_open, /* U */
+ .create = iot_create, /* U */
+ .readv = iot_readv, /* O */
+ .writev = iot_writev, /* O */
+ .flush = iot_flush, /* O */
+ .fsync = iot_fsync, /* O */
+ .lk = iot_lk, /* O */
+ .stat = iot_stat, /* V */
+ .fstat = iot_fstat, /* O */
+ .truncate = iot_truncate, /* V */
+ .ftruncate = iot_ftruncate, /* O */
+ .checksum = iot_checksum, /* U */
+ .unlink = iot_unlink, /* U */
+ .lookup = iot_lookup, /* U */
+ .setattr = iot_setattr, /* U */
+ .fsetattr = iot_fsetattr, /* O */
+ .access = iot_access, /* U */
+ .readlink = iot_readlink, /* U */
+ .mknod = iot_mknod, /* U */
+ .mkdir = iot_mkdir, /* U */
+ .rmdir = iot_rmdir, /* U */
+ .symlink = iot_symlink, /* U */
+ .rename = iot_rename, /* U */
+ .link = iot_link, /* U */
+ .opendir = iot_opendir, /* U */
+ .fsyncdir = iot_fsyncdir, /* O */
+ .statfs = iot_statfs, /* U */
+ .setxattr = iot_setxattr, /* U */
+ .getxattr = iot_getxattr, /* U */
+ .fgetxattr = iot_fgetxattr, /* O */
+ .fsetxattr = iot_fsetxattr, /* O */
+ .removexattr = iot_removexattr, /* U */
+ .readdir = iot_readdir, /* O */
+ .readdirp = iot_readdirp, /* O */
+ .xattrop = iot_xattrop, /* U */
+ .fxattrop = iot_fxattrop, /* O */
};
-struct xlator_fops fops = {
- .open = iot_open,
- .create = iot_create,
- .readv = iot_readv,
- .writev = iot_writev,
- .flush = iot_flush,
- .fsync = iot_fsync,
- .lk = iot_lk,
- .stat = iot_stat,
- .fstat = iot_fstat,
- .truncate = iot_truncate,
- .ftruncate = iot_ftruncate,
- .unlink = iot_unlink,
- .lookup = iot_lookup,
- .setattr = iot_setattr,
- .fsetattr = iot_fsetattr,
- .access = iot_access,
- .readlink = iot_readlink,
- .mknod = iot_mknod,
- .mkdir = iot_mkdir,
- .rmdir = iot_rmdir,
- .symlink = iot_symlink,
- .rename = iot_rename,
- .link = iot_link,
- .opendir = iot_opendir,
- .fsyncdir = iot_fsyncdir,
- .statfs = iot_statfs,
- .setxattr = iot_setxattr,
- .getxattr = iot_getxattr,
- .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,
- .fallocate = iot_fallocate,
- .discard = iot_discard,
- .zerofill = iot_zerofill,
+struct xlator_mops mops = {
};
-struct xlator_cbks cbks;
+struct xlator_cbks cbks = {
+};
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 = {"thread-count"},
+ .type = GF_OPTION_TYPE_INT,
+ .min = IOT_MIN_THREADS,
+ .max = IOT_MAX_THREADS
},
- { .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"
-
- },
- { .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 = {"autoscaling"},
+ .type = GF_OPTION_TYPE_BOOL
},
- {.key = {"idle-time"},
- .type = GF_OPTION_TYPE_INT,
- .min = 1,
- .max = 0x7fffffff,
- .default_value = "120",
+ { .key = {"min-threads"},
+ .type = GF_OPTION_TYPE_INT,
+ .min = IOT_MIN_THREADS,
+ .max = IOT_MAX_THREADS,
+ .description = "Minimum number of threads must be greater than or "
+ "equal to 2. If the specified value is less than 2 "
+ "it is adjusted upwards to 2. This is a requirement"
+ " for the current model of threading in io-threads."
},
- {.key = {"least-rate-limit"},
- .type = GF_OPTION_TYPE_INT,
- .min = 0,
- .max = INT_MAX,
- .default_value = "0",
- .description = "Max number of least priority operations to handle "
- "per-second"
- },
- { .key = {NULL},
+ { .key = {"max-threads"},
+ .type = GF_OPTION_TYPE_INT,
+ .min = IOT_MIN_THREADS,
+ .max = IOT_MAX_THREADS,
+ .description = "Maximum number of threads is advisory only so the "
+ "user specified value will be used."
},
+ { .key = {NULL} },
};
diff --git a/xlators/performance/io-threads/src/io-threads.h b/xlators/performance/io-threads/src/io-threads.h
index 1a9dee9ae2c..3843791ed8e 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-2009 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 General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that 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 __IOT_H
@@ -26,67 +35,149 @@
#include "list.h"
#include <stdlib.h>
#include "locking.h"
-#include "iot-mem-types.h"
+#include "compat.h"
+#ifndef GF_SOLARIS_HOST_OS
#include <semaphore.h>
-#include "statedump.h"
+#endif
+#define min(a,b) ((a)<(b)?(a):(b))
+#define max(a,b) ((a)>(b)?(a):(b))
struct iot_conf;
+struct iot_worker;
+struct iot_request;
+
+struct iot_request {
+ struct list_head list; /* Attaches this request to the list of
+ requests.
+ */
+ call_stub_t *stub;
+};
+
+typedef enum {
+ IOT_STATE_ACTIVE,
+ IOT_STATE_EXIT_REQUEST,
+ IOT_STATE_DEAD
+}iot_state_t;
+#define iot_worker_active(wrk) ((wrk)->state == IOT_STATE_ACTIVE)
#define MAX_IDLE_SKEW 4 /* In secs */
#define skew_sec_idle_time(sec) ((sec) + (random () % MAX_IDLE_SKEW))
-#define IOT_DEFAULT_IDLE 120 /* In secs. */
+#define IOT_DEFAULT_IDLE 180 /* In secs. */
-#define IOT_MIN_THREADS 1
+#define IOT_MIN_THREADS 2
#define IOT_DEFAULT_THREADS 16
#define IOT_MAX_THREADS 64
+#define IOT_SCALING_OFF _gf_false
+#define IOT_SCALING_ON _gf_true
+#define iot_ordered_scaling_on(conf) ((conf)->o_scaling == IOT_SCALING_ON)
+#define iot_unordered_scaling_on(conf) ((conf)->u_scaling == IOT_SCALING_ON)
#define IOT_THREAD_STACK_SIZE ((size_t)(1024*1024))
-
-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;
-
-#define IOT_LEAST_THROTTLE_DELAY 1 /* sample interval in seconds */
-struct iot_least_throttle {
- struct timeval sample_time; /* timestamp of current sample */
- uint32_t sample_cnt; /* sample count for active interval */
- uint32_t cached_rate; /* the most recently measured rate */
- int32_t rate_limit; /* user-specified rate limit */
- pthread_mutex_t lock;
+/* This signifies the max number of outstanding request we're expecting
+ * at a point for every worker thread.
+ * For an idea of the memory foot-print, consider at most 16 Bytes per
+ * iot_request_t on a 64-bit system with another 16 bytes per chunk in the
+ * header. For 64 slots in the pool, we'll use up 2 KiB, with 64 threads this
+ * goes up to 128 KiB.
+ *
+ * Note that this size defines the size of the per-worker mem pool. The
+ * advantage is that, we're not only reducing the rate of small iot_request_t
+ * allocations from the heap but also reducing the contention on the libc heap
+ * by having a mem pool, though small, for each worker.
+ */
+#define IOT_REQUEST_MEMPOOL_SIZE 64
+
+struct iot_worker {
+ struct list_head rqlist; /* List of requests assigned to me. */
+ struct iot_conf *conf;
+#ifndef HAVE_SPINLOCK
+ pthread_cond_t notifier;
+#else
+ sem_t notifier;
+#endif
+ int64_t q,dq;
+ gf_lock_t qlock;
+ int32_t queue_size;
+ pthread_t thread;
+ iot_state_t state; /* What state is the thread in. */
+ int thread_idx; /* Thread's index into the worker
+ array. Since this will be thread
+ local data, for ensuring that
+ number of threads dont fall below
+ a minimum, we just dont allow
+ threads with specific indices to
+ exit. Helps us in eliminating one
+ place where otherwise a lock
+ would have been required to update
+ centralized state inside conf.
+ */
+ struct mem_pool *req_pool; /* iot_request_t's come from here. */
};
struct iot_conf {
- pthread_mutex_t mutex;
- pthread_cond_t cond;
-
- int32_t max_count; /* configured maximum */
- int32_t curr_count; /* actual number of threads running */
- int32_t sleep_count;
-
- int32_t idle_time; /* in seconds */
-
- 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 */
+ int32_t thread_count;
+ struct iot_worker **workers;
xlator_t *this;
- size_t stack_size;
-
- struct iot_least_throttle throttle;
+ /* Config state for ordered threads. */
+ pthread_mutex_t otlock; /* Used to sync any state that needs
+ to be changed by the ordered
+ threads.
+ */
+
+ int max_o_threads; /* Max. number of ordered threads */
+ int min_o_threads; /* Min. number of ordered threads.
+ Ordered thread count never falls
+ below this threshold.
+ */
+
+ int o_idle_time; /* in Secs. The idle time after
+ which an ordered thread exits.
+ */
+ gf_boolean_t o_scaling; /* Set to IOT_SCALING_OFF if user
+ does not want thread scaling on
+ ordered threads. If scaling is
+ off, io-threads maintains at
+ least min_o_threads number of
+ threads and never lets any thread
+ exit.
+ */
+ struct iot_worker **oworkers; /* Ordered thread pool. */
+
+
+ /* Config state for unordered threads */
+ pthread_mutex_t utlock; /* Used for scaling un-ordered
+ threads. */
+ struct iot_worker **uworkers; /* Un-ordered thread pool. */
+ int max_u_threads; /* Number of unordered threads will
+ not be higher than this. */
+ int min_u_threads; /* Number of unordered threads
+ should not fall below this value.
+ */
+ int u_idle_time; /* If an unordered thread does not
+ get a request for this amount of
+ secs, it should try to die.
+ */
+ gf_boolean_t u_scaling; /* Set to IOT_SCALING_OFF if user
+ does not want thread scaling on
+ unordered threads. If scaling is
+ off, io-threads maintains at
+ least min_u_threads number of
+ threads and never lets any thread
+ exit.
+ */
+
+ pthread_attr_t w_attr; /* Used to reduce the stack size of
+ the pthread worker down from the
+ default of 8MiB.
+ */
};
typedef struct iot_conf iot_conf_t;
+typedef struct iot_worker iot_worker_t;
+typedef struct iot_request iot_request_t;
#endif /* __IOT_H */
diff --git a/xlators/performance/io-threads/src/iot-mem-types.h b/xlators/performance/io-threads/src/iot-mem-types.h
deleted file mode 100644
index 4fa8302d1f4..00000000000
--- a/xlators/performance/io-threads/src/iot-mem-types.h
+++ /dev/null
@@ -1,22 +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 __IOT_MEM_TYPES_H__
-#define __IOT_MEM_TYPES_H__
-
-#include "mem-types.h"
-
-enum gf_iot_mem_types_ {
- gf_iot_mt_iot_conf_t = gf_common_mt_end + 1,
- gf_iot_mt_end
-};
-#endif
-
diff --git a/xlators/performance/md-cache/Makefile.am b/xlators/performance/md-cache/Makefile.am
deleted file mode 100644
index af437a64d6d..00000000000
--- a/xlators/performance/md-cache/Makefile.am
+++ /dev/null
@@ -1 +0,0 @@
-SUBDIRS = src
diff --git a/xlators/performance/md-cache/src/Makefile.am b/xlators/performance/md-cache/src/Makefile.am
deleted file mode 100644
index 8c9f5a8582f..00000000000
--- a/xlators/performance/md-cache/src/Makefile.am
+++ /dev/null
@@ -1,25 +0,0 @@
-xlator_LTLIBRARIES = md-cache.la
-xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/performance
-
-md_cache_la_LDFLAGS = -module -avoid-version
-
-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_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \
- -I$(CONTRIBDIR)/rbtree
-
-AM_CFLAGS = -Wall $(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 6634cf962a5..00000000000
--- 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 a4193545b8d..00000000000
--- a/xlators/performance/md-cache/src/md-cache.c
+++ /dev/null
@@ -1,2323 +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 "compat-errno.h"
-#include "glusterfs-acl.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;
- gf_boolean_t force_readdirp;
-};
-
-
-static struct mdc_key {
- const char *name;
- int load;
- int check;
-} mdc_keys[] = {
- {
- .name = POSIX_ACL_ACCESS_XATTR,
- .load = 0,
- .check = 1,
- },
- {
- .name = POSIX_ACL_DEFAULT_XATTR,
- .load = 0,
- .check = 1,
- },
- {
- .name = GF_SELINUX_XATTR_KEY,
- .load = 0,
- .check = 1,
- },
- {
- .name = "security.capability",
- .load = 0,
- .check = 1,
- },
- {
- .name = "gfid-req",
- .load = 0,
- .check = 1,
- },
- {
- .name = NULL,
- .load = 0,
- .check = 0,
- }
-};
-
-
-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;
- char *key;
- 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_set (inode, this, &mdc_int);
-
- 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);
-
- GF_FREE (local->key);
-
- 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 int
-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 -1;
- }
- }
-
- /* posix xlator as part of listxattr will send both names
- * and values of the xattrs in the dict. But as per man page
- * listxattr is mainly supposed to send names of the all the
- * xattrs. gfapi, as of now will put all the keys it obtained
- * in the dict (sent by posix) into a buffer provided by the
- * caller (thus the values of those xattrs are lost). If some
- * xlator makes gfapi based calls (ex: snapview-server), then
- * it has to unwind the calls by putting those names it got
- * in the buffer again into the dict. But now it would not be
- * having the values for those xattrs. So it might just put
- * a 0 byte value ("") into the dict for each xattr and unwind
- * the call. So the xlators which cache the xattrs (as of now
- * md-cache caches the acl and selinux related xattrs), should
- * not update their cache if the value of a xattr is a 0 byte
- * data (i.e. "").
- */
- if (!strcmp (value->data, ""))
- continue;
-
- if (dict_set(u->dict, key, value) < 0) {
- u->ret = -1;
- return -1;
- }
-
- break;
- }
- return 0;
-}
-
-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_unset (xlator_t *this, inode_t *inode, char *name)
-{
- int ret = -1;
- struct md_cache *mdc = NULL;
-
- mdc = mdc_inode_prep (this, inode);
- if (!mdc)
- goto out;
-
- if (!name || !mdc->xattr)
- goto out;
-
- LOCK (&mdc->lock);
- {
- dict_del (mdc->xattr, name);
- }
- 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);
- {
- ret = 0;
- /* Missing xattr only means no keys were there, i.e
- a negative cache for the "loaded" keys
- */
- if (!mdc->xattr)
- goto unlock;
-
- if (dict)
- *dict = dict_ref (mdc->xattr);
- }
-unlock:
- UNLOCK (&mdc->lock);
-
-out:
- return ret;
-}
-
-
-int
-mdc_inode_iatt_invalidate (xlator_t *this, inode_t *inode)
-{
- int ret = -1;
- struct md_cache *mdc = NULL;
-
- if (mdc_inode_ctx_get (this, inode, &mdc) != 0)
- goto out;
-
- LOCK (&mdc->lock);
- {
- mdc->ia_time = 0;
- }
- UNLOCK (&mdc->lock);
-
-out:
- return ret;
-}
-
-
-int
-mdc_inode_xatt_invalidate (xlator_t *this, inode_t *inode)
-{
- int ret = -1;
- struct md_cache *mdc = NULL;
-
- if (mdc_inode_ctx_get (this, inode, &mdc) != 0)
- goto out;
-
- LOCK (&mdc->lock);
- {
- mdc->xa_time = 0;
- }
- 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].load)
- continue;
- if (strcmp (mdc_key, key) == 0)
- return 1;
- }
-
- return 0;
-}
-
-
-static int
-checkfn (dict_t *this, char *key, data_t *value, void *data)
-{
- struct checkpair *pair = data;
-
- if (!is_mdc_key_satisfied (key))
- pair->ret = 0;
-
- return 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;
- dict_t *xattr_alloc = NULL;
- mdc_local_t *local = NULL;
-
-
- local = mdc_local_get (frame);
- if (!local)
- goto uncached;
-
- loc_copy (&local->loc, loc);
-
- if (!loc->name)
- /* A nameless discovery is dangerous to serve from cache. We
- perform nameless lookup with the intention of
- re-establishing an inode "properly"
- */
- goto uncached;
-
- 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)
- xdata = xattr_alloc = dict_new ();
- 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);
- if (xattr_alloc)
- dict_unref (xattr_alloc);
- 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);
-
- mdc_inode_iatt_invalidate (this, local->loc.inode);
-
-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);
-
- mdc_inode_iatt_invalidate (this, local->fd->inode);
-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;
- int op_errno = ENODATA;
- 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 (!xattr || !dict_get (xattr, (char *)key)) {
- ret = -1;
- op_errno = ENODATA;
- }
-
- MDC_STACK_UNWIND (getxattr, frame, ret, op_errno, 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;
- int op_errno = ENODATA;
-
- 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 (!xattr || !dict_get (xattr, (char *)key)) {
- ret = -1;
- op_errno = ENODATA;
- }
-
- MDC_STACK_UNWIND (fgetxattr, frame, ret, op_errno, 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_removexattr_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;
-
- if (local->key)
- mdc_inode_xatt_unset (this, local->loc.inode, local->key);
- else
- mdc_inode_xatt_invalidate (this, local->loc.inode);
-
- mdc_inode_iatt_invalidate (this, local->loc.inode);
-out:
- MDC_STACK_UNWIND (removexattr, frame, op_ret, op_errno, xdata);
-
- return 0;
-}
-
-
-int
-mdc_removexattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
- const char *name, dict_t *xdata)
-{
- mdc_local_t *local = NULL;
-
- local = mdc_local_get (frame);
-
- loc_copy (&local->loc, loc);
-
- local->key = gf_strdup (name);
-
- STACK_WIND (frame, mdc_removexattr_cbk,
- FIRST_CHILD(this), FIRST_CHILD(this)->fops->removexattr,
- loc, name, xdata);
- return 0;
-}
-
-
-int
-mdc_fremovexattr_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;
-
- if (local->key)
- mdc_inode_xatt_unset (this, local->fd->inode, local->key);
- else
- mdc_inode_xatt_invalidate (this, local->fd->inode);
-
- mdc_inode_iatt_invalidate (this, local->fd->inode);
-out:
- MDC_STACK_UNWIND (fremovexattr, frame, op_ret, op_errno, xdata);
-
- return 0;
-}
-
-
-int
-mdc_fremovexattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
- const char *name, dict_t *xdata)
-{
- mdc_local_t *local = NULL;
-
- local = mdc_local_get (frame);
-
- local->fd = fd_ref (fd);
-
- local->key = gf_strdup (name);
-
- STACK_WIND (frame, mdc_fremovexattr_cbk,
- FIRST_CHILD(this), FIRST_CHILD(this)->fops->fremovexattr,
- fd, name, 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)
-{
- dict_t *xattr_alloc = NULL;
-
- if (!xdata)
- xdata = xattr_alloc = dict_new ();
- 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 (xattr_alloc)
- dict_unref (xattr_alloc);
- return 0;
-}
-
-int
-mdc_readdir_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret,
- int op_errno, gf_dirent_t *entries, dict_t *xdata)
-{
- STACK_UNWIND_STRICT (readdir, frame, op_ret, op_errno, entries, 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;
- struct mdc_conf *conf = this->private;
-
- if (!conf->force_readdirp) {
- STACK_WIND(frame, mdc_readdir_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->readdir, fd, size, offset,
- xdata);
- return 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_fallocate_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 (fallocate, frame, op_ret, op_errno, prebuf, postbuf,
- xdata);
-
- return 0;
-}
-
-int mdc_fallocate(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t mode,
- off_t offset, size_t len, dict_t *xdata)
-{
- mdc_local_t *local;
-
- local = mdc_local_get(frame);
- local->fd = fd_ref(fd);
-
- STACK_WIND(frame, mdc_fallocate_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fallocate, fd, mode, offset, len,
- xdata);
-
- return 0;
-}
-
-int
-mdc_discard_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(discard, frame, op_ret, op_errno, prebuf, postbuf,
- xdata);
-
- return 0;
-}
-
-int mdc_discard(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
- size_t len, dict_t *xdata)
-{
- mdc_local_t *local;
-
- local = mdc_local_get(frame);
- local->fd = fd_ref(fd);
-
- STACK_WIND(frame, mdc_discard_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->discard, fd, offset, len,
- xdata);
-
- return 0;
-}
-
-int
-mdc_zerofill_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(zerofill, frame, op_ret, op_errno, prebuf, postbuf,
- xdata);
-
- return 0;
-}
-
-int mdc_zerofill(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
- off_t len, dict_t *xdata)
-{
- mdc_local_t *local;
-
- local = mdc_local_get(frame);
- local->fd = fd_ref(fd);
-
- STACK_WIND(frame, mdc_zerofill_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->zerofill, fd, offset, len,
- 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);
-
- GF_OPTION_RECONF("force-readdirp", conf->force_readdirp, options, bool, out);
-
-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);
-
- GF_OPTION_INIT("force-readdirp", conf->force_readdirp, bool, out);
-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,
- .removexattr = mdc_removexattr,
- .fremovexattr= mdc_fremovexattr,
- .readdirp = mdc_readdirp,
- .readdir = mdc_readdir,
- .fallocate = mdc_fallocate,
- .discard = mdc_discard,
- .zerofill = mdc_zerofill,
-};
-
-
-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",
- },
- { .key = {"force-readdirp"},
- .type = GF_OPTION_TYPE_BOOL,
- .default_value = "true",
- .description = "Convert all readdir requests to readdirplus to "
- "collect stat info on each entry.",
- },
- { .key = {NULL} },
-};
diff --git a/xlators/performance/open-behind/Makefile.am b/xlators/performance/open-behind/Makefile.am
deleted file mode 100644
index af437a64d6d..00000000000
--- a/xlators/performance/open-behind/Makefile.am
+++ /dev/null
@@ -1 +0,0 @@
-SUBDIRS = src
diff --git a/xlators/performance/open-behind/src/Makefile.am b/xlators/performance/open-behind/src/Makefile.am
deleted file mode 100644
index 12528570783..00000000000
--- a/xlators/performance/open-behind/src/Makefile.am
+++ /dev/null
@@ -1,15 +0,0 @@
-xlator_LTLIBRARIES = open-behind.la
-xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/performance
-
-open_behind_la_LDFLAGS = -module -avoid-version
-
-open_behind_la_SOURCES = open-behind.c
-open_behind_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la
-
-noinst_HEADERS = open-behind-mem-types.h
-
-AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src
-
-AM_CFLAGS = -Wall $(GF_CFLAGS)
-
-CLEANFILES =
diff --git a/xlators/performance/open-behind/src/open-behind-mem-types.h b/xlators/performance/open-behind/src/open-behind-mem-types.h
deleted file mode 100644
index 1e94296f424..00000000000
--- a/xlators/performance/open-behind/src/open-behind-mem-types.h
+++ /dev/null
@@ -1,21 +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 __OB_MEM_TYPES_H__
-#define __OB_MEM_TYPES_H__
-
-#include "mem-types.h"
-
-enum gf_ob_mem_types_ {
- gf_ob_mt_fd_t = gf_common_mt_end + 1,
- gf_ob_mt_conf_t,
- gf_ob_mt_end
-};
-#endif
diff --git a/xlators/performance/open-behind/src/open-behind.c b/xlators/performance/open-behind/src/open-behind.c
deleted file mode 100644
index 742e4df3fdf..00000000000
--- a/xlators/performance/open-behind/src/open-behind.c
+++ /dev/null
@@ -1,1020 +0,0 @@
-/*
- Copyright (c) 2013 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 "open-behind-mem-types.h"
-#include "xlator.h"
-#include "statedump.h"
-#include "call-stub.h"
-#include "defaults.h"
-
-typedef struct ob_conf {
- gf_boolean_t use_anonymous_fd; /* use anonymous FDs wherever safe
- e.g - fstat() readv()
-
- whereas for fops like writev(), lk(),
- the fd is important for side effects
- like mandatory locks
- */
- gf_boolean_t lazy_open; /* delay backend open as much as possible */
- gf_boolean_t read_after_open; /* instead of sending readvs on
- anonymous fds, open the file
- first and then send readv i.e
- similar to what writev does
- */
-} ob_conf_t;
-
-
-typedef struct ob_fd {
- call_frame_t *open_frame;
- loc_t loc;
- dict_t *xdata;
- int flags;
- int op_errno;
- struct list_head list;
-} ob_fd_t;
-
-
-ob_fd_t *
-__ob_fd_ctx_get (xlator_t *this, fd_t *fd)
-{
- uint64_t value = 0;
- int ret = -1;
- ob_fd_t *ob_fd = NULL;
-
- ret = __fd_ctx_get (fd, this, &value);
- if (ret)
- return NULL;
-
- ob_fd = (void *) ((long) value);
-
- return ob_fd;
-}
-
-
-ob_fd_t *
-ob_fd_ctx_get (xlator_t *this, fd_t *fd)
-{
- ob_fd_t *ob_fd = NULL;
-
- LOCK (&fd->lock);
- {
- ob_fd = __ob_fd_ctx_get (this, fd);
- }
- UNLOCK (&fd->lock);
-
- return ob_fd;
-}
-
-
-int
-__ob_fd_ctx_set (xlator_t *this, fd_t *fd, ob_fd_t *ob_fd)
-{
- uint64_t value = 0;
- int ret = -1;
-
- value = (long) ((void *) ob_fd);
-
- ret = __fd_ctx_set (fd, this, value);
-
- return ret;
-}
-
-
-int
-ob_fd_ctx_set (xlator_t *this, fd_t *fd, ob_fd_t *ob_fd)
-{
- int ret = -1;
-
- LOCK (&fd->lock);
- {
- ret = __ob_fd_ctx_set (this, fd, ob_fd);
- }
- UNLOCK (&fd->lock);
-
- return ret;
-}
-
-
-ob_fd_t *
-ob_fd_new (void)
-{
- ob_fd_t *ob_fd = NULL;
-
- ob_fd = GF_CALLOC (1, sizeof (*ob_fd), gf_ob_mt_fd_t);
-
- INIT_LIST_HEAD (&ob_fd->list);
-
- return ob_fd;
-}
-
-
-void
-ob_fd_free (ob_fd_t *ob_fd)
-{
- loc_wipe (&ob_fd->loc);
-
- if (ob_fd->xdata)
- dict_unref (ob_fd->xdata);
-
- if (ob_fd->open_frame)
- STACK_DESTROY (ob_fd->open_frame->root);
-
- GF_FREE (ob_fd);
-}
-
-
-int
-ob_wake_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int op_ret, int op_errno, fd_t *fd_ret, dict_t *xdata)
-{
- fd_t *fd = NULL;
- struct list_head list;
- ob_fd_t *ob_fd = NULL;
- call_stub_t *stub = NULL, *tmp = NULL;
-
- fd = frame->local;
- frame->local = NULL;
-
- INIT_LIST_HEAD (&list);
-
- LOCK (&fd->lock);
- {
- ob_fd = __ob_fd_ctx_get (this, fd);
-
- list_splice_init (&ob_fd->list, &list);
-
- if (op_ret < 0) {
- /* mark fd BAD for ever */
- ob_fd->op_errno = op_errno;
- } else {
- __fd_ctx_del (fd, this, NULL);
- ob_fd_free (ob_fd);
- }
- }
- UNLOCK (&fd->lock);
-
- list_for_each_entry_safe (stub, tmp, &list, list) {
- list_del_init (&stub->list);
-
- if (op_ret < 0)
- call_unwind_error (stub, -1, op_errno);
- else
- call_resume (stub);
- }
-
- fd_unref (fd);
-
- STACK_DESTROY (frame->root);
-
- return 0;
-}
-
-
-int
-ob_fd_wake (xlator_t *this, fd_t *fd)
-{
- call_frame_t *frame = NULL;
- ob_fd_t *ob_fd = NULL;
-
- LOCK (&fd->lock);
- {
- ob_fd = __ob_fd_ctx_get (this, fd);
- if (!ob_fd)
- goto unlock;
-
- frame = ob_fd->open_frame;
- ob_fd->open_frame = NULL;
- }
-unlock:
- UNLOCK (&fd->lock);
-
- if (frame) {
- frame->local = fd_ref (fd);
-
- STACK_WIND (frame, ob_wake_cbk, FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->open,
- &ob_fd->loc, ob_fd->flags, fd, ob_fd->xdata);
- }
-
- return 0;
-}
-
-
-int
-open_and_resume (xlator_t *this, fd_t *fd, call_stub_t *stub)
-{
- ob_fd_t *ob_fd = NULL;
- int op_errno = 0;
-
- if (!fd)
- goto nofd;
-
- LOCK (&fd->lock);
- {
- ob_fd = __ob_fd_ctx_get (this, fd);
- if (!ob_fd)
- goto unlock;
-
- if (ob_fd->op_errno) {
- op_errno = ob_fd->op_errno;
- goto unlock;
- }
-
- list_add_tail (&stub->list, &ob_fd->list);
- }
-unlock:
- UNLOCK (&fd->lock);
-
-nofd:
- if (op_errno)
- call_unwind_error (stub, -1, op_errno);
- else if (ob_fd)
- ob_fd_wake (this, fd);
- else
- call_resume (stub);
-
- return 0;
-}
-
-
-int
-ob_open_behind (call_frame_t *frame, xlator_t *this, loc_t *loc, int flags,
- fd_t *fd, dict_t *xdata)
-{
- ob_fd_t *ob_fd = NULL;
- int ret = -1;
- ob_conf_t *conf = NULL;
-
-
- conf = this->private;
-
- if (flags & O_TRUNC) {
- STACK_WIND (frame, default_open_cbk,
- FIRST_CHILD (this), FIRST_CHILD (this)->fops->open,
- loc, flags, fd, xdata);
- return 0;
- }
-
- ob_fd = ob_fd_new ();
- if (!ob_fd)
- goto enomem;
-
- ob_fd->open_frame = copy_frame (frame);
- if (!ob_fd->open_frame)
- goto enomem;
- ret = loc_copy (&ob_fd->loc, loc);
- if (ret)
- goto enomem;
-
- ob_fd->flags = flags;
- if (xdata)
- ob_fd->xdata = dict_ref (xdata);
-
- ret = ob_fd_ctx_set (this, fd, ob_fd);
- if (ret)
- goto enomem;
-
- fd_ref (fd);
-
- STACK_UNWIND_STRICT (open, frame, 0, 0, fd, xdata);
-
- if (!conf->lazy_open)
- ob_fd_wake (this, fd);
-
- fd_unref (fd);
-
- return 0;
-enomem:
- if (ob_fd) {
- if (ob_fd->open_frame)
- STACK_DESTROY (ob_fd->open_frame->root);
- loc_wipe (&ob_fd->loc);
- if (ob_fd->xdata)
- dict_unref (ob_fd->xdata);
- GF_FREE (ob_fd);
- }
-
- return -1;
-}
-
-
-int
-ob_open (call_frame_t *frame, xlator_t *this, loc_t *loc, int flags,
- fd_t *fd, dict_t *xdata)
-{
- fd_t *old_fd = NULL;
- int ret = -1;
- int op_errno = 0;
- call_stub_t *stub = NULL;
-
- old_fd = fd_lookup (fd->inode, 0);
- if (old_fd) {
- /* open-behind only when this is the first FD */
- stub = fop_open_stub (frame, default_open_resume,
- loc, flags, fd, xdata);
- if (!stub) {
- op_errno = ENOMEM;
- fd_unref (old_fd);
- goto err;
- }
-
- open_and_resume (this, old_fd, stub);
-
- fd_unref (old_fd);
-
- return 0;
- }
-
- ret = ob_open_behind (frame, this, loc, flags, fd, xdata);
- if (ret) {
- op_errno = ENOMEM;
- goto err;
- }
-
- return 0;
-err:
- gf_log (this->name, GF_LOG_ERROR, "%s: %s", loc->path,
- strerror (op_errno));
-
- STACK_UNWIND_STRICT (open, frame, -1, op_errno, 0, 0);
-
- return 0;
-}
-
-
-fd_t *
-ob_get_wind_fd (xlator_t *this, fd_t *fd)
-{
- ob_conf_t *conf = NULL;
- ob_fd_t *ob_fd = NULL;
-
- conf = this->private;
-
- ob_fd = ob_fd_ctx_get (this, fd);
-
- if (ob_fd && conf->use_anonymous_fd)
- return fd_anonymous (fd->inode);
-
- return fd_ref (fd);
-}
-
-
-int
-ob_readv (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
- off_t offset, uint32_t flags, dict_t *xdata)
-{
- call_stub_t *stub = NULL;
- fd_t *wind_fd = NULL;
- ob_conf_t *conf = NULL;
-
- conf = this->private;
-
- if (!conf->read_after_open)
- wind_fd = ob_get_wind_fd (this, fd);
- else
- wind_fd = fd_ref (fd);
-
- stub = fop_readv_stub (frame, default_readv_resume, wind_fd,
- size, offset, flags, xdata);
- fd_unref (wind_fd);
-
- if (!stub)
- goto err;
-
- open_and_resume (this, wind_fd, stub);
-
- return 0;
-err:
- STACK_UNWIND_STRICT (readv, frame, -1, ENOMEM, 0, 0, 0, 0, 0);
-
- return 0;
-}
-
-
-int
-ob_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)
-{
- call_stub_t *stub = NULL;
-
- stub = fop_writev_stub (frame, default_writev_resume, fd, iov, count,
- offset, flags, iobref, xdata);
- if (!stub)
- goto err;
-
- open_and_resume (this, fd, stub);
-
- return 0;
-err:
- STACK_UNWIND_STRICT (writev, frame, -1, ENOMEM, 0, 0, 0);
-
- return 0;
-}
-
-
-int
-ob_fstat (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
-{
- call_stub_t *stub = NULL;
- fd_t *wind_fd = NULL;
-
- wind_fd = ob_get_wind_fd (this, fd);
-
- stub = fop_fstat_stub (frame, default_fstat_resume, wind_fd, xdata);
-
- fd_unref (wind_fd);
-
- if (!stub)
- goto err;
-
- open_and_resume (this, wind_fd, stub);
-
- return 0;
-err:
- STACK_UNWIND_STRICT (fstat, frame, -1, ENOMEM, 0, 0);
-
- return 0;
-}
-
-
-int
-ob_flush (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
-{
- call_stub_t *stub = NULL;
- ob_fd_t *ob_fd = NULL;
- gf_boolean_t unwind = _gf_false;
-
- LOCK (&fd->lock);
- {
- ob_fd = __ob_fd_ctx_get (this, fd);
- if (ob_fd && ob_fd->open_frame)
- /* if open() was never wound to backend,
- no need to wind flush() either.
- */
- unwind = _gf_true;
- }
- UNLOCK (&fd->lock);
-
- if (unwind)
- goto unwind;
-
- stub = fop_flush_stub (frame, default_flush_resume, fd, xdata);
- if (!stub)
- goto err;
-
- open_and_resume (this, fd, stub);
-
- return 0;
-err:
- STACK_UNWIND_STRICT (flush, frame, -1, ENOMEM, 0);
-
- return 0;
-
-unwind:
- STACK_UNWIND_STRICT (flush, frame, 0, 0, 0);
-
- return 0;
-}
-
-
-int
-ob_fsync (call_frame_t *frame, xlator_t *this, fd_t *fd, int flag,
- dict_t *xdata)
-{
- call_stub_t *stub = NULL;
-
- stub = fop_fsync_stub (frame, default_fsync_resume, fd, flag, xdata);
- if (!stub)
- goto err;
-
- open_and_resume (this, fd, stub);
-
- return 0;
-err:
- STACK_UNWIND_STRICT (fsync, frame, -1, ENOMEM, 0, 0, 0);
-
- return 0;
-}
-
-
-int
-ob_lk (call_frame_t *frame, xlator_t *this, fd_t *fd, int cmd,
- struct gf_flock *flock, dict_t *xdata)
-{
- call_stub_t *stub = NULL;
-
- stub = fop_lk_stub (frame, default_lk_resume, fd, cmd, flock, xdata);
- if (!stub)
- goto err;
-
- open_and_resume (this, fd, stub);
-
- return 0;
-err:
- STACK_UNWIND_STRICT (lk, frame, -1, ENOMEM, 0, 0);
-
- return 0;
-}
-
-int
-ob_ftruncate (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
- dict_t *xdata)
-{
- call_stub_t *stub = NULL;
-
- stub = fop_ftruncate_stub (frame, default_ftruncate_resume, fd, offset,
- xdata);
- if (!stub)
- goto err;
-
- open_and_resume (this, fd, stub);
-
- return 0;
-err:
- STACK_UNWIND_STRICT (ftruncate, frame, -1, ENOMEM, 0, 0, 0);
-
- return 0;
-}
-
-
-int
-ob_fsetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xattr,
- int flags, dict_t *xdata)
-{
- call_stub_t *stub = NULL;
-
- stub = fop_fsetxattr_stub (frame, default_fsetxattr_resume, fd, xattr,
- flags, xdata);
- if (!stub)
- goto err;
-
- open_and_resume (this, fd, stub);
-
- return 0;
-err:
- STACK_UNWIND_STRICT (fsetxattr, frame, -1, ENOMEM, 0);
-
- return 0;
-}
-
-
-int
-ob_fgetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd, const char *name,
- dict_t *xdata)
-{
- call_stub_t *stub = NULL;
-
- stub = fop_fgetxattr_stub (frame, default_fgetxattr_resume, fd, name,
- xdata);
- if (!stub)
- goto err;
-
- open_and_resume (this, fd, stub);
-
- return 0;
-err:
- STACK_UNWIND_STRICT (fgetxattr, frame, -1, ENOMEM, 0, 0);
-
- return 0;
-}
-
-
-int
-ob_fremovexattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
- const char *name, dict_t *xdata)
-{
- call_stub_t *stub = NULL;
-
- stub = fop_fremovexattr_stub (frame, default_fremovexattr_resume, fd,
- name, xdata);
- if (!stub)
- goto err;
-
- open_and_resume (this, fd, stub);
-
- return 0;
-err:
- STACK_UNWIND_STRICT (fremovexattr, frame, -1, ENOMEM, 0);
-
- return 0;
-}
-
-
-int
-ob_finodelk (call_frame_t *frame, xlator_t *this, const char *volume, fd_t *fd,
- int cmd, struct gf_flock *flock, dict_t *xdata)
-{
- call_stub_t *stub = NULL;
-
- stub = fop_finodelk_stub (frame, default_finodelk_resume, volume, fd,
- cmd, flock, xdata);
- if (!stub)
- goto err;
-
- open_and_resume (this, fd, stub);
-
- return 0;
-err:
- STACK_UNWIND_STRICT (finodelk, frame, -1, ENOMEM, 0);
-
- return 0;
-}
-
-
-int
-ob_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;
-
- stub = fop_fentrylk_stub (frame, default_fentrylk_resume, volume, fd,
- basename, cmd, type, xdata);
- if (!stub)
- goto err;
-
- open_and_resume (this, fd, stub);
-
- return 0;
-err:
- STACK_UNWIND_STRICT (fentrylk, frame, -1, ENOMEM, 0);
-
- return 0;
-}
-
-
-int
-ob_fxattrop (call_frame_t *frame, xlator_t *this, fd_t *fd,
- gf_xattrop_flags_t optype, dict_t *xattr, dict_t *xdata)
-{
- call_stub_t *stub = NULL;
-
- stub = fop_fxattrop_stub (frame, default_fxattrop_resume, fd, optype,
- xattr, xdata);
- if (!stub)
- goto err;
-
- open_and_resume (this, fd, stub);
-
- return 0;
-err:
- STACK_UNWIND_STRICT (fxattrop, frame, -1, ENOMEM, 0, 0);
-
- return 0;
-}
-
-
-int
-ob_fsetattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
- struct iatt *iatt, int valid, dict_t *xdata)
-{
- call_stub_t *stub = NULL;
-
- stub = fop_fsetattr_stub (frame, default_fsetattr_resume, fd,
- iatt, valid, xdata);
- if (!stub)
- goto err;
-
- open_and_resume (this, fd, stub);
-
- return 0;
-err:
- STACK_UNWIND_STRICT (fsetattr, frame, -1, ENOMEM, 0, 0, 0);
-
- return 0;
-}
-
-int
-ob_fallocate(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t mode,
- off_t offset, size_t len, dict_t *xdata)
-{
- call_stub_t *stub;
-
- stub = fop_fallocate_stub(frame, default_fallocate_resume, fd, mode,
- offset, len, xdata);
- if (!stub)
- goto err;
-
- open_and_resume(this, fd, stub);
-
- return 0;
-err:
- STACK_UNWIND_STRICT(fallocate, frame, -1, ENOMEM, NULL, NULL, NULL);
- return 0;
-}
-
-int
-ob_discard(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
- size_t len, dict_t *xdata)
-{
- call_stub_t *stub;
-
- stub = fop_discard_stub(frame, default_discard_resume, fd, offset, len,
- xdata);
- if (!stub)
- goto err;
-
- open_and_resume(this, fd, stub);
-
- return 0;
-err:
- STACK_UNWIND_STRICT(discard, frame, -1, ENOMEM, NULL, NULL, NULL);
- return 0;
-}
-
-int
-ob_zerofill(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
- off_t len, dict_t *xdata)
-{
- call_stub_t *stub;
-
- stub = fop_zerofill_stub(frame, default_zerofill_resume, fd,
- offset, len, xdata);
- if (!stub)
- goto err;
-
- open_and_resume(this, fd, stub);
-
- return 0;
-err:
- STACK_UNWIND_STRICT(zerofill, frame, -1, ENOMEM, NULL, NULL, NULL);
- return 0;
-}
-
-
-int
-ob_unlink (call_frame_t *frame, xlator_t *this, loc_t *loc, int xflags,
- dict_t *xdata)
-{
- fd_t *fd = NULL;
- call_stub_t *stub = NULL;
-
- stub = fop_unlink_stub (frame, default_unlink_resume, loc,
- xflags, xdata);
- if (!stub)
- goto err;
-
- fd = fd_lookup (loc->inode, 0);
-
- open_and_resume (this, fd, stub);
- if (fd)
- fd_unref (fd);
-
- return 0;
-err:
- STACK_UNWIND_STRICT (unlink, frame, -1, ENOMEM, 0, 0, 0);
-
- return 0;
-}
-
-
-int
-ob_rename (call_frame_t *frame, xlator_t *this, loc_t *src, loc_t *dst,
- dict_t *xdata)
-{
- fd_t *fd = NULL;
- call_stub_t *stub = NULL;
-
- stub = fop_rename_stub (frame, default_rename_resume, src, dst, xdata);
- if (!stub)
- goto err;
-
- if (dst->inode)
- fd = fd_lookup (dst->inode, 0);
-
- open_and_resume (this, fd, stub);
- if (fd)
- fd_unref (fd);
-
- return 0;
-err:
- STACK_UNWIND_STRICT (rename, frame, -1, ENOMEM, 0, 0, 0, 0, 0, 0);
-
- return 0;
-}
-
-
-int
-ob_release (xlator_t *this, fd_t *fd)
-{
- ob_fd_t *ob_fd = NULL;
-
- ob_fd = ob_fd_ctx_get (this, fd);
-
- ob_fd_free (ob_fd);
-
- return 0;
-}
-
-
-int
-ob_priv_dump (xlator_t *this)
-{
- ob_conf_t *conf = NULL;
- char key_prefix[GF_DUMP_MAX_BUF_LEN];
-
- conf = this->private;
-
- if (!conf)
- return -1;
-
- gf_proc_dump_build_key (key_prefix, "xlator.performance.open-behind",
- "priv");
-
- gf_proc_dump_add_section (key_prefix);
-
- gf_proc_dump_write ("use_anonymous_fd", "%d", conf->use_anonymous_fd);
-
- gf_proc_dump_write ("lazy_open", "%d", conf->lazy_open);
-
- return 0;
-}
-
-
-int
-ob_fdctx_dump (xlator_t *this, fd_t *fd)
-{
- ob_fd_t *ob_fd = NULL;
- char key_prefix[GF_DUMP_MAX_BUF_LEN] = {0, };
- int ret = 0;
-
- ret = TRY_LOCK (&fd->lock);
- if (ret)
- return 0;
-
- ob_fd = __ob_fd_ctx_get (this, fd);
- if (!ob_fd) {
- UNLOCK (&fd->lock);
- return 0;
- }
-
- gf_proc_dump_build_key (key_prefix, "xlator.performance.open-behind",
- "file");
- gf_proc_dump_add_section (key_prefix);
-
- gf_proc_dump_write ("fd", "%p", fd);
-
- gf_proc_dump_write ("open_frame", "%p", ob_fd->open_frame);
-
- gf_proc_dump_write ("open_frame.root.unique", "%p",
- ob_fd->open_frame->root->unique);
-
- gf_proc_dump_write ("loc.path", "%s", ob_fd->loc.path);
-
- gf_proc_dump_write ("loc.ino", "%s", uuid_utoa (ob_fd->loc.gfid));
-
- gf_proc_dump_write ("flags", "%p", ob_fd->open_frame);
-
- UNLOCK (&fd->lock);
-
- return 0;
-}
-
-
-int
-mem_acct_init (xlator_t *this)
-{
- int ret = -1;
-
- ret = xlator_mem_acct_init (this, gf_ob_mt_end + 1);
-
- if (ret)
- gf_log (this->name, GF_LOG_ERROR, "Memory accounting failed");
-
- return ret;
-}
-
-
-int
-reconfigure (xlator_t *this, dict_t *options)
-{
- ob_conf_t *conf = NULL;
- int ret = -1;
-
- conf = this->private;
-
- GF_OPTION_RECONF ("use-anonymous-fd", conf->use_anonymous_fd, options,
- bool, out);
-
- GF_OPTION_RECONF ("lazy-open", conf->lazy_open, options, bool, out);
- GF_OPTION_RECONF ("read-after-open", conf->read_after_open, options,
- bool, out);
-
- ret = 0;
-out:
- return ret;
-}
-
-
-int
-init (xlator_t *this)
-{
- ob_conf_t *conf = NULL;
-
- if (!this->children || this->children->next) {
- gf_log (this->name, GF_LOG_ERROR,
- "FATAL: volume (%s) not configured with exactly one "
- "child", this->name);
- return -1;
- }
-
- if (!this->parents)
- gf_log (this->name, GF_LOG_WARNING,
- "dangling volume. check volfile ");
-
- conf = GF_CALLOC (1, sizeof (*conf), gf_ob_mt_conf_t);
- if (!conf)
- goto err;
-
- GF_OPTION_INIT ("use-anonymous-fd", conf->use_anonymous_fd, bool, err);
-
- GF_OPTION_INIT ("lazy-open", conf->lazy_open, bool, err);
- GF_OPTION_INIT ("read-after-open", conf->read_after_open, bool, err);
- this->private = conf;
-
- return 0;
-err:
- if (conf)
- GF_FREE (conf);
-
- return -1;
-}
-
-
-void
-fini (xlator_t *this)
-{
- ob_conf_t *conf = NULL;
-
- conf = this->private;
-
- GF_FREE (conf);
-
- return;
-}
-
-
-struct xlator_fops fops = {
- .open = ob_open,
- .readv = ob_readv,
- .writev = ob_writev,
- .flush = ob_flush,
- .fsync = ob_fsync,
- .fstat = ob_fstat,
- .ftruncate = ob_ftruncate,
- .fsetxattr = ob_fsetxattr,
- .fgetxattr = ob_fgetxattr,
- .fremovexattr = ob_fremovexattr,
- .finodelk = ob_finodelk,
- .fentrylk = ob_fentrylk,
- .fxattrop = ob_fxattrop,
- .fsetattr = ob_fsetattr,
- .fallocate = ob_fallocate,
- .discard = ob_discard,
- .zerofill = ob_zerofill,
- .unlink = ob_unlink,
- .rename = ob_rename,
- .lk = ob_lk,
-};
-
-struct xlator_cbks cbks = {
- .release = ob_release,
-};
-
-struct xlator_dumpops dumpops = {
- .priv = ob_priv_dump,
- .fdctx = ob_fdctx_dump,
-};
-
-
-struct volume_options options[] = {
- { .key = {"use-anonymous-fd"},
- .type = GF_OPTION_TYPE_BOOL,
- .default_value = "yes",
- .description = "For read operations, use anonymous FD when "
- "original FD is open-behind and not yet opened in the backend.",
- },
- { .key = {"lazy-open"},
- .type = GF_OPTION_TYPE_BOOL,
- .default_value = "yes",
- .description = "Perform open in the backend only when a necessary "
- "FOP arrives (e.g writev on the FD, unlink of the file). When option "
- "is disabled, perform backend open right after unwinding open().",
- },
- { .key = {"read-after-open"},
- .type = GF_OPTION_TYPE_BOOL,
- .default_value = "no",
- .description = "read is sent only after actual open happens and real "
- "fd is obtained, instead of doing on anonymous fd (similar to write)",
- },
- { .key = {NULL} }
-
-};
diff --git a/xlators/performance/quick-read/src/Makefile.am b/xlators/performance/quick-read/src/Makefile.am
index 4906f408abc..644f27e3f74 100644
--- a/xlators/performance/quick-read/src/Makefile.am
+++ b/xlators/performance/quick-read/src/Makefile.am
@@ -1,15 +1,14 @@
xlator_LTLIBRARIES = quick-read.la
xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/performance
-quick_read_la_LDFLAGS = -module -avoid-version
+quick_read_la_LDFLAGS = -module -avoidversion
quick_read_la_SOURCES = quick-read.c
quick_read_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la
-noinst_HEADERS = quick-read.h quick-read-mem-types.h
+noinst_HEADERS = quick-read.h
-AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src
-
-AM_CFLAGS = -Wall $(GF_CFLAGS)
+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/performance/quick-read/src/quick-read-mem-types.h b/xlators/performance/quick-read/src/quick-read-mem-types.h
deleted file mode 100644
index 78547f64116..00000000000
--- a/xlators/performance/quick-read/src/quick-read-mem-types.h
+++ /dev/null
@@ -1,27 +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 __QR_MEM_TYPES_H__
-#define __QR_MEM_TYPES_H__
-
-#include "mem-types.h"
-
-enum gf_qr_mem_types_ {
- gf_qr_mt_qr_inode_t = gf_common_mt_end + 1,
- gf_qr_mt_content_t,
- gf_qr_mt_qr_fd_ctx_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 b49cd2e9e49..5cdceb4aeb3 100644
--- a/xlators/performance/quick-read/src/quick-read.c
+++ b/xlators/performance/quick-read/src/quick-read.c
@@ -1,1026 +1,2557 @@
/*
- 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 General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that 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 "quick-read.h"
#include "statedump.h"
-qr_inode_t *qr_inode_ctx_get (xlator_t *this, inode_t *inode);
-void __qr_inode_prune (qr_inode_table_t *table, qr_inode_t *qr_inode);
+#define QR_DEFAULT_CACHE_SIZE 134217728 /* 128MB */
+
+int32_t
+qr_readv (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
+ off_t offset);
-int
-__qr_inode_ctx_set (xlator_t *this, inode_t *inode, qr_inode_t *qr_inode)
+void
+qr_local_free (qr_local_t *local)
{
- uint64_t value = 0;
- int ret = -1;
+ if (local == NULL) {
+ goto out;
+ }
- value = (long) qr_inode;
+ if (local->stub != NULL) {
+ call_stub_destroy (local->stub);
+ }
+
+ if (local->path != NULL) {
+ FREE (local->path);
+ }
- ret = __inode_ctx_set (inode, this, &value);
+ FREE (local);
- return ret;
+out:
+ return;
}
-qr_inode_t *
-__qr_inode_ctx_get (xlator_t *this, inode_t *inode)
+static void
+qr_loc_wipe (loc_t *loc)
{
- qr_inode_t *qr_inode = NULL;
- uint64_t value = 0;
- int ret = -1;
+ if (loc == NULL) {
+ goto out;
+ }
+
+ if (loc->path) {
+ FREE (loc->path);
+ loc->path = NULL;
+ }
- ret = __inode_ctx_get (inode, this, &value);
- if (ret)
- return NULL;
+ if (loc->inode) {
+ inode_unref (loc->inode);
+ loc->inode = NULL;
+ }
- qr_inode = (void *) ((long) value);
+ if (loc->parent) {
+ inode_unref (loc->parent);
+ loc->parent = NULL;
+ }
- return qr_inode;
+out:
+ return;
}
-qr_inode_t *
-qr_inode_ctx_get (xlator_t *this, inode_t *inode)
+static int32_t
+qr_loc_fill (loc_t *loc, inode_t *inode, char *path)
{
- qr_inode_t *qr_inode = NULL;
+ int32_t ret = -1;
+ char *parent = NULL;
- LOCK (&inode->lock);
- {
- qr_inode = __qr_inode_ctx_get (this, inode);
- }
- UNLOCK (&inode->lock);
+ if ((loc == NULL) || (inode == NULL) || (path == NULL)) {
+ ret = -1;
+ errno = EINVAL;
+ goto out;
+ }
+
+ loc->inode = inode_ref (inode);
+ loc->path = strdup (path);
+ loc->ino = inode->ino;
+
+ parent = 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;
+ goto out;
+ }
+
+ loc->name = strrchr (loc->path, '/');
+ ret = 0;
+out:
+ if (ret == -1) {
+ qr_loc_wipe (loc);
+
+ }
- return qr_inode;
+ if (parent) {
+ FREE (parent);
+ }
+
+ return ret;
}
-qr_inode_t *
-qr_inode_new (xlator_t *this, inode_t *inode)
+void
+qr_resume_pending_ops (qr_fd_ctx_t *qr_fd_ctx)
{
- qr_inode_t *qr_inode = NULL;
+ struct list_head waiting_ops;
+ call_stub_t *stub = NULL, *tmp = NULL;
+
+ if (qr_fd_ctx == NULL) {
+ goto out;
+ }
- qr_inode = GF_CALLOC (1, sizeof (*qr_inode), gf_qr_mt_qr_inode_t);
- if (!qr_inode)
- return NULL;
+ INIT_LIST_HEAD (&waiting_ops);
- INIT_LIST_HEAD (&qr_inode->lru);
+ LOCK (&qr_fd_ctx->lock);
+ {
+ list_splice_init (&qr_fd_ctx->waiting_ops,
+ &waiting_ops);
+ }
+ UNLOCK (&qr_fd_ctx->lock);
- qr_inode->priority = 0; /* initial priority */
+ if (!list_empty (&waiting_ops)) {
+ list_for_each_entry_safe (stub, tmp, &waiting_ops, list) {
+ list_del_init (&stub->list);
+ call_resume (stub);
+ }
+ }
- return qr_inode;
+out:
+ return;
}
-qr_inode_t *
-qr_inode_ctx_get_or_new (xlator_t *this, inode_t *inode)
+static void
+qr_fd_ctx_free (qr_fd_ctx_t *qr_fd_ctx)
{
- qr_inode_t *qr_inode = NULL;
- int ret = -1;
- qr_private_t *priv = NULL;
-
- priv = this->private;
-
- LOCK (&inode->lock);
- {
- qr_inode = __qr_inode_ctx_get (this, inode);
- if (qr_inode)
- goto unlock;
-
- qr_inode = qr_inode_new (this, inode);
- if (!qr_inode)
- goto unlock;
-
- ret = __qr_inode_ctx_set (this, inode, qr_inode);
- if (ret) {
- __qr_inode_prune (&priv->table, qr_inode);
- GF_FREE (qr_inode);
- qr_inode = NULL;
- }
- }
-unlock:
- UNLOCK (&inode->lock);
+ if (qr_fd_ctx == NULL) {
+ goto out;
+ }
+
+ assert (list_empty (&qr_fd_ctx->waiting_ops));
- return qr_inode;
+ FREE (qr_fd_ctx->path);
+ FREE (qr_fd_ctx);
+
+out:
+ return;
}
+static inline uint32_t
+is_match (const char *path, const char *pattern)
+{
+ int32_t ret = 0;
+
+ ret = fnmatch (pattern, path, FNM_NOESCAPE);
+
+ return (ret == 0);
+}
+
uint32_t
qr_get_priority (qr_conf_t *conf, const char *path)
{
- uint32_t priority = 0;
- struct qr_priority *curr = NULL;
-
+ uint32_t priority = 0;
+ struct qr_priority *curr = NULL;
+
list_for_each_entry (curr, &conf->priority_list, list) {
- if (fnmatch (curr->pattern, path, FNM_NOESCAPE) == 0)
+ if (is_match (path, curr->pattern))
priority = curr->priority;
}
- return priority;
+ return priority;
}
-void
-__qr_inode_register (qr_inode_table_t *table, qr_inode_t *qr_inode)
+/* To be called with this-priv->table.lock held */
+qr_inode_t *
+__qr_inode_alloc (xlator_t *this, char *path, inode_t *inode)
{
- if (!qr_inode->data)
- return;
+ qr_inode_t *qr_inode = NULL;
+ qr_private_t *priv = NULL;
+ int priority = 0;
+
+ priv = this->private;
+
+ qr_inode = CALLOC (1, sizeof (*qr_inode));
+ if (qr_inode == NULL) {
+ gf_log (this->name, GF_LOG_ERROR, "out of memory");
+ goto out;
+ }
- if (list_empty (&qr_inode->lru))
- /* first time addition of this qr_inode into table */
- table->cache_used += qr_inode->size;
- else
- list_del_init (&qr_inode->lru);
+ INIT_LIST_HEAD (&qr_inode->lru);
+
+ priority = qr_get_priority (&priv->conf, path);
+
+ list_add_tail (&qr_inode->lru, &priv->table.lru[priority]);
- list_add_tail (&qr_inode->lru, &table->lru[qr_inode->priority]);
+ qr_inode->inode = inode;
+ qr_inode->priority = priority;
+out:
+ return qr_inode;
}
+/* To be called with qr_inode->table->lock held */
void
-qr_inode_set_priority (xlator_t *this, inode_t *inode, const char *path)
+__qr_inode_free (qr_inode_t *qr_inode)
{
- uint32_t priority = 0;
- qr_inode_table_t *table = NULL;
- qr_inode_t *qr_inode = NULL;
- qr_private_t *priv = NULL;
- qr_conf_t *conf = NULL;
-
- qr_inode = qr_inode_ctx_get (this, inode);
- if (!qr_inode)
- return;
-
- priv = this->private;
- table = &priv->table;
- conf = &priv->conf;
+ if (qr_inode == NULL) {
+ goto out;
+ }
- if (path)
- priority = qr_get_priority (conf, path);
- else
- /* retain existing priority, just bump LRU */
- priority = qr_inode->priority;
+ if (qr_inode->xattr) {
+ dict_unref (qr_inode->xattr);
+ }
- LOCK (&table->lock);
- {
- qr_inode->priority = priority;
+ list_del (&qr_inode->lru);
- __qr_inode_register (table, qr_inode);
- }
- UNLOCK (&table->lock);
+ FREE (qr_inode);
+out:
+ return;
}
/* To be called with priv->table.lock held */
void
-__qr_inode_prune (qr_inode_table_t *table, qr_inode_t *qr_inode)
+__qr_cache_prune (xlator_t *this)
{
- GF_FREE (qr_inode->data);
- qr_inode->data = NULL;
+ qr_private_t *priv = NULL;
+ qr_conf_t *conf = NULL;
+ qr_inode_table_t *table = NULL;
+ qr_inode_t *curr = NULL, *next = NULL;
+ int32_t index = 0;
+ uint64_t size_to_prune = 0;
+ uint64_t size_pruned = 0;
- if (!list_empty (&qr_inode->lru)) {
- table->cache_used -= qr_inode->size;
- qr_inode->size = 0;
+ priv = this->private;
+ table = &priv->table;
+ conf = &priv->conf;
- list_del_init (&qr_inode->lru);
- }
+ size_to_prune = table->cache_used - conf->cache_size;
+
+ for (index=0; index < conf->max_pri; index++) {
+ list_for_each_entry_safe (curr, next, &table->lru[index], lru) {
+ size_pruned += curr->stbuf.st_size;
+ inode_ctx_del (curr->inode, this, NULL);
+ __qr_inode_free (curr);
+ if (size_pruned >= size_to_prune)
+ goto done;
+ }
+ }
- memset (&qr_inode->buf, 0, sizeof (qr_inode->buf));
+done:
+ table->cache_used -= size_pruned;
+ return;
}
-void
-qr_inode_prune (xlator_t *this, inode_t *inode)
+/* To be called with table->lock held */
+inline char
+__qr_need_cache_prune (qr_conf_t *conf, qr_inode_table_t *table)
{
- qr_private_t *priv = NULL;
- qr_inode_table_t *table = NULL;
- qr_inode_t *qr_inode = NULL;
+ return (table->cache_used > conf->cache_size);
+}
- qr_inode = qr_inode_ctx_get (this, inode);
- if (!qr_inode)
- return;
+
+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 stat *buf, dict_t *dict, struct stat *postparent)
+{
+ data_t *content = NULL;
+ qr_inode_t *qr_inode = NULL;
+ uint64_t value = 0;
+ int ret = -1;
+ qr_conf_t *conf = NULL;
+ qr_inode_table_t *table = NULL;
+ qr_private_t *priv = NULL;
+ qr_local_t *local = NULL;
+
+ if ((op_ret == -1) || (dict == NULL)) {
+ goto out;
+ }
- priv = this->private;
- table = &priv->table;
+ conf = this->private;
+ priv = this->private;
+ conf = &priv->conf;
+ table = &priv->table;
- LOCK (&table->lock);
- {
- __qr_inode_prune (table, qr_inode);
- }
- UNLOCK (&table->lock);
-}
+ local = frame->local;
+ if (buf->st_size > conf->max_file_size) {
+ goto out;
+ }
-/* To be called with priv->table.lock held */
-void
-__qr_cache_prune (qr_inode_table_t *table, qr_conf_t *conf)
-{
- qr_inode_t *curr = NULL;
- qr_inode_t *next = NULL;
- int index = 0;
- size_t size_pruned = 0;
+ if (S_ISDIR (buf->st_mode)) {
+ goto out;
+ }
- for (index = 0; index < conf->max_pri; index++) {
- list_for_each_entry_safe (curr, next, &table->lru[index], lru) {
+ if (inode == NULL) {
+ op_ret = -1;
+ op_errno = EINVAL;
+ goto out;
+ }
- size_pruned += curr->size;
+ content = dict_get (dict, GLUSTERFS_CONTENT_KEY);
+ if (content == NULL) {
+ goto out;
+ }
- __qr_inode_prune (table, curr);
+ LOCK (&table->lock);
+ {
+ ret = inode_ctx_get (inode, this, &value);
+ if (ret == -1) {
+ qr_inode = __qr_inode_alloc (this, local->path, inode);
+ if (qr_inode == NULL) {
+ op_ret = -1;
+ op_errno = ENOMEM;
+ goto unlock;
+ }
+
+ ret = inode_ctx_put (inode, this,
+ (uint64_t)(long)qr_inode);
+ if (ret == -1) {
+ __qr_inode_free (qr_inode);
+ qr_inode = NULL;
+ op_ret = -1;
+ op_errno = EINVAL;
+ goto unlock;
+ }
+ } else {
+ qr_inode = (qr_inode_t *)(long)value;
+ if (qr_inode == NULL) {
+ op_ret = -1;
+ op_errno = EINVAL;
+ goto unlock;
+ }
+ }
- if (table->cache_used < conf->cache_size)
- return;
+ if (qr_inode->xattr) {
+ dict_unref (qr_inode->xattr);
+ qr_inode->xattr = NULL;
+
+ table->cache_used -= qr_inode->stbuf.st_size;
+ }
+
+ qr_inode->xattr = dict_ref (dict);
+ qr_inode->stbuf = *buf;
+ table->cache_used += buf->st_size;
+
+ gettimeofday (&qr_inode->tv, NULL);
+
+ if (__qr_need_cache_prune (conf, table)) {
+ __qr_cache_prune (this);
}
}
+unlock:
+ UNLOCK (&table->lock);
- return;
+
+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, dict,
+ postparent);
+ return 0;
}
-void
-qr_cache_prune (xlator_t *this)
+int32_t
+qr_lookup (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xattr_req)
{
- qr_private_t *priv = NULL;
- qr_conf_t *conf = NULL;
- qr_inode_table_t *table = NULL;
+ qr_conf_t *conf = NULL;
+ dict_t *new_req_dict = NULL;
+ int32_t op_ret = -1, op_errno = -1;
+ data_t *content = NULL;
+ uint64_t requested_size = 0, size = 0, value = 0;
+ char cached = 0;
+ qr_inode_t *qr_inode = NULL;
+ qr_private_t *priv = NULL;
+ qr_inode_table_t *table = NULL;
+ qr_local_t *local = NULL;
priv = this->private;
- table = &priv->table;
conf = &priv->conf;
+ if (conf == NULL) {
+ op_ret = -1;
+ op_errno = EINVAL;
+ goto unwind;
+ }
- LOCK (&table->lock);
- {
- if (table->cache_used > conf->cache_size)
- __qr_cache_prune (table, conf);
- }
- UNLOCK (&table->lock);
+ table = &priv->table;
+
+ local = CALLOC (1, sizeof (*local));
+ GF_VALIDATE_OR_GOTO_WITH_ERROR (this->name, local, unwind, op_errno,
+ ENOMEM);
+
+ frame->local = local;
+
+ local->path = strdup (loc->path);
+ GF_VALIDATE_OR_GOTO_WITH_ERROR (this->name, local, unwind, op_errno,
+ ENOMEM);
+ LOCK (&table->lock);
+ {
+ op_ret = inode_ctx_get (loc->inode, this, &value);
+ if (op_ret == 0) {
+ qr_inode = (qr_inode_t *)(long)value;
+ if (qr_inode != NULL) {
+ if (qr_inode->xattr) {
+ cached = 1;
+ }
+ }
+ }
+ }
+ UNLOCK (&table->lock);
+
+ 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;
+ gf_log (this->name, GF_LOG_ERROR, "out of memory");
+ goto unwind;
+ }
+ }
+
+ if (!cached) {
+ if (xattr_req) {
+ content = dict_get (xattr_req, GLUSTERFS_CONTENT_KEY);
+ if (content) {
+ requested_size = data_to_uint64 (content);
+ }
+ }
+
+ if ((conf->max_file_size > 0)
+ && (conf->max_file_size != requested_size)) {
+ size = (conf->max_file_size > requested_size) ?
+ conf->max_file_size : requested_size;
+
+ op_ret = dict_set (xattr_req, GLUSTERFS_CONTENT_KEY,
+ data_from_uint64 (size));
+ if (op_ret < 0) {
+ op_ret = -1;
+ op_errno = ENOMEM;
+ goto unwind;
+ }
+ }
+ }
+
+ STACK_WIND (frame, qr_lookup_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->lookup, loc, xattr_req);
+
+ if (new_req_dict) {
+ dict_unref (new_req_dict);
+ }
+
+ return 0;
+
+unwind:
+ QR_STACK_UNWIND (lookup, frame, op_ret, op_errno, NULL, NULL, NULL,
+ NULL);
+
+ if (new_req_dict) {
+ dict_unref (new_req_dict);
+ }
+
+ return 0;
}
-void *
-qr_content_extract (dict_t *xdata)
+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)
{
- data_t *data = NULL;
- void *content = NULL;
+ uint64_t value = 0;
+ int32_t ret = -1;
+ struct list_head waiting_ops;
+ qr_local_t *local = NULL;
+ qr_inode_t *qr_inode = NULL;
+ qr_fd_ctx_t *qr_fd_ctx = NULL;
+ call_stub_t *stub = NULL, *tmp = NULL;
+ char is_open = 0;
+ qr_private_t *priv = NULL;
+ qr_inode_table_t *table = NULL;
+
+ priv = this->private;
+ table = &priv->table;
+
+ local = frame->local;
+ if (local != NULL) {
+ local->op_ret = op_ret;
+ local->op_errno = op_errno;
+ is_open = local->is_open;
+ }
+
+ INIT_LIST_HEAD (&waiting_ops);
+
+ ret = fd_ctx_get (fd, this, &value);
+ if ((ret == -1) && (op_ret != -1)) {
+ op_ret = -1;
+ op_errno = EINVAL;
+ goto out;
+ }
+
+ if (value) {
+ qr_fd_ctx = (qr_fd_ctx_t *) (long)value;
+ }
- data = dict_get (xdata, GF_CONTENT_KEY);
- if (!data)
- return NULL;
+ if (qr_fd_ctx) {
+ LOCK (&qr_fd_ctx->lock);
+ {
+ qr_fd_ctx->open_in_transit = 0;
- content = GF_CALLOC (1, data->len, gf_qr_mt_content_t);
- if (!content)
- return NULL;
+ if (op_ret == 0) {
+ qr_fd_ctx->opened = 1;
+ }
+ list_splice_init (&qr_fd_ctx->waiting_ops,
+ &waiting_ops);
+ }
+ UNLOCK (&qr_fd_ctx->lock);
+
+ if (local && local->is_open
+ && ((local->open_flags & O_TRUNC) == O_TRUNC)) {
+ LOCK (&table->lock);
+ {
+ ret = inode_ctx_del (fd->inode, this, &value);
+ if (ret == 0) {
+ qr_inode = (qr_inode_t *)(long) value;
+
+ if (qr_inode != NULL) {
+ __qr_inode_free (qr_inode);
+ }
+ }
+ }
+ UNLOCK (&table->lock);
+ }
- memcpy (content, data->data, data->len);
+ if (!list_empty (&waiting_ops)) {
+ list_for_each_entry_safe (stub, tmp, &waiting_ops,
+ list) {
+ list_del_init (&stub->list);
+ call_resume (stub);
+ }
+ }
+ }
+out:
+ if (is_open) {
+ QR_STACK_UNWIND (open, frame, op_ret, op_errno, fd);
+ }
- return content;
+ return 0;
}
-void
-qr_content_update (xlator_t *this, qr_inode_t *qr_inode, void *data,
- struct iatt *buf)
+int32_t
+qr_open (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
+ fd_t *fd, int32_t wbflags)
{
- qr_private_t *priv = NULL;
- qr_inode_table_t *table = NULL;
+ qr_inode_t *qr_inode = NULL;
+ int32_t ret = -1;
+ uint64_t filep = 0;
+ char content_cached = 0;
+ qr_fd_ctx_t *qr_fd_ctx = NULL, *tmp_fd_ctx = NULL;
+ int32_t op_ret = -1, op_errno = -1;
+ qr_local_t *local = NULL;
+ qr_conf_t *conf = NULL;
+ qr_private_t *priv = NULL;
+ qr_inode_table_t *table = NULL;
priv = this->private;
+ conf = &priv->conf;
table = &priv->table;
- LOCK (&table->lock);
- {
- __qr_inode_prune (table, qr_inode);
+ tmp_fd_ctx = qr_fd_ctx = CALLOC (1, sizeof (*qr_fd_ctx));
+ if (qr_fd_ctx == NULL) {
+ op_ret = -1;
+ op_errno = ENOMEM;
+ gf_log (this->name, GF_LOG_ERROR, "out of memory");
+ goto unwind;
+ }
+
+ LOCK_INIT (&qr_fd_ctx->lock);
+ INIT_LIST_HEAD (&qr_fd_ctx->waiting_ops);
- qr_inode->data = data;
- qr_inode->size = buf->ia_size;
+ qr_fd_ctx->path = strdup (loc->path);
+ qr_fd_ctx->flags = flags;
- qr_inode->ia_mtime = buf->ia_mtime;
- qr_inode->ia_mtime_nsec = buf->ia_mtime_nsec;
+ ret = fd_ctx_set (fd, this, (uint64_t)(long)qr_fd_ctx);
+ if (ret == -1) {
+ op_ret = -1;
+ op_errno = EINVAL;
+ goto unwind;
+ }
+ tmp_fd_ctx = NULL;
+
+ local = CALLOC (1, sizeof (*local));
+ if (local == NULL) {
+ op_ret = -1;
+ op_errno = ENOMEM;
+ gf_log (this->name, GF_LOG_ERROR, "out of memory");
+ goto unwind;
+ }
- qr_inode->buf = *buf;
+ local->is_open = 1;
+ local->open_flags = flags;
+ frame->local = local;
+ LOCK (&table->lock);
+ {
+ ret = inode_ctx_get (fd->inode, this, &filep);
+ if (ret == 0) {
+ qr_inode = (qr_inode_t *)(long) filep;
+ if (qr_inode) {
+ if (qr_inode->xattr) {
+ content_cached = 1;
+ }
+ }
+ }
+ }
+ UNLOCK (&table->lock);
- gettimeofday (&qr_inode->last_refresh, NULL);
+ if (content_cached && ((flags & O_DIRECTORY) == O_DIRECTORY)) {
+ op_ret = -1;
+ op_errno = ENOTDIR;
+ goto unwind;
+ }
- __qr_inode_register (table, qr_inode);
- }
- UNLOCK (&table->lock);
+ if (!content_cached || ((flags & O_ACCMODE) == O_WRONLY)
+ || ((flags & O_TRUNC) == O_TRUNC)
+ || ((flags & O_DIRECT) == O_DIRECT)) {
+ LOCK (&qr_fd_ctx->lock);
+ {
+ /*
+ * we really need not set this flag, since open is
+ * not yet unwounded.
+ */
+
+ qr_fd_ctx->open_in_transit = 1;
+ if ((flags & O_DIRECT) == O_DIRECT) {
+ qr_fd_ctx->disabled = 1;
+ }
+ }
+ UNLOCK (&qr_fd_ctx->lock);
+ goto wind;
+ } else {
+ op_ret = 0;
+ op_errno = 0;
+ goto unwind;
+ }
+
+unwind:
+ if (tmp_fd_ctx != NULL) {
+ qr_fd_ctx_free (tmp_fd_ctx);
+ }
+
+ QR_STACK_UNWIND (open, frame, op_ret, op_errno, fd);
+ return 0;
- qr_cache_prune (this);
+wind:
+ STACK_WIND (frame, qr_open_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->open, loc, flags, fd, wbflags);
+ return 0;
}
-gf_boolean_t
-qr_size_fits (qr_conf_t *conf, struct iatt *buf)
+static inline char
+qr_time_elapsed (struct timeval *now, struct timeval *then)
{
- return (buf->ia_size <= conf->max_file_size);
+ return now->tv_sec - then->tv_sec;
}
-gf_boolean_t
-qr_mtime_equal (qr_inode_t *qr_inode, struct iatt *buf)
+static inline char
+qr_need_validation (qr_conf_t *conf, qr_inode_t *qr_inode)
{
- return (qr_inode->ia_mtime == buf->ia_mtime &&
- qr_inode->ia_mtime_nsec == buf->ia_mtime_nsec);
+ struct timeval now = {0, };
+ char need_validation = 0;
+
+ gettimeofday (&now, NULL);
+
+ if (qr_time_elapsed (&now, &qr_inode->tv) >= conf->cache_timeout)
+ need_validation = 1;
+
+ return need_validation;
}
-void
-__qr_content_refresh (xlator_t *this, qr_inode_t *qr_inode, struct iatt *buf)
+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 stat *buf)
{
- qr_private_t *priv = NULL;
- qr_inode_table_t *table = NULL;
- qr_conf_t *conf = NULL;
+ qr_inode_t *qr_inode = NULL;
+ qr_local_t *local = NULL;
+ uint64_t value = 0;
+ int32_t ret = 0;
+ qr_private_t *priv = NULL;
+ qr_inode_table_t *table = NULL;
+ call_stub_t *stub = NULL;
+
+ local = frame->local;
+ if ((local == NULL) || ((local->fd) == NULL)) {
+ op_ret = -1;
+ op_errno = EINVAL;
+ goto unwind;
+ }
+
+ if (op_ret == -1) {
+ goto unwind;
+ }
priv = this->private;
table = &priv->table;
- conf = &priv->conf;
- if (qr_size_fits (conf, buf) && qr_mtime_equal (qr_inode, buf)) {
- qr_inode->buf = *buf;
+ LOCK (&table->lock);
+ {
+ ret = inode_ctx_get (local->fd->inode, this, &value);
+ if (ret == 0) {
+ qr_inode = (qr_inode_t *)(long) value;
+ }
- gettimeofday (&qr_inode->last_refresh, NULL);
+ if (qr_inode != NULL) {
+ gettimeofday (&qr_inode->tv, NULL);
- __qr_inode_register (table, qr_inode);
- } else {
- __qr_inode_prune (table, qr_inode);
- }
+ if ((qr_inode->stbuf.st_mtime != buf->st_mtime)
+ || (ST_MTIM_NSEC(&qr_inode->stbuf) !=
+ ST_MTIM_NSEC(buf))) {
+ inode_ctx_del (local->fd->inode, this, NULL);
+ __qr_inode_free (qr_inode);
+ }
+ }
+ }
+ UNLOCK (&table->lock);
- return;
+ stub = local->stub;
+ local->stub = NULL;
+ local->just_validated = 1;
+ call_resume (stub);
+
+ return 0;
+
+unwind:
+ /* this is actually unwind of readv */
+ QR_STACK_UNWIND (readv, frame, op_ret, op_errno, NULL, -1, NULL,
+ NULL);
+ return 0;
}
-void
-qr_content_refresh (xlator_t *this, qr_inode_t *qr_inode, struct iatt *buf)
+int32_t
+qr_validate_cache_helper (call_frame_t *frame, xlator_t *this, fd_t *fd)
{
- qr_private_t *priv = NULL;
- qr_inode_table_t *table = NULL;
+ qr_local_t *local = NULL;
+ int32_t op_ret = -1, op_errno = -1;
- priv = this->private;
- table = &priv->table;
+ local = frame->local;
+ if (local == NULL) {
+ op_ret = -1;
+ op_errno = EINVAL;
+ } else {
+ op_ret = local->op_ret;
+ op_errno = local->op_errno;
+ }
- LOCK (&table->lock);
- {
- __qr_content_refresh (this, qr_inode, buf);
- }
- UNLOCK (&table->lock);
+ if (op_ret == -1) {
+ qr_validate_cache_cbk (frame, NULL, this, op_ret, op_errno,
+ NULL);
+ } else {
+ STACK_WIND (frame, qr_validate_cache_cbk, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->fstat, fd);
+ }
+
+ return 0;
}
-gf_boolean_t
-__qr_cache_is_fresh (xlator_t *this, qr_inode_t *qr_inode)
+int
+qr_validate_cache (call_frame_t *frame, xlator_t *this, fd_t *fd,
+ call_stub_t *stub)
{
- qr_conf_t *conf = NULL;
- qr_private_t *priv = NULL;
- struct timeval now;
- struct timeval diff;
-
- priv = this->private;
- conf = &priv->conf;
+ 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;
+
+ local = CALLOC (1, sizeof (*local));
+ if (local == NULL) {
+ goto out;
+ }
- gettimeofday (&now, NULL);
+ local->fd = fd;
+ local->stub = stub;
+ frame->local = local;
- timersub (&now, &qr_inode->last_refresh, &diff);
+ ret = fd_ctx_get (fd, this, &value);
+ if (ret == 0) {
+ qr_fd_ctx = (qr_fd_ctx_t *)(long) value;
+ }
- if (diff.tv_sec >= conf->cache_timeout)
- return _gf_false;
+ if (qr_fd_ctx) {
+ LOCK (&qr_fd_ctx->lock);
+ {
+ path = qr_fd_ctx->path;
+ flags = qr_fd_ctx->flags;
+
+ if (!(qr_fd_ctx->opened
+ || qr_fd_ctx->open_in_transit)) {
+ need_open = 1;
+ qr_fd_ctx->open_in_transit = 1;
+ }
+
+ if (qr_fd_ctx->opened) {
+ can_wind = 1;
+ } else {
+ validate_stub = fop_fstat_stub (frame,
+ qr_validate_cache_helper,
+ fd);
+ if (validate_stub == NULL) {
+ ret = -1;
+ qr_fd_ctx->open_in_transit = 0;
+ goto unlock;
+ }
+
+ list_add_tail (&validate_stub->list,
+ &qr_fd_ctx->waiting_ops);
+ }
+ }
+ unlock:
+ UNLOCK (&qr_fd_ctx->lock);
- return _gf_true;
-}
+ if (ret == -1) {
+ goto out;
+ }
+ } else {
+ can_wind = 1;
+ }
+ if (need_open) {
+ ret = qr_loc_fill (&loc, fd->inode, path);
+ if (ret == -1) {
+ qr_resume_pending_ops (qr_fd_ctx);
+ goto out;
+ }
-int
-qr_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, inode_t *inode_ret,
- struct iatt *buf, dict_t *xdata, struct iatt *postparent)
-{
- void *content = NULL;
- qr_inode_t *qr_inode = NULL;
- inode_t *inode = NULL;
+ STACK_WIND (frame, qr_open_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->open,
+ &loc, flags, fd, 0);
+
+ qr_loc_wipe (&loc);
+ } else if (can_wind) {
+ STACK_WIND (frame, qr_validate_cache_cbk,
+ FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->fstat, fd);
+ }
- inode = frame->local;
- frame->local = NULL;
+ ret = 0;
+out:
+ return ret;
+}
- if (op_ret == -1) {
- qr_inode_prune (this, inode);
- goto out;
- }
- if (dict_get (xdata, "sh-failed")) {
- qr_inode_prune (this, inode);
- goto 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 stat *stbuf, struct iobref *iobref)
+{
+ QR_STACK_UNWIND (readv, frame, op_ret, op_errno, vector, count,
+ stbuf, iobref);
+ return 0;
+}
- content = qr_content_extract (xdata);
-
- if (content) {
- /* new content came along, always replace old content */
- qr_inode = qr_inode_ctx_get_or_new (this, inode);
- if (!qr_inode) {
- /* no harm done */
- GF_FREE (content);
- goto out;
- }
- qr_content_update (this, qr_inode, content, buf);
- } else {
- /* purge old content if necessary */
- qr_inode = qr_inode_ctx_get (this, inode);
- if (!qr_inode)
- /* usual path for large files */
- goto out;
-
- qr_content_refresh (this, qr_inode, buf);
- }
-out:
- if (inode)
- inode_unref (inode);
- STACK_UNWIND_STRICT (lookup, frame, op_ret, op_errno, inode_ret,
- buf, xdata, postparent);
+int32_t
+qr_readv_helper (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
+ off_t offset)
+{
+ STACK_WIND (frame, qr_readv_cbk, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->readv, fd, size, offset);
return 0;
}
-int
-qr_lookup (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
+int32_t
+qr_readv (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
+ off_t offset)
{
- qr_private_t *priv = NULL;
- qr_conf_t *conf = NULL;
- qr_inode_t *qr_inode = NULL;
- int ret = -1;
- dict_t *new_xdata = NULL;
+ qr_inode_t *qr_inode = NULL;
+ qr_local_t *local = NULL;
+ char just_validated = 0;
+ int32_t ret = -1, op_ret = -1, op_errno = -1;
+ uint64_t value = 0;
+ int count = -1, flags = 0, i = 0;
+ char content_cached = 0, need_validation = 0;
+ char need_open = 0, can_wind = 0, need_unwind = 0;
+ struct iobuf *iobuf = NULL;
+ struct iobref *iobref = NULL;
+ struct stat stbuf = {0, };
+ data_t *content = NULL;
+ qr_fd_ctx_t *qr_fd_ctx = NULL;
+ call_stub_t *stub = NULL;
+ loc_t loc = {0, };
+ qr_conf_t *conf = NULL;
+ struct iovec *vector = NULL;
+ char *path = NULL;
+ glusterfs_ctx_t *ctx = NULL;
+ off_t start = 0, end = 0;
+ size_t len = 0;
+ struct iobuf_pool *iobuf_pool = NULL;
+ qr_private_t *priv = NULL;
+ qr_inode_table_t *table = NULL;
+
+ op_ret = 0;
priv = this->private;
conf = &priv->conf;
+ table = &priv->table;
- qr_inode = qr_inode_ctx_get (this, loc->inode);
- if (qr_inode && qr_inode->data)
- /* cached. only validate in qr_lookup_cbk */
- goto wind;
+ local = frame->local;
+ if (local != NULL) {
+ just_validated = local->just_validated;
+ FREE (local);
+ frame->local = NULL;
+ }
- if (!xdata)
- xdata = new_xdata = dict_new ();
+ ret = fd_ctx_get (fd, this, &value);
+ if (ret == 0) {
+ qr_fd_ctx = (qr_fd_ctx_t *)(long) value;
+ if (qr_fd_ctx != NULL) {
+ if (qr_fd_ctx->disabled) {
+ goto out;
+ }
+ }
+ }
- if (!xdata)
- goto wind;
+ iobuf_pool = this->ctx->iobuf_pool;
+
+ LOCK (&table->lock);
+ {
+ ret = inode_ctx_get (fd->inode, this, &value);
+ 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;
+ }
+
+ content = dict_get (qr_inode->xattr,
+ GLUSTERFS_CONTENT_KEY);
+
+ 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;
+ }
+ }
+
+ ctx = this->ctx;
+ count = (op_ret / iobuf_pool->page_size);
+ if ((op_ret % iobuf_pool->page_size)
+ != 0) {
+ count++;
+ }
+
+ if (count == 0) {
+ op_ret = 0;
+ goto unlock;
+ }
+
+ vector = CALLOC (count,
+ sizeof (*vector));
+ 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;
+ }
+
+ 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->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);
+ }
+
+ iobref_add (iobref, iobuf);
+ iobuf_unref (iobuf);
+
+ vector[i].iov_base = iobuf->ptr;
+ vector[i].iov_len = len;
+ }
+ }
+ }
+ }
+ }
+unlock:
+ UNLOCK (&table->lock);
- ret = 0;
- if (conf->max_file_size)
- ret = dict_set (xdata, GF_CONTENT_KEY,
- data_from_uint64 (conf->max_file_size));
- if (ret)
- gf_log (this->name, GF_LOG_WARNING,
- "cannot set key in request dict (%s)",
- loc->path);
-wind:
- frame->local = inode_ref (loc->inode);
+out:
+ if (content_cached || need_unwind) {
+ QR_STACK_UNWIND (readv, frame, op_ret, op_errno, vector,
+ count, &stbuf, iobref);
+
+ } else if (need_validation) {
+ stub = fop_readv_stub (frame, qr_readv, fd, size, offset);
+ if (stub == NULL) {
+ op_ret = -1;
+ op_errno = ENOMEM;
+ goto out;
+ }
- STACK_WIND (frame, qr_lookup_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->lookup, loc, xdata);
+ 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);
+ {
+ path = qr_fd_ctx->path;
+ flags = qr_fd_ctx->flags;
+
+ if (!(qr_fd_ctx->opened
+ || qr_fd_ctx->open_in_transit)) {
+ need_open = 1;
+ qr_fd_ctx->open_in_transit = 1;
+ }
+
+ if (qr_fd_ctx->opened) {
+ can_wind = 1;
+ } else {
+ stub = fop_readv_stub (frame,
+ qr_readv_helper,
+ fd, size,
+ offset);
+ if (stub == NULL) {
+ op_ret = -1;
+ op_errno = ENOMEM;
+ need_unwind = 1;
+ qr_fd_ctx->open_in_transit = 0;
+ goto fdctx_unlock;
+ }
+
+ list_add_tail (&stub->list,
+ &qr_fd_ctx->waiting_ops);
+ }
+ }
+ fdctx_unlock:
+ UNLOCK (&qr_fd_ctx->lock);
+
+ if (op_ret == -1) {
+ need_unwind = 1;
+ goto out;
+ }
+ } else {
+ can_wind = 1;
+ }
- if (new_xdata)
- dict_unref (new_xdata);
+ if (need_open) {
+ op_ret = qr_loc_fill (&loc, fd->inode, path);
+ if (op_ret == -1) {
+ qr_resume_pending_ops (qr_fd_ctx);
+ goto out;
+ }
+
+ STACK_WIND (frame, qr_open_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->open,
+ &loc, flags, fd, 0);
+
+ 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);
+ }
+
+ }
+
+ if (vector) {
+ FREE (vector);
+ }
+
+ if (iobref) {
+ iobref_unref (iobref);
+ }
return 0;
}
-int
-qr_readdirp_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int op_ret, int op_errno, gf_dirent_t *entries, dict_t *xdata)
+int32_t
+qr_writev_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct stat *prebuf,
+ struct stat *postbuf)
+{
+ QR_STACK_UNWIND (writev, frame, op_ret, op_errno, prebuf, postbuf);
+ return 0;
+}
+
+
+int32_t
+qr_writev_helper (call_frame_t *frame, xlator_t *this, fd_t *fd,
+ struct iovec *vector, int32_t count, off_t off,
+ struct iobref *iobref)
{
- gf_dirent_t *entry = NULL;
- qr_inode_t *qr_inode = NULL;
+ STACK_WIND (frame, qr_writev_cbk, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->writev, fd, vector, count, off,
+ iobref);
+ return 0;
+}
+
- if (op_ret <= 0)
- goto unwind;
+int32_t
+qr_writev (call_frame_t *frame, xlator_t *this, fd_t *fd, struct iovec *vector,
+ 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;
- list_for_each_entry (entry, &entries->list, list) {
- if (!entry->inode)
- continue;
+ priv = this->private;
+ table = &priv->table;
+
+ ret = fd_ctx_get (fd, this, &value);
+ if (ret == 0) {
+ qr_fd_ctx = (qr_fd_ctx_t *)(long) value;
+ }
- qr_inode = qr_inode_ctx_get (this, entry->inode);
- if (!qr_inode)
- /* no harm */
- continue;
+ LOCK (&table->lock);
+ {
+ ret = inode_ctx_get (fd->inode, this, &value);
+ if (ret == 0) {
+ qr_inode = (qr_inode_t *)(long)value;
+ if (qr_inode != NULL) {
+ inode_ctx_del (fd->inode, this, NULL);
+ __qr_inode_free (qr_inode);
+ }
+ }
+ }
+ UNLOCK (&table->lock);
+
+ if (qr_fd_ctx) {
+ LOCK (&qr_fd_ctx->lock);
+ {
+ path = qr_fd_ctx->path;
+ flags = qr_fd_ctx->flags;
+
+ if (!(qr_fd_ctx->opened
+ || qr_fd_ctx->open_in_transit)) {
+ need_open = 1;
+ qr_fd_ctx->open_in_transit = 1;
+ }
- qr_content_refresh (this, qr_inode, &entry->d_stat);
+ if (qr_fd_ctx->opened) {
+ can_wind = 1;
+ } else {
+ stub = fop_writev_stub (frame, qr_writev_helper,
+ fd, vector, count, off,
+ iobref);
+ if (stub == NULL) {
+ op_ret = -1;
+ op_errno = ENOMEM;
+ need_unwind = 1;
+ qr_fd_ctx->open_in_transit = 0;
+ goto unlock;
+ }
+
+ list_add_tail (&stub->list,
+ &qr_fd_ctx->waiting_ops);
+ }
+ }
+ unlock:
+ UNLOCK (&qr_fd_ctx->lock);
+ } else {
+ can_wind = 1;
}
-unwind:
- STACK_UNWIND_STRICT (readdirp, frame, op_ret, op_errno, entries, xdata);
- return 0;
+out:
+ if (need_unwind) {
+ 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, iobref);
+ } else if (need_open) {
+ op_ret = qr_loc_fill (&loc, fd->inode, path);
+ if (op_ret == -1) {
+ qr_resume_pending_ops (qr_fd_ctx);
+ goto out;
+ }
+
+ STACK_WIND (frame, qr_open_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->open, &loc, flags, fd, 0);
+
+ qr_loc_wipe (&loc);
+ }
+
+ return 0;
}
-int
-qr_readdirp (call_frame_t *frame, xlator_t *this, fd_t *fd,
- size_t size, off_t offset, dict_t *xdata)
+int32_t
+qr_fstat_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret,
+ int32_t op_errno, struct stat *buf)
{
- STACK_WIND (frame, qr_readdirp_cbk,
- FIRST_CHILD (this), FIRST_CHILD (this)->fops->readdirp,
- fd, size, offset, xdata);
+ QR_STACK_UNWIND (fstat, frame, op_ret, op_errno, buf);
return 0;
}
-int
-qr_readv_cached (call_frame_t *frame, qr_inode_t *qr_inode, size_t size,
- off_t offset, uint32_t flags, dict_t *xdata)
+int32_t
+qr_fstat_helper (call_frame_t *frame, xlator_t *this, fd_t *fd)
{
- xlator_t *this = NULL;
- qr_private_t *priv = NULL;
- qr_inode_table_t *table = NULL;
- int op_ret = -1;
- struct iobuf *iobuf = NULL;
- struct iobref *iobref = NULL;
- struct iovec iov = {0, };
- struct iatt buf = {0, };
-
- this = frame->this;
- priv = this->private;
- table = &priv->table;
+ STACK_WIND (frame, qr_fstat_cbk, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->fstat, fd);
+ return 0;
+}
- LOCK (&table->lock);
- {
- if (!qr_inode->data)
- goto unlock;
- if (offset >= qr_inode->size)
- goto unlock;
+int32_t
+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 = -1;
+ call_stub_t *stub = NULL;
+ loc_t loc = {0, };
+ char *path = NULL;
+ int flags = 0;
+
+ ret = fd_ctx_get (fd, this, &value);
+ if (ret == 0) {
+ qr_fd_ctx = (qr_fd_ctx_t *)(long) value;
+ }
- if (!__qr_cache_is_fresh (this, qr_inode))
- goto unlock;
+ if (qr_fd_ctx) {
+ LOCK (&qr_fd_ctx->lock);
+ {
+ path = qr_fd_ctx->path;
+ flags = qr_fd_ctx->flags;
- op_ret = min (size, (qr_inode->size - offset));
+ if (!(qr_fd_ctx->opened
+ || qr_fd_ctx->open_in_transit)) {
+ need_open = 1;
+ qr_fd_ctx->open_in_transit = 1;
+ }
- iobuf = iobuf_get2 (this->ctx->iobuf_pool, op_ret);
- if (!iobuf) {
- op_ret = -1;
- goto unlock;
- }
+ if (qr_fd_ctx->opened) {
+ can_wind = 1;
+ } else {
+ stub = fop_fstat_stub (frame, qr_fstat_helper,
+ fd);
+ if (stub == NULL) {
+ op_ret = -1;
+ op_errno = ENOMEM;
+ need_unwind = 1;
+ qr_fd_ctx->open_in_transit = 0;
+ goto unlock;
+ }
+
+ list_add_tail (&stub->list,
+ &qr_fd_ctx->waiting_ops);
+ }
+ }
+ unlock:
+ UNLOCK (&qr_fd_ctx->lock);
+ } else {
+ can_wind = 1;
+ }
- iobref = iobref_new ();
- if (!iobref) {
- op_ret = -1;
- goto unlock;
- }
+out:
+ if (need_unwind) {
+ 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);
+ } else if (need_open) {
+ op_ret = qr_loc_fill (&loc, fd->inode, path);
+ if (op_ret == -1) {
+ qr_resume_pending_ops (qr_fd_ctx);
+ goto out;
+ }
- iobref_add (iobref, iobuf);
+ STACK_WIND (frame, qr_open_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->open, &loc, flags, fd, 0);
- memcpy (iobuf->ptr, qr_inode->data + offset, op_ret);
+ qr_loc_wipe (&loc);
+ }
+
+ return 0;
+}
- buf = qr_inode->buf;
- /* bump LRU */
- __qr_inode_register (table, qr_inode);
- }
-unlock:
- UNLOCK (&table->lock);
- if (op_ret >= 0) {
- iov.iov_base = iobuf->ptr;
- iov.iov_len = op_ret;
- STACK_UNWIND_STRICT (readv, frame, op_ret, 0, &iov, 1,
- &buf, iobref, xdata);
- }
- iobuf_unref (iobuf);
+int32_t
+qr_fsetattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno,
+ struct stat *preop, struct stat *postop)
+{
+ QR_STACK_UNWIND (fsetattr, frame, op_ret, op_errno, preop, postop);
+ return 0;
+}
- iobref_unref (iobref);
- return op_ret;
+int32_t
+qr_fsetattr_helper (call_frame_t *frame, xlator_t *this, fd_t *fd,
+ struct stat *stbuf, int32_t valid)
+{
+ STACK_WIND(frame, qr_fsetattr_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->fsetattr, fd, stbuf,
+ valid);
+ return 0;
}
-int
-qr_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
+qr_fsetattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
+ struct stat *stbuf, int32_t valid)
{
- qr_inode_t *qr_inode = NULL;
+ 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 = -1;
+ char need_open = 0, can_wind = 0, need_unwind = 0;
+
+ ret = fd_ctx_get (fd, this, &value);
+ if (ret == 0) {
+ qr_fd_ctx = (qr_fd_ctx_t *)(long) value;
+ }
+
+ if (qr_fd_ctx) {
+ LOCK (&qr_fd_ctx->lock);
+ {
+ path = qr_fd_ctx->path;
+ flags = qr_fd_ctx->flags;
+ if (!(qr_fd_ctx->opened
+ || qr_fd_ctx->open_in_transit)) {
+ need_open = 1;
+ qr_fd_ctx->open_in_transit = 1;
+ }
+
+ if (qr_fd_ctx->opened) {
+ can_wind = 1;
+ } else {
+ stub = fop_fsetattr_stub (frame,
+ qr_fsetattr_helper,
+ fd, stbuf, valid);
+ if (stub == NULL) {
+ op_ret = -1;
+ op_errno = ENOMEM;
+ need_unwind = 1;
+ qr_fd_ctx->open_in_transit = 0;
+ goto unlock;
+ }
+
+ list_add_tail (&stub->list,
+ &qr_fd_ctx->waiting_ops);
+ }
+ }
+ unlock:
+ UNLOCK (&qr_fd_ctx->lock);
+ } else {
+ can_wind = 1;
+ }
- qr_inode = qr_inode_ctx_get (this, fd->inode);
- if (!qr_inode)
- goto wind;
+out:
+ if (need_unwind) {
+ 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);
+ } else if (need_open) {
+ op_ret = qr_loc_fill (&loc, fd->inode, path);
+ if (op_ret == -1) {
+ qr_resume_pending_ops (qr_fd_ctx);
+ goto out;
+ }
- if (qr_readv_cached (frame, qr_inode, size, offset, flags, xdata) < 0)
- goto wind;
+ STACK_WIND (frame, qr_open_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->open, &loc, flags, fd, 0);
- return 0;
-wind:
- STACK_WIND (frame, default_readv_cbk,
- FIRST_CHILD (this), FIRST_CHILD (this)->fops->readv,
- fd, size, offset, flags, xdata);
+ qr_loc_wipe (&loc);
+ }
+
+ return 0;
+}
+
+
+int32_t
+qr_fsetxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno)
+{
+ QR_STACK_UNWIND (fsetxattr, frame, op_ret, op_errno);
return 0;
}
-int
-qr_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
+qr_fsetxattr_helper (call_frame_t *frame, xlator_t *this, fd_t *fd,
+ dict_t *dict, int32_t flags)
+{
+ STACK_WIND (frame, qr_fsetxattr_cbk, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->fsetxattr, fd, dict, flags);
+ return 0;
+}
+
+
+int32_t
+qr_fsetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *dict,
+ int32_t flags)
{
- qr_inode_prune (this, fd->inode);
+ 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 = -1;
+ char need_open = 0, can_wind = 0, need_unwind = 0;
+
+ ret = fd_ctx_get (fd, this, &value);
+ if (ret == 0) {
+ qr_fd_ctx = (qr_fd_ctx_t *)(long) value;
+ }
- STACK_WIND (frame, default_writev_cbk,
- FIRST_CHILD (this), FIRST_CHILD (this)->fops->writev,
- fd, iov, count, offset, flags, iobref, xdata);
+ if (qr_fd_ctx) {
+ LOCK (&qr_fd_ctx->lock);
+ {
+ path = qr_fd_ctx->path;
+ open_flags = qr_fd_ctx->flags;
+
+ if (!(qr_fd_ctx->opened
+ || qr_fd_ctx->open_in_transit)) {
+ need_open = 1;
+ qr_fd_ctx->open_in_transit = 1;
+ }
+
+ if (qr_fd_ctx->opened) {
+ can_wind = 1;
+ } else {
+ stub = fop_fsetxattr_stub (frame,
+ qr_fsetxattr_helper,
+ fd, dict, flags);
+ if (stub == NULL) {
+ op_ret = -1;
+ op_errno = ENOMEM;
+ need_unwind = 1;
+ qr_fd_ctx->open_in_transit = 0;
+ goto unlock;
+ }
+
+ list_add_tail (&stub->list,
+ &qr_fd_ctx->waiting_ops);
+ }
+ }
+ unlock:
+ UNLOCK (&qr_fd_ctx->lock);
+ } else {
+ can_wind = 1;
+ }
+
+out:
+ if (need_unwind) {
+ 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);
+ } else if (need_open) {
+ op_ret = qr_loc_fill (&loc, fd->inode, path);
+ if (op_ret == -1) {
+ qr_resume_pending_ops (qr_fd_ctx);
+ goto out;
+ }
+
+ STACK_WIND (frame, qr_open_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->open, &loc, open_flags,
+ fd, 0);
+
+ qr_loc_wipe (&loc);
+ }
+
+ return 0;
+}
+
+
+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)
+{
+ QR_STACK_UNWIND (fgetxattr, frame, op_ret, op_errno, dict);
return 0;
}
-int
-qr_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset,
- dict_t *xdata)
+int32_t
+qr_fgetxattr_helper (call_frame_t *frame, xlator_t *this, fd_t *fd,
+ const char *name)
{
- qr_inode_prune (this, loc->inode);
+ STACK_WIND (frame, qr_fgetxattr_cbk, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->fgetxattr, fd, name);
+ return 0;
+}
+
+
+int32_t
+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 = -1;
+ char need_open = 0, can_wind = 0, need_unwind = 0;
+
+ /*
+ * FIXME: Can quick-read use the extended attributes stored in the
+ * cache? this needs to be discussed.
+ */
+
+ ret = fd_ctx_get (fd, this, &value);
+ if (ret == 0) {
+ qr_fd_ctx = (qr_fd_ctx_t *)(long) value;
+ }
+
+ if (qr_fd_ctx) {
+ LOCK (&qr_fd_ctx->lock);
+ {
+ path = qr_fd_ctx->path;
+ flags = qr_fd_ctx->flags;
+
+ if (!(qr_fd_ctx->opened
+ || qr_fd_ctx->open_in_transit)) {
+ need_open = 1;
+ qr_fd_ctx->open_in_transit = 1;
+ }
+
+ if (qr_fd_ctx->opened) {
+ can_wind = 1;
+ } else {
+ stub = fop_fgetxattr_stub (frame,
+ qr_fgetxattr_helper,
+ fd, name);
+ if (stub == NULL) {
+ op_ret = -1;
+ op_errno = ENOMEM;
+ need_unwind = 1;
+ qr_fd_ctx->open_in_transit = 0;
+ goto unlock;
+ }
+
+ list_add_tail (&stub->list,
+ &qr_fd_ctx->waiting_ops);
+ }
+ }
+ unlock:
+ UNLOCK (&qr_fd_ctx->lock);
+ } else {
+ can_wind = 1;
+ }
+
+out:
+ if (need_unwind) {
+ 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);
+ } else if (need_open) {
+ op_ret = qr_loc_fill (&loc, fd->inode, path);
+ if (op_ret == -1) {
+ qr_resume_pending_ops (qr_fd_ctx);
+ goto out;
+ }
+
+ STACK_WIND (frame, qr_open_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->open, &loc, flags, fd, 0);
+
+ qr_loc_wipe (&loc);
+ }
+
+ return 0;
+}
+
- STACK_WIND (frame, default_truncate_cbk,
- FIRST_CHILD (this), FIRST_CHILD (this)->fops->truncate,
- loc, offset, xdata);
+int32_t
+qr_flush_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret,
+ int32_t op_errno)
+{
+ QR_STACK_UNWIND (flush, frame, op_ret, op_errno);
return 0;
}
-int
-qr_ftruncate (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
- dict_t *xdata)
+int32_t
+qr_flush_helper (call_frame_t *frame, xlator_t *this, fd_t *fd)
+{
+ STACK_WIND (frame, qr_flush_cbk, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->flush, fd);
+ return 0;
+}
+
+
+int32_t
+qr_flush (call_frame_t *frame, xlator_t *this, fd_t *fd)
{
- qr_inode_prune (this, fd->inode);
+ uint64_t value = 0;
+ call_stub_t *stub = NULL;
+ qr_fd_ctx_t *qr_fd_ctx = NULL;
+ int32_t ret = -1, op_ret = -1, op_errno = -1;
+ char can_wind = 0, need_unwind = 0;
+
+ ret = fd_ctx_get (fd, this, &value);
+ if (ret == 0) {
+ qr_fd_ctx = (qr_fd_ctx_t *)(long)value;
+ }
+
+ if (qr_fd_ctx) {
+ LOCK (&qr_fd_ctx->lock);
+ {
+ if (qr_fd_ctx->opened) {
+ can_wind = 1;
+ } else if (qr_fd_ctx->open_in_transit) {
+ stub = fop_flush_stub (frame, qr_flush_helper,
+ fd);
+ if (stub == NULL) {
+ op_ret = -1;
+ op_errno = ENOMEM;
+ need_unwind = 1;
+ qr_fd_ctx->open_in_transit = 0;
+ goto unlock;
+ }
+
+ list_add_tail (&stub->list,
+ &qr_fd_ctx->waiting_ops);
+ } else {
+ op_ret = 0;
+ need_unwind = 1;
+ }
+ }
+ unlock:
+ UNLOCK (&qr_fd_ctx->lock);
+ } else {
+ can_wind = 1;
+ }
+
+ if (need_unwind) {
+ 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);
+ }
+
+ return 0;
+}
+
- STACK_WIND (frame, default_ftruncate_cbk,
- FIRST_CHILD (this), FIRST_CHILD (this)->fops->ftruncate,
- fd, offset, xdata);
+int32_t
+qr_fentrylk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno)
+{
+ QR_STACK_UNWIND (fentrylk, frame, op_ret, op_errno);
return 0;
}
+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)
+{
+ STACK_WIND(frame, qr_fentrylk_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->fentrylk, volume, fd, basename,
+ cmd, type);
+ return 0;
+}
-int
-qr_open (call_frame_t *frame, xlator_t *this, loc_t *loc, int flags,
- fd_t *fd, dict_t *xdata)
+
+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)
{
- qr_inode_set_priority (this, fd->inode, loc->path);
+ 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 = -1;
+ char need_open = 0, can_wind = 0, need_unwind = 0;
+
+ ret = fd_ctx_get (fd, this, &value);
+ if (ret == 0) {
+ qr_fd_ctx = (qr_fd_ctx_t *)(long)value;
+ }
+
+ if (qr_fd_ctx) {
+ LOCK (&qr_fd_ctx->lock);
+ {
+ path = qr_fd_ctx->path;
+ flags = qr_fd_ctx->flags;
+
+ if (!(qr_fd_ctx->opened
+ || qr_fd_ctx->open_in_transit)) {
+ need_open = 1;
+ qr_fd_ctx->open_in_transit = 1;
+ }
+
+ if (qr_fd_ctx->opened) {
+ can_wind = 1;
+ } else {
+ stub = fop_fentrylk_stub (frame,
+ qr_fentrylk_helper,
+ volume, fd, basename,
+ cmd, type);
+ if (stub == NULL) {
+ op_ret = -1;
+ op_errno = ENOMEM;
+ need_unwind = 1;
+ qr_fd_ctx->open_in_transit = 0;
+ goto unlock;
+ }
+
+ list_add_tail (&stub->list,
+ &qr_fd_ctx->waiting_ops);
+ }
+ }
+ unlock:
+ UNLOCK (&qr_fd_ctx->lock);
+ } else {
+ can_wind = 1;
+ }
+
+out:
+ if (need_unwind) {
+ 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);
+ } else if (need_open) {
+ op_ret = qr_loc_fill (&loc, fd->inode, path);
+ if (op_ret == -1) {
+ qr_resume_pending_ops (qr_fd_ctx);
+ goto out;
+ }
+
+ STACK_WIND (frame, qr_open_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->open, &loc, flags, fd, 0);
+
+ qr_loc_wipe (&loc);
+ }
+
+ return 0;
+}
- STACK_WIND (frame, default_open_cbk,
- FIRST_CHILD (this), FIRST_CHILD (this)->fops->open,
- loc, flags, fd, xdata);
+
+int32_t
+qr_finodelk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno)
+
+{
+ QR_STACK_UNWIND (finodelk, frame, op_ret, op_errno);
return 0;
}
-int
-qr_forget (xlator_t *this, inode_t *inode)
+
+int32_t
+qr_finodelk_helper (call_frame_t *frame, xlator_t *this, const char *volume,
+ fd_t *fd, int32_t cmd, struct flock *lock)
+{
+ STACK_WIND (frame, qr_finodelk_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->finodelk, volume, fd, cmd, lock);
+ return 0;
+}
+
+
+int32_t
+qr_finodelk (call_frame_t *frame, xlator_t *this, const char *volume, fd_t *fd,
+ int32_t cmd, struct flock *lock)
{
- qr_inode_t *qr_inode = NULL;
+ 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 = -1;
+ char need_open = 0, can_wind = 0, need_unwind = 0;
+
+ ret = fd_ctx_get (fd, this, &value);
+ if (ret == 0) {
+ qr_fd_ctx = (qr_fd_ctx_t *)(long)value;
+ }
- qr_inode = qr_inode_ctx_get (this, inode);
+ if (qr_fd_ctx) {
+ LOCK (&qr_fd_ctx->lock);
+ {
+ path = qr_fd_ctx->path;
+ flags = qr_fd_ctx->flags;
- if (!qr_inode)
- return 0;
+ if (!(qr_fd_ctx->opened
+ || qr_fd_ctx->open_in_transit)) {
+ need_open = 1;
+ qr_fd_ctx->open_in_transit = 1;
+ }
- qr_inode_prune (this, inode);
+ if (qr_fd_ctx->opened) {
+ can_wind = 1;
+ } else {
+ stub = fop_finodelk_stub (frame,
+ qr_finodelk_helper,
+ volume, fd, cmd,
+ lock);
+ if (stub == NULL) {
+ op_ret = -1;
+ op_errno = ENOMEM;
+ need_unwind = 1;
+ qr_fd_ctx->open_in_transit = 0;
+ goto unlock;
+ }
+
+ list_add_tail (&stub->list,
+ &qr_fd_ctx->waiting_ops);
+ }
+ }
+ unlock:
+ UNLOCK (&qr_fd_ctx->lock);
+ } else {
+ can_wind = 1;
+ }
- GF_FREE (qr_inode);
+out:
+ if (need_unwind) {
+ 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);
+ } else if (need_open) {
+ op_ret = qr_loc_fill (&loc, fd->inode, path);
+ if (op_ret == -1) {
+ qr_resume_pending_ops (qr_fd_ctx);
+ goto out;
+ }
- return 0;
+ STACK_WIND (frame, qr_open_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->open, &loc, flags, fd, 0);
+
+ qr_loc_wipe (&loc);
+ }
+
+ return 0;
}
int32_t
-qr_inodectx_dump (xlator_t *this, inode_t *inode)
+qr_fsync_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret,
+ int32_t op_errno, struct stat *prebuf, struct stat *postbuf)
{
- qr_inode_t *qr_inode = NULL;
- int32_t ret = -1;
- char key_prefix[GF_DUMP_MAX_BUF_LEN] = {0, };
- char buf[256] = {0, };
+ QR_STACK_UNWIND (fsync, frame, op_ret, op_errno, prebuf, postbuf);
+ return 0;
+}
- qr_inode = qr_inode_ctx_get (this, inode);
- if (!qr_inode)
- goto out;
- gf_proc_dump_build_key (key_prefix, "xlator.performance.quick-read",
- "inodectx");
- gf_proc_dump_add_section (key_prefix);
+int32_t
+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);
+ return 0;
+}
- gf_proc_dump_write ("entire-file-cached", "%s", qr_inode->data ? "yes" : "no");
+int32_t
+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 = -1;
+ char need_open = 0, can_wind = 0, need_unwind = 0;
+
+ ret = fd_ctx_get (fd, this, &value);
+ if (ret == 0) {
+ qr_fd_ctx = (qr_fd_ctx_t *)(long)value;
+ }
+
+ if (qr_fd_ctx) {
+ LOCK (&qr_fd_ctx->lock);
+ {
+ path = qr_fd_ctx->path;
+ open_flags = qr_fd_ctx->flags;
- if (qr_inode->last_refresh.tv_sec) {
- gf_time_fmt (buf, sizeof buf, qr_inode->last_refresh.tv_sec,
- gf_timefmt_FT);
- snprintf (buf + strlen (buf), sizeof buf - strlen (buf),
- ".%"GF_PRI_SUSECONDS, qr_inode->last_refresh.tv_usec);
+ if (!(qr_fd_ctx->opened
+ || qr_fd_ctx->open_in_transit)) {
+ need_open = 1;
+ qr_fd_ctx->open_in_transit = 1;
+ }
- gf_proc_dump_write ("last-cache-validation-time", "%s", buf);
+ if (qr_fd_ctx->opened) {
+ can_wind = 1;
+ } else {
+ stub = fop_fsync_stub (frame, qr_fsync_helper,
+ fd, flags);
+ if (stub == NULL) {
+ op_ret = -1;
+ op_errno = ENOMEM;
+ need_unwind = 1;
+ qr_fd_ctx->open_in_transit = 0;
+ goto unlock;
+ }
+
+ list_add_tail (&stub->list,
+ &qr_fd_ctx->waiting_ops);
+ }
+ }
+ unlock:
+ UNLOCK (&qr_fd_ctx->lock);
+ } else {
+ can_wind = 1;
}
- ret = 0;
out:
- return ret;
+ if (need_unwind) {
+ 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);
+ } else if (need_open) {
+ op_ret = qr_loc_fill (&loc, fd->inode, path);
+ if (op_ret == -1) {
+ qr_resume_pending_ops (qr_fd_ctx);
+ goto out;
+ }
+
+ STACK_WIND (frame, qr_open_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->open, &loc, open_flags,
+ fd, 0);
+
+ qr_loc_wipe (&loc);
+ }
+
+ return 0;
}
-int
-qr_priv_dump (xlator_t *this)
+int32_t
+qr_ftruncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct stat *prebuf,
+ struct stat *postbuf)
{
- qr_conf_t *conf = NULL;
- qr_private_t *priv = NULL;
- qr_inode_table_t *table = NULL;
- uint32_t file_count = 0;
- uint32_t i = 0;
- qr_inode_t *curr = NULL;
- uint64_t total_size = 0;
- char key_prefix[GF_DUMP_MAX_BUF_LEN];
-
- if (!this) {
- return -1;
+ int32_t ret = 0;
+ uint64_t value = 0;
+ qr_inode_t *qr_inode = NULL;
+ qr_local_t *local = NULL;
+ qr_private_t *priv = NULL;
+ qr_inode_table_t *table = NULL;
+
+ if (op_ret == -1) {
+ goto out;
}
priv = this->private;
- conf = &priv->conf;
+ table = &priv->table;
- if (!conf)
- return -1;
+ local = frame->local;
+ if ((local == NULL) || (local->fd == NULL)
+ || (local->fd->inode == NULL)) {
+ op_ret = -1;
+ op_errno = EINVAL;
+ goto out;
+ }
- table = &priv->table;
+ LOCK (&table->lock);
+ {
+ ret = inode_ctx_get (local->fd->inode, this, &value);
+ if (ret == 0) {
+ qr_inode = (qr_inode_t *)(long) value;
+
+ if (qr_inode) {
+ if (qr_inode->stbuf.st_size != postbuf->st_size)
+ {
+ inode_ctx_del (local->fd->inode, this,
+ NULL);
+ __qr_inode_free (qr_inode);
+ }
+ }
+ }
+ }
+ UNLOCK (&table->lock);
- gf_proc_dump_build_key (key_prefix, "xlator.performance.quick-read",
- "priv");
+out:
+ QR_STACK_UNWIND (ftruncate, frame, op_ret, op_errno, prebuf,
+ postbuf);
+ return 0;
+}
- 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);
+int32_t
+qr_ftruncate_helper (call_frame_t *frame, xlator_t *this, fd_t *fd,
+ off_t offset)
+{
+ STACK_WIND (frame, qr_ftruncate_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->ftruncate, fd, offset);
+ return 0;
+}
+
- if (!table) {
+int32_t
+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 = -1;
+ char need_open = 0, can_wind = 0, need_unwind = 0;
+
+ ret = fd_ctx_get (fd, this, &value);
+ if (ret == 0) {
+ qr_fd_ctx = (qr_fd_ctx_t *)(long)value;
+ }
+
+ local = CALLOC (1, sizeof (*local));
+ if (local == NULL) {
+ op_ret = -1;
+ op_errno = ENOMEM;
+ need_unwind = 1;
goto out;
- } else {
- for (i = 0; i < conf->max_pri; i++) {
- list_for_each_entry (curr, &table->lru[i], lru) {
- file_count++;
- total_size += curr->size;
+ }
+
+ local->fd = fd;
+ frame->local = local;
+
+ if (qr_fd_ctx) {
+ LOCK (&qr_fd_ctx->lock);
+ {
+ path = qr_fd_ctx->path;
+ flags = qr_fd_ctx->flags;
+
+ if (!(qr_fd_ctx->opened
+ || qr_fd_ctx->open_in_transit)) {
+ need_open = 1;
+ qr_fd_ctx->open_in_transit = 1;
+ }
+
+ if (qr_fd_ctx->opened) {
+ can_wind = 1;
+ } else {
+ stub = fop_ftruncate_stub (frame,
+ qr_ftruncate_helper,
+ fd, offset);
+ if (stub == NULL) {
+ op_ret = -1;
+ op_errno = ENOMEM;
+ need_unwind = 1;
+ qr_fd_ctx->open_in_transit = 0;
+ goto unlock;
+ }
+
+ list_add_tail (&stub->list,
+ &qr_fd_ctx->waiting_ops);
}
}
+ unlock:
+ UNLOCK (&qr_fd_ctx->lock);
+ } else {
+ can_wind = 1;
}
- gf_proc_dump_write ("total_files_cached", "%d", file_count);
- gf_proc_dump_write ("total_cache_used", "%d", total_size);
-
out:
+ if (need_unwind) {
+ QR_STACK_UNWIND (ftruncate, frame, op_ret, op_errno, NULL,
+ NULL);
+ } else if (can_wind) {
+ STACK_WIND (frame, qr_ftruncate_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->ftruncate, fd, offset);
+ } else if (need_open) {
+ op_ret = qr_loc_fill (&loc, fd->inode, path);
+ if (op_ret == -1) {
+ qr_resume_pending_ops (qr_fd_ctx);
+ goto out;
+ }
+
+ STACK_WIND (frame, qr_open_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->open, &loc, flags, fd, 0);
+
+ qr_loc_wipe (&loc);
+ }
+
return 0;
}
int32_t
-mem_acct_init (xlator_t *this)
+qr_lk_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret,
+ int32_t op_errno, struct flock *lock)
{
- int ret = -1;
+ 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 flock *lock)
+{
+ STACK_WIND (frame, qr_lk_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->lk, fd, cmd, lock);
+
+ return 0;
+}
- if (!this)
- return ret;
- ret = xlator_mem_acct_init (this, gf_qr_mt_end + 1);
+int32_t
+qr_lk (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t cmd,
+ struct 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 = -1;
+ char need_open = 0, can_wind = 0, need_unwind = 0;
+
+ ret = fd_ctx_get (fd, this, &value);
+ if (ret == 0) {
+ qr_fd_ctx = (qr_fd_ctx_t *)(long)value;
+ }
+
+ if (qr_fd_ctx) {
+ LOCK (&qr_fd_ctx->lock);
+ {
+ path = qr_fd_ctx->path;
+ flags = qr_fd_ctx->flags;
+
+ if (!(qr_fd_ctx->opened
+ || qr_fd_ctx->open_in_transit)) {
+ need_open = 1;
+ qr_fd_ctx->open_in_transit = 1;
+ }
- if (ret != 0) {
- gf_log (this->name, GF_LOG_ERROR, "Memory accounting init"
- "failed");
- return ret;
+ if (qr_fd_ctx->opened) {
+ can_wind = 1;
+ } else {
+ stub = fop_lk_stub (frame, qr_lk_helper, fd,
+ cmd, lock);
+ if (stub == NULL) {
+ op_ret = -1;
+ op_errno = ENOMEM;
+ need_unwind = 1;
+ qr_fd_ctx->open_in_transit = 0;
+ goto unlock;
+ }
+
+ list_add_tail (&stub->list,
+ &qr_fd_ctx->waiting_ops);
+ }
+ }
+ unlock:
+ UNLOCK (&qr_fd_ctx->lock);
+ } else {
+ can_wind = 1;
}
- return ret;
+out:
+ if (need_unwind) {
+ 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);
+ } else if (need_open) {
+ op_ret = qr_loc_fill (&loc, fd->inode, path);
+ if (op_ret == -1) {
+ qr_resume_pending_ops (qr_fd_ctx);
+ goto out;
+ }
+
+ STACK_WIND (frame, qr_open_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->open, &loc, flags, fd, 0);
+
+ qr_loc_wipe (&loc);
+ }
+
+ return 0;
}
-static gf_boolean_t
-check_cache_size_ok (xlator_t *this, int64_t cache_size)
+int32_t
+qr_release (xlator_t *this, fd_t *fd)
{
- int 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");
- goto out;
+ qr_fd_ctx_t *qr_fd_ctx = NULL;
+ int32_t ret = 0;
+ uint64_t value = 0;
+
+ ret = fd_ctx_del (fd, this, &value);
+ if (ret == 0) {
+ qr_fd_ctx = (qr_fd_ctx_t *)(long) value;
+ if (qr_fd_ctx) {
+ qr_fd_ctx_free (qr_fd_ctx);
+ }
}
- total_mem = get_mem_size ();
- if (-1 == total_mem)
- max_cache_size = opt->max;
- else
- max_cache_size = total_mem;
+ return 0;
+}
+
- 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);
- goto out;
+int32_t
+qr_forget (xlator_t *this, inode_t *inode)
+{
+ qr_inode_t *qr_inode = NULL;
+ uint64_t value = 0;
+ int32_t ret = -1;
+ qr_private_t *priv = NULL;
+
+ priv = this->private;
+
+ LOCK (&priv->table.lock);
+ {
+ ret = inode_ctx_del (inode, this, &value);
+ if (ret == 0) {
+ qr_inode = (qr_inode_t *)(long) value;
+ __qr_inode_free (qr_inode);
+ }
}
-out:
- return ret;
+ UNLOCK (&priv->table.lock);
+
+ return 0;
}
int
-reconfigure (xlator_t *this, dict_t *options)
+qr_priv_dump (xlator_t *this)
{
- int32_t ret = -1;
- qr_private_t *priv = NULL;
- qr_conf_t *conf = NULL;
- uint64_t cache_size_new = 0;
+ qr_conf_t *conf = NULL;
+ char key[GF_DUMP_MAX_BUF_LEN];
+ char key_prefix[GF_DUMP_MAX_BUF_LEN];
+ qr_private_t *priv = NULL;
- 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);
+ if (!this)
+ return -1;
priv = this->private;
-
conf = &priv->conf;
if (!conf) {
- goto out;
+ gf_log (this->name, GF_LOG_WARNING,
+ "conf null in xlator");
+ return -1;
}
- GF_OPTION_RECONF ("cache-timeout", conf->cache_timeout, options, int32,
- out);
+ gf_proc_dump_build_key (key_prefix,
+ "xlator.performance.quick-read",
+ "priv");
- GF_OPTION_RECONF ("cache-size", cache_size_new, options, size_uint64, 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;
- }
- conf->cache_size = cache_size_new;
+ gf_proc_dump_add_section (key_prefix);
- ret = 0;
-out:
- return ret;
+ 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);
+
+ return 0;
}
int32_t
qr_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 *priority_str = NULL;
- char *pattern = NULL;
- char *priority = NULL;
- char *string = NULL;
- struct qr_priority *curr = NULL, *tmp = NULL;
-
- GF_VALIDATE_OR_GOTO ("quick-read", opt_str, out);
- GF_VALIDATE_OR_GOTO ("quick-read", first, out);
-
- string = gf_strdup (opt_str);
+ int32_t max_pri = 1;
+ char *tmp_str = NULL;
+ char *tmp_str1 = NULL;
+ char *tmp_str2 = NULL;
+ char *dup_str = NULL;
+ char *priority_str = NULL;
+ char *pattern = NULL;
+ char *priority = NULL;
+ char *string = NULL;
+ struct qr_priority *curr = NULL, *tmp = NULL;
+
+ string = strdup (opt_str);
if (string == NULL) {
max_pri = -1;
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
- */
- priority_str = strtok_r (string, ",", &tmp_str);
- while (priority_str) {
- curr = GF_CALLOC (1, sizeof (*curr), gf_qr_mt_qr_priority_t);
+
+ /* 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
+ */
+ priority_str = strtok_r (string, ",", &tmp_str);
+ while (priority_str) {
+ curr = CALLOC (1, sizeof (*curr));
if (curr == NULL) {
max_pri = -1;
goto out;
}
- list_add_tail (&curr->list, first);
+ list_add_tail (&curr->list, first);
- dup_str = gf_strdup (priority_str);
+ dup_str = strdup (priority_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 ("quick-read", GF_LOG_TRACE,
- "quick-read priority : pattern %s : priority %s",
- pattern,
- priority);
+ gf_log ("quick-read", GF_LOG_TRACE,
+ "quick-read priority : pattern %s : priority %s",
+ pattern,
+ priority);
- curr->pattern = gf_strdup (pattern);
+ curr->pattern = 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);
+ free (dup_str);
dup_str = NULL;
- priority_str = strtok_r (NULL, ",", &tmp_str);
- }
+ priority_str = strtok_r (NULL, ",", &tmp_str);
+ }
out:
- GF_FREE (string);
+ if (string != NULL) {
+ free (string);
+ }
- GF_FREE (dup_str);
+ if (dup_str != NULL) {
+ free (dup_str);
+ }
if (max_pri == -1) {
list_for_each_entry_safe (curr, tmp, first, list) {
list_del_init (&curr->list);
- GF_FREE (curr->pattern);
- GF_FREE (curr);
+ free (curr->pattern);
+ free (curr);
}
}
- return max_pri;
+ return max_pri;
}
-int32_t
+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;
-
+
if (!this->children || this->children->next) {
gf_log (this->name, GF_LOG_ERROR,
"FATAL: volume (%s) not configured with exactly one "
- "child", this->name);
+ "child", this->name);
return -1;
}
- 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 ");
+ }
- priv = GF_CALLOC (1, sizeof (*priv), gf_qr_mt_qr_private_t);
+ priv = CALLOC (1, sizeof (*priv));
if (priv == NULL) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "out of memory");
ret = -1;
goto out;
}
LOCK_INIT (&priv->table.lock);
- conf = &priv->conf;
- GF_OPTION_INIT ("max-file-size", conf->max_file_size, size_uint64, out);
+ conf = &priv->conf;
- GF_OPTION_INIT ("cache-timeout", conf->cache_timeout, int32, out);
+ 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 ("cache-size", conf->cache_size, size_uint64, out);
- if (!check_cache_size_ok (this, conf->cache_size)) {
- ret = -1;
- goto 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;
+ }
}
- INIT_LIST_HEAD (&conf->priority_list);
- conf->max_pri = 1;
- if (dict_get (this->options, "priority")) {
- char *option_list = data_to_str (dict_get (this->options,
- "priority"));
- gf_log (this->name, GF_LOG_TRACE,
- "option path %s", option_list);
- /* parse the list of pattern:priority */
- conf->max_pri = qr_get_priority_list (option_list,
- &conf->priority_list);
+ 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;
+ }
+ }
- if (conf->max_pri == -1) {
+ INIT_LIST_HEAD (&conf->priority_list);
+ conf->max_pri = 1;
+ if (dict_get (this->options, "priority")) {
+ char *option_list = data_to_str (dict_get (this->options,
+ "priority"));
+ gf_log (this->name, GF_LOG_TRACE,
+ "option path %s", option_list);
+ /* parse the list of pattern:priority */
+ conf->max_pri = qr_get_priority_list (option_list,
+ &conf->priority_list);
+
+ if (conf->max_pri == -1) {
goto out;
}
conf->max_pri ++;
- }
+ }
- priv->table.lru = GF_CALLOC (conf->max_pri, sizeof (*priv->table.lru),
- gf_common_mt_list_head);
+ priv->table.lru = CALLOC (conf->max_pri,
+ sizeof (*priv->table.lru));
if (priv->table.lru == NULL) {
ret = -1;
+ gf_log (this->name, GF_LOG_ERROR, "out of memory");
goto out;
}
@@ -1033,7 +2564,7 @@ init (xlator_t *this)
this->private = priv;
out:
if ((ret == -1) && priv) {
- GF_FREE (priv);
+ FREE (priv);
}
return ret;
@@ -1041,103 +2572,60 @@ 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;
}
+
struct xlator_fops fops = {
- .lookup = qr_lookup,
- .readdirp = qr_readdirp,
+ .lookup = qr_lookup,
.open = qr_open,
.readv = qr_readv,
- .writev = qr_writev,
- .truncate = qr_truncate,
- .ftruncate = qr_ftruncate
+ .writev = qr_writev,
+ .fstat = qr_fstat,
+ .fsetxattr = qr_fsetxattr,
+ .fgetxattr = qr_fgetxattr,
+ .flush = qr_flush,
+ .fentrylk = qr_fentrylk,
+ .finodelk = qr_finodelk,
+ .fsync = qr_fsync,
+ .ftruncate = qr_ftruncate,
+ .lk = qr_lk,
+ .fsetattr = qr_fsetattr,
};
+
+struct xlator_mops mops = {
+};
+
+
struct xlator_cbks cbks = {
.forget = qr_forget,
+ .release = qr_release,
};
struct xlator_dumpops dumpops = {
.priv = qr_priv_dump,
- .inodectx = qr_inodectx_dump,
};
struct volume_options options[] = {
- { .key = {"priority"},
- .type = GF_OPTION_TYPE_ANY
- },
- { .key = {"cache-size"},
- .type = GF_OPTION_TYPE_SIZET,
- .min = 0,
- .max = 32 * GF_UNIT_GB,
- .default_value = "128MB",
- .description = "Size of the read cache."
- },
{ .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",
},
- { .key = {NULL} }
+ { .key = {"priority"},
+ .type = GF_OPTION_TYPE_ANY
+ },
+ { .key = {"cache-size"},
+ .type = GF_OPTION_TYPE_SIZET,
+ .min = 0,
+ .max = 6 * GF_UNIT_GB,
+ },
};
diff --git a/xlators/performance/quick-read/src/quick-read.h b/xlators/performance/quick-read/src/quick-read.h
index 6f0a0541731..8bf966c6397 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 General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that 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 __QUICK_READ_H
@@ -32,22 +41,42 @@
#include <sys/stat.h>
#include <unistd.h>
#include <fnmatch.h>
-#include "quick-read-mem-types.h"
+#define GLUSTERFS_CONTENT_KEY "glusterfs.content"
+
+struct qr_fd_ctx {
+ char opened;
+ char disabled;
+ char open_in_transit;
+ char *path;
+ int flags;
+ struct list_head waiting_ops;
+ gf_lock_t lock;
+};
+typedef struct qr_fd_ctx qr_fd_ctx_t;
+
+struct qr_local {
+ char is_open;
+ char just_validated;
+ char *path;
+ 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;
struct qr_inode {
- void *data;
- size_t size;
+ dict_t *xattr;
+ inode_t *inode;
int priority;
- uint32_t ia_mtime;
- uint32_t ia_mtime_nsec;
- struct iatt buf;
- struct timeval last_refresh;
+ struct stat stbuf;
+ struct timeval tv;
struct list_head lru;
};
typedef struct qr_inode qr_inode_t;
-
struct qr_priority {
char *pattern;
int32_t priority;
@@ -77,5 +106,14 @@ struct qr_private {
};
typedef struct qr_private qr_private_t;
+void qr_local_free (qr_local_t *local);
+
+#define QR_STACK_UNWIND(op, frame, params ...) do { \
+ qr_local_t *__local = frame->local; \
+ frame->local = NULL; \
+ STACK_UNWIND_STRICT (op, frame, params); \
+ qr_local_free (__local); \
+} while (0)
+
#endif /* #ifndef __QUICK_READ_H */
diff --git a/xlators/performance/read-ahead/src/Makefile.am b/xlators/performance/read-ahead/src/Makefile.am
index be80ae7ac68..7bb90228227 100644
--- a/xlators/performance/read-ahead/src/Makefile.am
+++ b/xlators/performance/read-ahead/src/Makefile.am
@@ -1,15 +1,14 @@
xlator_LTLIBRARIES = read-ahead.la
xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/performance
-read_ahead_la_LDFLAGS = -module -avoid-version
+read_ahead_la_LDFLAGS = -module -avoidversion
read_ahead_la_SOURCES = read-ahead.c page.c
read_ahead_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la
-noinst_HEADERS = read-ahead.h read-ahead-mem-types.h
+noinst_HEADERS = read-ahead.h
-AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src
-
-AM_CFLAGS = -Wall $(GF_CFLAGS)
+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/performance/read-ahead/src/page.c b/xlators/performance/read-ahead/src/page.c
index 6e5b52c5e27..07ab84ed8d7 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-2009 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 General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that 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
@@ -23,88 +32,79 @@
ra_page_t *
ra_page_get (ra_file_t *file, off_t offset)
{
- ra_page_t *page = NULL;
- off_t rounded_offset = 0;
+ ra_page_t *page = NULL;
+ off_t rounded_offset = 0;
- GF_VALIDATE_OR_GOTO ("read-ahead", file, out);
+ page = file->pages.next;
+ rounded_offset = floor (offset, file->page_size);
- page = file->pages.next;
- rounded_offset = floor (offset, file->page_size);
+ while (page != &file->pages && page->offset < rounded_offset)
+ page = page->next;
- while (page != &file->pages && page->offset < rounded_offset)
- page = page->next;
+ if (page == &file->pages || page->offset != rounded_offset)
+ page = NULL;
- if (page == &file->pages || page->offset != rounded_offset)
- page = NULL;
-
-out:
- return page;
+ return page;
}
ra_page_t *
ra_page_create (ra_file_t *file, off_t offset)
{
- ra_page_t *page = NULL;
- off_t rounded_offset = 0;
- ra_page_t *newpage = NULL;
+ ra_page_t *page = NULL;
+ off_t rounded_offset = 0;
+ ra_page_t *newpage = NULL;
- GF_VALIDATE_OR_GOTO ("read-ahead", file, out);
+ page = file->pages.next;
+ rounded_offset = floor (offset, file->page_size);
- page = file->pages.next;
- rounded_offset = floor (offset, file->page_size);
+ while (page != &file->pages && page->offset < rounded_offset)
+ page = page->next;
- while (page != &file->pages && page->offset < rounded_offset)
- page = page->next;
-
- if (page == &file->pages || page->offset != rounded_offset) {
- newpage = GF_CALLOC (1, sizeof (*newpage), gf_ra_mt_ra_page_t);
- if (!newpage) {
- goto out;
- }
+ if (page == &file->pages || page->offset != rounded_offset) {
+ newpage = CALLOC (1, sizeof (*newpage));
+ if (!newpage)
+ return NULL;
- newpage->offset = rounded_offset;
- newpage->prev = page->prev;
- newpage->next = page;
- newpage->file = file;
- page->prev->next = newpage;
- page->prev = newpage;
+ newpage->offset = rounded_offset;
+ newpage->prev = page->prev;
+ newpage->next = page;
+ newpage->file = file;
+ page->prev->next = newpage;
+ page->prev = newpage;
- page = newpage;
- }
+ page = newpage;
+ }
-out:
- return page;
+ return page;
}
void
ra_wait_on_page (ra_page_t *page, call_frame_t *frame)
{
- ra_waitq_t *waitq = NULL;
- ra_local_t *local = NULL;
-
- GF_VALIDATE_OR_GOTO ("read-ahead", frame, out);
- GF_VALIDATE_OR_GOTO (frame->this->name, page, out);
-
- local = frame->local;
-
- waitq = GF_CALLOC (1, sizeof (*waitq), gf_ra_mt_ra_waitq_t);
- if (!waitq) {
+ ra_waitq_t *waitq = NULL;
+ ra_local_t *local = NULL;
+
+ local = frame->local;
+ waitq = CALLOC (1, sizeof (*waitq));
+ if (!waitq) {
+ gf_log (frame->this->name, GF_LOG_ERROR,
+ "out of memory");
local->op_ret = -1;
local->op_errno = ENOMEM;
goto out;
- }
+ }
- waitq->data = frame;
- waitq->next = page->waitq;
- page->waitq = waitq;
+ waitq->data = frame;
+ waitq->next = page->waitq;
+ page->waitq = waitq;
- ra_local_lock (local);
- {
- local->wait_count++;
- }
- ra_local_unlock (local);
+ ra_local_lock (local);
+ {
+ local->wait_count++;
+ }
+ ra_local_unlock (local);
out:
return;
@@ -114,146 +114,118 @@ out:
void
ra_waitq_return (ra_waitq_t *waitq)
{
- ra_waitq_t *trav = NULL;
- ra_waitq_t *next = NULL;
- call_frame_t *frame = NULL;
+ ra_waitq_t *trav = NULL;
+ ra_waitq_t *next = NULL;
+ call_frame_t *frame = NULL;
- for (trav = waitq; trav; trav = next) {
- next = trav->next;
-
- frame = trav->data;
- ra_frame_return (frame);
- GF_FREE (trav);
- }
+ for (trav = waitq; trav; trav = next) {
+ next = trav->next;
- return;
+ frame = trav->data;
+ ra_frame_return (frame);
+ free (trav);
+ }
}
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 op_ret, int32_t op_errno, struct iovec *vector,
+ int32_t count, struct stat *stbuf, struct iobref *iobref)
{
- ra_local_t *local = NULL;
- off_t pending_offset = 0;
- ra_file_t *file = NULL;
- ra_page_t *page = NULL;
- ra_waitq_t *waitq = NULL;
- fd_t *fd = NULL;
- uint64_t tmp_file = 0;
-
- GF_ASSERT (frame);
-
- local = frame->local;
- fd = local->fd;
-
- fd_ctx_get (fd, this, &tmp_file);
-
- file = (ra_file_t *)(long)tmp_file;
- pending_offset = local->pending_offset;
-
- if (file == NULL) {
- gf_log (this->name, GF_LOG_WARNING,
- "read-ahead context not set in fd (%p)", fd);
- op_ret = -1;
- op_errno = EBADF;
- goto out;
- }
-
- ra_file_lock (file);
- {
- if (op_ret >= 0)
- file->stbuf = *stbuf;
-
- page = ra_page_get (file, pending_offset);
-
- if (!page) {
- gf_log (this->name, GF_LOG_TRACE,
- "wasted copy: %"PRId64"[+%"PRId64"] file=%p",
- pending_offset, file->page_size, file);
- 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);
- }
-
- page->vector = iov_dup (vector, count);
+ ra_local_t *local = NULL;
+ off_t pending_offset = 0;
+ ra_file_t *file = NULL;
+ ra_page_t *page = NULL;
+ off_t trav_offset = 0;
+ size_t payload_size = 0;
+ ra_waitq_t *waitq = NULL;
+ fd_t *fd = NULL;
+ int ret = 0;
+ uint64_t tmp_file = 0;
+
+ local = frame->local;
+ fd = local->fd;
+
+ ret = fd_ctx_get (fd, this, &tmp_file);
+
+ file = (ra_file_t *)(long)tmp_file;
+ pending_offset = local->pending_offset;
+ trav_offset = pending_offset;
+ payload_size = op_ret;
+
+ ra_file_lock (file);
+ {
+ if (op_ret >= 0)
+ file->stbuf = *stbuf;
+
+ 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_DEBUG,
+ "wasted copy: %"PRId64"[+%"PRId64"] file=%p",
+ pending_offset, file->page_size, file);
+ goto unlock;
+ }
+
+ if (page->vector) {
+ iobref_unref (page->iobref);
+ free (page->vector);
+ }
+
+ page->vector = iov_dup (vector, count);
if (page->vector == NULL) {
waitq = ra_page_error (page, -1, ENOMEM);
goto unlock;
}
- page->count = count;
- page->iobref = iobref_ref (iobref);
- page->ready = 1;
+ page->count = count;
+ page->iobref = iobref_ref (iobref);
+ page->ready = 1;
- page->size = iov_length (vector, count);
+ page->size = iov_length (vector, count);
- waitq = ra_page_wakeup (page);
- }
+ waitq = ra_page_wakeup (page);
+ }
unlock:
- ra_file_unlock (file);
+ ra_file_unlock (file);
- ra_waitq_return (waitq);
+ ra_waitq_return (waitq);
- fd_unref (local->fd);
+ fd_unref (local->fd);
- mem_put (frame->local);
- frame->local = NULL;
+ free (frame->local);
+ frame->local = NULL;
-out:
- STACK_DESTROY (frame->root);
- return 0;
+ STACK_DESTROY (frame->root);
+ return 0;
}
void
ra_page_fault (ra_file_t *file, call_frame_t *frame, off_t offset)
{
- call_frame_t *fault_frame = NULL;
- ra_local_t *fault_local = NULL;
- ra_page_t *page = NULL;
- ra_waitq_t *waitq = NULL;
- int32_t op_ret = -1, op_errno = -1;
-
- GF_VALIDATE_OR_GOTO ("read-ahead", frame, out);
- GF_VALIDATE_OR_GOTO (frame->this->name, file, out);
-
- fault_frame = copy_frame (frame);
+ call_frame_t *fault_frame = NULL;
+ ra_local_t *fault_local = NULL, *local = NULL;
+ ra_page_t *page = NULL;
+ ra_waitq_t *waitq = NULL;
+ int32_t op_ret = -1, op_errno = -1;
+
+ local = frame->local;
+ fault_frame = copy_frame (frame);
if (fault_frame == NULL) {
op_ret = -1;
op_errno = ENOMEM;
goto err;
}
- fault_local = mem_get0 (THIS->local_pool);
+ fault_local = CALLOC (1, sizeof (ra_local_t));
if (fault_local == NULL) {
STACK_DESTROY (fault_frame->root);
op_ret = -1;
@@ -261,18 +233,18 @@ ra_page_fault (ra_file_t *file, call_frame_t *frame, off_t offset)
goto err;
}
- fault_frame->local = fault_local;
- fault_local->pending_offset = offset;
- fault_local->pending_size = file->page_size;
+ fault_frame->local = fault_local;
+ fault_local->pending_offset = offset;
+ fault_local->pending_size = file->page_size;
- fault_local->fd = fd_ref (file->fd);
+ fault_local->fd = fd_ref (file->fd);
- 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);
+ 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);
- return;
+ return;
err:
ra_file_lock (file);
@@ -283,88 +255,80 @@ err:
op_errno);
}
ra_file_unlock (file);
-
+
if (waitq != NULL) {
ra_waitq_return (waitq);
}
-
-out:
- return;
}
-
void
ra_frame_fill (ra_page_t *page, call_frame_t *frame)
{
- ra_local_t *local = NULL;
- ra_fill_t *fill = NULL;
- off_t src_offset = 0;
- off_t dst_offset = 0;
- ssize_t copy_size = 0;
- ra_fill_t *new = NULL;
-
- GF_VALIDATE_OR_GOTO ("read-ahead", frame, out);
- GF_VALIDATE_OR_GOTO (frame->this->name, page, out);
-
- local = frame->local;
- fill = &local->fill;
-
- if (local->op_ret != -1 && page->size) {
- if (local->offset > page->offset)
- src_offset = local->offset - page->offset;
- else
- dst_offset = page->offset - local->offset;
-
- copy_size = min (page->size - src_offset,
- local->size - dst_offset);
-
- if (copy_size < 0) {
- /* if page contains fewer bytes and the required offset
- is beyond the page size in the page */
- copy_size = src_offset = 0;
- }
-
- fill = fill->next;
- while (fill != &local->fill) {
- if (fill->offset > page->offset) {
- break;
- }
- fill = fill->next;
- }
+ ra_local_t *local = NULL;
+ ra_fill_t *fill = NULL;
+ off_t src_offset = 0;
+ off_t dst_offset = 0;
+ ssize_t copy_size = 0;
+ ra_fill_t *new = NULL;
+
+ local = frame->local;
+ fill = &local->fill;
+
+ if (local->op_ret != -1 && page->size) {
+ if (local->offset > page->offset)
+ src_offset = local->offset - page->offset;
+ else
+ dst_offset = page->offset - local->offset;
+
+ copy_size = min (page->size - src_offset,
+ local->size - dst_offset);
+
+ if (copy_size < 0) {
+ /* if page contains fewer bytes and the required offset
+ is beyond the page size in the page */
+ copy_size = src_offset = 0;
+ }
+
+ fill = fill->next;
+ while (fill != &local->fill) {
+ if (fill->offset > page->offset) {
+ break;
+ }
+ fill = fill->next;
+ }
- new = GF_CALLOC (1, sizeof (*new), gf_ra_mt_ra_fill_t);
+ new = CALLOC (1, sizeof (*new));
if (new == NULL) {
local->op_ret = -1;
local->op_errno = ENOMEM;
goto out;
}
- new->offset = page->offset;
- new->size = copy_size;
- new->iobref = iobref_ref (page->iobref);
- new->count = iov_subset (page->vector, page->count,
- src_offset, src_offset+copy_size,
- NULL);
- new->vector = GF_CALLOC (new->count, sizeof (struct iovec),
- gf_ra_mt_iovec);
+ new->offset = page->offset;
+ new->size = copy_size;
+ new->iobref = iobref_ref (page->iobref);
+ new->count = iov_subset (page->vector, page->count,
+ src_offset, src_offset+copy_size,
+ NULL);
+ new->vector = CALLOC (new->count, sizeof (struct iovec));
if (new->vector == NULL) {
local->op_ret = -1;
local->op_errno = ENOMEM;
- GF_FREE (new);
+ FREE (new);
goto out;
}
- new->count = iov_subset (page->vector, page->count,
- src_offset, src_offset+copy_size,
- new->vector);
+ new->count = iov_subset (page->vector, page->count,
+ src_offset, src_offset+copy_size,
+ new->vector);
- new->next = fill;
- new->prev = new->next->prev;
- new->next->prev = new;
- new->prev->next = new;
+ new->next = fill;
+ new->prev = new->next->prev;
+ new->next->prev = new;
+ new->prev->next = new;
- local->op_ret += copy_size;
- }
+ local->op_ret += copy_size;
+ }
out:
return;
@@ -374,36 +338,35 @@ out:
void
ra_frame_unwind (call_frame_t *frame)
{
- ra_local_t *local = NULL;
- ra_fill_t *fill = NULL;
- int32_t count = 0;
- struct iovec *vector = NULL;
- int32_t copied = 0;
- struct iobref *iobref = NULL;
- ra_fill_t *next = NULL;
- fd_t *fd = NULL;
- ra_file_t *file = NULL;
- uint64_t tmp_file = 0;
-
- GF_VALIDATE_OR_GOTO ("read-ahead", frame, out);
-
- local = frame->local;
- fill = local->fill.next;
-
- iobref = iobref_new ();
+ ra_local_t *local = NULL;
+ ra_fill_t *fill = NULL;
+ int32_t count = 0;
+ struct iovec *vector;
+ int32_t copied = 0;
+ struct iobref *iobref = NULL;
+ ra_fill_t *next = NULL;
+ fd_t *fd = NULL;
+ ra_file_t *file = NULL;
+ int ret = 0;
+ uint64_t tmp_file = 0;
+
+ local = frame->local;
+ fill = local->fill.next;
+
+ iobref = iobref_new ();
if (iobref == NULL) {
local->op_ret = -1;
local->op_errno = ENOMEM;
}
- frame->local = NULL;
+ frame->local = NULL;
- while (fill != &local->fill) {
- count += fill->count;
- fill = fill->next;
- }
+ while (fill != &local->fill) {
+ count += fill->count;
+ fill = fill->next;
+ }
- vector = GF_CALLOC (count, sizeof (*vector), gf_ra_mt_iovec);
+ vector = CALLOC (count, sizeof (*vector));
if (vector == NULL) {
local->op_ret = -1;
local->op_errno = ENOMEM;
@@ -411,48 +374,42 @@ ra_frame_unwind (call_frame_t *frame)
iobref = NULL;
}
- fill = local->fill.next;
+ fill = local->fill.next;
- while (fill != &local->fill) {
- next = fill->next;
+ while (fill != &local->fill) {
+ next = fill->next;
if ((vector != NULL) && (iobref != NULL)) {
memcpy (((char *)vector) + copied, fill->vector,
fill->count * sizeof (*vector));
-
+
copied += (fill->count * sizeof (*vector));
- if (iobref_merge (iobref, fill->iobref)) {
- local->op_ret = -1;
- local->op_errno = ENOMEM;
- iobref_unref (iobref);
- iobref = NULL;
- }
+ iobref_merge (iobref, fill->iobref);
}
- fill->next->prev = fill->prev;
- fill->prev->next = fill->prev;
+ fill->next->prev = fill->prev;
+ fill->prev->next = fill->prev;
- iobref_unref (fill->iobref);
- GF_FREE (fill->vector);
- GF_FREE (fill);
+ iobref_unref (fill->iobref);
+ free (fill->vector);
+ free (fill);
- fill = next;
- }
+ fill = next;
+ }
- fd = local->fd;
- fd_ctx_get (fd, frame->this, &tmp_file);
- file = (ra_file_t *)(long)tmp_file;
+ fd = local->fd;
+ ret = fd_ctx_get (fd, frame->this, &tmp_file);
+ file = (ra_file_t *)(long)tmp_file;
- STACK_UNWIND_STRICT (readv, frame, local->op_ret, local->op_errno,
- vector, count, &file->stbuf, iobref, NULL);
+ STACK_UNWIND_STRICT (readv, frame, local->op_ret, local->op_errno,
+ vector, count, &file->stbuf, iobref);
- iobref_unref (iobref);
- pthread_mutex_destroy (&local->local_lock);
- mem_put (local);
- GF_FREE (vector);
+ iobref_unref (iobref);
+ pthread_mutex_destroy (&local->local_lock);
+ free (local);
+ free (vector);
-out:
- return;
+ return;
}
/*
@@ -463,28 +420,25 @@ out:
void
ra_frame_return (call_frame_t *frame)
{
- ra_local_t *local = NULL;
- int32_t wait_count = 0;
+ ra_local_t *local = NULL;
+ int32_t wait_count = 0;
- GF_VALIDATE_OR_GOTO ("read-ahead", frame, out);
+ local = frame->local;
+ assert (local->wait_count > 0);
- local = frame->local;
- GF_ASSERT (local->wait_count > 0);
-
- ra_local_lock (local);
- {
- wait_count = --local->wait_count;
- }
- ra_local_unlock (local);
+ ra_local_lock (local);
+ {
+ wait_count = --local->wait_count;
+ }
+ ra_local_unlock (local);
- if (!wait_count)
- ra_frame_unwind (frame);
+ if (!wait_count)
+ ra_frame_unwind (frame);
-out:
- return;
+ return;
}
-/*
+/*
* ra_page_wakeup -
* @page:
*
@@ -492,24 +446,19 @@ out:
ra_waitq_t *
ra_page_wakeup (ra_page_t *page)
{
- ra_waitq_t *waitq = NULL, *trav = NULL;
- call_frame_t *frame = NULL;
+ ra_waitq_t *waitq = NULL, *trav = NULL;
+ call_frame_t *frame;
- GF_VALIDATE_OR_GOTO ("read-ahead", page, out);
+ waitq = page->waitq;
+ page->waitq = NULL;
- waitq = page->waitq;
- page->waitq = NULL;
+ trav = waitq;
+ for (trav = waitq; trav; trav = trav->next) {
+ frame = trav->data;
+ ra_frame_fill (page, frame);
+ }
- for (trav = waitq; trav; trav = trav->next) {
- frame = trav->data;
- ra_frame_fill (page, frame);
- }
-
- if (page->stale) {
- ra_page_purge (page);
- }
-out:
- return waitq;
+ return waitq;
}
/*
@@ -520,20 +469,14 @@ out:
void
ra_page_purge (ra_page_t *page)
{
- GF_VALIDATE_OR_GOTO ("read-ahead", page, out);
-
- page->prev->next = page->next;
- page->next->prev = page->prev;
-
- if (page->iobref) {
- iobref_unref (page->iobref);
- }
-
- GF_FREE (page->vector);
- GF_FREE (page);
-
-out:
- return;
+ page->prev->next = page->next;
+ page->next->prev = page->prev;
+
+ if (page->iobref) {
+ iobref_unref (page->iobref);
+ }
+ free (page->vector);
+ free (page);
}
/*
@@ -546,33 +489,32 @@ out:
ra_waitq_t *
ra_page_error (ra_page_t *page, int32_t op_ret, int32_t op_errno)
{
- ra_waitq_t *waitq = NULL;
- ra_waitq_t *trav = NULL;
- call_frame_t *frame = NULL;
- ra_local_t *local = NULL;
- GF_VALIDATE_OR_GOTO ("read-ahead", page, out);
+ ra_waitq_t *waitq = NULL;
+ ra_waitq_t *trav = NULL;
+ call_frame_t *frame = NULL;
+ ra_local_t *local = NULL;
- waitq = page->waitq;
- page->waitq = NULL;
+ waitq = page->waitq;
+ page->waitq = NULL;
- for (trav = waitq; trav; trav = trav->next) {
- frame = trav->data;
+ trav = waitq;
+ for (trav = waitq; trav; trav = trav->next) {
+ frame = trav->data;
- local = frame->local;
- if (local->op_ret != -1) {
- local->op_ret = op_ret;
- local->op_errno = op_errno;
- }
- }
+ local = frame->local;
+ if (local->op_ret != -1) {
+ local->op_ret = op_ret;
+ local->op_errno = op_errno;
+ }
+ }
- ra_page_purge (page);
+ ra_page_purge (page);
-out:
- return waitq;
+ return waitq;
}
-/*
+/*
* ra_file_destroy -
* @file:
*
@@ -580,29 +522,24 @@ out:
void
ra_file_destroy (ra_file_t *file)
{
- ra_conf_t *conf = NULL;
- ra_page_t *trav = NULL;
-
- GF_VALIDATE_OR_GOTO ("read-ahead", file, out);
-
- conf = file->conf;
-
- ra_conf_lock (conf);
- {
- file->prev->next = file->next;
- file->next->prev = file->prev;
- }
- ra_conf_unlock (conf);
-
- trav = file->pages.next;
- while (trav != &file->pages) {
- ra_page_error (trav, -1, EINVAL);
- trav = file->pages.next;
- }
-
- pthread_mutex_destroy (&file->file_lock);
- GF_FREE (file);
-
-out:
- return;
+ ra_conf_t *conf = NULL;
+ ra_page_t *trav = NULL;
+
+ conf = file->conf;
+
+ ra_conf_lock (conf);
+ {
+ file->prev->next = file->next;
+ file->next->prev = file->prev;
+ }
+ ra_conf_unlock (conf);
+
+ trav = file->pages.next;
+ while (trav != &file->pages) {
+ ra_page_error (trav, -1, EINVAL);
+ trav = file->pages.next;
+ }
+
+ pthread_mutex_destroy (&file->file_lock);
+ free (file);
}
diff --git a/xlators/performance/read-ahead/src/read-ahead-mem-types.h b/xlators/performance/read-ahead/src/read-ahead-mem-types.h
deleted file mode 100644
index 219e2928919..00000000000
--- a/xlators/performance/read-ahead/src/read-ahead-mem-types.h
+++ /dev/null
@@ -1,26 +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 __RA_MEM_TYPES_H__
-#define __RA_MEM_TYPES_H__
-
-#include "mem-types.h"
-
-enum gf_ra_mem_types_ {
- gf_ra_mt_ra_file_t = gf_common_mt_end + 1,
- gf_ra_mt_ra_conf_t,
- gf_ra_mt_ra_page_t,
- gf_ra_mt_ra_waitq_t,
- gf_ra_mt_ra_fill_t,
- gf_ra_mt_iovec,
- gf_ra_mt_end
-};
-#endif
diff --git a/xlators/performance/read-ahead/src/read-ahead.c b/xlators/performance/read-ahead/src/read-ahead.c
index 01c861d52f2..e4c1ab2dab0 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-2009 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 General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that 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/>.
*/
-/*
- TODO:
- - handle O_DIRECT
- - maintain offset, flush on lseek
- - ensure efficient memory management in case of random seek
+/*
+ TODO:
+ - handle O_DIRECT
+ - maintain offset, flush on lseek
+ - ensure efficient memory managment in case of random seek
*/
#ifndef _CONFIG_H
@@ -35,63 +44,72 @@ 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;
+ 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);
+ conf = this->private;
- conf = this->private;
+ if (op_ret == -1) {
+ goto unwind;
+ }
- if (op_ret == -1) {
- goto unwind;
- }
+ wbflags = (long)frame->local;
- file = GF_CALLOC (1, sizeof (*file), gf_ra_mt_ra_file_t);
- if (!file) {
+ file = CALLOC (1, sizeof (*file));
+ if (!file) {
op_ret = -1;
op_errno = ENOMEM;
- goto unwind;
- }
+ gf_log (this->name, GF_LOG_ERROR,
+ "out of memory");
+ goto unwind;
+ }
- /* If O_DIRECT open, we disable caching on it */
+ /* If mandatory locking has been enabled on this file,
+ we disable caching on it */
- if ((fd->flags & O_DIRECT) || ((fd->flags & O_ACCMODE) == O_WRONLY))
- file->disabled = 1;
+ if ((fd->inode->st_mode & S_ISGID) && !(fd->inode->st_mode & S_IXGRP))
+ file->disabled = 1;
- file->offset = (unsigned long long) 0;
- file->conf = conf;
- file->pages.next = &file->pages;
- file->pages.prev = &file->pages;
- file->pages.offset = (unsigned long long) 0;
- file->pages.file = file;
-
- ra_conf_lock (conf);
- {
- file->next = conf->files.next;
- conf->files.next = file;
- file->next->prev = file;
- file->prev = &conf->files;
- }
- ra_conf_unlock (conf);
+ /* If O_DIRECT open, we disable caching on it */
- file->fd = fd;
- file->page_count = conf->page_count;
- file->page_size = conf->page_size;
- pthread_mutex_init (&file->file_lock, NULL);
+ if ((fd->flags & O_DIRECT) || ((fd->flags & O_ACCMODE) == O_WRONLY))
+ file->disabled = 1;
- if (!file->disabled) {
- file->page_count = 1;
+ if (wbflags & GF_OPEN_NOWB) {
+ file->disabled = 1;
}
- ret = fd_ctx_set (fd, this, (uint64_t)(long)file);
+ file->offset = (unsigned long long) 0;
+ file->conf = conf;
+ file->pages.next = &file->pages;
+ file->pages.prev = &file->pages;
+ file->pages.offset = (unsigned long long) 0;
+ file->pages.file = file;
+
+ ra_conf_lock (conf);
+ {
+ file->next = conf->files.next;
+ conf->files.next = file;
+ file->next->prev = file;
+ file->prev = &conf->files;
+ }
+ ra_conf_unlock (conf);
+
+ file->fd = fd;
+ file->page_count = conf->page_count;
+ file->page_size = conf->page_size;
+ pthread_mutex_init (&file->file_lock, NULL);
+
+ if (!file->disabled) {
+ file->page_count = 1;
+ }
+
+ ret = fd_ctx_set (fd, this, (uint64_t)(long)file);
if (ret == -1) {
- gf_log (frame->this->name, GF_LOG_WARNING,
- "cannot set read-ahead context information in fd (%p)",
- fd);
ra_file_destroy (file);
op_ret = -1;
op_errno = ENOMEM;
@@ -100,112 +118,109 @@ 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;
+ return 0;
}
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 stat *buf, struct stat *preparent,
+ struct stat *postparent)
{
- ra_conf_t *conf = NULL;
- ra_file_t *file = NULL;
- int ret = 0;
-
- GF_ASSERT (frame);
- GF_VALIDATE_OR_GOTO (frame->this->name, this, unwind);
+ ra_conf_t *conf = NULL;
+ ra_file_t *file = NULL;
+ int ret = 0;
- conf = this->private;
+ conf = this->private;
- if (op_ret == -1) {
- goto unwind;
- }
+ if (op_ret == -1) {
+ goto unwind;
+ }
- file = GF_CALLOC (1, sizeof (*file), gf_ra_mt_ra_file_t);
- if (!file) {
+ file = CALLOC (1, sizeof (*file));
+ if (!file) {
op_ret = -1;
op_errno = ENOMEM;
- goto unwind;
- }
+ gf_log (this->name, GF_LOG_ERROR,
+ "out of memory");
+ goto unwind;
+ }
- /* If O_DIRECT open, we disable caching on it */
+ /* If mandatory locking has been enabled on this file,
+ we disable caching on it */
- if ((fd->flags & O_DIRECT) || ((fd->flags & O_ACCMODE) == O_WRONLY))
- file->disabled = 1;
+ if ((fd->inode->st_mode & S_ISGID) && !(fd->inode->st_mode & S_IXGRP))
+ file->disabled = 1;
- file->offset = (unsigned long long) 0;
- //file->size = fd->inode->buf.ia_size;
- file->conf = conf;
- file->pages.next = &file->pages;
- file->pages.prev = &file->pages;
- file->pages.offset = (unsigned long long) 0;
- file->pages.file = file;
-
- ra_conf_lock (conf);
- {
- file->next = conf->files.next;
- conf->files.next = file;
- file->next->prev = file;
- file->prev = &conf->files;
- }
- ra_conf_unlock (conf);
+ /* If O_DIRECT open, we disable caching on it */
+
+ if ((fd->flags & O_DIRECT) || ((fd->flags & O_ACCMODE) == O_WRONLY))
+ file->disabled = 1;
+
+ file->offset = (unsigned long long) 0;
+ //file->size = fd->inode->buf.st_size;
+ file->conf = conf;
+ file->pages.next = &file->pages;
+ file->pages.prev = &file->pages;
+ file->pages.offset = (unsigned long long) 0;
+ file->pages.file = file;
- file->fd = fd;
- file->page_count = conf->page_count;
- file->page_size = conf->page_size;
- pthread_mutex_init (&file->file_lock, NULL);
+ ra_conf_lock (conf);
+ {
+ file->next = conf->files.next;
+ conf->files.next = file;
+ file->next->prev = file;
+ file->prev = &conf->files;
+ }
+ ra_conf_unlock (conf);
+
+ file->fd = fd;
+ file->page_count = conf->page_count;
+ file->page_size = conf->page_size;
+ pthread_mutex_init (&file->file_lock, NULL);
- ret = fd_ctx_set (fd, this, (uint64_t)(long)file);
+ ret = fd_ctx_set (fd, this, (uint64_t)(long)file);
if (ret == -1) {
- gf_log (this->name, GF_LOG_WARNING,
- "cannot set read ahead context information in fd (%p)",
- fd);
ra_file_destroy (file);
op_ret = -1;
op_errno = ENOMEM;
}
unwind:
- STACK_UNWIND_STRICT (create, frame, op_ret, op_errno, fd, inode, buf,
- preparent, postparent, xdata);
+ STACK_UNWIND_STRICT (create, frame, op_ret, op_errno, fd, inode, buf,
+ preparent, postparent);
- return 0;
+ return 0;
}
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);
+ STACK_WIND (frame, ra_open_cbk,
+ FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->open,
+ loc, flags, fd, wbflags);
- return 0;
+ return 0;
}
-
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)
{
- GF_ASSERT (frame);
- GF_ASSERT (this);
-
- STACK_WIND (frame, ra_create_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->create,
- loc, flags, mode, umask, fd, xdata);
+ STACK_WIND (frame, ra_create_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->create,
+ loc, flags, mode, fd);
- return 0;
+ return 0;
}
/* free cache pages between offset and offset+size,
@@ -213,1048 +228,750 @@ 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)
-{
- ra_page_t *trav = NULL;
- ra_page_t *next = NULL;
-
- ra_file_lock (file);
- {
- trav = file->pages.next;
- while (trav != &file->pages
- && 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;
- }
- }
- }
- trav = next;
- }
- }
- ra_file_unlock (file);
+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;
+
+ ra_file_lock (file);
+ {
+ trav = file->pages.next;
+ while (trav != &file->pages
+ && trav->offset < (offset + size)) {
+
+ next = trav->next;
+ if (trav->offset >= offset && !trav->waitq) {
+ ra_page_purge (trav);
+ }
+ trav = next;
+ }
+ }
+ ra_file_unlock (file);
}
int
ra_release (xlator_t *this, fd_t *fd)
{
- uint64_t tmp_file = 0;
- int ret = 0;
-
- GF_VALIDATE_OR_GOTO ("read-ahead", this, out);
- GF_VALIDATE_OR_GOTO (this->name, fd, out);
-
- ret = fd_ctx_del (fd, this, &tmp_file);
+ uint64_t tmp_file = 0;
+ int ret = 0;
- if (!ret) {
- ra_file_destroy ((ra_file_t *)(long)tmp_file);
- }
+ ret = fd_ctx_del (fd, this, &tmp_file);
+
+ if (!ret) {
+ ra_file_destroy ((ra_file_t *)(long)tmp_file);
+ }
-out:
- return 0;
+ return 0;
}
void
read_ahead (call_frame_t *frame, ra_file_t *file)
{
- off_t ra_offset = 0;
- size_t ra_size = 0;
- off_t trav_offset = 0;
- ra_page_t *trav = NULL;
- off_t cap = 0;
- char fault = 0;
-
- GF_VALIDATE_OR_GOTO ("read-ahead", frame, out);
- GF_VALIDATE_OR_GOTO (frame->this->name, file, out);
+ off_t ra_offset = 0;
+ size_t ra_size = 0;
+ off_t trav_offset = 0;
+ ra_page_t *trav = NULL;
+ off_t cap = 0;
+ char fault = 0;
- if (!file->page_count) {
- goto out;
- }
-
- ra_size = file->page_size * file->page_count;
- ra_offset = floor (file->offset, file->page_size);
- cap = file->size ? file->size : file->offset + ra_size;
-
- while (ra_offset < min (file->offset + ra_size, cap)) {
-
- ra_file_lock (file);
- {
- trav = ra_page_get (file, ra_offset);
- }
- ra_file_unlock (file);
-
- if (!trav)
- break;
+ if (!file->page_count)
+ return;
- ra_offset += file->page_size;
- }
+ ra_size = file->page_size * file->page_count;
+ ra_offset = floor (file->offset, file->page_size);
+ cap = file->size ? file->size : file->offset + ra_size;
- if (trav) {
- /* comfortable enough */
- goto out;
- }
+ while (ra_offset < min (file->offset + ra_size, cap)) {
- trav_offset = ra_offset;
+ ra_file_lock (file);
+ {
+ trav = ra_page_get (file, ra_offset);
+ }
+ ra_file_unlock (file);
- cap = file->size ? file->size : ra_offset + ra_size;
+ if (!trav)
+ break;
- while (trav_offset < min(ra_offset + ra_size, cap)) {
- fault = 0;
- ra_file_lock (file);
- {
- trav = ra_page_get (file, trav_offset);
- if (!trav) {
- fault = 1;
- trav = ra_page_create (file, trav_offset);
- if (trav)
- trav->dirty = 1;
- }
- }
- ra_file_unlock (file);
-
- if (!trav) {
- /* OUT OF MEMORY */
- break;
- }
+ ra_offset += file->page_size;
+ }
- if (fault) {
- gf_log (frame->this->name, GF_LOG_TRACE,
- "RA at offset=%"PRId64, trav_offset);
- ra_page_fault (file, frame, trav_offset);
- }
- trav_offset += file->page_size;
- }
+ if (trav)
+ /* comfortable enough */
+ return;
+
+ trav_offset = ra_offset;
+
+ trav = file->pages.next;
+ cap = file->size ? file->size : ra_offset + ra_size;
+
+ while (trav_offset < min(ra_offset + ra_size, cap)) {
+ fault = 0;
+ ra_file_lock (file);
+ {
+ trav = ra_page_get (file, trav_offset);
+ if (!trav) {
+ fault = 1;
+ trav = ra_page_create (file, trav_offset);
+ if (trav)
+ trav->dirty = 1;
+ }
+ }
+ ra_file_unlock (file);
+
+ if (!trav) {
+ /* OUT OF MEMORY */
+ break;
+ }
+
+ if (fault) {
+ gf_log (frame->this->name, GF_LOG_TRACE,
+ "RA at offset=%"PRId64, trav_offset);
+ ra_page_fault (file, frame, trav_offset);
+ }
+ trav_offset += file->page_size;
+ }
-out:
- return;
+ return;
}
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 stat *stbuf, struct iobref *iobref)
{
- GF_ASSERT (frame);
- STACK_DESTROY (frame->root);
- return 0;
+ STACK_DESTROY (frame->root);
+ return 0;
}
static void
dispatch_requests (call_frame_t *frame, ra_file_t *file)
{
- ra_local_t *local = NULL;
- ra_conf_t *conf = NULL;
- off_t rounded_offset = 0;
- off_t rounded_end = 0;
- off_t trav_offset = 0;
- ra_page_t *trav = NULL;
- call_frame_t *ra_frame = NULL;
- char need_atime_update = 1;
- char fault = 0;
-
- GF_VALIDATE_OR_GOTO ("read-ahead", frame, out);
- GF_VALIDATE_OR_GOTO (frame->this->name, file, out);
-
- local = frame->local;
- conf = file->conf;
-
- rounded_offset = floor (local->offset, file->page_size);
- rounded_end = roof (local->offset + local->size, file->page_size);
-
- trav_offset = rounded_offset;
-
- while (trav_offset < rounded_end) {
- fault = 0;
-
- ra_file_lock (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;
+ ra_local_t *local = NULL;
+ ra_conf_t *conf = NULL;
+ off_t rounded_offset = 0;
+ off_t rounded_end = 0;
+ off_t trav_offset = 0;
+ ra_page_t *trav = NULL;
+ call_frame_t *ra_frame = NULL;
+ char need_atime_update = 1;
+ char fault = 0;
+
+ local = frame->local;
+ conf = file->conf;
+
+ rounded_offset = floor (local->offset, file->page_size);
+ rounded_end = roof (local->offset + local->size, file->page_size);
+
+ trav_offset = rounded_offset;
+ trav = file->pages.next;
+
+ while (trav_offset < rounded_end) {
+ fault = 0;
+
+ ra_file_lock (file);
+ {
+ trav = ra_page_get (file, trav_offset);
+ if (!trav) {
+ trav = ra_page_create (file, trav_offset);
+ fault = 1;
+ need_atime_update = 0;
+ }
+
+ if (!trav) {
+ local->op_ret = -1;
+ local->op_errno = ENOMEM;
+ goto unlock;
}
- trav->dirty = 0;
-
- if (trav->ready) {
- gf_log (frame->this->name, GF_LOG_TRACE,
- "HIT at offset=%"PRId64".",
- trav_offset);
- ra_frame_fill (trav, frame);
- } else {
- gf_log (frame->this->name, GF_LOG_TRACE,
- "IN-TRANSIT at offset=%"PRId64".",
- trav_offset);
- ra_wait_on_page (trav, frame);
- need_atime_update = 0;
- }
- }
- unlock:
- ra_file_unlock (file);
-
- if (local->op_ret == -1) {
- goto out;
- }
- if (fault) {
- gf_log (frame->this->name, GF_LOG_TRACE,
- "MISS at offset=%"PRId64".",
- trav_offset);
- ra_page_fault (file, frame, trav_offset);
- }
-
- trav_offset += file->page_size;
- }
+ if (trav->ready) {
+ gf_log (frame->this->name, GF_LOG_TRACE,
+ "HIT at offset=%"PRId64".",
+ trav_offset);
+ ra_frame_fill (trav, frame);
+ } else {
+ gf_log (frame->this->name, GF_LOG_TRACE,
+ "IN-TRANSIT at offset=%"PRId64".",
+ trav_offset);
+ ra_wait_on_page (trav, frame);
+ need_atime_update = 0;
+ }
+ }
+ unlock:
+ ra_file_unlock (file);
+
+ if (fault) {
+ gf_log (frame->this->name, GF_LOG_TRACE,
+ "MISS at offset=%"PRId64".",
+ trav_offset);
+ ra_page_fault (file, frame, trav_offset);
+ }
+
+ trav_offset += file->page_size;
+ }
- if (need_atime_update && conf->force_atime_update) {
- /* TODO: use untimens() since readv() can confuse underlying
- io-cache and others */
- ra_frame = copy_frame (frame);
+ if (need_atime_update && conf->force_atime_update) {
+ /* TODO: use untimens() since readv() can confuse underlying
+ io-cache and others */
+ ra_frame = copy_frame (frame);
if (ra_frame == NULL) {
goto out;
}
- STACK_WIND (ra_frame, ra_need_atime_cbk,
- FIRST_CHILD (frame->this),
- FIRST_CHILD (frame->this)->fops->readv,
- file->fd, 1, 1, 0, NULL);
- }
+ STACK_WIND (ra_frame, ra_need_atime_cbk,
+ FIRST_CHILD (frame->this),
+ FIRST_CHILD (frame->this)->fops->readv,
+ file->fd, 1, 1);
+ }
out:
- return ;
+ return ;
}
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 stat *stbuf, struct iobref *iobref)
{
- GF_ASSERT (frame);
-
- 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;
+ return 0;
}
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;
- ra_conf_t *conf = NULL;
- int op_errno = EINVAL;
- char expected_offset = 1;
- uint64_t tmp_file = 0;
-
- GF_ASSERT (frame);
- GF_VALIDATE_OR_GOTO (frame->this->name, this, unwind);
- GF_VALIDATE_OR_GOTO (frame->this->name, fd, unwind);
+ ra_file_t *file = NULL;
+ ra_local_t *local = NULL;
+ ra_conf_t *conf = NULL;
+ int op_errno = 0;
+ int ret = 0;
+ char expected_offset = 1;
+ uint64_t tmp_file = 0;
- conf = this->private;
+ conf = this->private;
- gf_log (this->name, GF_LOG_TRACE,
- "NEW REQ at offset=%"PRId64" for size=%"GF_PRI_SIZET"",
- offset, size);
+ gf_log (this->name, GF_LOG_TRACE,
+ "NEW REQ at offset=%"PRId64" for size=%"GF_PRI_SIZET"",
+ offset, size);
- fd_ctx_get (fd, this, &tmp_file);
- file = (ra_file_t *)(long)tmp_file;
+ ret = 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_DEBUG, "readv received on fd with no"
+ " file set in its context");
+ goto unwind;
}
- if (file->offset != offset) {
- gf_log (this->name, GF_LOG_TRACE,
- "unexpected offset (%"PRId64" != %"PRId64") resetting",
- file->offset, offset);
-
- expected_offset = file->expected = file->page_count = 0;
- } else {
- gf_log (this->name, GF_LOG_TRACE,
- "expected offset (%"PRId64") when page_count=%d",
- offset, file->page_count);
-
- if (file->expected < (file->page_size * conf->page_count)) {
- file->expected += size;
- file->page_count = min ((file->expected
- / file->page_size),
- conf->page_count);
- }
- }
+ if (file->offset != offset) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "unexpected offset (%"PRId64" != %"PRId64") resetting",
+ file->offset, offset);
- if (!expected_offset) {
- flush_region (frame, file, 0, file->pages.prev->offset + 1, 0);
- }
+ expected_offset = file->expected = file->page_count = 0;
+ } else {
+ gf_log (this->name, GF_LOG_TRACE,
+ "expected offset (%"PRId64") when page_count=%d",
+ offset, file->page_count);
- local = mem_get0 (this->local_pool);
- if (!local) {
- op_errno = ENOMEM;
- goto unwind;
- }
+ if (file->expected < (conf->page_size * conf->page_count)) {
+ file->expected += size;
+ file->page_count = min ((file->expected / file->page_size),
+ conf->page_count);
+ }
+ }
- local->fd = fd;
- local->offset = offset;
- local->size = size;
- local->wait_count = 1;
+ if (!expected_offset) {
+ flush_region (frame, file, 0, file->pages.prev->offset + 1);
+ }
- local->fill.next = &local->fill;
- local->fill.prev = &local->fill;
+ 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 = (void *) CALLOC (1, sizeof (*local));
+ if (!local) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "out of memory");
+ op_errno = ENOMEM;
+ goto unwind;
+ }
- pthread_mutex_init (&local->local_lock, NULL);
+ local->fd = fd;
+ local->offset = offset;
+ local->size = size;
+ local->wait_count = 1;
- frame->local = local;
+ local->fill.next = &local->fill;
+ local->fill.prev = &local->fill;
- dispatch_requests (frame, file);
+ pthread_mutex_init (&local->local_lock, NULL);
- flush_region (frame, file, 0, floor (offset, file->page_size), 0);
+ frame->local = local;
+
+ dispatch_requests (frame, file);
+
+ flush_region (frame, file, 0, floor (offset, file->page_size));
read_ahead (frame, file);
- ra_frame_return (frame);
+ ra_frame_return (frame);
- file->offset = offset + size;
+ file->offset = offset + size;
- return 0;
+ 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;
+ 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);
- return 0;
+ STACK_UNWIND_STRICT (flush, frame, op_ret, op_errno);
+ return 0;
}
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 stat *prebuf, struct stat *postbuf)
{
- GF_ASSERT (frame);
- 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
-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;
- int32_t op_errno = EINVAL;
-
- GF_ASSERT (frame);
- GF_VALIDATE_OR_GOTO (frame->this->name, this, unwind);
- GF_VALIDATE_OR_GOTO (frame->this->name, fd, unwind);
-
- fd_ctx_get (fd, this, &tmp_file);
+ ra_file_t *file = NULL;
+ int ret = 0;
+ uint64_t tmp_file = 0;
+ int32_t op_errno = 0;
- file = (ra_file_t *)(long)tmp_file;
- if (file) {
- flush_region (frame, file, 0, file->pages.prev->offset+1, 0);
+ ret = fd_ctx_get (fd, this, &tmp_file);
+ file = (ra_file_t *)(long)tmp_file;
+ if (file == NULL) {
+ op_errno = EBADF;
+ gf_log (this->name, GF_LOG_DEBUG, "flush received on fd with no"
+ " file set in its context");
+ goto unwind;
}
- STACK_WIND (frame, ra_flush_cbk, FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->flush, fd, xdata);
- return 0;
+ 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);
+ 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;
- int32_t op_errno = EINVAL;
+ ra_file_t *file = NULL;
+ int ret = 0;
+ uint64_t tmp_file = 0;
+ int32_t op_errno = 0;
- GF_ASSERT (frame);
- GF_VALIDATE_OR_GOTO (frame->this->name, this, unwind);
- GF_VALIDATE_OR_GOTO (frame->this->name, fd, unwind);
-
- 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);
+ ret = fd_ctx_get (fd, this, &tmp_file);
+ file = (ra_file_t *)(long)tmp_file;
+ if (file == NULL) {
+ op_errno = EBADF;
+ gf_log (this->name, GF_LOG_DEBUG, "fsync received on fd with no"
+ " file set in its context");
+ goto unwind;
}
- STACK_WIND (frame, ra_fsync_cbk, FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->fsync, fd, datasync, xdata);
- return 0;
+ if (file) {
+ 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);
+ 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;
}
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)
+ int32_t op_ret, int32_t op_errno, struct stat *prebuf,
+ struct stat *postbuf)
{
- ra_file_t *file = NULL;
+ fd_t *fd = NULL;
+ ra_file_t *file = NULL;
+ int ret = 0;
+ uint64_t tmp_file = 0;
- GF_ASSERT (frame);
+ fd = frame->local;
- file = frame->local;
+ ret = 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);
- }
+ flush_region (frame, file, 0, file->pages.prev->offset+1);
- frame->local = NULL;
- STACK_UNWIND_STRICT (writev, frame, op_ret, op_errno, prebuf, postbuf,
- xdata);
- return 0;
+ frame->local = NULL;
+ 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;
- int32_t op_errno = EINVAL;
-
- GF_ASSERT (frame);
- GF_VALIDATE_OR_GOTO (frame->this->name, this, unwind);
- GF_VALIDATE_OR_GOTO (frame->this->name, fd, unwind);
-
- 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;
+ ra_file_t *file = NULL;
+ int ret = 0;
+ uint64_t tmp_file = 0;
+ int32_t op_errno = 0;
+
+ ret = fd_ctx_get (fd, this, &tmp_file);
+ file = (ra_file_t *)(long)tmp_file;
+ if (file == NULL) {
+ op_errno = EBADF;
+ gf_log (this->name, GF_LOG_DEBUG, "writev received on fd with"
+ "no file set in its context");
+ goto unwind;
}
- STACK_WIND (frame, ra_writev_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->writev,
- fd, vector, count, offset, flags, iobref, xdata);
+ flush_region (frame, file, 0, file->pages.prev->offset+1);
- return 0;
+ /* 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, 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;
}
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)
+ int32_t op_ret, int32_t op_errno, struct stat *prebuf,
+ struct stat *postbuf)
{
- GF_ASSERT (frame);
-
- 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;
}
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 stat *buf)
{
- GF_ASSERT (frame);
-
- 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
-ra_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset,
- dict_t *xdata)
-{
- ra_file_t *file = NULL;
- fd_t *iter_fd = NULL;
- inode_t *inode = NULL;
- uint64_t tmp_file = 0;
- int32_t op_errno = EINVAL;
-
- GF_ASSERT (frame);
- GF_VALIDATE_OR_GOTO (frame->this->name, this, unwind);
- GF_VALIDATE_OR_GOTO (frame->this->name, loc, unwind);
-
- inode = loc->inode;
-
- LOCK (&inode->lock);
- {
- list_for_each_entry (iter_fd, &inode->fd_list, inode_list) {
- fd_ctx_get (iter_fd, this, &tmp_file);
- 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_ftruncate.
- */
- flush_region (frame, file, 0,
- file->pages.prev->offset + 1, 1);
- }
- }
- UNLOCK (&inode->lock);
-
- STACK_WIND (frame, ra_truncate_cbk,
- FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->truncate,
- loc, offset, xdata);
- return 0;
-
-unwind:
- STACK_UNWIND_STRICT (truncate, frame, -1, op_errno, NULL, 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);
+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;
+ inode_t *inode = NULL;
+ int ret = 0;
+ uint64_t tmp_file = 0;
+
+ inode = loc->inode;
+
+ LOCK (&inode->lock);
+ {
+ list_for_each_entry (iter_fd, &inode->fd_list, inode_list) {
+ ret = fd_ctx_get (iter_fd, this, &tmp_file);
+ file = (ra_file_t *)(long)tmp_file;
+
+ if (!file)
+ continue;
+ flush_region (frame, file, 0,
+ file->pages.prev->offset + 1);
+ }
}
+ UNLOCK (&inode->lock);
-out:
- return;
+ STACK_WIND (frame, ra_truncate_cbk,
+ FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->truncate,
+ loc, offset);
+ return 0;
}
-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_file_t *file = NULL;
- fd_t *iter_fd = NULL;
- inode_t *inode = NULL;
- uint64_t tmp_file = 0;
- int32_t op_errno = EINVAL;
-
- GF_ASSERT (frame);
- GF_VALIDATE_OR_GOTO (frame->this->name, this, unwind);
- GF_VALIDATE_OR_GOTO (frame->this->name, fd, unwind);
-
- inode = fd->inode;
-
- LOCK (&inode->lock);
- {
- list_for_each_entry (iter_fd, &inode->fd_list, inode_list) {
- fd_ctx_get (iter_fd, this, &tmp_file);
- file = (ra_file_t *)(long)tmp_file;
-
- if (!file)
- continue;
- flush_region (frame, file, 0,
- file->pages.prev->offset + 1, 0);
- }
- }
- UNLOCK (&inode->lock);
-
- STACK_WIND (frame, ra_attr_cbk, FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->fstat, fd, xdata);
- return 0;
+ra_fstat (call_frame_t *frame, xlator_t *this, fd_t *fd)
+{
+ ra_file_t *file = NULL;
+ fd_t *iter_fd = NULL;
+ inode_t *inode = NULL;
+ int ret = 0;
+ uint64_t tmp_file = 0;
+
+ inode = fd->inode;
+
+ LOCK (&inode->lock);
+ {
+ list_for_each_entry (iter_fd, &inode->fd_list, inode_list) {
+ ret = fd_ctx_get (iter_fd, this, &tmp_file);
+ file = (ra_file_t *)(long)tmp_file;
+
+ if (!file)
+ continue;
+ flush_region (frame, file, 0,
+ file->pages.prev->offset + 1);
+ }
+ }
+ UNLOCK (&inode->lock);
-unwind:
- STACK_UNWIND_STRICT (stat, frame, -1, op_errno, NULL, NULL);
- return 0;
+ STACK_WIND (frame, ra_attr_cbk,
+ FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->fstat,
+ fd);
+ return 0;
}
int
-ra_ftruncate (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
- dict_t *xdata)
-{
- ra_file_t *file = NULL;
- fd_t *iter_fd = NULL;
- inode_t *inode = NULL;
- uint64_t tmp_file = 0;
- int32_t op_errno = EINVAL;
-
- GF_ASSERT (frame);
- GF_VALIDATE_OR_GOTO (frame->this->name, this, unwind);
- GF_VALIDATE_OR_GOTO (frame->this->name, fd, unwind);
-
- inode = fd->inode;
-
- LOCK (&inode->lock);
- {
- list_for_each_entry (iter_fd, &inode->fd_list, inode_list) {
- fd_ctx_get (iter_fd, this, &tmp_file);
- 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);
- }
- }
- UNLOCK (&inode->lock);
-
- STACK_WIND (frame, ra_truncate_cbk, FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->ftruncate, fd, offset, xdata);
- return 0;
-
-unwind:
- STACK_UNWIND_STRICT (truncate, frame, -1, op_errno, NULL, NULL, NULL);
- return 0;
-}
-
-int
-ra_discard_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)
-{
- GF_ASSERT (frame);
-
- STACK_UNWIND_STRICT (discard, frame, op_ret, op_errno, prebuf,
- postbuf, xdata);
- return 0;
-}
-
-static int
-ra_discard(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
- size_t len, dict_t *xdata)
-{
- ra_file_t *file = NULL;
- fd_t *iter_fd = NULL;
- inode_t *inode = NULL;
- uint64_t tmp_file = 0;
- int32_t op_errno = EINVAL;
-
- GF_ASSERT (frame);
- GF_VALIDATE_OR_GOTO (frame->this->name, this, unwind);
- GF_VALIDATE_OR_GOTO (frame->this->name, fd, unwind);
-
- inode = fd->inode;
-
- LOCK (&inode->lock);
- {
- list_for_each_entry (iter_fd, &inode->fd_list, inode_list) {
- fd_ctx_get (iter_fd, this, &tmp_file);
- file = (ra_file_t *)(long)tmp_file;
- if (!file)
- continue;
-
- flush_region(frame, file, offset, len, 1);
- }
- }
- UNLOCK (&inode->lock);
-
- STACK_WIND (frame, ra_discard_cbk, FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->discard, fd, offset, len, xdata);
- return 0;
+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;
+ inode_t *inode = NULL;
+ int ret = 0;
+ uint64_t tmp_file = 0;
+
+ inode = fd->inode;
+
+ LOCK (&inode->lock);
+ {
+ list_for_each_entry (iter_fd, &inode->fd_list, inode_list) {
+ ret = fd_ctx_get (iter_fd, this, &tmp_file);
+ file = (ra_file_t *)(long)tmp_file;
+ if (!file)
+ continue;
+ flush_region (frame, file, 0,
+ file->pages.prev->offset + 1);
+ }
+ }
+ UNLOCK (&inode->lock);
-unwind:
- STACK_UNWIND_STRICT (discard, frame, -1, op_errno, NULL, NULL, NULL);
- return 0;
-}
-
-int
-ra_zerofill_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)
-{
- GF_ASSERT (frame);
-
- STACK_UNWIND_STRICT (zerofill, frame, op_ret, op_errno, prebuf,
- postbuf, xdata);
- return 0;
-}
-
-static int
-ra_zerofill(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
- off_t len, dict_t *xdata)
-{
- ra_file_t *file = NULL;
- fd_t *iter_fd = NULL;
- inode_t *inode = NULL;
- uint64_t tmp_file = 0;
- int32_t op_errno = EINVAL;
-
- GF_ASSERT (frame);
- GF_VALIDATE_OR_GOTO (frame->this->name, this, unwind);
- GF_VALIDATE_OR_GOTO (frame->this->name, fd, unwind);
-
- inode = fd->inode;
-
- LOCK (&inode->lock);
- {
- list_for_each_entry (iter_fd, &inode->fd_list, inode_list) {
- fd_ctx_get (iter_fd, this, &tmp_file);
- file = (ra_file_t *)(long)tmp_file;
- if (!file)
- continue;
-
- flush_region(frame, file, offset, len, 1);
- }
- }
- UNLOCK (&inode->lock);
-
- STACK_WIND (frame, ra_zerofill_cbk, FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->zerofill, fd,
- offset, len, xdata);
- return 0;
-
-unwind:
- STACK_UNWIND_STRICT (zerofill, frame, -1, op_errno, NULL, NULL, NULL);
- return 0;
+ STACK_WIND (frame, ra_truncate_cbk,
+ FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->ftruncate,
+ fd, offset);
+ return 0;
}
int
ra_priv_dump (xlator_t *this)
{
- ra_conf_t *conf = NULL;
- int ret = -1;
- char key_prefix[GF_DUMP_MAX_BUF_LEN] = {0, };
- gf_boolean_t add_section = _gf_false;
+ ra_conf_t *conf = NULL;
+ int ret = -1;
+ char key[GF_DUMP_MAX_BUF_LEN];
+ char key_prefix[GF_DUMP_MAX_BUF_LEN];
- if (!this) {
- goto out;
- }
+ if (!this)
+ return -1;
conf = this->private;
if (!conf) {
- gf_log (this->name, GF_LOG_WARNING, "conf null in xlator");
- goto out;
+ gf_log (this->name, GF_LOG_WARNING,
+ "conf null in xlator");
+ return -1;
}
- gf_proc_dump_build_key (key_prefix, "xlator.performance.read-ahead",
- "priv");
-
- gf_proc_dump_add_section (key_prefix);
- add_section = _gf_true;
-
ret = pthread_mutex_trylock (&conf->conf_lock);
- if (ret)
- goto out;
- {
- 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);
- }
- pthread_mutex_unlock (&conf->conf_lock);
-
- ret = 0;
-out:
- if (ret && conf) {
- if (add_section == _gf_false)
- gf_proc_dump_add_section (key_prefix);
-
- gf_proc_dump_write ("Unable to dump priv",
- "(Lock acquisition failed) %s", this->name);
+ if (ret) {
+ gf_log ("", GF_LOG_WARNING, "Unable to lock client %s"
+ " errno: %d", this->name, errno);
+ return -1;
}
- return ret;
-}
-int32_t
-mem_acct_init (xlator_t *this)
-{
- int ret = -1;
-
- if (!this) {
- goto out;
- }
-
- ret = xlator_mem_acct_init (this, gf_ra_mt_end + 1);
-
- if (ret != 0) {
- gf_log (this->name, GF_LOG_ERROR, "Memory accounting init"
- "failed");
- }
-
-out:
- return ret;
-}
-
-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_proc_dump_build_key (key_prefix,
+ "xlator.performance.read-ahead",
+ "priv");
- GF_OPTION_RECONF ("page-count", conf->page_count, options, uint32, out);
+ gf_proc_dump_add_section (key_prefix);
+ 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);
- GF_OPTION_RECONF ("page-size", conf->page_size, options, size_uint64,
- out);
+ pthread_mutex_unlock (&conf->conf_lock);
- ret = 0;
- out:
- return ret;
+ return 0;
}
int
init (xlator_t *this)
{
- ra_conf_t *conf = NULL;
- int32_t ret = -1;
-
- GF_VALIDATE_OR_GOTO ("read-ahead", this, out);
+ ra_conf_t *conf = NULL;
+ dict_t *options = this->options;
+ char *page_count_string = NULL;
+ int32_t ret = -1;
- if (!this->children || this->children->next) {
- gf_log (this->name, GF_LOG_ERROR,
- "FATAL: read-ahead not configured with exactly one"
+ if (!this->children || this->children->next) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "FATAL: read-ahead not configured with exactly one"
" child");
goto out;
- }
-
- if (!this->parents) {
- gf_log (this->name, GF_LOG_WARNING,
- "dangling volume. check volfile ");
- }
+ }
- conf = (void *) GF_CALLOC (1, sizeof (*conf), gf_ra_mt_ra_conf_t);
+ if (!this->parents) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "dangling volume. check volfile ");
+ }
+
+ conf = (void *) CALLOC (1, sizeof (*conf));
if (conf == NULL) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "FATAL: Out of memory");
goto out;
}
- conf->page_size = this->ctx->page_size;
-
- GF_OPTION_INIT ("page-size", conf->page_size, size_uint64, out);
-
- GF_OPTION_INIT ("page-count", conf->page_count, uint32, out);
-
- GF_OPTION_INIT ("force-atime-update", conf->force_atime_update, bool, out);
-
- conf->files.next = &conf->files;
- conf->files.prev = &conf->files;
-
- pthread_mutex_init (&conf->conf_lock, NULL);
+ conf->page_size = this->ctx->page_size;
+ conf->page_count = 4;
+
+ if (dict_get (options, "page-count"))
+ page_count_string = data_to_str (dict_get (options,
+ "page-count"));
+ 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;
+ }
+ gf_log (this->name, GF_LOG_DEBUG, "Using conf->page_count = %u",
+ conf->page_count);
+ }
+
+ if (dict_get (options, "force-atime-update")) {
+ char *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_DEBUG, "Forcing atime "
+ "updates on cache hit");
+ }
- 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;
- }
+ conf->files.next = &conf->files;
+ conf->files.prev = &conf->files;
- this->private = conf;
+ pthread_mutex_init (&conf->conf_lock, NULL);
+ this->private = conf;
ret = 0;
out:
if (ret == -1) {
- GF_FREE (conf);
+ if (conf != NULL) {
+ FREE (conf);
+ }
}
return ret;
}
-
void
fini (xlator_t *this)
{
- ra_conf_t *conf = NULL;
+ ra_conf_t *conf = this->private;
- GF_VALIDATE_OR_GOTO ("read-ahead", this, out);
+ if (conf == NULL)
+ return;
- conf = this->private;
- if (conf == NULL) {
- 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);
+ pthread_mutex_destroy (&conf->conf_lock);
+ FREE (conf);
-out:
- return;
+ this->private = NULL;
+ return;
}
struct xlator_fops fops = {
- .open = ra_open,
- .create = ra_create,
- .readv = ra_readv,
- .writev = ra_writev,
- .flush = ra_flush,
- .fsync = ra_fsync,
- .truncate = ra_truncate,
- .ftruncate = ra_ftruncate,
- .fstat = ra_fstat,
- .discard = ra_discard,
- .zerofill = ra_zerofill,
+ .open = ra_open,
+ .create = ra_create,
+ .readv = ra_readv,
+ .writev = ra_writev,
+ .flush = ra_flush,
+ .fsync = ra_fsync,
+ .truncate = ra_truncate,
+ .ftruncate = ra_ftruncate,
+ .fstat = ra_fstat,
+};
+
+struct xlator_mops mops = {
};
struct xlator_cbks cbks = {
- .release = ra_release,
+ .release = ra_release,
};
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"
- },
- { .key = {"page-count"},
- .type = GF_OPTION_TYPE_INT,
- .min = 1,
- .max = 16,
- .default_value = "4",
- .description = "Number of pages that will be pre-fetched"
- },
- { .key = {"page-size"},
- .type = GF_OPTION_TYPE_SIZET,
- .min = 4096,
- .max = 1048576 * 64,
- .default_value = "131072",
- .description = "Page size with which read-ahead performs server I/O"
+ { .key = {"force-atime-update"},
+ .type = GF_OPTION_TYPE_BOOL
+ },
+ { .key = {"page-count"},
+ .type = GF_OPTION_TYPE_INT,
+ .min = 1,
+ .max = 16
},
- { .key = {NULL} },
+ { .key = {NULL} },
};
diff --git a/xlators/performance/read-ahead/src/read-ahead.h b/xlators/performance/read-ahead/src/read-ahead.h
index d1d768c34fb..d11143551f0 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-2009 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 General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that 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 __READ_AHEAD_H
@@ -22,7 +31,6 @@
#include "dict.h"
#include "xlator.h"
#include "common-utils.h"
-#include "read-ahead-mem-types.h"
struct ra_conf;
struct ra_local;
@@ -32,79 +40,77 @@ struct ra_waitq;
struct ra_waitq {
- struct ra_waitq *next;
- void *data;
+ struct ra_waitq *next;
+ void *data;
};
struct ra_fill {
- struct ra_fill *next;
- struct ra_fill *prev;
- off_t offset;
- size_t size;
- struct iovec *vector;
- int32_t count;
+ struct ra_fill *next;
+ struct ra_fill *prev;
+ off_t offset;
+ size_t size;
+ struct iovec *vector;
+ int32_t count;
struct iobref *iobref;
};
struct ra_local {
- mode_t mode;
- struct ra_fill fill;
- off_t offset;
- size_t size;
- int32_t op_ret;
- int32_t op_errno;
- off_t pending_offset;
- size_t pending_size;
- fd_t *fd;
- int32_t wait_count;
- pthread_mutex_t local_lock;
+ mode_t mode;
+ struct ra_fill fill;
+ off_t offset;
+ size_t size;
+ int32_t op_ret;
+ int32_t op_errno;
+ off_t pending_offset;
+ size_t pending_size;
+ fd_t *fd;
+ int32_t wait_count;
+ pthread_mutex_t local_lock;
};
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 ready;
- struct iovec *vector;
- int32_t count;
- off_t offset;
- size_t size;
- struct ra_waitq *waitq;
+ struct ra_page *next;
+ struct ra_page *prev;
+ struct ra_file *file;
+ char dirty;
+ char ready;
+ struct iovec *vector;
+ int32_t count;
+ off_t offset;
+ size_t size;
+ struct ra_waitq *waitq;
struct iobref *iobref;
- char stale;
};
struct ra_file {
- struct ra_file *next;
- struct ra_file *prev;
- struct ra_conf *conf;
- fd_t *fd;
- int disabled;
- size_t expected;
- struct ra_page pages;
- off_t offset;
- size_t size;
- int32_t refcount;
- pthread_mutex_t file_lock;
- struct iatt stbuf;
- uint64_t page_size;
- uint32_t page_count;
+ struct ra_file *next;
+ struct ra_file *prev;
+ struct ra_conf *conf;
+ fd_t *fd;
+ int disabled;
+ size_t expected;
+ struct ra_page pages;
+ off_t offset;
+ size_t size;
+ int32_t refcount;
+ pthread_mutex_t file_lock;
+ struct stat stbuf;
+ uint64_t page_size;
+ uint32_t page_count;
};
struct ra_conf {
- uint64_t page_size;
- uint32_t page_count;
- void *cache_block;
- struct ra_file files;
- gf_boolean_t force_atime_update;
- pthread_mutex_t conf_lock;
+ uint64_t page_size;
+ uint32_t page_count;
+ void *cache_block;
+ struct ra_file files;
+ gf_boolean_t force_atime_update;
+ pthread_mutex_t conf_lock;
};
@@ -117,19 +123,19 @@ typedef struct ra_fill ra_fill_t;
ra_page_t *
ra_page_get (ra_file_t *file,
- off_t offset);
+ off_t offset);
ra_page_t *
ra_page_create (ra_file_t *file,
- off_t offset);
+ off_t offset);
void
ra_page_fault (ra_file_t *file,
- call_frame_t *frame,
- off_t offset);
+ call_frame_t *frame,
+ off_t offset);
void
ra_wait_on_page (ra_page_t *page,
- call_frame_t *frame);
+ call_frame_t *frame);
ra_waitq_t *
ra_page_wakeup (ra_page_t *page);
@@ -139,8 +145,8 @@ ra_page_flush (ra_page_t *page);
ra_waitq_t *
ra_page_error (ra_page_t *page,
- int32_t op_ret,
- int32_t op_errno);
+ int32_t op_ret,
+ int32_t op_errno);
void
ra_page_purge (ra_page_t *page);
@@ -149,7 +155,7 @@ ra_frame_return (call_frame_t *frame);
void
ra_frame_fill (ra_page_t *page,
- call_frame_t *frame);
+ call_frame_t *frame);
void
ra_file_destroy (ra_file_t *file);
@@ -157,36 +163,36 @@ ra_file_destroy (ra_file_t *file);
static inline void
ra_file_lock (ra_file_t *file)
{
- pthread_mutex_lock (&file->file_lock);
+ pthread_mutex_lock (&file->file_lock);
}
static inline void
ra_file_unlock (ra_file_t *file)
{
- pthread_mutex_unlock (&file->file_lock);
+ pthread_mutex_unlock (&file->file_lock);
}
static inline void
ra_conf_lock (ra_conf_t *conf)
{
- pthread_mutex_lock (&conf->conf_lock);
+ pthread_mutex_lock (&conf->conf_lock);
}
static inline void
ra_conf_unlock (ra_conf_t *conf)
{
- pthread_mutex_unlock (&conf->conf_lock);
+ pthread_mutex_unlock (&conf->conf_lock);
}
static inline void
ra_local_lock (ra_local_t *local)
{
- pthread_mutex_lock (&local->local_lock);
+ pthread_mutex_lock (&local->local_lock);
}
static inline void
ra_local_unlock (ra_local_t *local)
{
- pthread_mutex_unlock (&local->local_lock);
+ pthread_mutex_unlock (&local->local_lock);
}
#endif /* __READ_AHEAD_H */
diff --git a/xlators/performance/readdir-ahead/Makefile.am b/xlators/performance/readdir-ahead/Makefile.am
deleted file mode 100644
index a985f42a877..00000000000
--- a/xlators/performance/readdir-ahead/Makefile.am
+++ /dev/null
@@ -1,3 +0,0 @@
-SUBDIRS = src
-
-CLEANFILES =
diff --git a/xlators/performance/readdir-ahead/src/Makefile.am b/xlators/performance/readdir-ahead/src/Makefile.am
deleted file mode 100644
index 539d6ede434..00000000000
--- a/xlators/performance/readdir-ahead/src/Makefile.am
+++ /dev/null
@@ -1,15 +0,0 @@
-xlator_LTLIBRARIES = readdir-ahead.la
-xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/performance
-
-readdir_ahead_la_LDFLAGS = -module -avoid-version
-
-readdir_ahead_la_SOURCES = readdir-ahead.c
-readdir_ahead_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la
-
-noinst_HEADERS = readdir-ahead.h readdir-ahead-mem-types.h
-
-AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src
-
-AM_CFLAGS = -Wall $(GF_CFLAGS)
-
-CLEANFILES =
diff --git a/xlators/performance/readdir-ahead/src/readdir-ahead-mem-types.h b/xlators/performance/readdir-ahead/src/readdir-ahead-mem-types.h
deleted file mode 100644
index 39e2c536975..00000000000
--- a/xlators/performance/readdir-ahead/src/readdir-ahead-mem-types.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- Copyright (c) 2008-2013 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 __RDA_MEM_TYPES_H__
-#define __RDA_MEM_TYPES_H__
-
-#include "mem-types.h"
-
-enum gf_rda_mem_types_ {
- gf_rda_mt_rda_local = gf_common_mt_end + 1,
- gf_rda_mt_rda_fd_ctx,
- gf_rda_mt_rda_priv,
- gf_rda_mt_end
-};
-
-#endif
diff --git a/xlators/performance/readdir-ahead/src/readdir-ahead.c b/xlators/performance/readdir-ahead/src/readdir-ahead.c
deleted file mode 100644
index 1a567a03ea8..00000000000
--- a/xlators/performance/readdir-ahead/src/readdir-ahead.c
+++ /dev/null
@@ -1,567 +0,0 @@
-/*
- Copyright (c) 2008-2013 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.
-*/
-
-/*
- * performance/readdir-ahead preloads a local buffer with directory entries
- * on opendir. The optimization involves using maximum sized gluster rpc
- * requests (128k) to minimize overhead of smaller client requests.
- *
- * For example, fuse currently supports a maximum readdir buffer of 4k
- * (regardless of the filesystem client's buffer size). readdir-ahead should
- * effectively convert these smaller requests into fewer, larger sized requests
- * for simple, sequential workloads (i.e., ls).
- *
- * The translator is currently designed to handle the simple, sequential case
- * only. If a non-sequential directory read occurs, readdir-ahead disables
- * preloads on the directory.
- */
-
-#ifndef _CONFIG_H
-#define _CONFIG_H
-#include "config.h"
-#endif
-
-#include "glusterfs.h"
-#include "xlator.h"
-#include "call-stub.h"
-#include "readdir-ahead.h"
-#include "readdir-ahead-mem-types.h"
-#include "defaults.h"
-
-static int rda_fill_fd(call_frame_t *, xlator_t *, fd_t *);
-
-/*
- * Get (or create) the fd context for storing prepopulated directory
- * entries.
- */
-static struct
-rda_fd_ctx *get_rda_fd_ctx(fd_t *fd, xlator_t *this)
-{
- uint64_t val;
- struct rda_fd_ctx *ctx;
-
- LOCK(&fd->lock);
-
- if (__fd_ctx_get(fd, this, &val) < 0) {
- ctx = GF_CALLOC(1, sizeof(struct rda_fd_ctx),
- gf_rda_mt_rda_fd_ctx);
- if (!ctx)
- goto out;
-
- LOCK_INIT(&ctx->lock);
- INIT_LIST_HEAD(&ctx->entries.list);
- ctx->state = RDA_FD_NEW;
- /* ctx offset values initialized to 0 */
-
- if (__fd_ctx_set(fd, this, (uint64_t) ctx) < 0) {
- GF_FREE(ctx);
- ctx = NULL;
- goto out;
- }
- } else {
- ctx = (struct rda_fd_ctx *) val;
- }
-out:
- UNLOCK(&fd->lock);
- return ctx;
-}
-
-/*
- * Reset the tracking state of the context.
- */
-static void
-rda_reset_ctx(struct rda_fd_ctx *ctx)
-{
- ctx->state = RDA_FD_NEW;
- ctx->cur_offset = 0;
- ctx->cur_size = 0;
- ctx->next_offset = 0;
- ctx->op_errno = 0;
- gf_dirent_free(&ctx->entries);
-}
-
-/*
- * Check whether we can handle a request. Offset verification is done by the
- * caller, so we only check whether the preload buffer has completion status
- * (including an error) or has some data to return.
- */
-static gf_boolean_t
-rda_can_serve_readdirp(struct rda_fd_ctx *ctx, size_t request_size)
-{
- if ((ctx->state & RDA_FD_EOD) ||
- (ctx->state & RDA_FD_ERROR) ||
- (!(ctx->state & RDA_FD_PLUGGED) && (ctx->cur_size > 0)))
- return _gf_true;
-
- return _gf_false;
-}
-
-/*
- * Serve a request from the fd dentry list based on the size of the request
- * buffer. ctx must be locked.
- */
-static int32_t
-__rda_serve_readdirp(xlator_t *this, gf_dirent_t *entries, size_t request_size,
- struct rda_fd_ctx *ctx)
-{
- gf_dirent_t *dirent, *tmp;
- size_t dirent_size, size = 0;
- int32_t count = 0;
- struct rda_priv *priv = this->private;
-
- list_for_each_entry_safe(dirent, tmp, &ctx->entries.list, list) {
- dirent_size = gf_dirent_size(dirent->d_name);
- if (size + dirent_size > request_size)
- break;
-
- size += dirent_size;
- list_del_init(&dirent->list);
- ctx->cur_size -= dirent_size;
-
- list_add_tail(&dirent->list, &entries->list);
- ctx->cur_offset = dirent->d_off;
- count++;
- }
-
- if (ctx->cur_size <= priv->rda_low_wmark)
- ctx->state |= RDA_FD_PLUGGED;
-
- return count;
-}
-
-static int32_t
-rda_readdirp_stub(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
- off_t offset, dict_t *xdata)
-{
- gf_dirent_t entries;
- int32_t ret;
- struct rda_fd_ctx *ctx;
- int op_errno = 0;
-
- ctx = get_rda_fd_ctx(fd, this);
- INIT_LIST_HEAD(&entries.list);
- ret = __rda_serve_readdirp(this, &entries, size, ctx);
-
- if (!ret && (ctx->state & RDA_FD_ERROR)) {
- ret = -1;
- ctx->state &= ~RDA_FD_ERROR;
-
- /*
- * the preload has stopped running in the event of an error, so
- * pass all future requests along
- */
- ctx->state |= RDA_FD_BYPASS;
- }
-
- /*
- * Use the op_errno sent by lower layers as xlators above will check
- * the op_errno for identifying whether readdir is completed or not.
- */
- op_errno = ctx->op_errno;
-
- STACK_UNWIND_STRICT(readdirp, frame, ret, op_errno, &entries, xdata);
- gf_dirent_free(&entries);
-
- return 0;
-}
-
-static int32_t
-rda_readdirp(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
- off_t off, dict_t *xdata)
-{
- struct rda_fd_ctx *ctx;
- call_stub_t *stub;
- int fill = 0;
-
- ctx = get_rda_fd_ctx(fd, this);
- if (!ctx)
- goto err;
-
- if (ctx->state & RDA_FD_BYPASS)
- goto bypass;
-
- LOCK(&ctx->lock);
-
- /* recheck now that we have the lock */
- if (ctx->state & RDA_FD_BYPASS) {
- UNLOCK(&ctx->lock);
- goto bypass;
- }
-
- /*
- * If a new read comes in at offset 0 and the buffer has been
- * completed, reset the context and kickstart the filler again.
- */
- if (!off && (ctx->state & RDA_FD_EOD) && (ctx->cur_size == 0)) {
- rda_reset_ctx(ctx);
- fill = 1;
- }
-
- /*
- * If a readdir occurs at an unexpected offset or we already have a
- * request pending, admit defeat and just get out of the way.
- */
- if (off != ctx->cur_offset || ctx->stub) {
- ctx->state |= RDA_FD_BYPASS;
- UNLOCK(&ctx->lock);
- goto bypass;
- }
-
- stub = fop_readdirp_stub(frame, rda_readdirp_stub, fd, size, off, xdata);
- if (!stub) {
- UNLOCK(&ctx->lock);
- goto err;
- }
-
- /*
- * If we haven't bypassed the preload, this means we can either serve
- * the request out of the preload or the request that enables us to do
- * so is in flight...
- */
- if (rda_can_serve_readdirp(ctx, size))
- call_resume(stub);
- else
- ctx->stub = stub;
-
- UNLOCK(&ctx->lock);
-
- if (fill)
- rda_fill_fd(frame, this, fd);
-
- return 0;
-
-bypass:
- STACK_WIND(frame, default_readdirp_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->readdirp, fd, size, off, xdata);
- return 0;
-
-err:
- STACK_UNWIND_STRICT(readdirp, frame, -1, ENOMEM, NULL, NULL);
- return 0;
-}
-
-static int32_t
-rda_fill_fd_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 *dirent, *tmp;
- struct rda_local *local = frame->local;
- struct rda_fd_ctx *ctx = local->ctx;
- struct rda_priv *priv = this->private;
- int fill = 1;
-
- LOCK(&ctx->lock);
-
- /* Verify that the preload buffer is still pending on this data. */
- if (ctx->next_offset != local->offset) {
- gf_log(this->name, GF_LOG_ERROR,
- "Out of sequence directory preload.");
- ctx->state |= (RDA_FD_BYPASS|RDA_FD_ERROR);
- ctx->op_errno = EUCLEAN;
-
- goto out;
- }
-
- if (entries) {
- list_for_each_entry_safe(dirent, tmp, &entries->list, list) {
- list_del_init(&dirent->list);
- /* must preserve entry order */
- list_add_tail(&dirent->list, &ctx->entries.list);
-
- ctx->cur_size += gf_dirent_size(dirent->d_name);
- ctx->next_offset = dirent->d_off;
- }
- }
-
- if (ctx->cur_size >= priv->rda_high_wmark)
- ctx->state &= ~RDA_FD_PLUGGED;
-
- if (!op_ret) {
- /* we've hit eod */
- ctx->state &= ~RDA_FD_RUNNING;
- ctx->state |= RDA_FD_EOD;
- ctx->op_errno = op_errno;
- } else if (op_ret == -1) {
- /* kill the preload and pend the error */
- ctx->state &= ~RDA_FD_RUNNING;
- ctx->state |= RDA_FD_ERROR;
- ctx->op_errno = op_errno;
- }
-
- /*
- * NOTE: The strict bypass logic in readdirp() means a pending request
- * is always based on ctx->cur_offset.
- */
- if (ctx->stub &&
- rda_can_serve_readdirp(ctx, ctx->stub->args.size)) {
- call_resume(ctx->stub);
- ctx->stub = NULL;
- }
-
-out:
- /*
- * If we have been marked for bypass and have no pending stub, clear the
- * run state so we stop preloading the context with entries.
- */
- if ((ctx->state & RDA_FD_BYPASS) && !ctx->stub)
- ctx->state &= ~RDA_FD_RUNNING;
-
- if (!(ctx->state & RDA_FD_RUNNING)) {
- fill = 0;
- STACK_DESTROY(ctx->fill_frame->root);
- ctx->fill_frame = NULL;
- }
-
- UNLOCK(&ctx->lock);
-
- if (fill)
- rda_fill_fd(frame, this, local->fd);
-
- return 0;
-}
-
-/*
- * Start prepopulating the fd context with directory entries.
- */
-static int
-rda_fill_fd(call_frame_t *frame, xlator_t *this, fd_t *fd)
-{
- call_frame_t *nframe = NULL;
- struct rda_local *local = NULL;
- struct rda_fd_ctx *ctx;
- off_t offset;
- struct rda_priv *priv = this->private;
-
- ctx = get_rda_fd_ctx(fd, this);
- if (!ctx)
- goto err;
-
- LOCK(&ctx->lock);
-
- if (ctx->state & RDA_FD_NEW) {
- ctx->state &= ~RDA_FD_NEW;
- ctx->state |= RDA_FD_RUNNING;
- if (priv->rda_low_wmark)
- ctx->state |= RDA_FD_PLUGGED;
- }
-
- offset = ctx->next_offset;
-
- if (!ctx->fill_frame) {
- nframe = copy_frame(frame);
- if (!nframe) {
- UNLOCK(&ctx->lock);
- goto err;
- }
-
- local = mem_get0(this->local_pool);
- if (!local) {
- UNLOCK(&ctx->lock);
- goto err;
- }
-
- local->ctx = ctx;
- local->fd = fd;
- nframe->local = local;
-
- ctx->fill_frame = nframe;
- } else {
- nframe = ctx->fill_frame;
- local = nframe->local;
- }
-
- local->offset = offset;
-
- UNLOCK(&ctx->lock);
-
- STACK_WIND(nframe, rda_fill_fd_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->readdirp, fd, priv->rda_req_size,
- offset, NULL);
-
- return 0;
-
-err:
- if (nframe)
- FRAME_DESTROY(nframe);
-
- return -1;
-}
-
-static int32_t
-rda_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)
-{
- if (!op_ret)
- rda_fill_fd(frame, this, fd);
-
- STACK_UNWIND_STRICT(opendir, frame, op_ret, op_errno, fd, xdata);
- return 0;
-}
-
-static int32_t
-rda_opendir(call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd,
- dict_t *xdata)
-{
- STACK_WIND(frame, rda_opendir_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->opendir, loc, fd, xdata);
- return 0;
-}
-
-static int32_t
-rda_releasedir(xlator_t *this, fd_t *fd)
-{
- uint64_t val;
- struct rda_fd_ctx *ctx;
-
- if (fd_ctx_del(fd, this, &val) < 0)
- return -1;
-
- ctx = (struct rda_fd_ctx *) val;
- if (!ctx)
- return 0;
-
- rda_reset_ctx(ctx);
-
- if (ctx->fill_frame)
- STACK_DESTROY(ctx->fill_frame->root);
-
- if (ctx->stub)
- gf_log(this->name, GF_LOG_ERROR,
- "released a directory with a pending stub");
-
- GF_FREE(ctx);
- return 0;
-}
-
-int32_t
-mem_acct_init(xlator_t *this)
-{
- int ret = -1;
-
- if (!this)
- goto out;
-
- ret = xlator_mem_acct_init(this, gf_rda_mt_end + 1);
-
- if (ret != 0)
- gf_log(this->name, GF_LOG_ERROR, "Memory accounting init"
- "failed");
-
-out:
- return ret;
-}
-
-int
-reconfigure(xlator_t *this, dict_t *options)
-{
- struct rda_priv *priv = this->private;
-
- GF_OPTION_RECONF("rda-request-size", priv->rda_req_size, options,
- uint32, err);
- GF_OPTION_RECONF("rda-low-wmark", priv->rda_low_wmark, options, size_uint64,
- err);
- GF_OPTION_RECONF("rda-high-wmark", priv->rda_high_wmark, options, size_uint64,
- err);
-
- return 0;
-err:
- return -1;
-}
-
-int
-init(xlator_t *this)
-{
- struct rda_priv *priv = NULL;
-
- GF_VALIDATE_OR_GOTO("readdir-ahead", this, err);
-
- if (!this->children || this->children->next) {
- gf_log(this->name, GF_LOG_ERROR,
- "FATAL: readdir-ahead not configured with exactly one"
- " child");
- goto err;
- }
-
- if (!this->parents) {
- gf_log(this->name, GF_LOG_WARNING,
- "dangling volume. check volfile ");
- }
-
- priv = GF_CALLOC(1, sizeof(struct rda_priv), gf_rda_mt_rda_priv);
- if (!priv)
- goto err;
- this->private = priv;
-
- this->local_pool = mem_pool_new(struct rda_local, 32);
- if (!this->local_pool)
- goto err;
-
- GF_OPTION_INIT("rda-request-size", priv->rda_req_size, uint32, err);
- GF_OPTION_INIT("rda-low-wmark", priv->rda_low_wmark, size_uint64, err);
- GF_OPTION_INIT("rda-high-wmark", priv->rda_high_wmark, size_uint64, err);
-
- return 0;
-
-err:
- if (this->local_pool)
- mem_pool_destroy(this->local_pool);
- if (priv)
- GF_FREE(priv);
-
- return -1;
-}
-
-
-void
-fini(xlator_t *this)
-{
- GF_VALIDATE_OR_GOTO ("readdir-ahead", this, out);
-
- GF_FREE(this->private);
-
-out:
- return;
-}
-
-struct xlator_fops fops = {
- .opendir = rda_opendir,
- .readdirp = rda_readdirp,
-};
-
-struct xlator_cbks cbks = {
- .releasedir = rda_releasedir,
-};
-
-struct volume_options options[] = {
- { .key = {"rda-request-size"},
- .type = GF_OPTION_TYPE_INT,
- .min = 4096,
- .max = 131072,
- .default_value = "131072",
- .description = "readdir-ahead request size",
- },
- { .key = {"rda-low-wmark"},
- .type = GF_OPTION_TYPE_SIZET,
- .min = 0,
- .max = 10 * GF_UNIT_MB,
- .default_value = "4096",
- .description = "the value under which we plug",
- },
- { .key = {"rda-high-wmark"},
- .type = GF_OPTION_TYPE_SIZET,
- .min = 0,
- .max = 100 * GF_UNIT_MB,
- .default_value = "131072",
- .description = "the value over which we unplug",
- },
- { .key = {NULL} },
-};
-
diff --git a/xlators/performance/readdir-ahead/src/readdir-ahead.h b/xlators/performance/readdir-ahead/src/readdir-ahead.h
deleted file mode 100644
index e48786daeca..00000000000
--- a/xlators/performance/readdir-ahead/src/readdir-ahead.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- Copyright (c) 2008-2013 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 __READDIR_AHEAD_H
-#define __READDIR_AHEAD_H
-
-/* state flags */
-#define RDA_FD_NEW (1 << 0)
-#define RDA_FD_RUNNING (1 << 1)
-#define RDA_FD_EOD (1 << 2)
-#define RDA_FD_ERROR (1 << 3)
-#define RDA_FD_BYPASS (1 << 4)
-#define RDA_FD_PLUGGED (1 << 5)
-
-struct rda_fd_ctx {
- off_t cur_offset; /* current head of the ctx */
- size_t cur_size; /* current size of the preload */
- off_t next_offset; /* tail of the ctx */
- uint32_t state;
- gf_lock_t lock;
- gf_dirent_t entries;
- call_frame_t *fill_frame;
- call_stub_t *stub;
- int op_errno;
-};
-
-struct rda_local {
- struct rda_fd_ctx *ctx;
- fd_t *fd;
- off_t offset;
-};
-
-struct rda_priv {
- uint32_t rda_req_size;
- uint64_t rda_low_wmark;
- uint64_t rda_high_wmark;
-};
-
-#endif /* __READDIR_AHEAD_H */
diff --git a/xlators/features/qemu-block/Makefile.am b/xlators/performance/stat-prefetch/Makefile.am
index af437a64d6d..af437a64d6d 100644
--- a/xlators/features/qemu-block/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 00000000000..cbea4bf5256
--- /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_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.c b/xlators/performance/stat-prefetch/src/stat-prefetch.c
new file mode 100644
index 00000000000..341583b4683
--- /dev/null
+++ b/xlators/performance/stat-prefetch/src/stat-prefetch.c
@@ -0,0 +1,3895 @@
+/*
+ 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
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that 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 "stat-prefetch.h"
+
+#define GF_SP_CACHE_BUCKETS 1
+#define GF_SP_CACHE_ENTRIES_EXPECTED 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;
+
+ if (ctx == NULL) {
+ goto out;
+ }
+
+ LOCK (&ctx->lock);
+ {
+ if (!list_empty (&ctx->waiting_ops)) {
+ gf_log (this->name, GF_LOG_CRITICAL, "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_CRITICAL,
+ "OP (%d)", stub->fop);
+
+ list_del_init (&stub->list);
+ call_stub_destroy (stub);
+ }
+ }
+ }
+ UNLOCK (&ctx->lock);
+
+ LOCK_DESTROY (&ctx->lock);
+ FREE (ctx);
+
+out:
+ return;
+}
+
+
+sp_inode_ctx_t *
+sp_inode_ctx_init ()
+{
+ sp_inode_ctx_t *inode_ctx = NULL;
+
+ inode_ctx = CALLOC (1, sizeof (*inode_ctx));
+ 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 stat *stbuf,
+ struct list_head *waiting_ops, int32_t *error)
+{
+ int32_t ret = 0;
+ sp_inode_ctx_t *inode_ctx = NULL;
+ uint64_t value = 0;
+
+ 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;
+ }
+
+ 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 == 0) && (stbuf != NULL)
+ && S_ISDIR (stbuf->st_mode)) {
+ memcpy (&inode_ctx->stbuf, stbuf,
+ sizeof (*stbuf));
+ }
+
+ if (waiting_ops != NULL) {
+ list_splice_init (&inode_ctx->waiting_ops,
+ waiting_ops);
+ }
+ }
+ UNLOCK (&inode_ctx->lock);
+
+out:
+ return ret;
+}
+
+
+sp_inode_ctx_t *
+sp_check_and_create_inode_ctx (xlator_t *this, inode_t *inode,
+ sp_expect_t expect, glusterfs_fop_t caller)
+{
+ uint64_t value = 0;
+ sp_inode_ctx_t *inode_ctx = NULL;
+ int32_t ret = 0;
+
+ if ((this == NULL) || (inode == NULL)) {
+ goto out;
+ }
+
+ LOCK (&inode->lock);
+ {
+ ret = __inode_ctx_get (inode, this, &value);
+ if (ret == 0) {
+ if (expect == SP_DONT_EXPECT) {
+ gf_log (this->name, GF_LOG_DEBUG, "inode_ctx "
+ "is not NULL (caller %d)", caller);
+ }
+
+ inode_ctx = (sp_inode_ctx_t *)(long)value;
+ } else {
+ if (expect == SP_EXPECT) {
+ gf_log (this->name, GF_LOG_DEBUG, "inode_ctx is"
+ " NULL (caller %d)", caller);
+ }
+
+ 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);
+ 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, glusterfs_fop_t caller)
+{
+ int32_t ret = -1, op_errno = -1;
+ sp_local_t *local = NULL;
+ sp_inode_ctx_t *inode_ctx = NULL;
+ uint64_t value = 0;
+
+ if (need_unwind != NULL) {
+ *need_unwind = 1;
+ }
+
+ if ((this == NULL) || (loc == NULL) || (loc->inode == NULL)
+ || (need_unwind == NULL) || (need_lookup == NULL)
+ || (can_wind == NULL)) {
+ op_errno = EINVAL;
+ goto out;
+ }
+
+ ret = inode_ctx_get (loc->inode, this, &value);
+ if (ret == -1) {
+ gf_log (this->name, GF_LOG_DEBUG, "context not set in inode "
+ "(%p) (caller %d)", loc->inode, caller);
+ *can_wind = 1;
+ *need_unwind = 0;
+ op_errno = 0;
+ ret = 0;
+ goto out;
+ }
+
+ inode_ctx = (sp_inode_ctx_t *)(long) value;
+ GF_VALIDATE_OR_GOTO_WITH_ERROR (this->name, inode_ctx, out, op_errno,
+ EINVAL);
+
+ LOCK (&inode_ctx->lock);
+ {
+ if (!(inode_ctx->looked_up || inode_ctx->lookup_in_progress)) {
+ if (frame->local == NULL) {
+ local = CALLOC (1, sizeof (*local));
+ GF_VALIDATE_OR_GOTO_WITH_ERROR (this->name,
+ local,
+ unlock,
+ op_errno,
+ ENOMEM);
+
+ frame->local = local;
+
+ ret = loc_copy (&local->loc, loc);
+ if (ret == -1) {
+ op_errno = errno;
+ gf_log (this->name, GF_LOG_ERROR, "%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;
+
+ priv = this->private;
+
+ if (!priv)
+ goto out;
+
+ if (!priv->mem_pool)
+ goto out;
+
+ cache = CALLOC (1, sizeof (*cache));
+ if (cache) {
+ cache->table =
+ rbthash_table_init (GF_SP_CACHE_BUCKETS,
+ sp_hashfn, free,
+ 0, priv->mem_pool);
+ if (cache->table == NULL) {
+ 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);
+ 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;
+ sp_private_t *priv = NULL;
+ void *data = NULL;
+
+ if ((cache == NULL) || ((name == NULL) && !remove_all)) {
+ goto out;
+ }
+
+ this = cache->this;
+
+ if (this == NULL)
+ goto out;
+
+ if (this->private == NULL)
+ goto out;
+
+ priv = this->private;
+
+ LOCK (&cache->lock);
+ {
+ if (remove_all) {
+ table = cache->table;
+ cache->table = rbthash_table_init (GF_SP_CACHE_BUCKETS,
+ sp_hashfn,
+ free,
+ 0,
+ priv->mem_pool);
+ if (cache->table == NULL) {
+ cache->table = table;
+ } else {
+ rbthash_table_destroy (table);
+ ret = 0;
+ }
+ } else {
+ data = rbthash_remove (cache->table, name,
+ strlen (name));
+ FREE (data);
+ ret = 0;
+ }
+ }
+ 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;
+
+ if ((cache == NULL) || (name == NULL) || (entry == NULL)) {
+ goto 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) {
+ 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;
+
+ if (fd == NULL) {
+ goto 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) {
+ FREE (fd_ctx->name);
+ fd_ctx->name = NULL;
+ }
+
+ if (fd_ctx->cache) {
+ sp_cache_free (fd_ctx->cache);
+ }
+
+ FREE (fd_ctx);
+out:
+ return;
+}
+
+
+inline sp_fd_ctx_t *
+sp_fd_ctx_init (void)
+{
+ sp_fd_ctx_t *fd_ctx = NULL;
+
+ fd_ctx = CALLOC (1, sizeof (*fd_ctx));
+
+ 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) {
+ gf_log (this->name, GF_LOG_ERROR, "out of memory");
+ goto out;
+ }
+
+ if (parent) {
+ fd_ctx->parent_inode = inode_ref (parent);
+ }
+
+ if (name) {
+ fd_ctx->name = strdup (name);
+ if (fd_ctx->name == NULL) {
+ sp_fd_ctx_free (fd_ctx);
+ fd_ctx = NULL;
+ }
+ }
+
+ 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;
+}
+
+
+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) {
+ gf_log (this->name, GF_LOG_ERROR, "out of memory");
+ ret = -1;
+ goto out;
+ }
+
+ ret = __fd_ctx_set (fd, this, (long)(void *)fd_ctx);
+ if (ret == -1) {
+ 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;
+
+ LOCK (&cache->lock);
+ {
+ list_for_each_entry (entry, &entries->list, list) {
+ if (S_ISDIR (entry->d_stat.st_mode)) {
+ continue;
+ }
+
+ new = gf_dirent_for_name (entry->d_name);
+ if (new == NULL) {
+ 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) {
+ FREE (new);
+ continue;
+ }
+
+ expected_offset = new->d_off;
+ }
+
+ cache->expected_offset = expected_offset;
+
+ ret = 0;
+ }
+unlock:
+ UNLOCK (&cache->lock);
+
+ 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 stat *buf, dict_t *dict, struct stat *postparent)
+{
+ int ret = 0;
+ struct list_head waiting_ops = {0, };
+ call_stub_t *stub = NULL, *tmp = NULL;
+ sp_local_t *local = NULL;
+ sp_cache_t *cache = NULL;
+ int need_unwind = 0;
+ char looked_up = 0, lookup_in_progress = 0;
+
+ INIT_LIST_HEAD (&waiting_ops);
+
+ local = frame->local;
+ if (local == NULL) {
+ op_ret = -1;
+ op_errno = EINVAL;
+ gf_log (this->name, GF_LOG_DEBUG, "local is NULL, but it is "
+ "needed to find and resume operations waiting on "
+ "lookup");
+ goto out;
+ }
+ if (op_ret == -1) {
+ cache = sp_get_cache_inode (this, local->loc.parent,
+ frame->root->pid);
+
+ if (cache) {
+ sp_cache_remove_entry (cache, (char *)local->loc.name,
+ 0);
+ sp_cache_unref (cache);
+ }
+ }
+
+ if (local->is_lookup)
+ need_unwind = 1;
+
+ lookup_in_progress = 0;
+ looked_up = 1;
+ ret = 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 = strdup (path);
+ if (cpy == NULL) {
+ 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;
+ sp_cache_t *cache_gp = NULL;
+ int32_t ret = -1;
+
+ ret = sp_get_ancestors (path, &parent, &grand_parent);
+ if (ret == -1) {
+ gf_log (this->name, GF_LOG_ERROR, "out of memory");
+ goto out;
+ }
+
+ if (grand_parent && strcmp (grand_parent, "/")) {
+ inode_gp = inode_from_path (itable, grand_parent);
+ if (inode_gp) {
+ cache_gp = sp_get_cache_inode (this, inode_gp,
+ frame->root->pid);
+ if (cache_gp) {
+ cpy = strdup (parent);
+ GF_VALIDATE_OR_GOTO_WITH_ERROR (this->name,
+ cpy, out, errno,
+ ENOMEM);
+ path = basename (cpy);
+ sp_cache_remove_entry (cache_gp, path, 0);
+ FREE (cpy);
+
+ sp_cache_unref (cache_gp);
+ }
+ inode_unref (inode_gp);
+ }
+ }
+
+ ret = 0;
+out:
+ if (parent) {
+ FREE (parent);
+ }
+
+ if (grand_parent) {
+ FREE (grand_parent);
+ }
+
+ return ret;
+}
+
+
+void
+sp_is_empty (dict_t *this, char *key, data_t *value, void *data)
+{
+ char *ptr = data;
+
+ 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 = -1;
+ 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_DEBUG, "context not set in inode "
+ "(%p)", loc->inode);
+ 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 stat 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;
+
+ if (loc == NULL || loc->inode == NULL) {
+ goto unwind;
+ }
+
+ inode_ctx = sp_check_and_create_inode_ctx (this, loc->inode,
+ SP_DONT_CARE, GF_FOP_LOOKUP);
+ if (inode_ctx == NULL) {
+ op_errno = ENOMEM;
+ 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;
+ }
+
+ FREE (dirent);
+ }
+ } else if (S_ISDIR (loc->inode->st_mode)) {
+ 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;
+ }
+
+ 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 = CALLOC (1, sizeof (*local));
+ 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_ERROR, "%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->inode, &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;
+
+ if (op_ret == -1) {
+ goto out;
+ }
+
+ if (!this->private) {
+ goto out;
+ }
+
+ local = frame->local;
+ if (local == NULL) {
+ 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) {
+ goto unlock;
+ }
+
+ ret = __sp_put_cache (this, fd, cache);
+ if (ret == -1) {
+ sp_cache_free (cache);
+ 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;
+
+ 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 == -1) {
+ goto unwind;
+ }
+
+ ret = sp_cache_remove_parent_entry (frame, this, fd->inode->table,
+ path);
+
+ FREE (path);
+
+ if (ret < 0) {
+ errno = -ret;
+ goto unwind;
+ }
+
+ local = CALLOC (1, sizeof (*local));
+ 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:
+ SP_STACK_UNWIND (readdir, frame, -1, 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 stat *prebuf,
+ struct stat *postbuf)
+{
+ 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 stat *buf,
+ struct stat *preoldparent, struct stat *postoldparent,
+ struct stat *prenewparent, struct stat *postnewparent)
+{
+ 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;
+
+ if (op_ret == -1) {
+ goto out;
+ }
+
+ local = frame->local;
+ GF_VALIDATE_OR_GOTO_WITH_ERROR (this->name, local, out, op_errno,
+ EINVAL);
+
+ fd_ctx = sp_fd_ctx_new (this, local->loc.parent,
+ (char *)local->loc.name, NULL);
+ GF_VALIDATE_OR_GOTO_WITH_ERROR (this->name, fd_ctx, out, op_errno,
+ ENOMEM);
+
+ op_ret = fd_ctx_set (fd, this, (long)(void *)fd_ctx);
+ if (op_ret == -1) {
+ 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 = -1;
+
+ ret = inode_ctx_get (loc->inode, this, &value);
+ if (ret == -1) {
+ gf_log (this->name, GF_LOG_DEBUG, "context not set in inode "
+ "(%p)", loc->inode);
+ 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)))) {
+ 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 = -1, ret = -1;
+ char can_wind = 0, need_lookup = 0, need_unwind = 1;
+
+ GF_VALIDATE_OR_GOTO_WITH_ERROR (this->name, loc, out, op_errno,
+ EINVAL);
+ GF_VALIDATE_OR_GOTO_WITH_ERROR (this->name, loc->inode, out,
+ op_errno, EINVAL);
+
+ local = CALLOC (1, sizeof (*local));
+ 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_ERROR, "%s", strerror (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, GF_FOP_OPEN);
+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 stat *buf, struct stat *preparent,
+ struct stat *postparent)
+{
+ sp_local_t *local = NULL;
+ sp_fd_ctx_t *fd_ctx = NULL;
+ char lookup_in_progress = 0, looked_up = 0;
+
+ if (op_ret == -1) {
+ goto out;
+ }
+
+ local = frame->local;
+ GF_VALIDATE_OR_GOTO_WITH_ERROR (this->name, local, out, op_errno,
+ EINVAL);
+
+ 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) {
+ goto out;
+ }
+
+ sp_update_inode_ctx (this, local->loc.parent, NULL, NULL, NULL,
+ NULL, postparent, NULL, NULL);
+
+ fd_ctx = sp_fd_ctx_new (this, local->loc.parent,
+ (char *)local->loc.name, NULL);
+ GF_VALIDATE_OR_GOTO_WITH_ERROR (this->name, fd_ctx, out, op_errno,
+ ENOMEM);
+
+ op_ret = fd_ctx_set (fd, this, (long)(void *)fd_ctx);
+ if (op_ret == -1) {
+ 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)
+{
+ 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;
+ gf_log (this->name, GF_LOG_ERROR, "out of memory");
+ goto out;
+ }
+
+ local = CALLOC (1, sizeof (*local));
+ 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;
+ goto out;
+ }
+
+ inode_ctx = sp_check_and_create_inode_ctx (this, loc->inode,
+ SP_DONT_EXPECT,
+ GF_FOP_CREATE);
+ if (inode_ctx == NULL) {
+ op_errno = ENOMEM;
+ 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);
+ }
+ 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 = -1;
+
+ ret = inode_ctx_get (loc->inode, this, &value);
+ if (ret == -1) {
+ gf_log (this->name, GF_LOG_DEBUG, "context not set in inode "
+ "(%p)", loc->inode);
+ 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) {
+ 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 = -1, ret = -1;
+ char can_wind = 0, need_lookup = 0, need_unwind = 1;
+
+ GF_VALIDATE_OR_GOTO_WITH_ERROR (this->name, loc, out, op_errno,
+ EINVAL);
+ GF_VALIDATE_OR_GOTO_WITH_ERROR (this->name, loc->inode, out,
+ op_errno, EINVAL);
+
+ local = CALLOC (1, sizeof (*local));
+ 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;
+ goto out;
+ }
+
+ stub = fop_opendir_stub (frame, sp_opendir_helper, loc, fd);
+ if (stub == NULL) {
+ op_errno = ENOMEM;
+ gf_log (this->name, GF_LOG_ERROR, "out of memory");
+ goto out;
+ }
+
+ sp_process_inode_ctx (frame, this, loc, stub, &need_unwind,
+ &need_lookup, &can_wind, &op_errno,
+ GF_FOP_OPENDIR);
+
+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 stat *buf, struct stat *preparent,
+ struct stat *postparent)
+{
+ sp_local_t *local = NULL;
+ char lookup_in_progress = 0, looked_up = 0;
+
+ if (op_ret == -1) {
+ goto out;
+ }
+
+ local = frame->local;
+ if (local == NULL) {
+ 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) {
+ goto out;
+ }
+
+ sp_update_inode_ctx (this, local->loc.parent, NULL, NULL, NULL,
+ NULL, postparent, NULL, NULL);
+
+out:
+ SP_STACK_UNWIND (mkdir, frame, op_ret, op_errno, inode, buf, preparent,
+ postparent);
+ return 0;
+}
+
+
+int32_t
+sp_mkdir (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode)
+{
+ int32_t ret = -1, op_errno = -1;
+ char need_unwind = 1;
+ sp_inode_ctx_t *inode_ctx = NULL;
+ sp_local_t *local = 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;
+ gf_log (this->name, GF_LOG_ERROR, "out of memory");
+ goto out;
+ }
+
+ local = CALLOC (1, sizeof (*local));
+ 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_ERROR, "%s", strerror (op_errno));
+ goto out;
+ }
+
+ inode_ctx = sp_check_and_create_inode_ctx (this, loc->inode,
+ SP_DONT_EXPECT,
+ GF_FOP_MKDIR);
+ if (inode_ctx == NULL) {
+ op_errno = ENOMEM;
+ 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);
+ }
+
+ return 0;
+}
+
+
+int32_t
+sp_mknod (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
+ dev_t rdev)
+{
+ int32_t op_errno = -1, ret = -1;
+ char need_unwind = 1;
+ sp_inode_ctx_t *inode_ctx = NULL;
+ sp_local_t *local = 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;
+ gf_log (this->name, GF_LOG_ERROR, "out of memory");
+ goto out;
+ }
+
+ local = CALLOC (1, sizeof (*local));
+ 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_ERROR, "%s", strerror (op_errno));
+ goto out;
+ }
+
+ inode_ctx = sp_check_and_create_inode_ctx (this, loc->inode,
+ SP_DONT_EXPECT,
+ GF_FOP_MKNOD);
+ if (inode_ctx == NULL) {
+ op_errno = ENOMEM;
+ 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);
+ }
+
+ return 0;
+}
+
+
+int32_t
+sp_symlink (call_frame_t *frame, xlator_t *this, const char *linkpath,
+ loc_t *loc)
+{
+ int32_t ret = -1, op_errno = -1;
+ char need_unwind = 1;
+ sp_inode_ctx_t *inode_ctx = NULL;
+ sp_local_t *local = 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;
+ gf_log (this->name, GF_LOG_ERROR, "out of memory");
+ goto out;
+ }
+
+ local = CALLOC (1, sizeof (*local));
+ 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_ERROR, "%s", strerror (op_errno));
+ goto out;
+ }
+
+ inode_ctx = sp_check_and_create_inode_ctx (this, loc->inode,
+ SP_DONT_EXPECT,
+ GF_FOP_SYMLINK);
+ if (inode_ctx == NULL) {
+ op_errno = ENOMEM;
+ 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);
+ }
+
+ 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 stat *buf, struct stat *preparent,
+ struct stat *postparent)
+{
+ 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 = -1;
+
+ ret = inode_ctx_get (oldloc->inode, this, &value);
+ if (ret == -1) {
+ gf_log (this->name, GF_LOG_DEBUG, "context not set in inode "
+ "(%p)", oldloc->inode);
+ 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) {
+ 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;
+ sp_cache_t *cache = NULL;
+ int32_t ret = 0, op_errno = -1;
+ char can_wind = 0, need_lookup = 0, need_unwind = 1;
+
+ GF_VALIDATE_OR_GOTO_WITH_ERROR (this->name, newloc, out, op_errno,
+ EINVAL);
+ GF_VALIDATE_OR_GOTO_WITH_ERROR (this->name, newloc->path, out,
+ op_errno, EINVAL);
+ GF_VALIDATE_OR_GOTO_WITH_ERROR (this->name, newloc->name, out,
+ op_errno, EINVAL);
+ GF_VALIDATE_OR_GOTO_WITH_ERROR (this->name, newloc->inode, out,
+ op_errno, EINVAL);
+
+ GF_VALIDATE_OR_GOTO_WITH_ERROR (this->name, oldloc->name, out,
+ op_errno, EINVAL);
+
+ ret = sp_cache_remove_parent_entry (frame, this, newloc->parent->table,
+ (char *)newloc->path);
+ if (ret == -1) {
+ op_errno = ENOMEM;
+ gf_log (this->name, GF_LOG_ERROR, "out of memory");
+ goto out;
+ }
+
+ cache = sp_get_cache_inode (this, oldloc->parent, frame->root->pid);
+ if (cache) {
+ sp_cache_remove_entry (cache, (char *)oldloc->name, 0);
+ sp_cache_unref (cache);
+ }
+
+ stub = fop_link_stub (frame, sp_link_helper, oldloc, newloc);
+ if (stub == NULL) {
+ op_errno = ENOMEM;
+ gf_log (this->name, GF_LOG_ERROR, "out of memory");
+ goto out;
+ }
+
+ sp_process_inode_ctx (frame, this, oldloc, stub, &need_unwind,
+ &need_lookup, &can_wind, &op_errno, GF_FOP_LINK);
+
+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 = -1;
+
+ ret = inode_ctx_get (loc->inode, this, &value);
+ if (ret == -1) {
+ gf_log (this->name, GF_LOG_DEBUG, "context not set in inode "
+ "(%p)", loc->inode);
+ 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) {
+ 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)
+{
+ sp_cache_t *cache = NULL;
+ int32_t op_errno = -1;
+ call_stub_t *stub = NULL;
+ char can_wind = 0, need_lookup = 0, need_unwind = 1;
+
+ GF_VALIDATE_OR_GOTO_WITH_ERROR (this->name, loc, out, op_errno,
+ EINVAL);
+ GF_VALIDATE_OR_GOTO_WITH_ERROR (this->name, loc->name, out, op_errno,
+ EINVAL);
+
+ cache = sp_get_cache_inode (this, loc->parent, frame->root->pid);
+ if (cache) {
+ sp_cache_remove_entry (cache, (char *)loc->name, 0);
+ sp_cache_unref (cache);
+ }
+
+ stub = fop_truncate_stub (frame, sp_truncate_helper, loc, offset);
+ if (stub == NULL) {
+ op_errno = ENOMEM;
+ gf_log (this->name, GF_LOG_ERROR, "out of memory");
+ goto out;
+ }
+
+ sp_process_inode_ctx (frame, this, loc, stub, &need_unwind,
+ &need_lookup, &can_wind, &op_errno,
+ GF_FOP_TRUNCATE);
+
+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;
+ sp_cache_t *cache = NULL;
+ uint64_t value = 0;
+ int32_t ret = 0;
+ inode_t *parent = NULL;
+ char *name = NULL;
+
+ ret = fd_ctx_get (fd, this, &value);
+ if (ret == -1) {
+ errno = EINVAL;
+ goto unwind;
+ }
+
+ fd_ctx = (void *)(long)value;
+ name = fd_ctx->name;
+ parent = fd_ctx->parent_inode;
+
+ cache = sp_get_cache_inode (this, parent, frame->root->pid);
+ if (cache) {
+ sp_cache_remove_entry (cache, name, 0);
+ sp_cache_unref (cache);
+ }
+
+ 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, 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 stat *prestat, struct stat *poststat)
+{
+ 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 stat *buf, int32_t valid)
+{
+ uint64_t value = 0;
+ sp_inode_ctx_t *inode_ctx = NULL;
+ int32_t ret = 0, op_ret = -1, op_errno = -1;
+
+ ret = inode_ctx_get (loc->inode, this, &value);
+ if (ret == -1) {
+ gf_log (this->name, GF_LOG_DEBUG, "context not set in inode "
+ "(%p)", loc->inode);
+ 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) {
+ 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 stat *buf, int32_t valid)
+{
+ sp_cache_t *cache = NULL;
+ int32_t op_errno = -1;
+ call_stub_t *stub = NULL;
+ char can_wind = 0, need_lookup = 0, need_unwind = 1;
+
+ GF_VALIDATE_OR_GOTO_WITH_ERROR (this->name, loc, out, op_errno,
+ EINVAL);
+ GF_VALIDATE_OR_GOTO_WITH_ERROR (this->name, loc->name, out, op_errno,
+ EINVAL);
+
+ cache = sp_get_cache_inode (this, loc->parent, frame->root->pid);
+ if (cache) {
+ sp_cache_remove_entry (cache, (char *)loc->name, 0);
+ sp_cache_unref (cache);
+ }
+
+ stub = fop_setattr_stub (frame, sp_setattr_helper, loc, buf, valid);
+ if (stub == NULL) {
+ op_errno = ENOMEM;
+ gf_log (this->name, GF_LOG_ERROR, "out of memory");
+ goto out;
+ }
+
+ sp_process_inode_ctx (frame, this, loc, stub, &need_unwind,
+ &need_lookup, &can_wind, &op_errno,
+ GF_FOP_SETATTR);
+
+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 stat *buf)
+{
+ 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 = -1;
+
+ ret = inode_ctx_get (loc->inode, this, &value);
+ if (ret == -1) {
+ gf_log (this->name, GF_LOG_DEBUG, "context not set in inode "
+ "(%p)", loc->inode);
+ 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) {
+ 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)
+{
+ sp_cache_t *cache = NULL;
+ int32_t op_errno = -1;
+ call_stub_t *stub = NULL;
+ char can_wind = 0, need_lookup = 0, need_unwind = 1;
+
+ GF_VALIDATE_OR_GOTO_WITH_ERROR (this->name, loc, out, op_errno,
+ EINVAL);
+ GF_VALIDATE_OR_GOTO_WITH_ERROR (this->name, loc->name, out,
+ op_errno, EINVAL);
+
+ cache = sp_get_cache_inode (this, loc->parent, frame->root->pid);
+ if (cache) {
+ sp_cache_remove_entry (cache, (char *)loc->name, 0);
+ sp_cache_unref (cache);
+ }
+
+ stub = fop_readlink_stub (frame, sp_readlink_helper, loc, size);
+ if (stub == NULL) {
+ op_errno = ENOMEM;
+ gf_log (this->name, GF_LOG_ERROR, "out of memory");
+ goto out;
+ }
+
+ sp_process_inode_ctx (frame, this, loc, stub, &need_unwind,
+ &need_lookup, &can_wind, &op_errno,
+ GF_FOP_READLINK);
+
+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 stat *preparent,
+ struct stat *postparent)
+{
+ 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)
+{
+ 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 = -1;
+
+ ret = inode_ctx_get (loc->inode, this, &value);
+ if (ret == -1) {
+ gf_log (this->name, GF_LOG_DEBUG, "context not set in inode "
+ "(%p)", loc->inode);
+ 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) {
+ 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)
+{
+ sp_cache_t *cache = NULL;
+ int32_t ret = -1, op_errno = -1;
+ call_stub_t *stub = NULL;
+ char can_wind = 0, need_lookup = 0, need_unwind = 1;
+
+ GF_VALIDATE_OR_GOTO_WITH_ERROR (this->name, loc, out, op_errno,
+ EINVAL);
+ GF_VALIDATE_OR_GOTO_WITH_ERROR (this->name, loc->name, out, op_errno,
+ EINVAL);
+
+ cache = sp_get_cache_inode (this, loc->parent, frame->root->pid);
+ if (cache) {
+ sp_cache_remove_entry (cache, (char *)loc->name, 0);
+ sp_cache_unref (cache);
+ }
+
+ 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_ERROR, "out of memory");
+ goto out;
+ }
+
+ stub = fop_unlink_stub (frame, sp_unlink_helper, loc);
+ if (stub == NULL) {
+ op_errno = ENOMEM;
+ gf_log (this->name, GF_LOG_ERROR, "out of memory");
+ goto out;
+ }
+
+ sp_process_inode_ctx (frame, this, loc, stub, &need_unwind,
+ &need_lookup, &can_wind, &op_errno,
+ GF_FOP_UNLINK);
+
+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;
+}
+
+
+void
+sp_remove_caches_from_all_fds_opened (xlator_t *this, inode_t *inode)
+{
+ fd_t *fd = NULL;
+ sp_cache_t *cache = NULL;
+
+ LOCK (&inode->lock);
+ {
+ list_for_each_entry (fd, &inode->fd_list, inode_list) {
+ cache = sp_get_cache_fd (this, fd);
+ if (cache) {
+ sp_cache_remove_entry (cache, NULL, 1);
+ sp_cache_unref (cache);
+ }
+ }
+ }
+ UNLOCK (&inode->lock);
+}
+
+
+int32_t
+sp_rmdir_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 = -1;
+
+ ret = inode_ctx_get (loc->inode, this, &value);
+ if (ret == -1) {
+ gf_log (this->name, GF_LOG_DEBUG, "context not set in inode "
+ "(%p)", loc->inode);
+ 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) {
+ goto unwind;
+ }
+
+ STACK_WIND (frame, sp_unlink_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->rmdir, loc);
+
+ return 0;
+
+unwind:
+ SP_STACK_UNWIND (rmdir, frame, -1, op_errno, NULL, NULL);
+ return 0;
+}
+
+
+int32_t
+sp_rmdir (call_frame_t *frame, xlator_t *this, loc_t *loc)
+{
+ sp_cache_t *cache = NULL;
+ int32_t ret = -1, op_errno = -1;
+ call_stub_t *stub = NULL;
+ char can_wind = 0, need_lookup = 0, need_unwind = 1;
+
+ GF_VALIDATE_OR_GOTO_WITH_ERROR (this->name, loc, 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->path, out, op_errno,
+ EINVAL);
+ GF_VALIDATE_OR_GOTO_WITH_ERROR (this->name, loc->inode, out,
+ op_errno, EINVAL);
+
+ sp_remove_caches_from_all_fds_opened (this, loc->inode);
+
+ cache = sp_get_cache_inode (this, loc->parent, frame->root->pid);
+ if (cache) {
+ sp_cache_remove_entry (cache, (char *)loc->name, 0);
+ sp_cache_unref (cache);
+ }
+
+ 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_ERROR, "out of memory");
+ goto out;
+ }
+
+ stub = fop_rmdir_stub (frame, sp_rmdir_helper, loc);
+ if (stub == NULL) {
+ op_errno = ENOMEM;
+ gf_log (this->name, GF_LOG_ERROR, "out of memory");
+ goto out;
+ }
+
+ sp_process_inode_ctx (frame, this, loc, stub, &need_unwind,
+ &need_lookup, &can_wind, &op_errno,
+ GF_FOP_RMDIR);
+
+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);
+ }
+
+ 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 stat *stbuf, struct iobref *iobref)
+{
+ 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;
+ sp_cache_t *cache = NULL;
+ uint64_t value = 0;
+ int32_t ret = 0;
+ inode_t *parent = NULL;
+ char *name = NULL;
+
+ ret = fd_ctx_get (fd, this, &value);
+ if (ret == -1) {
+ errno = EINVAL;
+ goto unwind;
+ }
+
+ fd_ctx = (void *)(long)value;
+ name = fd_ctx->name;
+ parent = fd_ctx->parent_inode;
+
+ cache = sp_get_cache_inode (this, parent, frame->root->pid);
+ if (cache) {
+ sp_cache_remove_entry (cache, name, 0);
+ sp_cache_unref (cache);
+ }
+
+ 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, 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;
+ sp_cache_t *cache = NULL;
+ uint64_t value = 0;
+ int32_t ret = 0;
+ inode_t *parent = NULL;
+ char *name = NULL;
+
+ ret = fd_ctx_get (fd, this, &value);
+ if (ret == -1) {
+ errno = EINVAL;
+ goto unwind;
+ }
+
+ fd_ctx = (void *)(long)value;
+ name = fd_ctx->name;
+ parent = fd_ctx->parent_inode;
+
+ cache = sp_get_cache_inode (this, parent, frame->root->pid);
+ if (cache) {
+ sp_cache_remove_entry (cache, name, 0);
+ sp_cache_unref (cache);
+ }
+
+ 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, 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;
+ sp_cache_t *cache = NULL;
+ uint64_t value = 0;
+ int32_t ret = 0;
+ inode_t *parent = NULL;
+ char *name = NULL;
+
+ ret = fd_ctx_get (fd, this, &value);
+ if (ret == -1) {
+ errno = EINVAL;
+ goto unwind;
+ }
+
+ fd_ctx = (void *)(long)value;
+ name = fd_ctx->name;
+ parent = fd_ctx->parent_inode;
+
+ cache = sp_get_cache_inode (this, parent, frame->root->pid);
+ if (cache) {
+ sp_cache_remove_entry (cache, name, 0);
+ sp_cache_unref (cache);
+ }
+
+ 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, 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 = -1;
+ 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;
+
+ ret = inode_ctx_get (oldloc->inode, this, &value);
+ if (ret == -1) {
+ gf_log (this->name, GF_LOG_DEBUG, "context not set in inode "
+ "(%p)", oldloc->inode);
+ op_errno = EINVAL;
+ goto unwind;
+ }
+
+ old_inode_ctx = (sp_inode_ctx_t *)(long) value;
+ GF_VALIDATE_OR_GOTO_WITH_ERROR (this->name, old_inode_ctx, unwind,
+ op_errno, EINVAL);
+
+ 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 */
+ 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) {
+ 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) {
+ op_errno = old_op_errno;
+ } else {
+ 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_cache_t *cache = NULL;
+ sp_inode_ctx_t *inode_ctx = NULL;
+ int32_t ret = -1, op_errno = -1;
+ char old_inode_can_wind = 0, new_inode_can_wind = 0;
+ char old_inode_need_lookup = 0, new_inode_need_lookup = 0;
+
+ GF_VALIDATE_OR_GOTO_WITH_ERROR (this->name, oldloc, out, op_errno,
+ EINVAL);
+ GF_VALIDATE_OR_GOTO_WITH_ERROR (this->name, oldloc->path, out,
+ op_errno, EINVAL);
+ GF_VALIDATE_OR_GOTO_WITH_ERROR (this->name, oldloc->name, out,
+ op_errno, EINVAL);
+ GF_VALIDATE_OR_GOTO_WITH_ERROR (this->name, oldloc->inode, out,
+ op_errno, EINVAL);
+
+ GF_VALIDATE_OR_GOTO_WITH_ERROR (this->name, newloc, out, op_errno,
+ EINVAL);
+ GF_VALIDATE_OR_GOTO_WITH_ERROR (this->name, newloc->path, out,
+ op_errno, EINVAL);
+
+ cache = sp_get_cache_inode (this, oldloc->parent, frame->root->pid);
+ if (cache) {
+ sp_cache_remove_entry (cache, (char *)oldloc->name, 0);
+ sp_cache_unref (cache);
+ }
+
+ cache = sp_get_cache_inode (this, newloc->parent, frame->root->pid);
+ if (cache) {
+ sp_cache_remove_entry (cache, (char *)newloc->name, 0);
+ sp_cache_unref (cache);
+ }
+
+ ret = sp_cache_remove_parent_entry (frame, this, oldloc->parent->table,
+ (char *)oldloc->path);
+ if (ret == -1) {
+ gf_log (this->name, GF_LOG_ERROR, "out of memory");
+ 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_ERROR, "out of memory");
+ goto out;
+ }
+
+ if (S_ISDIR (oldloc->inode->st_mode)) {
+ sp_remove_caches_from_all_fds_opened (this, oldloc->inode);
+ }
+
+ stub = fop_rename_stub (frame, sp_rename_helper, oldloc, newloc);
+ if (stub == NULL) {
+ op_errno = ENOMEM;
+ gf_log (this->name, GF_LOG_ERROR, "out of memory");
+ goto out;
+ }
+
+ ret = sp_process_inode_ctx (frame, this, oldloc, stub, &need_unwind,
+ &old_inode_need_lookup, &old_inode_can_wind,
+ &op_errno, GF_FOP_RENAME);
+ if (ret == -1) {
+ goto out;
+ }
+
+ if (newloc->inode != NULL) {
+ stub = fop_rename_stub (frame, sp_rename_helper, oldloc,
+ newloc);
+ if (stub == NULL) {
+ op_errno = ENOMEM;
+ gf_log (this->name, GF_LOG_ERROR, "out of memory");
+ goto out;
+ }
+
+ ret = sp_process_inode_ctx (frame, this, newloc, stub,
+ &need_unwind,
+ &new_inode_need_lookup,
+ &new_inode_can_wind, &op_errno,
+ GF_FOP_RENAME);
+ if (ret == -1) {
+ ret = inode_ctx_get (oldloc->inode, this, &value);
+ if (ret == -1) {
+ goto out;
+ }
+
+ inode_ctx = (sp_inode_ctx_t *)(long)value;
+ if (inode_ctx == NULL) {
+ 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 = -1;
+
+ ret = inode_ctx_get (loc->inode, this, &value);
+ if (ret == -1) {
+ gf_log (this->name, GF_LOG_DEBUG, "context not set in inode "
+ "(%p)", loc->inode);
+ 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) {
+ 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)
+{
+ sp_cache_t *cache = NULL;
+ int32_t op_errno = -1;
+ call_stub_t *stub = NULL;
+ char can_wind = 0, need_lookup = 0, need_unwind = 1;
+
+ GF_VALIDATE_OR_GOTO_WITH_ERROR (this->name, loc, out, op_errno,
+ EINVAL);
+ GF_VALIDATE_OR_GOTO_WITH_ERROR (this->name, loc->name, out, op_errno,
+ EINVAL);
+
+ cache = sp_get_cache_inode (this, loc->parent, frame->root->pid);
+ if (cache) {
+ sp_cache_remove_entry (cache, (char *)loc->name, 0);
+ sp_cache_unref (cache);
+ }
+
+ stub = fop_setxattr_stub (frame, sp_setxattr_helper, loc, dict, flags);
+ if (stub == NULL) {
+ op_errno = ENOMEM;
+ gf_log (this->name, GF_LOG_ERROR, "out of memory");
+ goto out;
+ }
+
+ sp_process_inode_ctx (frame, this, loc, stub, &need_unwind,
+ &need_lookup, &can_wind, &op_errno,
+ GF_FOP_SETXATTR);
+
+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 = -1;
+
+ ret = inode_ctx_get (loc->inode, this, &value);
+ if (ret == -1) {
+ gf_log (this->name, GF_LOG_DEBUG, "context not set in inode "
+ "(%p)", loc->inode);
+ 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) {
+ 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)
+{
+ sp_cache_t *cache = NULL;
+ int32_t op_errno = -1;
+ call_stub_t *stub = NULL;
+ char can_wind = 0, need_lookup = 0, need_unwind = 1;
+
+ GF_VALIDATE_OR_GOTO_WITH_ERROR (this->name, loc, out, op_errno,
+ EINVAL);
+ GF_VALIDATE_OR_GOTO_WITH_ERROR (this->name, loc->name, out, op_errno,
+ EINVAL);
+
+ cache = sp_get_cache_inode (this, loc->parent, frame->root->pid);
+ if (cache) {
+ sp_cache_remove_entry (cache, (char *)loc->name, 0);
+ sp_cache_unref (cache);
+ }
+
+ stub = fop_removexattr_stub (frame, sp_removexattr_helper, loc, name);
+ if (stub == NULL) {
+ op_errno = ENOMEM;
+ gf_log (this->name, GF_LOG_ERROR, "out of memory");
+ goto out;
+ }
+
+ sp_process_inode_ctx (frame, this, loc, stub, &need_unwind,
+ &need_lookup, &can_wind, &op_errno,
+ GF_FOP_REMOVEXATTR);
+
+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)
+{
+ 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 = -1;
+
+ ret = inode_ctx_get (loc->inode, this, &value);
+ if (ret == -1) {
+ gf_log (this->name, GF_LOG_DEBUG, "context not set in inode "
+ "(%p)", loc->inode);
+ 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) {
+ 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 = -1;
+ call_stub_t *stub = NULL;
+ char can_wind = 0, need_lookup = 0, need_unwind = 1;
+
+ GF_VALIDATE_OR_GOTO_WITH_ERROR (this->name, loc, out, op_errno,
+ EINVAL);
+ GF_VALIDATE_OR_GOTO_WITH_ERROR (this->name, loc->inode, out,
+ op_errno, EINVAL);
+
+ stub = fop_getxattr_stub (frame, sp_getxattr_helper, loc, name);
+ if (stub == NULL) {
+ op_errno = ENOMEM;
+ gf_log (this->name, GF_LOG_ERROR, "out of memory");
+ goto out;
+ }
+
+ sp_process_inode_ctx (frame, this, loc, stub, &need_unwind,
+ &need_lookup, &can_wind, &op_errno,
+ GF_FOP_GETXATTR);
+
+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_setdents (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags,
+ dir_entry_t *entries, int32_t count)
+{
+ sp_fd_ctx_t *fd_ctx = NULL;
+ sp_cache_t *cache = NULL;
+ uint64_t value = 0;
+ int32_t ret = 0;
+ inode_t *parent = NULL;
+ char *name = NULL;
+ dir_entry_t *trav = NULL;
+
+ ret = fd_ctx_get (fd, this, &value);
+ if (ret == -1) {
+ errno = EINVAL;
+ goto unwind;
+ }
+
+ fd_ctx = (void *)(long)value;
+ name = fd_ctx->name;
+ parent = fd_ctx->parent_inode;
+
+ cache = sp_get_cache_inode (this, parent, frame->root->pid);
+ if (cache) {
+ sp_cache_remove_entry (cache, name, 0);
+ sp_cache_unref (cache);
+ }
+
+ cache = sp_get_cache_fd (this, fd);
+ if (cache) {
+ for (trav = entries->next; trav; trav = trav->next) {
+ sp_cache_remove_entry (cache, trav->name, 0);
+ }
+ sp_cache_unref (cache);
+ }
+
+ STACK_WIND (frame, sp_err_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->setdents, fd, flags, entries,
+ count);
+ return 0;
+
+unwind:
+ SP_STACK_UNWIND (setdents, frame, -1, errno);
+ return 0;
+}
+
+
+int32_t
+sp_getdents_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dir_entry_t *entries,
+ int32_t count)
+{
+ dir_entry_t *trav = NULL;
+ sp_local_t *local = NULL;
+ sp_cache_t *cache = NULL;
+
+ if (op_ret == -1) {
+ goto out;
+ }
+
+ local = frame->local;
+ if ((local == NULL) || (local->fd == NULL)) {
+ op_ret = -1;
+ op_errno = EINVAL;
+ goto out;
+ }
+
+ cache = sp_get_cache_fd (this, local->fd);
+ if (cache) {
+ for (trav = entries->next; trav; trav = trav->next) {
+ if (S_ISLNK (trav->buf.st_mode)) {
+ sp_cache_remove_entry (cache, trav->name, 0);
+ }
+ }
+
+ sp_cache_unref (cache);
+ }
+
+out:
+ SP_STACK_UNWIND (getdents, frame, op_ret, op_errno, entries, count);
+ return 0;
+}
+
+
+int32_t
+sp_getdents (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
+ off_t offset, int32_t flags)
+{
+ sp_fd_ctx_t *fd_ctx = NULL;
+ sp_cache_t *cache = NULL;
+ uint64_t value = 0;
+ int32_t ret = 0;
+ inode_t *parent = NULL;
+ char *name = NULL;
+ sp_local_t *local = NULL;
+
+ ret = fd_ctx_get (fd, this, &value);
+ if (ret == -1) {
+ errno = EINVAL;
+ goto unwind;
+ }
+
+ fd_ctx = (void *)(long)value;
+ name = fd_ctx->name;
+ parent = fd_ctx->parent_inode;
+
+ cache = sp_get_cache_inode (this, parent, frame->root->pid);
+ if (cache) {
+ sp_cache_remove_entry (cache, name, 0);
+ sp_cache_unref (cache);
+ }
+
+ local = CALLOC (1, sizeof (*local));
+ if (local == NULL) {
+ gf_log (this->name, GF_LOG_ERROR, "out of memory");
+ goto unwind;
+ }
+
+ local->fd = fd;
+ frame->local = local;
+
+ STACK_WIND (frame, sp_getdents_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->getdents, fd, size, offset, flags);
+ return 0;
+
+unwind:
+ SP_STACK_UNWIND (getdents, frame, -1, errno, NULL, -1);
+ return 0;
+}
+
+
+int32_t
+sp_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)
+{
+ SP_STACK_UNWIND (checksum, frame, op_ret, op_errno, file_checksum,
+ dir_checksum);
+ return 0;
+}
+
+
+int32_t
+sp_checksum_helper (call_frame_t *frame, xlator_t *this, loc_t *loc,
+ int32_t flag)
+{
+ uint64_t value = 0;
+ sp_inode_ctx_t *inode_ctx = NULL;
+ int32_t ret = 0, op_ret = -1, op_errno = -1;
+
+ ret = inode_ctx_get (loc->inode, this, &value);
+ if (ret == -1) {
+ gf_log (this->name, GF_LOG_DEBUG, "context not set in inode "
+ "(%p)", loc->inode);
+ 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) {
+ goto unwind;
+ }
+
+ STACK_WIND (frame, sp_checksum_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->checksum, loc, flag);
+
+ return 0;
+
+unwind:
+ SP_STACK_UNWIND (checksum, frame, -1, op_errno, NULL, NULL);
+ return 0;
+}
+
+
+int32_t
+sp_checksum (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flag)
+{
+ sp_cache_t *cache = NULL;
+ int32_t op_errno = -1;
+ call_stub_t *stub = NULL;
+ char can_wind = 0, need_lookup = 0, need_unwind = 1;
+
+ GF_VALIDATE_OR_GOTO_WITH_ERROR (this->name, loc, out, op_errno,
+ EINVAL);
+ GF_VALIDATE_OR_GOTO_WITH_ERROR (this->name, loc->name, out,
+ op_errno, EINVAL);
+
+ cache = sp_get_cache_inode (this, loc->parent, frame->root->pid);
+ if (cache) {
+ sp_cache_remove_entry (cache, (char *)loc->name, 0);
+ sp_cache_unref (cache);
+ }
+
+ stub = fop_checksum_stub (frame, sp_checksum_helper, loc, flag);
+ if (stub == NULL) {
+ op_errno = ENOMEM;
+ gf_log (this->name, GF_LOG_ERROR, "out of memory");
+ goto out;
+ }
+
+ sp_process_inode_ctx (frame, this, loc, stub, &need_unwind,
+ &need_lookup, &can_wind, &op_errno,
+ GF_FOP_CHECKSUM);
+
+out:
+ if (need_unwind) {
+ SP_STACK_UNWIND (checksum, 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_checksum_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->checksum, loc, flag);
+ }
+
+ 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)
+{
+ 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 = -1;
+
+ ret = inode_ctx_get (loc->inode, this, &value);
+ if (ret == -1) {
+ gf_log (this->name, GF_LOG_DEBUG, "context not set in inode "
+ "(%p)", loc->inode);
+ 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) {
+ 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)
+{
+ sp_cache_t *cache = NULL;
+ int32_t op_errno = -1;
+ call_stub_t *stub = NULL;
+ char can_wind = 0, need_lookup = 0, need_unwind = 1;
+
+ GF_VALIDATE_OR_GOTO_WITH_ERROR (this->name, loc, out, op_errno,
+ EINVAL);
+ GF_VALIDATE_OR_GOTO_WITH_ERROR (this->name, loc->name, out, op_errno,
+ EINVAL);
+
+ cache = sp_get_cache_inode (this, loc->parent, frame->root->pid);
+ if (cache) {
+ sp_cache_remove_entry (cache, (char *)loc->name, 0);
+ sp_cache_unref (cache);
+ }
+
+ stub = fop_xattrop_stub (frame, sp_xattrop_helper, loc, flags, dict);
+ if (stub == NULL) {
+ op_errno = ENOMEM;
+ gf_log (this->name, GF_LOG_ERROR, "out of memory");
+ goto out;
+ }
+
+ sp_process_inode_ctx (frame, this, loc, stub, &need_unwind,
+ &need_lookup, &can_wind, &op_errno,
+ GF_FOP_XATTROP);
+
+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;
+ sp_cache_t *cache = NULL;
+ uint64_t value = 0;
+ int32_t ret = 0;
+ inode_t *parent = NULL;
+ char *name = NULL;
+
+ ret = fd_ctx_get (fd, this, &value);
+ if (ret == -1) {
+ errno = EINVAL;
+ goto unwind;
+ }
+
+ fd_ctx = (void *)(long)value;
+ name = fd_ctx->name;
+ parent = fd_ctx->parent_inode;
+
+ cache = sp_get_cache_inode (this, parent, frame->root->pid);
+ if (cache) {
+ sp_cache_remove_entry (cache, name, 0);
+ sp_cache_unref (cache);
+ }
+
+ 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, 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 stat *buf)
+{
+ STACK_UNWIND (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 = -1;
+
+ ret = inode_ctx_get (loc->inode, this, &value);
+ if (ret == -1) {
+ gf_log (this->name, GF_LOG_DEBUG, "context not set in inode "
+ "(%p)", loc->inode);
+ 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) {
+ 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_VALIDATE_OR_GOTO_WITH_ERROR (this->name, loc, out, op_errno,
+ EINVAL);
+ GF_VALIDATE_OR_GOTO_WITH_ERROR (this->name, loc->inode, out,
+ op_errno, EINVAL);
+
+ stub = fop_stat_stub (frame, sp_stat_helper, loc);
+ if (stub == NULL) {
+ op_errno = ENOMEM;
+ gf_log (this->name, GF_LOG_ERROR, "out of memory");
+ goto out;
+ }
+
+ sp_process_inode_ctx (frame, this, loc, stub, &need_unwind,
+ &need_lookup, &can_wind, &op_errno,
+ GF_FOP_STAT);
+
+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 = -1;
+
+ ret = inode_ctx_get (loc->inode, this, &value);
+ if (ret == -1) {
+ gf_log (this->name, GF_LOG_DEBUG, "context not set in inode "
+ "(%p)", loc->inode);
+ 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) {
+ 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_VALIDATE_OR_GOTO_WITH_ERROR (this->name, loc, out, op_errno,
+ EINVAL);
+ GF_VALIDATE_OR_GOTO_WITH_ERROR (this->name, loc->inode, out,
+ op_errno, EINVAL);
+
+ stub = fop_access_stub (frame, sp_access_helper, loc, mask);
+ if (stub == NULL) {
+ op_errno = ENOMEM;
+ gf_log (this->name, GF_LOG_ERROR, "out of memory");
+ goto out;
+ }
+
+ sp_process_inode_ctx (frame, this, loc, stub, &need_unwind,
+ &need_lookup, &can_wind, &op_errno,
+ GF_FOP_ACCESS);
+
+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 flock *lock)
+{
+ uint64_t value = 0;
+ sp_inode_ctx_t *inode_ctx = NULL;
+ int32_t ret = 0, op_ret = -1, op_errno = -1;
+
+ ret = inode_ctx_get (loc->inode, this, &value);
+ if (ret == -1) {
+ gf_log (this->name, GF_LOG_DEBUG, "context not set in inode "
+ "(%p)", loc->inode);
+ 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) {
+ 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 flock *lock)
+{
+ int32_t op_errno = -1;
+ call_stub_t *stub = NULL;
+ char can_wind = 0, need_lookup = 0, need_unwind = 1;
+
+ GF_VALIDATE_OR_GOTO_WITH_ERROR (this->name, loc, out, op_errno,
+ EINVAL);
+ GF_VALIDATE_OR_GOTO_WITH_ERROR (this->name, loc->inode, out,
+ op_errno, EINVAL);
+
+ stub = fop_inodelk_stub (frame, sp_inodelk_helper, volume, loc, cmd,
+ lock);
+ if (stub == NULL) {
+ op_errno = ENOMEM;
+ gf_log (this->name, GF_LOG_ERROR, "out of memory");
+ goto out;
+ }
+
+ sp_process_inode_ctx (frame, this, loc, stub, &need_unwind,
+ &need_lookup, &can_wind, &op_errno,
+ GF_FOP_INODELK);
+
+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 = -1;
+
+ ret = inode_ctx_get (loc->inode, this, &value);
+ if (ret == -1) {
+ gf_log (this->name, GF_LOG_DEBUG, "context not set in inode "
+ "(%p)", loc->inode);
+ 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) {
+ 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 = -1;
+ call_stub_t *stub = NULL;
+ char can_wind = 0, need_lookup = 0, need_unwind = 1;
+
+ GF_VALIDATE_OR_GOTO_WITH_ERROR (this->name, loc, out, op_errno,
+ EINVAL);
+ GF_VALIDATE_OR_GOTO_WITH_ERROR (this->name, loc->inode, out,
+ op_errno, EINVAL);
+
+ stub = fop_entrylk_stub (frame, sp_entrylk_helper, volume, loc,
+ basename, cmd, type);
+ if (stub == NULL) {
+ op_errno = ENOMEM;
+ gf_log (this->name, GF_LOG_ERROR, "out of memory");
+ goto out;
+ }
+
+ sp_process_inode_ctx (frame, this, loc, stub, &need_unwind,
+ &need_lookup, &can_wind, &op_errno,
+ GF_FOP_ENTRYLK);
+
+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 stat *buf = NULL;
+ uint64_t value = 0;
+
+ inode_ctx_del (inode, this, &value);
+
+ if (value) {
+ buf = (void *)(long)value;
+ FREE (buf);
+ }
+
+ 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;
+
+ 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_DEBUG, "cache hits: %lu, "
+ "cache miss: %lu", cache->hits, cache->miss);
+ }
+
+ sp_fd_ctx_free (fd_ctx);
+ }
+
+ return 0;
+}
+
+
+
+int32_t
+init (xlator_t *this)
+{
+ int32_t ret = -1;
+ sp_private_t *priv = NULL;
+
+ 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 = CALLOC (1, sizeof(sp_private_t));
+ LOCK_INIT (&priv->lock);
+
+ this->private = priv;
+
+ ret = 0;
+out:
+ return ret;
+}
+
+void
+fini (xlator_t *this)
+{
+ 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,
+ .setdents = sp_setdents,
+ .getdents = sp_getdents,
+ .checksum = sp_checksum,
+ .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_mops mops = {
+};
+
+struct xlator_cbks cbks = {
+ .forget = sp_forget,
+ .release = sp_release,
+ .releasedir = sp_release
+};
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 00000000000..3fcf4a0a63e
--- /dev/null
+++ b/xlators/performance/stat-prefetch/src/stat-prefetch.h
@@ -0,0 +1,104 @@
+/*
+ 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
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that 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 _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 <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 stat 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;
+ 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/Makefile.am b/xlators/performance/symlink-cache/src/Makefile.am
index 4091c329325..06e85fc9216 100644
--- a/xlators/performance/symlink-cache/src/Makefile.am
+++ b/xlators/performance/symlink-cache/src/Makefile.am
@@ -1,13 +1,12 @@
xlator_LTLIBRARIES = symlink-cache.la
xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/testing/performance
-symlink_cache_la_LDFLAGS = -module -avoid-version
+symlink_cache_la_LDFLAGS = -module -avoidversion
symlink_cache_la_SOURCES = symlink-cache.c
symlink_cache_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la
-AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src
-
-AM_CFLAGS = -Wall $(GF_CFLAGS)
+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/performance/symlink-cache/src/symlink-cache.c b/xlators/performance/symlink-cache/src/symlink-cache.c
index 3b5fbc252ec..22b1c5482ea 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-2009 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 General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that 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/>.
*/
@@ -81,7 +90,7 @@ sc_cache_update (xlator_t *this, inode_t *inode, const char *link)
int
-sc_cache_set (xlator_t *this, inode_t *inode, struct iatt *buf,
+sc_cache_set (xlator_t *this, inode_t *inode, struct stat *buf,
const char *link)
{
struct symlink_cache *sc = NULL;
@@ -117,7 +126,7 @@ sc_cache_set (xlator_t *this, inode_t *inode, struct iatt *buf,
}
}
- sc->ctime = buf->ia_ctime;
+ sc->ctime = buf->st_ctime;
gf_log (this->name, GF_LOG_DEBUG,
"setting symlink cache: %s", link);
@@ -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);
}
@@ -170,12 +180,12 @@ sc_cache_flush (xlator_t *this, inode_t *inode)
int
-sc_cache_validate (xlator_t *this, inode_t *inode, struct iatt *buf)
+sc_cache_validate (xlator_t *this, inode_t *inode, struct stat *buf)
{
struct symlink_cache *sc = NULL;
uint64_t tmp_sc = 0;
- if (!IA_ISLNK (buf->ia_type)) {
+ if (!S_ISLNK (buf->st_mode)) {
sc_cache_flush (this, inode);
return 0;
}
@@ -194,7 +204,7 @@ sc_cache_validate (xlator_t *this, inode_t *inode, struct iatt *buf)
sc = (struct symlink_cache *)(long)tmp_sc;
}
- if (sc->ctime == buf->ia_ctime)
+ if (sc->ctime == buf->st_ctime)
return 0;
/* STALE */
@@ -206,7 +216,7 @@ sc_cache_validate (xlator_t *this, inode_t *inode, struct iatt *buf)
sc->readlink = NULL;
}
- sc->ctime = buf->ia_ctime;
+ sc->ctime = buf->st_ctime;
return 0;
}
@@ -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 stat *sbuf)
{
if (op_ret > 0)
sc_cache_update (this, frame->local, link);
@@ -240,18 +250,17 @@ 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 (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, };
+ struct stat buf = {0, };
sc_cache_get (this, loc->inode, &link);
@@ -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 (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;
}
@@ -286,8 +294,8 @@ sc_readlink (call_frame_t *frame, xlator_t *this,
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)
+ inode_t *inode, struct stat *buf, struct stat *preparent,
+ struct stat *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 (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)
{
frame->local = strdup (dst);
STACK_WIND (frame, sc_symlink_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->symlink,
- dst, src, umask, xdata);
+ dst, src);
return 0;
}
@@ -319,28 +327,27 @@ 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,
- struct iatt *postparent)
+ inode_t *inode, struct stat *buf, dict_t *xattr,
+ struct stat *postparent)
{
if (op_ret == 0)
sc_cache_validate (this, inode, buf);
else
sc_cache_flush (this, inode);
- STACK_UNWIND_STRICT (lookup, frame, op_ret, op_errno, inode, buf,
- xdata, postparent);
+ STACK_UNWIND (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,
@@ -389,6 +397,8 @@ struct xlator_fops fops = {
.readlink = sc_readlink,
};
+struct xlator_mops mops = {
+};
struct xlator_cbks cbks = {
.forget = sc_forget,
diff --git a/xlators/performance/write-behind/src/Makefile.am b/xlators/performance/write-behind/src/Makefile.am
index 6c829d8ee36..f800abad50d 100644
--- a/xlators/performance/write-behind/src/Makefile.am
+++ b/xlators/performance/write-behind/src/Makefile.am
@@ -1,15 +1,12 @@
xlator_LTLIBRARIES = write-behind.la
xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/performance
-write_behind_la_LDFLAGS = -module -avoid-version
+write_behind_la_LDFLAGS = -module -avoidversion
write_behind_la_SOURCES = write-behind.c
write_behind_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la
-noinst_HEADERS = write-behind-mem-types.h
-
-AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src
-
-AM_CFLAGS = -Wall $(GF_CFLAGS)
+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/performance/write-behind/src/write-behind-mem-types.h b/xlators/performance/write-behind/src/write-behind-mem-types.h
deleted file mode 100644
index f64f429ce22..00000000000
--- a/xlators/performance/write-behind/src/write-behind-mem-types.h
+++ /dev/null
@@ -1,26 +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 __WB_MEM_TYPES_H__
-#define __WB_MEM_TYPES_H__
-
-#include "mem-types.h"
-
-enum gf_wb_mem_types_ {
- gf_wb_mt_wb_file_t = gf_common_mt_end + 1,
- gf_wb_mt_wb_request_t,
- gf_wb_mt_iovec,
- gf_wb_mt_wb_conf_t,
- gf_wb_mt_wb_inode_t,
- gf_wb_mt_end
-};
-#endif
-
diff --git a/xlators/performance/write-behind/src/write-behind.c b/xlators/performance/write-behind/src/write-behind.c
index 3cb0d449bbc..91342700ee6 100644
--- a/xlators/performance/write-behind/src/write-behind.c
+++ b/xlators/performance/write-behind/src/write-behind.c
@@ -1,13 +1,24 @@
/*
- Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
+ Copyright (c) 2006-2009 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 General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that 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/>.
*/
+/*TODO: check for non null wb_file_data before getting wb_file */
+
#ifndef _CONFIG_H
#define _CONFIG_H
@@ -24,2146 +35,2509 @@
#include "common-utils.h"
#include "call-stub.h"
#include "statedump.h"
-#include "defaults.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;
-struct wb_inode;
-
-typedef struct wb_inode {
- ssize_t window_conf;
- ssize_t window_current;
- ssize_t transit; /* size of data stack_wound, and yet
- to be fulfilled (wb_fulfill_cbk).
- used for trickling_writes
- */
-
- list_head_t all; /* All requests, from enqueue() till destroy().
- Used only for resetting generation
- number when empty.
- */
- list_head_t todo; /* Work to do (i.e, STACK_WIND to server).
- Once we STACK_WIND, the entry is taken
- off the list. If it is non-sync write,
- then we continue to track it via @liability
- or @temptation depending on the status
- of its writeback.
- */
- list_head_t liability; /* Non-sync writes which are lied
- (STACK_UNWIND'ed to caller) but ack
- from server not yet complete. This
- is the "liability" which we hold, and
- must guarantee that dependent operations
- which arrive later (which overlap, etc.)
- are issued only after their dependencies
- in this list are "fulfilled".
-
- Server acks for entries in this list
- shrinks the window.
-
- The sum total of all req->write_size
- of entries in this list must be kept less
- than the permitted window size.
- */
- list_head_t temptation; /* Operations for which we are tempted
- to 'lie' (write-behind), but temporarily
- holding off (because of insufficient
- window capacity, etc.)
-
- This is the list to look at to grow
- the window (in __wb_pick_unwinds()).
-
- Entries typically get chosen from
- write-behind from this list, and therefore
- get "upgraded" to the "liability" list.
- */
- list_head_t wip; /* List of write calls in progress, SYNC or non-SYNC
- which are currently STACK_WIND'ed towards the server.
- This is for guaranteeing that no two overlapping
- writes are in progress at the same time. Modules
- like eager-lock in AFR depend on this behavior.
- */
- uint64_t gen; /* Liability generation number. Represents
- the current 'state' of liability. Every
- new addition to the liability list bumps
- the generation number.
-
- a newly arrived request is only required
- to perform causal checks against the entries
- in the liability list which were present
- at the time of its addition. the generation
- number at the time of its addition is stored
- in the request and used during checks.
-
- the liability list can grow while the request
- waits in the todo list waiting for its
- dependent operations to complete. however
- it is not of the request's concern to depend
- itself on those new entries which arrived
- after it arrived (i.e, those that have a
- liability generation higher than itself)
- */
- size_t size; /* Size of the file to catch write after EOF. */
+struct wb_page;
+struct wb_file;
+
+
+typedef struct wb_file {
+ int disabled;
+ uint64_t disable_till;
+ size_t window_conf;
+ size_t window_current;
+ size_t aggregate_current;
+ int32_t refcount;
+ int32_t op_ret;
+ int32_t op_errno;
+ list_head_t request;
+ list_head_t passive_requests;
+ fd_t *fd;
gf_lock_t lock;
xlator_t *this;
-} wb_inode_t;
+}wb_file_t;
typedef struct wb_request {
- list_head_t all;
- list_head_t todo;
- list_head_t lie; /* either in @liability or @temptation */
- list_head_t winds;
- list_head_t unwinds;
- list_head_t wip;
-
- call_stub_t *stub;
-
- ssize_t write_size; /* currently held size
- (after collapsing) */
- size_t orig_size; /* size which arrived with the request.
- This is the size by which we grow
- the window when unwinding the frame.
- */
- size_t total_size; /* valid only in @head in wb_fulfill().
- This is the size with which we perform
- STACK_WIND to server and therefore the
- amount by which we shrink the window.
- */
-
- int op_ret;
- int op_errno;
-
- int32_t refcount;
- wb_inode_t *wb_inode;
- glusterfs_fop_t fop;
- gf_lkowner_t lk_owner;
- struct iobref *iobref;
- uint64_t gen; /* inode liability state at the time of
- request arrival */
-
- fd_t *fd;
- struct {
- size_t size; /* 0 size == till infinity */
- off_t off;
- int append:1; /* offset is invalid. only one
- outstanding append at a time */
- int tempted:1; /* true only for non-sync writes */
- int lied:1; /* sin committed */
- int fulfilled:1; /* got server acknowledgement */
- int go:1; /* enough aggregating, good to go */
- } ordering;
+ 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;
+ union {
+ struct {
+ char write_behind;
+ char stack_wound;
+ char got_reply;
+ char virgin;
+ }write_request;
+
+ struct {
+ char marked_for_resume;
+ }other_requests;
+ }flags;
} wb_request_t;
-typedef struct wb_conf {
- uint64_t aggregate_size;
- uint64_t window_size;
- gf_boolean_t flush_behind;
- gf_boolean_t trickling_writes;
- gf_boolean_t strict_write_ordering;
- gf_boolean_t strict_O_DIRECT;
-} wb_conf_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;
+};
-void
-wb_process_queue (wb_inode_t *wb_inode);
+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;
+ int op_errno;
+ call_frame_t *frame;
+ fd_t *fd;
+ int32_t reply_count;
+} wb_local_t;
-wb_inode_t *
-__wb_inode_ctx_get (xlator_t *this, inode_t *inode)
-{
- uint64_t value = 0;
- wb_inode_t *wb_inode = NULL;
+typedef struct wb_conf wb_conf_t;
+typedef struct wb_page wb_page_t;
- __inode_ctx_get (inode, this, &value);
- wb_inode = (wb_inode_t *)(unsigned long) value;
- return wb_inode;
-}
+int32_t
+wb_process_queue (call_frame_t *frame, wb_file_t *file, char flush_all);
+ssize_t
+wb_sync (call_frame_t *frame, wb_file_t *file, list_head_t *winds);
-wb_inode_t *
-wb_inode_ctx_get (xlator_t *this, inode_t *inode)
-{
- wb_inode_t *wb_inode = NULL;
+ssize_t
+__wb_mark_winds (list_head_t *list, list_head_t *winds, size_t aggregate_size,
+ char wind_all, char enable_trickling_writes);
- GF_VALIDATE_OR_GOTO ("write-behind", this, out);
- GF_VALIDATE_OR_GOTO (this->name, inode, out);
- LOCK (&inode->lock);
- {
- wb_inode = __wb_inode_ctx_get (this, inode);
- }
- UNLOCK (&inode->lock);
-out:
- return wb_inode;
-}
-
-
-gf_boolean_t
-wb_fd_err (fd_t *fd, xlator_t *this, int32_t *op_errno)
+static void
+__wb_request_unref (wb_request_t *this)
{
- gf_boolean_t err = _gf_false;
- uint64_t value = 0;
- int32_t tmp = 0;
+ if (this->refcount <= 0) {
+ gf_log ("wb-request", GF_LOG_DEBUG,
+ "refcount(%d) is <= 0", this->refcount);
+ return;
+ }
- if (fd_ctx_get (fd, this, &value) == 0) {
- if (op_errno) {
- tmp = value;
- *op_errno = tmp;
+ this->refcount--;
+ if (this->refcount == 0) {
+ list_del_init (&this->list);
+ if (this->stub && this->stub->fop == GF_FOP_WRITE) {
+ call_stub_destroy (this->stub);
}
- err = _gf_true;
+ FREE (this);
}
-
- return err;
}
-/*
- 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"
- }
-*/
-
-gf_boolean_t
-wb_requests_overlap (wb_request_t *req1, wb_request_t *req2)
-{
- uint64_t r1_start = 0;
- uint64_t r1_end = 0;
- uint64_t r2_start = 0;
- uint64_t r2_end = 0;
- enum _gf_boolean do_overlap = 0;
-
- r1_start = req1->ordering.off;
- if (req1->ordering.size)
- r1_end = r1_start + req1->ordering.size - 1;
- else
- r1_end = ULLONG_MAX;
-
- r2_start = req2->ordering.off;
- if (req2->ordering.size)
- r2_end = r2_start + req2->ordering.size - 1;
- else
- r2_end = ULLONG_MAX;
-
- do_overlap = ((r1_end >= r2_start) && (r2_end >= r1_start));
-
- return do_overlap;
-}
-
-
-gf_boolean_t
-wb_requests_conflict (wb_request_t *lie, wb_request_t *req)
+static void
+wb_request_unref (wb_request_t *this)
{
- wb_conf_t *conf = NULL;
-
- conf = req->wb_inode->this->private;
-
- if (lie == req)
- /* request cannot conflict with itself */
- return _gf_false;
-
- if (lie->gen >= req->gen)
- /* this liability entry was behind
- us in the todo list */
- return _gf_false;
-
- if (lie->ordering.append)
- /* all modifications wait for the completion
- of outstanding append */
- return _gf_true;
-
- if (conf->strict_write_ordering)
- /* We are sure (lie->gen < req->gen) by now. So
- skip overlap check if strict write ordering is
- requested and always return "conflict" against a
- lower generation lie. */
- return _gf_true;
-
- return wb_requests_overlap (lie, req);
+ wb_file_t *file = NULL;
+ if (this == NULL) {
+ gf_log ("wb-request", GF_LOG_DEBUG,
+ "request is NULL");
+ return;
+ }
+
+ file = this->file;
+ LOCK (&file->lock);
+ {
+ __wb_request_unref (this);
+ }
+ UNLOCK (&file->lock);
}
-gf_boolean_t
-wb_liability_has_conflict (wb_inode_t *wb_inode, wb_request_t *req)
+static wb_request_t *
+__wb_request_ref (wb_request_t *this)
{
- wb_request_t *each = NULL;
-
- list_for_each_entry (each, &wb_inode->liability, lie) {
- if (wb_requests_conflict (each, req))
- return _gf_true;
+ if (this->refcount < 0) {
+ gf_log ("wb-request", GF_LOG_DEBUG,
+ "refcount(%d) is < 0", this->refcount);
+ return NULL;
}
- return _gf_false;
+ this->refcount++;
+ return this;
}
-gf_boolean_t
-wb_wip_has_conflict (wb_inode_t *wb_inode, wb_request_t *req)
+wb_request_t *
+wb_request_ref (wb_request_t *this)
{
- wb_request_t *each = NULL;
-
- if (req->stub->fop != GF_FOP_WRITE)
- /* non-writes fundamentally never conflict with WIP requests */
- return _gf_false;
-
- list_for_each_entry (each, &wb_inode->wip, wip) {
- if (each == req)
- /* request never conflicts with itself,
- though this condition should never occur.
- */
- continue;
+ wb_file_t *file = NULL;
+ if (this == NULL) {
+ gf_log ("wb-request", GF_LOG_DEBUG,
+ "request is NULL");
+ return NULL;
+ }
- if (wb_requests_overlap (each, req))
- return _gf_true;
+ file = this->file;
+ LOCK (&file->lock);
+ {
+ this = __wb_request_ref (this);
}
+ UNLOCK (&file->lock);
- return _gf_false;
+ return this;
}
-static int
-__wb_request_unref (wb_request_t *req)
-{
- int ret = -1;
- wb_inode_t *wb_inode = NULL;
-
- wb_inode = req->wb_inode;
-
- if (req->refcount <= 0) {
- gf_log ("wb-request", GF_LOG_WARNING,
- "refcount(%d) is <= 0", req->refcount);
+wb_request_t *
+wb_enqueue (wb_file_t *file, call_stub_t *stub)
+{
+ wb_request_t *request = NULL;
+ call_frame_t *frame = NULL;
+ wb_local_t *local = NULL;
+ struct iovec *vector = NULL;
+ int32_t count = 0;
+
+ request = CALLOC (1, sizeof (*request));
+ if (request == NULL) {
goto out;
}
- ret = --req->refcount;
- if (req->refcount == 0) {
- list_del_init (&req->todo);
- list_del_init (&req->lie);
- list_del_init (&req->wip);
-
- list_del_init (&req->all);
- if (list_empty (&wb_inode->all)) {
- wb_inode->gen = 0;
- /* in case of accounting errors? */
- wb_inode->window_current = 0;
- }
-
- list_del_init (&req->winds);
- list_del_init (&req->unwinds);
-
- if (req->stub && req->ordering.tempted) {
- call_stub_destroy (req->stub);
- req->stub = NULL;
- } /* else we would have call_resume()'ed */
-
- if (req->iobref)
- iobref_unref (req->iobref);
+ INIT_LIST_HEAD (&request->list);
+ INIT_LIST_HEAD (&request->winds);
+ INIT_LIST_HEAD (&request->unwinds);
+ INIT_LIST_HEAD (&request->other_requests);
- if (req->fd)
- fd_unref (req->fd);
+ request->stub = stub;
+ request->file = file;
- GF_FREE (req);
+ frame = stub->frame;
+ local = frame->local;
+ if (local) {
+ local->request = request;
}
-out:
- return ret;
-}
+ if (stub->fop == GF_FOP_WRITE) {
+ vector = stub->args.writev.vector;
+ count = stub->args.writev.count;
-static int
-wb_request_unref (wb_request_t *req)
-{
- wb_inode_t *wb_inode = NULL;
- int ret = -1;
-
- GF_VALIDATE_OR_GOTO ("write-behind", req, out);
+ frame = stub->frame;
+ local = frame->local;
+ request->write_size = iov_length (vector, count);
+ local->op_ret = request->write_size;
+ local->op_errno = 0;
- wb_inode = req->wb_inode;
+ request->flags.write_request.virgin = 1;
+ }
- LOCK (&wb_inode->lock);
+ LOCK (&file->lock);
{
- ret = __wb_request_unref (req);
+ list_add_tail (&request->list, &file->request);
+ if (stub->fop == GF_FOP_WRITE) {
+ /* reference for stack winding */
+ __wb_request_ref (request);
+
+ /* reference for stack unwinding */
+ __wb_request_ref (request);
+
+ file->aggregate_current += request->write_size;
+ } else {
+ /*reference for resuming */
+ __wb_request_ref (request);
+ }
}
- UNLOCK (&wb_inode->lock);
+ UNLOCK (&file->lock);
out:
- return ret;
+ return request;
}
-static wb_request_t *
-__wb_request_ref (wb_request_t *req)
+wb_file_t *
+wb_file_create (xlator_t *this, fd_t *fd)
{
- GF_VALIDATE_OR_GOTO ("write-behind", req, out);
+ wb_file_t *file = NULL;
+ wb_conf_t *conf = this->private;
- if (req->refcount < 0) {
- gf_log ("wb-request", GF_LOG_WARNING,
- "refcount(%d) is < 0", req->refcount);
- req = NULL;
+ file = CALLOC (1, sizeof (*file));
+ if (file == NULL) {
goto out;
}
- req->refcount++;
+ INIT_LIST_HEAD (&file->request);
+ INIT_LIST_HEAD (&file->passive_requests);
+
+ /*
+ fd_ref() not required, file should never decide the existance of
+ an fd
+ */
+ file->fd= fd;
+ file->disable_till = conf->disable_till;
+ file->this = this;
+ file->refcount = 1;
+ file->window_conf = conf->window_size;
+
+ fd_ctx_set (fd, this, (uint64_t)(long)file);
out:
- return req;
+ return file;
}
-
-wb_request_t *
-wb_request_ref (wb_request_t *req)
+void
+wb_file_destroy (wb_file_t *file)
{
- wb_inode_t *wb_inode = NULL;
+ int32_t refcount = 0;
- GF_VALIDATE_OR_GOTO ("write-behind", req, out);
-
- wb_inode = req->wb_inode;
- LOCK (&wb_inode->lock);
+ LOCK (&file->lock);
{
- req = __wb_request_ref (req);
+ refcount = --file->refcount;
}
- UNLOCK (&wb_inode->lock);
+ UNLOCK (&file->lock);
-out:
- return req;
+ if (!refcount){
+ LOCK_DESTROY (&file->lock);
+ FREE (file);
+ }
+
+ return;
}
-gf_boolean_t
-wb_enqueue_common (wb_inode_t *wb_inode, call_stub_t *stub, int tempted)
+int32_t
+wb_sync_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret,
+ int32_t op_errno, struct stat *prebuf, struct stat *postbuf)
{
- wb_request_t *req = NULL;
-
- GF_VALIDATE_OR_GOTO ("write-behind", wb_inode, out);
- GF_VALIDATE_OR_GOTO (wb_inode->this->name, stub, out);
-
- req = GF_CALLOC (1, sizeof (*req), gf_wb_mt_wb_request_t);
- if (!req)
- goto out;
+ wb_local_t *local = NULL;
+ list_head_t *winds = NULL;
+ wb_file_t *file = NULL;
+ wb_request_t *request = NULL, *dummy = NULL;
+ wb_local_t *per_request_local = NULL;
+ int32_t ret = -1;
+ fd_t *fd = NULL;
- INIT_LIST_HEAD (&req->all);
- INIT_LIST_HEAD (&req->todo);
- INIT_LIST_HEAD (&req->lie);
- INIT_LIST_HEAD (&req->winds);
- INIT_LIST_HEAD (&req->unwinds);
- INIT_LIST_HEAD (&req->wip);
- req->stub = stub;
- req->wb_inode = wb_inode;
- req->fop = stub->fop;
- req->ordering.tempted = tempted;
+ local = frame->local;
+ winds = &local->winds;
+ file = local->file;
- if (stub->fop == GF_FOP_WRITE) {
- req->write_size = iov_length (stub->args.vector,
- stub->args.count);
-
- /* req->write_size can change as we collapse
- small writes. But the window needs to grow
- only by how much we acknowledge the app. so
- copy the original size in orig_size for the
- purpose of accounting.
- */
- req->orig_size = req->write_size;
-
- /* Let's be optimistic that we can
- lie about it
- */
- req->op_ret = req->write_size;
- req->op_errno = 0;
-
- if (stub->args.fd->flags & O_APPEND)
- req->ordering.append = 1;
- }
-
- req->lk_owner = stub->frame->root->lk_owner;
-
- switch (stub->fop) {
- case GF_FOP_WRITE:
- LOCK (&wb_inode->lock);
- {
- if (wb_inode->size < stub->args.offset) {
- req->ordering.off = wb_inode->size;
- req->ordering.size = stub->args.offset
- + req->write_size
- - wb_inode->size;
- } else {
- req->ordering.off = stub->args.offset;
- req->ordering.size = req->write_size;
- }
-
- if (wb_inode->size < stub->args.offset + req->write_size)
- wb_inode->size = stub->args.offset
- + req->write_size;
- }
- UNLOCK (&wb_inode->lock);
-
- req->fd = fd_ref (stub->args.fd);
-
- break;
- case GF_FOP_READ:
- req->ordering.off = stub->args.offset;
- req->ordering.size = stub->args.size;
-
- req->fd = fd_ref (stub->args.fd);
-
- break;
- case GF_FOP_TRUNCATE:
- req->ordering.off = stub->args.offset;
- req->ordering.size = 0; /* till infinity */
- LOCK (&wb_inode->lock);
- {
- wb_inode->size = req->ordering.off;
- }
- UNLOCK (&wb_inode->lock);
- break;
- case GF_FOP_FTRUNCATE:
- req->ordering.off = stub->args.offset;
- req->ordering.size = 0; /* till infinity */
- LOCK (&wb_inode->lock);
- {
- wb_inode->size = req->ordering.off;
- }
- UNLOCK (&wb_inode->lock);
-
- req->fd = fd_ref (stub->args.fd);
-
- break;
- default:
- break;
- }
-
- LOCK (&wb_inode->lock);
+ LOCK (&file->lock);
{
- list_add_tail (&req->all, &wb_inode->all);
+ list_for_each_entry_safe (request, dummy, winds, winds) {
+ request->flags.write_request.got_reply = 1;
- req->gen = wb_inode->gen;
+ if (!request->flags.write_request.write_behind
+ && (op_ret == -1)) {
+ per_request_local = request->stub->frame->local;
+ per_request_local->op_ret = op_ret;
+ per_request_local->op_errno = op_errno;
+ }
- list_add_tail (&req->todo, &wb_inode->todo);
- __wb_request_ref (req); /* for wind */
+ if (request->flags.write_request.write_behind) {
+ file->window_current -= request->write_size;
+ }
- if (req->ordering.tempted) {
- list_add_tail (&req->lie, &wb_inode->temptation);
- __wb_request_ref (req); /* for unwind */
- }
+ __wb_request_unref (request);
+ }
+
+ if (op_ret == -1) {
+ file->op_ret = op_ret;
+ file->op_errno = op_errno;
+ }
+ fd = file->fd;
}
- UNLOCK (&wb_inode->lock);
-
-out:
- if (!req)
- return _gf_false;
-
- return _gf_true;
-}
+ UNLOCK (&file->lock);
+ ret = wb_process_queue (frame, file, 0);
+ if ((ret == -1) && (errno == ENOMEM)) {
+ LOCK (&file->lock);
+ {
+ file->op_ret = -1;
+ file->op_errno = ENOMEM;
+ }
+ UNLOCK (&file->lock);
+ }
-gf_boolean_t
-wb_enqueue (wb_inode_t *wb_inode, call_stub_t *stub)
-{
- return wb_enqueue_common (wb_inode, stub, 0);
-}
+ /* safe place to do fd_unref */
+ fd_unref (fd);
+ STACK_DESTROY (frame->root);
-gf_boolean_t
-wb_enqueue_tempted (wb_inode_t *wb_inode, call_stub_t *stub)
-{
- return wb_enqueue_common (wb_inode, stub, 1);
+ return 0;
}
-wb_inode_t *
-__wb_inode_create (xlator_t *this, inode_t *inode)
-{
- wb_inode_t *wb_inode = NULL;
- wb_conf_t *conf = NULL;
-
- GF_VALIDATE_OR_GOTO (this->name, inode, out);
-
- conf = this->private;
+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;
+
+ conf = file->this->private;
+ list_for_each_entry (request, winds, winds) {
+ total_count += request->stub->args.writev.count;
+ if (total_count > 0) {
+ break;
+ }
+ }
- wb_inode = GF_CALLOC (1, sizeof (*wb_inode), gf_wb_mt_wb_inode_t);
- if (!wb_inode)
+ if (total_count == 0) {
goto out;
+ }
+
+ list_for_each_entry_safe (request, dummy, winds, winds) {
+ if (!vector) {
+ vector = MALLOC (VECTORSIZE (MAX_VECTOR_COUNT));
+ if (vector == NULL) {
+ bytes = -1;
+ goto out;
+ }
+
+ iobref = iobref_new ();
+ if (iobref == NULL) {
+ bytes = -1;
+ goto out;
+ }
+
+ local = CALLOC (1, sizeof (*local));
+ if (local == NULL) {
+ bytes = -1;
+ goto out;
+ }
+
+ INIT_LIST_HEAD (&local->winds);
+
+ first_request = request;
+ current_size = 0;
+ }
- INIT_LIST_HEAD (&wb_inode->all);
- INIT_LIST_HEAD (&wb_inode->todo);
- INIT_LIST_HEAD (&wb_inode->liability);
- INIT_LIST_HEAD (&wb_inode->temptation);
- INIT_LIST_HEAD (&wb_inode->wip);
-
- wb_inode->this = this;
+ count += request->stub->args.writev.count;
+ bytecount = VECTORSIZE (request->stub->args.writev.count);
+ memcpy (((char *)vector)+copied,
+ request->stub->args.writev.vector,
+ bytecount);
+ copied += bytecount;
+
+ current_size += request->write_size;
+
+ if (request->stub->args.writev.iobref) {
+ iobref_merge (iobref,
+ request->stub->args.writev.iobref);
+ }
- wb_inode->window_conf = conf->window_size;
+ next = NULL;
+ if (request->winds.next != winds) {
+ next = list_entry (request->winds.next,
+ wb_request_t, winds);
+ }
- LOCK_INIT (&wb_inode->lock);
+ list_del_init (&request->winds);
+ list_add_tail (&request->winds, &local->winds);
- __inode_ctx_put (inode, this, (uint64_t)(unsigned long)wb_inode);
+ if ((!next)
+ || ((count + next->stub->args.writev.count)
+ > MAX_VECTOR_COUNT)
+ || ((current_size + next->write_size)
+ > conf->aggregate_size))
+ {
+ sync_frame = copy_frame (frame);
+ if (sync_frame == NULL) {
+ bytes = -1;
+ goto out;
+ }
+
+ sync_frame->local = local;
+ local->file = file;
+
+ LOCK (&file->lock);
+ {
+ fd = file->fd;
+ }
+ UNLOCK (&file->lock);
+
+ fd_ref (fd);
+
+ bytes += current_size;
+ STACK_WIND (sync_frame,
+ wb_sync_cbk,
+ FIRST_CHILD(sync_frame->this),
+ FIRST_CHILD(sync_frame->this)->fops->writev,
+ fd, vector,
+ count,
+ first_request->stub->args.writev.off,
+ iobref);
+
+ iobref_unref (iobref);
+ FREE (vector);
+ first_request = NULL;
+ iobref = NULL;
+ vector = NULL;
+ sync_frame = NULL;
+ local = NULL;
+ copied = count = 0;
+ }
+ }
out:
- return wb_inode;
-}
-
+ if (sync_frame != NULL) {
+ sync_frame->local = NULL;
+ STACK_DESTROY (sync_frame->root);
+ }
-wb_inode_t *
-wb_inode_create (xlator_t *this, inode_t *inode)
-{
- wb_inode_t *wb_inode = NULL;
+ if (local != NULL) {
+ FREE (local);
+ }
- GF_VALIDATE_OR_GOTO (this->name, inode, out);
+ if (iobref != NULL) {
+ iobref_unref (iobref);
+ }
- LOCK (&inode->lock);
- {
- wb_inode = __wb_inode_ctx_get (this, inode);
- if (!wb_inode)
- wb_inode = __wb_inode_create (this, inode);
+ if (vector != NULL) {
+ FREE (vector);
}
- UNLOCK (&inode->lock);
-out:
- return wb_inode;
+ return bytes;
}
-void
-wb_inode_destroy (wb_inode_t *wb_inode)
+int32_t
+wb_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret,
+ int32_t op_errno, struct stat *buf)
{
- GF_VALIDATE_OR_GOTO ("write-behind", wb_inode, out);
+ wb_local_t *local = NULL;
+ wb_request_t *request = NULL;
+ call_frame_t *process_frame = NULL;
+ wb_file_t *file = NULL;
+ int32_t ret = -1;
+ fd_t *fd = NULL;
+
+ local = frame->local;
+ file = local->file;
- LOCK_DESTROY (&wb_inode->lock);
- GF_FREE (wb_inode);
-out:
- return;
-}
+ request = local->request;
+ if (request) {
+ process_frame = copy_frame (frame);
+ if (process_frame == NULL) {
+ op_ret = -1;
+ op_errno = ENOMEM;
+ }
+ }
+ STACK_UNWIND_STRICT (stat, frame, op_ret, op_errno, buf);
-void
-__wb_fulfill_request (wb_request_t *req)
-{
- wb_inode_t *wb_inode = NULL;
+ if (request != NULL) {
+ wb_request_unref (request);
+ }
+
+ if (process_frame != NULL) {
+ ret = wb_process_queue (process_frame, file, 0);
+ if ((ret == -1) && (errno == ENOMEM) && (file != NULL)) {
+ LOCK (&file->lock);
+ {
+ file->op_ret = -1;
+ file->op_errno = ENOMEM;
+ }
+ UNLOCK (&file->lock);
+ }
- wb_inode = req->wb_inode;
+ STACK_DESTROY (process_frame->root);
+ }
- req->ordering.fulfilled = 1;
- wb_inode->window_current -= req->total_size;
- wb_inode->transit -= req->total_size;
+ if (file) {
+ LOCK (&file->lock);
+ {
+ fd = file->fd;
+ }
+ UNLOCK (&file->lock);
- if (!req->ordering.lied) {
- /* TODO: fail the req->frame with error if
- necessary
- */
- }
+ fd_unref (fd);
+ }
- __wb_request_unref (req);
+ return 0;
}
-void
-wb_head_done (wb_request_t *head)
+static int32_t
+wb_stat_helper (call_frame_t *frame, xlator_t *this, loc_t *loc)
{
- wb_request_t *req = NULL;
- wb_request_t *tmp = NULL;
- wb_inode_t *wb_inode = NULL;
-
- wb_inode = head->wb_inode;
-
- LOCK (&wb_inode->lock);
- {
- list_for_each_entry_safe (req, tmp, &head->winds, winds) {
- __wb_fulfill_request (req);
- }
- __wb_fulfill_request (head);
- }
- UNLOCK (&wb_inode->lock);
+ STACK_WIND (frame, wb_stat_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->stat,
+ loc);
+ return 0;
}
-void
-wb_fulfill_err (wb_request_t *head, int op_errno)
-{
- wb_inode_t *wb_inode;
- wb_request_t *req;
-
- wb_inode = head->wb_inode;
-
- /* for all future requests yet to arrive */
- fd_ctx_set (head->fd, THIS, op_errno);
-
- LOCK (&wb_inode->lock);
- {
- /* for all requests already arrived */
- list_for_each_entry (req, &wb_inode->all, all) {
- if (req->fd != head->fd)
- continue;
- req->op_ret = -1;
- req->op_errno = op_errno;
- }
- }
- UNLOCK (&wb_inode->lock);
-}
+int32_t
+wb_stat (call_frame_t *frame, xlator_t *this, loc_t *loc)
+{
+ wb_file_t *file = NULL;
+ fd_t *iter_fd = NULL;
+ wb_local_t *local = NULL;
+ uint64_t tmp_file = 0;
+ call_stub_t *stub = NULL;
+ wb_request_t *request = NULL;
+ int32_t ret = -1, op_errno = EINVAL;
+
+ if (loc->inode) {
+ /* FIXME: fd_lookup extends life of fd till stat returns */
+ iter_fd = fd_lookup (loc->inode, frame->root->pid);
+ if (iter_fd) {
+ if (!fd_ctx_get (iter_fd, this, &tmp_file)) {
+ file = (wb_file_t *)(long)tmp_file;
+ } else {
+ fd_unref (iter_fd);
+ iter_fd = NULL;
+ }
+ }
+ }
+ local = CALLOC (1, sizeof (*local));
+ if (local == NULL) {
+ op_errno = ENOMEM;
+ goto unwind;
+ }
-int
-wb_fulfill_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)
-{
- wb_inode_t *wb_inode = NULL;
- wb_request_t *head = NULL;
+ local->file = file;
+
+ frame->local = local;
- head = frame->local;
- frame->local = NULL;
+ if (file) {
+ stub = fop_stat_stub (frame, wb_stat_helper, loc);
+ if (stub == NULL) {
+ op_errno = ENOMEM;
+ goto unwind;
+ }
- wb_inode = head->wb_inode;
+ request = wb_enqueue (file, stub);
+ if (request == NULL) {
+ op_errno = ENOMEM;
+ goto unwind;
+ }
- if (op_ret == -1) {
- wb_fulfill_err (head, op_errno);
- } else if (op_ret < head->total_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).
- */
- wb_fulfill_err (head, EIO);
- }
+ ret = wb_process_queue (frame, file, 1);
+ if ((ret == -1) && (errno == ENOMEM)) {
+ op_errno = ENOMEM;
+ goto unwind;
+ }
- wb_head_done (head);
+ } else {
+ STACK_WIND (frame, wb_stat_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->stat,
+ loc);
+ }
+ return 0;
- wb_process_queue (wb_inode);
+unwind:
+ STACK_UNWIND_STRICT (stat, frame, -1, op_errno, NULL);
- STACK_DESTROY (frame->root);
+ if (stub) {
+ call_stub_destroy (stub);
+ }
+
+ if (iter_fd != NULL) {
+ fd_unref (iter_fd);
+ }
return 0;
}
-#define WB_IOV_LOAD(vec, cnt, req, head) do { \
- memcpy (&vec[cnt], req->stub->args.vector, \
- (req->stub->args.count * sizeof(vec[0]))); \
- cnt += req->stub->args.count; \
- head->total_size += req->write_size; \
- } while (0)
+int32_t
+wb_fstat_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret,
+ int32_t op_errno, struct stat *buf)
+{
+ wb_local_t *local = NULL;
+ wb_request_t *request = NULL;
+ wb_file_t *file = NULL;
+ int32_t ret = -1;
+
+ local = frame->local;
+ file = local->file;
+
+ request = local->request;
+ if ((file != NULL) && (request != NULL)) {
+ wb_request_unref (request);
+ ret = wb_process_queue (frame, file, 0);
+ if ((ret == -1) && (errno == ENOMEM)) {
+ op_ret = -1;
+ op_errno = ENOMEM;
+ }
+ }
+ STACK_UNWIND_STRICT (fstat, frame, op_ret, op_errno, buf);
-int
-wb_fulfill_head (wb_inode_t *wb_inode, wb_request_t *head)
-{
- struct iovec vector[MAX_VECTOR_COUNT];
- int count = 0;
- wb_request_t *req = NULL;
- call_frame_t *frame = NULL;
- gf_boolean_t fderr = _gf_false;
- xlator_t *this = NULL;
+ return 0;
+}
- this = THIS;
- /* make sure head->total_size is updated before we run into any
- * errors
- */
+int32_t
+wb_fstat_helper (call_frame_t *frame, xlator_t *this, fd_t *fd)
+{
+ STACK_WIND (frame,
+ wb_fstat_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->fstat,
+ fd);
+ return 0;
+}
- WB_IOV_LOAD (vector, count, head, head);
- list_for_each_entry (req, &head->winds, winds) {
- WB_IOV_LOAD (vector, count, req, head);
+int32_t
+wb_fstat (call_frame_t *frame, xlator_t *this, fd_t *fd)
+{
+ wb_file_t *file = NULL;
+ wb_local_t *local = NULL;
+ uint64_t tmp_file = 0;
+ call_stub_t *stub = NULL;
+ wb_request_t *request = NULL;
+ int32_t ret = -1;
+ int op_errno = EINVAL;
- if (iobref_merge (head->stub->args.iobref,
- req->stub->args.iobref))
- goto err;
- }
+ if ((!S_ISDIR (fd->inode->st_mode))
+ && fd_ctx_get (fd, this, &tmp_file)) {
+ gf_log (this->name, GF_LOG_DEBUG, "write behind file pointer is"
+ " not stored in context of fd(%p), returning EBADFD",
+ fd);
- if (wb_fd_err (head->fd, this, NULL)) {
- fderr = _gf_true;
- goto err;
+ STACK_UNWIND_STRICT (fstat, frame, -1, EBADFD, NULL);
+ return 0;
}
- frame = create_frame (wb_inode->this, wb_inode->this->ctx->pool);
- if (!frame)
- goto err;
+ file = (wb_file_t *)(long)tmp_file;
+ local = CALLOC (1, sizeof (*local));
+ if (local == NULL) {
+ STACK_UNWIND_STRICT (fstat, frame, -1, ENOMEM, NULL);
+ return 0;
+ }
- frame->root->lk_owner = head->lk_owner;
- frame->local = head;
+ local->file = file;
- LOCK (&wb_inode->lock);
- {
- wb_inode->transit += head->total_size;
- }
- UNLOCK (&wb_inode->lock);
+ frame->local = local;
- STACK_WIND (frame, wb_fulfill_cbk, FIRST_CHILD (frame->this),
- FIRST_CHILD (frame->this)->fops->writev,
- head->fd, vector, count,
- head->stub->args.offset,
- head->stub->args.flags,
- head->stub->args.iobref, NULL);
+ if (file) {
+ stub = fop_fstat_stub (frame, wb_fstat_helper, fd);
+ if (stub == NULL) {
+ op_errno = ENOMEM;
+ goto unwind;
+ }
+
+ request = wb_enqueue (file, stub);
+ if (request == NULL) {
+ op_errno = ENOMEM;
+ goto unwind;
+ }
- return 0;
-err:
- if (!fderr) {
- /* frame creation failure */
- fderr = ENOMEM;
- wb_fulfill_err (head, fderr);
+ /*
+ FIXME:should the request queue be emptied in case of error?
+ */
+ ret = wb_process_queue (frame, file, 1);
+ if ((ret == -1) && (errno == ENOMEM)) {
+ op_errno = ENOMEM;
+ goto unwind;
+ }
+ } else {
+ STACK_WIND (frame,
+ wb_fstat_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->fstat,
+ fd);
}
- wb_head_done (head);
+ return 0;
+unwind:
+ STACK_UNWIND_STRICT (fstat, frame, -1, op_errno, NULL);
+
+ if (stub) {
+ call_stub_destroy (stub);
+ }
- return fderr;
+ return 0;
}
-#define NEXT_HEAD(head, req) do { \
- if (head) \
- ret |= wb_fulfill_head (wb_inode, head); \
- head = req; \
- expected_offset = req->stub->args.offset + \
- req->write_size; \
- curr_aggregate = 0; \
- vector_count = 0; \
- } while (0)
-
+int32_t
+wb_truncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct stat *prebuf,
+ struct stat *postbuf)
+{
+ wb_local_t *local = NULL;
+ wb_request_t *request = NULL;
+ wb_file_t *file = NULL;
+ call_frame_t *process_frame = NULL;
+ int32_t ret = -1;
+ fd_t *fd = NULL;
+
+ local = frame->local;
+ file = local->file;
+ request = local->request;
+
+ if ((request != NULL) && (file != NULL)) {
+ process_frame = copy_frame (frame);
+ if (process_frame == NULL) {
+ op_ret = -1;
+ op_errno = ENOMEM;
+ }
+ }
-int
-wb_fulfill (wb_inode_t *wb_inode, list_head_t *liabilities)
-{
- wb_request_t *req = NULL;
- wb_request_t *head = NULL;
- wb_request_t *tmp = NULL;
- wb_conf_t *conf = NULL;
- off_t expected_offset = 0;
- size_t curr_aggregate = 0;
- size_t vector_count = 0;
- int ret = 0;
-
- conf = wb_inode->this->private;
-
- list_for_each_entry_safe (req, tmp, liabilities, winds) {
- list_del_init (&req->winds);
-
- if (!head) {
- NEXT_HEAD (head, req);
- continue;
- }
-
- if (req->fd != head->fd) {
- NEXT_HEAD (head, req);
- continue;
- }
-
- if (!is_same_lkowner (&req->lk_owner, &head->lk_owner)) {
- NEXT_HEAD (head, req);
- continue;
- }
-
- if (expected_offset != req->stub->args.offset) {
- NEXT_HEAD (head, req);
- continue;
- }
-
- if ((curr_aggregate + req->write_size) > conf->aggregate_size) {
- NEXT_HEAD (head, req);
- continue;
- }
-
- if (vector_count + req->stub->args.count >
- MAX_VECTOR_COUNT) {
- NEXT_HEAD (head, req);
- continue;
- }
-
- list_add_tail (&req->winds, &head->winds);
- curr_aggregate += req->write_size;
- vector_count += req->stub->args.count;
- }
-
- if (head)
- ret |= wb_fulfill_head (wb_inode, head);
-
- return ret;
-}
+ STACK_UNWIND_STRICT (truncate, frame, op_ret, op_errno, prebuf, postbuf);
+ if (request) {
+ wb_request_unref (request);
+ }
-void
-wb_do_unwinds (wb_inode_t *wb_inode, list_head_t *lies)
-{
- wb_request_t *req = NULL;
- wb_request_t *tmp = NULL;
- call_frame_t *frame = NULL;
- struct iatt buf = {0, };
+ if (process_frame != NULL) {
+ ret = wb_process_queue (process_frame, file, 0);
+ if ((ret == -1) && (errno == ENOMEM) && (file != NULL)) {
+ LOCK (&file->lock);
+ {
+ file->op_ret = -1;
+ file->op_errno = ENOMEM;
+ }
+ UNLOCK (&file->lock);
+ }
- list_for_each_entry_safe (req, tmp, lies, unwinds) {
- frame = req->stub->frame;
+ STACK_DESTROY (process_frame->root);
+ }
- STACK_UNWIND_STRICT (writev, frame, req->op_ret, req->op_errno,
- &buf, &buf, NULL); /* :O */
- req->stub->frame = NULL;
+ if (file) {
+ LOCK (&file->lock);
+ {
+ fd = file->fd;
+ }
+ UNLOCK (&file->lock);
- list_del_init (&req->unwinds);
- wb_request_unref (req);
+ fd_unref (fd);
}
- return;
+ return 0;
}
-void
-__wb_pick_unwinds (wb_inode_t *wb_inode, list_head_t *lies)
+static int32_t
+wb_truncate_helper (call_frame_t *frame, xlator_t *this, loc_t *loc,
+ off_t offset)
{
- wb_request_t *req = NULL;
- wb_request_t *tmp = NULL;
-
- list_for_each_entry_safe (req, tmp, &wb_inode->temptation, lie) {
- if (!req->ordering.fulfilled &&
- wb_inode->window_current > wb_inode->window_conf)
- continue;
-
- list_del_init (&req->lie);
- list_move_tail (&req->unwinds, lies);
+ STACK_WIND (frame,
+ wb_truncate_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->truncate,
+ loc,
+ offset);
- wb_inode->window_current += req->orig_size;
-
- if (!req->ordering.fulfilled) {
- /* burden increased */
- list_add_tail (&req->lie, &wb_inode->liability);
-
- req->ordering.lied = 1;
-
- wb_inode->gen++;
- }
- }
-
- return;
+ return 0;
}
-int
-__wb_collapse_small_writes (wb_request_t *holder, wb_request_t *req)
+int32_t
+wb_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset)
{
- char *ptr = NULL;
- struct iobuf *iobuf = NULL;
- struct iobref *iobref = NULL;
- int ret = -1;
- ssize_t required_size = 0;
- size_t holder_len = 0;
- size_t req_len = 0;
-
- if (!holder->iobref) {
- holder_len = iov_length (holder->stub->args.vector,
- holder->stub->args.count);
- req_len = iov_length (req->stub->args.vector,
- req->stub->args.count);
-
- required_size = max ((THIS->ctx->page_size),
- (holder_len + req_len));
- iobuf = iobuf_get2 (req->wb_inode->this->ctx->iobuf_pool,
- required_size);
- if (iobuf == NULL) {
- goto out;
- }
+ wb_file_t *file = NULL;
+ fd_t *iter_fd = NULL;
+ wb_local_t *local = NULL;
+ uint64_t tmp_file = 0;
+ call_stub_t *stub = NULL;
+ wb_request_t *request = NULL;
+ int32_t ret = -1, op_errno = ENOMEM;
- iobref = iobref_new ();
- if (iobref == NULL) {
- iobuf_unref (iobuf);
- goto out;
+ if (loc->inode)
+ {
+ /*
+ FIXME: fd_lookup extends life of fd till the execution of
+ truncate_cbk
+ */
+ iter_fd = fd_lookup (loc->inode, frame->root->pid);
+ if (iter_fd) {
+ if (!fd_ctx_get (iter_fd, this, &tmp_file)){
+ file = (wb_file_t *)(long)tmp_file;
+ } else {
+ fd_unref (iter_fd);
+ }
}
+ }
+
+ local = CALLOC (1, sizeof (*local));
+ if (local == NULL) {
+ op_errno = ENOMEM;
+ goto unwind;
+ }
- ret = iobref_add (iobref, iobuf);
- if (ret != 0) {
- gf_log (req->wb_inode->this->name, GF_LOG_WARNING,
- "cannot add iobuf (%p) into iobref (%p)",
- iobuf, iobref);
- iobuf_unref (iobuf);
- iobref_unref (iobref);
- goto out;
+ local->file = file;
+
+ frame->local = local;
+ if (file) {
+ stub = fop_truncate_stub (frame, wb_truncate_helper, loc,
+ offset);
+ if (stub == NULL) {
+ op_errno = ENOMEM;
+ goto unwind;
}
- iov_unload (iobuf->ptr, holder->stub->args.vector,
- holder->stub->args.count);
- holder->stub->args.vector[0].iov_base = iobuf->ptr;
- holder->stub->args.count = 1;
+ request = wb_enqueue (file, stub);
+ if (request == NULL) {
+ op_errno = ENOMEM;
+ goto unwind;
+ }
+
+ ret = wb_process_queue (frame, file, 1);
+ if ((ret == -1) && (errno == ENOMEM)) {
+ op_errno = ENOMEM;
+ goto unwind;
+ }
+ } else {
+ STACK_WIND (frame,
+ wb_truncate_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->truncate,
+ loc,
+ offset);
+ }
- iobref_unref (holder->stub->args.iobref);
- holder->stub->args.iobref = iobref;
+ return 0;
- iobuf_unref (iobuf);
+unwind:
+ STACK_UNWIND_STRICT (truncate, frame, -1, op_errno, NULL, NULL);
- holder->iobref = iobref_ref (iobref);
+ if (stub) {
+ call_stub_destroy (stub);
}
- ptr = holder->stub->args.vector[0].iov_base + holder->write_size;
+ return 0;
+}
- iov_unload (ptr, req->stub->args.vector,
- req->stub->args.count);
- holder->stub->args.vector[0].iov_len += req->write_size;
- holder->write_size += req->write_size;
- holder->ordering.size += req->write_size;
+int32_t
+wb_ftruncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct stat *prebuf,
+ struct stat *postbuf)
+{
+ wb_local_t *local = NULL;
+ wb_request_t *request = NULL;
+ wb_file_t *file = NULL;
+ int32_t ret = -1;
+
+ local = frame->local;
+ file = local->file;
+ request = local->request;
+
+ if ((request != NULL) && (file != NULL)) {
+ wb_request_unref (request);
+ ret = wb_process_queue (frame, file, 0);
+ if ((ret == -1) && (errno == ENOMEM)) {
+ op_ret = -1;
+ op_errno = ENOMEM;
+ }
+ }
- ret = 0;
-out:
- return ret;
+ STACK_UNWIND_STRICT (ftruncate, frame, op_ret, op_errno, prebuf, postbuf);
+
+ return 0;
}
-void
-__wb_preprocess_winds (wb_inode_t *wb_inode)
-{
- off_t offset_expected = 0;
- ssize_t space_left = 0;
- wb_request_t *req = NULL;
- wb_request_t *tmp = NULL;
- wb_request_t *holder = NULL;
- wb_conf_t *conf = NULL;
- int ret = 0;
- ssize_t page_size = 0;
-
- /* With asynchronous IO from a VM guest (as a file), there
- can be two sequential writes happening in two regions
- of the file. But individual (broken down) IO requests
- can arrive interleaved.
-
- TODO: cycle for each such sequence sifting
- through the interleaved ops
- */
-
- page_size = wb_inode->this->ctx->page_size;
- conf = wb_inode->this->private;
-
- list_for_each_entry_safe (req, tmp, &wb_inode->todo, todo) {
- if (!req->ordering.tempted) {
- if (holder) {
- if (wb_requests_conflict (holder, req))
- /* do not hold on write if a
- dependent write is in queue */
- holder->ordering.go = 1;
- }
- /* collapse only non-sync writes */
- continue;
- } else if (!holder) {
- /* holder is always a non-sync write */
- holder = req;
- continue;
- }
-
- offset_expected = holder->stub->args.offset
- + holder->write_size;
-
- if (req->stub->args.offset != offset_expected) {
- holder->ordering.go = 1;
- holder = req;
- continue;
- }
-
- if (!is_same_lkowner (&req->lk_owner, &holder->lk_owner)) {
- holder->ordering.go = 1;
- holder = req;
- continue;
- }
-
- if (req->fd != holder->fd) {
- holder->ordering.go = 1;
- holder = req;
- continue;
- }
+static int32_t
+wb_ftruncate_helper (call_frame_t *frame, xlator_t *this, fd_t *fd,
+ off_t offset)
+{
+ STACK_WIND (frame,
+ wb_ftruncate_cbk,
+ FIRST_CHILD(this),
+ 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)
+{
+ wb_file_t *file = NULL;
+ wb_local_t *local = NULL;
+ uint64_t tmp_file = 0;
+ call_stub_t *stub = NULL;
+ wb_request_t *request = NULL;
+ int32_t ret = -1;
+ int op_errno = EINVAL;
+
+ if ((!S_ISDIR (fd->inode->st_mode))
+ && fd_ctx_get (fd, this, &tmp_file)) {
+ gf_log (this->name, GF_LOG_DEBUG, "write behind file pointer is"
+ " not stored in context of fd(%p), returning EBADFD",
+ fd);
+
+ STACK_UNWIND_STRICT (ftruncate, frame, -1, EBADFD,
+ NULL, NULL);
+ return 0;
+ }
- space_left = page_size - holder->write_size;
+ file = (wb_file_t *)(long)tmp_file;
- if (space_left < req->write_size) {
- holder->ordering.go = 1;
- holder = req;
- continue;
- }
+ local = CALLOC (1, sizeof (*local));
+ if (local == NULL) {
+ STACK_UNWIND_STRICT (ftruncate, frame, -1, ENOMEM,
+ NULL, NULL);
+ return 0;
+ }
- ret = __wb_collapse_small_writes (holder, req);
- if (ret)
- continue;
+ local->file = file;
- /* collapsed request is as good as wound
- (from its p.o.v)
- */
- list_del_init (&req->todo);
- __wb_fulfill_request (req);
+ frame->local = local;
- /* Only the last @holder in queue which
+ if (file) {
+ stub = fop_ftruncate_stub (frame, wb_ftruncate_helper, fd,
+ offset);
+ if (stub == NULL) {
+ op_errno = ENOMEM;
+ goto unwind;
+ }
- - does not have any non-buffered-writes following it
- - has not yet filled its capacity
+ request = wb_enqueue (file, stub);
+ if (request == NULL) {
+ op_errno = ENOMEM;
+ goto unwind;
+ }
- does not get its 'go' set, in anticipation of the arrival
- of consecutive smaller writes.
- */
+ ret = wb_process_queue (frame, file, 1);
+ if ((ret == -1) && (errno == ENOMEM)) {
+ op_errno = ENOMEM;
+ goto unwind;
+ }
+ } else {
+ STACK_WIND (frame,
+ wb_ftruncate_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->ftruncate,
+ fd,
+ offset);
}
- /* but if trickling writes are enabled, then do not hold back
- writes if there are no outstanding requests
- */
+ return 0;
+
+unwind:
+ STACK_UNWIND_STRICT (ftruncate, frame, -1, op_errno, NULL, NULL);
- if (conf->trickling_writes && !wb_inode->transit && holder)
- holder->ordering.go = 1;
+ if (stub) {
+ call_stub_destroy (stub);
+ }
- return;
+ return 0;
}
-void
-__wb_pick_winds (wb_inode_t *wb_inode, list_head_t *tasks,
- list_head_t *liabilities)
+int32_t
+wb_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct stat *statpre, struct stat *statpost)
{
- wb_request_t *req = NULL;
- wb_request_t *tmp = NULL;
+ wb_local_t *local = NULL;
+ wb_request_t *request = NULL;
+ call_frame_t *process_frame = NULL;
+ wb_file_t *file = NULL;
+ int32_t ret = -1;
+ fd_t *fd = NULL;
+
+ local = frame->local;
+ file = local->file;
+ request = local->request;
- list_for_each_entry_safe (req, tmp, &wb_inode->todo, todo) {
- if (wb_liability_has_conflict (wb_inode, req))
- continue;
+ if (request) {
+ process_frame = copy_frame (frame);
+ if (process_frame == NULL) {
+ op_ret = -1;
+ op_errno = ENOMEM;
+ }
+ }
+
+ STACK_UNWIND_STRICT (setattr, frame, op_ret, op_errno, statpre, statpost);
- if (req->ordering.tempted && !req->ordering.go)
- /* wait some more */
- continue;
+ if (request) {
+ wb_request_unref (request);
+ }
- if (req->stub->fop == GF_FOP_WRITE) {
- if (wb_wip_has_conflict (wb_inode, req))
- continue;
+ if (request && (process_frame != NULL)) {
+ ret = wb_process_queue (process_frame, file, 0);
+ if ((ret == -1) && (errno == ENOMEM) && (file != NULL)) {
+ LOCK (&file->lock);
+ {
+ file->op_ret = -1;
+ file->op_errno = ENOMEM;
+ }
+ UNLOCK (&file->lock);
+ }
- list_add_tail (&req->wip, &wb_inode->wip);
+ STACK_DESTROY (process_frame->root);
+ }
- if (!req->ordering.tempted)
- /* unrefed in wb_writev_cbk */
- req->stub->frame->local =
- __wb_request_ref (req);
- }
+ if (file) {
+ LOCK (&file->lock);
+ {
+ fd = file->fd;
+ }
+ UNLOCK (&file->lock);
- list_del_init (&req->todo);
+ fd_unref (fd);
+ }
- if (req->ordering.tempted)
- list_add_tail (&req->winds, liabilities);
- else
- list_add_tail (&req->winds, tasks);
- }
+ return 0;
}
-void
-wb_do_winds (wb_inode_t *wb_inode, list_head_t *tasks)
+static int32_t
+wb_setattr_helper (call_frame_t *frame, xlator_t *this, loc_t *loc,
+ struct stat *stbuf, int32_t valid)
{
- wb_request_t *req = NULL;
- wb_request_t *tmp = NULL;
+ STACK_WIND (frame,
+ wb_setattr_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->setattr,
+ loc,
+ stbuf,
+ valid);
- list_for_each_entry_safe (req, tmp, tasks, winds) {
- list_del_init (&req->winds);
-
- call_resume (req->stub);
-
- wb_request_unref (req);
- }
+ return 0;
}
-void
-wb_process_queue (wb_inode_t *wb_inode)
-{
- list_head_t tasks = {0, };
- list_head_t lies = {0, };
- list_head_t liabilities = {0, };
- int retry = 0;
-
- INIT_LIST_HEAD (&tasks);
- INIT_LIST_HEAD (&lies);
- INIT_LIST_HEAD (&liabilities);
+int32_t
+wb_setattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
+ struct stat *stbuf, int32_t valid)
+{
+ wb_file_t *file = NULL;
+ fd_t *iter_fd = NULL;
+ wb_local_t *local = NULL;
+ uint64_t tmp_file = 0;
+ call_stub_t *stub = NULL;
+ wb_request_t *request = NULL;
+ int32_t ret = -1, op_errno = EINVAL;
+
+ local = CALLOC (1, sizeof (*local));
+ if (local == NULL) {
+ op_errno = ENOMEM;
+ goto unwind;
+ }
- do {
- LOCK (&wb_inode->lock);
- {
- __wb_preprocess_winds (wb_inode);
- __wb_pick_winds (wb_inode, &tasks, &liabilities);
+ frame->local = local;
- __wb_pick_unwinds (wb_inode, &lies);
+ 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
+ of wb_utimens_cbk
+ */
+ iter_fd = fd_lookup (loc->inode, frame->root->pid);
+ if (iter_fd) {
+ if (!fd_ctx_get (iter_fd, this, &tmp_file)) {
+ file = (wb_file_t *)(long)tmp_file;
+ } else {
+ fd_unref (iter_fd);
+ }
}
- UNLOCK (&wb_inode->lock);
- wb_do_unwinds (wb_inode, &lies);
+ }
- wb_do_winds (wb_inode, &tasks);
+ local->file = file;
- /* fd might've been marked bad due to previous errors.
- * Since, caller of wb_process_queue might be the last fop on
- * inode, make sure we keep processing request queue, till there
- * are no requests left.
- */
- retry = wb_fulfill (wb_inode, &liabilities);
- } while (retry);
+ if (file) {
+ stub = fop_setattr_stub (frame, wb_setattr_helper, loc, stbuf, valid);
+ if (stub == NULL) {
+ op_errno = ENOMEM;
+ goto unwind;
+ }
- return;
-}
+ request = wb_enqueue (file, stub);
+ if (request == NULL) {
+ op_errno = ENOMEM;
+ goto unwind;
+ }
+ ret = wb_process_queue (frame, file, 1);
+ if ((ret == -1) && (errno == ENOMEM)) {
+ op_errno = ENOMEM;
+ goto unwind;
+ }
+ } else {
+ STACK_WIND (frame,
+ wb_setattr_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->setattr,
+ loc,
+ stbuf, valid);
+ }
-void
-wb_set_inode_size(wb_inode_t *wb_inode, struct iatt *postbuf)
-{
- GF_ASSERT (wb_inode);
- GF_ASSERT (postbuf);
-
- LOCK (&wb_inode->lock);
- {
- wb_inode->size = postbuf->ia_size;
- }
- UNLOCK (&wb_inode->lock);
-}
+ return 0;
+unwind:
+ STACK_UNWIND_STRICT (setattr, frame, -1, op_errno,
+ NULL, NULL);
+ if (stub) {
+ call_stub_destroy (stub);
+ }
+out:
+ return 0;
+}
-int
-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)
+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)
{
- wb_request_t *req = NULL;
- wb_inode_t *wb_inode;
+ int32_t wbflags = 0, flags = 0;
+ wb_file_t *file = NULL;
+ wb_conf_t *conf = NULL;
+ wb_local_t *local = NULL;
- req = frame->local;
- frame->local = NULL;
- wb_inode = req->wb_inode;
+ conf = this->private;
- wb_request_unref (req);
+ local = frame->local;
+ if (local == NULL) {
+ op_ret = -1;
+ op_errno = EINVAL;
+ goto out;
+ }
- /* requests could be pending while this was in progress */
- wb_process_queue(wb_inode);
+ flags = local->flags;
+ wbflags = local->wbflags;
- STACK_UNWIND_STRICT (writev, frame, op_ret, op_errno, prebuf, postbuf,
- xdata);
- return 0;
-}
+ if (op_ret != -1) {
+ file = wb_file_create (this, fd);
+ if (file == NULL) {
+ op_ret = -1;
+ op_errno = ENOMEM;
+ goto out;
+ }
+ /*
+ If mandatory locking has been enabled on this file,
+ we disable caching on it
+ */
+
+ if ((fd->inode->st_mode & S_ISGID)
+ && !(fd->inode->st_mode & S_IXGRP))
+ 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;
+ }
-int
-wb_writev_helper (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)
-{
- STACK_WIND (frame, wb_writev_cbk,
- FIRST_CHILD (this), FIRST_CHILD (this)->fops->writev,
- fd, vector, count, offset, flags, iobref, xdata);
- return 0;
+ if (wbflags & GF_OPEN_NOWB) {
+ file->disabled = 1;
+ }
+
+ LOCK_INIT (&file->lock);
+ }
+
+out:
+ STACK_UNWIND_STRICT (open, frame, op_ret, op_errno, fd);
+ return 0;
}
-int
-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
+wb_open (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
+ fd_t *fd, int32_t wbflags)
{
- wb_inode_t *wb_inode = NULL;
- wb_conf_t *conf = NULL;
- gf_boolean_t wb_disabled = 0;
- call_stub_t *stub = NULL;
- int ret = -1;
- int32_t op_errno = EINVAL;
- int o_direct = O_DIRECT;
-
- conf = this->private;
-
- if (wb_fd_err (fd, this, &op_errno)) {
- goto unwind;
- }
-
- wb_inode = wb_inode_create (this, fd->inode);
- if (!wb_inode) {
- op_errno = ENOMEM;
- goto unwind;
- }
-
- if (!conf->strict_O_DIRECT)
- o_direct = 0;
-
- if (fd->flags & (O_SYNC|O_DSYNC|o_direct))
- wb_disabled = 1;
-
- if (flags & (O_SYNC|O_DSYNC|o_direct))
- wb_disabled = 1;
+ wb_local_t *local = NULL;
+ int32_t op_errno = EINVAL;
- if (wb_disabled)
- stub = fop_writev_stub (frame, wb_writev_helper, fd, vector,
- count, offset, flags, iobref, xdata);
- else
- stub = fop_writev_stub (frame, NULL, fd, vector, count, offset,
- flags, iobref, xdata);
- if (!stub) {
+ local = CALLOC (1, sizeof (*local));
+ if (local == NULL) {
op_errno = ENOMEM;
goto unwind;
}
- if (wb_disabled)
- ret = wb_enqueue (wb_inode, stub);
- else
- ret = wb_enqueue_tempted (wb_inode, stub);
-
- if (!ret) {
- op_errno = ENOMEM;
- goto unwind;
- }
-
- wb_process_queue (wb_inode);
+ 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, wbflags);
return 0;
unwind:
- STACK_UNWIND_STRICT (writev, frame, -1, op_errno, NULL, NULL, NULL);
+ STACK_UNWIND_STRICT (open, frame, -1, op_errno, NULL);
+ return 0;
+}
- if (stub)
- call_stub_destroy (stub);
+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 stat *buf, struct stat *preparent,
+ struct stat *postparent)
+{
+ long flags = 0;
+ wb_file_t *file = NULL;
+ wb_conf_t *conf = this->private;
+
+ if (op_ret != -1) {
+ file = wb_file_create (this, fd);
+ if (file == NULL) {
+ op_ret = -1;
+ op_errno = ENOMEM;
+ goto out;
+ }
+ /*
+ * If mandatory locking has been enabled on this file,
+ * we disable caching on it
+ */
+ if ((fd->inode->st_mode & S_ISGID)
+ && !(fd->inode->st_mode & S_IXGRP))
+ file->disabled = 1;
+
+ /* If O_DIRECT then, we disable chaching */
+ if (frame->local) {
+ flags = (long)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;
+ }
+ }
+
+ LOCK_INIT (&file->lock);
+ }
+
+ frame->local = NULL;
+
+out:
+ STACK_UNWIND_STRICT (create, frame, op_ret, op_errno, fd, inode, buf, preparent,
+ postparent);
return 0;
}
-int
-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)
+int32_t
+wb_create (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
+ mode_t mode, fd_t *fd)
{
- STACK_WIND (frame, default_readv_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->readv, fd, size, offset, flags,
- xdata);
+ frame->local = (void *)(long)flags;
+
+ STACK_WIND (frame,
+ wb_create_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->create,
+ loc, flags, mode, fd);
return 0;
}
-int
-wb_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
+__wb_mark_wind_all (wb_file_t *file, list_head_t *list, list_head_t *winds)
{
- wb_inode_t *wb_inode = NULL;
- call_stub_t *stub = NULL;
+ wb_request_t *request = NULL;
+ size_t size = 0;
+ char first_request = 1;
+ off_t offset_expected = 0;
- wb_inode = wb_inode_ctx_get (this, fd->inode);
- if (!wb_inode)
- goto noqueue;
+ list_for_each_entry (request, list, list)
+ {
+ if ((request->stub == NULL)
+ || (request->stub->fop != GF_FOP_WRITE)) {
+ break;
+ }
- stub = fop_readv_stub (frame, wb_readv_helper, fd, size,
- offset, flags, xdata);
- if (!stub)
- goto unwind;
+ if (!request->flags.write_request.stack_wound) {
+ if (first_request) {
+ first_request = 0;
+ offset_expected = request->stub->args.writev.off;
+ }
+
+ if (request->stub->args.writev.off != offset_expected) {
+ break;
+ }
+
+ size += request->write_size;
+ offset_expected += request->write_size;
+ file->aggregate_current -= request->write_size;
+
+ request->flags.write_request.stack_wound = 1;
+ list_add_tail (&request->winds, winds);
+ }
+ }
+
+ return size;
+}
- if (!wb_enqueue (wb_inode, stub))
- goto unwind;
- wb_process_queue (wb_inode);
+void
+__wb_can_wind (list_head_t *list, char *other_fop_in_queue,
+ char *non_contiguous_writes, char *incomplete_writes)
+{
+ wb_request_t *request = NULL;
+ char first_request = 1;
+ off_t offset_expected = 0;
- return 0;
+ list_for_each_entry (request, list, list)
+ {
+ if ((request->stub == NULL)
+ || (request->stub->fop != GF_FOP_WRITE)) {
+ if (request->stub && other_fop_in_queue) {
+ *other_fop_in_queue = 1;
+ }
+ break;
+ }
-unwind:
- STACK_UNWIND_STRICT (readv, frame, -1, ENOMEM, NULL, 0, NULL, NULL,
- NULL);
- return 0;
+ if (request->flags.write_request.stack_wound
+ && !request->flags.write_request.got_reply
+ && (incomplete_writes != NULL)) {
+ *incomplete_writes = 1;
+ break;
+ }
-noqueue:
- STACK_WIND (frame, default_readv_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->readv, fd, size, offset, flags,
- xdata);
- return 0;
-}
+ if (!request->flags.write_request.stack_wound) {
+ if (first_request) {
+ first_request = 0;
+ offset_expected = request->stub->args.writev.off;
+ }
+ if (offset_expected != request->stub->args.writev.off) {
+ if (non_contiguous_writes) {
+ *non_contiguous_writes = 1;
+ }
+ break;
+ }
-int
-wb_flush_bg_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
-{
- STACK_DESTROY (frame->root);
- return 0;
+ offset_expected += request->write_size;
+ }
+ }
+
+ return;
}
-int
-wb_flush_helper (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
+ssize_t
+__wb_mark_winds (list_head_t *list, list_head_t *winds, size_t aggregate_conf,
+ char wind_all, char enable_trickling_writes)
{
- wb_conf_t *conf = NULL;
- wb_inode_t *wb_inode = NULL;
- call_frame_t *bg_frame = NULL;
- int32_t op_errno = 0;
- int op_ret = 0;
+ size_t size = 0;
+ char other_fop_in_queue = 0;
+ char incomplete_writes = 0;
+ char non_contiguous_writes = 0;
+ wb_request_t *request = NULL;
+ wb_file_t *file = NULL;
- conf = this->private;
+ if (list_empty (list)) {
+ goto out;
+ }
- wb_inode = wb_inode_ctx_get (this, fd->inode);
- if (!wb_inode) {
- op_ret = -1;
- op_errno = EINVAL;
- goto unwind;
- }
+ request = list_entry (list->next, typeof (*request), list);
+ file = request->file;
- if (wb_fd_err (fd, this, &op_errno)) {
- op_ret = -1;
- goto unwind;
- }
+ if (!wind_all && (file->aggregate_current < aggregate_conf)) {
+ __wb_can_wind (list, &other_fop_in_queue,
+ &non_contiguous_writes, &incomplete_writes);
+ }
- if (conf->flush_behind)
- goto flushbehind;
-
- STACK_WIND (frame, default_flush_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->flush, fd, xdata);
- return 0;
-
-flushbehind:
- bg_frame = copy_frame (frame);
- if (!bg_frame) {
- op_ret = -1;
- op_errno = ENOMEM;
- goto unwind;
- }
-
- STACK_WIND (bg_frame, wb_flush_bg_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->flush, fd, xdata);
- /* fall through */
-unwind:
- STACK_UNWIND_STRICT (flush, frame, op_ret, op_errno, NULL);
+ if ((enable_trickling_writes && !incomplete_writes)
+ || (wind_all) || (non_contiguous_writes)
+ || (other_fop_in_queue)
+ || (file->aggregate_current >= aggregate_conf)) {
+ size = __wb_mark_wind_all (file, list, winds);
+ }
- return 0;
+out:
+ return size;
}
-int
-wb_flush (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
+size_t
+__wb_mark_unwind_till (list_head_t *list, list_head_t *unwinds, size_t size)
{
- wb_inode_t *wb_inode = NULL;
- call_stub_t *stub = NULL;
-
- wb_inode = wb_inode_ctx_get (this, fd->inode);
- if (!wb_inode)
- goto noqueue;
-
- stub = fop_flush_stub (frame, wb_flush_helper, fd, xdata);
- if (!stub)
- goto unwind;
+ size_t written_behind = 0;
+ wb_request_t *request = NULL;
+ wb_file_t *file = NULL;
- if (!wb_enqueue (wb_inode, stub))
- goto unwind;
-
- wb_process_queue (wb_inode);
+ if (list_empty (list)) {
+ goto out;
+ }
- return 0;
+ request = list_entry (list->next, typeof (*request), list);
+ file = request->file;
-unwind:
- STACK_UNWIND_STRICT (flush, frame, -1, ENOMEM, NULL);
+ list_for_each_entry (request, list, list)
+ {
+ if ((request->stub == NULL)
+ || (request->stub->fop != GF_FOP_WRITE)) {
+ continue;
+ }
- return 0;
+ if (written_behind <= size) {
+ if (!request->flags.write_request.write_behind) {
+ written_behind += request->write_size;
+ request->flags.write_request.write_behind = 1;
+ list_add_tail (&request->unwinds, unwinds);
+
+ if (!request->flags.write_request.got_reply) {
+ file->window_current += request->write_size;
+ }
+ }
+ } else {
+ break;
+ }
+ }
-noqueue:
- STACK_WIND (frame, default_flush_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->flush, fd, xdata);
- return 0;
+out:
+ return written_behind;
}
-
-int
-wb_fsync_helper (call_frame_t *frame, xlator_t *this, fd_t *fd,
- int32_t datasync, dict_t *xdata)
+void
+__wb_mark_unwinds (list_head_t *list, list_head_t *unwinds)
{
- STACK_WIND (frame, default_fsync_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fsync, fd, datasync, xdata);
- return 0;
-}
+ wb_request_t *request = NULL;
+ wb_file_t *file = NULL;
+ if (list_empty (list)) {
+ goto out;
+ }
-int
-wb_fsync (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t datasync,
- dict_t *xdata)
-{
- wb_inode_t *wb_inode = NULL;
- call_stub_t *stub = NULL;
- int32_t op_errno = EINVAL;
+ request = list_entry (list->next, typeof (*request), list);
+ file = request->file;
- if (wb_fd_err (fd, this, &op_errno))
- goto unwind;
+ if (file->window_current <= file->window_conf) {
+ __wb_mark_unwind_till (list, unwinds,
+ file->window_conf - file->window_current);
+ }
- wb_inode = wb_inode_ctx_get (this, fd->inode);
- if (!wb_inode)
- goto noqueue;
+out:
+ return;
+}
- stub = fop_fsync_stub (frame, wb_fsync_helper, fd, datasync, xdata);
- if (!stub)
- goto unwind;
- if (!wb_enqueue (wb_inode, stub))
- goto unwind;
+uint32_t
+__wb_get_other_requests (list_head_t *list, list_head_t *other_requests)
+{
+ wb_request_t *request = NULL;
+ uint32_t count = 0;
+ list_for_each_entry (request, list, list) {
+ if ((request->stub == NULL)
+ || (request->stub->fop == GF_FOP_WRITE)) {
+ break;
+ }
+
+ if (!request->flags.other_requests.marked_for_resume) {
+ request->flags.other_requests.marked_for_resume = 1;
+ list_add_tail (&request->other_requests,
+ other_requests);
+ count++;
+ }
+ }
- wb_process_queue (wb_inode);
+ return count;
+}
- return 0;
-unwind:
- STACK_UNWIND_STRICT (fsync, frame, -1, op_errno, NULL, NULL, NULL);
+int32_t
+wb_stack_unwind (list_head_t *unwinds)
+{
+ struct stat buf = {0,};
+ wb_request_t *request = NULL, *dummy = NULL;
+ call_frame_t *frame = NULL;
+ wb_local_t *local = NULL;
- return 0;
+ list_for_each_entry_safe (request, dummy, unwinds, unwinds)
+ {
+ frame = request->stub->frame;
+ local = frame->local;
-noqueue:
- STACK_WIND (frame, default_fsync_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fsync, fd, datasync, xdata);
- return 0;
-}
+ STACK_UNWIND (frame, local->op_ret, local->op_errno, &buf,
+ &buf);
+ wb_request_unref (request);
+ }
-int
-wb_stat_helper (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
-{
- STACK_WIND (frame, default_stat_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->stat, loc, xdata);
return 0;
}
-int
-wb_stat (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
+int32_t
+wb_resume_other_requests (call_frame_t *frame, wb_file_t *file,
+ list_head_t *other_requests)
{
- wb_inode_t *wb_inode = NULL;
- call_stub_t *stub = NULL;
+ int32_t ret = 0;
+ wb_request_t *request = NULL, *dummy = NULL;
+ int32_t fops_removed = 0;
+ char wind = 0;
+ call_stub_t *stub = NULL;
+ if (list_empty (other_requests)) {
+ goto out;
+ }
- wb_inode = wb_inode_ctx_get (this, loc->inode);
- if (!wb_inode)
- goto noqueue;
-
- stub = fop_stat_stub (frame, wb_stat_helper, loc, xdata);
- if (!stub)
- goto unwind;
-
- if (!wb_enqueue (wb_inode, stub))
- goto unwind;
+ list_for_each_entry_safe (request, dummy, other_requests,
+ other_requests) {
+ wind = request->stub->wind;
+ stub = request->stub;
+
+ LOCK (&file->lock);
+ {
+ request->stub = NULL;
+ }
+ UNLOCK (&file->lock);
+
+ if (!wind) {
+ wb_request_unref (request);
+ fops_removed++;
+ }
+
+ call_resume (stub);
+ }
- wb_process_queue (wb_inode);
+ if (fops_removed > 0) {
+ ret = wb_process_queue (frame, file, 0);
+ }
+
+out:
+ return ret;
+}
- return 0;
-unwind:
- STACK_UNWIND_STRICT (stat, frame, -1, ENOMEM, NULL, NULL);
+int32_t
+wb_do_ops (call_frame_t *frame, wb_file_t *file, list_head_t *winds,
+ list_head_t *unwinds, list_head_t *other_requests)
+{
+ int32_t ret = -1;
- if (stub)
- call_stub_destroy (stub);
- return 0;
+ ret = wb_stack_unwind (unwinds);
+ if (ret == -1) {
+ goto out;
+ }
-noqueue:
- STACK_WIND (frame, default_stat_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->stat, loc, xdata);
- return 0;
-}
+ ret = wb_sync (frame, file, winds);
+ if (ret == -1) {
+ goto out;
+ }
+ ret = wb_resume_other_requests (frame, file, other_requests);
-int
-wb_fstat_helper (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
-{
- STACK_WIND (frame, default_fstat_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fstat, fd, xdata);
- return 0;
+out:
+ return ret;
}
-int
-wb_fstat (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
+inline int
+__wb_copy_into_holder (wb_request_t *holder, wb_request_t *request)
{
- wb_inode_t *wb_inode = NULL;
- call_stub_t *stub = NULL;
-
+ char *ptr = NULL;
+ struct iobuf *iobuf = NULL;
+ struct iobref *iobref = NULL;
+ int ret = -1;
- wb_inode = wb_inode_ctx_get (this, fd->inode);
- if (!wb_inode)
- goto noqueue;
+ if (holder->flags.write_request.virgin) {
+ iobuf = iobuf_get (request->file->this->ctx->iobuf_pool);
+ if (iobuf == NULL) {
+ gf_log (request->file->this->name, GF_LOG_ERROR,
+ "out of memory");
+ goto out;
+ }
- stub = fop_fstat_stub (frame, wb_fstat_helper, fd, xdata);
- if (!stub)
- goto unwind;
+ iobref = iobref_new ();
+ if (iobref == NULL) {
+ iobuf_unref (iobuf);
+ gf_log (request->file->this->name, GF_LOG_ERROR,
+ "out of memory");
+ goto out;
+ }
+
+ ret = iobref_add (iobref, iobuf);
+ if (ret != 0) {
+ iobuf_unref (iobuf);
+ iobref_unref (iobref);
+ gf_log (request->file->this->name, GF_LOG_DEBUG,
+ "cannot add iobuf (%p) into iobref (%p)",
+ iobuf, iobref);
+ goto out;
+ }
+
+ iov_unload (iobuf->ptr, holder->stub->args.writev.vector,
+ holder->stub->args.writev.count);
+ holder->stub->args.writev.vector[0].iov_base = iobuf->ptr;
+
+ iobref_unref (holder->stub->args.writev.iobref);
+ holder->stub->args.writev.iobref = iobref;
+
+ iobuf_unref (iobuf);
- if (!wb_enqueue (wb_inode, stub))
- goto unwind;
+ holder->flags.write_request.virgin = 0;
+ }
- wb_process_queue (wb_inode);
+ ptr = holder->stub->args.writev.vector[0].iov_base + holder->write_size;
- return 0;
+ iov_unload (ptr,
+ request->stub->args.writev.vector,
+ request->stub->args.writev.count);
-unwind:
- STACK_UNWIND_STRICT (fstat, frame, -1, ENOMEM, NULL, NULL);
+ holder->stub->args.writev.vector[0].iov_len += request->write_size;
+ holder->write_size += request->write_size;
- if (stub)
- call_stub_destroy (stub);
- return 0;
+ request->flags.write_request.stack_wound = 1;
+ list_move_tail (&request->list, &request->file->passive_requests);
-noqueue:
- STACK_WIND (frame, default_fstat_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fstat, fd, xdata);
- return 0;
+ ret = 0;
+out:
+ return ret;
}
-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)
+/* this procedure assumes that write requests have only one vector to write */
+void
+__wb_collapse_write_bufs (list_head_t *requests, size_t page_size)
{
- GF_ASSERT (frame->local);
-
- if (op_ret == 0)
- wb_set_inode_size (frame->local, postbuf);
-
- frame->local = NULL;
+ off_t offset_expected = 0;
+ size_t space_left = 0;
+ wb_request_t *request = NULL, *tmp = NULL, *holder = NULL;
+ int ret = 0;
- STACK_UNWIND_STRICT (truncate, frame, op_ret, op_errno, prebuf,
- postbuf, xdata);
- return 0;
-}
+ list_for_each_entry_safe (request, tmp, requests, list) {
+ if ((request->stub == NULL)
+ || (request->stub->fop != GF_FOP_WRITE)
+ || (request->flags.write_request.stack_wound)) {
+ holder = NULL;
+ continue;
+ }
+ if (request->flags.write_request.write_behind) {
+ if (holder == NULL) {
+ holder = request;
+ continue;
+ }
+
+ offset_expected = holder->stub->args.writev.off
+ + holder->write_size;
+
+ if (request->stub->args.writev.off != offset_expected) {
+ holder = request;
+ continue;
+ }
+
+ space_left = page_size - holder->write_size;
+
+ if (space_left >= request->write_size) {
+ ret = __wb_copy_into_holder (holder, request);
+ if (ret != 0) {
+ break;
+ }
+
+ __wb_request_unref (request);
+ } else {
+ holder = request;
+ }
+ } else {
+ break;
+ }
+ }
-int
-wb_truncate_helper (call_frame_t *frame, xlator_t *this, loc_t *loc,
- off_t offset, dict_t *xdata)
-{
- STACK_WIND (frame, wb_truncate_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->truncate, loc, offset, xdata);
- return 0;
+ return;
}
-int
-wb_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset,
- dict_t *xdata)
+int32_t
+wb_process_queue (call_frame_t *frame, wb_file_t *file, char flush_all)
{
- wb_inode_t *wb_inode = NULL;
- call_stub_t *stub = NULL;
-
- wb_inode = wb_inode_create (this, loc->inode);
- if (!wb_inode)
- goto unwind;
+ list_head_t winds, unwinds, other_requests;
+ size_t size = 0;
+ wb_conf_t *conf = NULL;
+ uint32_t count = 0;
+ int32_t ret = -1;
- frame->local = wb_inode;
+ INIT_LIST_HEAD (&winds);
+ INIT_LIST_HEAD (&unwinds);
+ INIT_LIST_HEAD (&other_requests);
+
+ if (file == NULL) {
+ errno = EINVAL;
+ goto out;
+ }
- stub = fop_truncate_stub (frame, wb_truncate_helper, loc,
- offset, xdata);
- if (!stub)
- goto unwind;
+ conf = file->this->private;
+ size = conf->aggregate_size;
+ LOCK (&file->lock);
+ {
+ /*
+ * make sure requests are marked for unwinding and adjacent
+ * 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.
+ */
+ __wb_mark_unwinds (&file->request, &unwinds);
- if (!wb_enqueue (wb_inode, stub))
- goto unwind;
+ __wb_collapse_write_bufs (&file->request,
+ file->this->ctx->page_size);
- wb_process_queue (wb_inode);
+ count = __wb_get_other_requests (&file->request,
+ &other_requests);
- return 0;
+ if (count == 0) {
+ __wb_mark_winds (&file->request, &winds, size,
+ flush_all,
+ conf->enable_trickling_writes);
+ }
-unwind:
- STACK_UNWIND_STRICT (truncate, frame, -1, ENOMEM, NULL, NULL, NULL);
+ }
+ UNLOCK (&file->lock);
- if (stub)
- call_stub_destroy (stub);
+ ret = wb_do_ops (frame, file, &winds, &unwinds, &other_requests);
- return 0;
+out:
+ return ret;
}
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)
+wb_writev_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct stat *prebuf,
+ struct stat *postbuf)
{
- GF_ASSERT (frame->local);
-
- if (op_ret == 0)
- wb_set_inode_size (frame->local, postbuf);
-
- frame->local = NULL;
-
- STACK_UNWIND_STRICT (ftruncate, frame, op_ret, op_errno, prebuf,
- postbuf, xdata);
+ STACK_UNWIND_STRICT (writev, frame, op_ret, op_errno, prebuf, postbuf);
return 0;
}
-int
-wb_ftruncate_helper (call_frame_t *frame, xlator_t *this, fd_t *fd,
- off_t offset, dict_t *xdata)
-{
- STACK_WIND (frame, wb_ftruncate_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->ftruncate, fd, offset, xdata);
- 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, struct iobref *iobref)
+{
+ wb_file_t *file = NULL;
+ char wb_disabled = 0;
+ call_frame_t *process_frame = NULL;
+ size_t size = 0;
+ uint64_t tmp_file = 0;
+ call_stub_t *stub = NULL;
+ wb_local_t *local = NULL;
+ wb_request_t *request = NULL;
+ int32_t ret = -1;
+ int32_t op_ret = -1, op_errno = EINVAL;
+
+ if (vector != NULL)
+ size = iov_length (vector, count);
+
+ if ((!S_ISDIR (fd->inode->st_mode))
+ && fd_ctx_get (fd, this, &tmp_file)) {
+ gf_log (this->name, GF_LOG_DEBUG, "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 ((!S_ISDIR (fd->inode->st_mode)) && (file == NULL)) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "wb_file not found for fd %p", fd);
+ op_errno = EBADFD;
+ goto unwind;
+ }
+ if (file != NULL) {
+ LOCK (&file->lock);
+ {
+ op_ret = file->op_ret;
+ op_errno = file->op_errno;
+
+ file->op_ret = 0;
+
+ if ((op_ret == 0)
+ && (file->disabled || file->disable_till)) {
+ if (size > file->disable_till) {
+ file->disable_till = 0;
+ } else {
+ file->disable_till -= size;
+ }
+ wb_disabled = 1;
+ }
+ }
+ UNLOCK (&file->lock);
+ } else {
+ wb_disabled = 1;
+ }
-int
-wb_ftruncate (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
- dict_t *xdata)
-{
- wb_inode_t *wb_inode = NULL;
- call_stub_t *stub = NULL;
- int32_t op_errno = 0;
+ if (op_ret == -1) {
+ STACK_UNWIND_STRICT (writev, frame, op_ret, op_errno,
+ 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, iobref);
+ return 0;
+ }
- wb_inode = wb_inode_create (this, fd->inode);
- if (!wb_inode) {
+ process_frame = copy_frame (frame);
+ if (process_frame == NULL) {
op_errno = ENOMEM;
- goto unwind;
+ goto unwind;
}
- if (wb_fd_err (fd, this, &op_errno))
- goto unwind;
+ local = CALLOC (1, sizeof (*local));
+ if (local == NULL) {
+ op_errno = ENOMEM;
+ goto unwind;
+ return 0;
+ }
- frame->local = wb_inode;
+ frame->local = local;
+ local->file = file;
- stub = fop_ftruncate_stub (frame, wb_ftruncate_helper, fd,
- offset, xdata);
- if (!stub) {
+ stub = fop_writev_stub (frame, NULL, fd, vector, count, offset,
+ iobref);
+ if (stub == NULL) {
op_errno = ENOMEM;
- goto unwind;
+ goto unwind;
}
- if (!wb_enqueue (wb_inode, stub)) {
+ request = wb_enqueue (file, stub);
+ if (request == NULL) {
+ op_errno = ENOMEM;
+ goto unwind;
+ }
+
+ ret = wb_process_queue (process_frame, file, 0);
+ if ((ret == -1) && (errno == ENOMEM)) {
op_errno = ENOMEM;
- goto unwind;
+ goto unwind;
}
- wb_process_queue (wb_inode);
+ STACK_DESTROY (process_frame->root);
return 0;
unwind:
- frame->local = NULL;
+ STACK_UNWIND_STRICT (writev, frame, -1, op_errno, NULL, NULL);
- STACK_UNWIND_STRICT (ftruncate, frame, -1, op_errno, NULL, NULL, NULL);
+ if (process_frame) {
+ STACK_DESTROY (process_frame->root);
+ }
- if (stub)
+ if (stub) {
call_stub_destroy (stub);
- return 0;
-}
-
+ }
-int
-wb_setattr_helper (call_frame_t *frame, xlator_t *this, loc_t *loc,
- struct iatt *stbuf, int32_t valid, dict_t *xdata)
-{
- STACK_WIND (frame, default_setattr_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->setattr, loc, stbuf, valid, xdata);
return 0;
}
-int
-wb_setattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
- struct iatt *stbuf, int32_t valid, dict_t *xdata)
-{
- wb_inode_t *wb_inode = NULL;
- call_stub_t *stub = NULL;
-
- wb_inode = wb_inode_ctx_get (this, loc->inode);
- if (!wb_inode)
- goto noqueue;
-
- stub = fop_setattr_stub (frame, wb_setattr_helper, loc, stbuf,
- valid, xdata);
- if (!stub)
- goto unwind;
-
- if (!wb_enqueue (wb_inode, stub))
- goto unwind;
-
- wb_process_queue (wb_inode);
-
- return 0;
-unwind:
- STACK_UNWIND_STRICT (setattr, frame, -1, ENOMEM, NULL, NULL, NULL);
+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 stat *stbuf, struct iobref *iobref)
+{
+ wb_local_t *local = NULL;
+ wb_file_t *file = NULL;
+ wb_request_t *request = NULL;
+ int32_t ret = 0;
+
+ local = frame->local;
+ file = local->file;
+ request = local->request;
+
+ if ((request != NULL) && (file != NULL)) {
+ wb_request_unref (request);
+
+ ret = wb_process_queue (frame, file, 0);
+ if ((ret == -1) && (errno == ENOMEM)) {
+ op_ret = -1;
+ op_errno = ENOMEM;
+ }
+ }
- if (stub)
- call_stub_destroy (stub);
- return 0;
+ STACK_UNWIND_STRICT (readv, frame, op_ret, op_errno, vector, count, stbuf, iobref);
-noqueue:
- STACK_WIND (frame, default_setattr_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->setattr, loc, stbuf, valid, xdata);
return 0;
}
-int
-wb_fsetattr_helper (call_frame_t *frame, xlator_t *this, fd_t *fd,
- struct iatt *stbuf, int32_t valid, dict_t *xdata)
-{
- STACK_WIND (frame, default_fsetattr_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fsetattr, fd, stbuf, valid, xdata);
+static int32_t
+wb_readv_helper (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
+ off_t offset)
+{
+ STACK_WIND (frame,
+ wb_readv_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->readv,
+ fd, size, offset);
+
return 0;
}
-int
-wb_fsetattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
- struct iatt *stbuf, int32_t valid, dict_t *xdata)
-{
- wb_inode_t *wb_inode = NULL;
- call_stub_t *stub = NULL;
+int32_t
+wb_readv (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
+ off_t offset)
+{
+ wb_file_t *file = NULL;
+ wb_local_t *local = NULL;
+ uint64_t tmp_file = 0;
+ call_stub_t *stub = NULL;
+ int32_t ret = -1;
+ wb_request_t *request = NULL;
+
+ if ((!S_ISDIR (fd->inode->st_mode))
+ && fd_ctx_get (fd, this, &tmp_file)) {
+ gf_log (this->name, GF_LOG_DEBUG, "write behind file pointer is"
+ " not stored in context of fd(%p), returning EBADFD",
+ fd);
+
+ STACK_UNWIND_STRICT (readv, frame, -1, EBADFD,
+ NULL, 0, NULL, NULL);
+ return 0;
+ }
- wb_inode = wb_inode_ctx_get (this, fd->inode);
- if (!wb_inode)
- goto noqueue;
+ file = (wb_file_t *)(long)tmp_file;
- stub = fop_fsetattr_stub (frame, wb_fsetattr_helper, fd, stbuf,
- valid, xdata);
- if (!stub)
- goto unwind;
+ local = CALLOC (1, sizeof (*local));
+ if (local == NULL) {
+ STACK_UNWIND_STRICT (readv, frame, -1, ENOMEM,
+ NULL, 0, NULL, NULL);
+ return 0;
+ }
- if (!wb_enqueue (wb_inode, stub))
- goto unwind;
+ local->file = file;
- wb_process_queue (wb_inode);
+ frame->local = local;
+ if (file) {
+ stub = fop_readv_stub (frame, wb_readv_helper, fd, size,
+ offset);
+ if (stub == NULL) {
+ STACK_UNWIND_STRICT (readv, frame, -1, ENOMEM,
+ NULL, 0, NULL, NULL);
+ return 0;
+ }
- return 0;
-unwind:
- STACK_UNWIND_STRICT (fsetattr, frame, -1, ENOMEM, NULL, NULL, NULL);
+ request = wb_enqueue (file, stub);
+ if (request == NULL) {
+ STACK_UNWIND_STRICT (readv, frame, -1, ENOMEM,
+ NULL, 0, NULL, NULL);
+ call_stub_destroy (stub);
+ return 0;
+ }
- if (stub)
- call_stub_destroy (stub);
- return 0;
+ ret = wb_process_queue (frame, file, 1);
+ if ((ret == -1) && (errno == ENOMEM)) {
+ STACK_UNWIND_STRICT (readv, frame, -1, ENOMEM,
+ NULL, 0, NULL, NULL);
+ call_stub_destroy (stub);
+ return 0;
+ }
+
+ } else {
+ STACK_WIND (frame,
+ wb_readv_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->readv,
+ fd, size, offset);
+ }
-noqueue:
- STACK_WIND (frame, default_fsetattr_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fsetattr, fd, stbuf, valid, xdata);
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)
+int
+wb_flush_bg_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno)
{
- wb_inode_t *wb_inode = NULL;
-
- wb_inode = wb_inode_create (this, fd->inode);
- if (!wb_inode)
- goto unwind;
+ wb_local_t *local = NULL;
+ wb_file_t *file = NULL;
+ wb_request_t *request = NULL;
+ fd_t *fd = NULL;
- if (((flags & O_RDWR) || (flags & O_WRONLY)) && (flags & O_TRUNC))
- wb_inode->size = 0;
+ local = frame->local;
+ if (local) {
+ file = local->file;
+ request = local->request;
+ }
- STACK_WIND_TAIL (frame, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->create, loc, flags, mode,
- umask, fd, xdata);
- return 0;
+ if (request)
+ wb_request_unref (request);
-unwind:
- STACK_UNWIND_STRICT (create, frame, -1, ENOMEM, NULL, NULL, NULL, NULL,
- NULL, NULL);
- return 0;
-}
+ if (file) {
+ wb_process_queue (frame, file, 0);
+ fd = file->fd;
+ }
+ if (fd)
+ fd_unref (fd);
-int32_t
-wb_open (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
- fd_t *fd, dict_t *xdata)
-{
- wb_inode_t *wb_inode = NULL;
+ STACK_DESTROY (frame->root);
+ return 0;
+}
- wb_inode = wb_inode_create (this, fd->inode);
- if (!wb_inode)
- goto unwind;
- if (((flags & O_RDWR) || (flags & O_WRONLY)) && (flags & O_TRUNC))
- wb_inode->size = 0;
+int
+wb_flush_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno)
+{
+ wb_local_t *local = NULL;
+ wb_request_t *request = NULL;
+ wb_file_t *file = NULL;
+ int fop_ret = 0;
+ int fop_errno = 0;
+
+ local = frame->local;
+ if (local) {
+ file = local->file;
+ request = local->request;
+ }
- STACK_WIND_TAIL (frame, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->open, loc, flags, fd, xdata);
- return 0;
+ fop_ret = op_ret;
+ fop_errno = op_errno;
-unwind:
- STACK_UNWIND_STRICT (open, frame, -1, ENOMEM, NULL, NULL);
- return 0;
-}
+ if (request)
+ wb_request_unref (request);
+ if (!file)
+ goto unwind;
-int32_t
-wb_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)
-{
- if (op_ret == 0) {
- wb_inode_t *wb_inode = wb_inode_ctx_get (this, inode);
- if (wb_inode)
- wb_set_inode_size (wb_inode, buf);
+ if (file->op_ret < 0) {
+ fop_ret = file->op_ret;
+ fop_errno = file->op_errno;
}
- STACK_UNWIND_STRICT (lookup, frame, op_ret, op_errno, inode, buf,
- xdata, postparent);
- return 0;
-}
+ wb_process_queue (frame, file, 0);
+unwind:
+ STACK_UNWIND_STRICT (flush, frame, fop_ret, fop_errno);
-int32_t
-wb_lookup (call_frame_t *frame, xlator_t *this, loc_t *loc,
- dict_t *xdata)
-{
- STACK_WIND (frame, wb_lookup_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->lookup, loc, xdata);
return 0;
}
int
-wb_forget (xlator_t *this, inode_t *inode)
+wb_flush_helper (call_frame_t *frame, xlator_t *this, fd_t *fd)
{
- uint64_t tmp = 0;
- wb_inode_t *wb_inode = NULL;
-
- inode_ctx_del (inode, this, &tmp);
-
- wb_inode = (wb_inode_t *)(long)tmp;
+ wb_conf_t *conf = NULL;
+ call_frame_t *flush_frame = NULL;
+ wb_file_t *file = NULL;
+ wb_local_t *local = NULL;
+ int op_ret = 0;
+ int op_errno = 0;
- if (!wb_inode)
- return 0;
+ conf = this->private;
+ local = frame->local;
+ if (local)
+ file = local->file;
- GF_ASSERT (list_empty (&wb_inode->todo));
- GF_ASSERT (list_empty (&wb_inode->liability));
- GF_ASSERT (list_empty (&wb_inode->temptation));
+ if (conf->flush_behind)
+ flush_frame = copy_frame (frame);
- GF_FREE (wb_inode);
+ if (flush_frame) {
+ flush_frame->local = frame->local;
+ frame->local = NULL;
- return 0;
-}
+ file->fd = fd_ref (fd);
+ STACK_WIND (flush_frame, wb_flush_bg_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->flush,
+ fd);
+ if (file) {
+ op_ret = file->op_ret;
+ op_errno = file->op_errno;
+ }
-int
-wb_release (xlator_t *this, fd_t *fd)
-{
- uint64_t tmp = 0;
+ STACK_UNWIND_STRICT (flush, frame, op_ret, op_errno);
- fd_ctx_del (fd, this, &tmp);
+ } else {
+ STACK_WIND (frame, wb_flush_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->flush,
+ fd);
+ }
return 0;
}
int
-wb_priv_dump (xlator_t *this)
+wb_flush (call_frame_t *frame, xlator_t *this, fd_t *fd)
{
- wb_conf_t *conf = NULL;
- char key_prefix[GF_DUMP_MAX_BUF_LEN] = {0, };
- int ret = -1;
-
- GF_VALIDATE_OR_GOTO ("write-behind", this, out);
+ wb_conf_t *conf = NULL;
+ wb_file_t *file = NULL;
+ wb_local_t *local = NULL;
+ uint64_t tmp_file = 0;
+ call_stub_t *stub = NULL;
+ call_frame_t *process_frame = NULL;
+ wb_request_t *request = NULL;
+ int32_t ret = 0;
conf = this->private;
- GF_VALIDATE_OR_GOTO (this->name, conf, out);
- gf_proc_dump_build_key (key_prefix, "xlator.performance.write-behind",
- "priv");
+ if ((!S_ISDIR (fd->inode->st_mode))
+ && fd_ctx_get (fd, this, &tmp_file)) {
+ gf_log (this->name, GF_LOG_DEBUG, "write behind file pointer is"
+ " not stored in context of fd(%p), returning EBADFD",
+ fd);
- gf_proc_dump_add_section (key_prefix);
+ STACK_UNWIND_STRICT (flush, frame, -1, EBADFD);
+ return 0;
+ }
- gf_proc_dump_write ("aggregate_size", "%d", conf->aggregate_size);
- gf_proc_dump_write ("window_size", "%d", conf->window_size);
- gf_proc_dump_write ("flush_behind", "%d", conf->flush_behind);
- gf_proc_dump_write ("trickling_writes", "%d", conf->trickling_writes);
+ file = (wb_file_t *)(long)tmp_file;
- ret = 0;
-out:
- return ret;
-}
+ if (!file)
+ goto nofile;
+ if (file->disabled)
+ goto nofile;
-void
-__wb_dump_requests (struct list_head *head, char *prefix)
-{
- char key[GF_DUMP_MAX_BUF_LEN] = {0, };
- char key_prefix[GF_DUMP_MAX_BUF_LEN] = {0, }, flag = 0;
- wb_request_t *req = NULL;
+ local = CALLOC (1, sizeof (*local));
+ if (local == NULL) {
+ STACK_UNWIND (frame, -1, ENOMEM, NULL);
+ return 0;
+ }
+
+ local->file = file;
+
+ frame->local = local;
+ stub = fop_flush_stub (frame, wb_flush_helper, fd);
+ if (stub == NULL) {
+ STACK_UNWIND_STRICT (flush, frame, -1, ENOMEM);
+ return 0;
+ }
- list_for_each_entry (req, head, all) {
- gf_proc_dump_build_key (key_prefix, key,
- (char *)gf_fop_list[req->fop]);
+ process_frame = copy_frame (frame);
+ if (process_frame == NULL) {
+ STACK_UNWIND_STRICT (flush, frame, -1, ENOMEM);
+ call_stub_destroy (stub);
+ return 0;
+ }
- gf_proc_dump_add_section(key_prefix);
+ request = wb_enqueue (file, stub);
+ if (request == NULL) {
+ STACK_UNWIND_STRICT (flush, frame, -1, ENOMEM);
+ call_stub_destroy (stub);
+ STACK_DESTROY (process_frame->root);
+ return 0;
+ }
- gf_proc_dump_write ("request-ptr", "%p", req);
+ ret = wb_process_queue (process_frame, file, 1);
+ if (ret == -1) {
+ STACK_UNWIND_STRICT (flush, frame, -1, ENOMEM);
+ call_stub_destroy (stub);
+ STACK_DESTROY (process_frame->root);
+ return 0;
+ }
- gf_proc_dump_write ("refcount", "%d", req->refcount);
+ STACK_DESTROY (process_frame->root);
- if (list_empty (&req->todo))
- gf_proc_dump_write ("wound", "yes");
- else
- gf_proc_dump_write ("wound", "no");
+ return 0;
- if (req->fop == GF_FOP_WRITE) {
- gf_proc_dump_write ("size", "%"GF_PRI_SIZET,
- req->write_size);
+nofile:
+ STACK_WIND (frame, wb_flush_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->flush,
+ fd);
+ return 0;
+}
- gf_proc_dump_write ("offset", "%"PRId64,
- req->stub->args.offset);
- flag = req->ordering.lied;
- gf_proc_dump_write ("lied", "%d", flag);
+static int32_t
+wb_fsync_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret,
+ int32_t op_errno, struct stat *prebuf, struct stat *postbuf)
+{
+ wb_local_t *local = NULL;
+ wb_file_t *file = NULL;
+ wb_request_t *request = NULL;
+ int32_t ret = -1;
- flag = req->ordering.append;
- gf_proc_dump_write ("append", "%d", flag);
+ local = frame->local;
+ file = local->file;
+ request = local->request;
- flag = req->ordering.fulfilled;
- gf_proc_dump_write ("fulfilled", "%d", flag);
+ if (file != NULL) {
+ LOCK (&file->lock);
+ {
+ if (file->op_ret == -1) {
+ op_ret = file->op_ret;
+ op_errno = file->op_errno;
- flag = req->ordering.go;
- gf_proc_dump_write ("go", "%d", flag);
+ file->op_ret = 0;
+ }
+ }
+ UNLOCK (&file->lock);
+
+ if (request) {
+ wb_request_unref (request);
+ ret = wb_process_queue (frame, file, 0);
+ if ((ret == -1) && (errno == ENOMEM)) {
+ op_ret = -1;
+ op_errno = ENOMEM;
+ }
}
+
}
+
+ STACK_UNWIND_STRICT (fsync, frame, op_ret, op_errno, prebuf, postbuf);
+
+ return 0;
}
-int
-wb_inode_dump (xlator_t *this, inode_t *inode)
+static int32_t
+wb_fsync_helper (call_frame_t *frame, xlator_t *this, fd_t *fd,
+ int32_t datasync)
{
- wb_inode_t *wb_inode = NULL;
- int32_t ret = -1;
- char *path = NULL;
- char key_prefix[GF_DUMP_MAX_BUF_LEN] = {0, };
- char uuid_str[64] = {0,};
-
- if ((inode == NULL) || (this == NULL)) {
- ret = 0;
- goto out;
- }
+ STACK_WIND (frame,
+ wb_fsync_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->fsync,
+ fd, datasync);
+ return 0;
+}
- wb_inode = wb_inode_ctx_get (this, inode);
- if (wb_inode == NULL) {
- ret = 0;
- goto out;
- }
- gf_proc_dump_build_key (key_prefix, "xlator.performance.write-behind",
- "wb_inode");
+int32_t
+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;
+ uint64_t tmp_file = 0;
+ call_stub_t *stub = NULL;
+ wb_request_t *request = NULL;
+ int32_t ret = -1;
+
+ if ((!S_ISDIR (fd->inode->st_mode))
+ && fd_ctx_get (fd, this, &tmp_file)) {
+ gf_log (this->name, GF_LOG_DEBUG, "write behind file pointer is"
+ " not stored in context of fd(%p), returning EBADFD",
+ fd);
+
+ STACK_UNWIND_STRICT (fsync, frame, -1, EBADFD, NULL, NULL);
+ return 0;
+ }
- gf_proc_dump_add_section (key_prefix);
+ file = (wb_file_t *)(long)tmp_file;
- __inode_path (inode, NULL, &path);
- if (path != NULL) {
- gf_proc_dump_write ("path", "%s", path);
- GF_FREE (path);
+ local = CALLOC (1, sizeof (*local));
+ if (local == NULL) {
+ STACK_UNWIND_STRICT (fsync, frame, -1, ENOMEM, NULL, NULL);
+ return 0;
}
- gf_proc_dump_write ("inode", "%p", inode);
-
- gf_proc_dump_write ("window_conf", "%"GF_PRI_SIZET,
- wb_inode->window_conf);
+ local->file = file;
- gf_proc_dump_write ("window_current", "%"GF_PRI_SIZET,
- wb_inode->window_current);
+ frame->local = local;
+ if (file) {
+ stub = fop_fsync_stub (frame, wb_fsync_helper, fd, datasync);
+ if (stub == NULL) {
+ STACK_UNWIND_STRICT (fsync, frame, -1, ENOMEM,
+ NULL, NULL);
+ return 0;
+ }
+
+ request = wb_enqueue (file, stub);
+ if (request == NULL) {
+ STACK_UNWIND_STRICT (fsync, frame, -1, ENOMEM,
+ NULL, NULL);
+ call_stub_destroy (stub);
+ return 0;
+ }
- ret = TRY_LOCK (&wb_inode->lock);
- if (!ret)
- {
- if (!list_empty (&wb_inode->all)) {
- __wb_dump_requests (&wb_inode->all, key_prefix);
+ ret = wb_process_queue (frame, file, 1);
+ if ((ret == -1) && (errno == ENOMEM)) {
+ STACK_UNWIND_STRICT (fsync, frame, -1, ENOMEM,
+ NULL, NULL);
+ call_stub_destroy (stub);
+ return 0;
}
- UNLOCK (&wb_inode->lock);
+
+ } else {
+ STACK_WIND (frame,
+ wb_fsync_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->fsync,
+ fd, datasync);
}
- if (ret && wb_inode)
- gf_proc_dump_write ("Unable to dump the inode information",
- "(Lock acquisition failed) %p (gfid: %s)",
- wb_inode,
- uuid_utoa_r (inode->gfid, uuid_str));
- ret = 0;
-out:
- return ret;
+ return 0;
}
-int
-mem_acct_init (xlator_t *this)
+int32_t
+wb_release (xlator_t *this, fd_t *fd)
{
- int ret = -1;
+ uint64_t file_ptr = 0;
+ wb_file_t *file = NULL;
- if (!this) {
- goto out;
- }
+ fd_ctx_get (fd, this, &file_ptr);
+ file = (wb_file_t *) (long) file_ptr;
- ret = xlator_mem_acct_init (this, gf_wb_mt_end + 1);
+ if (file != NULL) {
+ LOCK (&file->lock);
+ {
+ assert (list_empty (&file->request));
+ }
+ UNLOCK (&file->lock);
- if (ret != 0) {
- gf_log (this->name, GF_LOG_ERROR, "Memory accounting init"
- "failed");
+ wb_file_destroy (file);
}
-out:
- return ret;
+ return 0;
}
-
int
-reconfigure (xlator_t *this, dict_t *options)
+wb_priv_dump (xlator_t *this)
{
- wb_conf_t *conf = NULL;
- int ret = -1;
+ wb_conf_t *conf = NULL;
+ char key[GF_DUMP_MAX_BUF_LEN];
+ char key_prefix[GF_DUMP_MAX_BUF_LEN];
- conf = this->private;
+ if (!this)
+ return -1;
- GF_OPTION_RECONF ("cache-size", conf->window_size, options, size_uint64, out);
+ conf = this->private;
+ if (!conf) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "conf null in xlator");
+ return -1;
+ }
- GF_OPTION_RECONF ("flush-behind", conf->flush_behind, options, bool,
- out);
+ gf_proc_dump_build_key (key_prefix,
+ "xlator.performance.write-behind",
+ "priv");
- GF_OPTION_RECONF ("trickling-writes", conf->trickling_writes, options,
- bool, out);
+ gf_proc_dump_add_section (key_prefix);
- GF_OPTION_RECONF ("strict-O_DIRECT", conf->strict_O_DIRECT, options,
- bool, out);
+ 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);
- GF_OPTION_RECONF ("strict-write-ordering", conf->strict_write_ordering,
- options, bool, out);
- ret = 0;
-out:
- return ret;
+ return 0;
}
-
-int32_t
+int32_t
init (xlator_t *this)
{
- wb_conf_t *conf = NULL;
- int32_t ret = -1;
+ dict_t *options = NULL;
+ wb_conf_t *conf = NULL;
+ char *str = NULL;
+ int32_t ret = -1;
if ((this->children == NULL)
|| this->children->next) {
gf_log (this->name, GF_LOG_ERROR,
"FATAL: write-behind (%s) not configured with exactly "
- "one child", this->name);
- goto out;
+ "one child",
+ this->name);
+ return -1;
}
if (this->parents == NULL) {
gf_log (this->name, GF_LOG_WARNING,
- "dangling volume. check volfilex");
+ "dangling volume. check volfile");
}
+
+ options = this->options;
- conf = GF_CALLOC (1, sizeof (*conf), gf_wb_mt_wb_conf_t);
+ conf = CALLOC (1, sizeof (*conf));
if (conf == NULL) {
- goto out;
+ gf_log (this->name, GF_LOG_ERROR,
+ "FATAL: Out of memory");
+ return -1;
+ }
+
+ 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");
+ return -1;
+ }
}
/* 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);
+ return -1;
+ }
+ }
+ gf_log (this->name, GF_LOG_DEBUG,
+ "disabling write-behind for first %"PRIu64" bytes",
+ conf->disable_till);
+
/* configure 'option window-size <size>' */
- GF_OPTION_INIT ("cache-size", conf->window_size, size_uint64, 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);
+ FREE (conf);
+ return -1;
+ }
+ }
if (!conf->window_size && conf->aggregate_size) {
gf_log (this->name, GF_LOG_WARNING,
@@ -2176,54 +2550,64 @@ init (xlator_t *this)
if (conf->window_size < conf->aggregate_size) {
gf_log (this->name, GF_LOG_ERROR,
"aggregate-size(%"PRIu64") cannot be more than "
- "window-size(%"PRIu64")", conf->aggregate_size,
- conf->window_size);
- goto out;
+ "window-size"
+ "(%"PRIu64")", conf->window_size, conf->aggregate_size);
+ FREE (conf);
+ return -1;
}
/* configure 'option flush-behind <on/off>' */
- GF_OPTION_INIT ("flush-behind", conf->flush_behind, bool, out);
-
- GF_OPTION_INIT ("trickling-writes", conf->trickling_writes, 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");
+ return -1;
+ }
- GF_OPTION_INIT ("strict-O_DIRECT", conf->strict_O_DIRECT, bool, out);
+ if (conf->flush_behind) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "enabling flush-behind");
+ }
+ }
- GF_OPTION_INIT ("strict-write-ordering", conf->strict_write_ordering,
- bool, 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");
+ return -1;
+ }
+ }
this->private = conf;
- ret = 0;
-
-out:
- if (ret) {
- GF_FREE (conf);
- }
- return ret;
+ return 0;
}
void
fini (xlator_t *this)
{
- wb_conf_t *conf = NULL;
-
- GF_VALIDATE_OR_GOTO ("write-behind", this, out);
-
- conf = this->private;
- if (!conf) {
- goto out;
- }
-
- this->private = NULL;
- GF_FREE (conf);
+ wb_conf_t *conf = this->private;
-out:
+ FREE (conf);
return;
}
struct xlator_fops fops = {
.writev = wb_writev,
+ .open = wb_open,
+ .create = wb_create,
.readv = wb_readv,
.flush = wb_flush,
.fsync = wb_fsync,
@@ -2232,55 +2616,38 @@ struct xlator_fops fops = {
.truncate = wb_truncate,
.ftruncate = wb_ftruncate,
.setattr = wb_setattr,
- .fsetattr = wb_fsetattr,
};
+struct xlator_mops mops = {
+};
struct xlator_cbks cbks = {
- .forget = wb_forget,
.release = wb_release
};
-
struct xlator_dumpops dumpops = {
.priv = wb_priv_dump,
- .inodectx = wb_inode_dump,
};
-
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 FOP is sent to backend filesystem. "
+ { .key = {"flush-behind"},
+ .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 write-behind buffer for a single file "
- "(inode)."
+ { .key = {"cache-size", "window-size"},
+ .type = GF_OPTION_TYPE_SIZET,
+ .min = 512 * GF_UNIT_KB,
+ .max = 1 * GF_UNIT_GB
},
- { .key = {"trickling-writes"},
- .type = GF_OPTION_TYPE_BOOL,
- .default_value = "on",
+ { .key = {"disable-for-first-nbytes"},
+ .type = GF_OPTION_TYPE_SIZET,
+ .min = 1,
+ .max = 1 * GF_UNIT_MB,
},
- { .key = {"strict-O_DIRECT"},
+ { .key = {"enable-O_SYNC"},
.type = GF_OPTION_TYPE_BOOL,
- .default_value = "off",
- .description = "This option when set to off, ignores the "
- "O_DIRECT flag."
- },
- { .key = {"strict-write-ordering"},
+ },
+ { .key = {"enable-trickling-writes"},
.type = GF_OPTION_TYPE_BOOL,
- .default_value = "off",
- .description = "Do not let later writes overtake earlier writes even "
- "if they do not overlap",
},
{ .key = {NULL} },
};
diff --git a/xlators/playground/Makefile.am b/xlators/playground/Makefile.am
deleted file mode 100644
index e7de6b31aff..00000000000
--- a/xlators/playground/Makefile.am
+++ /dev/null
@@ -1,2 +0,0 @@
-SUBDIRS = template
-CLEANFILES =
diff --git a/xlators/playground/template/Makefile.am b/xlators/playground/template/Makefile.am
deleted file mode 100644
index f2689244371..00000000000
--- a/xlators/playground/template/Makefile.am
+++ /dev/null
@@ -1,2 +0,0 @@
-SUBDIRS = src
-
diff --git a/xlators/playground/template/src/Makefile.am b/xlators/playground/template/src/Makefile.am
deleted file mode 100644
index 21f1c5f6b75..00000000000
--- a/xlators/playground/template/src/Makefile.am
+++ /dev/null
@@ -1,16 +0,0 @@
-xlator_LTLIBRARIES = template.la
-xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/testing/features
-
-template_la_LDFLAGS = -module -avoid-version
-
-template_la_SOURCES = template.c
-template_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la
-
-noinst_HEADERS = template.h
-
-AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src
-
-AM_CFLAGS = -Wall $(GF_CFLAGS)
-
-CLEANFILES =
-
diff --git a/xlators/playground/template/src/template.c b/xlators/playground/template/src/template.c
deleted file mode 100644
index 37a7794a07e..00000000000
--- a/xlators/playground/template/src/template.c
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- Copyright (c) 2006-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 "template.h"
-
-int32_t
-init (xlator_t *this)
-{
-
- if (!this->children || this->children->next) {
- gf_log (this->name, GF_LOG_ERROR,
- "not configured with exactly one child. exiting");
- 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 = {
-};
-
-struct xlator_cbks cbks = {
-};
-
-struct volume_options options[] = {
- { .key = {NULL} },
-};
diff --git a/xlators/playground/template/src/template.h b/xlators/playground/template/src/template.h
deleted file mode 100644
index d6aced50107..00000000000
--- a/xlators/playground/template/src/template.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- Copyright (c) 2013 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 __TEMPLATE_H__
-#define __TEMPLATE_H__
-
-#ifndef _CONFIG_H
-#define _CONFIG_H
-#include "config.h"
-#endif
-
-#include "glusterfs.h"
-#include "logging.h"
-#include "dict.h"
-#include "xlator.h"
-#include "defaults.h"
-
-#endif /* __TEMPLATE_H__ */
diff --git a/xlators/protocol/Makefile.am b/xlators/protocol/Makefile.am
index 91b03b1416a..745e277c2a6 100644
--- a/xlators/protocol/Makefile.am
+++ b/xlators/protocol/Makefile.am
@@ -1 +1,3 @@
-SUBDIRS = auth client server
+SUBDIRS = client server
+
+CLEANFILES =
diff --git a/xlators/protocol/auth/Makefile.am b/xlators/protocol/auth/Makefile.am
deleted file mode 100644
index e9e0ba97e14..00000000000
--- a/xlators/protocol/auth/Makefile.am
+++ /dev/null
@@ -1 +0,0 @@
-SUBDIRS = addr login
diff --git a/xlators/protocol/auth/addr/Makefile.am b/xlators/protocol/auth/addr/Makefile.am
deleted file mode 100644
index af437a64d6d..00000000000
--- a/xlators/protocol/auth/addr/Makefile.am
+++ /dev/null
@@ -1 +0,0 @@
-SUBDIRS = src
diff --git a/xlators/protocol/auth/addr/src/Makefile.am b/xlators/protocol/auth/addr/src/Makefile.am
deleted file mode 100644
index 426e7c2fb36..00000000000
--- a/xlators/protocol/auth/addr/src/Makefile.am
+++ /dev/null
@@ -1,14 +0,0 @@
-auth_LTLIBRARIES = addr.la
-authdir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/auth
-
-addr_la_LDFLAGS = -module -avoid-version
-
-addr_la_SOURCES = addr.c
-addr_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la
-
-AM_CPPFLAGS = $(GF_CPPFLAGS) \
- -I$(top_srcdir)/libglusterfs/src \
- -I$(top_srcdir)/xlators/protocol/server/src \
- -I$(top_srcdir)/rpc/rpc-lib/src/
-
-AM_CFLAGS = -Wall $(GF_CFLAGS)
diff --git a/xlators/protocol/auth/addr/src/addr.c b/xlators/protocol/auth/addr/src/addr.c
deleted file mode 100644
index 181d091bd49..00000000000
--- a/xlators/protocol/auth/addr/src/addr.c
+++ /dev/null
@@ -1,230 +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 <fnmatch.h>
-#include <sys/socket.h>
-#include <netdb.h>
-#include "authenticate.h"
-#include "dict.h"
-#include "rpc-transport.h"
-
-#define ADDR_DELIMITER " ,"
-#define PRIVILEGED_PORT_CEILING 1024
-
-#ifndef AF_INET_SDP
-#define AF_INET_SDP 27
-#endif
-
-auth_result_t
-gf_auth (dict_t *input_params, dict_t *config_params)
-{
- auth_result_t result = AUTH_DONT_CARE;
- int ret = 0;
- char *name = NULL;
- char *searchstr = NULL;
- peer_info_t *peer_info = NULL;
- data_t *peer_info_data = NULL;
- data_t *allow_addr = NULL;
- data_t *reject_addr = NULL;
- char *addr_str = NULL;
- char *tmp = NULL;
- char *addr_cpy = NULL;
- char *service = NULL;
- uint16_t peer_port = 0;
- char is_inet_sdp = 0;
- 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) {
- gf_log ("authenticate/addr", GF_LOG_DEBUG,
- "remote-subvolume not specified");
- goto out;
- }
-
- ret = gf_asprintf (&searchstr, "auth.addr.%s.allow", name);
- if (-1 == ret) {
- gf_log ("auth/addr", GF_LOG_DEBUG,
- "asprintf failed while setting search string");
- goto out;
- }
-
- allow_addr = dict_get (config_params, searchstr);
- GF_FREE (searchstr);
-
- ret = gf_asprintf (&searchstr, "auth.addr.%s.reject", name);
- if (-1 == ret) {
- gf_log ("auth/addr", GF_LOG_ERROR,
- "asprintf failed while setting search string");
- goto out;
- }
- reject_addr = dict_get (config_params, searchstr);
- GF_FREE (searchstr);
-
- if (!allow_addr) {
- /* TODO: backword compatibility */
- ret = gf_asprintf (&searchstr, "auth.ip.%s.allow", name);
- if (-1 == ret) {
- gf_log ("auth/addr", GF_LOG_ERROR,
- "asprintf failed while setting search string");
- goto out;
- }
- allow_addr = dict_get (config_params, searchstr);
- GF_FREE (searchstr);
- }
-
- if (!(allow_addr || reject_addr)) {
- gf_log ("auth/addr", GF_LOG_DEBUG,
- "none of the options auth.addr.%s.allow or "
- "auth.addr.%s.reject specified, returning auth_dont_care",
- name, name);
- goto out;
- }
-
- peer_info_data = dict_get (input_params, "peer-info");
- if (!peer_info_data) {
- gf_log ("auth/addr", GF_LOG_ERROR,
- "peer-info not present");
- goto out;
- }
-
- peer_info = data_to_ptr (peer_info_data);
-
- switch (((struct sockaddr *) &peer_info->sockaddr)->sa_family)
- {
- case AF_INET_SDP:
- is_inet_sdp = 1;
- ((struct sockaddr *) &peer_info->sockaddr)->sa_family = AF_INET;
-
- case AF_INET:
- case AF_INET6:
- {
- strcpy (peer_addr, peer_info->identifier);
- service = strrchr (peer_addr, ':');
- *service = '\0';
- service ++;
-
- if (is_inet_sdp) {
- ((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) {
- gf_log ("auth/addr", GF_LOG_ERROR,
- "client is bound to port %d which is not privileged",
- peer_port);
- goto out;
- }
- break;
-
- case AF_UNIX:
- strcpy (peer_addr, peer_info->identifier);
- break;
-
- default:
- gf_log ("authenticate/addr", GF_LOG_ERROR,
- "unknown address family %d",
- ((struct sockaddr *) &peer_info->sockaddr)->sa_family);
- goto out;
- }
- }
-
- if (reject_addr) {
- addr_cpy = gf_strdup (reject_addr->data);
- if (!addr_cpy)
- goto out;
-
- addr_str = strtok_r (addr_cpy, ADDR_DELIMITER, &tmp);
-
- while (addr_str) {
- gf_log (name, GF_LOG_DEBUG,
- "rejected = \"%s\", received addr = \"%s\"",
- addr_str, peer_addr);
- if (addr_str[0] == '!') {
- negate = 1;
- addr_str++;
- }
-
- match = fnmatch (addr_str, peer_addr, 0);
- if (negate ? match : !match) {
- result = AUTH_REJECT;
- goto out;
- }
- addr_str = strtok_r (NULL, ADDR_DELIMITER, &tmp);
- }
- GF_FREE (addr_cpy);
- addr_cpy = NULL;
- }
-
- if (allow_addr) {
- addr_cpy = gf_strdup (allow_addr->data);
- if (!addr_cpy)
- goto out;
-
- addr_str = strtok_r (addr_cpy, ADDR_DELIMITER, &tmp);
-
- while (addr_str) {
- gf_log (name, GF_LOG_DEBUG,
- "allowed = \"%s\", received addr = \"%s\"",
- addr_str, peer_addr);
- if (addr_str[0] == '!') {
- negate = 1;
- addr_str++;
- }
-
- match = fnmatch (addr_str, peer_addr, 0);
- if (negate ? match : !match) {
- result = AUTH_ACCEPT;
- goto out;
- }
- addr_str = strtok_r (NULL, ADDR_DELIMITER, &tmp);
- }
- }
-
-out:
- GF_FREE (addr_cpy);
-
- return result;
-}
-
-struct volume_options options[] = {
- { .key = {"auth.addr.*.allow"},
- .type = GF_OPTION_TYPE_INTERNET_ADDRESS_LIST
- },
- { .key = {"auth.addr.*.reject"},
- .type = GF_OPTION_TYPE_INTERNET_ADDRESS_LIST
- },
- /* Backword compatibility */
- { .key = {"auth.ip.*.allow"},
- .type = GF_OPTION_TYPE_INTERNET_ADDRESS_LIST
- },
- { .key = {NULL} }
-};
diff --git a/xlators/protocol/auth/login/Makefile.am b/xlators/protocol/auth/login/Makefile.am
deleted file mode 100644
index af437a64d6d..00000000000
--- a/xlators/protocol/auth/login/Makefile.am
+++ /dev/null
@@ -1 +0,0 @@
-SUBDIRS = src
diff --git a/xlators/protocol/auth/login/src/Makefile.am b/xlators/protocol/auth/login/src/Makefile.am
deleted file mode 100644
index d84db91c4e1..00000000000
--- a/xlators/protocol/auth/login/src/Makefile.am
+++ /dev/null
@@ -1,12 +0,0 @@
-auth_LTLIBRARIES = login.la
-authdir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/auth
-
-login_la_LDFLAGS = -module -avoid-version
-
-login_la_SOURCES = login.c
-login_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la
-
-AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \
- -I$(top_srcdir)/xlators/protocol/server/src
-
-AM_CFLAGS = -Wall $(GF_CFLAGS)
diff --git a/xlators/protocol/auth/login/src/login.c b/xlators/protocol/auth/login/src/login.c
deleted file mode 100644
index 56b93a9f9e9..00000000000
--- a/xlators/protocol/auth/login/src/login.c
+++ /dev/null
@@ -1,148 +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 <fnmatch.h>
-#include "authenticate.h"
-
-auth_result_t gf_auth (dict_t *input_params, dict_t *config_params)
-{
- auth_result_t result = AUTH_DONT_CARE;
- int ret = 0;
- data_t *allow_user = NULL;
- data_t *username_data = NULL;
- data_t *passwd_data = NULL;
- data_t *password_data = NULL;
- char *username = NULL;
- char *password = NULL;
- char *brick_name = NULL;
- char *searchstr = NULL;
- char *username_str = NULL;
- char *tmp = NULL;
- char *username_cpy = NULL;
- gf_boolean_t using_ssl = _gf_false;
-
- username_data = dict_get (input_params, "ssl-name");
- if (username_data) {
- gf_log ("auth/login", GF_LOG_INFO,
- "connecting user name: %s", username_data->data);
- using_ssl = _gf_true;
- result = AUTH_REJECT;
- }
- else {
- username_data = dict_get (input_params, "username");
- if (!username_data) {
- gf_log ("auth/login", GF_LOG_DEBUG,
- "username not found, returning DONT-CARE");
- goto out;
- }
- password_data = dict_get (input_params, "password");
- if (!password_data) {
- gf_log ("auth/login", GF_LOG_WARNING,
- "password not found, returning DONT-CARE");
- goto out;
- }
- password = data_to_str (password_data);
- }
- username = data_to_str (username_data);
-
- brick_name = data_to_str (dict_get (input_params, "remote-subvolume"));
- if (!brick_name) {
- gf_log ("auth/login", GF_LOG_ERROR,
- "remote-subvolume not specified");
- result = AUTH_REJECT;
- goto out;
- }
-
- ret = gf_asprintf (&searchstr, "auth.login.%s.%s", brick_name,
- using_ssl ? "ssl-allow" : "allow");
- if (-1 == ret) {
- gf_log ("auth/login", GF_LOG_WARNING,
- "asprintf failed while setting search string, "
- "returning DONT-CARE");
- goto out;
- }
-
- allow_user = dict_get (config_params, searchstr);
- GF_FREE (searchstr);
-
- if (allow_user) {
- gf_log ("auth/login", GF_LOG_INFO,
- "allowed user names: %s", allow_user->data);
- username_cpy = gf_strdup (allow_user->data);
- if (!username_cpy)
- goto out;
-
- username_str = strtok_r (username_cpy, " ,", &tmp);
-
- /*
- * We have to match a user's *authenticated* name to one in the
- * list. If we're using SSL, they're already authenticated.
- * Otherwise, they need a matching password to complete the
- * process.
- */
- while (username_str) {
- if (!fnmatch (username_str, username, 0)) {
- if (using_ssl) {
- result = AUTH_ACCEPT;
- break;
- }
- ret = gf_asprintf (&searchstr,
- "auth.login.%s.password",
- username);
- if (-1 == ret) {
- gf_log ("auth/login", GF_LOG_WARNING,
- "asprintf failed while setting search string");
- goto out;
- }
- passwd_data = dict_get (config_params, searchstr);
- GF_FREE (searchstr);
-
- if (!passwd_data) {
- gf_log ("auth/login", GF_LOG_ERROR,
- "wrong username/password combination");
- result = AUTH_REJECT;
- goto out;
- }
-
- result = !((strcmp (data_to_str (passwd_data),
- password)) ?
- AUTH_ACCEPT :
- AUTH_REJECT);
- if (result == AUTH_REJECT)
- gf_log ("auth/login", GF_LOG_ERROR,
- "wrong password for user %s",
- username);
-
- break;
- }
- username_str = strtok_r (NULL, " ,", &tmp);
- }
- }
-
-out:
- GF_FREE (username_cpy);
-
- return result;
-}
-
-struct volume_options options[] = {
- { .key = {"auth.login.*.allow"},
- .type = GF_OPTION_TYPE_ANY
- },
- { .key = {"auth.login.*.password"},
- .type = GF_OPTION_TYPE_ANY
- },
- { .key = {NULL} }
-};
diff --git a/xlators/protocol/client/Makefile.am b/xlators/protocol/client/Makefile.am
index af437a64d6d..d471a3f9243 100644
--- a/xlators/protocol/client/Makefile.am
+++ b/xlators/protocol/client/Makefile.am
@@ -1 +1,3 @@
SUBDIRS = src
+
+CLEANFILES =
diff --git a/xlators/protocol/client/src/Makefile.am b/xlators/protocol/client/src/Makefile.am
index cf89d42da30..fb720942cc6 100644
--- a/xlators/protocol/client/src/Makefile.am
+++ b/xlators/protocol/client/src/Makefile.am
@@ -2,19 +2,15 @@
xlator_LTLIBRARIES = client.la
xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/protocol
-client_la_LDFLAGS = -module -avoid-version
+client_la_LDFLAGS = -module -avoidversion
-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-protocol.c saved-frames.c
+client_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la
-client_la_SOURCES = client.c client-helpers.c client-rpc-fops.c \
- client-handshake.c client-callback.c client-lk.c
+noinst_HEADERS = client-protocol.h saved-frames.h
-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)
-AM_CPPFLAGS = $(GF_CPPFLAGS) \
- -I$(top_srcdir)/libglusterfs/src \
- -I$(top_srcdir)/rpc/xdr/src -I$(top_srcdir)/rpc/rpc-lib/src/
+CLEANFILES =
-AM_CFLAGS = -Wall $(GF_CFLAGS)
diff --git a/xlators/protocol/client/src/client-callback.c b/xlators/protocol/client/src/client-callback.c
deleted file mode 100644
index b2707cb395b..00000000000
--- a/xlators/protocol/client/src/client-callback.c
+++ /dev/null
@@ -1,56 +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 "rpc-clnt.h"
-
-int
-client_cbk_null (struct rpc_clnt *rpc, void *mydata, void *data)
-{
- gf_log (THIS->name, GF_LOG_WARNING,
- "this function should not be called");
- return 0;
-}
-
-int
-client_cbk_fetchspec (struct rpc_clnt *rpc, void *mydata, void *data)
-{
- gf_log (THIS->name, GF_LOG_WARNING,
- "this function should not be called");
- return 0;
-}
-
-int
-client_cbk_ino_flush (struct rpc_clnt *rpc, void *mydata, void *data)
-{
- gf_log (THIS->name, GF_LOG_WARNING,
- "this function should not be called");
- return 0;
-}
-
-rpcclnt_cb_actor_t gluster_cbk_actors[GF_CBK_MAXVALUE] = {
- [GF_CBK_NULL] = {"NULL", GF_CBK_NULL, client_cbk_null },
- [GF_CBK_FETCHSPEC] = {"FETCHSPEC", GF_CBK_FETCHSPEC, client_cbk_fetchspec },
- [GF_CBK_INO_FLUSH] = {"INO_FLUSH", GF_CBK_INO_FLUSH, client_cbk_ino_flush },
-};
-
-
-struct rpcclnt_cb_program gluster_cbk_prog = {
- .progname = "GlusterFS Callback",
- .prognum = GLUSTER_CBK_PROGRAM,
- .progver = GLUSTER_CBK_VERSION,
- .actors = gluster_cbk_actors,
- .numactors = GF_CBK_MAXVALUE,
-};
diff --git a/xlators/protocol/client/src/client-handshake.c b/xlators/protocol/client/src/client-handshake.c
deleted file mode 100644
index 42b7ac0745e..00000000000
--- a/xlators/protocol/client/src/client-handshake.c
+++ /dev/null
@@ -1,1703 +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 "fd-lk.h"
-#include "client.h"
-#include "xlator.h"
-#include "defaults.h"
-#include "glusterfs.h"
-#include "statedump.h"
-#include "compat-errno.h"
-
-#include "glusterfs3.h"
-#include "portmap-xdr.h"
-#include "rpc-common-xdr.h"
-
-#define CLIENT_REOPEN_MAX_ATTEMPTS 1024
-extern rpc_clnt_prog_t clnt3_3_fop_prog;
-extern rpc_clnt_prog_t clnt_pmap_prog;
-
-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;
-
-int
-client3_getspec_cbk (struct rpc_req *req, struct iovec *iov, int count,
- void *myframe)
-{
- gf_getspec_rsp rsp = {0,};
- call_frame_t *frame = NULL;
- int ret = 0;
-
- frame = myframe;
-
- if (!frame || !frame->this) {
- gf_log (THIS->name, GF_LOG_ERROR, "frame not found with the request, "
- "returning EINVAL");
- rsp.op_ret = -1;
- rsp.op_errno = EINVAL;
- goto out;
- }
- if (-1 == req->rpc_status) {
- gf_log (frame->this->name, GF_LOG_WARNING,
- "received RPC status error, returning ENOTCONN");
- rsp.op_ret = -1;
- rsp.op_errno = ENOTCONN;
- goto out;
- }
-
- ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_getspec_rsp);
- if (ret < 0) {
- gf_log (frame->this->name, GF_LOG_ERROR,
- "XDR decoding failed, returning EINVAL");
- rsp.op_ret = -1;
- rsp.op_errno = EINVAL;
- goto out;
- }
-
- if (-1 == rsp.op_ret) {
- gf_log (frame->this->name, GF_LOG_WARNING,
- "failed to get the 'volume file' from server");
- goto out;
- }
-
-out:
- CLIENT_STACK_UNWIND (getspec, frame, rsp.op_ret, rsp.op_errno,
- rsp.spec);
-
- /* Don't use 'GF_FREE', this is allocated by libc */
- free (rsp.spec);
-
- return 0;
-}
-
-int32_t client3_getspec (call_frame_t *frame, xlator_t *this, void *data)
-{
- clnt_conf_t *conf = NULL;
- clnt_args_t *args = NULL;
- gf_getspec_req req = {0,};
- int op_errno = ESTALE;
- int ret = 0;
-
- if (!frame || !this || !data)
- goto unwind;
-
- args = data;
- conf = this->private;
- req.flags = args->flags;
- req.key = (char *)args->name;
-
- 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);
-
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING,
- "failed to send the request");
- }
-
- return 0;
-unwind:
- CLIENT_STACK_UNWIND (getspec, frame, -1, op_errno, NULL);
- return 0;
-
-}
-
-int
-client_notify_parents_child_up (xlator_t *this)
-{
- clnt_conf_t *conf = NULL;
- int ret = 0;
-
- conf = this->private;
- ret = default_notify (this, GF_EVENT_CHILD_UP, NULL);
- if (ret)
- gf_log (this->name, GF_LOG_INFO,
- "notify of CHILD_UP failed");
-
- conf->last_sent_event = GF_EVENT_CHILD_UP;
- return 0;
-}
-
-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;
- }
- 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, };
- char *process_uuid = NULL;
-
- GF_VALIDATE_OR_GOTO ("client", this, err);
-
- conf = (clnt_conf_t *) this->private;
-
- req.lk_ver = client_get_lk_ver (conf);
- ret = dict_get_str (this->options, "process-uuid", &process_uuid);
- if (!process_uuid) {
- ret = -1;
- goto err;
- }
- req.uid = gf_strdup (process_uuid);
- if (!req.uid) {
- 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);
-
- fdctx->reopen_done (fdctx, this);
-
- 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);
- return 0;
- out:
- if (ret) {
- clnt_fd_lk_reacquire_failed (this, fdctx, conf);
- fdctx->reopen_done (fdctx, this);
- 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;
- }
- pthread_mutex_unlock (&conf->lock);
-
- fdctx->reopen_done (fdctx, this);
- }
-
- 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");
- fdctx->reopen_done (fdctx, this);
- } 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;
-}
-
-void
-client_default_reopen_done (clnt_fd_ctx_t *fdctx, xlator_t *this)
-{
- gf_log_callingfn (this->name, GF_LOG_WARNING,
- "This function should never be called");
-}
-
-void
-client_reopen_done (clnt_fd_ctx_t *fdctx, xlator_t *this)
-{
- clnt_conf_t *conf = NULL;
- gf_boolean_t destroy = _gf_false;
-
- conf = this->private;
-
- pthread_mutex_lock (&conf->lock);
- {
- fdctx->reopen_attempts = 0;
- if (!fdctx->released)
- list_add_tail (&fdctx->sfd_pos, &conf->saved_fds);
- else
- destroy = _gf_true;
- fdctx->reopen_done = client_default_reopen_done;
- }
- pthread_mutex_unlock (&conf->lock);
-
- if (destroy)
- client_fdctx_destroy (this, fdctx);
-}
-
-void
-client_child_up_reopen_done (clnt_fd_ctx_t *fdctx, xlator_t *this)
-{
- clnt_conf_t *conf = NULL;
- uint64_t fd_count = 0;
-
- conf = this->private;
-
- LOCK (&conf->rec_lock);
- {
- fd_count = --(conf->reopen_fd_count);
- }
- UNLOCK (&conf->rec_lock);
-
- client_reopen_done (fdctx, this);
- 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);
- }
-}
-
-int
-client3_3_reopen_cbk (struct rpc_req *req, struct iovec *iov, int count,
- void *myframe)
-{
- int32_t ret = -1;
- gfs3_open_rsp rsp = {0,};
- gf_boolean_t attempt_lock_recovery = _gf_false;
- clnt_local_t *local = NULL;
- clnt_conf_t *conf = NULL;
- clnt_fd_ctx_t *fdctx = NULL;
- call_frame_t *frame = NULL;
- xlator_t *this = NULL;
-
- frame = myframe;
- this = frame->this;
- conf = this->private;
- local = frame->local;
- fdctx = local->fdctx;
-
- if (-1 == req->rpc_status) {
- gf_log (frame->this->name, GF_LOG_WARNING,
- "received RPC status error, returning ENOTCONN");
- 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 (frame->this->name, GF_LOG_ERROR, "XDR decoding failed");
- rsp.op_ret = -1;
- rsp.op_errno = EINVAL;
- goto out;
- }
-
- if (rsp.op_ret < 0) {
- gf_log (frame->this->name, GF_LOG_WARNING,
- "reopen on %s failed (%s)",
- local->loc.path, strerror (rsp.op_errno));
- } else {
- gf_log (frame->this->name, GF_LOG_DEBUG,
- "reopen on %s succeeded (remote-fd = %"PRId64")",
- local->loc.path, rsp.fd);
- }
-
- if (rsp.op_ret == -1) {
- ret = -1;
- goto out;
- }
-
- pthread_mutex_lock (&conf->lock);
- {
- fdctx->remote_fd = rsp.fd;
- if (!fdctx->released) {
- if (conf->lk_heal &&
- !client_fd_lk_list_empty (fdctx->lk_ctx,
- _gf_false)) {
- attempt_lock_recovery = _gf_true;
- fdctx->lk_heal_state = GF_LK_HEAL_IN_PROGRESS;
- }
- }
- }
- pthread_mutex_unlock (&conf->lock);
-
- ret = 0;
-
- if (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);
- }
- }
-
-out:
- if (!attempt_lock_recovery)
- fdctx->reopen_done (fdctx, this);
-
- frame->local = NULL;
- STACK_DESTROY (frame->root);
-
- client_local_wipe (local);
-
- return 0;
-}
-
-int
-client3_3_reopendir_cbk (struct rpc_req *req, struct iovec *iov, int count,
- void *myframe)
-{
- int32_t ret = -1;
- gfs3_open_rsp rsp = {0,};
- clnt_local_t *local = NULL;
- clnt_conf_t *conf = NULL;
- clnt_fd_ctx_t *fdctx = NULL;
- call_frame_t *frame = NULL;
-
- frame = myframe;
- local = frame->local;
- fdctx = local->fdctx;
- conf = frame->this->private;
-
-
- if (-1 == req->rpc_status) {
- gf_log (frame->this->name, GF_LOG_WARNING,
- "received RPC status error, returning ENOTCONN");
- 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 (frame->this->name, GF_LOG_ERROR, "XDR decoding failed");
- rsp.op_ret = -1;
- rsp.op_errno = EINVAL;
- goto out;
- }
-
- if (rsp.op_ret < 0) {
- gf_log (frame->this->name, GF_LOG_WARNING,
- "reopendir on %s failed (%s)",
- local->loc.path, strerror (rsp.op_errno));
- } else {
- gf_log (frame->this->name, GF_LOG_INFO,
- "reopendir on %s succeeded (fd = %"PRId64")",
- local->loc.path, rsp.fd);
- }
-
- if (-1 == rsp.op_ret) {
- ret = -1;
- goto out;
- }
-
- pthread_mutex_lock (&conf->lock);
- {
- fdctx->remote_fd = rsp.fd;
- }
- pthread_mutex_unlock (&conf->lock);
-
-out:
- fdctx->reopen_done (fdctx, frame->this);
-
- frame->local = NULL;
- STACK_DESTROY (frame->root);
- client_local_wipe (local);
-
- return 0;
-}
-
-static int
-protocol_client_reopendir (clnt_fd_ctx_t *fdctx, xlator_t *this)
-{
- int ret = -1;
- gfs3_opendir_req req = {{0,},};
- clnt_local_t *local = NULL;
- call_frame_t *frame = NULL;
- clnt_conf_t *conf = NULL;
-
- conf = this->private;
-
- local = mem_get0 (this->local_pool);
- 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;
-
- frame = create_frame (this, this->ctx->pool);
- if (!frame) {
- ret = -1;
- goto out;
- }
-
- memcpy (req.gfid, fdctx->gfid, 16);
-
- gf_log (frame->this->name, GF_LOG_DEBUG,
- "attempting reopen on %s", local->loc.path);
-
- frame->local = local;
-
- 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");
- }
-
- return 0;
-
-out:
- if (frame) {
- frame->local = NULL;
- STACK_DESTROY (frame->root);
- }
-
- if (local)
- client_local_wipe (local);
-
- fdctx->reopen_done (fdctx, this);
-
- return 0;
-
-}
-
-static int
-protocol_client_reopenfile (clnt_fd_ctx_t *fdctx, xlator_t *this)
-{
- int ret = -1;
- gfs3_open_req req = {{0,},};
- clnt_local_t *local = NULL;
- call_frame_t *frame = NULL;
- clnt_conf_t *conf = NULL;
-
- conf = this->private;
-
- frame = create_frame (this, this->ctx->pool);
- if (!frame) {
- ret = -1;
- goto out;
- }
-
- local = mem_get0 (this->local_pool);
- 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;
-
- frame->local = local;
-
- memcpy (req.gfid, fdctx->gfid, 16);
- req.flags = gf_flags_from_flags (fdctx->flags);
- req.flags = req.flags & (~(O_TRUNC|O_CREAT|O_EXCL));
-
- gf_log (frame->this->name, GF_LOG_DEBUG,
- "attempting reopen on %s", local->loc.path);
-
- 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");
- }
-
- return 0;
-
-out:
- if (frame) {
- frame->local = NULL;
- STACK_DESTROY (frame->root);
- }
-
- if (local)
- client_local_wipe (local);
-
- fdctx->reopen_done (fdctx, this);
-
- return 0;
-
-}
-
-static void
-protocol_client_reopen (clnt_fd_ctx_t *fdctx, xlator_t *this)
-{
- if (fdctx->is_dir)
- protocol_client_reopendir (fdctx, this);
- else
- protocol_client_reopenfile (fdctx, this);
-}
-
-gf_boolean_t
-__is_fd_reopen_in_progress (clnt_fd_ctx_t *fdctx)
-{
- if (fdctx->reopen_done == client_default_reopen_done)
- return _gf_false;
- return _gf_true;
-}
-
-void
-client_attempt_reopen (fd_t *fd, xlator_t *this)
-{
- clnt_conf_t *conf = NULL;
- clnt_fd_ctx_t *fdctx = NULL;
- gf_boolean_t reopen = _gf_false;
-
- if (!fd || !this)
- goto out;
-
- conf = this->private;
- pthread_mutex_lock (&conf->lock);
- {
- fdctx = this_fd_get_ctx (fd, this);
- if (!fdctx)
- goto unlock;
- if (__is_fd_reopen_in_progress (fdctx))
- goto unlock;
- if (fdctx->remote_fd != -1)
- goto unlock;
-
- if (fdctx->reopen_attempts == CLIENT_REOPEN_MAX_ATTEMPTS) {
- reopen = _gf_true;
- fdctx->reopen_done = client_reopen_done;
- list_del_init (&fdctx->sfd_pos);
- } else {
- fdctx->reopen_attempts++;
- }
- }
-unlock:
- pthread_mutex_unlock (&conf->lock);
- if (reopen)
- protocol_client_reopen (fdctx, this);
-out:
- return;
-}
-
-int
-client_post_handshake (call_frame_t *frame, xlator_t *this)
-{
- clnt_conf_t *conf = NULL;
- clnt_fd_ctx_t *tmp = NULL;
- clnt_fd_ctx_t *fdctx = NULL;
- struct list_head reopen_head;
-
- int count = 0;
-
- if (!this || !this->private)
- goto out;
-
- conf = this->private;
- INIT_LIST_HEAD (&reopen_head);
-
- pthread_mutex_lock (&conf->lock);
- {
- list_for_each_entry_safe (fdctx, tmp, &conf->saved_fds,
- sfd_pos) {
- if (fdctx->remote_fd != -1)
- continue;
-
- fdctx->reopen_done = client_child_up_reopen_done;
- list_del_init (&fdctx->sfd_pos);
- list_add_tail (&fdctx->sfd_pos, &reopen_head);
- count++;
- }
- }
- pthread_mutex_unlock (&conf->lock);
-
- /* Delay notifying CHILD_UP to parents
- until all locks are recovered */
- if (count > 0) {
- gf_log (this->name, GF_LOG_INFO,
- "%d fds open - Delaying child_up until they are re-opened",
- count);
- client_save_number_fds (conf, count);
-
- list_for_each_entry_safe (fdctx, tmp, &reopen_head, sfd_pos) {
- list_del_init (&fdctx->sfd_pos);
-
- protocol_client_reopen (fdctx, this);
- }
- } else {
- gf_log (this->name, GF_LOG_DEBUG,
- "No fds to open - notifying all parents child up");
- client_set_lk_version (this);
- client_notify_parents_child_up (this);
- }
-out:
- return 0;
-}
-
-int
-client_setvolume_cbk (struct rpc_req *req, struct iovec *iov, int count, void *myframe)
-{
- call_frame_t *frame = NULL;
- clnt_conf_t *conf = NULL;
- xlator_t *this = NULL;
- dict_t *reply = NULL;
- char *process_uuid = NULL;
- char *remote_error = NULL;
- char *remote_subvol = NULL;
- 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;
-
- frame = myframe;
- this = frame->this;
- conf = this->private;
-
- if (-1 == req->rpc_status) {
- gf_log (frame->this->name, GF_LOG_WARNING,
- "received RPC status error");
- op_ret = -1;
- goto out;
- }
-
- ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_setvolume_rsp);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR, "XDR decoding failed");
- op_ret = -1;
- goto out;
- }
- op_ret = rsp.op_ret;
- op_errno = gf_error_to_errno (rsp.op_errno);
- if (-1 == rsp.op_ret) {
- gf_log (frame->this->name, GF_LOG_WARNING,
- "failed to set the volume (%s)",
- (op_errno)? strerror (op_errno) : "--");
- }
-
- reply = dict_new ();
- if (!reply)
- goto out;
-
- if (rsp.dict.dict_len) {
- ret = dict_unserialize (rsp.dict.dict_val,
- rsp.dict.dict_len, &reply);
- if (ret < 0) {
- gf_log (frame->this->name, GF_LOG_WARNING,
- "failed to unserialize buffer to dict");
- goto out;
- }
- }
-
- ret = dict_get_str (reply, "ERROR", &remote_error);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_WARNING,
- "failed to get ERROR string from reply dict");
- }
-
- ret = dict_get_str (reply, "process-uuid", &process_uuid);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_WARNING,
- "failed to get 'process-uuid' from reply dict");
- }
-
- if (op_ret < 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "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)
- gf_log (this->name, GF_LOG_INFO,
- "notify of VOLFILE_MODIFIED failed");
- conf->last_sent_event = GF_EVENT_VOLFILE_MODIFIED;
- }
- goto out;
- }
-
- ret = dict_get_str (this->options, "remote-subvolume",
- &remote_subvol);
- if (ret || !remote_subvol) {
- gf_log (this->name, GF_LOG_WARNING,
- "failed to find key 'remote-subvolume' in the options");
- 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 &&
- !strcmp (this->ctx->process_uuid, process_uuid)) {
- rpc_transport_t *peer_trans = NULL;
- uint64_t peertrans_int = 0;
-
- ret = dict_get_uint64 (reply, "transport-ptr",
- &peertrans_int);
- if (ret)
- goto out;
-
- gf_log (this->name, GF_LOG_WARNING,
- "attaching to the local volume '%s'",
- remote_subvol);
-
- peer_trans = (void *) (long) (peertrans_int);
-
- rpc_transport_setpeer (req->conn->trans, peer_trans);
- }
- */
-
- gf_log (this->name, GF_LOG_INFO,
- "Connected to %s, attached to remote volume '%s'.",
- conf->rpc->conn.name,
- remote_subvol);
-
- rpc_clnt_set_connected (&conf->rpc->conn);
-
- op_ret = 0;
- conf->connecting = 0;
- conf->connected = 1;
-
- 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");
- client_notify_parents_child_up (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,
- * tell the parents that i am all ok..
- */
- gf_log (this->name, GF_LOG_INFO, "sending CHILD_CONNECTING event");
- ret = default_notify (this, GF_EVENT_CHILD_CONNECTING, NULL);
- if (ret)
- gf_log (this->name, GF_LOG_INFO,
- "notify of CHILD_CONNECTING failed");
- conf->last_sent_event = GF_EVENT_CHILD_CONNECTING;
- conf->connecting= 1;
- ret = 0;
- }
-
- free (rsp.dict.dict_val);
-
- STACK_DESTROY (frame->root);
-
- if (reply)
- dict_unref (reply);
-
- return ret;
-}
-
-int
-client_setvolume (xlator_t *this, struct rpc_clnt *rpc)
-{
- int ret = 0;
- gf_setvolume_req req = {{0,},};
- call_frame_t *fr = NULL;
- char *process_uuid_xl = NULL;
- clnt_conf_t *conf = NULL;
- dict_t *options = NULL;
- char counter_str[32] = {0};
-
- options = this->options;
- conf = this->private;
-
- if (conf->fops) {
- ret = dict_set_int32 (options, "fops-version",
- conf->fops->prognum);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "failed to set version-fops(%d) in handshake msg",
- conf->fops->prognum);
- goto fail;
- }
- }
-
- if (conf->mgmt) {
- ret = dict_set_int32 (options, "mgmt-version", conf->mgmt->prognum);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "failed to set version-mgmt(%d) in handshake msg",
- conf->mgmt->prognum);
- goto fail;
- }
- }
-
- /* When lock-heal is enabled:
- * 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.
- * When lock-heal is disabled, connection-id should always be unique so
- * that server never gets to reuse the previous connection resources
- * so it cleans up the resources on every disconnect. Otherwise
- * it may lead to stale resources, i.e. leaked file desciptors,
- * inode/entry locks
- */
- if (!conf->lk_heal) {
- snprintf (counter_str, sizeof (counter_str),
- "-%"PRIu64, conf->setvol_count);
- conf->setvol_count++;
- }
- ret = gf_asprintf (&process_uuid_xl, "%s-%s-%d%s",
- this->ctx->process_uuid, this->name,
- this->graph->id, counter_str);
- 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,
- "failed to set process-uuid(%s) in handshake msg",
- process_uuid_xl);
- 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",
- this->ctx->cmd_args.volfile_id);
- if (ret)
- gf_log (this->name, GF_LOG_ERROR,
- "failed to set 'volfile-key'");
- }
- ret = dict_set_uint32 (options, "volfile-checksum",
- this->graph->volfile_checksum);
- if (ret)
- gf_log (this->name, GF_LOG_ERROR,
- "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));
- }
-
- ret = dict_serialized_length (options);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "failed to get serialized length of dict");
- ret = -1;
- goto fail;
- }
- req.dict.dict_len = ret;
- req.dict.dict_val = GF_CALLOC (1, req.dict.dict_len,
- gf_client_mt_clnt_req_buf_t);
- ret = dict_serialize (options, req.dict.dict_val);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "failed to serialize dictionary");
- goto fail;
- }
-
- fr = create_frame (this, this->ctx->pool);
- if (!fr)
- goto fail;
-
- 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);
-
-fail:
- GF_FREE (req.dict.dict_val);
-
- return ret;
-}
-
-int
-select_server_supported_programs (xlator_t *this, gf_prog_detail *prog)
-{
- gf_prog_detail *trav = NULL;
- clnt_conf_t *conf = NULL;
- int ret = -1;
-
- if (!this || !prog) {
- gf_log (THIS->name, GF_LOG_WARNING,
- "xlator not found OR RPC program not found");
- goto out;
- }
-
- conf = this->private;
- trav = 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;
- gf_log (this->name, GF_LOG_INFO,
- "Using Program %s, Num (%"PRId64"), "
- "Version (%"PRId64")",
- trav->progname, trav->prognum, trav->progver);
- ret = 0;
- }
- if (ret) {
- gf_log (this->name, GF_LOG_TRACE,
- "%s (%"PRId64") not supported", trav->progname,
- trav->progver);
- }
- trav = trav->next;
- }
-
-out:
- return ret;
-}
-
-
-int
-server_has_portmap (xlator_t *this, gf_prog_detail *prog)
-{
- gf_prog_detail *trav = NULL;
- int ret = -1;
-
- if (!this || !prog) {
- gf_log (THIS->name, GF_LOG_WARNING,
- "xlator not found OR RPC program not found");
- goto out;
- }
-
- trav = prog;
-
- while (trav) {
- if ((trav->prognum == GLUSTER_PMAP_PROGRAM) &&
- (trav->progver == GLUSTER_PMAP_VERSION)) {
- gf_log (this->name, GF_LOG_DEBUG,
- "detected portmapper on server");
- ret = 0;
- break;
- }
- trav = trav->next;
- }
-
-out:
- return ret;
-}
-
-
-int
-client_query_portmap_cbk (struct rpc_req *req, struct iovec *iov, int count, void *myframe)
-{
- struct pmap_port_by_brick_rsp rsp = {0,};
- call_frame_t *frame = NULL;
- clnt_conf_t *conf = NULL;
- int ret = -1;
- struct rpc_clnt_config config = {0, };
- xlator_t *this = NULL;
-
- frame = myframe;
- if (!frame || !frame->this || !frame->this->private) {
- gf_log (THIS->name, GF_LOG_WARNING,
- "frame not found with rpc request");
- goto out;
- }
- this = frame->this;
- conf = frame->this->private;
-
- if (-1 == req->rpc_status) {
- gf_log (this->name, GF_LOG_WARNING,
- "received RPC status error, try again later");
- goto out;
- }
-
- ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_pmap_port_by_brick_rsp);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR, "XDR decoding failed");
- goto out;
- }
-
- if (-1 == rsp.op_ret) {
- ret = -1;
- gf_log (this->name, ((!conf->portmap_err_logged) ?
- GF_LOG_ERROR : GF_LOG_DEBUG),
- "failed to get the port number for remote subvolume. "
- "Please run 'gluster volume status' on server to see "
- "if brick process is running.");
- conf->portmap_err_logged = 1;
- goto out;
- }
-
- conf->portmap_err_logged = 0;
- conf->disconnect_err_logged = 0;
- config.remote_port = rsp.port;
- rpc_clnt_reconfig (conf->rpc, &config);
-
- conf->skip_notify = 1;
- conf->quick_reconnect = 1;
-
-out:
- if (frame)
- STACK_DESTROY (frame->root);
-
- if (conf) {
- /* Need this to connect the same transport on different port */
- /* ie, glusterd to glusterfsd */
- rpc_transport_disconnect (conf->rpc->conn.trans);
- }
-
- return ret;
-}
-
-
-int
-client_query_portmap (xlator_t *this, struct rpc_clnt *rpc)
-{
- int ret = -1;
- pmap_port_by_brick_req req = {0,};
- call_frame_t *fr = NULL;
- 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;
-
- ret = dict_get_str (options, "remote-subvolume", &remote_subvol);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "remote-subvolume not set in volfile");
- goto fail;
- }
-
- req.brick = remote_subvol;
-
- if (!dict_get_str (options, "transport-type", &xprt)) {
- if (!strcmp (xprt, "rdma")) {
- snprintf (brick_name, sizeof(brick_name), "%s.rdma",
- remote_subvol);
- req.brick = brick_name;
- }
- }
-
- fr = create_frame (this, this->ctx->pool);
- if (!fr) {
- ret = -1;
- goto fail;
- }
-
- 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);
-
-fail:
- return ret;
-}
-
-
-int
-client_dump_version_cbk (struct rpc_req *req, struct iovec *iov, int count,
- void *myframe)
-{
- gf_dump_rsp rsp = {0,};
- gf_prog_detail *trav = NULL;
- gf_prog_detail *next = NULL;
- call_frame_t *frame = NULL;
- clnt_conf_t *conf = NULL;
- int ret = 0;
-
- frame = myframe;
- conf = frame->this->private;
-
- if (-1 == req->rpc_status) {
- gf_log (frame->this->name, GF_LOG_WARNING,
- "received RPC status error");
- goto out;
- }
-
- ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_dump_rsp);
- if (ret < 0) {
- gf_log (frame->this->name, GF_LOG_ERROR, "XDR decoding failed");
- goto out;
- }
- if (-1 == rsp.op_ret) {
- gf_log (frame->this->name, GF_LOG_WARNING,
- "failed to get the 'versions' from server");
- goto out;
- }
-
- if (server_has_portmap (frame->this, rsp.prog) == 0) {
- ret = client_query_portmap (frame->this, conf->rpc);
- goto out;
- }
-
- /* Check for the proper version string */
- /* Reply in "Name:Program-Number:Program-Version,..." format */
- ret = select_server_supported_programs (frame->this, rsp.prog);
- if (ret) {
- gf_log (frame->this->name, GF_LOG_ERROR,
- "server doesn't support the version");
- goto out;
- }
-
- client_setvolume (frame->this, conf->rpc);
-
-out:
- /* don't use GF_FREE, buffer was allocated by libc */
- if (rsp.prog) {
- trav = rsp.prog;
- while (trav) {
- next = trav->next;
- free (trav->progname);
- free (trav);
- trav = next;
- }
- }
-
- STACK_DESTROY (frame->root);
-
- if (ret != 0)
- rpc_transport_disconnect (conf->rpc->conn.trans);
-
- return ret;
-}
-
-int
-client_handshake (xlator_t *this, struct rpc_clnt *rpc)
-{
- call_frame_t *frame = NULL;
- clnt_conf_t *conf = NULL;
- gf_dump_req req = {0,};
- int ret = 0;
-
- conf = this->private;
- if (!conf->handshake) {
- gf_log (this->name, GF_LOG_WARNING, "handshake program not found");
- goto out;
- }
-
- frame = create_frame (this, this->ctx->pool);
- if (!frame)
- goto out;
-
- 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);
-
-out:
- return ret;
-}
-
-char *clnt_handshake_procs[GF_HNDSK_MAXVALUE] = {
- [GF_HNDSK_NULL] = "NULL",
- [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 = {
- .progname = "GlusterFS Handshake",
- .prognum = GLUSTER_HNDSK_PROGRAM,
- .progver = GLUSTER_HNDSK_VERSION,
- .procnames = clnt_handshake_procs,
-};
-
-char *clnt_dump_proc[GF_DUMP_MAXVALUE] = {
- [GF_DUMP_NULL] = "NULL",
- [GF_DUMP_DUMP] = "DUMP",
-};
-
-rpc_clnt_prog_t clnt_dump_prog = {
- .progname = "GF-DUMP",
- .prognum = GLUSTER_DUMP_PROGRAM,
- .progver = GLUSTER_DUMP_VERSION,
- .procnames = clnt_dump_proc,
-};
-
-char *clnt_pmap_procs[GF_PMAP_MAXVALUE] = {
- [GF_PMAP_PORTBYBRICK] = "PORTBYBRICK",
-};
-
-rpc_clnt_prog_t clnt_pmap_prog = {
- .progname = "PORTMAP",
- .prognum = GLUSTER_PMAP_PROGRAM,
- .progver = GLUSTER_PMAP_VERSION,
- .procnames = clnt_pmap_procs,
-};
diff --git a/xlators/protocol/client/src/client-helpers.c b/xlators/protocol/client/src/client-helpers.c
deleted file mode 100644
index 5d9f00fdc70..00000000000
--- a/xlators/protocol/client/src/client-helpers.c
+++ /dev/null
@@ -1,349 +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 "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)
-{
- 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 (clnt_fd_ctx_t *)(unsigned long)ctxaddr;
-}
-
-
-clnt_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 (clnt_fd_ctx_t *)(unsigned long)ctxaddr;
-}
-
-
-void
-this_fd_set_ctx (fd_t *file, xlator_t *this, loc_t *loc, clnt_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_INFO,
- "%s (%s): trying duplicate remote fd set. ",
- loc->path, uuid_utoa (loc->inode->gfid));
- else
- gf_log (this->name, GF_LOG_INFO,
- "%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_WARNING,
- "%s (%s): failed to set remote fd",
- loc->path, uuid_utoa (loc->inode->gfid));
- else
- gf_log (this->name, GF_LOG_WARNING,
- "%p: failed to set remote fd", file);
- }
-out:
- return;
-}
-
-
-int
-client_local_wipe (clnt_local_t *local)
-{
- if (local) {
- loc_wipe (&local->loc);
- loc_wipe (&local->loc2);
-
- if (local->fd) {
- fd_unref (local->fd);
- }
-
- if (local->iobref) {
- iobref_unref (local->iobref);
- }
-
- GF_FREE (local->name);
-
- mem_put (local);
- }
-
- return 0;
-}
-
-int
-unserialize_rsp_dirent (struct gfs3_readdir_rsp *rsp, gf_dirent_t *entries)
-{
- struct gfs3_dirlist *trav = NULL;
- gf_dirent_t *entry = NULL;
- int entry_len = 0;
- int ret = -1;
-
- trav = rsp->reply;
- while (trav) {
- entry_len = gf_dirent_size (trav->name);
- entry = GF_CALLOC (1, entry_len, gf_common_mt_gf_dirent_t);
- if (!entry)
- goto out;
-
- entry->d_ino = trav->d_ino;
- entry->d_off = trav->d_off;
- entry->d_len = trav->d_len;
- entry->d_type = trav->d_type;
-
- strcpy (entry->d_name, trav->name);
-
- list_add_tail (&entry->list, &entries->list);
-
- trav = trav->nextentry;
- }
-
- ret = 0;
-out:
- return ret;
-}
-
-int
-unserialize_rsp_direntp (xlator_t *this, fd_t *fd,
- 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);
- if (!entry)
- goto out;
-
- entry->d_ino = trav->d_ino;
- entry->d_off = trav->d_off;
- entry->d_len = trav->d_len;
- entry->d_type = trav->d_type;
-
- gf_stat_to_iatt (&trav->stat, &entry->d_stat);
-
- 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;
- }
-
- ret = 0;
-out:
- return ret;
-}
-
-int
-clnt_readdirp_rsp_cleanup (gfs3_readdirp_rsp *rsp)
-{
- gfs3_dirplist *prev = NULL;
- gfs3_dirplist *trav = NULL;
-
- trav = rsp->reply;
- prev = trav;
- while (trav) {
- trav = trav->nextentry;
- /* on client, the rpc lib allocates this */
- free (prev->dict.dict_val);
- free (prev->name);
- free (prev);
- prev = trav;
- }
-
- return 0;
-}
-
-int
-clnt_readdir_rsp_cleanup (gfs3_readdir_rsp *rsp)
-{
- gfs3_dirlist *prev = NULL;
- gfs3_dirlist *trav = NULL;
-
- trav = rsp->reply;
- prev = trav;
- while (trav) {
- trav = trav->nextentry;
- /* on client, the rpc lib allocates this */
- free (prev->name);
- free (prev);
- prev = trav;
- }
-
- return 0;
-}
-
-int
-client_get_remote_fd (xlator_t *this, fd_t *fd, int flags, int64_t *remote_fd)
-{
- clnt_fd_ctx_t *fdctx = NULL;
- clnt_conf_t *conf = NULL;
-
- GF_VALIDATE_OR_GOTO (this->name, fd, out);
- GF_VALIDATE_OR_GOTO (this->name, remote_fd, out);
-
- conf = this->private;
- pthread_mutex_lock (&conf->lock);
- {
- fdctx = this_fd_get_ctx (fd, this);
- if (!fdctx)
- *remote_fd = GF_ANON_FD_NO;
- else if (__is_fd_reopen_in_progress (fdctx))
- *remote_fd = -1;
- else
- *remote_fd = fdctx->remote_fd;
- }
- pthread_mutex_unlock (&conf->lock);
-
- if ((flags & FALLBACK_TO_ANON_FD) && (*remote_fd == -1))
- *remote_fd = GF_ANON_FD_NO;
-
- return 0;
-out:
- return -1;
-}
-
-gf_boolean_t
-client_is_reopen_needed (fd_t *fd, xlator_t *this, int64_t remote_fd)
-{
- clnt_fd_ctx_t *fdctx = NULL;
-
- fdctx = this_fd_get_ctx (fd, this);
- if (fdctx && (fdctx->remote_fd == -1) &&
- (remote_fd == GF_ANON_FD_NO))
- return _gf_true;
- return _gf_false;
-}
-
-int
-client_fd_fop_prepare_local (call_frame_t *frame, fd_t *fd, int64_t remote_fd)
-{
- xlator_t *this = NULL;
- clnt_conf_t *conf = NULL;
- clnt_local_t *local = NULL;
- int ret = 0;
-
- this = frame->this;
- conf = this->private;
-
- if (!frame || !fd) {
- ret = -EINVAL;
- goto out;
- }
-
- frame->local = mem_get0 (this->local_pool);
- if (frame->local == NULL) {
- ret = -ENOMEM;
- goto out;
- }
-
- local = frame->local;
- local->fd = fd_ref (fd);
- local->attempt_reopen = client_is_reopen_needed (fd, this, remote_fd);
- return 0;
-out:
- return ret;
-}
diff --git a/xlators/protocol/client/src/client-lk.c b/xlators/protocol/client/src/client-lk.c
deleted file mode 100644
index b3c36a42021..00000000000
--- a/xlators/protocol/client/src/client-lk.c
+++ /dev/null
@@ -1,573 +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 "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);
-
-static void
-__dump_client_lock (client_posix_lock_t *lock)
-{
- xlator_t *this = NULL;
-
- this = THIS;
-
- gf_log (this->name, GF_LOG_INFO,
- "{fd=%p}"
- "{%s lk-owner:%s %"PRId64" - %"PRId64"}"
- "{start=%"PRId64" end=%"PRId64"}",
- lock->fd,
- lock->fl_type == F_WRLCK ? "Write-Lock" : "Read-Lock",
- lkowner_utoa (&lock->owner),
- lock->user_flock.l_start,
- lock->user_flock.l_len,
- lock->fl_start,
- lock->fl_end);
-}
-
-static int
-dump_client_locks_fd (clnt_fd_ctx_t *fdctx)
-{
- client_posix_lock_t *lock = NULL;
- int count = 0;
-
- pthread_mutex_lock (&fdctx->mutex);
- {
- list_for_each_entry (lock, &fdctx->lock_list, list) {
- __dump_client_lock (lock);
- count++;
- }
- }
- pthread_mutex_unlock (&fdctx->mutex);
-
- return count;
-
-}
-
-int
-dump_client_locks (inode_t *inode)
-{
- fd_t *fd = NULL;
- clnt_conf_t *conf = NULL;
- xlator_t *this = NULL;
- clnt_fd_ctx_t *fdctx = NULL;
-
- int total_count = 0;
- int locks_fd_count = 0;
-
- this = THIS;
- conf = this->private;
-
- LOCK (&inode->lock);
- {
- list_for_each_entry (fd, &inode->fd_list, inode_list) {
- locks_fd_count = 0;
-
- pthread_mutex_lock (&conf->lock);
- {
- fdctx = this_fd_get_ctx (fd, this);
- }
- pthread_mutex_unlock (&conf->lock);
-
- if (fdctx)
- locks_fd_count = dump_client_locks_fd (fdctx);
-
- total_count += locks_fd_count;
- }
-
- }
- UNLOCK (&inode->lock);
-
- return total_count;
-
-}
-
-static off_t
-__get_lock_length (off_t start, off_t end)
-{
- if (end == LLONG_MAX)
- return 0;
- else
- return (end - start + 1);
-}
-
-/* Add two locks */
-static client_posix_lock_t *
-add_locks (client_posix_lock_t *l1, client_posix_lock_t *l2)
-{
- client_posix_lock_t *sum = NULL;
-
- sum = GF_CALLOC (1, sizeof (*sum), gf_client_mt_clnt_lock_t);
- if (!sum)
- return NULL;
-
- sum->fl_start = min (l1->fl_start, l2->fl_start);
- sum->fl_end = max (l1->fl_end, l2->fl_end);
-
- sum->user_flock.l_start = sum->fl_start;
- sum->user_flock.l_len = __get_lock_length (sum->fl_start,
- sum->fl_end);
-
- return sum;
-}
-
-
-/* Return true if the locks overlap, false otherwise */
-static int
-locks_overlap (client_posix_lock_t *l1, client_posix_lock_t *l2)
-{
- /*
- Note:
- FUSE always gives us absolute offsets, so no need to worry
- about SEEK_CUR or SEEK_END
- */
-
- return ((l1->fl_end >= l2->fl_start) &&
- (l2->fl_end >= l1->fl_start));
-}
-
-static void
-__delete_client_lock (client_posix_lock_t *lock)
-{
- list_del_init (&lock->list);
-}
-
-/* Destroy a posix_lock */
-static void
-__destroy_client_lock (client_posix_lock_t *lock)
-{
- GF_FREE (lock);
-}
-
-/* Subtract two locks */
-struct _values {
- client_posix_lock_t *locks[3];
-};
-
-/* {big} must always be contained inside {small} */
-static struct _values
-subtract_locks (client_posix_lock_t *big, client_posix_lock_t *small)
-{
- struct _values v = { .locks = {0, 0, 0} };
-
- if ((big->fl_start == small->fl_start) &&
- (big->fl_end == small->fl_end)) {
- /* both edges coincide with big */
- v.locks[0] = GF_CALLOC (1, sizeof (client_posix_lock_t),
- gf_client_mt_clnt_lock_t );
- GF_ASSERT (v.locks[0]);
- memcpy (v.locks[0], big, sizeof (client_posix_lock_t));
- v.locks[0]->fl_type = small->fl_type;
- }
- else if ((small->fl_start > big->fl_start) &&
- (small->fl_end < big->fl_end)) {
- /* both edges lie inside big */
- v.locks[0] = GF_CALLOC (1, sizeof (client_posix_lock_t),
- gf_client_mt_clnt_lock_t);
- GF_ASSERT (v.locks[0]);
- v.locks[1] = GF_CALLOC (1, sizeof (client_posix_lock_t),
- gf_client_mt_clnt_lock_t);
- GF_ASSERT (v.locks[1]);
- v.locks[2] = GF_CALLOC (1, sizeof (client_posix_lock_t),
- gf_client_mt_clnt_lock_t);
- GF_ASSERT (v.locks[2]);
-
- memcpy (v.locks[0], big, sizeof (client_posix_lock_t));
- v.locks[0]->fl_end = small->fl_start - 1;
- v.locks[0]->user_flock.l_len = __get_lock_length (v.locks[0]->fl_start,
- v.locks[0]->fl_end);
-
- memcpy (v.locks[1], small, sizeof (client_posix_lock_t));
- memcpy (v.locks[2], big, sizeof (client_posix_lock_t));
- v.locks[2]->fl_start = small->fl_end + 1;
- v.locks[2]->user_flock.l_start = small->fl_end + 1;
- }
- /* one edge coincides with big */
- else if (small->fl_start == big->fl_start) {
- v.locks[0] = GF_CALLOC (1, sizeof (client_posix_lock_t),
- gf_client_mt_clnt_lock_t);
- GF_ASSERT (v.locks[0]);
- v.locks[1] = GF_CALLOC (1, sizeof (client_posix_lock_t),
- gf_client_mt_clnt_lock_t);
- GF_ASSERT (v.locks[1]);
-
- memcpy (v.locks[0], big, sizeof (client_posix_lock_t));
- v.locks[0]->fl_start = small->fl_end + 1;
- v.locks[0]->user_flock.l_start = small->fl_end + 1;
-
- memcpy (v.locks[1], small, sizeof (client_posix_lock_t));
- }
- else if (small->fl_end == big->fl_end) {
- v.locks[0] = GF_CALLOC (1, sizeof (client_posix_lock_t),
- gf_client_mt_clnt_lock_t);
- GF_ASSERT (v.locks[0]);
- v.locks[1] = GF_CALLOC (1, sizeof (client_posix_lock_t),
- gf_client_mt_clnt_lock_t);
- GF_ASSERT (v.locks[1]);
-
- memcpy (v.locks[0], big, sizeof (client_posix_lock_t));
- v.locks[0]->fl_end = small->fl_start - 1;
- v.locks[0]->user_flock.l_len = __get_lock_length (v.locks[0]->fl_start,
- v.locks[0]->fl_end);
-
- memcpy (v.locks[1], small, sizeof (client_posix_lock_t));
- }
- else {
- /* LOG-TODO : decide what more info is required here*/
- gf_log ("client-protocol", GF_LOG_CRITICAL,
- "Unexpected case in subtract_locks. Please send "
- "a bug report to gluster-devel@gluster.org");
- }
-
- return v;
-}
-
-static void
-__delete_unlck_locks (clnt_fd_ctx_t *fdctx)
-{
- client_posix_lock_t *l = NULL;
- client_posix_lock_t *tmp = NULL;
-
- list_for_each_entry_safe (l, tmp, &fdctx->lock_list, list) {
- if (l->fl_type == F_UNLCK) {
- __delete_client_lock (l);
- __destroy_client_lock (l);
- }
- }
-}
-
-static void
-__insert_lock (clnt_fd_ctx_t *fdctx, client_posix_lock_t *lock)
-{
- list_add_tail (&lock->list, &fdctx->lock_list);
-
- return;
-}
-
-static void
-__insert_and_merge (clnt_fd_ctx_t *fdctx, client_posix_lock_t *lock)
-{
- client_posix_lock_t *conf = NULL;
- client_posix_lock_t *t = NULL;
- client_posix_lock_t *sum = NULL;
- int i = 0;
- struct _values v = { .locks = {0, 0, 0} };
-
- list_for_each_entry_safe (conf, t, &fdctx->lock_list, list) {
- if (!locks_overlap (conf, lock))
- continue;
-
- if (is_same_lkowner (&conf->owner, &lock->owner)) {
- if (conf->fl_type == lock->fl_type) {
- sum = add_locks (lock, conf);
-
- sum->fd = lock->fd;
-
- __delete_client_lock (conf);
- __destroy_client_lock (conf);
-
- __destroy_client_lock (lock);
- __insert_and_merge (fdctx, sum);
-
- return;
- } else {
- sum = add_locks (lock, conf);
-
- sum->fd = conf->fd;
- sum->owner = conf->owner;
-
- v = subtract_locks (sum, lock);
-
- __delete_client_lock (conf);
- __destroy_client_lock (conf);
-
- __delete_client_lock (lock);
- __destroy_client_lock (lock);
-
- __destroy_client_lock (sum);
-
- for (i = 0; i < 3; i++) {
- if (!v.locks[i])
- continue;
-
- INIT_LIST_HEAD (&v.locks[i]->list);
- __insert_and_merge (fdctx,
- v.locks[i]);
- }
-
- __delete_unlck_locks (fdctx);
- return;
- }
- }
-
- if (lock->fl_type == F_UNLCK) {
- continue;
- }
-
- if ((conf->fl_type == F_RDLCK) && (lock->fl_type == F_RDLCK)) {
- __insert_lock (fdctx, lock);
- return;
- }
- }
-
- /* no conflicts, so just insert */
- if (lock->fl_type != F_UNLCK) {
- __insert_lock (fdctx, lock);
- } else {
- __destroy_client_lock (lock);
- }
-}
-
-static void
-client_setlk (clnt_fd_ctx_t *fdctx, client_posix_lock_t *lock)
-{
- pthread_mutex_lock (&fdctx->mutex);
- {
- __insert_and_merge (fdctx, lock);
- }
- pthread_mutex_unlock (&fdctx->mutex);
-
- return;
-}
-
-static void
-destroy_client_lock (client_posix_lock_t *lock)
-{
- GF_FREE (lock);
-}
-
-int32_t
-delete_granted_locks_owner (fd_t *fd, gf_lkowner_t *owner)
-{
- clnt_fd_ctx_t *fdctx = NULL;
- client_posix_lock_t *lock = NULL;
- client_posix_lock_t *tmp = NULL;
- xlator_t *this = NULL;
-
- struct list_head delete_list;
- int ret = 0;
- int count = 0;
-
- INIT_LIST_HEAD (&delete_list);
- this = THIS;
- fdctx = this_fd_get_ctx (fd, this);
- if (!fdctx) {
- gf_log (this->name, GF_LOG_WARNING,
- "fdctx not valid");
- ret = -1;
- goto out;
- }
-
- pthread_mutex_lock (&fdctx->mutex);
- {
- list_for_each_entry_safe (lock, tmp, &fdctx->lock_list, list) {
- if (!is_same_lkowner (&lock->owner, owner)) {
- list_del_init (&lock->list);
- list_add_tail (&lock->list, &delete_list);
- count++;
- }
- }
- }
- pthread_mutex_unlock (&fdctx->mutex);
-
- list_for_each_entry_safe (lock, tmp, &delete_list, list) {
- list_del_init (&lock->list);
- destroy_client_lock (lock);
- }
-
- /* FIXME: Need to actually print the locks instead of count */
- gf_log (this->name, GF_LOG_TRACE,
- "Number of locks cleared=%d", count);
-
-out:
- return ret;
-}
-
-int32_t
-delete_granted_locks_fd (clnt_fd_ctx_t *fdctx)
-{
- client_posix_lock_t *lock = NULL;
- client_posix_lock_t *tmp = NULL;
- xlator_t *this = NULL;
-
- struct list_head delete_list;
- int ret = 0;
- int count = 0;
-
- INIT_LIST_HEAD (&delete_list);
- this = THIS;
-
- pthread_mutex_lock (&fdctx->mutex);
- {
- list_splice_init (&fdctx->lock_list, &delete_list);
- }
- pthread_mutex_unlock (&fdctx->mutex);
-
- list_for_each_entry_safe (lock, tmp, &delete_list, list) {
- list_del_init (&lock->list);
- count++;
- destroy_client_lock (lock);
- }
-
- /* FIXME: Need to actually print the locks instead of count */
- gf_log (this->name, GF_LOG_TRACE,
- "Number of locks cleared=%d", count);
-
- return ret;
-}
-
-int32_t
-client_cmd_to_gf_cmd (int32_t cmd, int32_t *gf_cmd)
-{
- int ret = 0;
-
- 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 if (cmd == F_RESLK_LCK)
- *gf_cmd = GF_LK_RESLK_LCK;
- else if (cmd == F_RESLK_LCKW)
- *gf_cmd = GF_LK_RESLK_LCKW;
- else if (cmd == F_RESLK_UNLCK)
- *gf_cmd = GF_LK_RESLK_UNLCK;
- else if (cmd == F_GETLK_FD)
- *gf_cmd = GF_LK_GETLK_FD;
- else
- ret = -1;
-
- return ret;
-
-}
-
-static client_posix_lock_t *
-new_client_lock (struct gf_flock *flock, gf_lkowner_t *owner,
- int32_t cmd, fd_t *fd)
-{
- client_posix_lock_t *new_lock = NULL;
-
- new_lock = GF_CALLOC (1, sizeof (*new_lock),
- gf_client_mt_clnt_lock_t);
- if (!new_lock) {
- goto out;
- }
-
- INIT_LIST_HEAD (&new_lock->list);
- new_lock->fd = fd;
- memcpy (&new_lock->user_flock, flock, sizeof (struct gf_flock));
-
- new_lock->fl_type = flock->l_type;
- new_lock->fl_start = flock->l_start;
-
- if (flock->l_len == 0)
- new_lock->fl_end = LLONG_MAX;
- else
- new_lock->fl_end = flock->l_start + flock->l_len - 1;
-
- new_lock->owner = *owner;
-
- new_lock->cmd = cmd; /* Not really useful */
-
-out:
- return new_lock;
-}
-
-void
-client_save_number_fds (clnt_conf_t *conf, int count)
-{
- LOCK (&conf->rec_lock);
- {
- conf->reopen_fd_count = count;
- }
- UNLOCK (&conf->rec_lock);
-}
-
-int
-client_add_lock_for_recovery (fd_t *fd, struct gf_flock *flock,
- gf_lkowner_t *owner, int32_t cmd)
-{
- clnt_fd_ctx_t *fdctx = NULL;
- xlator_t *this = NULL;
- client_posix_lock_t *lock = NULL;
- clnt_conf_t *conf = NULL;
-
- int ret = 0;
-
- this = THIS;
- conf = this->private;
-
- pthread_mutex_lock (&conf->lock);
- {
- fdctx = this_fd_get_ctx (fd, this);
- }
- pthread_mutex_unlock (&conf->lock);
-
- if (!fdctx) {
- gf_log (this->name, GF_LOG_WARNING,
- "failed to get fd context. sending EBADFD");
- ret = -EBADFD;
- goto out;
- }
-
- lock = new_client_lock (flock, owner, cmd, fd);
- if (!lock) {
- ret = -ENOMEM;
- goto out;
- }
-
- client_setlk (fdctx, lock);
-
-out:
- return ret;
-
-}
-
-int32_t
-client_dump_locks (char *name, inode_t *inode,
- dict_t *dict)
-{
- int ret = 0;
- dict_t *new_dict = NULL;
- char dict_string[256];
-
- GF_ASSERT (dict);
- new_dict = dict;
-
- ret = dump_client_locks (inode);
- snprintf (dict_string, 256, "%d locks dumped in log file", ret);
-
- ret = dict_set_dynstr(new_dict, CLIENT_DUMP_LOCKS, dict_string);
- if (ret) {
- gf_log (THIS->name, GF_LOG_WARNING,
- "could not set dict with %s", CLIENT_DUMP_LOCKS);
- goto out;
- }
-
-out:
-
- return ret;
-}
-
-int32_t
-is_client_dump_locks_cmd (char *name)
-{
- int ret = 0;
-
- if (strcmp (name, CLIENT_DUMP_LOCKS) == 0)
- ret = 1;
-
- return ret;
-}
diff --git a/xlators/protocol/client/src/client-mem-types.h b/xlators/protocol/client/src/client-mem-types.h
deleted file mode 100644
index f6573da2ddd..00000000000
--- a/xlators/protocol/client/src/client-mem-types.h
+++ /dev/null
@@ -1,25 +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 __CLIENT_MEM_TYPES_H__
-#define __CLIENT_MEM_TYPES_H__
-
-#include "mem-types.h"
-
-enum gf_client_mem_types_ {
- gf_client_mt_clnt_conf_t = gf_common_mt_end + 1,
- 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-protocol.c b/xlators/protocol/client/src/client-protocol.c
new file mode 100644
index 00000000000..5a2ea4cb1cf
--- /dev/null
+++ b/xlators/protocol/client/src/client-protocol.c
@@ -0,0 +1,7244 @@
+/*
+ Copyright (c) 2006-2009 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 "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 <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_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) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "%s (%"PRId64"): trying duplicate remote fd set. ",
+ loc->path, loc->inode->ino);
+ }
+
+ ret = fd_ctx_set (file, this, (uint64_t)(unsigned long)ctx);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "%s (%"PRId64"): failed to set remote fd",
+ loc->path, loc->inode->ino);
+ }
+out:
+ return;
+}
+
+
+static int
+client_local_wipe (client_local_t *local)
+{
+ if (local) {
+ loc_wipe (&local->loc);
+
+ if (local->fd)
+ fd_unref (local->fd);
+
+ 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->cbk;
+
+ 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;
+ }
+
+ 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);
+ 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)
+ 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);
+ }
+
+ 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)
+{
+ 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 = calloc (1, sizeof (*local));
+ 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_FOP_CREATE,
+ hdr, hdrlen, NULL, 0, NULL);
+ return ret;
+unwind:
+ if (hdr)
+ free (hdr);
+ frame->local = NULL;
+ STACK_UNWIND (frame, -1, EINVAL, fd, NULL, NULL);
+ if (local)
+ client_local_wipe (local);
+ 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 = calloc (1, sizeof (*local));
+ 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_FOP_OPEN,
+ hdr, hdrlen, NULL, 0, NULL);
+
+ return ret;
+unwind:
+ if (hdr)
+ free (hdr);
+ frame->local = NULL;
+ STACK_UNWIND (frame, -1, EINVAL, fd);
+ if (local)
+ client_local_wipe (local);
+ 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;
+ int32_t op_errno = EINVAL;
+
+ 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);
+ op_errno = ENOENT;
+ 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_FOP_STAT,
+ hdr, hdrlen, NULL, 0, NULL);
+
+ return ret;
+unwind:
+ if (hdr)
+ free (hdr);
+ STACK_UNWIND (frame, -1, op_errno, 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_FOP_READLINK,
+ hdr, hdrlen, NULL, 0, NULL);
+
+ return ret;
+unwind:
+ if (hdr)
+ 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)
+{
+ 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 = calloc (1, sizeof (*local));
+ 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_FOP_MKNOD,
+ hdr, hdrlen, NULL, 0, NULL);
+
+ return ret;
+unwind:
+ if (hdr)
+ free (hdr);
+ frame->local = NULL;
+ STACK_UNWIND (frame, -1, EINVAL, loc->inode, NULL);
+ if (local)
+ client_local_wipe (local);
+ 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)
+{
+ 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;
+
+ if (loc->ino == 1) { /*Fail mkdir for root dir */
+ gf_log (this->name, GF_LOG_ERROR,
+ "MKDIR %"PRId64"/%s (%s): Failing mkdir call on "
+ "root", loc->ino, loc->name, loc->path);
+ goto unwind;
+ }
+
+ local = calloc (1, sizeof (*local));
+ 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_FOP_MKDIR,
+ hdr, hdrlen, NULL, 0, NULL);
+
+ return ret;
+unwind:
+ if (hdr)
+ free (hdr);
+ frame->local = NULL;
+ STACK_UNWIND_STRICT (mkdir, frame, -1, EINVAL, loc->inode, NULL, NULL, NULL);
+ if (local)
+ client_local_wipe (local);
+ 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_FOP_UNLINK,
+ hdr, hdrlen, NULL, 0, NULL);
+
+ return ret;
+unwind:
+ if (hdr)
+ 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_FOP_RMDIR,
+ hdr, hdrlen, NULL, 0, NULL);
+
+ return ret;
+unwind:
+ if (hdr)
+ 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)
+{
+ 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 = calloc (1, sizeof (*local));
+ 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_FOP_SYMLINK,
+ hdr, hdrlen, NULL, 0, NULL);
+ return ret;
+unwind:
+ if (hdr)
+ free (hdr);
+ frame->local = NULL;
+ STACK_UNWIND (frame, -1, EINVAL, loc->inode, NULL);
+ if (local)
+ client_local_wipe (local);
+ 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_FOP_RENAME,
+ hdr, hdrlen, NULL, 0, NULL);
+ return ret;
+unwind:
+ if (hdr)
+ 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;
+ int32_t op_errno = EINVAL;
+
+ local = calloc (1, sizeof (*local));
+ 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);
+ op_errno = ENOENT;
+ 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_FOP_LINK,
+ hdr, hdrlen, NULL, 0, NULL);
+ return ret;
+unwind:
+ if (hdr)
+ free (hdr);
+ frame->local = NULL;
+ STACK_UNWIND (frame, -1, op_errno, oldloc->inode, NULL);
+ if (local)
+ client_local_wipe (local);
+ 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_FOP_TRUNCATE,
+ hdr, hdrlen, NULL, 0, NULL);
+
+ return ret;
+unwind:
+ if (hdr)
+ 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_FOP_READ,
+ hdr, hdrlen, NULL, 0, NULL);
+
+ return 0;
+unwind:
+ if (hdr)
+ 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_FOP_WRITE,
+ hdr, hdrlen, vector, count, iobref);
+ return ret;
+unwind:
+ if (hdr)
+ 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_FOP_STATFS,
+ hdr, hdrlen, NULL, 0, NULL);
+
+ return ret;
+unwind:
+ if (hdr)
+ 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_FOP_FLUSH,
+ hdr, hdrlen, NULL, 0, NULL);
+
+ return 0;
+unwind:
+ if (hdr)
+ 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_FOP_FSYNC,
+ hdr, hdrlen, NULL, 0, NULL);
+
+ return ret;
+unwind:
+ if (hdr)
+ 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);
+ 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_FOP_XATTROP,
+ hdr, hdrlen, NULL, 0, NULL);
+ return ret;
+unwind:
+ if (hdr)
+ 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_FOP_FXATTROP,
+ hdr, hdrlen, NULL, 0, NULL);
+ return ret;
+unwind:
+ if (hdr)
+ 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_FOP_SETXATTR,
+ hdr, hdrlen, NULL, 0, NULL);
+ return ret;
+unwind:
+ if (hdr)
+ 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_FOP_FSETXATTR,
+ hdr, hdrlen, NULL, 0, NULL);
+ return ret;
+unwind:
+ if (hdr)
+ 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_FOP_GETXATTR,
+ hdr, hdrlen, NULL, 0, NULL);
+ return ret;
+unwind:
+ if (hdr)
+ 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_FOP_FGETXATTR,
+ hdr, hdrlen, NULL, 0, NULL);
+ return ret;
+unwind:
+ if (hdr)
+ 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_FOP_REMOVEXATTR,
+ hdr, hdrlen, NULL, 0, NULL);
+ return ret;
+unwind:
+ if (hdr)
+ 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 = calloc (1, sizeof (*local));
+ 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_FOP_OPENDIR,
+ hdr, hdrlen, NULL, 0, NULL);
+
+ return ret;
+unwind:
+ if (hdr)
+ free (hdr);
+ frame->local = NULL;
+ STACK_UNWIND (frame, -1, EINVAL, fd);
+ if (local)
+ client_local_wipe (local);
+ 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_getdents (call_frame_t *frame, xlator_t *this, fd_t *fd,
+ size_t size, off_t offset, int32_t flag)
+{
+ gf_hdr_common_t *hdr = NULL;
+ gf_fop_getdents_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);
+ }
+
+ remote_fd = fdctx->remote_fd;
+ hdrlen = gf_hdr_len (req, 0);
+ hdr = gf_hdr_new (req, 0);
+ GF_VALIDATE_OR_GOTO (frame->this->name, hdr, unwind);
+
+ req = gf_param (hdr);
+ GF_VALIDATE_OR_GOTO (frame->this->name, hdr, unwind);
+
+ req->fd = hton64 (remote_fd);
+ req->size = hton32 (size);
+ req->offset = hton64 (offset);
+ req->flags = hton32 (flag);
+
+ ret = protocol_client_xfer (frame, this,
+ CLIENT_CHANNEL (this, CHANNEL_BULK),
+ GF_OP_TYPE_FOP_REQUEST, GF_FOP_GETDENTS,
+ hdr, hdrlen, NULL, 0, NULL);
+
+ return 0;
+unwind:
+ STACK_UNWIND (frame, -1, EINVAL, NULL, 0);
+ 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_FOP_READDIRP,
+ hdr, hdrlen, NULL, 0, NULL);
+
+ return 0;
+unwind:
+ if (hdr)
+ 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_FOP_READDIR,
+ hdr, hdrlen, NULL, 0, NULL);
+
+ return 0;
+unwind:
+ if (hdr)
+ 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_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_FOP_ACCESS,
+ hdr, hdrlen, NULL, 0, NULL);
+
+ return ret;
+unwind:
+ if (hdr)
+ 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_FOP_FTRUNCATE,
+ hdr, hdrlen, NULL, 0, NULL);
+
+ return ret;
+unwind:
+ if (hdr)
+ 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_FOP_FSTAT,
+ hdr, hdrlen, NULL, 0, NULL);
+
+ return ret;
+unwind:
+ if (hdr)
+ 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 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_FOP_LK,
+ hdr, hdrlen, NULL, 0, NULL);
+ return ret;
+unwind:
+ if (hdr)
+ 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 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_FOP_INODELK,
+ hdr, hdrlen, NULL, 0, NULL);
+ return ret;
+unwind:
+ if (hdr)
+ 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 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_FOP_FINODELK,
+ hdr, hdrlen, NULL, 0, NULL);
+ return ret;
+unwind:
+ if (hdr)
+ 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_FOP_ENTRYLK,
+ hdr, hdrlen, NULL, 0, NULL);
+
+ return ret;
+unwind:
+ if (hdr)
+ 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_FOP_FENTRYLK,
+ hdr, hdrlen, NULL, 0, NULL);
+
+ return ret;
+unwind:
+ if (hdr)
+ 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;
+
+ local = calloc (1, sizeof (*local));
+ GF_VALIDATE_OR_GOTO (this->name, local, unwind);
+
+ loc_copy (&local->loc, loc);
+
+ frame->local = local;
+
+ GF_VALIDATE_OR_GOTO (this->name, loc, unwind);
+ GF_VALIDATE_OR_GOTO (this->name, loc->path, unwind);
+
+ 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);
+ op_errno = ENOENT;
+ 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);
+ FREE (buf);
+ }
+
+ req->dictlen = hton32 (dictlen);
+
+ ret = protocol_client_xfer (frame, this,
+ CLIENT_CHANNEL (this, CHANNEL_LOWLAT),
+ GF_OP_TYPE_FOP_REQUEST, GF_FOP_LOOKUP,
+ hdr, hdrlen, NULL, 0, NULL);
+ return ret;
+
+unwind:
+ frame->local = NULL;
+ STACK_UNWIND (frame, op_ret, op_errno, loc->inode, NULL, NULL);
+ if (local)
+ client_local_wipe (local);
+ return ret;
+}
+
+
+int
+client_setdents (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags,
+ dir_entry_t *entries, int32_t count)
+{
+ gf_hdr_common_t *hdr = NULL;
+ gf_fop_setdents_req_t *req = NULL;
+ int64_t remote_fd = 0;
+ char *ptr = NULL;
+ dir_entry_t *trav = NULL;
+ uint32_t len = 0;
+ int32_t buf_len = 0;
+ int32_t ret = -1;
+ int32_t op_ret = -1;
+ int32_t op_errno = EINVAL;
+ int32_t vec_count = 0;
+ size_t hdrlen = -1;
+ struct iovec vector[1];
+ struct iobref *iobref = NULL;
+ struct iobuf *iobuf = NULL;
+ client_fd_ctx_t *fdctx = NULL;
+ client_conf_t *conf = NULL;
+
+ GF_VALIDATE_OR_GOTO (this->name, fd, 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_DEBUG,
+ "(%"PRId64"): failed to get fd ctx. EBADFD",
+ fd->inode->ino);
+ op_errno = EBADFD;
+ goto unwind;
+ }
+
+ if (fdctx->remote_fd == -1) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "(%"PRId64"): failed to get fd ctx. EBADFD",
+ fd->inode->ino);
+ op_errno = EBADFD;
+ goto unwind;
+ }
+
+ remote_fd = fdctx->remote_fd;
+ GF_VALIDATE_OR_GOTO (this->name, entries, unwind);
+ GF_VALIDATE_OR_GOTO (this->name, count, unwind);
+
+ trav = entries->next;
+ while (trav) {
+ len += strlen (trav->name);
+ len += 1;
+ len += strlen (trav->link);
+ len += 1;
+ len += 256; // max possible for statbuf;
+ trav = trav->next;
+ }
+ iobuf = iobuf_get (this->ctx->iobuf_pool);
+ GF_VALIDATE_OR_GOTO (this->name, iobuf, unwind);
+
+ ptr = iobuf->ptr;
+
+ trav = entries->next;
+ while (trav) {
+ int32_t this_len = 0;
+ char *tmp_buf = NULL;
+ struct stat *stbuf = &trav->buf;
+ {
+ /* Convert the stat buf to string */
+ uint64_t dev = stbuf->st_dev;
+ uint64_t ino = stbuf->st_ino;
+ uint32_t mode = stbuf->st_mode;
+ uint32_t nlink = stbuf->st_nlink;
+ uint32_t uid = stbuf->st_uid;
+ uint32_t gid = stbuf->st_gid;
+ uint64_t rdev = stbuf->st_rdev;
+ uint64_t size = stbuf->st_size;
+ uint32_t blksize = stbuf->st_blksize;
+ uint64_t blocks = stbuf->st_blocks;
+
+ uint32_t atime = stbuf->st_atime;
+ uint32_t mtime = stbuf->st_mtime;
+ uint32_t ctime = stbuf->st_ctime;
+
+ uint32_t atime_nsec = ST_ATIM_NSEC(stbuf);
+ uint32_t mtime_nsec = ST_MTIM_NSEC(stbuf);
+ uint32_t ctime_nsec = ST_CTIM_NSEC(stbuf);
+
+ ret = asprintf (&tmp_buf, GF_STAT_PRINT_FMT_STR,
+ dev, ino, mode, nlink, uid, gid,
+ rdev, size, blksize, blocks,
+ atime, atime_nsec, mtime, mtime_nsec,
+ ctime, ctime_nsec);
+ if (-1 == ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "asprintf failed while setting stat "
+ "buf to string");
+ STACK_UNWIND (frame, -1, ENOMEM);
+ return 0;
+ }
+ }
+ this_len = sprintf (ptr, "%s/%s%s\n",
+ trav->name, tmp_buf, trav->link);
+
+ FREE (tmp_buf);
+ trav = trav->next;
+ ptr += this_len;
+ }
+ buf_len = strlen (iobuf->ptr);
+
+ 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->flags = hton32 (flags);
+ req->count = hton32 (count);
+
+ iobref = iobref_new ();
+ iobref_add (iobref, iobuf);
+
+ ret = protocol_client_xfer (frame, this,
+ CLIENT_CHANNEL (this, CHANNEL_BULK),
+ GF_OP_TYPE_FOP_REQUEST, GF_FOP_SETDENTS,
+ hdr, hdrlen, vector, vec_count, iobref);
+
+ if (iobref)
+ iobref_unref (iobref);
+
+ if (iobuf)
+ iobuf_unref (iobuf);
+
+ return ret;
+unwind:
+
+ if (iobref)
+ iobref_unref (iobref);
+
+ if (iobuf)
+ iobuf_unref (iobuf);
+
+ STACK_UNWIND (frame, op_ret, op_errno);
+ return 0;
+}
+
+int
+client_setattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
+ struct stat *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;
+ int32_t op_errno = EINVAL;
+
+ 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);
+ op_errno = ENOENT;
+ 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_stat (&req->stbuf, stbuf);
+ req->valid = hton32 (valid);
+
+ ret = protocol_client_xfer (frame, this,
+ CLIENT_CHANNEL (this, CHANNEL_BULK),
+ GF_OP_TYPE_FOP_REQUEST, GF_FOP_SETATTR,
+ hdr, hdrlen, NULL, 0, NULL);
+
+ return ret;
+unwind:
+ STACK_UNWIND (frame, -1, op_errno, NULL);
+ return 0;
+}
+
+
+int
+client_fsetattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
+ struct stat *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_stat (&req->stbuf, stbuf);
+ req->valid = hton32 (valid);
+
+ ret = protocol_client_xfer (frame, this,
+ CLIENT_CHANNEL (this, CHANNEL_BULK),
+ GF_OP_TYPE_FOP_REQUEST, GF_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);
+ 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
+ */
+
+/**
+ * client_stats - stats function for client protocol
+ * @frame: call frame
+ * @this: this translator structure
+ * @flags:
+ *
+ * external reference through client_protocol_xlator->mops->stats
+ */
+
+int
+client_stats (call_frame_t *frame, xlator_t *this, int32_t flags)
+{
+ gf_hdr_common_t *hdr = NULL;
+ gf_mop_stats_req_t *req = NULL;
+ size_t hdrlen = -1;
+ int ret = -1;
+
+ GF_VALIDATE_OR_GOTO ("client", this, unwind);
+
+ 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->flags = hton32 (flags);
+
+ ret = protocol_client_xfer (frame, this,
+ CLIENT_CHANNEL (this, CHANNEL_BULK),
+ GF_OP_TYPE_MOP_REQUEST, GF_MOP_STATS,
+ hdr, hdrlen, NULL, 0, NULL);
+
+ return ret;
+unwind:
+ STACK_UNWIND (frame, -1, EINVAL, NULL);
+ return 0;
+}
+
+
+/* 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)
+ 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)
+ 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 stat stbuf = {0, };
+ struct stat preparent = {0, };
+ struct stat 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_stat (&rsp->stat, &stbuf);
+
+ gf_stat_to_stat (&rsp->preparent, &preparent);
+ gf_stat_to_stat (&rsp->postparent, &postparent);
+
+ ino = stbuf.st_ino;
+ gen = stbuf.st_dev;
+ }
+
+ 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 = CALLOC (1, sizeof (*fdctx));
+ 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 = CALLOC (1, sizeof (*fdctx));
+ 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 stat 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_stat (&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 stat stbuf = {0, };
+ inode_t *inode = NULL;
+ client_local_t *local = NULL;
+ int ret = 0;
+ struct stat preparent = {0,};
+ struct stat 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_stat (&rsp->stat, &stbuf);
+
+ ret = inode_ctx_put2 (local->loc.inode, frame->this,
+ stbuf.st_ino, stbuf.st_dev);
+ 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);
+ client_local_wipe (local);
+ return 0;
+ }
+
+ gf_stat_to_stat (&rsp->preparent, &preparent);
+ gf_stat_to_stat (&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 stat stbuf = {0, };
+ struct stat preparent = {0,};
+ struct stat 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_stat (&rsp->stat, &stbuf);
+
+ ret = inode_ctx_put2 (inode, frame->this,
+ stbuf.st_ino, stbuf.st_dev);
+ 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);
+ client_local_wipe (local);
+ return 0;
+ }
+ gf_stat_to_stat (&rsp->preparent, &preparent);
+ gf_stat_to_stat (&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 stat stbuf = {0, };
+ inode_t *inode = NULL;
+ client_local_t *local = NULL;
+ struct stat preparent = {0,};
+ struct stat 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_stat (&rsp->stat, &stbuf);
+
+ gf_stat_to_stat (&rsp->preparent, &preparent);
+ gf_stat_to_stat (&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 stat prestat = {0, };
+ struct stat 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_stat (&rsp->prestat, &prestat);
+ gf_stat_to_stat (&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 stat 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_stat (&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 stat prestat = {0, };
+ struct stat 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_stat (&rsp->prestat, &prestat);
+ gf_stat_to_stat (&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 stat 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_stat (&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 stat prestat = {0, };
+ struct stat 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_stat (&rsp->prestat, &prestat);
+ gf_stat_to_stat (&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 stat prestat = {0, };
+ struct stat 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_stat (&rsp->prestat, &prestat);
+ gf_stat_to_stat (&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 stat preparent = {0,};
+ struct stat 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_stat (&rsp->preparent, &preparent);
+ gf_stat_to_stat (&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 stat stbuf = {0, };
+ gf_fop_rename_rsp_t *rsp = NULL;
+ int32_t op_ret = 0;
+ int32_t op_errno = 0;
+ struct stat preoldparent = {0, };
+ struct stat postoldparent = {0, };
+ struct stat prenewparent = {0, };
+ struct stat 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_stat (&rsp->stat, &stbuf);
+ gf_stat_to_stat (&rsp->preoldparent, &preoldparent);
+ gf_stat_to_stat (&rsp->postoldparent, &postoldparent);
+ gf_stat_to_stat (&rsp->prenewparent, &prenewparent);
+ gf_stat_to_stat (&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 stat 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_stat (&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 stat stbuf = {0, };
+ inode_t *inode = NULL;
+ client_local_t *local = NULL;
+ int ret = 0;
+ struct stat preparent = {0,};
+ struct stat 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_stat (&rsp->stat, &stbuf);
+
+ ret = inode_ctx_put2 (inode, frame->this, stbuf.st_ino,
+ stbuf.st_dev);
+ 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);
+ client_local_wipe (local);
+ return 0;
+ }
+
+ gf_stat_to_stat (&rsp->preparent, &preparent);
+ gf_stat_to_stat (&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 = CALLOC (1, sizeof (*fdctx));
+ 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 stat preparent = {0,};
+ struct stat 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_stat (&rsp->preparent, &preparent);
+ gf_stat_to_stat (&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 stat stbuf = {0, };
+ struct stat 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_stat (&rsp->postparent, &postparent);
+
+ if (op_ret == 0) {
+ op_ret = -1;
+ gf_stat_to_stat (&rsp->stat, &stbuf);
+
+ ret = inode_ctx_get2 (inode, frame->this, &oldino, &oldgen);
+ if (oldino != stbuf.st_ino || oldgen != stbuf.st_dev) {
+ 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.st_dev, stbuf.st_ino);
+ op_errno = ESTALE;
+ goto fail;
+ }
+
+ ret = inode_ctx_put2 (inode, frame->this,
+ stbuf.st_ino, stbuf.st_dev);
+ 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)
+ 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 stat statpre = {0, };
+ struct stat 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_stat (&rsp->statpre, &statpre);
+ gf_stat_to_stat (&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 stat statpre = {0, };
+ struct stat 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_stat (&rsp->statpre, &statpre);
+ gf_stat_to_stat (&rsp->statpost, &statpost);
+ }
+
+ STACK_UNWIND (frame, op_ret, op_errno, &statpre, &statpost);
+
+ return 0;
+}
+
+static dir_entry_t *
+gf_bin_to_direntry (char *buf, size_t count)
+{
+ int idx = 0;
+ int bread = 0;
+ size_t rcount = 0;
+ char *ender = NULL;
+ char *buffer = NULL;
+ char tmp_buf[512] = {0,};
+ dir_entry_t *trav = NULL;
+ dir_entry_t *prev = NULL;
+ dir_entry_t *thead = NULL;
+ dir_entry_t *head = NULL;
+
+ thead = CALLOC (1, sizeof (dir_entry_t));
+ GF_VALIDATE_OR_GOTO ("client-protocol", thead, fail);
+
+ buffer = buf;
+ prev = thead;
+
+ for (idx = 0; idx < count ; idx++) {
+ bread = 0;
+ trav = CALLOC (1, sizeof (dir_entry_t));
+ GF_VALIDATE_OR_GOTO ("client-protocol", trav, fail);
+
+ ender = strchr (buffer, '/');
+ if (!ender)
+ break;
+ rcount = ender - buffer;
+ trav->name = CALLOC (1, rcount + 2);
+ GF_VALIDATE_OR_GOTO ("client-protocol", trav->name, fail);
+
+ strncpy (trav->name, buffer, rcount);
+ bread = rcount + 1;
+ buffer += bread;
+
+ ender = strchr (buffer, '\n');
+ if (!ender)
+ break;
+ rcount = ender - buffer;
+ strncpy (tmp_buf, buffer, rcount);
+ bread = rcount + 1;
+ buffer += bread;
+
+ gf_string_to_stat (tmp_buf, &trav->buf);
+
+ ender = strchr (buffer, '\n');
+ if (!ender)
+ break;
+ rcount = ender - buffer;
+ *ender = '\0';
+ if (S_ISLNK (trav->buf.st_mode))
+ trav->link = strdup (buffer);
+ else
+ trav->link = "";
+
+ bread = rcount + 1;
+ buffer += bread;
+
+ prev->next = trav;
+ prev = trav;
+ }
+
+ head = thead;
+fail:
+ return head;
+}
+
+
+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;
+ FREE (trav->name);
+ if (S_ISLNK (trav->buf.st_mode))
+ FREE (trav->link);
+ FREE (trav);
+ trav = prev->next;
+ }
+ FREE (head);
+fail:
+ return 0;
+}
+
+/*
+ * client_getdents_cbk - readdir callback for client protocol
+ * @frame: call frame
+ * @args: argument dictionary
+ *
+ * not for external reference
+ */
+
+int
+client_getdents_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen,
+ struct iobuf *iobuf)
+{
+ gf_fop_getdents_rsp_t *rsp = NULL;
+ int32_t op_ret = 0;
+ int32_t op_errno = 0;
+ int32_t gf_errno = 0;
+ int32_t nr_count = 0;
+ dir_entry_t *entry = 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) {
+ nr_count = ntoh32 (rsp->count);
+ entry = gf_bin_to_direntry(iobuf->ptr, nr_count);
+ if (entry == NULL) {
+ op_ret = -1;
+ op_errno = EINVAL;
+ }
+ }
+
+ STACK_UNWIND (frame, op_ret, op_errno, entry, nr_count);
+
+ if (iobuf)
+ iobuf_unref (iobuf);
+ if (entry)
+ gf_free_direntry(entry);
+
+ 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)
+ 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 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_writedir_cbk -
+ *
+ * @frame:
+ * @args:
+ *
+ * not for external reference
+ */
+
+int
+client_setdents_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_stats_cbk - stats callback for client protocol
+ *
+ * @frame: call frame
+ * @args: argument dictionary
+ *
+ * not for external reference
+ */
+
+int
+client_stats_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen,
+ struct iobuf *iobuf)
+{
+ struct xlator_stats stats = {0,};
+ gf_mop_stats_rsp_t *rsp = NULL;
+ char *buffer = 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)
+ {
+ buffer = rsp->buf;
+
+ sscanf (buffer, "%"SCNx64",%"SCNx64",%"SCNx64",%"SCNx64
+ ",%"SCNx64",%"SCNx64",%"SCNx64",%"SCNx64"\n",
+ &stats.nr_files, &stats.disk_usage, &stats.free_disk,
+ &stats.total_disk_size, &stats.read_usage,
+ &stats.write_usage, &stats.disk_speed,
+ &stats.nr_clients);
+ }
+
+ STACK_UNWIND (frame, op_ret, op_errno, &stats);
+ 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)
+ 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_log (call_frame_t *frame, xlator_t *this, const char *msg)
+{
+ gf_hdr_common_t * hdr = NULL;
+ gf_mop_log_req_t * req = NULL;
+ size_t hdrlen = -1;
+ int msglen = 0;
+ int ret = -1;
+
+ if (msg)
+ msglen = STRLEN_0 (msg);
+
+ hdrlen = gf_hdr_len (req, msglen);
+ hdr = gf_hdr_new (req, msglen);
+
+ GF_VALIDATE_OR_GOTO (this->name, hdr, unwind);
+
+ req = gf_param (hdr);
+ req->msglen = hton32 (msglen);
+
+ if (msglen)
+ strcpy (req->msg, msg);
+
+ ret = protocol_client_xfer (frame, this,
+ CLIENT_CHANNEL (this, CHANNEL_BULK),
+ GF_OP_TYPE_MOP_REQUEST, GF_MOP_LOG,
+ hdr, hdrlen, NULL, 0, NULL);
+
+ return ret;
+
+unwind:
+ if (hdr)
+ free (hdr);
+
+ STACK_UNWIND (frame, -1, EINVAL, NULL);
+ return 0;
+}
+
+
+int
+client_log_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen,
+ struct iobuf *iobuf)
+{
+ gf_mop_log_rsp_t * rsp = 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);
+
+ STACK_UNWIND (frame, op_ret, op_errno);
+
+ return 0;
+}
+
+
+int
+client_checksum (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flag)
+{
+ gf_hdr_common_t *hdr = NULL;
+ gf_fop_checksum_req_t *req = NULL;
+ size_t hdrlen = -1;
+ int ret = -1;
+ ino_t ino = 0;
+ uint64_t gen = 0;
+
+ hdrlen = gf_hdr_len (req, strlen (loc->path) + 1);
+ hdr = gf_hdr_new (req, strlen (loc->path) + 1);
+ req = gf_param (hdr);
+
+ ret = inode_ctx_get2 (loc->inode, this, &ino, &gen);
+ if (loc->inode->ino && ret < 0) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "CHECKSUM %"PRId64" (%s): "
+ "failed to get remote inode number",
+ loc->inode->ino, loc->path);
+ STACK_UNWIND (frame, -1, EINVAL, NULL, NULL);
+ return 0;
+ }
+
+ req->ino = hton64 (ino);
+ req->gen = hton64 (gen);
+ req->flag = hton32 (flag);
+ strcpy (req->path, loc->path);
+
+ ret = protocol_client_xfer (frame, this,
+ CLIENT_CHANNEL (this, CHANNEL_BULK),
+ GF_OP_TYPE_FOP_REQUEST, GF_FOP_CHECKSUM,
+ hdr, hdrlen, NULL, 0, NULL);
+
+ return ret;
+}
+
+
+int
+client_checksum_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen,
+ struct iobuf *iobuf)
+{
+ gf_fop_checksum_rsp_t *rsp = NULL;
+ int32_t op_ret = 0;
+ int32_t op_errno = 0;
+ int32_t gf_errno = 0;
+ unsigned char *fchecksum = NULL;
+ unsigned char *dchecksum = 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) {
+ fchecksum = rsp->fchecksum;
+ dchecksum = rsp->dchecksum + NAME_MAX;
+ }
+
+ STACK_UNWIND (frame, op_ret, op_errno, fchecksum, dchecksum);
+ 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_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 = calloc (1, sizeof (*local));
+ 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_FOP_OPENDIR,
+ hdr, hdrlen, NULL, 0, NULL);
+
+ return ret;
+
+out:
+ if (frame)
+ STACK_DESTROY (frame->root);
+
+ if (local)
+ client_local_wipe (local);
+
+ if (path)
+ 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 = calloc (1, sizeof (*local));
+ 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_FOP_OPEN,
+ hdr, hdrlen, NULL, 0, NULL);
+
+ return ret;
+
+out:
+ if (frame)
+ STACK_DESTROY (frame->root);
+
+ if (local)
+ client_local_wipe (local);
+
+ if (path)
+ 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_NORMAL,
+ "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 = 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);
+
+ 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;
+}
+
+
+static gf_op_t gf_fops[] = {
+ [GF_FOP_STAT] = client_stat_cbk,
+ [GF_FOP_READLINK] = client_readlink_cbk,
+ [GF_FOP_MKNOD] = client_mknod_cbk,
+ [GF_FOP_MKDIR] = client_mkdir_cbk,
+ [GF_FOP_UNLINK] = client_unlink_cbk,
+ [GF_FOP_RMDIR] = client_rmdir_cbk,
+ [GF_FOP_SYMLINK] = client_symlink_cbk,
+ [GF_FOP_RENAME] = client_rename_cbk,
+ [GF_FOP_LINK] = client_link_cbk,
+ [GF_FOP_TRUNCATE] = client_truncate_cbk,
+ [GF_FOP_OPEN] = client_open_cbk,
+ [GF_FOP_READ] = client_readv_cbk,
+ [GF_FOP_WRITE] = client_write_cbk,
+ [GF_FOP_STATFS] = client_statfs_cbk,
+ [GF_FOP_FLUSH] = client_flush_cbk,
+ [GF_FOP_FSYNC] = client_fsync_cbk,
+ [GF_FOP_SETXATTR] = client_setxattr_cbk,
+ [GF_FOP_GETXATTR] = client_getxattr_cbk,
+ [GF_FOP_REMOVEXATTR] = client_removexattr_cbk,
+ [GF_FOP_OPENDIR] = client_opendir_cbk,
+ [GF_FOP_GETDENTS] = client_getdents_cbk,
+ [GF_FOP_FSYNCDIR] = client_fsyncdir_cbk,
+ [GF_FOP_ACCESS] = client_access_cbk,
+ [GF_FOP_CREATE] = client_create_cbk,
+ [GF_FOP_FTRUNCATE] = client_ftruncate_cbk,
+ [GF_FOP_FSTAT] = client_fstat_cbk,
+ [GF_FOP_LK] = client_lk_common_cbk,
+ [GF_FOP_LOOKUP] = client_lookup_cbk,
+ [GF_FOP_SETDENTS] = client_setdents_cbk,
+ [GF_FOP_READDIR] = client_readdir_cbk,
+ [GF_FOP_READDIRP] = client_readdirp_cbk,
+ [GF_FOP_INODELK] = client_inodelk_cbk,
+ [GF_FOP_FINODELK] = client_finodelk_cbk,
+ [GF_FOP_ENTRYLK] = client_entrylk_cbk,
+ [GF_FOP_FENTRYLK] = client_fentrylk_cbk,
+ [GF_FOP_CHECKSUM] = client_checksum_cbk,
+ [GF_FOP_RCHECKSUM] = client_rchecksum_cbk,
+ [GF_FOP_XATTROP] = client_xattrop_cbk,
+ [GF_FOP_FXATTROP] = client_fxattrop_cbk,
+ [GF_FOP_SETATTR] = client_setattr_cbk,
+ [GF_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_STATS] = client_stats_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_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;
+}
+
+/*
+ * 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 = CALLOC (1, sizeof (client_conf_t));
+
+ 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 (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 = CALLOC (1, sizeof (*conn));
+
+ conn->saved_frames = 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) {
+ 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 = 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->ctx->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)
+ 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 */
+ 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 = -1;
+ 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,
+ .setdents = client_setdents,
+ .getdents = client_getdents,
+ .checksum = client_checksum,
+ .rchecksum = client_rchecksum,
+ .xattrop = client_xattrop,
+ .fxattrop = client_fxattrop,
+ .setattr = client_setattr,
+ .fsetattr = client_fsetattr,
+};
+
+struct xlator_mops mops = {
+ .stats = client_stats,
+ .getspec = client_getspec,
+ .log = client_log,
+};
+
+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/client/src/client-protocol.h b/xlators/protocol/client/src/client-protocol.h
new file mode 100644
index 00000000000..27348690296
--- /dev/null
+++ b/xlators/protocol/client/src/client-protocol.h
@@ -0,0 +1,178 @@
+/*
+ Copyright (c) 2006-2009 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 _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 stat *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->st_dev = dev;
+ stbuf->st_ino = ino;
+ stbuf->st_mode = mode;
+ stbuf->st_nlink = nlink;
+ stbuf->st_uid = uid;
+ stbuf->st_gid = gid;
+ stbuf->st_rdev = rdev;
+ stbuf->st_size = size;
+ stbuf->st_blksize = blksize;
+ stbuf->st_blocks = blocks;
+
+ stbuf->st_atime = atime;
+ stbuf->st_mtime = mtime;
+ stbuf->st_ctime = ctime;
+
+ ST_ATIM_NSEC_SET(stbuf, atime_nsec);
+ ST_MTIM_NSEC_SET(stbuf, mtime_nsec);
+ ST_CTIM_NSEC_SET(stbuf, ctime_nsec);
+
+}
+
+#endif
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 8391c121f27..00000000000
--- a/xlators/protocol/client/src/client-rpc-fops.c
+++ /dev/null
@@ -1,6210 +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 "rpc-common-xdr.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);
-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;
- struct iobref *new_iobref = NULL;
- ssize_t xdr_size = 0;
- struct rpc_req rpcreq = {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 (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->loc.path, 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",
- strerror (gf_error_to_errno (rsp.op_errno)),
- local->loc.path);
- }
-
- 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",
- strerror (gf_error_to_errno (rsp.op_errno)),
- local->loc.path);
- }
-
- 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;
- fdctx->reopen_done = client_default_reopen_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, fop_log_level (GF_FOP_OPEN,
- gf_error_to_errno (rsp.op_errno)),
- "remote operation failed: %s. Path: %s (%s)",
- strerror (gf_error_to_errno (rsp.op_errno)),
- local->loc.path, loc_gfid_utoa (&local->loc));
- }
-
- 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_error_to_errno(rsp.op_errno) == ENOENT)?
- GF_LOG_DEBUG: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_error_to_errno (rsp.op_errno) == ENOENT)
- ? GF_LOG_DEBUG : 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;
- clnt_local_t *local = 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_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)));
- } else if (rsp.op_ret >= 0) {
- if (local->attempt_reopen)
- client_attempt_reopen (local->fd, this);
- }
- 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, fop_log_level (GF_FOP_FLUSH,
- gf_error_to_errno (rsp.op_errno)),
- "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) ||
- (op_errno == ESTALE) ||
- (op_errno == ENOENT)) ?
- GF_LOG_DEBUG : GF_LOG_WARNING),
- "remote operation failed: %s. Path: %s (%s). Key: %s",
- strerror (op_errno),
- local->loc.path, loc_gfid_utoa (&local->loc),
- (local->name) ? 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;
- gf_loglevel_t loglevel = GF_LOG_NONE;
-
- 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) {
- if ((ENODATA == rsp.op_errno) || (ENOATTR == rsp.op_errno))
- loglevel = GF_LOG_DEBUG;
- else
- loglevel = GF_LOG_WARNING;
-
- gf_log (this->name, loglevel, "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) {
- gf_log (this->name, fop_log_level (GF_FOP_INODELK,
- gf_error_to_errno (rsp.op_errno)),
- "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;
- clnt_local_t *local = NULL;
-
-
- frame = myframe;
- this = frame->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;
- }
-
- 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, fop_log_level (GF_FOP_FINODELK,
- gf_error_to_errno (rsp.op_errno)),
- "remote operation failed: %s",
- strerror (gf_error_to_errno (rsp.op_errno)));
- } else if (rsp.op_ret == 0) {
- if (local->attempt_reopen)
- client_attempt_reopen (local->fd, this);
- }
- 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) {
- gf_log (this->name, fop_log_level (GF_FOP_ENTRYLK,
- gf_error_to_errno (rsp.op_errno)),
- "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->loc.path, loc_gfid_utoa (&local->loc));
- }
-
- 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)));
- } else if (rsp.op_ret == 0) {
- if (local->attempt_reopen)
- client_attempt_reopen (local->fd, this);
- }
- 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_fallocate_cbk (struct rpc_req *req, struct iovec *iov, int count,
- void *myframe)
-{
- call_frame_t *frame = NULL;
- gfs3_fallocate_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_fallocate_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 (fallocate, 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_discard_cbk(struct rpc_req *req, struct iovec *iov, int count,
- void *myframe)
-{
- call_frame_t *frame = NULL;
- gfs3_discard_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_discard_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 (discard, 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_zerofill_cbk(struct rpc_req *req, struct iovec *iov, int count,
- void *myframe)
-{
- call_frame_t *frame = NULL;
- gfs3_zerofill_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_zerofill_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 (zerofill, 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",
- strerror (gf_error_to_errno (rsp.op_errno)),
- local->loc.path);
- }
-
- 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->loc.path, local->loc2.path);
- }
-
- 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, fop_log_level (GF_FOP_OPENDIR,
- gf_error_to_errno (rsp.op_errno)),
- "remote operation failed: %s. Path: %s (%s)",
- strerror (gf_error_to_errno (rsp.op_errno)),
- local->loc.path, loc_gfid_utoa (&local->loc));
- }
- 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;
- if (xdata)
- ret = dict_set_int32 (xdata, "gfid-changed", 1);
-
- goto out;
- }
-
- rsp.op_ret = 0;
-
-out:
- rsp.op_errno = op_errno;
- if (rsp.op_ret == -1) {
- /* any error other than ENOENT */
- if (!(local->loc.name && rsp.op_errno == ENOENT) &&
- !(rsp.op_errno == ESTALE))
- gf_log (this->name, GF_LOG_WARNING,
- "remote operation failed: %s. Path: %s (%s)",
- strerror (rsp.op_errno), local->loc.path,
- loc_gfid_utoa (&local->loc));
- 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)));
- } else if (rsp.op_ret >= 0) {
- if (local->attempt_reopen)
- client_attempt_reopen (local->fd, this);
- }
- 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_TRACE, "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_TRACE, "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;
- }
- frame->local = local;
-
- if (!(args->loc && args->loc->inode))
- goto unwind;
-
- loc_copy (&local->loc, args->loc);
- loc_path (&local->loc, NULL);
-
- 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 (this, args->fd, DEFAULT_REMOTE_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);
- loc_path (&local->loc, NULL);
-
- 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_path (&local->loc, NULL);
- loc_copy (&local->loc2, args->newloc);
- loc_path (&local->loc2, NULL);
- 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;
- }
- frame->local = local;
-
- if (!(args->loc && args->loc->parent))
- goto unwind;
-
- loc_copy (&local->loc, args->loc);
- loc_path (&local->loc, NULL);
-
- 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;
- }
- frame->local = local;
-
- if (!(args->loc && args->loc->parent))
- goto unwind;
-
- loc_copy (&local->loc, args->loc);
- loc_path (&local->loc, NULL);
-
- 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;
- }
- frame->local = local;
-
- if (!(args->loc && args->loc->parent))
- goto unwind;
-
- local->fd = fd_ref (args->fd);
- local->flags = args->flags;
-
- loc_copy (&local->loc, args->loc);
- loc_path (&local->loc, NULL);
-
- 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;
- }
- frame->local = local;
-
- if (!(args->loc && args->loc->inode))
- goto unwind;
-
- local->fd = fd_ref (args->fd);
- local->flags = args->flags;
- loc_copy (&local->loc, args->loc);
- loc_path (&local->loc, 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);
- 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;
- clnt_local_t *local = 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;
-
- if (!frame || !this || !data)
- goto unwind;
-
- args = data;
- conf = this->private;
-
- CLIENT_GET_REMOTE_FD (this, args->fd, FALLBACK_TO_ANON_FD,
- remote_fd, op_errno, unwind);
- ret = client_fd_fop_prepare_local (frame, args->fd, remote_fd);
- if (ret) {
- op_errno = -ret;
- goto unwind;
- }
- local = frame->local;
-
- 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->iobref = rsp_iobref;
- rsp_iobref = NULL;
-
- 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) {
- //unwind is done in the cbk
- gf_log (this->name, GF_LOG_WARNING, "failed to send the fop");
- }
-
- GF_FREE (req.xdata.xdata_val);
-
- 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 (this, args->fd, FALLBACK_TO_ANON_FD,
- remote_fd, op_errno, unwind);
- ret = client_fd_fop_prepare_local (frame, args->fd, remote_fd);
- if (ret) {
- op_errno = -ret;
- goto 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 (this, args->fd, DEFAULT_REMOTE_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 (this, args->fd, DEFAULT_REMOTE_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 (this, args->fd, DEFAULT_REMOTE_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;
- }
- frame->local = local;
-
- if (!(args->loc && args->loc->inode))
- goto unwind;
-
- local->fd = fd_ref (args->fd);
- loc_copy (&local->loc, args->loc);
- loc_path (&local->loc, 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);
-
- 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 (this, args->fd, DEFAULT_REMOTE_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 (this, args->fd, DEFAULT_REMOTE_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 (this, args->fd, DEFAULT_REMOTE_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);
- loc_path (&local->loc, NULL);
- 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);
-
- loc_copy (&local->loc, args->loc);
- loc_path (&local->loc, NULL);
- 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;
- clnt_local_t *local = NULL;
- gfs3_fxattrop_req req = {{0,},};
- 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}, };
-
- if (!frame || !this || !data)
- goto unwind;
-
- args = data;
- conf = this->private;
-
- CLIENT_GET_REMOTE_FD (this, args->fd, FALLBACK_TO_ANON_FD,
- remote_fd, op_errno, unwind);
- ret = client_fd_fop_prepare_local (frame, args->fd, remote_fd);
- if (ret) {
- op_errno = -ret;
- goto unwind;
- }
-
- local = frame->local;
-
- req.fd = remote_fd;
- req.flags = args->flags;
- memcpy (req.gfid, args->fd->inode->gfid, 16);
-
- 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);
-
- 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 (this, args->fd, DEFAULT_REMOTE_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;
- }
- frame->local = local;
-
- CLIENT_GET_REMOTE_FD (this, args->fd, DEFAULT_REMOTE_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);
-
- 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 (this, args->fd, FALLBACK_TO_ANON_FD,
- remote_fd, op_errno, unwind);
- ret = client_fd_fop_prepare_local (frame, args->fd, remote_fd);
- if (ret) {
- op_errno = -ret;
- 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 = 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 (this, args->fd, DEFAULT_REMOTE_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 (this, args->fd, DEFAULT_REMOTE_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 (this, args->fd, DEFAULT_REMOTE_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 (this, args->fd, DEFAULT_REMOTE_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 (this, args->fd, DEFAULT_REMOTE_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;
-}
-
-int32_t
-client3_3_fallocate(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_fallocate_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 (this, args->fd, DEFAULT_REMOTE_FD,
- remote_fd, op_errno, unwind);
-
- req.fd = remote_fd;
- req.flags = args->flags;
- req.offset = args->offset;
- req.size = args->size;
- 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_FALLOCATE,
- client3_3_fallocate_cbk, NULL,
- NULL, 0, NULL, 0,
- NULL, (xdrproc_t)xdr_gfs3_fallocate_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 (fallocate, frame, -1, op_errno, NULL, NULL, NULL);
- GF_FREE (req.xdata.xdata_val);
-
- return 0;
-}
-
-int32_t
-client3_3_discard(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_discard_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 (this, args->fd, DEFAULT_REMOTE_FD,
- remote_fd, op_errno, unwind);
-
- req.fd = remote_fd;
- req.offset = args->offset;
- req.size = args->size;
- 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_DISCARD, client3_3_discard_cbk,
- NULL, NULL, 0, NULL, 0, NULL,
- (xdrproc_t) xdr_gfs3_discard_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(discard, frame, -1, op_errno, NULL, NULL, NULL);
- GF_FREE (req.xdata.xdata_val);
-
- return 0;
-}
-
-int32_t
-client3_3_zerofill(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_zerofill_req req = {{0},};
- int op_errno = ESTALE;
- int ret = 0;
-
- GF_ASSERT (frame);
-
- if (!this || !data)
- goto unwind;
-
- args = data;
- conf = this->private;
-
- CLIENT_GET_REMOTE_FD (this, args->fd, DEFAULT_REMOTE_FD,
- remote_fd, op_errno, unwind);
-
- req.fd = remote_fd;
- req.offset = args->offset;
- req.size = args->size;
- 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_ZEROFILL, client3_3_zerofill_cbk,
- NULL, NULL, 0, NULL, 0, NULL,
- (xdrproc_t) xdr_gfs3_zerofill_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(zerofill, 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_FALLOCATE] = { "FALLOCATE", client3_3_fallocate },
- [GF_FOP_DISCARD] = { "DISCARD", client3_3_discard },
- [GF_FOP_ZEROFILL] = { "ZEROFILL", client3_3_zerofill},
- [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",
- [GFS3_OP_FALLOCATE] = "FALLOCATE",
- [GFS3_OP_DISCARD] = "DISCARD",
- [GFS3_OP_ZEROFILL] = "ZEROFILL",
-
-};
-
-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
deleted file mode 100644
index 25565925a5d..00000000000
--- a/xlators/protocol/client/src/client.c
+++ /dev/null
@@ -1,2930 +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 "xlator.h"
-#include "defaults.h"
-#include "glusterfs.h"
-#include "statedump.h"
-#include "compat-errno.h"
-
-#include "xdr-rpc.h"
-#include "glusterfs3.h"
-
-extern rpc_clnt_prog_t clnt_handshake_prog;
-extern rpc_clnt_prog_t clnt_dump_prog;
-extern struct rpcclnt_cb_program gluster_cbk_prog;
-
-int client_handshake (xlator_t *this, struct rpc_clnt *rpc);
-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_ts,
- 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;
- struct iobref *new_iobref = NULL;
- ssize_t xdr_size = 0;
- struct rpc_req rpcreq = {0, };
- uint64_t ngroups = 0;
- uint64_t gid = 0;
-
- GF_VALIDATE_OR_GOTO ("client", this, out);
- GF_VALIDATE_OR_GOTO (this->name, prog, out);
- GF_VALIDATE_OR_GOTO (this->name, frame, out);
-
- conf = this->private;
-
- /* If 'setvolume' is not successful, we should not send frames to
- server, mean time we should be able to send 'DUMP' and 'SETVOLUME'
- call itself even if its not connected */
- if (!(conf->connected ||
- ((prog->prognum == GLUSTER_DUMP_PROGRAM) ||
- (prog->prognum == GLUSTER_PMAP_PROGRAM) ||
- ((prog->prognum == GLUSTER_HNDSK_PROGRAM) &&
- (procnum == GF_HNDSK_SETVOLUME))))) {
- /* This particular error captured/logged in
- functions calling this */
- gf_log (this->name, GF_LOG_DEBUG,
- "connection in disconnected state");
- 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;
- }
-
- 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 out;
- }
-
- 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) {
- /* callingfn so that, we can get to know which xdr
- function was called */
- gf_log_callingfn (this->name, GF_LOG_WARNING,
- "XDR payload creation failed");
- goto out;
- }
- iov.iov_len = ret;
- count = 1;
- }
-
- /* do not send all groups if they are resolved server-side */
- if (!conf->send_gids) {
- /* copy some values for restoring later */
- ngroups = frame->root->ngrps;
- frame->root->ngrps = 1;
- if (ngroups <= SMALL_GROUP_COUNT) {
- gid = frame->root->groups_small[0];
- frame->root->groups_small[0] = frame->root->gid;
- frame->root->groups = frame->root->groups_small;
- }
- }
-
- /* Send the msg */
- ret = rpc_clnt_submit (conf->rpc, prog, procnum, cbkfn, &iov, count,
- NULL, 0, new_iobref, frame, rsphdr, rsphdr_count,
- rsp_payload, rsp_payload_count, rsp_iobref);
-
- if (ret < 0) {
- gf_log (this->name, GF_LOG_DEBUG, "rpc_clnt_submit failed");
- }
-
- if (!conf->send_gids) {
- /* restore previous values */
- frame->root->ngrps = ngroups;
- if (ngroups <= SMALL_GROUP_COUNT)
- frame->root->groups_small[0] = gid;
- }
-
- 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)
- iobref_unref (new_iobref);
-
- if (iobuf)
- iobuf_unref (iobuf);
-
- return 0;
-}
-
-
-int32_t
-client_forget (xlator_t *this, inode_t *inode)
-{
- /* Nothing here */
- return 0;
-}
-
-int32_t
-client_releasedir (xlator_t *this, fd_t *fd)
-{
- 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.fd = fd;
-
- proc = &conf->fops->proctable[GF_FOP_RELEASEDIR];
- if (!proc) {
- gf_log (this->name, GF_LOG_ERROR,
- "rpc procedure not found for %s",
- gf_fop_list[GF_FOP_RELEASEDIR]);
- goto out;
- }
- if (proc->fn) {
- ret = proc->fn (NULL, this, &args);
- }
-out:
- if (ret)
- gf_log (this->name, GF_LOG_WARNING,
- "releasedir fop failed");
- return 0;
-}
-
-int32_t
-client_release (xlator_t *this, fd_t *fd)
-{
- 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.fd = fd;
- proc = &conf->fops->proctable[GF_FOP_RELEASE];
- if (!proc) {
- gf_log (this->name, GF_LOG_ERROR,
- "rpc procedure not found for %s",
- gf_fop_list[GF_FOP_RELEASE]);
- goto out;
- }
- if (proc->fn) {
- ret = proc->fn (NULL, this, &args);
- }
-out:
- if (ret)
- gf_log (this->name, GF_LOG_WARNING,
- "release fop failed");
- return 0;
-}
-
-
-int32_t
-client_lookup (call_frame_t *frame, xlator_t *this, loc_t *loc,
- 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.loc = loc;
- args.xdata = xdata;
-
- proc = &conf->fops->proctable[GF_FOP_LOOKUP];
- if (!proc) {
- gf_log (this->name, GF_LOG_ERROR,
- "rpc procedure not found for %s",
- gf_fop_list[GF_FOP_LOOKUP]);
- goto out;
- }
- if (proc->fn)
- ret = proc->fn (frame, this, &args);
-out:
- /* think of avoiding a missing frame */
- if (ret)
- STACK_UNWIND_STRICT (lookup, frame, -1, ENOTCONN,
- NULL, NULL, NULL, NULL);
-
- return 0;
-}
-
-
-int32_t
-client_stat (call_frame_t *frame, xlator_t *this, loc_t *loc, 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.loc = loc;
- args.xdata = xdata;
-
- proc = &conf->fops->proctable[GF_FOP_STAT];
- if (!proc) {
- gf_log (this->name, GF_LOG_ERROR,
- "rpc procedure not found for %s",
- gf_fop_list[GF_FOP_STAT]);
- goto out;
- }
- if (proc->fn)
- ret = proc->fn (frame, this, &args);
-out:
- if (ret)
- STACK_UNWIND_STRICT (stat, frame, -1, ENOTCONN, NULL, NULL);
-
- return 0;
-}
-
-
-int32_t
-client_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc,
- off_t offset, 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.loc = loc;
- args.offset = offset;
- args.xdata = xdata;
-
- proc = &conf->fops->proctable[GF_FOP_TRUNCATE];
- if (!proc) {
- gf_log (this->name, GF_LOG_ERROR,
- "rpc procedure not found for %s",
- gf_fop_list[GF_FOP_TRUNCATE]);
- goto out;
- }
- if (proc->fn)
- ret = proc->fn (frame, this, &args);
-out:
- if (ret)
- STACK_UNWIND_STRICT (truncate, frame, -1, ENOTCONN, NULL, NULL, NULL);
-
-
- return 0;
-}
-
-
-int32_t
-client_ftruncate (call_frame_t *frame, xlator_t *this, fd_t *fd,
- off_t offset, 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.fd = fd;
- args.offset = offset;
- args.xdata = xdata;
-
- proc = &conf->fops->proctable[GF_FOP_FTRUNCATE];
- if (!proc) {
- gf_log (this->name, GF_LOG_ERROR,
- "rpc procedure not found for %s",
- gf_fop_list[GF_FOP_FTRUNCATE]);
- goto out;
- }
- if (proc->fn)
- ret = proc->fn (frame, this, &args);
-out:
- if (ret)
- STACK_UNWIND_STRICT (ftruncate, frame, -1, ENOTCONN, NULL, NULL, NULL);
-
- return 0;
-}
-
-
-
-int32_t
-client_access (call_frame_t *frame, xlator_t *this, loc_t *loc,
- int32_t mask, 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.loc = loc;
- args.mask = mask;
- args.xdata = xdata;
-
- proc = &conf->fops->proctable[GF_FOP_ACCESS];
- if (!proc) {
- gf_log (this->name, GF_LOG_ERROR,
- "rpc procedure not found for %s",
- gf_fop_list[GF_FOP_ACCESS]);
- goto out;
- }
- if (proc->fn)
- ret = proc->fn (frame, this, &args);
-out:
- if (ret)
- STACK_UNWIND_STRICT (access, frame, -1, ENOTCONN, NULL);
-
- return 0;
-}
-
-
-
-
-int32_t
-client_readlink (call_frame_t *frame, xlator_t *this, loc_t *loc,
- size_t size, 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.loc = loc;
- args.size = size;
- args.xdata = xdata;
-
- proc = &conf->fops->proctable[GF_FOP_READLINK];
- if (!proc) {
- gf_log (this->name, GF_LOG_ERROR,
- "rpc procedure not found for %s",
- gf_fop_list[GF_FOP_READLINK]);
- goto out;
- }
- if (proc->fn)
- ret = proc->fn (frame, this, &args);
-out:
- if (ret)
- STACK_UNWIND_STRICT (readlink, frame, -1, ENOTCONN, NULL, NULL, NULL);
-
- return 0;
-}
-
-
-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)
-{
- 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.loc = loc;
- args.mode = mode;
- args.rdev = rdev;
- args.umask = umask;
- args.xdata = xdata;
-
- proc = &conf->fops->proctable[GF_FOP_MKNOD];
- if (!proc) {
- gf_log (this->name, GF_LOG_ERROR,
- "rpc procedure not found for %s",
- gf_fop_list[GF_FOP_MKNOD]);
- goto out;
- }
- if (proc->fn)
- ret = proc->fn (frame, this, &args);
-out:
- if (ret)
- STACK_UNWIND_STRICT (mknod, frame, -1, ENOTCONN,
- NULL, NULL, NULL, NULL, NULL);
-
- return 0;
-}
-
-
-int
-client_mkdir (call_frame_t *frame, xlator_t *this, loc_t *loc,
- mode_t mode, mode_t umask, 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.loc = loc;
- args.mode = mode;
- args.umask = umask;
- args.xdata = xdata;
-
- proc = &conf->fops->proctable[GF_FOP_MKDIR];
- if (!proc) {
- gf_log (this->name, GF_LOG_ERROR,
- "rpc procedure not found for %s",
- gf_fop_list[GF_FOP_MKDIR]);
- goto out;
- }
- if (proc->fn)
- ret = proc->fn (frame, this, &args);
-out:
- if (ret)
- STACK_UNWIND_STRICT (mkdir, frame, -1, ENOTCONN,
- NULL, NULL, NULL, NULL, NULL);
-
- return 0;
-}
-
-
-
-int32_t
-client_unlink (call_frame_t *frame, xlator_t *this, loc_t *loc,
- int xflag, 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.loc = loc;
- args.xdata = xdata;
- args.flags = xflag;
-
- proc = &conf->fops->proctable[GF_FOP_UNLINK];
- if (!proc) {
- gf_log (this->name, GF_LOG_ERROR,
- "rpc procedure not found for %s",
- gf_fop_list[GF_FOP_UNLINK]);
- goto out;
- }
- if (proc->fn)
- ret = proc->fn (frame, this, &args);
-out:
- if (ret)
- STACK_UNWIND_STRICT (unlink, frame, -1, ENOTCONN,
- NULL, NULL, NULL);
-
- return 0;
-}
-
-int32_t
-client_rmdir (call_frame_t *frame, xlator_t *this, loc_t *loc, int flags,
- 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.loc = loc;
- args.flags = flags;
- args.xdata = xdata;
-
- proc = &conf->fops->proctable[GF_FOP_RMDIR];
- if (!proc) {
- gf_log (this->name, GF_LOG_ERROR,
- "rpc procedure not found for %s",
- gf_fop_list[GF_FOP_RMDIR]);
- goto out;
- }
- if (proc->fn)
- ret = proc->fn (frame, this, &args);
-out:
- /* think of avoiding a missing frame */
- if (ret)
- STACK_UNWIND_STRICT (rmdir, frame, -1, ENOTCONN,
- NULL, NULL, NULL);
-
- return 0;
-}
-
-
-int
-client_symlink (call_frame_t *frame, xlator_t *this, const char *linkpath,
- loc_t *loc, mode_t umask, 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.linkname = linkpath;
- args.loc = loc;
- args.umask = umask;
- args.xdata = xdata;
-
- proc = &conf->fops->proctable[GF_FOP_SYMLINK];
- if (!proc) {
- gf_log (this->name, GF_LOG_ERROR,
- "rpc procedure not found for %s",
- gf_fop_list[GF_FOP_SYMLINK]);
- goto out;
- }
- if (proc->fn)
- ret = proc->fn (frame, this, &args);
-out:
- if (ret)
- STACK_UNWIND_STRICT (symlink, frame, -1, ENOTCONN,
- NULL, NULL, NULL, NULL, NULL);
-
- return 0;
-}
-
-
-
-int32_t
-client_rename (call_frame_t *frame, xlator_t *this, loc_t *oldloc,
- loc_t *newloc, 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.oldloc = oldloc;
- args.newloc = newloc;
- args.xdata = xdata;
-
- proc = &conf->fops->proctable[GF_FOP_RENAME];
- if (!proc) {
- gf_log (this->name, GF_LOG_ERROR,
- "rpc procedure not found for %s",
- gf_fop_list[GF_FOP_RENAME]);
- goto out;
- }
- if (proc->fn)
- ret = proc->fn (frame, this, &args);
-out:
- if (ret)
- STACK_UNWIND_STRICT (rename, frame, -1, ENOTCONN,
- NULL, NULL, NULL, NULL, NULL, NULL);
-
- return 0;
-}
-
-
-
-int32_t
-client_link (call_frame_t *frame, xlator_t *this, loc_t *oldloc,
- loc_t *newloc, 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.oldloc = oldloc;
- args.newloc = newloc;
- args.xdata = xdata;
-
- proc = &conf->fops->proctable[GF_FOP_LINK];
- if (!proc) {
- gf_log (this->name, GF_LOG_ERROR,
- "rpc procedure not found for %s",
- gf_fop_list[GF_FOP_LINK]);
- goto out;
- }
- if (proc->fn)
- ret = proc->fn (frame, this, &args);
-out:
- if (ret)
- STACK_UNWIND_STRICT (link, frame, -1, ENOTCONN,
- NULL, NULL, NULL, NULL, NULL);
-
- return 0;
-}
-
-
-
-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)
-{
- 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.loc = loc;
- args.mode = mode;
- args.fd = fd;
- args.umask = umask;
- args.xdata = xdata;
-
- if (!conf->filter_o_direct)
- args.flags = flags;
- else
- args.flags = (flags & ~O_DIRECT);
-
- proc = &conf->fops->proctable[GF_FOP_CREATE];
- if (!proc) {
- gf_log (this->name, GF_LOG_ERROR,
- "rpc procedure not found for %s",
- gf_fop_list[GF_FOP_CREATE]);
- goto out;
- }
- if (proc->fn)
- ret = proc->fn (frame, this, &args);
-out:
- if (ret)
- STACK_UNWIND_STRICT (create, frame, -1, ENOTCONN,
- NULL, NULL, NULL, NULL, NULL, NULL);
-
- return 0;
-}
-
-
-
-int32_t
-client_open (call_frame_t *frame, xlator_t *this, loc_t *loc,
- int32_t flags, fd_t *fd, 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.loc = loc;
- args.fd = fd;
- args.xdata = xdata;
-
- if (!conf->filter_o_direct)
- args.flags = flags;
- else
- args.flags = (flags & ~O_DIRECT);
-
- proc = &conf->fops->proctable[GF_FOP_OPEN];
- if (!proc) {
- gf_log (this->name, GF_LOG_ERROR,
- "rpc procedure not found for %s",
- gf_fop_list[GF_FOP_OPEN]);
- goto out;
- }
- if (proc->fn)
- ret = proc->fn (frame, this, &args);
-
-out:
- if (ret)
- STACK_UNWIND_STRICT (open, frame, -1, ENOTCONN, NULL, NULL);
-
- return 0;
-}
-
-
-
-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)
-{
- 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.fd = fd;
- args.size = size;
- args.offset = offset;
- args.flags = flags;
- args.xdata = xdata;
-
- proc = &conf->fops->proctable[GF_FOP_READ];
- if (!proc) {
- gf_log (this->name, GF_LOG_ERROR,
- "rpc procedure not found for %s",
- gf_fop_list[GF_FOP_READ]);
- goto out;
- }
- if (proc->fn)
- ret = proc->fn (frame, this, &args);
-
-out:
- if (ret)
- STACK_UNWIND_STRICT (readv, frame, -1, ENOTCONN,
- NULL, 0, NULL, NULL, NULL);
-
- return 0;
-}
-
-
-
-
-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)
-{
- 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.fd = fd;
- args.vector = vector;
- args.count = count;
- args.offset = off;
- args.size = iov_length (vector, count);
- args.flags = flags;
- args.iobref = iobref;
- args.xdata = xdata;
-
- proc = &conf->fops->proctable[GF_FOP_WRITE];
- if (!proc) {
- gf_log (this->name, GF_LOG_ERROR,
- "rpc procedure not found for %s",
- gf_fop_list[GF_FOP_WRITE]);
- goto out;
- }
- if (proc->fn)
- ret = proc->fn (frame, this, &args);
-out:
- if (ret)
- STACK_UNWIND_STRICT (writev, frame, -1, ENOTCONN, NULL, NULL, NULL);
-
- return 0;
-}
-
-
-int32_t
-client_flush (call_frame_t *frame, xlator_t *this, fd_t *fd, 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.fd = fd;
- args.xdata = xdata;
-
- proc = &conf->fops->proctable[GF_FOP_FLUSH];
- if (!proc) {
- gf_log (this->name, GF_LOG_ERROR,
- "rpc procedure not found for %s",
- gf_fop_list[GF_FOP_FLUSH]);
- goto out;
- }
- if (proc->fn)
- ret = proc->fn (frame, this, &args);
-out:
- if (ret)
- STACK_UNWIND_STRICT (flush, frame, -1, ENOTCONN, NULL);
-
- return 0;
-}
-
-
-
-int32_t
-client_fsync (call_frame_t *frame, xlator_t *this, fd_t *fd,
- int32_t flags, 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.fd = fd;
- args.flags = flags;
- args.xdata = xdata;
-
- proc = &conf->fops->proctable[GF_FOP_FSYNC];
- if (!proc) {
- gf_log (this->name, GF_LOG_ERROR,
- "rpc procedure not found for %s",
- gf_fop_list[GF_FOP_FSYNC]);
- goto out;
- }
- if (proc->fn)
- ret = proc->fn (frame, this, &args);
-out:
- if (ret)
- STACK_UNWIND_STRICT (fsync, frame, -1, ENOTCONN, NULL, NULL, NULL);
-
- return 0;
-}
-
-
-
-int32_t
-client_fstat (call_frame_t *frame, xlator_t *this, fd_t *fd, 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.fd = fd;
- args.xdata = xdata;
-
- proc = &conf->fops->proctable[GF_FOP_FSTAT];
- if (!proc) {
- gf_log (this->name, GF_LOG_ERROR,
- "rpc procedure not found for %s",
- gf_fop_list[GF_FOP_FSTAT]);
- goto out;
- }
- if (proc->fn)
- ret = proc->fn (frame, this, &args);
-out:
- if (ret)
- STACK_UNWIND_STRICT (fstat, frame, -1, ENOTCONN, NULL, NULL);
-
- return 0;
-}
-
-
-
-int32_t
-client_opendir (call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd,
- 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.loc = loc;
- args.fd = fd;
- args.xdata = xdata;
-
- proc = &conf->fops->proctable[GF_FOP_OPENDIR];
- if (!proc) {
- gf_log (this->name, GF_LOG_ERROR,
- "rpc procedure not found for %s",
- gf_fop_list[GF_FOP_OPENDIR]);
- goto out;
- }
- if (proc->fn)
- ret = proc->fn (frame, this, &args);
-out:
- if (ret)
- STACK_UNWIND_STRICT (opendir, frame, -1, ENOTCONN, NULL, NULL);
-
- return 0;
-}
-
-
-
-int32_t
-client_fsyncdir (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags, 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.fd = fd;
- args.flags = flags;
- args.xdata = xdata;
-
- proc = &conf->fops->proctable[GF_FOP_FSYNCDIR];
- if (!proc) {
- gf_log (this->name, GF_LOG_ERROR,
- "rpc procedure not found for %s",
- gf_fop_list[GF_FOP_FSYNCDIR]);
- goto out;
- }
- if (proc->fn)
- ret = proc->fn (frame, this, &args);
-out:
- if (ret)
- STACK_UNWIND_STRICT (fsyncdir, frame, -1, ENOTCONN, NULL);
-
- return 0;
-}
-
-
-
-int32_t
-client_statfs (call_frame_t *frame, xlator_t *this, loc_t *loc, 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.loc = loc;
- args.xdata = xdata;
-
- proc = &conf->fops->proctable[GF_FOP_STATFS];
- if (!proc) {
- gf_log (this->name, GF_LOG_ERROR,
- "rpc procedure not found for %s",
- gf_fop_list[GF_FOP_STATFS]);
- goto out;
- }
- if (proc->fn)
- ret = proc->fn (frame, this, &args);
-out:
- if (ret)
- STACK_UNWIND_STRICT (statfs, frame, -1, ENOTCONN, NULL, NULL);
-
- return 0;
-}
-
-static gf_boolean_t
-is_client_rpc_init_command (dict_t *dict, xlator_t *this,
- char **value)
-{
- gf_boolean_t ret = _gf_false;
- int dict_ret = -1;
-
- if (!strstr (this->name, "replace-brick")) {
- gf_log (this->name, GF_LOG_TRACE, "name is !replace-brick");
- goto out;
- }
- dict_ret = dict_get_str (dict, CLIENT_CMD_CONNECT, value);
- if (dict_ret) {
- gf_log (this->name, GF_LOG_TRACE, "key %s not present",
- CLIENT_CMD_CONNECT);
- goto out;
- }
-
- ret = _gf_true;
-
-out:
- return ret;
-
-}
-
-static gf_boolean_t
-is_client_rpc_destroy_command (dict_t *dict, xlator_t *this)
-{
- gf_boolean_t ret = _gf_false;
- int dict_ret = -1;
- char *dummy = NULL;
-
- if (strncmp (this->name, "replace-brick", 13)) {
- gf_log (this->name, GF_LOG_TRACE, "name is !replace-brick");
- goto out;
- }
-
- dict_ret = dict_get_str (dict, CLIENT_CMD_DISCONNECT, &dummy);
- if (dict_ret) {
- gf_log (this->name, GF_LOG_TRACE, "key %s not present",
- CLIENT_CMD_DISCONNECT);
- goto out;
- }
-
- ret = _gf_true;
-
-out:
- return ret;
-
-}
-
-static gf_boolean_t
-client_set_remote_options (char *value, xlator_t *this)
-{
- char *dup_value = NULL;
- char *host = NULL;
- char *subvol = NULL;
- char *host_dup = NULL;
- char *subvol_dup = NULL;
- char *remote_port_str = NULL;
- char *tmp = NULL;
- int remote_port = 0;
- gf_boolean_t ret = _gf_false;
-
- dup_value = gf_strdup (value);
- host = strtok_r (dup_value, ":", &tmp);
- subvol = strtok_r (NULL, ":", &tmp);
- remote_port_str = strtok_r (NULL, ":", &tmp);
-
- if (!subvol) {
- gf_log (this->name, GF_LOG_WARNING,
- "proper value not passed as subvolume");
- goto out;
- }
-
- host_dup = gf_strdup (host);
- if (!host_dup) {
- goto out;
- }
-
- ret = dict_set_dynstr (this->options, "remote-host", host_dup);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING,
- "failed to set remote-host with %s", host);
- goto out;
- }
-
- subvol_dup = gf_strdup (subvol);
- if (!subvol_dup) {
- goto out;
- }
-
- ret = dict_set_dynstr (this->options, "remote-subvolume", subvol_dup);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING,
- "failed to set remote-host with %s", host);
- goto out;
- }
-
- remote_port = atoi (remote_port_str);
- GF_ASSERT (remote_port);
-
- ret = dict_set_int32 (this->options, "remote-port",
- remote_port);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "failed to set remote-port to %d", remote_port);
- goto out;
- }
-
- ret = _gf_true;
-out:
- GF_FREE (dup_value);
-
- return ret;
-}
-
-
-int32_t
-client_setxattr (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *dict,
- int32_t flags, dict_t *xdata)
-{
- int ret = -1;
- int op_ret = -1;
- int op_errno = ENOTCONN;
- int need_unwind = 0;
- clnt_conf_t *conf = NULL;
- rpc_clnt_procedure_t *proc = NULL;
- clnt_args_t args = {0,};
- char *value = NULL;
-
-
- if (is_client_rpc_init_command (dict, this, &value) == _gf_true) {
- 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);
- ret = client_init_rpc (this);
- }
-
- if (!ret) {
- op_ret = 0;
- op_errno = 0;
- }
- need_unwind = 1;
- goto out;
- }
-
- if (is_client_rpc_destroy_command (dict, this) == _gf_true) {
- gf_log (this->name, GF_LOG_INFO, "client rpc destroy command");
- ret = client_destroy_rpc (this);
- if (ret) {
- op_ret = 0;
- op_errno = 0;
- }
- need_unwind = 1;
- goto out;
- }
-
- conf = this->private;
- if (!conf || !conf->fops) {
- op_errno = ENOTCONN;
- need_unwind = 1;
- goto out;
- }
-
- args.loc = loc;
- args.xattr = dict;
- args.flags = flags;
- args.xdata = xdata;
-
- proc = &conf->fops->proctable[GF_FOP_SETXATTR];
- if (!proc) {
- gf_log (this->name, GF_LOG_ERROR,
- "rpc procedure not found for %s",
- gf_fop_list[GF_FOP_SETXATTR]);
- goto out;
- }
- if (proc->fn) {
- ret = proc->fn (frame, this, &args);
- if (ret) {
- need_unwind = 1;
- }
- }
-out:
- if (need_unwind)
- STACK_UNWIND_STRICT (setxattr, frame, op_ret, op_errno, NULL);
-
- return 0;
-}
-
-
-
-int32_t
-client_fsetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
- dict_t *dict, int32_t flags, 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.fd = fd;
- args.xattr = dict;
- args.flags = flags;
- args.xdata = xdata;
-
- proc = &conf->fops->proctable[GF_FOP_FSETXATTR];
- if (!proc) {
- gf_log (this->name, GF_LOG_ERROR,
- "rpc procedure not found for %s",
- gf_fop_list[GF_FOP_FSETXATTR]);
- goto out;
- }
- if (proc->fn)
- ret = proc->fn (frame, this, &args);
-out:
- if (ret)
- STACK_UNWIND_STRICT (fsetxattr, frame, -1, ENOTCONN, NULL);
-
- return 0;
-}
-
-
-
-
-int32_t
-client_fgetxattr (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.fd = fd;
- args.name = name;
- args.xdata = xdata;
-
- proc = &conf->fops->proctable[GF_FOP_FGETXATTR];
- if (!proc) {
- gf_log (this->name, GF_LOG_ERROR,
- "rpc procedure not found for %s",
- gf_fop_list[GF_FOP_FGETXATTR]);
- goto out;
- }
- if (proc->fn)
- ret = proc->fn (frame, this, &args);
-out:
- if (ret)
- STACK_UNWIND_STRICT (fgetxattr, frame, -1, ENOTCONN, NULL, NULL);
-
- return 0;
-}
-
-
-
-int32_t
-client_getxattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
- 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.loc = loc;
- args.xdata = xdata;
-
- proc = &conf->fops->proctable[GF_FOP_GETXATTR];
- if (!proc) {
- gf_log (this->name, GF_LOG_ERROR,
- "rpc procedure not found for %s",
- gf_fop_list[GF_FOP_GETXATTR]);
- goto out;
- }
- if (proc->fn)
- ret = proc->fn (frame, this, &args);
-out:
- if (ret)
- STACK_UNWIND_STRICT (getxattr, frame, -1, ENOTCONN, NULL, NULL);
-
- return 0;
-}
-
-
-
-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)
-{
- 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.loc = loc;
- args.flags = flags;
- args.xattr = dict;
- args.xdata = xdata;
-
- proc = &conf->fops->proctable[GF_FOP_XATTROP];
- if (!proc) {
- gf_log (this->name, GF_LOG_ERROR,
- "rpc procedure not found for %s",
- gf_fop_list[GF_FOP_XATTROP]);
- goto out;
- }
- if (proc->fn)
- ret = proc->fn (frame, this, &args);
-out:
- if (ret)
- STACK_UNWIND_STRICT (xattrop, frame, -1, ENOTCONN, NULL, NULL);
-
- return 0;
-}
-
-
-
-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)
-{
- 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.fd = fd;
- args.flags = flags;
- args.xattr = dict;
- args.xdata = xdata;
-
- proc = &conf->fops->proctable[GF_FOP_FXATTROP];
- if (!proc) {
- gf_log (this->name, GF_LOG_ERROR,
- "rpc procedure not found for %s",
- gf_fop_list[GF_FOP_FXATTROP]);
- goto out;
- }
- if (proc->fn)
- ret = proc->fn (frame, this, &args);
-out:
- if (ret)
- STACK_UNWIND_STRICT (fxattrop, frame, -1, ENOTCONN, NULL, NULL);
-
- return 0;
-}
-
-
-
-int32_t
-client_removexattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
- 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.loc = loc;
- args.xdata = xdata;
-
- proc = &conf->fops->proctable[GF_FOP_REMOVEXATTR];
- if (!proc) {
- gf_log (this->name, GF_LOG_ERROR,
- "rpc procedure not found for %s",
- gf_fop_list[GF_FOP_REMOVEXATTR]);
- goto out;
- }
- if (proc->fn)
- ret = proc->fn (frame, this, &args);
-out:
- if (ret)
- STACK_UNWIND_STRICT (removexattr, frame, -1, ENOTCONN, NULL);
-
- 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)
-{
- 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.fd = fd;
- args.cmd = cmd;
- args.flock = lock;
- args.xdata = xdata;
-
- proc = &conf->fops->proctable[GF_FOP_LK];
- if (!proc) {
- gf_log (this->name, GF_LOG_ERROR,
- "rpc procedure not found for %s",
- gf_fop_list[GF_FOP_LK]);
- goto out;
- }
- if (proc->fn)
- ret = proc->fn (frame, this, &args);
-out:
- if (ret)
- STACK_UNWIND_STRICT (lk, frame, -1, ENOTCONN, NULL, NULL);
-
- return 0;
-}
-
-
-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)
-{
- 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.loc = loc;
- args.cmd = cmd;
- args.flock = lock;
- args.volume = volume;
- args.xdata = xdata;
-
- proc = &conf->fops->proctable[GF_FOP_INODELK];
- if (!proc) {
- gf_log (this->name, GF_LOG_ERROR,
- "rpc procedure not found for %s",
- gf_fop_list[GF_FOP_INODELK]);
- goto out;
- }
- if (proc->fn)
- ret = proc->fn (frame, this, &args);
-out:
- if (ret)
- STACK_UNWIND_STRICT (inodelk, frame, -1, ENOTCONN, NULL);
-
- return 0;
-}
-
-
-
-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)
-{
- 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.fd = fd;
- args.cmd = cmd;
- args.flock = lock;
- args.volume = volume;
- args.xdata = xdata;
-
- proc = &conf->fops->proctable[GF_FOP_FINODELK];
- if (!proc) {
- gf_log (this->name, GF_LOG_ERROR,
- "rpc procedure not found for %s",
- gf_fop_list[GF_FOP_FINODELK]);
- goto out;
- }
- if (proc->fn)
- ret = proc->fn (frame, this, &args);
-out:
- if (ret)
- STACK_UNWIND_STRICT (finodelk, frame, -1, ENOTCONN, NULL);
-
- return 0;
-}
-
-
-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)
-{
- 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.loc = loc;
- args.basename = basename;
- args.type = type;
- args.volume = volume;
- args.cmd_entrylk = cmd;
- args.xdata = xdata;
-
- proc = &conf->fops->proctable[GF_FOP_ENTRYLK];
- if (!proc) {
- gf_log (this->name, GF_LOG_ERROR,
- "rpc procedure not found for %s",
- gf_fop_list[GF_FOP_ENTRYLK]);
- goto out;
- }
- if (proc->fn)
- ret = proc->fn (frame, this, &args);
-out:
- if (ret)
- STACK_UNWIND_STRICT (entrylk, frame, -1, ENOTCONN, NULL);
-
- return 0;
-}
-
-
-
-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)
-{
- 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.fd = fd;
- args.basename = basename;
- args.type = type;
- args.volume = volume;
- args.cmd_entrylk = cmd;
- args.xdata = xdata;
-
- proc = &conf->fops->proctable[GF_FOP_FENTRYLK];
- if (!proc) {
- gf_log (this->name, GF_LOG_ERROR,
- "rpc procedure not found for %s",
- gf_fop_list[GF_FOP_FENTRYLK]);
- goto out;
- }
- if (proc->fn)
- ret = proc->fn (frame, this, &args);
-out:
- if (ret)
- STACK_UNWIND_STRICT (fentrylk, frame, -1, ENOTCONN, NULL);
-
- return 0;
-}
-
-
-int32_t
-client_rchecksum (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
- int32_t len, 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.fd = fd;
- args.offset = offset;
- args.len = len;
- args.xdata = xdata;
-
- proc = &conf->fops->proctable[GF_FOP_RCHECKSUM];
- if (!proc) {
- gf_log (this->name, GF_LOG_ERROR,
- "rpc procedure not found for %s",
- gf_fop_list[GF_FOP_RCHECKSUM]);
- goto out;
- }
- if (proc->fn)
- ret = proc->fn (frame, this, &args);
-out:
- if (ret)
- STACK_UNWIND_STRICT (rchecksum, frame, -1, ENOTCONN, 0, NULL, 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)
-{
- 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.fd = fd;
- args.size = size;
- args.offset = off;
- args.xdata = xdata;
-
- proc = &conf->fops->proctable[GF_FOP_READDIR];
- if (!proc) {
- gf_log (this->name, GF_LOG_ERROR,
- "rpc procedure not found for %s",
- gf_fop_list[GF_FOP_READDIR]);
- goto out;
- }
- if (proc->fn)
- ret = proc->fn (frame, this, &args);
-out:
- if (ret)
- STACK_UNWIND_STRICT (readdir, frame, -1, ENOTCONN, NULL, NULL);
-
- return 0;
-}
-
-
-int32_t
-client_readdirp (call_frame_t *frame, xlator_t *this, fd_t *fd,
- size_t size, off_t off, dict_t *dict)
-{
- 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.fd = fd;
- args.size = size;
- args.offset = off;
- args.xdata = dict;
-
- proc = &conf->fops->proctable[GF_FOP_READDIRP];
- if (!proc) {
- gf_log (this->name, GF_LOG_ERROR,
- "rpc procedure not found for %s",
- gf_fop_list[GF_FOP_READDIRP]);
- goto out;
- }
- if (proc->fn)
- ret = proc->fn (frame, this, &args);
-out:
- if (ret)
- STACK_UNWIND_STRICT (readdirp, frame, -1, ENOTCONN, NULL, NULL);
-
- return 0;
-}
-
-
-int32_t
-client_setattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
- struct iatt *stbuf, int32_t valid, 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.loc = loc;
- args.stbuf = stbuf;
- args.valid = valid;
- args.xdata = xdata;
-
- proc = &conf->fops->proctable[GF_FOP_SETATTR];
- if (!proc) {
- gf_log (this->name, GF_LOG_ERROR,
- "rpc procedure not found for %s",
- gf_fop_list[GF_FOP_SETATTR]);
- goto out;
- }
- if (proc->fn)
- ret = proc->fn (frame, this, &args);
-out:
- if (ret)
- STACK_UNWIND_STRICT (setattr, frame, -1, ENOTCONN, NULL, 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)
-{
- 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.fd = fd;
- args.stbuf = stbuf;
- args.valid = valid;
- args.xdata = xdata;
-
- proc = &conf->fops->proctable[GF_FOP_FSETATTR];
- if (!proc) {
- gf_log (this->name, GF_LOG_ERROR,
- "rpc procedure not found for %s",
- gf_fop_list[GF_FOP_FSETATTR]);
- goto out;
- }
- if (proc->fn)
- ret = proc->fn (frame, this, &args);
-out:
- if (ret)
- STACK_UNWIND_STRICT (fsetattr, frame, -1, ENOTCONN, NULL, NULL, NULL);
-
- return 0;
-}
-
-int32_t
-client_fallocate(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t mode,
- off_t offset, size_t len, 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.fd = fd;
- args.flags = mode;
- args.offset = offset;
- args.size = len;
- args.xdata = xdata;
-
- proc = &conf->fops->proctable[GF_FOP_FALLOCATE];
- if (!proc) {
- gf_log (this->name, GF_LOG_ERROR,
- "rpc procedure not found for %s",
- gf_fop_list[GF_FOP_FALLOCATE]);
- goto out;
- }
- if (proc->fn)
- ret = proc->fn (frame, this, &args);
-out:
- if (ret)
- STACK_UNWIND_STRICT (fallocate, frame, -1, ENOTCONN, NULL, NULL, NULL);
-
- return 0;
-}
-
-int32_t
-client_discard(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
- size_t len, 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.fd = fd;
- args.offset = offset;
- args.size = len;
- args.xdata = xdata;
-
- proc = &conf->fops->proctable[GF_FOP_DISCARD];
- if (!proc) {
- gf_log (this->name, GF_LOG_ERROR,
- "rpc procedure not found for %s",
- gf_fop_list[GF_FOP_DISCARD]);
- goto out;
- }
- if (proc->fn)
- ret = proc->fn (frame, this, &args);
-out:
- if (ret)
- STACK_UNWIND_STRICT(discard, frame, -1, ENOTCONN, NULL, NULL, NULL);
-
- return 0;
-}
-
-int32_t
-client_zerofill(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
- off_t len, 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.fd = fd;
- args.offset = offset;
- args.size = len;
- args.xdata = xdata;
-
- proc = &conf->fops->proctable[GF_FOP_ZEROFILL];
- if (!proc) {
- gf_log (this->name, GF_LOG_ERROR,
- "rpc procedure not found for %s",
- gf_fop_list[GF_FOP_ZEROFILL]);
- goto out;
- }
- if (proc->fn)
- ret = proc->fn (frame, this, &args);
-out:
- if (ret)
- STACK_UNWIND_STRICT(zerofill, frame, -1, ENOTCONN,
- NULL, NULL, NULL);
-
- return 0;
-}
-
-
-int32_t
-client_getspec (call_frame_t *frame, xlator_t *this, const char *key,
- int32_t flags)
-{
- 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 || !conf->handshake)
- goto out;
-
- args.name = key;
- args.flags = flags;
-
- /* For all other xlators, getspec is an fop, hence its in fops table */
- proc = &conf->fops->proctable[GF_FOP_GETSPEC];
- if (!proc) {
- gf_log (this->name, GF_LOG_ERROR,
- "rpc procedure not found for %s",
- gf_fop_list[GF_FOP_GETSPEC]);
- goto out;
- }
- if (proc->fn) {
- /* But at protocol level, this is handshake */
- ret = proc->fn (frame, this, &args);
- }
-out:
- if (ret)
- STACK_UNWIND_STRICT (getspec, frame, -1, EINVAL, NULL);
-
- return 0;
-}
-
-
-int
-client_mark_fd_bad (xlator_t *this)
-{
- clnt_conf_t *conf = NULL;
- clnt_fd_ctx_t *tmp = NULL, *fdctx = NULL;
-
- conf = this->private;
-
- pthread_mutex_lock (&conf->lock);
- {
- list_for_each_entry_safe (fdctx, tmp, &conf->saved_fds,
- sfd_pos) {
- fdctx->remote_fd = -1;
- }
- }
- pthread_mutex_unlock (&conf->lock);
-
- return 0;
-}
-
-
-int
-client_rpc_notify (struct rpc_clnt *rpc, void *mydata, rpc_clnt_event_t event,
- void *data)
-{
- xlator_t *this = NULL;
- char *handshake = NULL;
- clnt_conf_t *conf = NULL;
- int ret = 0;
-
- this = mydata;
- if (!this || !this->private) {
- gf_log ("client", GF_LOG_ERROR,
- (this != NULL) ?
- "private structure of the xlator is NULL":
- "xlator is NULL");
- goto out;
- }
-
- conf = this->private;
-
- switch (event) {
- case RPC_CLNT_CONNECT:
- {
- conf->connected = 1;
- // connect happened, send 'get_supported_versions' mop
- ret = dict_get_str (this->options, "disable-handshake",
- &handshake);
-
- gf_log (this->name, GF_LOG_DEBUG, "got RPC_CLNT_CONNECT");
-
- if ((ret < 0) || (strcasecmp (handshake, "on"))) {
- ret = client_handshake (this, rpc);
- if (ret)
- gf_log (this->name, GF_LOG_WARNING,
- "handshake msg returned %d", ret);
- } else {
- //conf->rpc->connected = 1;
- if (conf->last_sent_event != GF_EVENT_CHILD_UP) {
- ret = default_notify (this, GF_EVENT_CHILD_UP,
- NULL);
- if (ret)
- gf_log (this->name, GF_LOG_INFO,
- "CHILD_UP notify failed");
- 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);
-
- if (!conf->skip_notify) {
- if (conf->connected) {
- gf_log (this->name,
- ((!conf->disconnect_err_logged)
- ? GF_LOG_INFO : GF_LOG_DEBUG),
- "disconnected from %s. Client process "
- "will keep trying to connect to "
- "glusterd until brick's port is "
- "available",
- conf->rpc->conn.name);
-
- if (conf->portmap_err_logged)
- conf->disconnect_err_logged = 1;
- }
-
- /* If the CHILD_DOWN event goes to parent xlator
- multiple times, the logic of parent xlator notify
- may get screwed up.. (eg. CHILD_MODIFIED event in
- replicate), hence make sure events which are passed
- to parent are genuine */
- if (conf->last_sent_event != GF_EVENT_CHILD_DOWN) {
- ret = default_notify (this, GF_EVENT_CHILD_DOWN,
- NULL);
- if (ret)
- gf_log (this->name, GF_LOG_INFO,
- "CHILD_DOWN notify failed");
- conf->last_sent_event = GF_EVENT_CHILD_DOWN;
- }
- } else {
- if (conf->connected)
- gf_log (this->name, GF_LOG_DEBUG,
- "disconnected (skipped notify)");
- }
-
- conf->connected = 0;
- conf->skip_notify = 0;
-
- if (conf->quick_reconnect) {
- conf->quick_reconnect = 0;
- rpc_clnt_start (rpc);
-
- } else {
- rpc->conn.config.remote_port = 0;
-
- }
-
- break;
-
- default:
- gf_log (this->name, GF_LOG_TRACE,
- "got some other RPC event %d", event);
-
- break;
- }
-
-out:
- return 0;
-}
-
-
-int
-notify (xlator_t *this, int32_t event, void *data, ...)
-{
- clnt_conf_t *conf = NULL;
-
- conf = this->private;
- if (!conf)
- return 0;
-
- switch (event) {
- case GF_EVENT_PARENT_UP:
- {
- gf_log (this->name, GF_LOG_INFO,
- "parent translators are ready, attempting connect "
- "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;
-
- default:
- gf_log (this->name, GF_LOG_DEBUG,
- "got %d, calling default_notify ()", event);
-
- default_notify (this, event, data);
- conf->last_sent_event = event;
- break;
- }
-
- return 0;
-}
-
-int
-client_check_remote_host (xlator_t *this, dict_t *options)
-{
- char *remote_host = NULL;
- int ret = -1;
-
- ret = dict_get_str (options, "remote-host", &remote_host);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_INFO, "Remote host is not set. "
- "Assuming the volfile server as remote host.");
-
- if (!this->ctx->cmd_args.volfile_server) {
- gf_log (this->name, GF_LOG_ERROR,
- "No remote host to connect.");
- goto out;
- }
-
- ret = dict_set_str (options, "remote-host",
- this->ctx->cmd_args.volfile_server);
- if (ret == -1) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to set the remote host");
- goto out;
- }
- }
-
- ret = 0;
-out:
- return ret;
-}
-
-int
-build_client_config (xlator_t *this, clnt_conf_t *conf)
-{
- int ret = -1;
-
- if (!conf)
- goto out;
-
- GF_OPTION_INIT ("frame-timeout", conf->rpc_conf.rpc_timeout,
- int32, out);
-
- GF_OPTION_INIT ("remote-port", conf->rpc_conf.remote_port,
- int32, out);
-
- GF_OPTION_INIT ("ping-timeout", conf->opt.ping_timeout,
- int32, out);
-
- GF_OPTION_INIT ("remote-subvolume", conf->opt.remote_subvolume,
- path, out);
- if (!conf->opt.remote_subvolume)
- gf_log (this->name, GF_LOG_WARNING,
- "option 'remote-subvolume' not given");
-
- GF_OPTION_INIT ("filter-O_DIRECT", conf->filter_o_direct,
- bool, out);
-
- GF_OPTION_INIT ("send-gids", conf->send_gids, bool, out);
-
- ret = client_check_remote_host (this, this->options);
- if (ret)
- goto out;
-
- ret = 0;
-out:
- 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;
-}
-
-int
-client_destroy_rpc (xlator_t *this)
-{
- int ret = -1;
- clnt_conf_t *conf = NULL;
-
- conf = this->private;
- if (!conf)
- 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,
- "Client rpc conn destroyed");
- goto out;
- }
-
- gf_log (this->name, GF_LOG_WARNING,
- "RPC destroy called on already destroyed "
- "connection");
-
-out:
- return ret;
-}
-
-int
-client_init_rpc (xlator_t *this)
-{
- int ret = -1;
- clnt_conf_t *conf = NULL;
-
- conf = this->private;
-
- if (conf->rpc) {
- gf_log (this->name, GF_LOG_WARNING,
- "client rpc already init'ed");
- ret = -1;
- goto out;
- }
-
- conf->rpc = rpc_clnt_new (this->options, this->ctx, this->name, 0);
- if (!conf->rpc) {
- gf_log (this->name, GF_LOG_ERROR, "failed to initialize RPC");
- goto out;
- }
-
- ret = rpc_clnt_register_notify (conf->rpc, client_rpc_notify, this);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "failed to register notify");
- goto out;
- }
-
- conf->handshake = &clnt_handshake_prog;
- conf->dump = &clnt_dump_prog;
-
- ret = rpcclnt_cbk_program_register (conf->rpc, &gluster_cbk_prog,
- this);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "failed to register callback program");
- goto out;
- }
-
- ret = 0;
-
- gf_log (this->name, GF_LOG_DEBUG, "client init successful");
-out:
- return ret;
-}
-
-
-int
-client_init_grace_timer (xlator_t *this, dict_t *options,
- clnt_conf_t *conf)
-{
- 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;
-
- 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_ts.tv_sec = grace_timeout;
- else
- conf->grace_ts.tv_sec = 10;
-
- conf->grace_ts.tv_nsec = 0;
-
- gf_log (this->name, GF_LOG_DEBUG, "Client grace timeout "
- "value = %"GF_PRI_SECOND, conf->grace_ts.tv_sec);
-
- ret = 0;
-out:
- return ret;
-}
-
-int
-reconfigure (xlator_t *this, dict_t *options)
-{
- clnt_conf_t *conf = NULL;
- int ret = -1;
- int subvol_ret = 0;
- char *old_remote_subvol = NULL;
- char *new_remote_subvol = NULL;
- char *old_remote_host = NULL;
- char *new_remote_host = NULL;
-
- conf = this->private;
-
- GF_OPTION_RECONF ("frame-timeout", conf->rpc_conf.rpc_timeout,
- options, int32, out);
-
- GF_OPTION_RECONF ("ping-timeout", conf->opt.ping_timeout,
- options, int32, out);
-
- ret = client_check_remote_host (this, options);
- if (ret)
- goto out;
-
- 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;
- goto out;
- }
- }
- }
-
- subvol_ret = dict_get_str (this->options, "remote-subvolume",
- &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;
- goto out;
- }
- }
- }
-
- GF_OPTION_RECONF ("filter-O_DIRECT", conf->filter_o_direct,
- options, bool, out);
-
- GF_OPTION_RECONF ("send-gids", conf->send_gids, options, bool, out);
-
- 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 "
- "subvolumes");
- goto out;
- }
-
- if (!this->parents) {
- gf_log (this->name, GF_LOG_WARNING,
- "Volume is dangling. ");
- }
-
- conf = GF_CALLOC (1, sizeof (*conf), gf_client_mt_clnt_conf_t);
- if (!conf)
- goto out;
-
- 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 */
-
- this->private = conf;
-
- /* If it returns -1, then its a failure, if it returns +1 we need
- have to understand that 'this' is subvolume of a xlator which,
- will set the remote host and remote subvolume in a setxattr
- call.
- */
-
- ret = build_client_config (this, conf);
- if (ret == -1)
- goto out;
-
- if (ret) {
- ret = 0;
- 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:
- if (ret)
- this->fini (this);
-
- return ret;
-}
-
-void
-fini (xlator_t *this)
-{
- clnt_conf_t *conf = NULL;
-
- conf = this->private;
- 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);
- }
-
- /* Saved Fds */
- /* TODO: */
-
- pthread_mutex_destroy (&conf->lock);
-
- GF_FREE (conf);
- }
- 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)
-{
- clnt_conf_t *conf = NULL;
- int ret = -1;
- clnt_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)
- return -1;
-
- ret = pthread_mutex_trylock(&conf->lock);
- if (ret)
- 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) {
- sprintf (key, "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_write ("connected", "%d", conf->connected);
-
- if (conf->rpc) {
- gf_proc_dump_write("total_bytes_read", "%"PRIu64,
- conf->rpc->conn.trans->total_bytes_read);
-
- gf_proc_dump_write("total_bytes_written", "%"PRIu64,
- conf->rpc->conn.trans->total_bytes_write);
- }
- pthread_mutex_unlock(&conf->lock);
-
- return 0;
-
-}
-
-int32_t
-client_inodectx_dump (xlator_t *this, inode_t *inode)
-{
- if (!inode)
- return -1;
-
- if (!this)
- return -1;
-
- /*TODO*/
-
- return 0;
-}
-
-
-
-
-struct xlator_cbks cbks = {
- .forget = client_forget,
- .release = client_release,
- .releasedir = client_releasedir
-};
-
-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,
- .fremovexattr = client_fremovexattr,
- .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,
- .fallocate = client_fallocate,
- .discard = client_discard,
- .zerofill = client_zerofill,
- .getspec = client_getspec,
-};
-
-
-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", "rdma"},
- .type = GF_OPTION_TYPE_STR
- },
- { .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
- },
- { .key = {"frame-timeout",
- "rpc-timeout" },
- .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 = 0,
- .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",
- .description = "When the connection to client is lost, server "
- "cleans up all the locks held by the client. After "
- "the connection is restored, the client reacquires "
- "(heals) the fcntl locks released by the server."
- },
- { .key = {"grace-timeout"},
- .type = GF_OPTION_TYPE_INT,
- .min = 10,
- .max = 1800,
- .default_value = "10",
- .description = "Specifies the duration for the lock state to be "
- "maintained on the client after a network "
- "disconnection. Range 10-1800 seconds."
- },
- {.key = {"tcp-window-size"},
- .type = GF_OPTION_TYPE_SIZET,
- .min = GF_MIN_SOCKET_WINDOW_SIZE,
- .max = GF_MAX_SOCKET_WINDOW_SIZE,
- .description = "Specifies the window size for tcp socket."
- },
- { .key = {"filter-O_DIRECT"},
- .type = GF_OPTION_TYPE_BOOL,
- .default_value = "disable",
- .description = "If enabled, in open() and creat() calls, O_DIRECT "
- "flag will be filtered at the client protocol level so server will "
- "still continue to cache the file. This works similar to NFS's "
- "behavior of O_DIRECT",
- },
- { .key = {"send-gids"},
- .type = GF_OPTION_TYPE_BOOL,
- .default_value = "on",
- },
- { .key = {NULL} },
-};
diff --git a/xlators/protocol/client/src/client.h b/xlators/protocol/client/src/client.h
deleted file mode 100644
index 69f77570cd0..00000000000
--- a/xlators/protocol/client/src/client.h
+++ /dev/null
@@ -1,260 +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 _CLIENT_H
-#define _CLIENT_H
-
-#include <pthread.h>
-#include <stdint.h>
-
-#include "rpc-clnt.h"
-#include "list.h"
-#include "inode.h"
-#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;
-
-typedef enum {
- DEFAULT_REMOTE_FD = 0,
- FALLBACK_TO_ANON_FD = 1
-} clnt_remote_fd_flags_t;
-
-#define CLIENT_GET_REMOTE_FD(xl, fd, flags, remote_fd, op_errno, label) \
- do { \
- int _ret = 0; \
- _ret = client_get_remote_fd (xl, fd, flags, &remote_fd);\
- if (_ret < 0) { \
- op_errno = errno; \
- goto label; \
- } \
- if (remote_fd == -1) { \
- gf_log (xl->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;
- int ping_timeout;
-};
-
-typedef struct clnt_conf {
- struct rpc_clnt *rpc;
- struct clnt_options opt;
- struct rpc_clnt_config rpc_conf;
- struct list_head saved_fds;
- pthread_mutex_t lock;
- int connecting;
- int connected;
-
- rpc_clnt_prog_t *fops;
- rpc_clnt_prog_t *mgmt;
- rpc_clnt_prog_t *handshake;
- rpc_clnt_prog_t *dump;
-
- uint64_t reopen_fd_count; /* Count of fds reopened after a
- connection is established */
- gf_lock_t rec_lock;
- int skip_notify;
-
- int last_sent_event; /* Flag used to make sure we are
- not repeating the same event
- which was sent earlier */
- char portmap_err_logged; /* flag used to prevent
- excessive logging */
- char disconnect_err_logged; /* flag used to prevent
- excessive disconnect
- logging */
- gf_boolean_t lk_heal;
- uint16_t lk_version; /* this variable is used to distinguish
- client-server transaction while
- performing lock healing */
- struct timespec grace_ts;
- 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;
- gf_boolean_t quick_reconnect; /* When reconnecting after
- portmap query, do not let
- the reconnection happen after
- the usual 3-second wait
- */
- gf_boolean_t filter_o_direct; /* if set, filter O_DIRECT from
- the flags list of open() */
- /* set volume is the op which results in creating/re-using
- * the conn-id and is called once per connection, this remembers
- * how manytimes set_volume is called
- */
- uint64_t setvol_count;
-
- gf_boolean_t send_gids; /* let the server resolve gids */
-} clnt_conf_t;
-
-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;
- char is_dir;
- char released;
- int32_t flags;
- fd_lk_ctx_t *lk_ctx;
- pthread_mutex_t mutex;
- lk_heal_state_t lk_heal_state;
- uuid_t gfid;
- void (*reopen_done) (struct _client_fd_ctx*, xlator_t *);
- struct list_head lock_list; /* List of all granted locks on this fd */
- int32_t reopen_attempts;
-} clnt_fd_ctx_t;
-
-typedef struct _client_posix_lock {
- fd_t *fd; /* The fd on which the lk operation was made */
-
- struct gf_flock user_flock; /* the flock supplied by the user */
- off_t fl_start;
- off_t fl_end;
- short fl_type;
- int32_t cmd; /* the cmd for the lock call */
- gf_lkowner_t owner; /* lock owner from fuse */
- struct list_head list; /* reference used to add to the fdctx list of locks */
-} client_posix_lock_t;
-
-typedef struct client_local {
- loc_t loc;
- loc_t loc2;
- fd_t *fd;
- clnt_fd_ctx_t *fdctx;
- uint32_t flags;
- struct iobref *iobref;
-
- client_posix_lock_t *client_lock;
- gf_lkowner_t owner;
- int32_t cmd;
- struct list_head lock_list;
- pthread_mutex_t mutex;
- char *name;
- gf_boolean_t attempt_reopen;
-} clnt_local_t;
-
-typedef struct client_args {
- loc_t *loc;
- fd_t *fd;
- const char *linkname;
- struct iobref *iobref;
- struct iovec *vector;
- dict_t *xattr;
- struct iatt *stbuf;
- loc_t *oldloc;
- loc_t *newloc;
- const char *name;
- struct gf_flock *flock;
- const char *volume;
- const char *basename;
- off_t offset;
- int32_t mask;
- int32_t cmd;
- size_t size;
- mode_t mode;
- dev_t rdev;
- int32_t flags;
- int32_t count;
- int32_t datasync;
- entrylk_cmd cmd_entrylk;
- entrylk_type type;
- 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);
-
-clnt_fd_ctx_t *this_fd_get_ctx (fd_t *file, xlator_t *this);
-clnt_fd_ctx_t *this_fd_del_ctx (fd_t *file, xlator_t *this);
-void this_fd_set_ctx (fd_t *file, xlator_t *this, loc_t *loc,
- clnt_fd_ctx_t *ctx);
-
-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 iovec *rsphdr, int rsphdr_count,
- struct iovec *rsp_payload, int rsp_count,
- struct iobref *rsp_iobref, xdrproc_t xdrproc);
-
-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 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_fd (clnt_fd_ctx_t *fdctx);
-int32_t client_cmd_to_gf_cmd (int32_t cmd, int32_t *gf_cmd);
-void client_save_number_fds (clnt_conf_t *conf, int count);
-int dump_client_locks (inode_t *inode);
-int client_notify_parents_child_up (xlator_t *this);
-int32_t is_client_dump_locks_cmd (char *name);
-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);
-void client_default_reopen_done (clnt_fd_ctx_t *fdctx, xlator_t *this);
-void client_attempt_reopen (fd_t *fd, xlator_t *this);
-int client_get_remote_fd (xlator_t *this, fd_t *fd, int flags,
- int64_t *remote_fd);
-int client_fd_fop_prepare_local (call_frame_t *frame, fd_t *fd,
- int64_t remote_fd);
-gf_boolean_t
-__is_fd_reopen_in_progress (clnt_fd_ctx_t *fdctx);
-#endif /* !_CLIENT_H */
diff --git a/xlators/protocol/client/src/saved-frames.c b/xlators/protocol/client/src/saved-frames.c
new file mode 100644
index 00000000000..cd5349e21fb
--- /dev/null
+++ b/xlators/protocol/client/src/saved-frames.c
@@ -0,0 +1,191 @@
+/*
+ Copyright (c) 2008-2009 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 "saved-frames.h"
+#include "common-utils.h"
+#include "protocol.h"
+#include "xlator.h"
+
+
+
+struct saved_frames *
+saved_frames_new (void)
+{
+ struct saved_frames *saved_frames = NULL;
+
+ saved_frames = CALLOC (sizeof (*saved_frames), 1);
+ if (!saved_frames) {
+ return NULL;
+ }
+
+ 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 = CALLOC (sizeof (*saved_frame), 1);
+ 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;
+
+ 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);
+ FREE (trav);
+ }
+}
+
+
+void
+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);
+
+ FREE (frames);
+}
diff --git a/xlators/protocol/client/src/saved-frames.h b/xlators/protocol/client/src/saved-frames.h
new file mode 100644
index 00000000000..5c18abbcc9e
--- /dev/null
+++ b/xlators/protocol/client/src/saved-frames.h
@@ -0,0 +1,79 @@
+/*
+ Copyright (c) 2008-2009 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 _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 *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 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/server/Makefile.am b/xlators/protocol/server/Makefile.am
index af437a64d6d..d471a3f9243 100644
--- a/xlators/protocol/server/Makefile.am
+++ b/xlators/protocol/server/Makefile.am
@@ -1 +1,3 @@
SUBDIRS = src
+
+CLEANFILES =
diff --git a/xlators/protocol/server/src/Makefile.am b/xlators/protocol/server/src/Makefile.am
index 6a18bf02561..ae93912fc00 100644
--- a/xlators/protocol/server/src/Makefile.am
+++ b/xlators/protocol/server/src/Makefile.am
@@ -1,26 +1,18 @@
+
xlator_LTLIBRARIES = server.la
xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/protocol
-server_la_LDFLAGS = -module -avoid-version
-
-server_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la \
- $(top_builddir)/rpc/rpc-lib/src/libgfrpc.la \
- $(top_builddir)/rpc/xdr/src/libgfxdr.la
+server_la_LDFLAGS = -module -avoidversion
-server_la_SOURCES = server.c server-resolve.c server-helpers.c \
- server-rpc-fops.c server-handshake.c authenticate.c
+server_la_SOURCES = server-protocol.c server-resolve.c server-helpers.c
+server_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la
-noinst_HEADERS = server.h server-helpers.h server-mem-types.h authenticate.h
+noinst_HEADERS = server-protocol.h server-helpers.h
-AM_CPPFLAGS = $(GF_CPPFLAGS) \
- -I$(top_srcdir)/libglusterfs/src \
- -DCONFDIR=\"$(sysconfdir)/glusterfs\" \
- -DLIBDIR=\"$(libdir)/glusterfs/$(PACKAGE_VERSION)/auth\" \
- -I$(top_srcdir)/xlators/protocol/lib/src \
- -I$(top_srcdir)/rpc/rpc-lib/src \
- -I$(top_srcdir)/rpc/xdr/src
+AM_CFLAGS = -fPIC -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -Wall -D$(GF_HOST_OS) \
+ -I$(top_srcdir)/libglusterfs/src -shared -nostartfiles \
+ -DDATADIR=\"$(localstatedir)\" -DCONFDIR=\"$(sysconfdir)/glusterfs\" \
+ $(GF_CFLAGS)
-AM_CFLAGS = -Wall $(GF_CFLAGS) \
- -DDATADIR=\"$(localstatedir)\"
+CLEANFILES =
-CLEANFILES = *~
diff --git a/xlators/protocol/server/src/authenticate.c b/xlators/protocol/server/src/authenticate.c
deleted file mode 100644
index d8d138a84bc..00000000000
--- a/xlators/protocol/server/src/authenticate.c
+++ /dev/null
@@ -1,253 +0,0 @@
-/*
- Copyright (c) 2007-2013 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
-
-#ifndef _GNU_SOURCE
-#define _GNU_SOURCE
-#endif
-
-#include <stdio.h>
-#include <dlfcn.h>
-#include <errno.h>
-#include "authenticate.h"
-
-static int
-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) {
- dict_set (this, key, data_from_dynptr (NULL, 0));
- *error = -1;
- return -1;
- }
-
- 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 -1;
- }
- 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));
- dlclose (handle);
- *error = -1;
- return -1;
- }
-
- auth_handle = GF_CALLOC (1, sizeof (*auth_handle),
- gf_common_mt_auth_handle_t);
- if (!auth_handle) {
- dict_set (this, key, data_from_dynptr (NULL, 0));
- *error = -1;
- dlclose (handle);
- return -1;
- }
- 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 -1;
- }
- 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)));
- return 0;
-}
-
-static int
-fini (dict_t *this, char *key, data_t *value, void *data)
-{
- auth_handle_t *handle = data_to_ptr (value);
- if (handle) {
- dlclose (handle->handle);
- }
- return 0;
-}
-
-static int
-_gf_auth_option_validate (dict_t *d, char *k, data_t *v, void *tmp)
-{
- auth_handle_t *handle = NULL;
- xlator_t *xl = NULL;
- int ret = 0;
-
- xl = tmp;
-
- handle = data_to_ptr (v);
- if (!handle)
- return 0;
-
- list_add_tail (&(handle->vol_opt->list), &(xl->volume_options));
-
- ret = xlator_options_validate_list (xl, xl->options,
- handle->vol_opt, NULL);
- if (ret) {
- gf_log ("authenticate", GF_LOG_ERROR,
- "volume option validation failed");
- return -1;
- }
- return 0;
-}
-
-int32_t
-gf_auth_init (xlator_t *xl, dict_t *auth_modules)
-{
- int ret = 0;
-
- dict_foreach (auth_modules, init, &ret);
- if (ret)
- goto out;
-
- ret = dict_foreach (auth_modules, _gf_auth_option_validate, xl);
-
-out:
- 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;
-
-int
-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));
- }
- return 0;
-}
-
-int
-reduce (dict_t *this, char *key, data_t *value, void *data)
-{
- int64_t val = 0;
- int64_t *res = data;
- if (!data)
- return 0;
-
- 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;
- }
- return 0;
-}
-
-
-auth_result_t
-gf_authenticate (dict_t *input_params,
- dict_t *config_params,
- dict_t *auth_modules)
-{
- char *name = NULL;
- dict_t *results = NULL;
- int64_t result = AUTH_DONT_CARE;
- data_t *peerinfo_data = NULL;
-
- 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) {
- peerinfo_data = dict_get (input_params, "peer-info-name");
-
- 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/server/src/authenticate.h b/xlators/protocol/server/src/authenticate.h
deleted file mode 100644
index d4d43e49873..00000000000
--- a/xlators/protocol/server/src/authenticate.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- Copyright (c) 2007-2013 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 _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/server/src/server-handshake.c b/xlators/protocol/server/src/server-handshake.c
deleted file mode 100644
index 9396499cc3d..00000000000
--- a/xlators/protocol/server/src/server-handshake.c
+++ /dev/null
@@ -1,792 +0,0 @@
-/*
- Copyright (c) 2010-2013 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 "server.h"
-#include "server-helpers.h"
-#include "rpc-common-xdr.h"
-#include "glusterfs3-xdr.h"
-#include "compat-errno.h"
-#include "glusterfs3.h"
-#include "authenticate.h"
-
-struct __get_xl_struct {
- const char *name;
- xlator_t *reply;
-};
-int
-gf_compare_client_version (rpcsvc_request_t *req, int fop_prognum,
- int mgmt_prognum)
-{
- int ret = -1;
- /* TODO: think.. */
- if (glusterfs3_3_fop_prog.prognum == fop_prognum)
- ret = 0;
-
- return ret;
-}
-
-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;
-}
-
-
-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_t);
- 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_INFO,
- "the volume file was modified between a prior access "
- "and now. This may lead to inconsistency between "
- "clients, you are advised to remount client");
- temp_volfile->checksum = checksum;
- }
-
-out:
- return 0;
-}
-
-
-static size_t
-getspec_build_volfile_path (xlator_t *this, const char *key, char *path,
- size_t path_len)
-{
- char *filename = NULL;
- server_conf_t *conf = NULL;
- int ret = -1;
- int free_filename = 0;
- char data_key[256] = {0,};
-
- conf = this->private;
-
- /* 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) {
- /* Make sure that key doesn't contain "../" in path */
- if ((gf_strstr (key, "/", "..")) == -1) {
- gf_log (this->name, GF_LOG_ERROR,
- "%s: invalid key", key);
- goto out;
- }
- }
- }
-
- 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);
- }
- }
-
- if (!filename && key) {
- ret = gf_asprintf (&filename, "%s/%s.vol", conf->conf_dir, key);
- if (-1 == ret)
- goto out;
-
- free_filename = 1;
- }
- if (!filename)
- filename = DEFAULT_VOLUME_FILE_PATH;
-
- ret = -1;
-
- if ((filename) && (path_len > strlen (filename))) {
- strcpy (path, filename);
- ret = strlen (filename);
- }
-
-out:
- if (free_filename)
- GF_FREE (filename);
-
- return ret;
-}
-
-int
-_validate_volfile_checksum (xlator_t *this, char *key,
- uint32_t checksum)
-{
- char filename[PATH_MAX] = {0,};
- server_conf_t *conf = NULL;
- struct _volfile_ctx *temp_volfile = NULL;
- int ret = 0;
- int fd = 0;
- uint32_t local_checksum = 0;
-
- conf = this->private;
- temp_volfile = conf->volfile;
-
- if (!checksum)
- goto out;
-
- if (!temp_volfile) {
- ret = getspec_build_volfile_path (this, key, filename,
- sizeof (filename));
- if (ret <= 0)
- goto out;
- fd = open (filename, O_RDONLY);
- if (-1 == fd) {
- ret = 0;
- gf_log (this->name, GF_LOG_INFO,
- "failed to open volume file (%s) : %s",
- filename, strerror (errno));
- goto out;
- }
- get_checksum_for_file (fd, &local_checksum);
- _volfile_update_checksum (this, key, local_checksum);
- close (fd);
- }
-
- 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;
-}
-
-
-int
-server_getspec (rpcsvc_request_t *req)
-{
- int32_t ret = -1;
- int32_t op_errno = ENOENT;
- int32_t spec_fd = -1;
- size_t file_len = 0;
- char filename[PATH_MAX] = {0,};
- struct stat stbuf = {0,};
- uint32_t checksum = 0;
- char *key = NULL;
- server_conf_t *conf = NULL;
- xlator_t *this = NULL;
- gf_getspec_req args = {0,};
- gf_getspec_rsp rsp = {0,};
-
- this = req->svc->mydata;
- conf = this->private;
- ret = xdr_to_generic (req->msg[0], &args,
- (xdrproc_t)xdr_gf_getspec_req);
- if (ret < 0) {
- //failed to decode msg;
- req->rpc_err = GARBAGE_ARGS;
- op_errno = EINVAL;
- goto fail;
- }
-
- ret = getspec_build_volfile_path (this, args.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 (this->name, GF_LOG_ERROR,
- "Unable to stat %s (%s)",
- filename, strerror (errno));
- op_errno = errno;
- goto fail;
- }
-
- spec_fd = open (filename, O_RDONLY);
- if (spec_fd < 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "Unable to open %s (%s)",
- filename, strerror (errno));
- op_errno = errno;
- goto fail;
- }
- ret = file_len = stbuf.st_size;
-
- if (conf->verify_volfile) {
- get_checksum_for_file (spec_fd, &checksum);
- _volfile_update_checksum (this, key, checksum);
- }
- } else {
- op_errno = ENOENT;
- }
-
- if (file_len) {
- rsp.spec = GF_CALLOC (file_len, sizeof (char),
- gf_server_mt_rsp_buf_t);
- if (!rsp.spec) {
- ret = -1;
- op_errno = ENOMEM;
- goto fail;
- }
- ret = read (spec_fd, rsp.spec, file_len);
- }
-
- /* convert to XDR */
- op_errno = errno;
-fail:
- if (!rsp.spec)
- rsp.spec = "";
- 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);
-
- return 0;
-}
-
-
-int
-server_setvolume (rpcsvc_request_t *req)
-{
- gf_setvolume_req args = {{0,},};
- gf_setvolume_rsp rsp = {0,};
- client_t *client = NULL;
- server_ctx_t *serv_ctx = NULL;
- server_conf_t *conf = NULL;
- peer_info_t *peerinfo = NULL;
- dict_t *reply = NULL;
- dict_t *config_params = NULL;
- dict_t *params = NULL;
- char *name = NULL;
- char *client_uid = NULL;
- char *clnt_version = NULL;
- xlator_t *xl = NULL;
- char *msg = NULL;
- char *volfile_key = NULL;
- xlator_t *this = NULL;
- uint32_t checksum = 0;
- int32_t ret = -1;
- int32_t op_ret = -1;
- 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 ();
- ret = xdr_to_generic (req->msg[0], &args,
- (xdrproc_t)xdr_gf_setvolume_req);
- if (ret < 0) {
- //failed to decode msg;
- req->rpc_err = GARBAGE_ARGS;
- goto fail;
- }
-
- this = req->svc->mydata;
-
- config_params = dict_copy_with_ref (this->options, NULL);
- conf = this->private;
-
- buf = memdup (args.dict.dict_val, args.dict.dict_len);
- if (buf == NULL) {
- op_ret = -1;
- op_errno = ENOMEM;
- goto fail;
- }
-
- ret = dict_unserialize (buf, args.dict.dict_len, &params);
- if (ret < 0) {
- ret = dict_set_str (reply, "ERROR",
- "Internal error: failed to unserialize "
- "request dictionary");
- if (ret < 0)
- gf_log (this->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;
- }
-
- params->extra_free = buf;
- buf = NULL;
-
- ret = dict_get_str (params, "process-uuid", &client_uid);
- if (ret < 0) {
- ret = dict_set_str (reply, "ERROR",
- "UUID not specified");
- if (ret < 0)
- gf_log (this->name, GF_LOG_DEBUG,
- "failed to set error msg");
-
- op_ret = -1;
- op_errno = EINVAL;
- 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;
- }
-
- client = gf_client_get (this, &req->cred, client_uid);
- if (client == NULL) {
- op_ret = -1;
- op_errno = ENOMEM;
- goto fail;
- }
-
- gf_log (this->name, GF_LOG_DEBUG, "Connected to %s", client->client_uid);
- cancelled = server_cancel_grace_timer (this, client);
- if (cancelled)//Do gf_client_put on behalf of grace-timer-handler.
- gf_client_put (client, NULL);
-
- serv_ctx = server_ctx_get (client, client->this);
- if (serv_ctx == NULL) {
- gf_log (this->name, GF_LOG_INFO, "server_ctx_get() failed");
- goto fail;
- }
-
- if (serv_ctx->lk_version != 0 &&
- serv_ctx->lk_version != lk_version) {
- (void) server_connection_cleanup (this, client,
- INTERNAL_LOCKS | POSIX_LOCKS);
- }
-
- if (req->trans->xl_private != client)
- req->trans->xl_private = client;
-
- auth_set_username_passwd (params, config_params, client);
- if (req->trans->ssl_name) {
- if (dict_set_str(params,"ssl-name",req->trans->ssl_name) != 0) {
- gf_log (this->name, GF_LOG_WARNING,
- "failed to set ssl_name %s", req->trans->ssl_name);
- /* Not fatal, auth will just fail. */
- }
- }
-
- ret = dict_get_int32 (params, "fops-version", &fop_version);
- if (ret < 0) {
- ret = dict_set_str (reply, "ERROR",
- "No FOP version number specified");
- if (ret < 0)
- gf_log (this->name, GF_LOG_DEBUG,
- "failed to set error msg");
- }
-
- ret = dict_get_int32 (params, "mgmt-version", &mgmt_version);
- if (ret < 0) {
- ret = dict_set_str (reply, "ERROR",
- "No MGMT version number specified");
- if (ret < 0)
- gf_log (this->name, GF_LOG_DEBUG,
- "failed to set error msg");
- }
-
- ret = gf_compare_client_version (req, fop_version, mgmt_version);
- if (ret != 0) {
- ret = gf_asprintf (&msg, "version mismatch: client(%d)"
- " - client-mgmt(%d)",
- fop_version, mgmt_version);
- /* get_supported_version (req)); */
- if (-1 == ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "asprintf failed while setting up error msg");
- goto fail;
- }
- ret = dict_set_dynstr (reply, "ERROR", msg);
- if (ret < 0)
- gf_log (this->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 (this->name, GF_LOG_DEBUG,
- "failed to set error msg");
-
- op_ret = -1;
- op_errno = EINVAL;
- goto fail;
- }
-
- xl = get_xlator_by_name (this, name);
- if (xl == NULL) {
- ret = gf_asprintf (&msg, "remote-subvolume \"%s\" is not found",
- name);
- if (-1 == ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "asprintf failed while setting error msg");
- goto fail;
- }
- ret = dict_set_dynstr (reply, "ERROR", msg);
- if (ret < 0)
- gf_log (this->name, GF_LOG_DEBUG,
- "failed to set error msg");
-
- op_ret = -1;
- op_errno = ENOENT;
- goto fail;
- }
-
- if (conf->verify_volfile) {
- ret = dict_get_uint32 (params, "volfile-checksum", &checksum);
- if (ret == 0) {
- ret = dict_get_str (params, "volfile-key",
- &volfile_key);
- if (ret)
- gf_log (this->name, GF_LOG_DEBUG,
- "failed to set 'volfile-key'");
-
- ret = _validate_volfile_checksum (this, volfile_key,
- checksum);
- if (-1 == ret) {
- ret = dict_set_str (reply, "ERROR",
- "volume-file checksum "
- "varies from earlier "
- "access");
- if (ret < 0)
- gf_log (this->name, GF_LOG_DEBUG,
- "failed to set error msg");
-
- op_ret = -1;
- op_errno = ESTALE;
- goto fail;
- }
- }
- }
-
-
- peerinfo = &req->trans->peerinfo;
- if (peerinfo) {
- ret = dict_set_static_ptr (params, "peer-info", peerinfo);
- if (ret < 0)
- gf_log (this->name, GF_LOG_DEBUG,
- "failed to set peer-info");
- }
- if (conf->auth_modules == NULL) {
- gf_log (this->name, GF_LOG_ERROR,
- "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)",
- client->client_uid,
- (clnt_version) ? clnt_version : "old");
- op_ret = 0;
- client->bound_xl = xl;
- ret = dict_set_str (reply, "ERROR", "Success");
- if (ret < 0)
- gf_log (this->name, GF_LOG_DEBUG,
- "failed to set error msg");
- } else {
- gf_log (this->name, GF_LOG_ERROR,
- "Cannot authenticate client from %s %s",
- client->client_uid,
- (clnt_version) ? clnt_version : "old");
-
- op_ret = -1;
- op_errno = EACCES;
- ret = dict_set_str (reply, "ERROR", "Authentication failed");
- if (ret < 0)
- gf_log (this->name, GF_LOG_DEBUG,
- "failed to set error msg");
- goto fail;
- }
-
- if (client->bound_xl == NULL) {
- ret = dict_set_str (reply, "ERROR",
- "Check volfile and handshake "
- "options in protocol/client");
- if (ret < 0)
- gf_log (this->name, GF_LOG_DEBUG,
- "failed to set error msg");
-
- op_ret = -1;
- op_errno = EACCES;
- goto fail;
- }
-
- if ((client->bound_xl != NULL) &&
- (ret >= 0) &&
- (client->bound_xl->itable == NULL)) {
- /* create inode table for this bound_xl, if one doesn't
- already exist */
-
- gf_log (this->name, GF_LOG_TRACE,
- "creating inode table with lru_limit=%"PRId32", "
- "xlator=%s", conf->inode_lru_limit,
- client->bound_xl->name);
-
- /* TODO: what is this ? */
- client->bound_xl->itable =
- inode_table_new (conf->inode_lru_limit,
- client->bound_xl);
- }
-
- ret = dict_set_str (reply, "process-uuid",
- this->ctx->process_uuid);
- if (ret)
- gf_log (this->name, GF_LOG_DEBUG,
- "failed to set 'process-uuid'");
-
- ret = dict_set_uint32 (reply, "clnt-lk-version", serv_ctx->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)
- gf_log (this->name, GF_LOG_DEBUG,
- "failed to set 'transport-ptr'");
-
-fail:
- rsp.dict.dict_len = dict_serialized_length (reply);
- if (rsp.dict.dict_len > UINT_MAX) {
- gf_log ("server-handshake", GF_LOG_DEBUG,
- "failed to get serialized length of reply dict");
- op_ret = -1;
- op_errno = EINVAL;
- rsp.dict.dict_len = 0;
- }
-
- if (rsp.dict.dict_len) {
- rsp.dict.dict_val = GF_CALLOC (1, rsp.dict.dict_len,
- gf_server_mt_rsp_buf_t);
- if (rsp.dict.dict_val) {
- ret = dict_serialize (reply, rsp.dict.dict_val);
- if (ret < 0) {
- gf_log ("server-handshake", GF_LOG_DEBUG,
- "failed to serialize reply dict");
- op_ret = -1;
- op_errno = -ret;
- }
- }
- }
- rsp.op_ret = op_ret;
- rsp.op_errno = gf_errno_to_error (op_errno);
-
- /* if bound_xl is NULL or something fails, then put the connection
- * back. Otherwise the connection would have been added to the
- * list of connections the server is maintaining and might segfault
- * during statedump when bound_xl of the connection is accessed.
- */
- if (op_ret && !xl) {
- /* We would have set the xl_private of the transport to the
- * @conn. But if we have put the connection i.e shutting down
- * the connection, then we should set xl_private to NULL as it
- * would be pointing to a freed memory and would segfault when
- * accessed upon getting DISCONNECT.
- */
- gf_client_put (client, NULL);
- req->trans->xl_private = NULL;
- }
- server_submit_reply (NULL, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gf_setvolume_rsp);
-
-
- free (args.dict.dict_val);
-
- GF_FREE (rsp.dict.dict_val);
-
- dict_unref (params);
- dict_unref (reply);
- dict_unref (config_params);
-
- GF_FREE (buf);
-
- return 0;
-}
-
-
-int
-server_ping (rpcsvc_request_t *req)
-{
- gf_common_rsp rsp = {0,};
-
- /* Accepted */
- rsp.op_ret = 0;
-
- server_submit_reply (NULL, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gf_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,};
- client_t *client = NULL;
- server_ctx_t *serv_ctx = NULL;
- xlator_t *this = NULL;
-
- this = req->svc->mydata;
- //TODO: Decide on an appropriate errno for the error-path
- //below
- if (!this)
- goto fail;
-
- op_ret = xdr_to_generic (req->msg[0], &args,
- (xdrproc_t)xdr_gf_set_lk_ver_req);
- if (op_ret < 0) {
- //failed to decode msg;
- req->rpc_err = GARBAGE_ARGS;
- goto fail;
- }
-
- client = gf_client_get (this, &req->cred, args.uid);
- serv_ctx = server_ctx_get (client, client->this);
- if (serv_ctx == NULL) {
- gf_log (this->name, GF_LOG_INFO, "server_ctx_get() failed");
- goto fail;
- }
-
- serv_ctx->lk_version = args.lk_ver;
- rsp.lk_ver = args.lk_ver;
-
- op_ret = 0;
-fail:
- if (client)
- gf_client_put (client, NULL);
-
- 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_MAXVALUE] = {
- [GF_HNDSK_NULL] = {"NULL", GF_HNDSK_NULL, server_null, NULL, 0, DRC_NA},
- [GF_HNDSK_SETVOLUME] = {"SETVOLUME", GF_HNDSK_SETVOLUME, server_setvolume, NULL, 0, DRC_NA},
- [GF_HNDSK_GETSPEC] = {"GETSPEC", GF_HNDSK_GETSPEC, server_getspec, NULL, 0, DRC_NA},
- [GF_HNDSK_PING] = {"PING", GF_HNDSK_PING, server_ping, NULL, 0, DRC_NA},
- [GF_HNDSK_SET_LK_VER] = {"SET_LK_VER", GF_HNDSK_SET_LK_VER, server_set_lk_version, NULL, 0, DRC_NA},
-};
-
-
-struct rpcsvc_program gluster_handshake_prog = {
- .progname = "GlusterFS Handshake",
- .prognum = GLUSTER_HNDSK_PROGRAM,
- .progver = GLUSTER_HNDSK_VERSION,
- .actors = gluster_handshake_actors,
- .numactors = GF_HNDSK_MAXVALUE,
-};
diff --git a/xlators/protocol/server/src/server-helpers.c b/xlators/protocol/server/src/server-helpers.c
index 545be6e9580..7b99ded2314 100644
--- a/xlators/protocol/server/src/server-helpers.c
+++ b/xlators/protocol/server/src/server-helpers.c
@@ -1,11 +1,20 @@
/*
- Copyright (c) 2010-2013 Red Hat, Inc. <http://www.redhat.com>
+ Copyright (c) 2006-2009 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 General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that 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
@@ -13,143 +22,150 @@
#include "config.h"
#endif
-#include "server.h"
+#include "server-protocol.h"
#include "server-helpers.h"
-#include "gidcache.h"
-#include <fnmatch.h>
-#include <pwd.h>
-#include <grp.h>
-/* based on nfs_fix_aux_groups() */
+/* server_loc_fill - derive a loc_t for a given inode number
+ *
+ * NOTE: make sure that @loc is empty, because any pointers it holds with reference will
+ * be leaked after returning from here.
+ */
int
-gid_resolve (server_conf_t *conf, call_stack_t *root)
+server_loc_fill (loc_t *loc, server_state_t *state,
+ ino_t ino, ino_t par,
+ const char *name, const char *path)
{
- int ret = 0;
- struct passwd mypw;
- char mystrs[1024];
- struct passwd *result;
- gid_t mygroups[GF_MAX_AUX_GROUPS];
- gid_list_t gl;
- const gid_list_t *agl;
- int ngroups, i;
-
- agl = gid_cache_lookup (&conf->gid_cache, root->uid, 0, 0);
- if (agl) {
- root->ngrps = agl->gl_count;
- goto fill_groups;
- }
+ inode_t *inode = NULL;
+ inode_t *parent = NULL;
+ int32_t ret = -1;
+ char *dentry_path = NULL;
- ret = getpwuid_r (root->uid, &mypw, mystrs, sizeof(mystrs), &result);
- if (ret != 0) {
- gf_log("gid-cache", GF_LOG_ERROR, "getpwuid_r(%u) failed",
- root->uid);
- return -1;
- }
- if (!result) {
- gf_log ("gid-cache", GF_LOG_ERROR, "getpwuid_r(%u) found "
- "nothing", root->uid);
- return -1;
- }
+ GF_VALIDATE_OR_GOTO ("server", loc, out);
+ GF_VALIDATE_OR_GOTO ("server", state, out);
+ GF_VALIDATE_OR_GOTO ("server", path, out);
+
+ /* anything beyond this point is success */
+ ret = 0;
+ loc->ino = ino;
+ inode = loc->inode;
+ if (inode == NULL) {
+ if (ino)
+ inode = inode_search (state->itable, ino, NULL);
- gf_log ("gid-cache", GF_LOG_TRACE, "mapped %u => %s", root->uid,
- result->pw_name);
+ if ((inode == NULL) &&
+ (par && name))
+ inode = inode_search (state->itable, par, name);
- ngroups = GF_MAX_AUX_GROUPS;
- ret = getgrouplist (result->pw_name, root->gid, mygroups, &ngroups);
- if (ret == -1) {
- gf_log ("gid-cache", GF_LOG_ERROR, "could not map %s to group "
- "list (%d gids)", result->pw_name, root->ngrps);
- return -1;
+ loc->inode = inode;
+ if (inode)
+ loc->ino = inode->ino;
}
- root->ngrps = (uint16_t) ngroups;
-fill_groups:
- if (agl) {
- /* the gl is not complete, we only use gl.gl_list later on */
- gl.gl_list = agl->gl_list;
- } else {
- /* setup a full gid_list_t to add it to the gid_cache */
- gl.gl_id = root->uid;
- gl.gl_uid = root->uid;
- gl.gl_gid = root->gid;
- gl.gl_count = root->ngrps;
-
- gl.gl_list = GF_MALLOC (root->ngrps * sizeof(gid_t),
- gf_common_mt_groups_t);
- if (gl.gl_list)
- memcpy (gl.gl_list, mygroups,
- sizeof(gid_t) * root->ngrps);
+ parent = loc->parent;
+ if (parent == NULL) {
+ if (inode)
+ parent = inode_parent (inode, par, name);
else
- return -1;
- }
-
- if (root->ngrps == 0) {
- ret = 0;
- goto out;
+ parent = inode_search (state->itable, par, NULL);
+ loc->parent = parent;
}
- if (call_stack_alloc_groups (root, root->ngrps) != 0) {
- ret = -1;
- goto out;
+ if (name && parent) {
+ ret = inode_path (parent, name, &dentry_path);
+ if (ret < 0) {
+ gf_log (state->bound_xl->name, GF_LOG_DEBUG,
+ "failed to build path for %"PRId64"/%s: %s",
+ parent->ino, name, strerror (-ret));
+ }
+ } else if (inode) {
+ ret = inode_path (inode, NULL, &dentry_path);
+ if (ret < 0) {
+ gf_log (state->bound_xl->name, GF_LOG_DEBUG,
+ "failed to build path for %"PRId64": %s",
+ inode->ino, strerror (-ret));
+ }
}
- /* finally fill the groups from the */
- for (i = 0; i < root->ngrps; ++i)
- root->groups[i] = gl.gl_list[i];
+ if (dentry_path) {
+ if (strcmp (dentry_path, path)) {
+ gf_log (state->bound_xl->name, GF_LOG_DEBUG,
+ "paths differ for inode(%"PRId64"): "
+ "client path = %s. dentry path = %s",
+ ino, path, dentry_path);
+ }
-out:
- if (agl) {
- gid_cache_release (&conf->gid_cache, agl);
+ loc->path = dentry_path;
+ loc->name = strrchr (loc->path, '/');
+ if (loc->name)
+ loc->name++;
} else {
- if (gid_cache_add (&conf->gid_cache, &gl) != 1)
- GF_FREE (gl.gl_list);
+ loc->path = strdup (path);
+ loc->name = strrchr (loc->path, '/');
+ if (loc->name)
+ loc->name++;
}
- return ret;
-}
-
-int
-server_resolve_groups (call_frame_t *frame, rpcsvc_request_t *req)
-{
- xlator_t *this = NULL;
- server_conf_t *conf = NULL;
-
- GF_VALIDATE_OR_GOTO ("server", frame, out);
- GF_VALIDATE_OR_GOTO ("server", req, out);
-
- this = req->trans->xl;
- conf = this->private;
-
- return gid_resolve (conf, frame->root);
out:
- return -1;
+ return ret;
}
-int
-server_decode_groups (call_frame_t *frame, rpcsvc_request_t *req)
+/*
+ * stat_to_str - convert struct stat to a ASCII string
+ * @stbuf: struct stat pointer
+ *
+ * not for external reference
+ */
+char *
+stat_to_str (struct stat *stbuf)
{
- int i = 0;
-
- GF_VALIDATE_OR_GOTO ("server", frame, out);
- GF_VALIDATE_OR_GOTO ("server", req, out);
-
- if (call_stack_alloc_groups (frame->root, req->auxgidcount) != 0)
- return -1;
-
- frame->root->ngrps = req->auxgidcount;
- if (frame->root->ngrps == 0)
- return 0;
-
- /* ngrps cannot be bigger than USHRT_MAX(65535) */
- if (frame->root->ngrps > GF_MAX_AUX_GROUPS)
- return -1;
-
- for (; i < frame->root->ngrps; ++i)
- frame->root->groups[i] = req->auxgids[i];
-out:
- return 0;
+ int ret = 0;
+ char *tmp_buf = NULL;
+
+ uint64_t dev = stbuf->st_dev;
+ uint64_t ino = stbuf->st_ino;
+ uint32_t mode = stbuf->st_mode;
+ uint32_t nlink = stbuf->st_nlink;
+ uint32_t uid = stbuf->st_uid;
+ uint32_t gid = stbuf->st_gid;
+ uint64_t rdev = stbuf->st_rdev;
+ uint64_t size = stbuf->st_size;
+ uint32_t blksize = stbuf->st_blksize;
+ uint64_t blocks = stbuf->st_blocks;
+ uint32_t atime = stbuf->st_atime;
+ uint32_t mtime = stbuf->st_mtime;
+ uint32_t ctime = stbuf->st_ctime;
+
+ uint32_t atime_nsec = ST_ATIM_NSEC(stbuf);
+ uint32_t mtime_nsec = ST_MTIM_NSEC(stbuf);
+ uint32_t ctime_nsec = ST_CTIM_NSEC(stbuf);
+
+
+ ret = asprintf (&tmp_buf,
+ GF_STAT_PRINT_FMT_STR,
+ dev,
+ ino,
+ mode,
+ nlink,
+ uid,
+ gid,
+ rdev,
+ size,
+ blksize,
+ blocks,
+ atime,
+ atime_nsec,
+ mtime,
+ mtime_nsec,
+ ctime,
+ ctime_nsec);
+ if (-1 == ret) {
+ gf_log ("protocol/server", GF_LOG_DEBUG,
+ "asprintf failed while setting up stat buffer string");
+ return NULL;
+ }
+ return tmp_buf;
}
@@ -166,38 +182,52 @@ server_loc_wipe (loc_t *loc)
loc->inode = NULL;
}
- GF_FREE ((void *)loc->path);
+ if (loc->path)
+ FREE (loc->path);
}
void
server_resolve_wipe (server_resolve_t *resolve)
{
- GF_FREE ((void *)resolve->path);
+ struct resolve_comp *comp = NULL;
+ int i = 0;
- GF_FREE ((void *)resolve->bname);
+ if (resolve->path)
+ FREE (resolve->path);
- loc_wipe (&resolve->resolve_loc);
+ if (resolve->bname)
+ FREE (resolve->bname);
+
+ if (resolve->resolved)
+ 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);
+ }
+ FREE (resolve->components);
+ }
}
void
free_state (server_state_t *state)
{
- if (state->xprt) {
- rpc_transport_unref (state->xprt);
- state->xprt = NULL;
+ 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;
@@ -213,14 +243,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)
+ FREE (state->volume);
- GF_FREE ((void *)state->name);
+ if (state->name)
+ FREE (state->name);
server_loc_wipe (&state->loc);
server_loc_wipe (&state->loc2);
@@ -228,982 +255,687 @@ free_state (server_state_t *state)
server_resolve_wipe (&state->resolve);
server_resolve_wipe (&state->resolve2);
- GF_FREE (state);
+ FREE (state);
}
-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)
+call_frame_t *
+server_copy_frame (call_frame_t *frame)
{
- int32_t ret = -1;
- fd_t *fd = NULL;
- client_t *client = NULL;
+ call_frame_t *new_frame = NULL;
+ server_state_t *state = NULL, *new_state = NULL;
- GF_VALIDATE_OR_GOTO ("server", this, out);
- GF_VALIDATE_OR_GOTO ("server", frame, out);
+ state = frame->root->state;
- fd = frame->local;
- client = frame->root->client;
+ new_frame = copy_frame (frame);
- fd_unref (fd);
- frame->local = NULL;
+ new_state = CALLOC (1, sizeof (server_state_t));
- gf_client_unref (client);
- STACK_DESTROY (frame->root);
+ new_frame->root->op = frame->root->op;
+ new_frame->root->type = frame->root->type;
+ new_frame->root->trans = state->trans;
+ new_frame->root->state = new_state;
- ret = 0;
-out:
- return ret;
-}
+ new_state->bound_xl = state->bound_xl;
+ new_state->trans = transport_ref (state->trans);
+ new_state->itable = state->itable;
+ new_state->resolve.fd_no = -1;
+ new_state->resolve2.fd_no = -1;
-static int
-do_fd_cleanup (xlator_t *this, client_t* client, 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;
- char *path = NULL;
-
- GF_VALIDATE_OR_GOTO ("server", this, out);
- GF_VALIDATE_OR_GOTO ("server", fdentries, out);
-
- bound_xl = client->bound_xl;
- for (i = 0;i < fd_count; i++) {
- fd = fdentries[i].fd;
-
- if (fd != NULL) {
- tmp_frame = create_frame (this, this->ctx->pool);
- if (tmp_frame == NULL) {
- goto out;
- }
-
- GF_ASSERT (fd->inode);
-
- ret = inode_path (fd->inode, NULL, &path);
+ return new_frame;
+}
- if (ret > 0) {
- gf_log (this->name, GF_LOG_INFO,
- "fd cleanup on %s", path);
- GF_FREE (path);
- } else {
- gf_log (this->name, GF_LOG_INFO,
- "fd cleanup on inode with gfid %s",
- uuid_utoa (fd->inode->gfid));
- }
+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 = CALLOC (1, sizeof (struct _locker));
+ if (new == NULL) {
+ gf_log ("server", GF_LOG_ERROR,
+ "failed to allocate memory for \'struct _locker\'");
+ goto out;
+ }
+ INIT_LIST_HEAD (&new->lockers);
- tmp_frame->local = fd;
- tmp_frame->root->pid = 0;
- gf_client_ref (client);
- tmp_frame->root->client = client;
- memset (&tmp_frame->root->lk_owner, 0,
- sizeof (gf_lkowner_t));
+ new->volume = strdup (volume);
- STACK_WIND (tmp_frame,
- server_connection_cleanup_flush_cbk,
- bound_xl, bound_xl->fops->flush, fd, NULL);
- }
+ if (fd == NULL) {
+ loc_copy (&new->loc, loc);
+ dir = S_ISDIR (new->loc.inode->st_mode);
+ } else {
+ new->fd = fd_ref (fd);
+ dir = S_ISDIR (fd->inode->st_mode);
}
- GF_FREE (fdentries);
- ret = 0;
+ 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;
}
int
-server_connection_cleanup (xlator_t *this, client_t *client,
- int32_t flags)
+gf_del_locker (struct _lock_table *table, const char *volume,
+ loc_t *loc, fd_t *fd, pid_t pid)
{
- server_ctx_t *serv_ctx = NULL;
- fdentry_t *fdentries = NULL;
- uint32_t fd_count = 0;
- int cd_ret = 0;
- int ret = 0;
-
- GF_VALIDATE_OR_GOTO (this->name, this, out);
- GF_VALIDATE_OR_GOTO (this->name, client, out);
- GF_VALIDATE_OR_GOTO (this->name, flags, out);
+ 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;
- serv_ctx = server_ctx_get (client, client->this);
+ INIT_LIST_HEAD (&del);
- if (serv_ctx == NULL) {
- gf_log (this->name, GF_LOG_INFO, "server_ctx_get() failed");
- goto out;
+ if (fd) {
+ dir = S_ISDIR (fd->inode->st_mode);
+ } else {
+ dir = S_ISDIR (loc->inode->st_mode);
}
- LOCK (&serv_ctx->fdtable_lock);
+ LOCK (&table->lock);
{
- if (serv_ctx->fdtable && (flags & POSIX_LOCKS))
- fdentries = gf_fd_fdtable_get_all_fds (serv_ctx->fdtable,
- &fd_count);
- }
- UNLOCK (&serv_ctx->fdtable_lock);
-
- if (client->bound_xl == NULL)
- goto out;
+ if (dir) {
+ head = &table->dir_lockers;
+ } else {
+ head = &table->file_lockers;
+ }
- if (flags & INTERNAL_LOCKS) {
- cd_ret = gf_client_disconnect (client);
+ 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);
- if (fdentries != NULL)
- ret = do_fd_cleanup (this, client, fdentries, fd_count);
- else
- gf_log (this->name, GF_LOG_INFO, "no fdentries to clean");
+ tmp = NULL;
+ locker = NULL;
- if (cd_ret || ret)
- ret = -1;
+ 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);
+
+ free (locker->volume);
+ free (locker);
+ }
-out:
return ret;
}
-static call_frame_t *
-server_alloc_frame (rpcsvc_request_t *req)
+int
+gf_direntry_to_bin (dir_entry_t *head, char *buffer)
{
- call_frame_t *frame = NULL;
- server_state_t *state = NULL;
- client_t *client = NULL;
-
- GF_VALIDATE_OR_GOTO ("server", req, out);
- GF_VALIDATE_OR_GOTO ("server", req->trans, out);
- GF_VALIDATE_OR_GOTO ("server", req->svc, out);
- GF_VALIDATE_OR_GOTO ("server", req->svc->ctx, out);
-
- client = req->trans->xl_private;
- GF_VALIDATE_OR_GOTO ("server", client, out);
-
- frame = create_frame (client->this, req->svc->ctx->pool);
- if (!frame)
- goto out;
+ dir_entry_t *trav = NULL;
+ uint32_t len = 0;
+ uint32_t this_len = 0;
+ size_t buflen = -1;
+ char *ptr = NULL;
+ char *tmp_buf = NULL;
+
+ trav = head->next;
+ while (trav) {
+ len += strlen (trav->name);
+ len += 1;
+ len += strlen (trav->link);
+ len += 1; /* for '\n' */
+ len += 256; // max possible for statbuf;
+ trav = trav->next;
+ }
- state = GF_CALLOC (1, sizeof (*state), gf_server_mt_state_t);
- if (!state)
- goto out;
+ ptr = buffer;
+ trav = head->next;
+ while (trav) {
+ tmp_buf = stat_to_str (&trav->buf);
+ /* tmp_buf will have \n before \0 */
- if (client->bound_xl)
- state->itable = client->bound_xl->itable;
+ this_len = sprintf (ptr, "%s/%s%s\n",
+ trav->name, tmp_buf,
+ trav->link);
- state->xprt = rpc_transport_ref (req->trans);
- state->resolve.fd_no = -1;
- state->resolve2.fd_no = -1;
+ FREE (tmp_buf);
+ trav = trav->next;
+ ptr += this_len;
+ }
- frame->root->client = client;
- frame->root->state = state; /* which socket */
- frame->root->unique = 0; /* which call */
+ buflen = strlen (buffer);
- frame->this = client->this;
-out:
- return frame;
+ return buflen;
}
-call_frame_t *
-get_frame_from_request (rpcsvc_request_t *req)
+static struct _lock_table *
+gf_lock_table_new (void)
{
- call_frame_t *frame = NULL;
- client_t *client = NULL;
- client_t *tmp_client = NULL;
- xlator_t *this = NULL;
- server_conf_t *priv = NULL;
- clienttable_t *clienttable = NULL;
- unsigned int i = 0;
-
- GF_VALIDATE_OR_GOTO ("server", req, out);
-
- client = req->trans->xl_private;
+ struct _lock_table *new = NULL;
- frame = server_alloc_frame (req);
- if (!frame)
+ new = CALLOC (1, sizeof (struct _lock_table));
+ if (new == NULL) {
+ gf_log ("server-protocol", GF_LOG_CRITICAL,
+ "failed to allocate memory for new lock table");
goto out;
-
- frame->root->op = req->procnum;
-
- frame->root->unique = req->xid;
-
- client = req->trans->xl_private;
- this = req->trans->xl;
- priv = this->private;
- clienttable = this->ctx->clienttable;
-
- for (i = 0; i < clienttable->max_clients; i++) {
- tmp_client = clienttable->cliententries[i].client;
- if (client == tmp_client) {
- /* for non trusted clients username and password
- would not have been set. So for non trusted clients
- (i.e clients not from the same machine as the brick,
- and clients from outside the storage pool)
- do the root-squashing.
- TODO: If any client within the storage pool (i.e
- mounting within a machine from the pool but using
- other machine's ip/hostname from the same pool)
- is present treat it as a trusted client
- */
- if (!client->auth.username && req->pid != NFS_PID)
- RPC_AUTH_ROOT_SQUASH (req);
-
- /* Problem: If we just check whether the client is
- trusted client and do not do root squashing for
- them, then for smb clients and UFO clients root
- squashing will never happen as they use the fuse
- mounts done within the trusted pool (i.e they are
- trusted clients).
- Solution: To fix it, do root squashing for trusted
- clients also. If one wants to have a client within
- the storage pool for which root-squashing does not
- happen, then the client has to be mounted with
- --no-root-squash option. But for defrag client and
- gsyncd client do not do root-squashing.
- */
- if (client->auth.username &&
- req->pid != GF_CLIENT_PID_NO_ROOT_SQUASH &&
- req->pid != GF_CLIENT_PID_GSYNCD &&
- req->pid != GF_CLIENT_PID_DEFRAG &&
- req->pid != GF_CLIENT_PID_AFR_SELF_HEALD &&
- req->pid != GF_CLIENT_PID_QUOTA_MOUNT)
- RPC_AUTH_ROOT_SQUASH (req);
-
- /* For nfs clients the server processes will be running
- within the trusted storage pool machines. So if we
- do not do root-squashing for nfs servers, thinking
- that its a trusted client, then root-squashing wont
- work for nfs clients.
- */
- if (req->pid == NFS_PID)
- RPC_AUTH_ROOT_SQUASH (req);
- }
}
-
- frame->root->uid = req->uid;
- frame->root->gid = req->gid;
- frame->root->pid = req->pid;
- gf_client_ref (client);
- frame->root->client = client;
- frame->root->lk_owner = req->lk_owner;
-
- if (priv->server_manage_gids)
- server_resolve_groups (frame, req);
- else
- server_decode_groups (frame, req);
-
- frame->local = req;
+ INIT_LIST_HEAD (&new->dir_lockers);
+ INIT_LIST_HEAD (&new->file_lockers);
+ LOCK_INIT (&new->lock);
out:
- return frame;
+ return new;
}
int
-server_build_config (xlator_t *this, server_conf_t *conf)
+do_lock_table_cleanup (xlator_t *this, server_connection_t *conn,
+ call_frame_t *frame, struct _lock_table *ltable)
{
- data_t *data = NULL;
- int ret = -1;
- struct stat buf = {0,};
-
- GF_VALIDATE_OR_GOTO ("server", this, out);
- GF_VALIDATE_OR_GOTO ("server", conf, out);
-
- ret = dict_get_int32 (this->options, "inode-lru-limit",
- &conf->inode_lru_limit);
- if (ret < 0) {
- conf->inode_lru_limit = 16384;
- }
-
- conf->verify_volfile = 1;
- data = dict_get (this->options, "verify-volfile-checksum");
- if (data) {
- ret = gf_string2boolean(data->data, &conf->verify_volfile);
- if (ret != 0) {
- gf_log (this->name, GF_LOG_WARNING,
- "wrong value for 'verify-volfile-checksum', "
- "Neglecting option");
- }
- }
+ struct list_head file_lockers, dir_lockers;
+ call_frame_t *tmp_frame = NULL;
+ struct 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);
- data = dict_get (this->options, "trace");
- if (data) {
- ret = gf_string2boolean (data->data, &conf->trace);
- if (ret != 0) {
- gf_log (this->name, GF_LOG_WARNING,
- "'trace' takes on only boolean values. "
- "Neglecting option");
- }
+ list_splice_init (&ltable->dir_lockers, &dir_lockers);
}
+ UNLOCK (&ltable->lock);
- /* TODO: build_rpc_config (); */
- ret = dict_get_int32 (this->options, "limits.transaction-size",
- &conf->rpc_conf.max_block_size);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_TRACE,
- "defaulting limits.transaction-size to %d",
- DEFAULT_BLOCK_SIZE);
- conf->rpc_conf.max_block_size = DEFAULT_BLOCK_SIZE;
- }
+ free (ltable);
- data = dict_get (this->options, "config-directory");
- if (data) {
- /* Check whether the specified directory exists,
- or directory specified is non standard */
- ret = stat (data->data, &buf);
- if ((ret != 0) || !S_ISDIR (buf.st_mode)) {
+ 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,
- "Directory '%s' doesn't exist, exiting.",
- data->data);
- ret = -1;
+ "out of memory");
goto out;
}
- /* Make sure that conf-dir doesn't contain ".." in path */
- if ((gf_strstr (data->data, "/", "..")) == -1) {
- ret = -1;
- gf_log (this->name, GF_LOG_ERROR,
- "%s: invalid conf_dir", data->data);
- 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, 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, server_nop_cbk,
+ bound_xl,
+ bound_xl->fops->inodelk,
+ locker->volume,
+ &(locker->loc), F_SETLK, &flock);
+ loc_wipe (&locker->loc);
}
- conf->conf_dir = gf_strdup (data->data);
- }
- ret = 0;
-out:
- return ret;
-}
-
-
-void
-print_caller (char *str, int size, call_frame_t *frame)
-{
- server_state_t *state = NULL;
-
- GF_VALIDATE_OR_GOTO ("server", str, out);
- GF_VALIDATE_OR_GOTO ("server", frame, out);
-
- state = CALL_STATE (frame);
-
- snprintf (str, size,
- " Callid=%"PRId64", Client=%s",
- frame->root->unique,
- state->xprt->peerinfo.identifier);
-
-out:
- return;
-}
-
-
-void
-server_print_resolve (char *str, int size, server_resolve_t *resolve)
-{
- int filled = 0;
+ free (locker->volume);
+
+ list_del_init (&locker->lockers);
+ 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, 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, server_nop_cbk,
+ bound_xl,
+ bound_xl->fops->entrylk,
+ locker->volume,
+ &(locker->loc), NULL,
+ ENTRYLK_UNLOCK, ENTRYLK_WRLCK);
+ loc_wipe (&locker->loc);
+ }
- GF_VALIDATE_OR_GOTO ("server", str, out);
+ free (locker->volume);
- if (!resolve) {
- snprintf (str, size, "<nul>");
- return;
+ list_del_init (&locker->lockers);
+ free (locker);
}
+ ret = 0;
- 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->bname)
- filled += snprintf (str + filled, size - filled,
- "bname=%s,", resolve->bname);
- if (resolve->path)
- filled += snprintf (str + filled, size - filled,
- "path=%s", resolve->path);
-
- snprintf (str + filled, size - filled, "}");
out:
- return;
+ return ret;
}
-void
-server_print_loc (char *str, int size, loc_t *loc)
+static int
+server_connection_cleanup_flush_cbk (call_frame_t *frame, void *cookie,
+ xlator_t *this, int32_t op_ret,
+ int32_t op_errno)
{
- int filled = 0;
-
- GF_VALIDATE_OR_GOTO ("server", str, out);
-
- 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);
-
- snprintf (str + filled, size - filled, "}");
-out:
- return;
-}
+ fd_t *fd = NULL;
+ fd = frame->local;
-void
-server_print_params (char *str, int size, server_state_t *state)
-{
- int filled = 0;
-
- GF_VALIDATE_OR_GOTO ("server", str, out);
-
- 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);
+ fd_unref (fd);
+ frame->local = NULL;
-/* FIXME
- snprintf (str + filled, size - filled,
- "bound_xl=%s}", state->client->bound_xl->name);
-*/
-out:
- return;
+ STACK_DESTROY (frame->root);
+ return 0;
}
int
-server_resolve_is_empty (server_resolve_t *resolve)
-{
- if (resolve->fd_no != -1)
- return 0;
-
- if (resolve->path != 0)
- return 0;
-
- if (resolve->bname != 0)
- return 0;
-
- return 1;
-}
-
-
-void
-server_print_reply (call_frame_t *frame, int op_ret, int op_errno)
+do_fd_cleanup (xlator_t *this, server_connection_t *conn, call_frame_t *frame,
+ fdentry_t *fdentries, int fd_count)
{
- server_conf_t *conf = NULL;
- server_state_t *state = NULL;
- xlator_t *this = NULL;
- char caller[512];
- char fdstr[32];
- char *op = "UNKNOWN";
-
- GF_VALIDATE_OR_GOTO ("server", frame, out);
-
- this = frame->this;
- conf = this->private;
-
- GF_VALIDATE_OR_GOTO ("server", conf, out);
- GF_VALIDATE_OR_GOTO ("server", conf->trace, out);
+ fd_t *fd = NULL;
+ int i = 0, ret = -1;
+ call_frame_t *tmp_frame = NULL;
+ xlator_t *bound_xl = NULL;
- state = CALL_STATE (frame);
+ bound_xl = conn->bound_xl;
+ for (i = 0;i < fd_count; i++) {
+ fd = fdentries[i].fd;
- print_caller (caller, 256, frame);
+ 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;
- switch (frame->root->type) {
- case GF_OP_TYPE_FOP:
- op = (char *)gf_fop_list[frame->root->op];
- break;
- default:
- op = "";
+ 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);
+ }
}
- fdstr[0] = '\0';
- if (state->fd)
- snprintf (fdstr, 32, " fd=%p", state->fd);
+ FREE (fdentries);
+ ret = 0;
- gf_log (this->name, GF_LOG_INFO,
- "%s%s => (%d, %d)%s",
- op, caller, op_ret, op_errno, fdstr);
out:
- return;
+ return ret;
}
-
-void
-server_print_request (call_frame_t *frame)
+int
+do_connection_cleanup (xlator_t *this, server_connection_t *conn,
+ struct _lock_table *ltable, fdentry_t *fdentries, int fd_count)
{
- server_conf_t *conf = NULL;
- xlator_t *this = NULL;
- server_state_t *state = NULL;
- char *op = "UNKNOWN";
- char resolve_vars[256];
- char resolve2_vars[256];
- char loc_vars[256];
- char loc2_vars[256];
- char other_vars[512];
- char caller[512];
-
- GF_VALIDATE_OR_GOTO ("server", frame, out);
-
- this = frame->this;
- conf = this->private;
-
- GF_VALIDATE_OR_GOTO ("server", conf, out);
-
- if (!conf->trace)
+ int ret = 0;
+ int saved_ret = 0;
+ call_frame_t *frame = NULL;
+ server_state_t *state = NULL;
+
+ frame = create_frame (this, this->ctx->pool);
+ if (frame == NULL) {
+ gf_log (this->name, GF_LOG_ERROR, "out of memory");
goto out;
+ }
- state = CALL_STATE (frame);
-
- 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);
+ saved_ret = do_lock_table_cleanup (this, conn, frame, ltable);
- if (!server_resolve_is_empty (&state->resolve)) {
- server_print_resolve (resolve_vars, 256, &state->resolve);
- server_print_loc (loc_vars, 256, &state->loc);
+ if (fdentries != NULL) {
+ ret = do_fd_cleanup (this, conn, frame, fdentries, fd_count);
}
- if (!server_resolve_is_empty (&state->resolve2)) {
- server_print_resolve (resolve2_vars, 256, &state->resolve2);
- server_print_loc (loc2_vars, 256, &state->loc2);
- }
+ state = CALL_STATE (frame);
+ if (state)
+ free (state);
- server_print_params (other_vars, 512, state);
+ STACK_DESTROY (frame->root);
- switch (frame->root->type) {
- case GF_OP_TYPE_FOP:
- op = (char *)gf_fop_list[frame->root->op];
- break;
- default:
- op = "";
- break;
+ if (saved_ret || ret) {
+ ret = -1;
}
- gf_log (this->name, GF_LOG_INFO,
- "%s%s%s%s%s%s%s",
- op, caller,
- resolve_vars, loc_vars, resolve2_vars, loc2_vars, other_vars);
out:
- return;
+ return ret;
}
int
-serialize_rsp_direntp (gf_dirent_t *entries, gfs3_readdirp_rsp *rsp)
+server_connection_cleanup (xlator_t *this, server_connection_t *conn)
{
- gf_dirent_t *entry = NULL;
- gfs3_dirplist *trav = NULL;
- gfs3_dirplist *prev = NULL;
- int ret = -1;
-
- GF_VALIDATE_OR_GOTO ("server", entries, out);
- GF_VALIDATE_OR_GOTO ("server", rsp, out);
-
- list_for_each_entry (entry, &entries->list, list) {
- trav = GF_CALLOC (1, sizeof (*trav), gf_server_mt_dirent_rsp_t);
- if (!trav)
- goto out;
+ char do_cleanup = 0;
+ struct _lock_table *ltable = NULL;
+ fdentry_t *fdentries = NULL;
+ uint32_t fd_count = 0;
+ int ret = 0;
- trav->d_ino = entry->d_ino;
- trav->d_off = entry->d_off;
- trav->d_len = entry->d_len;
- trav->d_type = entry->d_type;
- 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 > UINT_MAX) {
- gf_log (THIS->name, GF_LOG_ERROR,
- "failed to get serialized length "
- "of reply dict");
- errno = EINVAL;
- trav->dict.dict_len = 0;
- goto out;
- }
+ if (conn == NULL) {
+ 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;
+ 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 ();
}
- 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 (conn->fdtable) {
+ fdentries = gf_fd_fdtable_get_all_fds (conn->fdtable,
+ &fd_count);
}
+ do_cleanup = 1;
}
-
- if (prev)
- prev->nextentry = trav;
- else
- rsp->reply = trav;
-
- prev = trav;
- trav = NULL;
}
+ pthread_mutex_unlock (&conn->lock);
+
+ if (do_cleanup) {
+ if (conn->bound_xl) {
+ ret = do_connection_cleanup (this, conn, ltable, fdentries, fd_count);
+ } else {
+ if (ltable){
+ free(ltable);
+ ltable = NULL;
+ }
+ if (fdentries){
+ free(fdentries);
+ fdentries = NULL;
+ }
+ }
+ }
- ret = 0;
out:
- GF_FREE (trav);
-
return ret;
}
int
-serialize_rsp_dirent (gf_dirent_t *entries, gfs3_readdir_rsp *rsp)
+server_connection_destroy (xlator_t *this, server_connection_t *conn)
{
- gf_dirent_t *entry = NULL;
- gfs3_dirlist *trav = NULL;
- gfs3_dirlist *prev = NULL;
- int ret = -1;
-
- GF_VALIDATE_OR_GOTO ("server", entries, out);
- GF_VALIDATE_OR_GOTO ("server", rsp, out);
-
- list_for_each_entry (entry, &entries->list, list) {
- trav = GF_CALLOC (1, sizeof (*trav), gf_server_mt_dirent_rsp_t);
- if (!trav)
- goto out;
- trav->d_ino = entry->d_ino;
- trav->d_off = entry->d_off;
- trav->d_len = entry->d_len;
- trav->d_type = entry->d_type;
- trav->name = entry->d_name;
- if (prev)
- prev->nextentry = trav;
- else
- rsp->reply = trav;
-
- prev = trav;
- }
-
- ret = 0;
-out:
- return ret;
-}
-
-
-int
-readdir_rsp_cleanup (gfs3_readdir_rsp *rsp)
-{
- gfs3_dirlist *prev = NULL;
- gfs3_dirlist *trav = NULL;
+ 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 file_lockers;
+ struct list_head dir_lockers;
+ struct _lock_table *ltable = NULL;
+ struct _locker *locker = NULL, *tmp = NULL;
+ struct flock flock = {0,};
+ fd_t *fd = NULL;
+ int32_t i = 0;
+ fdentry_t *fdentries = NULL;
+ uint32_t fd_count = 0;
- trav = rsp->reply;
- prev = trav;
- while (trav) {
- trav = trav->nextentry;
- GF_FREE (prev);
- prev = trav;
+ if (conn == NULL) {
+ ret = 0;
+ goto out;
}
- return 0;
-}
-
+ pthread_mutex_lock (&(conn->lock));
+ {
+ if (conn->ltable) {
+ ltable = conn->ltable;
+ conn->ltable = NULL;
+ }
+ }
+ pthread_mutex_unlock (&conn->lock);
+
+ 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);
+
+ 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);
+
+ INIT_LIST_HEAD (&file_lockers);
+ INIT_LIST_HEAD (&dir_lockers);
+
+ LOCK (&ltable->lock);
+ {
+ list_splice_init (&ltable->file_lockers,
+ &file_lockers);
-int
-readdirp_rsp_cleanup (gfs3_readdirp_rsp *rsp)
-{
- gfs3_dirplist *prev = NULL;
- gfs3_dirplist *trav = NULL;
+ list_splice_init (&ltable->dir_lockers, &dir_lockers);
+ }
+ UNLOCK (&ltable->lock);
+ 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, 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, server_nop_cbk,
+ bound_xl,
+ bound_xl->fops->inodelk,
+ locker->volume,
+ &(locker->loc), F_SETLK, &flock);
+ loc_wipe (&locker->loc);
+ }
- trav = rsp->reply;
- prev = trav;
- while (trav) {
- trav = trav->nextentry;
- GF_FREE (prev->dict.dict_val);
- GF_FREE (prev);
- prev = trav;
- }
+ free (locker->volume);
- return 0;
-}
+ list_del_init (&locker->lockers);
+ free (locker);
+ }
+ tmp = NULL;
+ locker = NULL;
+ list_for_each_entry_safe (locker, tmp, &dir_lockers, lockers) {
+ tmp_frame = copy_frame (frame);
-int
-gf_server_check_getxattr_cmd (call_frame_t *frame, const char *key)
-{
+ tmp_frame->root->pid = 0;
+ tmp_frame->root->trans = conn;
+
+ if (locker->fd) {
+ 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 {
+ 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);
+ }
- server_conf_t *conf = NULL;
- rpc_transport_t *xprt = NULL;
+ free (locker->volume);
- conf = frame->this->private;
- if (!conf)
- return 0;
+ list_del_init (&locker->lockers);
+ free (locker);
+ }
- 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);
+ 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);
+ }
}
+ FREE (fdentries);
}
- pthread_mutex_unlock (&conf->mutex);
- }
-
- /* Add more options/keys here */
-
- return 0;
-}
-
+ } else {
+ if (ltable){
+ free(ltable);
+ ltable = NULL;
+ }
+ if (fdentries){
+ free(fdentries);
+ fdentries = NULL;
+ }
+ }
-int
-gf_server_check_setxattr_cmd (call_frame_t *frame, dict_t *dict)
-{
+ if (frame) {
+ state = CALL_STATE (frame);
+ if (state)
+ free (state);
+ STACK_DESTROY (frame->root);
+ }
- server_conf_t *conf = NULL;
- rpc_transport_t *xprt = NULL;
- uint64_t total_read = 0;
- uint64_t total_write = 0;
+ gf_log (this->name, GF_LOG_INFO, "destroyed connection of %s",
+ conn->id);
- conf = frame->this->private;
- if (!conf || !dict)
- return 0;
+ FREE (conn->id);
+ FREE (conn);
- if (dict_foreach_fnmatch (dict, "*io*stat*dump",
- dict_null_foreach_fn, NULL ) > 0) {
- list_for_each_entry (xprt, &conf->xprt_list, list) {
- total_read += xprt->total_bytes_read;
- total_write += xprt->total_bytes_write;
- }
- gf_log ("stats", GF_LOG_INFO,
- "total-read %"PRIu64", total-write %"PRIu64,
- total_read, total_write);
- }
-
- return 0;
+out:
+ return ret;
}
-gf_boolean_t
-server_cancel_grace_timer (xlator_t *this, client_t *client)
+server_connection_t *
+server_connection_get (xlator_t *this, const char *id)
{
- server_ctx_t *serv_ctx = NULL;
- gf_timer_t *timer = NULL;
- gf_boolean_t cancelled = _gf_false;
-
- if (!this || !client) {
- gf_log (THIS->name, GF_LOG_ERROR,
- "Invalid arguments to cancel connection timer");
- return cancelled;
- }
-
- serv_ctx = server_ctx_get (client, client->this);
+ server_connection_t *conn = NULL;
+ server_connection_t *trav = NULL;
+ server_conf_t *conf = NULL;
- if (serv_ctx == NULL) {
- gf_log (this->name, GF_LOG_INFO, "server_ctx_get() failed");
- goto out;
- }
+ conf = this->private;
- LOCK (&serv_ctx->fdtable_lock);
+ pthread_mutex_lock (&conf->mutex);
{
- if (serv_ctx->grace_timer) {
- timer = serv_ctx->grace_timer;
- serv_ctx->grace_timer = NULL;
+ list_for_each_entry (trav, &conf->conns, list) {
+ if (!strcmp (id, trav->id)) {
+ conn = trav;
+ break;
+ }
}
- }
- UNLOCK (&serv_ctx->fdtable_lock);
-
- if (timer) {
- gf_timer_call_cancel (this->ctx, timer);
- cancelled = _gf_true;
- }
-out:
- return cancelled;
-}
-
-server_ctx_t*
-server_ctx_get (client_t *client, xlator_t *xlator)
-{
- void *tmp = NULL;
- server_ctx_t *ctx = NULL;
-
- client_ctx_get (client, xlator, &tmp);
- ctx = tmp;
+ if (!conn) {
+ conn = (void *) CALLOC (1, sizeof (*conn));
- if (ctx != NULL)
- goto out;
+ conn->id = strdup (id);
+ conn->fdtable = gf_fd_fdtable_alloc ();
+ conn->ltable = gf_lock_table_new ();
- ctx = GF_CALLOC (1, sizeof (server_ctx_t), gf_server_mt_server_conf_t);
+ pthread_mutex_init (&conn->lock, NULL);
- if (ctx == NULL)
- goto out;
+ list_add (&conn->list, &conf->conns);
+ }
- /* ctx->lk_version = 0; redundant */
- ctx->fdtable = gf_fd_fdtable_alloc ();
+ conn->ref++;
+ conn->active_transports++;
+ }
+ pthread_mutex_unlock (&conf->mutex);
- if (ctx->fdtable == NULL) {
- GF_FREE (ctx);
- ctx = NULL;
- goto out;
- }
-
- LOCK_INIT (&ctx->fdtable_lock);
-
- if (client_ctx_set (client, xlator, ctx) != 0) {
- LOCK_DESTROY (&ctx->fdtable_lock);
- GF_FREE (ctx->fdtable);
- GF_FREE (ctx);
- ctx = NULL;
- }
-
-out:
- return ctx;
+ return conn;
}
-int
-auth_set_username_passwd (dict_t *input_params, dict_t *config_params,
- client_t *client)
-{
- int ret = 0;
- data_t *allow_user = NULL;
- data_t *passwd_data = NULL;
- char *username = NULL;
- char *password = NULL;
- char *brick_name = NULL;
- char *searchstr = NULL;
- char *username_str = NULL;
- char *tmp = NULL;
- char *username_cpy = NULL;
-
- ret = dict_get_str (input_params, "username", &username);
- if (ret) {
- gf_log ("auth/login", GF_LOG_DEBUG,
- "username not found, returning DONT-CARE");
- /* For non trusted clients username and password
- will not be there. So dont reject the client.
- */
- ret = 0;
- goto out;
- }
-
- ret = dict_get_str (input_params, "password", &password);
- if (ret) {
- gf_log ("auth/login", GF_LOG_WARNING,
- "password not found, returning DONT-CARE");
- goto out;
- }
- ret = dict_get_str (input_params, "remote-subvolume", &brick_name);
- if (ret) {
- gf_log ("auth/login", GF_LOG_ERROR,
- "remote-subvolume not specified");
- ret = -1;
- goto out;
- }
+void
+server_connection_put (xlator_t *this, server_connection_t *conn)
+{
+ server_conf_t *conf = NULL;
+ server_connection_t *todel = NULL;
- ret = gf_asprintf (&searchstr, "auth.login.%s.allow", brick_name);
- if (-1 == ret) {
- ret = 0;
+ if (conn == NULL) {
goto out;
}
- allow_user = dict_get (config_params, searchstr);
- GF_FREE (searchstr);
-
- if (allow_user) {
- username_cpy = gf_strdup (allow_user->data);
- if (!username_cpy)
- goto out;
+ conf = this->private;
- username_str = strtok_r (username_cpy, " ,", &tmp);
-
- while (username_str) {
- if (!fnmatch (username_str, username, 0)) {
- ret = gf_asprintf (&searchstr,
- "auth.login.%s.password",
- username);
- if (-1 == ret)
- goto out;
-
- passwd_data = dict_get (config_params,
- searchstr);
- GF_FREE (searchstr);
-
- if (!passwd_data) {
- gf_log ("auth/login", GF_LOG_ERROR,
- "wrong username/password "
- "combination");
- ret = -1;
- goto out;
- }
+ pthread_mutex_lock (&conf->mutex);
+ {
+ conn->ref--;
- ret = !((strcmp (data_to_str (passwd_data),
- password))?0: -1);
- if (!ret) {
- client->auth.username =
- gf_strdup (username);
- client->auth.passwd =
- gf_strdup (password);
- }
- if (ret == -1)
- gf_log ("auth/login", GF_LOG_ERROR,
- "wrong password for user %s",
- username);
- break;
- }
- username_str = strtok_r (NULL, " ,", &tmp);
+ if (!conn->ref) {
+ list_del_init (&conn->list);
+ todel = conn;
}
}
+ pthread_mutex_unlock (&conf->mutex);
-out:
- GF_FREE (username_cpy);
+ if (todel) {
+ server_connection_destroy (this, todel);
+ }
- return ret;
+out:
+ return;
}
diff --git a/xlators/protocol/server/src/server-helpers.h b/xlators/protocol/server/src/server-helpers.h
index e7238d9ca6a..867035d3334 100644
--- a/xlators/protocol/server/src/server-helpers.h
+++ b/xlators/protocol/server/src/server-helpers.h
@@ -1,60 +1,72 @@
/*
- Copyright (c) 2010-2013 Red Hat, Inc. <http://www.redhat.com>
+ Copyright (c) 2006-2009 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 General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that 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.
-#ifndef _SERVER_HELPERS_H
-#define _SERVER_HELPERS_H
+ 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 "server.h"
+#ifndef __SERVER_HELPERS_H__
+#define __SERVER_HELPERS_H__
#define CALL_STATE(frame) ((server_state_t *)frame->root->state)
-#define XPRT_FROM_FRAME(frame) ((rpc_transport_t *) CALL_STATE(frame)->xprt)
+#define BOUND_XL(frame) ((xlator_t *) CALL_STATE(frame)->bound_xl)
+
+#define TRANSPORT_FROM_FRAME(frame) ((transport_t *) CALL_STATE(frame)->trans)
-#define SERVER_CONF(frame) \
- ((server_conf_t *)XPRT_FROM_FRAME(frame)->this->private)
+#define SERVER_CONNECTION(frame) \
+ ((server_connection_t *) TRANSPORT_FROM_FRAME(frame)->xl_private)
-#define XPRT_FROM_XLATOR(this) ((((server_conf_t *)this->private))->listen)
+#define SERVER_CONF(frame) \
+ ((server_conf_t *)TRANSPORT_FROM_FRAME(frame)->xl->private)
-#define INODE_LRU_LIMIT(this) \
- (((server_conf_t *)(this->private))->config.inode_lru_limit)
+#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_state (server_state_t *state);
+char *
+stat_to_str (struct stat *stbuf);
-void server_loc_wipe (loc_t *loc);
+call_frame_t *
+server_copy_frame (call_frame_t *frame);
-void
-server_print_request (call_frame_t *frame);
+void free_state (server_state_t *state);
-call_frame_t *
-get_frame_from_request (rpcsvc_request_t *req);
+void server_loc_wipe (loc_t *loc);
-int
-server_connection_cleanup (xlator_t *this, struct _client_t *client,
- int32_t flags);
+int32_t
+gf_add_locker (struct _lock_table *table, const char *volume,
+ loc_t *loc,
+ fd_t *fd,
+ pid_t pid);
-gf_boolean_t
-server_cancel_grace_timer (xlator_t *this, struct _client_t *client);
+int32_t
+gf_del_locker (struct _lock_table *table, const char *volume,
+ loc_t *loc,
+ fd_t *fd,
+ pid_t pid);
-int
-server_build_config (xlator_t *this, server_conf_t *conf);
+int32_t
+gf_direntry_to_bin (dir_entry_t *head, char *bufferp);
-int serialize_rsp_dirent (gf_dirent_t *entries, gfs3_readdir_rsp *rsp);
-int serialize_rsp_direntp (gf_dirent_t *entries, gfs3_readdirp_rsp *rsp);
-int readdirp_rsp_cleanup (gfs3_readdirp_rsp *rsp);
-int readdir_rsp_cleanup (gfs3_readdir_rsp *rsp);
-int auth_set_username_passwd (dict_t *input_params, dict_t *config_params,
- struct _client_t *client);
+void
+server_print_request (call_frame_t *frame);
-server_ctx_t *server_ctx_get (client_t *client, xlator_t *xlator);
-#endif /* !_SERVER_HELPERS_H */
+#endif /* __SERVER_HELPERS_H__ */
diff --git a/xlators/protocol/server/src/server-mem-types.h b/xlators/protocol/server/src/server-mem-types.h
deleted file mode 100644
index 19c3466d37f..00000000000
--- a/xlators/protocol/server/src/server-mem-types.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- Copyright (c) 2010-2013 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 __SERVER_MEM_TYPES_H__
-#define __SERVER_MEM_TYPES_H__
-
-#include "mem-types.h"
-
-enum gf_server_mem_types_ {
- gf_server_mt_server_conf_t = gf_common_mt_end + 1,
- gf_server_mt_resolv_comp_t,
- gf_server_mt_state_t,
- gf_server_mt_locker_t,
- gf_server_mt_lock_table_t,
- gf_server_mt_conn_t,
- 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-protocol.c b/xlators/protocol/server/src/server-protocol.c
new file mode 100644
index 00000000000..0cfdf0095cf
--- /dev/null
+++ b/xlators/protocol/server/src/server-protocol.c
@@ -0,0 +1,6907 @@
+/*
+ Copyright (c) 2006-2009 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 <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"
+
+
+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;
+}
+
+
+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, "}");
+}
+
+
+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, "}");
+}
+
+
+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);
+}
+
+
+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
+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_NORMAL,
+ "%s%s => (%d, %d)%s",
+ op, caller, op_ret, op_errno, fdstr);
+}
+
+
+void
+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_NORMAL,
+ "%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
+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_state (state);
+
+}
+
+
+/*
+ * server_setdents_cbk - writedir callback for server protocol
+ * @frame: call frame
+ * @cookie:
+ * @this:
+ * @op_ret: return value
+ * @op_errno: errno
+ *
+ * not for external reference
+ */
+int
+server_setdents_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_setdents_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_FOP_REPLY, GF_FOP_SETDENTS,
+ hdr, hdrlen, NULL, 0, NULL);
+
+ return 0;
+}
+
+/*
+ * server_lk_cbk - lk callback for server protocol
+ * @frame: call frame
+ * @cookie:
+ * @this:
+ * @op_ret:
+ * @op_errno:
+ * @lock:
+ *
+ * not for external reference
+ */
+int
+server_lk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct 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) {
+ 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_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_FOP_LK,
+ hdr, hdrlen, NULL, 0, NULL);
+
+ return 0;
+}
+
+
+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_FOP_INODELK,
+ hdr, hdrlen, NULL, 0, NULL);
+
+ return 0;
+}
+
+
+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_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
+ */
+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_FOP_ENTRYLK,
+ hdr, hdrlen, NULL, 0, NULL);
+
+ return 0;
+}
+
+
+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);
+
+ if (op_ret >= 0) {
+ state = CALL_STATE(frame);
+ 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_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
+ */
+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_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
+ */
+int
+server_rmdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct stat *preparent,
+ struct stat *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_stat (&rsp->preparent, preparent);
+ gf_stat_from_stat (&rsp->postparent, postparent);
+ }
+
+ protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_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
+ */
+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 stat *stbuf, struct stat *preparent,
+ struct stat *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_stat (&rsp->stat, stbuf);
+ gf_stat_from_stat (&rsp->preparent, preparent);
+ gf_stat_from_stat (&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_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
+ */
+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 stat *stbuf, struct stat *preparent,
+ struct stat *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_stat (&rsp->stat, stbuf);
+ gf_stat_from_stat (&rsp->preparent, preparent);
+ gf_stat_from_stat (&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_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
+ */
+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_FOP_FSYNCDIR,
+ hdr, hdrlen, NULL, 0, NULL);
+
+ return 0;
+}
+
+
+/*
+ * server_getdents_cbk - readdir callback for server protocol
+ * @frame: call frame
+ * @cookie:
+ * @this:
+ * @op_ret: return value
+ * @op_errno: errno
+ * @entries:
+ * @count:
+ *
+ * not for external reference
+ */
+int
+server_getdents_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dir_entry_t *entries,
+ int32_t count)
+{
+ gf_hdr_common_t *hdr = NULL;
+ gf_fop_getdents_rsp_t *rsp = NULL;
+ size_t hdrlen = 0;
+ int32_t vec_count = 0;
+ int32_t gf_errno = 0;
+ struct iobref *iobref = NULL;
+ struct iobuf *iobuf = NULL;
+ size_t buflen = 0;
+ struct iovec vector[1];
+ server_state_t *state = NULL;
+
+ state = CALL_STATE(frame);
+
+ if (op_ret >= 0) {
+ iobuf = iobuf_get (this->ctx->iobuf_pool);
+ if (!iobuf) {
+ op_ret = -1;
+ op_errno = ENOMEM;
+ goto out;
+ }
+
+ buflen = gf_direntry_to_bin (entries, iobuf->ptr);
+ if (buflen < 0) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "fd - %"PRId64" (%"PRId64"): failed to convert "
+ "entries list to string buffer",
+ state->resolve.fd_no, state->fd->inode->ino);
+ op_ret = -1;
+ op_errno = EINVAL;
+ goto out;
+ }
+
+ iobref = iobref_new ();
+ if (iobref == NULL) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "fd - %"PRId64" (%"PRId64"): failed to get iobref",
+ state->resolve.fd_no, state->fd->inode->ino);
+ op_ret = -1;
+ op_errno = ENOMEM;
+ goto out;
+ }
+
+ iobref_add (iobref, iobuf);
+
+ vector[0].iov_base = iobuf->ptr;
+ vector[0].iov_len = buflen;
+ vec_count = 1;
+ } else {
+ gf_log (this->name, GF_LOG_TRACE,
+ "%"PRId64": GETDENTS %"PRId64" (%"PRId64"): %"PRId32" (%s)",
+ frame->root->unique,
+ state->resolve.fd_no,
+ state->fd ? state->fd->inode->ino : 0,
+ op_ret, strerror (op_errno));
+ vector[0].iov_base = NULL;
+ vector[0].iov_len = 0;
+ }
+
+out:
+ hdrlen = gf_hdr_len (rsp, 0);
+ hdr = gf_hdr_new (rsp, 0);
+ rsp = gf_param (hdr);
+
+ rsp->count = hton32 (count);
+
+ 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_FOP_GETDENTS,
+ hdr, hdrlen, vector, vec_count, iobref);
+
+ if (iobref)
+ iobref_unref (iobref);
+ if (iobuf)
+ iobuf_unref (iobuf);
+
+ return 0;
+}
+
+
+/*
+ * server_readdir_cbk - getdents callback for server protocol
+ * @frame: call frame
+ * @cookie:
+ * @this:
+ * @op_ret:
+ * @op_errno:
+ *
+ * not for external reference
+ */
+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_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
+ */
+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
+ */
+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_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
+ */
+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_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
+ */
+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_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
+ */
+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_FOP_GETXATTR,
+ hdr, hdrlen, NULL, 0, NULL);
+
+ return 0;
+}
+
+
+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_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
+ */
+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_FOP_SETXATTR,
+ hdr, hdrlen, NULL, 0, NULL);
+
+ return 0;
+}
+
+
+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_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
+ */
+int
+server_rename_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct stat *stbuf,
+ struct stat *preoldparent, struct stat *postoldparent,
+ struct stat *prenewparent, struct stat *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->st_ino = state->loc.inode->ino;
+ stbuf->st_mode = state->loc.inode->st_mode;
+
+ 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_stat (&rsp->stat, stbuf);
+
+ gf_stat_from_stat (&rsp->preoldparent, preoldparent);
+ gf_stat_from_stat (&rsp->postoldparent, postoldparent);
+
+ gf_stat_from_stat (&rsp->prenewparent, prenewparent);
+ gf_stat_from_stat (&rsp->postnewparent, postnewparent);
+ }
+
+ protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_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
+ */
+int
+server_unlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct stat *preparent,
+ struct stat *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_stat (&rsp->preparent, preparent);
+ gf_stat_from_stat (&rsp->postparent, postparent);
+ }
+
+ protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_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
+ */
+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 stat *stbuf, struct stat *preparent,
+ struct stat *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_stat (&rsp->stat, stbuf);
+ gf_stat_from_stat (&rsp->preparent, preparent);
+ gf_stat_from_stat (&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_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
+ */
+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 stat *stbuf, struct stat *preparent,
+ struct stat *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->st_ino = state->loc.inode->ino;
+
+ gf_stat_from_stat (&rsp->stat, stbuf);
+ gf_stat_from_stat (&rsp->preparent, preparent);
+ gf_stat_from_stat (&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_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
+ */
+int
+server_truncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct stat *prebuf,
+ struct stat *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_stat (&rsp->prestat, prebuf);
+ gf_stat_from_stat (&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_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
+ */
+int
+server_fstat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct stat *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_stat (&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_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
+ */
+int
+server_ftruncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct stat *prebuf,
+ struct stat *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_stat (&rsp->prestat, prebuf);
+ gf_stat_from_stat (&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_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
+ */
+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_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
+ */
+int
+server_fsync_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct stat *prebuf,
+ struct stat *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_stat (&(rsp->prestat), prebuf);
+ gf_stat_from_stat (&(rsp->poststat), postbuf);
+ }
+
+ protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_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
+ */
+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
+ */
+
+int
+server_writev_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct stat *prebuf,
+ struct stat *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_stat (&rsp->prestat, prebuf);
+ gf_stat_from_stat (&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_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
+ */
+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 stat *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_stat (&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_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
+ */
+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_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 stat of created file
+ *
+ * not for external reference
+ */
+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 stat *stbuf,
+ struct stat *preparent, struct stat *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->st_ino);
+
+ link_inode = inode_link (inode, state->loc.parent,
+ state->loc.name, stbuf);
+
+ if (link_inode != inode) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "create(%s) inode (ptr=%p, ino=%"PRId64", "
+ "gen=%"PRId64") found conflict (ptr=%p, "
+ "ino=%"PRId64", gen=%"PRId64")",
+ state->loc.path, inode, inode->ino,
+ inode->generation, link_inode,
+ link_inode->ino, link_inode->generation);
+
+ /*
+ 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_stat (&rsp->stat, stbuf);
+ gf_stat_from_stat (&rsp->preparent, preparent);
+ gf_stat_from_stat (&rsp->postparent, postparent);
+ }
+
+ protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_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
+ */
+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 stat *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_stat (&(rsp->buf), sbuf);
+ strcpy (rsp->path, buf);
+ }
+
+ protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_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
+ */
+int
+server_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct stat *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_stat (&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_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
+ */
+
+int
+server_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno,
+ struct stat *statpre, struct stat *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_stat (&rsp->statpre, statpre);
+ gf_stat_from_stat (&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_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
+ */
+int
+server_fsetattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno,
+ struct stat *statpre, struct stat *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_stat (&rsp->statpre, statpre);
+ gf_stat_from_stat (&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_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
+ */
+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 stat *stbuf, dict_t *dict,
+ struct stat *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_stat (&rsp->postparent, postparent);
+
+ if (op_ret == 0) {
+ root_inode = BOUND_XL(frame)->itable->root;
+ if (inode == root_inode) {
+ /* we just looked up root ("/") */
+ stbuf->st_ino = 1;
+ if (inode->st_mode == 0)
+ inode->st_mode = stbuf->st_mode;
+ }
+
+ gf_stat_from_stat (&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_FOP_LOOKUP,
+ hdr, hdrlen, NULL, 0, NULL);
+
+ return 0;
+}
+
+
+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_FOP_XATTROP,
+ hdr, hdrlen, NULL, 0, NULL);
+
+ return 0;
+}
+
+
+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_FOP_FXATTROP,
+ hdr, hdrlen, NULL, 0, NULL);
+
+ return 0;
+}
+
+
+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;
+}
+
+
+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 = strdup (req->path);
+
+ if (IS_NOT_ROOT (pathlen)) {
+ state->resolve.bname = 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);
+ FREE (req_dictbuf);
+ goto err;
+ }
+
+ xattr_req->extra_free = req_dictbuf;
+ state->dict = xattr_req;
+ }
+
+ 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
+ */
+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;
+}
+
+
+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;
+}
+
+
+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 = strdup (req->path);
+ }
+
+ resolve_and_resume (frame, server_stat_resume);
+
+ return 0;
+}
+
+
+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;
+}
+
+
+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 = strdup (req->path);
+
+ gf_stat_to_stat (&req->stbuf, &state->stbuf);
+ state->valid = ntoh32 (req->valid);
+
+ resolve_and_resume (frame, server_setattr_resume);
+
+ return 0;
+}
+
+
+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;
+}
+
+
+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_stat (&req->stbuf, &state->stbuf);
+ state->valid = ntoh32 (req->valid);
+
+ resolve_and_resume (frame, server_fsetattr_resume);
+
+ return 0;
+}
+
+
+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;
+}
+
+
+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 = strdup (req->path);
+
+ state->size = ntoh32 (req->size);
+
+ resolve_and_resume (frame, server_readlink_resume);
+
+ return 0;
+}
+
+
+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);
+
+ 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;
+}
+
+
+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 = strdup (req->path);
+ state->resolve.bname = strdup (req->bname + pathlen);
+ state->mode = ntoh32 (req->mode);
+ state->flags = gf_flags_to_flags (ntoh32 (req->flags));
+
+ resolve_and_resume (frame, server_create_resume);
+
+ return 0;
+}
+
+
+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;
+}
+
+
+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 = strdup (req->path);
+
+ state->flags = gf_flags_to_flags (ntoh32 (req->flags));
+
+ resolve_and_resume (frame, server_open_resume);
+
+ return 0;
+}
+
+
+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;
+}
+
+
+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);
+
+ resolve_and_resume (frame, server_readv_resume);
+
+ return 0;
+}
+
+
+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;
+}
+
+
+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;
+ }
+
+ resolve_and_resume (frame, server_writev_resume);
+
+ return 0;
+}
+
+
+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;
+}
+
+
+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;
+}
+
+
+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);
+
+ resolve_and_resume (frame, server_fsync_resume);
+
+ return 0;
+}
+
+
+
+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;
+}
+
+
+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);
+
+ resolve_and_resume (frame, server_flush_resume);
+
+ return 0;
+}
+
+
+
+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;
+}
+
+
+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);
+
+ resolve_and_resume (frame, server_ftruncate_resume);
+
+ return 0;
+}
+
+
+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;
+}
+
+
+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);
+
+ resolve_and_resume (frame, server_fstat_resume);
+
+ return 0;
+}
+
+
+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;
+}
+
+
+
+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 = strdup (req->path);
+ state->resolve.ino = ntoh64 (req->ino);
+ state->resolve.gen = ntoh64 (req->gen);
+ state->offset = ntoh64 (req->offset);
+
+ resolve_and_resume (frame, server_truncate_resume);
+
+ return 0;
+}
+
+
+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;
+}
+
+
+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 = strdup (req->path);
+ state->resolve.bname = strdup (req->bname + pathlen);
+
+ resolve_and_resume (frame, server_unlink_resume);
+
+ return 0;
+}
+
+
+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;
+}
+
+
+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 = 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);
+ FREE (req_dictbuf);
+ goto err;
+ }
+
+ dict->extra_free = req_dictbuf;
+ state->dict = dict;
+ }
+
+ 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;
+
+}
+
+
+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;
+}
+
+
+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);
+ FREE (req_dictbuf);
+ goto err;
+ }
+
+ dict->extra_free = req_dictbuf;
+ state->dict = dict;
+ }
+
+ 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;
+}
+
+
+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;
+}
+
+
+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);
+ free (req_dictbuf);
+ goto fail;
+ }
+ dict->extra_free = req_dictbuf;
+ state->dict = dict;
+ dict = NULL;
+ }
+
+ 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;
+}
+
+
+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;
+}
+
+
+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 = 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);
+ free (req_dictbuf);
+ goto fail;
+ }
+ dict->extra_free = req_dictbuf;
+ state->dict = dict;
+ dict = NULL;
+ }
+
+ 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;
+}
+
+
+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;
+}
+
+
+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 = strdup (req->path);
+ state->resolve.ino = ntoh64 (req->ino);
+ state->resolve.gen = ntoh64 (req->gen);
+
+ namelen = ntoh32 (req->namelen);
+ if (namelen)
+ state->name = strdup (req->name + pathlen);
+
+ resolve_and_resume (frame, server_getxattr_resume);
+
+ return 0;
+}
+
+
+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;
+}
+
+
+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 = strdup (req->name);
+
+ resolve_and_resume (frame, server_fgetxattr_resume);
+
+ return 0;
+}
+
+
+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;
+}
+
+
+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 = strdup (req->path);
+ state->resolve.ino = ntoh64 (req->ino);
+ state->resolve.gen = ntoh64 (req->gen);
+ state->name = strdup (req->name + pathlen);
+
+ resolve_and_resume (frame, server_removexattr_resume);
+
+ return 0;
+}
+
+
+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;
+}
+
+
+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 = strdup (req->path);
+
+ resolve_and_resume (frame, server_statfs_resume);
+
+ return 0;
+}
+
+
+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;
+}
+
+
+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 = strdup (req->path);
+ state->resolve.ino = ntoh64 (req->ino);
+ state->resolve.gen = ntoh64 (req->gen);
+
+ resolve_and_resume (frame, server_opendir_resume);
+
+ return 0;
+}
+
+
+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;
+}
+
+int
+server_getdents_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_getdents_cbk,
+ bound_xl,
+ bound_xl->fops->getdents,
+ state->fd, state->size, state->offset, state->flags);
+
+ return 0;
+err:
+ server_getdents_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, 0);
+ return 0;
+}
+
+int
+server_getdents (call_frame_t *frame, xlator_t *bound_xl,
+ gf_hdr_common_t *hdr, size_t hdrlen,
+ struct iobuf *iobuf)
+{
+ gf_fop_getdents_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);
+ state->flags = ntoh32 (req->flags);
+
+ resolve_and_resume (frame, server_getdents_resume);
+
+ return 0;
+}
+
+/*
+ * server_readdirp_cbk - getdents callback for server protocol
+ * @frame: call frame
+ * @cookie:
+ * @this:
+ * @op_ret:
+ * @op_errno:
+ *
+ * not for external reference
+ */
+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_FOP_READDIRP,
+ hdr, hdrlen, NULL, 0, NULL);
+
+ return 0;
+}
+
+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
+ */
+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);
+
+ resolve_and_resume (frame, server_readdirp_resume);
+
+ return 0;
+}
+
+
+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
+ */
+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);
+
+ resolve_and_resume (frame, server_readdir_resume);
+
+ return 0;
+}
+
+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
+ */
+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);
+
+ resolve_and_resume (frame, server_fsyncdir_resume);
+
+ return 0;
+}
+
+
+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);
+
+ return 0;
+err:
+ server_mknod_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL, NULL, NULL);
+ return 0;
+}
+
+
+
+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 = strdup (req->path);
+ state->resolve.bname = strdup (req->bname + pathlen);
+
+ state->mode = ntoh32 (req->mode);
+ state->dev = ntoh64 (req->dev);
+
+ resolve_and_resume (frame, server_mknod_resume);
+
+ return 0;
+}
+
+
+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);
+
+ return 0;
+err:
+ server_mkdir_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL, NULL, NULL);
+ return 0;
+}
+
+
+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 = strdup (req->path);
+ state->resolve.bname = strdup (req->bname + pathlen);
+
+ state->mode = ntoh32 (req->mode);
+
+ resolve_and_resume (frame, server_mkdir_resume);
+
+ return 0;
+}
+
+
+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;
+}
+
+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 = strdup (req->path);
+ state->resolve.bname = strdup (req->bname + pathlen);
+
+ resolve_and_resume (frame, server_rmdir_resume);
+
+ return 0;
+}
+
+
+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;
+}
+
+
+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 = 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 = 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;
+ }
+
+ resolve_and_resume (frame, server_inodelk_resume);
+
+ return 0;
+}
+
+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;
+}
+
+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 = 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;
+ }
+
+ resolve_and_resume (frame, server_finodelk_resume);
+
+ return 0;
+}
+
+
+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;
+}
+
+
+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 = strdup (req->path);
+ state->resolve.ino = ntoh64 (req->ino);
+ state->resolve.gen = ntoh64 (req->gen);
+
+ if (namelen)
+ state->name = strdup (req->name + pathlen);
+ state->volume = strdup (req->volume + pathlen + namelen);
+
+ state->cmd = ntoh32 (req->cmd);
+ state->type = ntoh32 (req->type);
+
+ resolve_and_resume (frame, server_entrylk_resume);
+
+ return 0;
+}
+
+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;
+}
+
+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 = strdup (req->volume + namelen);
+
+
+ resolve_and_resume (frame, server_finodelk_resume);
+
+ return 0;
+}
+
+
+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;
+}
+
+
+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 = strdup (req->path);
+
+ state->mask = ntoh32 (req->mask);
+
+ resolve_and_resume (frame, server_access_resume);
+
+ return 0;
+}
+
+
+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);
+
+ return 0;
+err:
+ server_symlink_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL, NULL, NULL);
+ return 0;
+}
+
+
+
+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 = strdup (req->path);
+ state->resolve.bname = strdup (req->bname + pathlen);
+ state->name = strdup (req->linkname + pathlen + baselen);
+
+ resolve_and_resume (frame, server_symlink_resume);
+
+ return 0;
+}
+
+
+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;
+}
+
+
+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 = strdup (req->oldpath);
+ state->resolve.ino = ntoh64 (req->oldino);
+ state->resolve.gen = ntoh64 (req->oldgen);
+
+ state->resolve2.type = RESOLVE_NOT;
+ state->resolve2.path = strdup (req->newpath + oldpathlen);
+ state->resolve2.bname = strdup (req->newbname + oldpathlen + newpathlen);
+ state->resolve2.par = ntoh64 (req->newpar);
+ state->resolve2.gen = ntoh64 (req->newgen);
+
+ resolve_and_resume (frame, server_link_resume);
+
+ return 0;
+}
+
+
+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;
+}
+
+
+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 = strdup (req->oldpath);
+ state->resolve.bname = strdup (req->oldbname + oldpathlen);
+ state->resolve.par = ntoh64 (req->oldpar);
+ state->resolve.gen = ntoh64 (req->oldgen);
+
+ state->resolve2.type = RESOLVE_MAY;
+ state->resolve2.path = strdup (req->newpath + oldpathlen + oldbaselen);
+ state->resolve2.bname = strdup (req->newbname + oldpathlen + oldbaselen +
+ newpathlen);
+ state->resolve2.par = ntoh64 (req->newpar);
+ state->resolve2.gen = ntoh64 (req->newgen);
+
+ resolve_and_resume (frame, server_rename_resume);
+
+ return 0;
+}
+
+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
+ */
+
+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;
+ }
+
+
+ resolve_and_resume (frame, server_lk_resume);
+
+ return 0;
+}
+
+
+int
+server_setdents_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_setdents_cbk,
+ BOUND_XL(frame),
+ BOUND_XL(frame)->fops->setdents,
+ state->fd, state->flags, state->entry, state->nr_count);
+
+ return 0;
+err:
+ server_setdents_cbk (frame, NULL, frame->this, state->resolve.op_ret, state->resolve.op_errno);
+ return 0;
+}
+/*
+ * server_writedir -
+ *
+ * @frame:
+ * @bound_xl:
+ * @params:
+ *
+ */
+int
+server_setdents (call_frame_t *frame, xlator_t *bound_xl,
+ gf_hdr_common_t *hdr, size_t hdrlen,
+ struct iobuf *iobuf)
+{
+ server_connection_t *conn = NULL;
+ gf_fop_setdents_req_t *req = NULL;
+ server_state_t *state = NULL;
+ dir_entry_t *entry = NULL;
+ dir_entry_t *trav = NULL;
+ dir_entry_t *prev = NULL;
+ int32_t count = 0;
+ int32_t i = 0;
+ int32_t bread = 0;
+ char *ender = NULL;
+ char *buffer_ptr = NULL;
+ char tmp_buf[512] = {0,};
+
+ 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->nr_count = ntoh32 (req->count);
+
+
+ if (iobuf == NULL) {
+ gf_log (frame->this->name, GF_LOG_ERROR,
+ "fd - %"PRId64" (%"PRId64"): received a null buffer, "
+ "returning EINVAL",
+ state->resolve.fd_no, state->fd->inode->ino);
+
+ server_setdents_cbk (frame, NULL, frame->this, -1, ENOMEM);
+
+ goto out;
+ }
+
+ entry = CALLOC (1, sizeof (dir_entry_t));
+ ERR_ABORT (entry);
+ prev = entry;
+ buffer_ptr = iobuf->ptr;
+
+ for (i = 0; i < state->nr_count ; i++) {
+ bread = 0;
+ trav = CALLOC (1, sizeof (dir_entry_t));
+ ERR_ABORT (trav);
+
+ ender = strchr (buffer_ptr, '/');
+ if (!ender)
+ break;
+ count = ender - buffer_ptr;
+ trav->name = CALLOC (1, count + 2);
+ ERR_ABORT (trav->name);
+
+ strncpy (trav->name, buffer_ptr, count);
+ bread = count + 1;
+ buffer_ptr += bread;
+
+ ender = strchr (buffer_ptr, '\n');
+ if (!ender)
+ break;
+ count = ender - buffer_ptr;
+ strncpy (tmp_buf, buffer_ptr, count);
+ bread = count + 1;
+ buffer_ptr += bread;
+
+ /* TODO: use str_to_stat instead */
+ {
+ uint64_t dev;
+ uint64_t ino;
+ uint32_t mode;
+ uint32_t nlink;
+ uint32_t uid;
+ uint32_t gid;
+ uint64_t rdev;
+ uint64_t size;
+ uint32_t blksize;
+ uint64_t blocks;
+ uint32_t atime;
+ uint32_t atime_nsec;
+ uint32_t mtime;
+ uint32_t mtime_nsec;
+ uint32_t ctime;
+ uint32_t ctime_nsec;
+
+ sscanf (tmp_buf, GF_STAT_PRINT_FMT_STR,
+ &dev, &ino, &mode, &nlink, &uid, &gid, &rdev,
+ &size, &blksize, &blocks, &atime, &atime_nsec,
+ &mtime, &mtime_nsec, &ctime, &ctime_nsec);
+
+ trav->buf.st_dev = dev;
+ trav->buf.st_ino = ino;
+ trav->buf.st_mode = mode;
+ trav->buf.st_nlink = nlink;
+ trav->buf.st_uid = uid;
+ trav->buf.st_gid = gid;
+ trav->buf.st_rdev = rdev;
+ trav->buf.st_size = size;
+ trav->buf.st_blksize = blksize;
+ trav->buf.st_blocks = blocks;
+
+ trav->buf.st_atime = atime;
+ trav->buf.st_mtime = mtime;
+ trav->buf.st_ctime = ctime;
+
+ ST_ATIM_NSEC_SET(&trav->buf, atime_nsec);
+ ST_MTIM_NSEC_SET(&trav->buf, mtime_nsec);
+ ST_CTIM_NSEC_SET(&trav->buf, ctime_nsec);
+
+ }
+
+ ender = strchr (buffer_ptr, '\n');
+ if (!ender)
+ break;
+ count = ender - buffer_ptr;
+ *ender = '\0';
+ if (S_ISLNK (trav->buf.st_mode)) {
+ trav->link = strdup (buffer_ptr);
+ } else
+ trav->link = "";
+ bread = count + 1;
+ buffer_ptr += bread;
+
+ prev->next = trav;
+ prev = trav;
+ }
+
+ state->entry = entry;
+ resolve_and_resume (frame, server_setdents_resume);
+
+
+ /* Free the variables allocated in this fop here */
+ trav = entry->next;
+ prev = entry;
+ while (trav) {
+ prev->next = trav->next;
+ FREE (trav->name);
+ if (S_ISLNK (trav->buf.st_mode))
+ FREE (trav->link);
+ FREE (trav);
+ trav = prev->next;
+ }
+ FREE (entry);
+
+out:
+ if (iobuf)
+ iobuf_unref (iobuf);
+ return 0;
+}
+
+
+
+/* xxx_MOPS */
+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 = CALLOC (1, sizeof (struct _volfile_ctx));
+
+ temp_volfile->next = conf->volfile;
+ temp_volfile->key = (key)? 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 = strdup (conf_dir_data->data);
+ free_conf_dir = 1;
+ }
+
+ ret = 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)
+ free (conf_dir);
+
+ if (free_filename)
+ free (filename);
+
+ return ret;
+}
+
+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:
+ *
+ */
+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;
+}
+
+
+int
+server_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)
+{
+ gf_hdr_common_t *hdr = NULL;
+ gf_fop_checksum_rsp_t *rsp = NULL;
+ size_t hdrlen = 0;
+ int32_t gf_errno = 0;
+
+ hdrlen = gf_hdr_len (rsp, NAME_MAX + 1 + NAME_MAX + 1);
+ hdr = gf_hdr_new (rsp, NAME_MAX + 1 + NAME_MAX + 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) {
+ memcpy (rsp->fchecksum, fchecksum, NAME_MAX);
+ rsp->fchecksum[NAME_MAX] = '\0';
+ memcpy (rsp->dchecksum + NAME_MAX,
+ dchecksum, NAME_MAX);
+ rsp->dchecksum[NAME_MAX + NAME_MAX] = '\0';
+ }
+
+ protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_FOP_CHECKSUM,
+ hdr, hdrlen, NULL, 0, NULL);
+
+ return 0;
+}
+
+int
+server_checksum_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_checksum_cbk,
+ BOUND_XL(frame),
+ BOUND_XL(frame)->fops->checksum,
+ &state->loc, state->flags);
+
+ return 0;
+err:
+ server_checksum_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL);
+
+ return 0;
+}
+
+int
+server_checksum (call_frame_t *frame, xlator_t *bound_xl,
+ gf_hdr_common_t *hdr, size_t hdrlen,
+ struct iobuf *iobuf)
+{
+ gf_fop_checksum_req_t *req = NULL;
+ server_state_t *state = NULL;
+
+ req = gf_param (hdr);
+ state = CALL_STATE (frame);
+
+ state->resolve.type = RESOLVE_MAY;
+ state->resolve.path = strdup (req->path);
+ state->resolve.gen = ntoh64 (req->gen);
+ state->resolve.ino = ntoh64 (req->ino);
+ state->flags = ntoh32 (req->flag);
+
+ resolve_and_resume (frame, server_checksum_resume);
+
+ return 0;
+}
+
+
+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_FOP_RCHECKSUM,
+ hdr, hdrlen, NULL, 0, NULL);
+
+ return 0;
+}
+
+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;
+
+}
+
+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);
+
+ 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
+ *
+ */
+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;
+};
+
+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
+ *
+ */
+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 = 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 = asprintf (&msg, "protocol version mismatch: client(%s) "
+ "- server(%s)", version, GF_PROTOCOL_VERSION);
+ if (-1 == ret) {
+ gf_log (trans->xl->name, GF_LOG_ERROR,
+ "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 = asprintf (&msg, "remote-subvolume \"%s\" is not found",
+ name);
+ if (-1 == ret) {
+ gf_log (trans->xl->name, GF_LOG_ERROR,
+ "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");
+
+ 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 (xl->name, 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 (xl->name, 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;
+}
+
+/*
+ * server_mop_stats_cbk - stats callback for server management operation
+ * @frame: call frame
+ * @cookie:
+ * @this:
+ * @op_ret: return value
+ * @op_errno: errno
+ * @stats:err
+ *
+ * not for external reference
+ */
+
+int
+server_mop_stats_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t ret, int32_t op_errno,
+ struct xlator_stats *stats)
+{
+ /* TODO: get this information from somewhere else, not extern */
+ gf_hdr_common_t *hdr = NULL;
+ gf_mop_stats_rsp_t *rsp = NULL;
+ char buffer[256] = {0,};
+ int64_t glusterfsd_stats_nr_clients = 0;
+ size_t hdrlen = 0;
+ size_t buf_len = 0;
+ int32_t gf_errno = 0;
+
+ if (ret >= 0) {
+ sprintf (buffer,
+ "%"PRIx64",%"PRIx64",%"PRIx64
+ ",%"PRIx64",%"PRIx64",%"PRIx64
+ ",%"PRIx64",%"PRIx64"\n",
+ stats->nr_files, stats->disk_usage, stats->free_disk,
+ stats->total_disk_size, stats->read_usage,
+ stats->write_usage, stats->disk_speed,
+ glusterfsd_stats_nr_clients);
+
+ buf_len = strlen (buffer);
+ }
+
+ hdrlen = gf_hdr_len (rsp, buf_len + 1);
+ hdr = gf_hdr_new (rsp, buf_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);
+
+ strcpy (rsp->buf, buffer);
+
+ protocol_server_reply (frame, GF_OP_TYPE_MOP_REPLY, GF_MOP_STATS,
+ hdr, hdrlen, NULL, 0, NULL);
+
+ return 0;
+}
+
+
+/*
+ * mop_unlock - unlock management function for server protocol
+ * @frame: call frame
+ * @bound_xl:
+ * @params: parameter dictionary
+ *
+ */
+int
+mop_stats (call_frame_t *frame, xlator_t *bound_xl,
+ gf_hdr_common_t *hdr, size_t hdrlen,
+ struct iobuf *iobuf)
+{
+ int32_t flag = 0;
+ gf_mop_stats_req_t *req = NULL;
+
+ req = gf_param (hdr);
+
+ flag = ntoh32 (req->flags);
+
+ STACK_WIND (frame, server_mop_stats_cbk,
+ bound_xl,
+ bound_xl->mops->stats,
+ flag);
+
+ return 0;
+}
+
+
+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;
+}
+
+
+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;
+}
+
+
+/*
+ * unknown_op_cbk - This function is called when a opcode for unknown
+ * type is called. Helps to keep the backward/forward
+ * compatiblity
+ * @frame: call frame
+ * @type:
+ * @opcode:
+ *
+ */
+
+int
+unknown_op_cbk (call_frame_t *frame, int32_t type, int32_t opcode)
+{
+ gf_hdr_common_t *hdr = NULL;
+ gf_fop_flush_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 (-1);
+ gf_errno = gf_errno_to_error (ENOSYS);
+ hdr->rsp.op_errno = hton32 (gf_errno);
+
+ protocol_server_reply (frame, type, opcode,
+ hdr, 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 = CALLOC (1, sizeof (*state));
+ 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;
+}
+
+
+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_FOP_STAT] = server_stat,
+ [GF_FOP_READLINK] = server_readlink,
+ [GF_FOP_MKNOD] = server_mknod,
+ [GF_FOP_MKDIR] = server_mkdir,
+ [GF_FOP_UNLINK] = server_unlink,
+ [GF_FOP_RMDIR] = server_rmdir,
+ [GF_FOP_SYMLINK] = server_symlink,
+ [GF_FOP_RENAME] = server_rename,
+ [GF_FOP_LINK] = server_link,
+ [GF_FOP_TRUNCATE] = server_truncate,
+ [GF_FOP_OPEN] = server_open,
+ [GF_FOP_READ] = server_readv,
+ [GF_FOP_WRITE] = server_writev,
+ [GF_FOP_STATFS] = server_statfs,
+ [GF_FOP_FLUSH] = server_flush,
+ [GF_FOP_FSYNC] = server_fsync,
+ [GF_FOP_SETXATTR] = server_setxattr,
+ [GF_FOP_GETXATTR] = server_getxattr,
+ [GF_FOP_FGETXATTR] = server_fgetxattr,
+ [GF_FOP_FSETXATTR] = server_fsetxattr,
+ [GF_FOP_REMOVEXATTR] = server_removexattr,
+ [GF_FOP_OPENDIR] = server_opendir,
+ [GF_FOP_GETDENTS] = server_getdents,
+ [GF_FOP_FSYNCDIR] = server_fsyncdir,
+ [GF_FOP_ACCESS] = server_access,
+ [GF_FOP_CREATE] = server_create,
+ [GF_FOP_FTRUNCATE] = server_ftruncate,
+ [GF_FOP_FSTAT] = server_fstat,
+ [GF_FOP_LK] = server_lk,
+ [GF_FOP_LOOKUP] = server_lookup,
+ [GF_FOP_SETDENTS] = server_setdents,
+ [GF_FOP_READDIR] = server_readdir,
+ [GF_FOP_READDIRP] = server_readdirp,
+ [GF_FOP_INODELK] = server_inodelk,
+ [GF_FOP_FINODELK] = server_finodelk,
+ [GF_FOP_ENTRYLK] = server_entrylk,
+ [GF_FOP_FENTRYLK] = server_fentrylk,
+ [GF_FOP_CHECKSUM] = server_checksum,
+ [GF_FOP_RCHECKSUM] = server_rchecksum,
+ [GF_FOP_XATTROP] = server_xattrop,
+ [GF_FOP_FXATTROP] = server_fxattrop,
+ [GF_FOP_SETATTR] = server_setattr,
+ [GF_FOP_FSETATTR] = server_fsetattr,
+};
+
+
+
+static gf_op_t gf_mops[] = {
+ [GF_MOP_SETVOLUME] = mop_setvolume,
+ [GF_MOP_GETVOLUME] = mop_getvolume,
+ [GF_MOP_STATS] = mop_stats,
+ [GF_MOP_GETSPEC] = mop_getspec,
+ [GF_MOP_PING] = mop_ping,
+ [GF_MOP_LOG] = mop_log,
+};
+
+static gf_op_t gf_cbks[] = {
+ [GF_CBK_FORGET] = server_forget,
+ [GF_CBK_RELEASE] = server_release,
+ [GF_CBK_RELEASEDIR] = server_releasedir
+};
+
+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_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;
+ }
+ 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;
+ }
+ 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_nop_cbk - nop callback for server protocol
+ * @frame: call frame
+ * @cookie:
+ * @this:
+ * @op_ret: return value
+ * @op_errno: errno
+ *
+ * not for external reference
+ */
+int
+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_state (state);
+ STACK_DESTROY (frame->root);
+ return 0;
+}
+
+/*
+ * server_fd - fdtable dump function for server protocol
+ * @this:
+ *
+ */
+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;
+ }
+
+int
+server_priv (xlator_t *this)
+{
+ return 0;
+}
+
+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 = 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");
+ }
+ }
+
+ FREE (key_cpy);
+out:
+ return;
+}
+
+
+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 = 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;
+ free (key_cpy);
+ break;
+ }
+ 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;
+}
+
+
+/*
+ * 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 = CALLOC (1, sizeof (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->ctx->top = this;
+
+ ret = 0;
+out:
+ return ret;
+}
+
+
+
+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 */
+ 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);
+ }
+
+ 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 = data;
+ peer_info_t *peerinfo = NULL;
+ peer_info_t *myinfo = NULL;
+
+ if (trans != NULL) {
+ 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?
+ */
+ server_connection_cleanup (this, trans->xl_private);
+ }
+ }
+ break;
+
+ case GF_EVENT_TRANSPORT_CLEANUP:
+ {
+ if (trans->xl_private) {
+ 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;
+ }
+
+ return ret;
+}
+
+
+struct xlator_mops mops = {
+};
+
+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/server/src/server-protocol.h b/xlators/protocol/server/src/server-protocol.h
new file mode 100644
index 00000000000..78bc138279a
--- /dev/null
+++ b/xlators/protocol/server/src/server-protocol.h
@@ -0,0 +1,196 @@
+/*
+ Copyright (c) 2006-2009 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 _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 "authenticate.h"
+#include "fd.h"
+#include "byte-order.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 *
+server_connection_get (xlator_t *this, const char *id);
+
+void
+server_connection_put (xlator_t *this, server_connection_t *conn);
+
+int
+server_connection_destroy (xlator_t *this, server_connection_t *conn);
+
+int
+server_connection_cleanup (xlator_t *this, server_connection_t *conn);
+
+int
+server_nop_cbk (call_frame_t *frame, void *cookie,
+ xlator_t *this, int32_t op_ret, int32_t op_errno);
+
+
+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
+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 stat stbuf;
+ int valid;
+
+ fd_t *fd;
+ 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 flock flock;
+ const char *volume;
+ dir_entry_t *entry;
+};
+
+
+#endif
diff --git a/xlators/protocol/server/src/server-resolve.c b/xlators/protocol/server/src/server-resolve.c
index 3b787c61734..255223bb01e 100644
--- a/xlators/protocol/server/src/server-resolve.c
+++ b/xlators/protocol/server/src/server-resolve.c
@@ -1,11 +1,20 @@
/*
- Copyright (c) 2010-2013 Red Hat, Inc. <http://www.redhat.com>
+ Copyright (c) 2009 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 General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that 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
@@ -13,7 +22,7 @@
#include "config.h"
#endif
-#include "server.h"
+#include "server-protocol.h"
#include "server-helpers.h"
@@ -24,9 +33,66 @@ 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;
+
+ trav = path;
+
+ for (trav = path; *trav; trav++) {
+ if (*trav == '/')
+ count++;
+ }
+
+ return count + 2;
+}
+
+
+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 = strdup (resolve->path);
+ resolve->resolved = resolved;
+
+ count = component_count (resolve->path);
+ components = CALLOC (sizeof (*components), count);
+ 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;
+}
+
int
resolve_loc_touchup (call_frame_t *frame)
@@ -45,196 +111,202 @@ resolve_loc_touchup (call_frame_t *frame)
if (!loc->path) {
if (loc->parent && resolve->bname) {
ret = inode_path (loc->parent, resolve->bname, &path);
- loc->name = resolve->bname;
} else if (loc->inode) {
ret = inode_path (loc->inode, NULL, &path);
}
- if (ret)
- gf_log (frame->this->name, GF_LOG_TRACE,
- "return value inode_path %d", ret);
+
+ if (!path)
+ path = 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 (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);
- 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,
- int op_ret, int op_errno, inode_t *inode, struct iatt *buf,
- dict_t *xdata, struct iatt *postparent)
+resolve_deep_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int op_ret, int op_errno, inode_t *inode, struct stat *buf,
+ dict_t *xattr, struct stat *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;
+ goto get_out_of_here;
}
- link_inode = inode_link (inode, NULL, NULL, buf);
-
- if (!link_inode) {
- loc_wipe (resolve_loc);
- goto out;
+ 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;
}
- inode_lookup (link_inode);
-
- /* wipe the loc only after the inode has been linked to the inode
- table. Otherwise before inode gets linked to the inode table,
- inode would have been unrefed (this might have been destroyed
- if refcount becomes 0, and put back to mempool). So once the
- inode gets destroyed, inode_link is a redundant operation. But
- without knowing that the destroyed inode's pointer is saved in
- the resolved_loc as parent (while constructing loc for resolving
- the entry) and the inode_new call for resolving the entry will
- return the same pointer to the inode as the parent (because in
- reality the inode is a free inode present in cold list of the
- inode mem-pool).
- */
- loc_wipe (resolve_loc);
-
- if (uuid_is_null (resolve->pargfid)) {
- inode_unref (link_inode);
- goto out;
- }
+ loc_wipe (&resolve->deep_loc);
- resolve_loc->parent = link_inode;
- uuid_copy (resolve_loc->pargfid, resolve_loc->parent->gfid);
+ i++; /* next component */
- resolve_loc->name = resolve->bname;
+ if (!components[i].basename) {
+ /* all components of the path are resolved */
+ goto get_out_of_here;
+ }
- resolve_loc->inode = inode_new (state->itable);
+ /* join the current component with the path resolved until now */
+ *(components[i].basename - 1) = '/';
- inode_path (resolve_loc->parent, resolve_loc->name,
- (char **) &resolve_loc->path);
+ resolve->deep_loc.path = 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 (frame, resolve_gfid_entry_cbk,
- frame->root->client->bound_xl,
- frame->root->client->bound_xl->fops->lookup,
- &resolve->resolve_loc, state->xdata);
+ STACK_WIND_COOKIE (frame, resolve_deep_cbk, (void *) (long) i,
+ BOUND_XL (frame), BOUND_XL (frame)->fops->lookup,
+ &resolve->deep_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;
+ xlator_t *this = 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);
- resolve_loc->inode = inode_new (state->itable);
- ret = loc_path (resolve_loc, NULL);
+ /* start from the root */
+ resolve->deep_loc.inode = state->itable->root;
+ resolve->deep_loc.path = strdup ("/");
+ resolve->deep_loc.name = "";
- STACK_WIND (frame, resolve_gfid_cbk,
- frame->root->client->bound_xl,
- frame->root->client->bound_xl->fops->lookup,
- &resolve->resolve_loc, state->xdata);
+ STACK_WIND_COOKIE (frame, resolve_deep_cbk, (void *) (long) i,
+ BOUND_XL (frame), BOUND_XL (frame)->fops->lookup,
+ &resolve->deep_loc, NULL);
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 = 0;
+ int ino_idx = 0;
+ 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) {
+ 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 (!components[par_idx].inode) {
+ resolve->op_ret = -1;
+ resolve->op_errno = ENOENT;
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 (!components[ino_idx].inode &&
+ (resolve->type == RESOLVE_MUST || resolve->type == RESOLVE_EXACT)) {
+ resolve->op_ret = -1;
+ resolve->op_errno = ENOENT;
+ goto out;
+ }
- return 0;
-}
+ 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
@@ -257,20 +329,36 @@ resolve_entry_simple (call_frame_t *frame)
this = frame->this;
resolve = state->resolve_now;
- parent = inode_find (state->itable, resolve->pargfid);
+ 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 = ESTALE;
+ 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) {
+ /* 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 */
- 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) {
@@ -293,9 +381,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_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;
@@ -321,17 +409,21 @@ 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_gfid (frame);
+ resolve_path_deep (frame);
return 0;
}
@@ -348,26 +440,38 @@ 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;
- inode = inode_find (state->itable, resolve->gfid);
+ 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 = ESTALE;
+ resolve->op_errno = ENOENT;
ret = 1;
goto out;
}
+ if (inode->ino != 1 && inode->generation != resolve->gen) {
+ resolve->op_ret = -1;
+ resolve->op_errno = ENOENT;
+ ret = -1;
+ goto out;
+ }
+
ret = 0;
state->loc_now->inode = inode_ref (inode);
- uuid_copy (state->loc_now->gfid, resolve->gfid);
out:
if (inode)
@@ -381,17 +485,21 @@ int
server_resolve_inode (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_inode_simple (frame);
if (ret > 0) {
loc_wipe (loc);
- resolve_gfid (frame);
+ resolve_path_deep (frame);
return 0;
}
@@ -405,101 +513,26 @@ 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_ctx_t *serv_ctx = NULL;
- server_state_t *state = NULL;
- client_t *client = NULL;
- server_resolve_t *resolve = NULL;
- uint64_t fd_no = -1;
+ 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;
- if (fd_no == GF_ANON_FD_NO) {
- server_resolve_anonfd (frame);
- return 0;
- }
-
- client = frame->root->client;
-
- serv_ctx = server_ctx_get (client, client->this);
-
- if (serv_ctx == NULL) {
- gf_log ("", GF_LOG_INFO, "server_ctx_get() failed");
- resolve->op_ret = -1;
- resolve->op_errno = ENOMEM;
- return 0;
- }
-
- state->fd = gf_fd_fdptr_get (serv_ctx->fdtable, fd_no);
+ state->fd = gf_fd_fdptr_get (conn->fdtable, fd_no);
if (!state->fd) {
- gf_log ("", GF_LOG_INFO, "fd not found in context");
resolve->op_ret = -1;
- resolve->op_errno = EBADF;
+ resolve->op_errno = EBADFD;
}
server_resolve_all (frame);
@@ -512,28 +545,30 @@ 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 (!uuid_is_null (resolve->pargfid)) {
+ } else if (resolve->par) {
server_resolve_entry (frame);
- } else if (!uuid_is_null (resolve->gfid)) {
+ } else if (resolve->ino) {
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) {
+
+ resolve_path_deep (frame);
+
+ } else {
resolve->op_ret = -1;
resolve->op_errno = EINVAL;
@@ -549,12 +584,14 @@ 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);
server_print_request (frame);
- state->resume_fn (frame, frame->root->client->bound_xl);
+ state->resume_fn (frame, bound_xl);
return 0;
}
@@ -604,10 +641,13 @@ int
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/server/src/server-rpc-fops.c b/xlators/protocol/server/src/server-rpc-fops.c
deleted file mode 100644
index 4b53de632e4..00000000000
--- a/xlators/protocol/server/src/server-rpc-fops.c
+++ /dev/null
@@ -1,6168 +0,0 @@
-/*
- Copyright (c) 2010-2013 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 <openssl/md5.h>
-
-#include "server.h"
-#include "server-helpers.h"
-#include "rpc-common-xdr.h"
-#include "glusterfs3-xdr.h"
-#include "glusterfs3.h"
-#include "compat-errno.h"
-
-#include "xdr-nfs3.h"
-
-#define SERVER_REQ_SET_ERROR(req, ret) \
- do { \
- rpcsvc_request_seterr (req, GARBAGE_ARGS); \
- ret = RPCSVC_ACTOR_ERROR; \
- } while (0)
-
-/* 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)
-{
- gfs3_statfs_rsp rsp = {0,};
- rpcsvc_request_t *req = NULL;
-
- 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);
-
-out:
- rsp.op_ret = op_ret;
- rsp.op_errno = gf_errno_to_error (op_errno);
-
- req = frame->local;
- server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gfs3_statfs_rsp);
-
- GF_FREE (rsp.xdata.xdata_val);
-
- return 0;
-}
-
-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,
- struct iatt *postparent)
-{
- rpcsvc_request_t *req = NULL;
- server_state_t *state = NULL;
- inode_t *root_inode = NULL;
- inode_t *link_inode = NULL;
- loc_t fresh_loc = {0,};
- gfs3_lookup_rsp rsp = {0,};
- uuid_t rootgfid = {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,
- frame->root->client->bound_xl,
- frame->root->client->bound_xl->fops->lookup,
- &fresh_loc, state->xdata);
-
- 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) {
- 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);
- }
- }
- goto out;
- }
-
- root_inode = frame->root->client->bound_xl->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.stat, stbuf);
-
- if (!__is_root_gfid (inode->gfid)) {
- link_inode = inode_link (inode, state->loc.parent,
- state->loc.name, stbuf);
- if (link_inode) {
- inode_lookup (link_inode);
- inode_unref (link_inode);
- }
- }
-
-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,
- fop_log_level (GF_FOP_LOOKUP, op_errno),
- "%"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,
- fop_log_level (GF_FOP_LOOKUP, op_errno),
- "%"PRId64": LOOKUP %s (%s) ==> (%s)",
- frame->root->unique, state->loc.path,
- uuid_utoa (state->resolve.gfid),
- strerror (op_errno));
- }
- }
-
- req = frame->local;
- server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gfs3_lookup_rsp);
-
- GF_FREE (rsp.xdata.xdata_val);
-
- return 0;
-}
-
-
-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)
-{
- gfs3_lk_rsp rsp = {0,};
- rpcsvc_request_t *req = NULL;
- server_state_t *state = NULL;
-
- GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
- rsp.xdata.xdata_len, op_errno, out);
-
- if (op_ret) {
- state = CALL_STATE (frame);
- gf_log (this->name, fop_log_level (GF_FOP_LK, op_errno),
- "%"PRId64": LK %"PRId64" (%s) ==> "
- "(%s)", frame->root->unique,
- state->resolve.fd_no,
- uuid_utoa (state->resolve.gfid),
- strerror (op_errno));
- 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);
-
-out:
- rsp.op_ret = op_ret;
- rsp.op_errno = gf_errno_to_error (op_errno);
-
- req = frame->local;
- server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gfs3_lk_rsp);
-
- GF_FREE (rsp.xdata.xdata_val);
-
- return 0;
-}
-
-
-int
-server_inodelk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
-{
- gf_common_rsp rsp = {0,};
- server_state_t *state = NULL;
- rpcsvc_request_t *req = NULL;
-
- 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) {
- gf_log (this->name, fop_log_level (GF_FOP_INODELK, op_errno),
- "%"PRId64": INODELK %s (%s) ==> (%s)",
- frame->root->unique, state->loc.path,
- uuid_utoa (state->resolve.gfid),
- strerror (op_errno));
- goto out;
- }
-
-out:
- rsp.op_ret = op_ret;
- rsp.op_errno = gf_errno_to_error (op_errno);
-
- req = frame->local;
- server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gf_common_rsp);
-
- GF_FREE (rsp.xdata.xdata_val);
-
- return 0;
-}
-
-
-int
-server_finodelk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
-{
- gf_common_rsp rsp = {0,};
- server_state_t *state = NULL;
- rpcsvc_request_t *req = NULL;
-
- 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) {
- gf_log (this->name, fop_log_level (GF_FOP_FINODELK, op_errno),
- "%"PRId64": FINODELK %"PRId64" (%s) "
- "==> (%s)", frame->root->unique,
- state->resolve.fd_no,
- uuid_utoa (state->resolve.gfid),
- strerror (op_errno));
- goto out;
- }
-
-out:
- rsp.op_ret = op_ret;
- rsp.op_errno = gf_errno_to_error (op_errno);
-
- req = frame->local;
- server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gf_common_rsp);
-
- GF_FREE (rsp.xdata.xdata_val);
-
- 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)
-{
- gf_common_rsp rsp = {0,};
- server_state_t *state = NULL;
- rpcsvc_request_t *req = NULL;
-
- 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) {
- gf_log (this->name, fop_log_level (GF_FOP_ENTRYLK, op_errno),
- "%"PRId64": ENTRYLK %s (%s) ==> (%s)",
- frame->root->unique, state->loc.path,
- uuid_utoa (state->resolve.gfid),
- strerror (op_errno));
- goto out;
- }
-
-out:
- rsp.op_ret = op_ret;
- rsp.op_errno = gf_errno_to_error (op_errno);
-
- req = frame->local;
- server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gf_common_rsp);
-
- GF_FREE (rsp.xdata.xdata_val);
-
- 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)
-{
- gf_common_rsp rsp = {0,};
- server_state_t *state = NULL;
- rpcsvc_request_t *req = NULL;
-
- 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) {
- gf_log (this->name, fop_log_level (GF_FOP_FENTRYLK, op_errno),
- "%"PRId64": FENTRYLK %"PRId64" (%s) ==>(%s)",
- frame->root->unique, state->resolve.fd_no,
- uuid_utoa (state->resolve.gfid),
- strerror (op_errno));
- goto out;
- }
-
-out:
- rsp.op_ret = op_ret;
- rsp.op_errno = gf_errno_to_error (op_errno);
-
- req = frame->local;
- server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gf_common_rsp);
-
- GF_FREE (rsp.xdata.xdata_val);
-
- return 0;
-}
-
-
-int
-server_access_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
-{
- gf_common_rsp rsp = {0,};
- rpcsvc_request_t *req = NULL;
- server_state_t *state = NULL;
-
- GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
- rsp.xdata.xdata_len, op_errno, out);
-
- if (op_ret) {
- state = CALL_STATE (frame);
- 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;
- }
-
-out:
- rsp.op_ret = op_ret;
- rsp.op_errno = gf_errno_to_error (op_errno);
-
- req = frame->local;
- server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gf_common_rsp);
-
- GF_FREE (rsp.xdata.xdata_val);
-
- return 0;
-}
-
-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)
-{
- gfs3_rmdir_rsp rsp = {0,};
- server_state_t *state = NULL;
- inode_t *parent = NULL;
- rpcsvc_request_t *req = NULL;
-
- GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
- rsp.xdata.xdata_len, op_errno, out);
-
- state = CALL_STATE (frame);
-
- if (op_ret) {
- gf_log (this->name, GF_LOG_INFO,
- "%"PRId64": RMDIR %s (%s/%s) ==> (%s)",
- frame->root->unique, state->loc.path,
- uuid_utoa (state->resolve.pargfid),
- state->resolve.bname, strerror (op_errno));
- goto out;
- }
-
- 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);
-
- req = frame->local;
- server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gfs3_rmdir_rsp);
-
- GF_FREE (rsp.xdata.xdata_val);
-
- return 0;
-}
-
-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)
-{
- gfs3_mkdir_rsp rsp = {0,};
- server_state_t *state = NULL;
- inode_t *link_inode = NULL;
- rpcsvc_request_t *req = NULL;
-
- 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) {
- gf_log (this->name, GF_LOG_INFO,
- "%"PRId64": MKDIR %s (%s/%s) ==> (%s)",
- frame->root->unique, state->loc.path,
- uuid_utoa (state->resolve.pargfid),
- state->resolve.bname, strerror (op_errno));
- goto out;
- }
-
- 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);
-
- req = frame->local;
- server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gfs3_mkdir_rsp);
-
- GF_FREE (rsp.xdata.xdata_val);
-
- return 0;
-}
-
-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)
-{
- gfs3_mknod_rsp rsp = {0,};
- server_state_t *state = NULL;
- inode_t *link_inode = NULL;
- rpcsvc_request_t *req = NULL;
-
- 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) {
- gf_log (this->name, GF_LOG_INFO,
- "%"PRId64": MKNOD %s (%s/%s) ==> (%s)",
- frame->root->unique, state->loc.path,
- uuid_utoa (state->resolve.pargfid),
- state->resolve.bname, strerror (op_errno));
- goto out;
- }
-
- 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);
-
- req = frame->local;
- server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gfs3_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)
-{
- gf_common_rsp rsp = {0,};
- server_state_t *state = NULL;
- rpcsvc_request_t *req = NULL;
-
- GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
- rsp.xdata.xdata_len, op_errno, out);
-
- if (op_ret < 0) {
- state = CALL_STATE (frame);
- gf_log (this->name, GF_LOG_INFO,
- "%"PRId64": FSYNCDIR %"PRId64" (%s) ==> (%s)",
- frame->root->unique, state->resolve.fd_no,
- uuid_utoa (state->resolve.gfid),
- strerror (op_errno));
- goto out;
- }
-
-out:
- rsp.op_ret = op_ret;
- rsp.op_errno = gf_errno_to_error (op_errno);
-
- req = frame->local;
- server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gf_common_rsp);
-
- GF_FREE (rsp.xdata.xdata_val);
-
- 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)
-{
- gfs3_readdir_rsp rsp = {0,};
- server_state_t *state = NULL;
- rpcsvc_request_t *req = NULL;
- int ret = 0;
-
- GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
- rsp.xdata.xdata_len, op_errno, out);
-
- if (op_ret < 0) {
- state = CALL_STATE (frame);
- 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;
- }
-
- /* (op_ret == 0) is valid, and means EOF */
- if (op_ret) {
- ret = serialize_rsp_dirent (entries, &rsp);
- if (ret == -1) {
- op_ret = -1;
- op_errno = ENOMEM;
- goto out;
- }
- }
-
-out:
- rsp.op_ret = op_ret;
- rsp.op_errno = gf_errno_to_error (op_errno);
-
- req = frame->local;
- server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gfs3_readdir_rsp);
-
- GF_FREE (rsp.xdata.xdata_val);
-
- 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_state_t *state = NULL;
- server_ctx_t *serv_ctx = NULL;
- rpcsvc_request_t *req = NULL;
- gfs3_opendir_rsp rsp = {0,};
- uint64_t fd_no = 0;
-
- GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
- rsp.xdata.xdata_len, op_errno, out);
-
- if (op_ret < 0) {
- state = CALL_STATE (frame);
- gf_log (this->name, fop_log_level (GF_FOP_OPENDIR, op_errno),
- "%"PRId64": OPENDIR %s (%s) ==> (%s)",
- frame->root->unique, state->loc.path,
- uuid_utoa (state->resolve.gfid), strerror (op_errno));
- goto out;
- }
-
- serv_ctx = server_ctx_get (frame->root->client, this);
- if (serv_ctx == NULL) {
- gf_log (this->name, GF_LOG_INFO, "server_ctx_get() failed");
- goto out;
- }
-
- fd_bind (fd);
- fd_no = gf_fd_unused_get (serv_ctx->fdtable, fd);
- fd_ref (fd); // on behalf of the client
-
-out:
- rsp.fd = fd_no;
- rsp.op_ret = op_ret;
- rsp.op_errno = gf_errno_to_error (op_errno);
-
- req = frame->local;
- server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gfs3_opendir_rsp);
-
- GF_FREE (rsp.xdata.xdata_val);
-
- 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)
-{
- gf_common_rsp rsp = {0,};
- rpcsvc_request_t *req = NULL;
- server_state_t *state = NULL;
- gf_loglevel_t loglevel = GF_LOG_NONE;
-
- GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
- rsp.xdata.xdata_len, op_errno, out);
-
- if (op_ret == -1) {
- state = CALL_STATE (frame);
- if (ENODATA == op_errno || ENOATTR == op_errno)
- loglevel = GF_LOG_DEBUG;
- else
- loglevel = GF_LOG_INFO;
-
- gf_log (this->name, loglevel,
- "%"PRId64": REMOVEXATTR %s (%s) of key %s ==> (%s)",
- frame->root->unique, state->loc.path,
- 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);
-
- req = frame->local;
- server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gf_common_rsp);
-
- GF_FREE (rsp.xdata.xdata_val);
-
- 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)
-{
- gf_common_rsp rsp = {0,};
- rpcsvc_request_t *req = NULL;
- server_state_t *state = NULL;
-
- GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
- rsp.xdata.xdata_len, op_errno, out);
-
- if (op_ret == -1) {
- state = CALL_STATE (frame);
- 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);
-
- req = frame->local;
- server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gf_common_rsp);
-
- GF_FREE (rsp.xdata.xdata_val);
-
- 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)
-{
- gfs3_getxattr_rsp rsp = {0,};
- rpcsvc_request_t *req = NULL;
- server_state_t *state = NULL;
-
- GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
- rsp.xdata.xdata_len, op_errno, out);
-
- if (op_ret == -1) {
- state = CALL_STATE (frame);
- gf_log (this->name, fop_log_level (GF_FOP_GETXATTR, op_errno),
- "%"PRId64": GETXATTR %s (%s) (%s) ==> (%s)",
- frame->root->unique, state->loc.path,
- uuid_utoa (state->resolve.gfid),
- state->name, strerror (op_errno));
- goto out;
- }
-
- GF_PROTOCOL_DICT_SERIALIZE (this, dict, &rsp.dict.dict_val,
- rsp.dict.dict_len, op_errno, out);
-
-out:
- rsp.op_ret = op_ret;
- rsp.op_errno = gf_errno_to_error (op_errno);
-
- req = frame->local;
- server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gfs3_getxattr_rsp);
-
- GF_FREE (rsp.dict.dict_val);
-
- GF_FREE (rsp.xdata.xdata_val);
-
- return 0;
-}
-
-
-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)
-{
- gfs3_fgetxattr_rsp rsp = {0,};
- server_state_t *state = NULL;
- rpcsvc_request_t *req = NULL;
-
- GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
- rsp.xdata.xdata_len, op_errno, out);
-
- if (op_ret == -1) {
- state = CALL_STATE (frame);
- gf_log (this->name, fop_log_level (GF_FOP_FGETXATTR, op_errno),
- "%"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;
- }
-
- GF_PROTOCOL_DICT_SERIALIZE (this, dict, &rsp.dict.dict_val,
- rsp.dict.dict_len, op_errno, out);
-
-out:
-
- rsp.op_ret = op_ret;
- rsp.op_errno = gf_errno_to_error (op_errno);
-
- req = frame->local;
- server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gfs3_fgetxattr_rsp);
-
- GF_FREE (rsp.dict.dict_val);
-
- GF_FREE (rsp.xdata.xdata_val);
-
- return 0;
-}
-
-/* print every key */
-static int
-_gf_server_log_setxattr_failure (dict_t *d, char *k, data_t *v,
- void *tmp)
-{
- server_state_t *state = NULL;
- call_frame_t *frame = NULL;
-
- frame = tmp;
- state = CALL_STATE (frame);
-
- gf_log (THIS->name, GF_LOG_INFO,
- "%"PRId64": SETXATTR %s (%s) ==> %s",
- frame->root->unique, state->loc.path,
- uuid_utoa (state->resolve.gfid), k);
- 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)
-{
- gf_common_rsp rsp = {0,};
- rpcsvc_request_t *req = NULL;
- server_state_t *state = NULL;
-
- GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
- rsp.xdata.xdata_len, op_errno, out);
-
- if (op_ret == -1) {
- state = CALL_STATE (frame);
- if (op_errno != ENOTSUP)
- dict_foreach (state->dict,
- _gf_server_log_setxattr_failure,
- frame);
-
- gf_log (THIS->name, ((op_errno == ENOTSUP) ?
- GF_LOG_DEBUG : GF_LOG_INFO),
- "%s", strerror (op_errno));
- goto out;
- }
-
-out:
- rsp.op_ret = op_ret;
- rsp.op_errno = gf_errno_to_error (op_errno);
-
- req = frame->local;
- server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gf_common_rsp);
-
- GF_FREE (rsp.xdata.xdata_val);
-
- return 0;
-}
-
-/* print every key here */
-static int
-_gf_server_log_fsetxattr_failure (dict_t *d, char *k, data_t *v,
- void *tmp)
-{
- call_frame_t *frame = NULL;
- server_state_t *state = NULL;
-
- frame = tmp;
- state = CALL_STATE (frame);
-
- gf_log (THIS->name, GF_LOG_INFO,
- "%"PRId64": FSETXATTR %"PRId64" (%s) ==> %s",
- frame->root->unique, state->resolve.fd_no,
- uuid_utoa (state->resolve.gfid), k);
-
- return 0;
-}
-
-int
-server_fsetxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
-{
- gf_common_rsp rsp = {0,};
- rpcsvc_request_t *req = NULL;
- server_state_t *state = NULL;
-
- GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
- rsp.xdata.xdata_len, op_errno, out);
-
- if (op_ret == -1) {
- state = CALL_STATE (frame);
- if (op_errno != ENOTSUP) {
- dict_foreach (state->dict,
- _gf_server_log_fsetxattr_failure,
- frame);
- }
- gf_log (THIS->name, ((op_errno == ENOTSUP) ?
- GF_LOG_DEBUG : GF_LOG_INFO),
- "%s", strerror (op_errno));
- goto out;
- }
-
-out:
- rsp.op_ret = op_ret;
- rsp.op_errno = gf_errno_to_error (op_errno);
-
- req = frame->local;
- server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gf_common_rsp);
-
- GF_FREE (rsp.xdata.xdata_val);
-
- return 0;
-}
-
-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)
-{
- 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,};
-
- GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
- rsp.xdata.xdata_len, op_errno, out);
-
- state = CALL_STATE (frame);
-
- 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;
-
- /* TODO: log gfid of the inodes */
- gf_log (frame->root->client->bound_xl->name, GF_LOG_TRACE,
- "%"PRId64": RENAME_CBK %s ==> %s",
- frame->root->unique, state->loc.name, state->loc2.name);
-
- /* 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);
-
- inode_unref (tmp_inode);
- }
-
- 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);
-
-out:
- rsp.op_ret = op_ret;
- rsp.op_errno = gf_errno_to_error (op_errno);
-
- req = frame->local;
- server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gfs3_rename_rsp);
-
- GF_FREE (rsp.xdata.xdata_val);
-
- return 0;
-}
-
-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)
-{
- gfs3_unlink_rsp rsp = {0,};
- server_state_t *state = NULL;
- inode_t *parent = NULL;
- rpcsvc_request_t *req = NULL;
-
- GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
- rsp.xdata.xdata_len, op_errno, out);
-
- state = CALL_STATE (frame);
-
- if (op_ret) {
- gf_log (this->name, fop_log_level (GF_FOP_UNLINK, op_errno),
- "%"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;
- }
-
- /* TODO: log gfid of the inodes */
- gf_log (frame->root->client->bound_xl->name, GF_LOG_TRACE,
- "%"PRId64": UNLINK_CBK %s",
- frame->root->unique, 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);
-
- 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);
-
- req = frame->local;
- server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gfs3_unlink_rsp);
-
- GF_FREE (rsp.xdata.xdata_val);
-
- return 0;
-}
-
-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)
-{
- gfs3_symlink_rsp rsp = {0,};
- server_state_t *state = NULL;
- inode_t *link_inode = NULL;
- rpcsvc_request_t *req = NULL;
-
- 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) {
- gf_log (this->name, GF_LOG_INFO,
- "%"PRId64": SYMLINK %s (%s/%s) ==> (%s)",
- frame->root->unique, state->loc.path,
- uuid_utoa (state->resolve.pargfid),
- state->resolve.bname, strerror (op_errno));
- goto out;
- }
-
- 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);
-
- req = frame->local;
- server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gfs3_symlink_rsp);
-
- GF_FREE (rsp.xdata.xdata_val);
-
- return 0;
-}
-
-
-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)
-{
- 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,};
-
- GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
- rsp.xdata.xdata_len, op_errno, out);
-
- state = CALL_STATE (frame);
-
- if (op_ret) {
- uuid_utoa_r (state->resolve.gfid, gfid_str);
- uuid_utoa_r (state->resolve2.pargfid, newpar_str);
-
- 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;
- }
-
- 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);
-
- req = frame->local;
- server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gfs3_link_rsp);
-
- GF_FREE (rsp.xdata.xdata_val);
-
- return 0;
-}
-
-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)
-{
- gfs3_truncate_rsp rsp = {0,};
- server_state_t *state = NULL;
- rpcsvc_request_t *req = NULL;
-
- GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
- rsp.xdata.xdata_len, op_errno, out);
-
- if (op_ret) {
- state = CALL_STATE (frame);
- gf_log (this->name, GF_LOG_INFO,
- "%"PRId64": TRUNCATE %s (%s) ==> (%s)",
- frame->root->unique, state->loc.path,
- uuid_utoa (state->resolve.gfid), strerror (op_errno));
- goto out;
- }
-
- 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);
-
- req = frame->local;
- server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gfs3_truncate_rsp);
-
- GF_FREE (rsp.xdata.xdata_val);
-
- 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)
-{
- gfs3_fstat_rsp rsp = {0,};
- server_state_t *state = NULL;
- rpcsvc_request_t *req = NULL;
-
- GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
- rsp.xdata.xdata_len, op_errno, out);
-
- if (op_ret) {
- state = CALL_STATE (frame);
- gf_log (this->name, GF_LOG_INFO,
- "%"PRId64": FSTAT %"PRId64" (%s) ==> (%s)",
- frame->root->unique, state->resolve.fd_no,
- uuid_utoa (state->resolve.gfid), strerror (op_errno));
- goto out;
- }
-
- gf_stat_from_iatt (&rsp.stat, stbuf);
-
-out:
- rsp.op_ret = op_ret;
- rsp.op_errno = gf_errno_to_error (op_errno);
-
- req = frame->local;
- server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gfs3_fstat_rsp);
-
- GF_FREE (rsp.xdata.xdata_val);
-
- return 0;
-}
-
-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)
-{
- gfs3_ftruncate_rsp rsp = {0};
- server_state_t *state = NULL;
- rpcsvc_request_t *req = NULL;
-
- GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
- rsp.xdata.xdata_len, op_errno, out);
-
- if (op_ret) {
- state = CALL_STATE (frame);
- gf_log (this->name, GF_LOG_INFO,
- "%"PRId64": FTRUNCATE %"PRId64" (%s)==> (%s)",
- frame->root->unique, state->resolve.fd_no,
- uuid_utoa (state->resolve.gfid), strerror (op_errno));
- goto out;
- }
-
- 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);
-
- req = frame->local;
- server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gfs3_ftruncate_rsp);
-
- GF_FREE (rsp.xdata.xdata_val);
-
- 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)
-{
- gf_common_rsp rsp = {0,};
- server_state_t *state = NULL;
- rpcsvc_request_t *req = NULL;
-
- GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
- rsp.xdata.xdata_len, op_errno, out);
-
- if (op_ret < 0) {
- state = CALL_STATE (frame);
- gf_log (this->name, fop_log_level (GF_FOP_FLUSH, op_errno),
- "%"PRId64": FLUSH %"PRId64" (%s) ==> (%s)",
- frame->root->unique, state->resolve.fd_no,
- uuid_utoa (state->resolve.gfid), strerror (op_errno));
- goto out;
- }
-
-out:
- rsp.op_ret = op_ret;
- rsp.op_errno = gf_errno_to_error (op_errno);
-
- req = frame->local;
- server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gf_common_rsp);
-
- GF_FREE (rsp.xdata.xdata_val);
-
- return 0;
-}
-
-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)
-{
- gfs3_fsync_rsp rsp = {0,};
- server_state_t *state = NULL;
- rpcsvc_request_t *req = NULL;
-
- GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
- rsp.xdata.xdata_len, op_errno, out);
-
- if (op_ret < 0) {
- state = CALL_STATE (frame);
- gf_log (this->name, GF_LOG_INFO,
- "%"PRId64": FSYNC %"PRId64" (%s) ==> (%s)",
- frame->root->unique, state->resolve.fd_no,
- uuid_utoa (state->resolve.gfid), strerror (op_errno));
- goto out;
- }
-
- 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);
-
- req = frame->local;
- server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gfs3_fsync_rsp);
-
- GF_FREE (rsp.xdata.xdata_val);
-
- return 0;
-}
-
-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)
-{
- gfs3_write_rsp rsp = {0,};
- server_state_t *state = NULL;
- rpcsvc_request_t *req = NULL;
-
- GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
- rsp.xdata.xdata_len, op_errno, out);
-
- if (op_ret < 0) {
- state = CALL_STATE (frame);
- gf_log (this->name, GF_LOG_INFO,
- "%"PRId64": WRITEV %"PRId64" (%s) ==> (%s)",
- frame->root->unique, state->resolve.fd_no,
- uuid_utoa (state->resolve.gfid), strerror (op_errno));
- goto out;
- }
-
- 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);
-
- req = frame->local;
- server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gfs3_write_rsp);
-
- GF_FREE (rsp.xdata.xdata_val);
-
- return 0;
-}
-
-
-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)
-{
- gfs3_read_rsp rsp = {0,};
- server_state_t *state = NULL;
- rpcsvc_request_t *req = NULL;
-
-#ifdef GF_TESTING_IO_XDATA
- {
- int ret = 0;
- if (!xdata)
- xdata = dict_new ();
-
- 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);
-
- if (op_ret < 0) {
- state = CALL_STATE (frame);
- gf_log (this->name, GF_LOG_INFO,
- "%"PRId64": READV %"PRId64" (%s) ==> (%s)",
- frame->root->unique, state->resolve.fd_no,
- uuid_utoa (state->resolve.gfid), strerror (op_errno));
- goto out;
- }
-
- 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);
-
- req = frame->local;
- server_submit_reply (frame, req, &rsp, vector, count, iobref,
- (xdrproc_t)xdr_gfs3_read_rsp);
-
- GF_FREE (rsp.xdata.xdata_val);
-
- return 0;
-}
-
-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)
-{
- gfs3_rchecksum_rsp rsp = {0,};
- rpcsvc_request_t *req = NULL;
- server_state_t *state = NULL;
-
- GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
- rsp.xdata.xdata_len, op_errno, out);
-
- if (op_ret < 0) {
- state = CALL_STATE (frame);
- gf_log (this->name, GF_LOG_INFO,
- "%"PRId64": RCHECKSUM %"PRId64" (%s)==> (%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);
-
- req = frame->local;
- server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gfs3_rchecksum_rsp);
-
- GF_FREE (rsp.xdata.xdata_val);
-
- return 0;
-}
-
-
-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)
-{
- server_state_t *state = NULL;
- server_ctx_t *serv_ctx = NULL;
- rpcsvc_request_t *req = NULL;
- uint64_t fd_no = 0;
- gfs3_open_rsp rsp = {0,};
-
- GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
- rsp.xdata.xdata_len, op_errno, out);
-
- if (op_ret < 0) {
- state = CALL_STATE (frame);
- gf_log (this->name, fop_log_level (GF_FOP_OPEN, op_errno),
- "%"PRId64": OPEN %s (%s) ==> (%s)",
- frame->root->unique, state->loc.path,
- uuid_utoa (state->resolve.gfid),
- strerror (op_errno));
- goto out;
- }
-
- serv_ctx = server_ctx_get (frame->root->client, this);
- if (serv_ctx == NULL) {
- gf_log (this->name, GF_LOG_INFO, "server_ctx_get() failed");
- goto out;
- }
-
- fd_bind (fd);
- fd_no = gf_fd_unused_get (serv_ctx->fdtable, fd);
- fd_ref (fd);
- rsp.fd = fd_no;
-
-out:
- rsp.op_ret = op_ret;
- rsp.op_errno = gf_errno_to_error (op_errno);
-
- req = frame->local;
- server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gfs3_open_rsp);
- GF_FREE (rsp.xdata.xdata_val);
-
- 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)
-{
- server_state_t *state = NULL;
- server_ctx_t *serv_ctx = NULL;
- inode_t *link_inode = NULL;
- rpcsvc_request_t *req = NULL;
- uint64_t fd_no = 0;
- gfs3_create_rsp rsp = {0,};
-
- 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) {
- 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;
- }
-
- /* TODO: log gfid too */
- gf_log (frame->root->client->bound_xl->name, GF_LOG_TRACE,
- "%"PRId64": CREATE %s (%s)",
- frame->root->unique, state->loc.name,
- uuid_utoa (stbuf->ia_gfid));
-
- link_inode = inode_link (inode, state->loc.parent,
- state->loc.name, stbuf);
-
- if (!link_inode) {
- op_ret = -1;
- op_errno = ENOENT;
- goto out;
- }
-
- 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);
-
- serv_ctx = server_ctx_get (frame->root->client, this);
- if (serv_ctx == NULL) {
- gf_log (this->name, GF_LOG_INFO, "server_ctx_get() failed");
- goto out;
- }
-
- fd_bind (fd);
- fd_no = gf_fd_unused_get (serv_ctx->fdtable, fd);
- fd_ref (fd);
-
- if ((fd_no > UINT64_MAX) || (fd == 0)) {
- op_ret = -1;
- op_errno = errno;
- }
-
- gf_stat_from_iatt (&rsp.stat, stbuf);
- gf_stat_from_iatt (&rsp.preparent, preparent);
- gf_stat_from_iatt (&rsp.postparent, postparent);
-
-out:
- rsp.fd = fd_no;
- rsp.op_ret = op_ret;
- rsp.op_errno = gf_errno_to_error (op_errno);
-
- req = frame->local;
- server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gfs3_create_rsp);
-
- GF_FREE (rsp.xdata.xdata_val);
-
- return 0;
-}
-
-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)
-{
- gfs3_readlink_rsp rsp = {0,};
- server_state_t *state = NULL;
- rpcsvc_request_t *req = NULL;
-
- GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
- rsp.xdata.xdata_len, op_errno, out);
-
- if (op_ret < 0) {
- state = CALL_STATE (frame);
- gf_log (this->name, GF_LOG_INFO,
- "%"PRId64": READLINK %s (%s) ==> (%s)",
- frame->root->unique, state->loc.path,
- uuid_utoa (state->resolve.gfid),
- strerror (op_errno));
- goto out;
- }
-
- 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 = "";
-
- req = frame->local;
- server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gfs3_readlink_rsp);
-
- GF_FREE (rsp.xdata.xdata_val);
-
- 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)
-{
- gfs3_stat_rsp rsp = {0,};
- server_state_t *state = NULL;
- rpcsvc_request_t *req = NULL;
-
- GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
- rsp.xdata.xdata_len, op_errno, out);
-
- if (op_ret) {
- state = CALL_STATE (frame);
- gf_log (this->name, fop_log_level (GF_FOP_STAT, op_errno),
- "%"PRId64": STAT %s (%s) ==> (%s)",
- frame->root->unique, state->loc.path,
- uuid_utoa (state->resolve.gfid),
- strerror (op_errno));
- goto out;
- }
-
- gf_stat_from_iatt (&rsp.stat, stbuf);
-
-out:
- rsp.op_ret = op_ret;
- rsp.op_errno = gf_errno_to_error (op_errno);
-
- req = frame->local;
- server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gfs3_stat_rsp);
-
- GF_FREE (rsp.xdata.xdata_val);
-
- return 0;
-}
-
-
-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)
-{
- gfs3_setattr_rsp rsp = {0,};
- server_state_t *state = NULL;
- rpcsvc_request_t *req = NULL;
-
- GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
- rsp.xdata.xdata_len, op_errno, out);
-
- if (op_ret) {
- state = CALL_STATE (frame);
- gf_log (this->name, GF_LOG_INFO,
- "%"PRId64": SETATTR %s (%s) ==> (%s)",
- frame->root->unique, state->loc.path,
- uuid_utoa (state->resolve.gfid),
- strerror (op_errno));
- goto out;
- }
-
- 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);
-
- req = frame->local;
- server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gfs3_setattr_rsp);
-
- GF_FREE (rsp.xdata.xdata_val);
-
- return 0;
-}
-
-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)
-{
- gfs3_fsetattr_rsp rsp = {0,};
- server_state_t *state = NULL;
- rpcsvc_request_t *req = NULL;
-
- GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
- rsp.xdata.xdata_len, op_errno, out);
-
- if (op_ret) {
- state = CALL_STATE (frame);
- gf_log (this->name, GF_LOG_INFO,
- "%"PRId64": FSETATTR %"PRId64" (%s) ==> (%s)",
- frame->root->unique, state->resolve.fd_no,
- uuid_utoa (state->resolve.gfid),
- strerror (op_errno));
- goto out;
- }
-
- 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);
-
- req = frame->local;
- server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gfs3_fsetattr_rsp);
-
- GF_FREE (rsp.xdata.xdata_val);
-
- return 0;
-}
-
-
-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)
-{
- gfs3_xattrop_rsp rsp = {0,};
- server_state_t *state = NULL;
- rpcsvc_request_t *req = NULL;
-
- GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
- rsp.xdata.xdata_len, op_errno, out);
-
- if (op_ret < 0) {
- state = CALL_STATE (frame);
- gf_log (this->name, GF_LOG_INFO,
- "%"PRId64": XATTROP %s (%s) ==> (%s)",
- frame->root->unique, state->loc.path,
- uuid_utoa (state->resolve.gfid),
- strerror (op_errno));
- goto out;
- }
-
- GF_PROTOCOL_DICT_SERIALIZE (this, dict, &rsp.dict.dict_val,
- rsp.dict.dict_len, op_errno, out);
-
-out:
- rsp.op_ret = op_ret;
- rsp.op_errno = gf_errno_to_error (op_errno);
-
- req = frame->local;
- server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gfs3_xattrop_rsp);
-
- GF_FREE (rsp.dict.dict_val);
-
- GF_FREE (rsp.xdata.xdata_val);
-
- return 0;
-}
-
-
-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)
-{
- gfs3_xattrop_rsp rsp = {0,};
- server_state_t *state = NULL;
- rpcsvc_request_t *req = NULL;
-
- GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
- rsp.xdata.xdata_len, op_errno, out);
-
- if (op_ret < 0) {
- state = CALL_STATE (frame);
- gf_log (this->name, GF_LOG_INFO,
- "%"PRId64": FXATTROP %"PRId64" (%s) ==> (%s)",
- frame->root->unique, state->resolve.fd_no,
- uuid_utoa (state->resolve.gfid),
- strerror (op_errno));
- goto out;
- }
-
- GF_PROTOCOL_DICT_SERIALIZE (this, dict, &rsp.dict.dict_val,
- rsp.dict.dict_len, op_errno, out);
-
-out:
- rsp.op_ret = op_ret;
- rsp.op_errno = gf_errno_to_error (op_errno);
-
- req = frame->local;
- server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gfs3_fxattrop_rsp);
-
- GF_FREE (rsp.dict.dict_val);
-
- GF_FREE (rsp.xdata.xdata_val);
-
- return 0;
-}
-
-
-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)
-{
- gfs3_readdirp_rsp rsp = {0,};
- server_state_t *state = NULL;
- rpcsvc_request_t *req = NULL;
- int ret = 0;
-
- 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) {
- state = CALL_STATE (frame);
- 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;
- }
-
- /* (op_ret == 0) is valid, and means EOF */
- if (op_ret) {
- ret = serialize_rsp_direntp (entries, &rsp);
- if (ret == -1) {
- op_ret = -1;
- op_errno = ENOMEM;
- goto out;
- }
- }
-
- 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);
-
- req = frame->local;
- server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gfs3_readdirp_rsp);
-
- GF_FREE (rsp.xdata.xdata_val);
-
- readdirp_rsp_cleanup (&rsp);
-
- return 0;
-}
-
-int
-server_fallocate_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)
-{
- gfs3_fallocate_rsp rsp = {0,};
- server_state_t *state = NULL;
- rpcsvc_request_t *req = NULL;
-
- GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
- rsp.xdata.xdata_len, op_errno, out);
-
- if (op_ret) {
- state = CALL_STATE (frame);
- gf_log (this->name, GF_LOG_INFO,
- "%"PRId64": FALLOCATE %"PRId64" (%s) ==> (%s)",
- frame->root->unique, state->resolve.fd_no,
- uuid_utoa (state->resolve.gfid),
- strerror (op_errno));
- goto out;
- }
-
- 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);
-
- req = frame->local;
- server_submit_reply(frame, req, &rsp, NULL, 0, NULL,
- (xdrproc_t) xdr_gfs3_fallocate_rsp);
-
- GF_FREE (rsp.xdata.xdata_val);
-
- return 0;
-}
-
-int
-server_discard_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)
-{
- gfs3_discard_rsp rsp = {0,};
- server_state_t *state = NULL;
- rpcsvc_request_t *req = NULL;
-
- GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
- rsp.xdata.xdata_len, op_errno, out);
-
- if (op_ret) {
- state = CALL_STATE (frame);
- gf_log (this->name, GF_LOG_INFO,
- "%"PRId64": DISCARD %"PRId64" (%s) ==> (%s)",
- frame->root->unique, state->resolve.fd_no,
- uuid_utoa (state->resolve.gfid),
- strerror (op_errno));
- goto out;
- }
-
- 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);
-
- req = frame->local;
- server_submit_reply(frame, req, &rsp, NULL, 0, NULL,
- (xdrproc_t) xdr_gfs3_discard_rsp);
-
- GF_FREE (rsp.xdata.xdata_val);
-
- return 0;
-}
-
-int
-server_zerofill_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)
-{
- gfs3_zerofill_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) {
- gf_log (this->name, GF_LOG_INFO,
- "%"PRId64": ZEROFILL%"PRId64" (%s) ==> (%s)",
- frame->root->unique, state->resolve.fd_no,
- uuid_utoa (state->resolve.gfid),
- strerror (op_errno));
- goto out;
- }
-
- 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_zerofill_rsp);
-
- GF_FREE (rsp.xdata.xdata_val);
-
- return 0;
-}
-
-
-/* Resume function section */
-
-int
-server_rchecksum_resume (call_frame_t *frame, xlator_t *bound_xl)
-{
- server_state_t *state = NULL;
- int op_ret = 0;
- int op_errno = EINVAL;
-
- 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, state->xdata);
-
- return 0;
-err:
- server_rchecksum_cbk (frame, NULL, frame->this, op_ret, op_errno, 0,
- NULL, NULL);
-
- return 0;
-
-}
-
-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, bound_xl->fops->lk,
- state->fd, state->cmd, &state->flock, state->xdata);
-
- return 0;
-
-err:
- server_lk_cbk (frame, NULL, frame->this, state->resolve.op_ret,
- state->resolve.op_errno, NULL, NULL);
- return 0;
-}
-
-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, state->xdata);
- return 0;
-err:
- server_rename_cbk (frame, NULL, frame->this, op_ret, op_errno,
- NULL, NULL, NULL, NULL, NULL, NULL);
- return 0;
-}
-
-
-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, state->xdata);
-
- return 0;
-err:
- server_link_cbk (frame, NULL, frame->this, op_ret, op_errno,
- NULL, NULL, NULL, NULL, NULL);
- return 0;
-}
-
-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->umask, state->xdata);
-
- return 0;
-err:
- server_symlink_cbk (frame, NULL, frame->this, state->resolve.op_ret,
- state->resolve.op_errno, NULL, NULL, NULL, NULL, NULL);
- return 0;
-}
-
-
-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, state->xdata);
- return 0;
-err:
- server_access_cbk (frame, NULL, frame->this, state->resolve.op_ret,
- state->resolve.op_errno, NULL);
- return 0;
-}
-
-int
-server_fentrylk_resume (call_frame_t *frame, xlator_t *bound_xl)
-{
- GF_UNUSED int ret = -1;
- server_state_t *state = NULL;
-
- state = CALL_STATE (frame);
-
- if (state->resolve.op_ret != 0)
- goto err;
-
- if (!state->xdata)
- state->xdata = dict_new ();
-
- if (state->xdata)
- ret = dict_set_str (state->xdata, "connection-id",
- frame->root->client->client_uid);
-
- STACK_WIND (frame, server_fentrylk_cbk, bound_xl,
- bound_xl->fops->fentrylk,
- state->volume, state->fd, state->name,
- state->cmd, state->type, state->xdata);
-
- return 0;
-err:
- server_fentrylk_cbk (frame, NULL, frame->this, state->resolve.op_ret,
- state->resolve.op_errno, NULL);
- return 0;
-}
-
-
-int
-server_entrylk_resume (call_frame_t *frame, xlator_t *bound_xl)
-{
- GF_UNUSED int ret = -1;
- server_state_t *state = NULL;
-
- state = CALL_STATE (frame);
-
- if (state->resolve.op_ret != 0)
- goto err;
-
- if (!state->xdata)
- state->xdata = dict_new ();
-
- if (state->xdata)
- ret = dict_set_str (state->xdata, "connection-id",
- frame->root->client->client_uid);
-
- STACK_WIND (frame, server_entrylk_cbk,
- bound_xl, bound_xl->fops->entrylk,
- state->volume, &state->loc, state->name,
- state->cmd, state->type, state->xdata);
- return 0;
-err:
- server_entrylk_cbk (frame, NULL, frame->this, state->resolve.op_ret,
- state->resolve.op_errno, NULL);
- return 0;
-}
-
-
-int
-server_finodelk_resume (call_frame_t *frame, xlator_t *bound_xl)
-{
- GF_UNUSED int ret = -1;
- server_state_t *state = NULL;
-
- gf_log (bound_xl->name, GF_LOG_DEBUG, "frame %p, xlator %p",
- frame, bound_xl);
-
- state = CALL_STATE (frame);
-
- if (state->resolve.op_ret != 0)
- goto err;
-
- if (!state->xdata)
- state->xdata = dict_new ();
-
- if (state->xdata)
- ret = dict_set_str (state->xdata, "connection-id",
- frame->root->client->client_uid);
-
- STACK_WIND (frame, server_finodelk_cbk, bound_xl,
- bound_xl->fops->finodelk, state->volume, state->fd,
- state->cmd, &state->flock, state->xdata);
-
- return 0;
-err:
- server_finodelk_cbk (frame, NULL, frame->this, state->resolve.op_ret,
- state->resolve.op_errno, NULL);
-
- return 0;
-}
-
-int
-server_inodelk_resume (call_frame_t *frame, xlator_t *bound_xl)
-{
- GF_UNUSED int ret = -1;
- server_state_t *state = NULL;
-
- gf_log (bound_xl->name, GF_LOG_DEBUG, "frame %p, xlator %p",
- frame, bound_xl);
-
- state = CALL_STATE (frame);
-
- if (state->resolve.op_ret != 0)
- goto err;
-
- if (!state->xdata)
- state->xdata = dict_new ();
-
- if (state->xdata)
- ret = dict_set_str (state->xdata, "connection-id",
- frame->root->client->client_uid);
-
- STACK_WIND (frame, server_inodelk_cbk, bound_xl,
- bound_xl->fops->inodelk, state->volume, &state->loc,
- state->cmd, &state->flock, state->xdata);
- return 0;
-err:
- server_inodelk_cbk (frame, NULL, frame->this, state->resolve.op_ret,
- state->resolve.op_errno, NULL);
- return 0;
-}
-
-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, state->flags, state->xdata);
- return 0;
-err:
- server_rmdir_cbk (frame, NULL, frame->this, state->resolve.op_ret,
- state->resolve.op_errno, NULL, NULL, NULL);
- return 0;
-}
-
-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->umask, state->xdata);
-
- return 0;
-err:
- server_mkdir_cbk (frame, NULL, frame->this, state->resolve.op_ret,
- state->resolve.op_errno, NULL, NULL, NULL, NULL, NULL);
- return 0;
-}
-
-
-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->umask, state->xdata);
-
- return 0;
-err:
- server_mknod_cbk (frame, NULL, frame->this, state->resolve.op_ret,
- state->resolve.op_errno, NULL, NULL, NULL, NULL, NULL);
- return 0;
-}
-
-
-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, state->xdata);
- return 0;
-
-err:
- server_fsyncdir_cbk (frame, NULL, frame->this,
- state->resolve.op_ret,
- state->resolve.op_errno, NULL);
- return 0;
-}
-
-
-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;
-
- GF_ASSERT (state->fd);
-
- STACK_WIND (frame, server_readdir_cbk,
- bound_xl,
- bound_xl->fops->readdir,
- state->fd, state->size, state->offset, state->xdata);
-
- return 0;
-err:
- server_readdir_cbk (frame, NULL, frame->this, state->resolve.op_ret,
- state->resolve.op_errno, NULL, NULL);
- return 0;
-}
-
-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, state->dict);
-
- return 0;
-err:
- server_readdirp_cbk (frame, NULL, frame->this, state->resolve.op_ret,
- state->resolve.op_errno, NULL, NULL);
- return 0;
-}
-
-
-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);
- 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);
- return 0;
-err:
- server_opendir_cbk (frame, NULL, frame->this, state->resolve.op_ret,
- state->resolve.op_errno, NULL, NULL);
- return 0;
-}
-
-
-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, state->xdata);
- return 0;
-
-err:
- server_statfs_cbk (frame, NULL, frame->this, state->resolve.op_ret,
- state->resolve.op_errno, NULL, NULL);
- return 0;
-}
-
-
-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, state->xdata);
- 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);
- return 0;
-}
-
-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, state->xdata);
- return 0;
-err:
- server_fgetxattr_cbk (frame, NULL, frame->this, state->resolve.op_ret,
- state->resolve.op_errno, NULL, NULL);
- return 0;
-}
-
-
-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, state->xdata);
- return 0;
-err:
- server_xattrop_cbk (frame, NULL, frame->this, state->resolve.op_ret,
- state->resolve.op_errno, NULL, NULL);
- return 0;
-}
-
-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, state->xdata);
- return 0;
-err:
- server_fxattrop_cbk (frame, NULL, frame->this, state->resolve.op_ret,
- state->resolve.op_errno, NULL, NULL);
- return 0;
-}
-
-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, state->xdata);
- return 0;
-err:
- server_fsetxattr_cbk (frame, NULL, frame->this, state->resolve.op_ret,
- state->resolve.op_errno, NULL);
-
- return 0;
-}
-
-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, state->flags, state->xdata);
- return 0;
-err:
- server_unlink_cbk (frame, NULL, frame->this, state->resolve.op_ret,
- state->resolve.op_errno, NULL, NULL, NULL);
- return 0;
-}
-
-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, state->xdata);
- return 0;
-err:
- server_truncate_cbk (frame, NULL, frame->this, state->resolve.op_ret,
- state->resolve.op_errno, NULL, NULL, NULL);
- return 0;
-}
-
-
-
-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, state->xdata);
- return 0;
-err:
- server_fstat_cbk (frame, NULL, frame->this, state->resolve.op_ret,
- state->resolve.op_errno, NULL, NULL);
- return 0;
-}
-
-
-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, state->xdata);
- return 0;
-err:
- server_setxattr_cbk (frame, NULL, frame->this, state->resolve.op_ret,
- state->resolve.op_errno, NULL);
-
- return 0;
-}
-
-
-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, state->xdata);
- return 0;
-err:
- server_getxattr_cbk (frame, NULL, frame->this, state->resolve.op_ret,
- state->resolve.op_errno, NULL, NULL);
- return 0;
-}
-
-
-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, state->xdata);
- return 0;
-err:
- server_ftruncate_cbk (frame, NULL, frame->this, state->resolve.op_ret,
- state->resolve.op_errno, NULL, NULL, NULL);
-
- return 0;
-}
-
-
-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, state->xdata);
- return 0;
-err:
- server_flush_cbk (frame, NULL, frame->this, state->resolve.op_ret,
- state->resolve.op_errno, NULL);
-
- return 0;
-}
-
-
-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, state->xdata);
- return 0;
-err:
- server_fsync_cbk (frame, NULL, frame->this, state->resolve.op_ret,
- state->resolve.op_errno, NULL, NULL, NULL);
-
- return 0;
-}
-
-int
-server_writev_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_writev_cbk,
- bound_xl, bound_xl->fops->writev,
- state->fd, state->payload_vector, state->payload_count,
- state->offset, state->flags, state->iobref, state->xdata);
-
- return 0;
-err:
- server_writev_cbk (frame, NULL, frame->this, state->resolve.op_ret,
- state->resolve.op_errno, NULL, NULL, NULL);
- return 0;
-}
-
-
-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, state->flags, state->xdata);
-
- return 0;
-err:
- server_readv_cbk (frame, NULL, frame->this, state->resolve.op_ret,
- state->resolve.op_errno, NULL, 0, NULL, NULL, NULL);
- return 0;
-}
-
-
-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);
- 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);
-
- return 0;
-err:
- server_create_cbk (frame, NULL, frame->this, state->resolve.op_ret,
- state->resolve.op_errno, NULL, NULL, NULL,
- NULL, NULL, NULL);
- return 0;
-}
-
-
-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, state->xdata);
-
- return 0;
-err:
- server_open_cbk (frame, NULL, frame->this, state->resolve.op_ret,
- state->resolve.op_errno, NULL, NULL);
- return 0;
-}
-
-
-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, state->xdata);
- return 0;
-err:
- server_readlink_cbk (frame, NULL, frame->this, state->resolve.op_ret,
- state->resolve.op_errno, NULL, NULL, NULL);
- return 0;
-}
-
-
-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, state->xdata);
- return 0;
-err:
- server_fsetattr_cbk (frame, NULL, frame->this, state->resolve.op_ret,
- state->resolve.op_errno, NULL, NULL, NULL);
-
- return 0;
-}
-
-
-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, state->xdata);
- return 0;
-err:
- server_setattr_cbk (frame, NULL, frame->this, state->resolve.op_ret,
- state->resolve.op_errno, NULL, NULL, NULL);
-
- return 0;
-}
-
-
-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, state->xdata);
- return 0;
-err:
- server_stat_cbk (frame, NULL, frame->this, state->resolve.op_ret,
- state->resolve.op_errno, NULL, NULL);
- return 0;
-}
-
-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->xdata);
-
- return 0;
-err:
- server_lookup_cbk (frame, NULL, frame->this, state->resolve.op_ret,
- state->resolve.op_errno, NULL, NULL, NULL, NULL);
-
- return 0;
-}
-
-int
-server_fallocate_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_fallocate_cbk,
- bound_xl, bound_xl->fops->fallocate,
- state->fd, state->flags, state->offset, state->size,
- state->xdata);
- return 0;
-err:
- server_fallocate_cbk(frame, NULL, frame->this, state->resolve.op_ret,
- state->resolve.op_errno, NULL, NULL, NULL);
-
- return 0;
-}
-
-int
-server_discard_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_discard_cbk,
- bound_xl, bound_xl->fops->discard,
- state->fd, state->offset, state->size, state->xdata);
- return 0;
-err:
- server_discard_cbk(frame, NULL, frame->this, state->resolve.op_ret,
- state->resolve.op_errno, NULL, NULL, NULL);
-
- return 0;
-}
-
-int
-server_zerofill_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_zerofill_cbk,
- bound_xl, bound_xl->fops->zerofill,
- state->fd, state->offset, state->size, state->xdata);
- return 0;
-err:
- server_zerofill_cbk(frame, NULL, frame->this, state->resolve.op_ret,
- state->resolve.op_errno, NULL, NULL, NULL);
-
- return 0;
-}
-
-
-
-/* Fop section */
-
-int
-server3_3_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;
-
- if (!req)
- return 0;
-
- /* Initialize args first, then decode */
-
- ret = xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_stat_req);
- if (ret < 0) {
- //failed to decode msg;
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
-
- frame = get_frame_from_request (req);
- if (!frame) {
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
- frame->root->op = GF_FOP_STAT;
-
- state = CALL_STATE (frame);
- if (!frame->root->client->bound_xl) {
- /* auth failure, request on subvolume without setvolume */
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
-
- state->resolve.type = RESOLVE_MUST;
- memcpy (state->resolve.gfid, args.gfid, 16);
-
- GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl,
- state->xdata,
- args.xdata.xdata_val,
- args.xdata.xdata_len, ret,
- op_errno, out);
-
-
- ret = 0;
- resolve_and_resume (frame, server_stat_resume);
-
-out:
- free (args.xdata.xdata_val);
-
- if (op_errno)
- SERVER_REQ_SET_ERROR (req, ret);
-
- return ret;
-}
-
-
-int
-server3_3_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;
-
- ret = xdr_to_generic (req->msg[0], &args,
- (xdrproc_t)xdr_gfs3_setattr_req);
- if (ret < 0) {
- //failed to decode msg;
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
-
- frame = get_frame_from_request (req);
- if (!frame) {
- // something wrong, mostly insufficient memory
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
- frame->root->op = GF_FOP_SETATTR;
-
- state = CALL_STATE (frame);
- if (!frame->root->client->bound_xl) {
- /* auth failure, request on subvolume without setvolume */
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
-
- state->resolve.type = RESOLVE_MUST;
- memcpy (state->resolve.gfid, args.gfid, 16);
-
- gf_stat_to_iatt (&args.stbuf, &state->stbuf);
- state->valid = args.valid;
-
- GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->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)
- SERVER_REQ_SET_ERROR (req, ret);
-
- free (args.xdata.xdata_val);
-
- return ret;
-}
-
-
-int
-server3_3_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;
-
- ret = xdr_to_generic (req->msg[0], &args,
- (xdrproc_t)xdr_gfs3_fsetattr_req);
- if (ret < 0) {
- //failed to decode msg;
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
-
- frame = get_frame_from_request (req);
- if (!frame) {
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
- frame->root->op = GF_FOP_FSETATTR;
-
- state = CALL_STATE (frame);
- if (!frame->root->client->bound_xl) {
- /* auth failure, request on subvolume without setvolume */
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
-
- state->resolve.type = RESOLVE_MUST;
- state->resolve.fd_no = args.fd;
-
- gf_stat_to_iatt (&args.stbuf, &state->stbuf);
- state->valid = args.valid;
-
- GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->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)
- SERVER_REQ_SET_ERROR (req, ret);
-
- return ret;
-}
-
-int
-server3_3_fallocate(rpcsvc_request_t *req)
-{
- server_state_t *state = NULL;
- call_frame_t *frame = NULL;
- gfs3_fallocate_req args = {{0},};
- int ret = -1;
- int op_errno = 0;
-
- if (!req)
- return ret;
-
- ret = xdr_to_generic (req->msg[0], &args,
- (xdrproc_t)xdr_gfs3_fallocate_req);
- if (ret < 0) {
- //failed to decode msg;
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
-
- frame = get_frame_from_request (req);
- if (!frame) {
- // something wrong, mostly insufficient memory
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
- frame->root->op = GF_FOP_FALLOCATE;
-
- state = CALL_STATE (frame);
- if (!frame->root->client->bound_xl) {
- /* auth failure, request on subvolume without setvolume */
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
-
- state->resolve.type = RESOLVE_MUST;
- state->resolve.fd_no = args.fd;
-
- state->flags = args.flags;
- state->offset = args.offset;
- state->size = args.size;
- memcpy(state->resolve.gfid, args.gfid, 16);
-
- GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl,
- state->xdata,
- args.xdata.xdata_val,
- args.xdata.xdata_len, ret,
- op_errno, out);
-
- ret = 0;
- resolve_and_resume (frame, server_fallocate_resume);
-
-out:
- free (args.xdata.xdata_val);
-
- if (op_errno)
- SERVER_REQ_SET_ERROR (req, ret);
-
- return ret;
-}
-
-
-int
-server3_3_discard(rpcsvc_request_t *req)
-{
- server_state_t *state = NULL;
- call_frame_t *frame = NULL;
- gfs3_discard_req args = {{0},};
- int ret = -1;
- int op_errno = 0;
-
- if (!req)
- return ret;
-
- ret = xdr_to_generic (req->msg[0], &args,
- (xdrproc_t)xdr_gfs3_discard_req);
- if (ret < 0) {
- //failed to decode msg;
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
-
- frame = get_frame_from_request (req);
- if (!frame) {
- // something wrong, mostly insufficient memory
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
- frame->root->op = GF_FOP_DISCARD;
-
- state = CALL_STATE (frame);
- if (!frame->root->client->bound_xl) {
- /* auth failure, request on subvolume without setvolume */
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
-
- state->resolve.type = RESOLVE_MUST;
- state->resolve.fd_no = args.fd;
-
- state->offset = args.offset;
- state->size = args.size;
- memcpy(state->resolve.gfid, args.gfid, 16);
-
- GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl,
- state->xdata,
- args.xdata.xdata_val,
- args.xdata.xdata_len, ret,
- op_errno, out);
-
- ret = 0;
- resolve_and_resume (frame, server_discard_resume);
-
-out:
- free (args.xdata.xdata_val);
-
- if (op_errno)
- SERVER_REQ_SET_ERROR (req, ret);
-
- return ret;
-}
-
-
-int
-server3_3_zerofill(rpcsvc_request_t *req)
-{
- server_state_t *state = NULL;
- call_frame_t *frame = NULL;
- gfs3_zerofill_req args = {{0},};
- int ret = -1;
- int op_errno = 0;
-
- if (!req)
- return ret;
-
- ret = xdr_to_generic (req->msg[0], &args,
- (xdrproc_t)xdr_gfs3_zerofill_req);
- if (ret < 0) {
- /*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_ZEROFILL;
-
- state = CALL_STATE (frame);
- if (!frame->root->client->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;
-
- state->offset = args.offset;
- state->size = args.size;
- memcpy(state->resolve.gfid, args.gfid, 16);
-
- GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl, state->xdata,
- (args.xdata.xdata_val),
- (args.xdata.xdata_len), ret,
- op_errno, out);
-
- ret = 0;
- resolve_and_resume (frame, server_zerofill_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_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;
-
- ret = xdr_to_generic (req->msg[0], &args,
- (xdrproc_t)xdr_gfs3_readlink_req);
- if (ret < 0) {
- //failed to decode msg;
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
-
- frame = get_frame_from_request (req);
- if (!frame) {
- // something wrong, mostly insufficient memory
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
- frame->root->op = GF_FOP_READLINK;
-
- state = CALL_STATE (frame);
- if (!frame->root->client->bound_xl) {
- /* auth failure, request on subvolume without setvolume */
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
-
- state->resolve.type = RESOLVE_MUST;
- memcpy (state->resolve.gfid, args.gfid, 16);
-
- state->size = args.size;
-
- GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->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)
- SERVER_REQ_SET_ERROR (req, ret);
-
- return ret;
-}
-
-
-int
-server3_3_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;
-
- if (!req)
- return ret;
-
- args.bname = alloca (req->msg[0].iov_len);
-
- ret = xdr_to_generic (req->msg[0], &args,
- (xdrproc_t)xdr_gfs3_create_req);
- if (ret < 0) {
- //failed to decode msg;
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
-
- frame = get_frame_from_request (req);
- if (!frame) {
- // something wrong, mostly insufficient memory
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
- frame->root->op = GF_FOP_CREATE;
-
- state = CALL_STATE (frame);
- if (!frame->root->client->bound_xl) {
- /* auth failure, request on subvolume without setvolume */
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
-
-
- 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 (frame->root->client->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 (op_errno)
- SERVER_REQ_SET_ERROR (req, ret);
-
- return ret;
-}
-
-
-int
-server3_3_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;
-
- ret = xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_open_req);
- if (ret < 0) {
- //failed to decode msg;
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
-
- frame = get_frame_from_request (req);
- if (!frame) {
- // something wrong, mostly insufficient memory
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
- frame->root->op = GF_FOP_OPEN;
-
- state = CALL_STATE (frame);
- if (!frame->root->client->bound_xl) {
- /* auth failure, request on subvolume without setvolume */
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
-
- state->resolve.type = RESOLVE_MUST;
- memcpy (state->resolve.gfid, args.gfid, 16);
-
- state->flags = gf_flags_to_flags (args.flags);
-
- GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->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)
- SERVER_REQ_SET_ERROR (req, ret);
-
- free (args.xdata.xdata_val);
-
- return ret;
-}
-
-
-int
-server3_3_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;
-
- ret = xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_read_req);
- if (ret < 0) {
- //failed to decode msg;
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
-
- frame = get_frame_from_request (req);
- if (!frame) {
- // something wrong, mostly insufficient memory
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
- frame->root->op = GF_FOP_READ;
-
- state = CALL_STATE (frame);
- if (!frame->root->client->bound_xl) {
- /* auth failure, request on subvolume without setvolume */
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
-
- state->resolve.type = RESOLVE_MUST;
- 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 (frame->root->client->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)
- SERVER_REQ_SET_ERROR (req, ret);
-
- return ret;
-}
-
-
-int
-server3_3_writev (rpcsvc_request_t *req)
-{
- server_state_t *state = NULL;
- call_frame_t *frame = NULL;
- gfs3_write_req args = {{0,},};
- 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);
- if (len < 0) {
- //failed to decode msg;
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
-
- frame = get_frame_from_request (req);
- if (!frame) {
- // something wrong, mostly insufficient memory
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
- frame->root->op = GF_FOP_WRITE;
-
- state = CALL_STATE (frame);
- if (!frame->root->client->bound_xl) {
- /* auth failure, request on subvolume without setvolume */
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
-
- state->resolve.type = RESOLVE_MUST;
- state->resolve.fd_no = args.fd;
- state->offset = args.offset;
- state->size = args.size;
- 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
- = (req->msg[0].iov_base + len);
- state->payload_vector[0].iov_len
- = req->msg[0].iov_len - len;
- state->payload_count = 1;
- }
-
- for (i = 1; i < req->count; i++) {
- state->payload_vector[state->payload_count++]
- = req->msg[i];
- }
-
- for (i = 0; i < state->payload_count; i++) {
- state->size += state->payload_vector[i].iov_len;
- }
-
- GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->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)
- SERVER_REQ_SET_ERROR (req, ret);
-
- return ret;
-}
-
-
-#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;
-}
-
-
-int
-server3_3_release (rpcsvc_request_t *req)
-{
- client_t *client = NULL;
- server_ctx_t *serv_ctx = NULL;
- gfs3_release_req args = {{0,},};
- gf_common_rsp rsp = {0,};
- int ret = -1;
-
- ret = xdr_to_generic (req->msg[0], &args,
- (xdrproc_t)xdr_gfs3_release_req);
- if (ret < 0) {
- //failed to decode msg;
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
-
- client = req->trans->xl_private;
- if (!client) {
- /* Handshake is not complete yet. */
- req->rpc_err = SYSTEM_ERR;
- goto out;
- }
-
- serv_ctx = server_ctx_get (client, client->this);
- if (serv_ctx == NULL) {
- gf_log (req->trans->name, GF_LOG_INFO,
- "server_ctx_get() failed");
- req->rpc_err = SYSTEM_ERR;
- goto out;
- }
-
- gf_fd_put (serv_ctx->fdtable, args.fd);
-
- server_submit_reply (NULL, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gf_common_rsp);
-
- ret = 0;
-out:
- return ret;
-}
-
-int
-server3_3_releasedir (rpcsvc_request_t *req)
-{
- client_t *client = NULL;
- server_ctx_t *serv_ctx = NULL;
- gfs3_releasedir_req args = {{0,},};
- gf_common_rsp rsp = {0,};
- int ret = -1;
-
- ret = xdr_to_generic (req->msg[0], &args,
- (xdrproc_t)xdr_gfs3_release_req);
- if (ret < 0) {
- //failed to decode msg;
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
-
- client = req->trans->xl_private;
- if (!client) {
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
-
- serv_ctx = server_ctx_get (client, client->this);
- if (serv_ctx == NULL) {
- gf_log (req->trans->name, GF_LOG_INFO,
- "server_ctx_get() failed");
- req->rpc_err = SYSTEM_ERR;
- goto out;
- }
-
- gf_fd_put (serv_ctx->fdtable, args.fd);
-
- server_submit_reply (NULL, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gf_common_rsp);
-
- ret = 0;
-out:
- return ret;
-}
-
-
-int
-server3_3_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;
-
- ret = xdr_to_generic (req->msg[0], &args,
- (xdrproc_t)xdr_gfs3_fsync_req);
- if (ret < 0) {
- //failed to decode msg;
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
-
- frame = get_frame_from_request (req);
- if (!frame) {
- // something wrong, mostly insufficient memory
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
- frame->root->op = GF_FOP_FSYNC;
-
- state = CALL_STATE (frame);
- if (!frame->root->client->bound_xl) {
- /* auth failure, request on subvolume without setvolume */
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
-
- 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 (frame->root->client->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)
- SERVER_REQ_SET_ERROR (req, ret);
-
- return ret;
-}
-
-
-
-int
-server3_3_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;
-
- ret = xdr_to_generic (req->msg[0], &args,
- (xdrproc_t)xdr_gfs3_flush_req);
- if (ret < 0) {
- //failed to decode msg;
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
-
- frame = get_frame_from_request (req);
- if (!frame) {
- // something wrong, mostly insufficient memory
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
- frame->root->op = GF_FOP_FLUSH;
-
- state = CALL_STATE (frame);
- if (!frame->root->client->bound_xl) {
- /* auth failure, request on subvolume without setvolume */
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
-
- state->resolve.type = RESOLVE_MUST;
- state->resolve.fd_no = args.fd;
- memcpy (state->resolve.gfid, args.gfid, 16);
-
- GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->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)
- SERVER_REQ_SET_ERROR (req, ret);
-
- return ret;
-}
-
-
-
-int
-server3_3_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;
-
- ret = xdr_to_generic (req->msg[0], &args,
- (xdrproc_t)xdr_gfs3_ftruncate_req);
- if (ret < 0) {
- //failed to decode msg;
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
-
- frame = get_frame_from_request (req);
- if (!frame) {
- // something wrong, mostly insufficient memory
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
- frame->root->op = GF_FOP_FTRUNCATE;
-
- state = CALL_STATE (frame);
- if (!frame->root->client->bound_xl) {
- /* auth failure, request on subvolume without setvolume */
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
-
- 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 (frame->root->client->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)
- SERVER_REQ_SET_ERROR (req, ret);
-
- return ret;
-}
-
-
-int
-server3_3_fstat (rpcsvc_request_t *req)
-{
- server_state_t *state = NULL;
- call_frame_t *frame = NULL;
- gfs3_fstat_req args = {{0,},};
- int ret = -1;
- int op_errno = 0;
-
- if (!req)
- return ret;
-
- ret = xdr_to_generic (req->msg[0], &args,
- (xdrproc_t)xdr_gfs3_fstat_req);
- if (ret < 0) {
- //failed to decode msg;
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
-
- frame = get_frame_from_request (req);
- if (!frame) {
- // something wrong, mostly insufficient memory
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
- frame->root->op = GF_FOP_FSTAT;
-
- state = CALL_STATE (frame);
- if (!frame->root->client->bound_xl) {
- /* auth failure, request on subvolume without setvolume */
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
-
- state->resolve.type = RESOLVE_MUST;
- state->resolve.fd_no = args.fd;
- memcpy (state->resolve.gfid, args.gfid, 16);
-
- GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->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)
- SERVER_REQ_SET_ERROR (req, ret);
-
- return ret;
-}
-
-
-int
-server3_3_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;
-
- ret = xdr_to_generic (req->msg[0], &args,
- (xdrproc_t)xdr_gfs3_truncate_req);
- if (ret < 0) {
- //failed to decode msg;
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
-
- frame = get_frame_from_request (req);
- if (!frame) {
- // something wrong, mostly insufficient memory
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
- frame->root->op = GF_FOP_TRUNCATE;
-
- state = CALL_STATE (frame);
- if (!frame->root->client->bound_xl) {
- /* auth failure, request on subvolume without setvolume */
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
-
- state->resolve.type = RESOLVE_MUST;
- memcpy (state->resolve.gfid, args.gfid, 16);
- state->offset = args.offset;
-
- GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->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)
- SERVER_REQ_SET_ERROR (req, ret);
-
- return ret;
-}
-
-
-
-int
-server3_3_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.bname = alloca (req->msg[0].iov_len);
-
- ret = xdr_to_generic (req->msg[0], &args,
- (xdrproc_t)xdr_gfs3_unlink_req);
- if (ret < 0) {
- //failed to decode msg;
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
-
- frame = get_frame_from_request (req);
- if (!frame) {
- // something wrong, mostly insufficient memory
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
- frame->root->op = GF_FOP_UNLINK;
-
- state = CALL_STATE (frame);
- if (!frame->root->client->bound_xl) {
- /* auth failure, request on subvolume without setvolume */
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
-
- state->resolve.type = RESOLVE_MUST;
- state->resolve.bname = gf_strdup (args.bname);
- memcpy (state->resolve.pargfid, args.pargfid, 16);
-
- state->flags = args.xflags;
-
- GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->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)
- SERVER_REQ_SET_ERROR (req, ret);
-
- return ret;
-}
-
-
-int
-server3_3_setxattr (rpcsvc_request_t *req)
-{
- server_state_t *state = NULL;
- dict_t *dict = NULL;
- call_frame_t *frame = NULL;
- gfs3_setxattr_req args = {{0,},};
- int32_t ret = -1;
- int32_t op_errno = 0;
-
- if (!req)
- return ret;
-
- args.dict.dict_val = alloca (req->msg[0].iov_len);
-
- ret = xdr_to_generic (req->msg[0], &args,
- (xdrproc_t)xdr_gfs3_setxattr_req);
- if (ret < 0) {
- //failed to decode msg;
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
-
- frame = get_frame_from_request (req);
- if (!frame) {
- // something wrong, mostly insufficient memory
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
- frame->root->op = GF_FOP_SETXATTR;
-
- state = CALL_STATE (frame);
- if (!frame->root->client->bound_xl) {
- /* auth failure, request on subvolume without setvolume */
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
-
- state->resolve.type = RESOLVE_MUST;
- state->flags = args.flags;
- memcpy (state->resolve.gfid, args.gfid, 16);
-
- GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl,
- dict,
- (args.dict.dict_val),
- (args.dict.dict_len), ret,
- op_errno, out);
-
- 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 (frame->root->client->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)
- SERVER_REQ_SET_ERROR (req, ret);
-
- if (dict)
- dict_unref (dict);
-
- return ret;
-}
-
-
-
-int
-server3_3_fsetxattr (rpcsvc_request_t *req)
-{
- server_state_t *state = NULL;
- dict_t *dict = NULL;
- call_frame_t *frame = NULL;
- gfs3_fsetxattr_req args = {{0,},};
- int32_t ret = -1;
- int32_t op_errno = 0;
-
- if (!req)
- return ret;
-
- args.dict.dict_val = alloca (req->msg[0].iov_len);
- ret = xdr_to_generic (req->msg[0], &args,
- (xdrproc_t)xdr_gfs3_fsetxattr_req);
- if (ret < 0) {
- //failed to decode msg;
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
-
- frame = get_frame_from_request (req);
- if (!frame) {
- // something wrong, mostly insufficient memory
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
- frame->root->op = GF_FOP_FSETXATTR;
-
- state = CALL_STATE (frame);
- if (!frame->root->client->bound_xl) {
- /* auth failure, request on subvolume without setvolume */
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
-
- 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 (frame->root->client->bound_xl,
- dict,
- (args.dict.dict_val),
- (args.dict.dict_len), ret,
- op_errno, out);
-
- state->dict = dict;
-
- GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl,
- state->xdata,
- args.xdata.xdata_val,
- args.xdata.xdata_len, ret,
- op_errno, out);
-
- ret = 0;
- resolve_and_resume (frame, server_fsetxattr_resume);
-
- return ret;
-out:
- free (args.xdata.xdata_val);
-
- if (op_errno)
- SERVER_REQ_SET_ERROR (req, ret);
-
- if (dict)
- dict_unref (dict);
-
- return ret;
-}
-
-
-
-int
-server3_3_fxattrop (rpcsvc_request_t *req)
-{
- dict_t *dict = NULL;
- server_state_t *state = NULL;
- call_frame_t *frame = NULL;
- gfs3_fxattrop_req args = {{0,},};
- int32_t ret = -1;
- int32_t op_errno = 0;
-
- if (!req)
- return ret;
-
- args.dict.dict_val = alloca (req->msg[0].iov_len);
- ret = xdr_to_generic (req->msg[0], &args,
- (xdrproc_t)xdr_gfs3_fxattrop_req);
- if (ret < 0) {
- //failed to decode msg;
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
-
- frame = get_frame_from_request (req);
- if (!frame) {
- // something wrong, mostly insufficient memory
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
- frame->root->op = GF_FOP_FXATTROP;
-
- state = CALL_STATE (frame);
- if (!frame->root->client->bound_xl) {
- /* auth failure, request on subvolume without setvolume */
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
-
- 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 (frame->root->client->bound_xl,
- dict,
- (args.dict.dict_val),
- (args.dict.dict_len), ret,
- op_errno, out);
-
- state->dict = dict;
-
- GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl,
- state->xdata,
- args.xdata.xdata_val,
- args.xdata.xdata_len, ret,
- op_errno, out);
-
- ret = 0;
- resolve_and_resume (frame, server_fxattrop_resume);
-
- return ret;
-
-out:
- free (args.xdata.xdata_val);
-
- if (op_errno)
- SERVER_REQ_SET_ERROR (req, ret);
-
- if (dict)
- dict_unref (dict);
-
- return ret;
-}
-
-
-
-int
-server3_3_xattrop (rpcsvc_request_t *req)
-{
- dict_t *dict = NULL;
- server_state_t *state = NULL;
- call_frame_t *frame = NULL;
- gfs3_xattrop_req args = {{0,},};
- int32_t ret = -1;
- int32_t op_errno = 0;
-
- if (!req)
- return ret;
-
- args.dict.dict_val = alloca (req->msg[0].iov_len);
-
- ret = xdr_to_generic (req->msg[0], &args,
- (xdrproc_t)xdr_gfs3_xattrop_req);
- if (ret < 0) {
- //failed to decode msg;
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
-
- frame = get_frame_from_request (req);
- if (!frame) {
- // something wrong, mostly insufficient memory
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
- frame->root->op = GF_FOP_XATTROP;
-
- state = CALL_STATE (frame);
- if (!frame->root->client->bound_xl) {
- /* auth failure, request on subvolume without setvolume */
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
-
- state->resolve.type = RESOLVE_MUST;
- state->flags = args.flags;
- memcpy (state->resolve.gfid, args.gfid, 16);
-
- GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl,
- dict,
- (args.dict.dict_val),
- (args.dict.dict_len), ret,
- op_errno, out);
-
- state->dict = dict;
-
- GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl,
- state->xdata,
- args.xdata.xdata_val,
- args.xdata.xdata_len, ret,
- op_errno, out);
-
- ret = 0;
- resolve_and_resume (frame, server_xattrop_resume);
-
- return ret;
-out:
- free (args.xdata.xdata_val);
-
- if (op_errno)
- SERVER_REQ_SET_ERROR (req, ret);
-
- if (dict)
- dict_unref (dict);
-
- return ret;
-}
-
-
-int
-server3_3_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);
-
- ret = xdr_to_generic (req->msg[0], &args,
- (xdrproc_t)xdr_gfs3_getxattr_req);
- if (ret < 0) {
- //failed to decode msg;
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
-
- frame = get_frame_from_request (req);
- if (!frame) {
- // something wrong, mostly insufficient memory
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
- frame->root->op = GF_FOP_GETXATTR;
-
- state = CALL_STATE (frame);
- if (!frame->root->client->bound_xl) {
- /* auth failure, request on subvolume without setvolume */
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
-
- state->resolve.type = RESOLVE_MUST;
- memcpy (state->resolve.gfid, args.gfid, 16);
-
- if (args.namelen) {
- state->name = gf_strdup (args.name);
- /* There can be some commands hidden in key, check and proceed */
- gf_server_check_getxattr_cmd (frame, state->name);
- }
-
- GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->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)
- SERVER_REQ_SET_ERROR (req, ret);
-
- return ret;
-}
-
-
-int
-server3_3_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);
- ret = xdr_to_generic (req->msg[0], &args,
- (xdrproc_t)xdr_gfs3_fgetxattr_req);
- if (ret < 0) {
- //failed to decode msg;
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
-
- frame = get_frame_from_request (req);
- if (!frame) {
- // something wrong, mostly insufficient memory
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
- frame->root->op = GF_FOP_FGETXATTR;
-
- state = CALL_STATE (frame);
- if (!frame->root->client->bound_xl) {
- /* auth failure, request on subvolume without setvolume */
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
-
- 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 (frame->root->client->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)
- SERVER_REQ_SET_ERROR (req, ret);
-
- return ret;
-}
-
-
-
-int
-server3_3_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);
-
- ret = xdr_to_generic (req->msg[0], &args,
- (xdrproc_t)xdr_gfs3_removexattr_req);
- if (ret < 0) {
- //failed to decode msg;
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
-
- frame = get_frame_from_request (req);
- if (!frame) {
- // something wrong, mostly insufficient memory
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
- frame->root->op = GF_FOP_REMOVEXATTR;
-
- state = CALL_STATE (frame);
- if (!frame->root->client->bound_xl) {
- /* auth failure, request on subvolume without setvolume */
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
-
- state->resolve.type = RESOLVE_MUST;
- memcpy (state->resolve.gfid, args.gfid, 16);
- state->name = gf_strdup (args.name);
-
- GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->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)
- SERVER_REQ_SET_ERROR (req, ret);
-
- 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);
-
- ret = xdr_to_generic (req->msg[0], &args,
- (xdrproc_t)xdr_gfs3_fremovexattr_req);
- if (ret < 0) {
- //failed to decode msg;
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
-
- frame = get_frame_from_request (req);
- if (!frame) {
- // something wrong, mostly insufficient memory
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
- frame->root->op = GF_FOP_FREMOVEXATTR;
-
- state = CALL_STATE (frame);
- if (!frame->root->client->bound_xl) {
- /* auth failure, request on subvolume without setvolume */
- SERVER_REQ_SET_ERROR (req, ret);
- 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 (frame->root->client->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)
- SERVER_REQ_SET_ERROR (req, ret);
-
- return ret;
-}
-
-
-
-
-int
-server3_3_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;
-
- ret = xdr_to_generic (req->msg[0], &args,
- (xdrproc_t)xdr_gfs3_opendir_req);
- if (ret < 0) {
- //failed to decode msg;
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
-
- frame = get_frame_from_request (req);
- if (!frame) {
- // something wrong, mostly insufficient memory
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
- frame->root->op = GF_FOP_OPENDIR;
-
- state = CALL_STATE (frame);
- if (!frame->root->client->bound_xl) {
- /* auth failure, request on subvolume without setvolume */
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
-
- state->resolve.type = RESOLVE_MUST;
- memcpy (state->resolve.gfid, args.gfid, 16);
-
- GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->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)
- SERVER_REQ_SET_ERROR (req, ret);
-
- return ret;
-}
-
-
-int
-server3_3_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;
-
- ret = xdr_to_generic (req->msg[0], &args,
- (xdrproc_t)xdr_gfs3_readdirp_req);
- if (ret < 0) {
- //failed to decode msg;
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
-
- frame = get_frame_from_request (req);
- if (!frame) {
- // something wrong, mostly insufficient memory
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
- frame->root->op = GF_FOP_READDIRP;
-
- state = CALL_STATE (frame);
- if (!frame->root->client->bound_xl) {
- /* auth failure, request on subvolume without setvolume */
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
-
- /* FIXME: this should go away when variable sized iobufs are introduced
- * and transport layer can send msgs bigger than current page-size.
- */
- headers_size = sizeof (struct rpc_msg) + sizeof (gfs3_readdir_rsp);
- if ((frame->this->ctx->page_size < args.size)
- || ((frame->this->ctx->page_size - args.size) < headers_size)) {
- state->size = frame->this->ctx->page_size - headers_size;
- } else {
- state->size = args.size;
- }
-
- 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 (frame->root->client->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)
- SERVER_REQ_SET_ERROR (req, ret);
-
- free (args.dict.dict_val);
-
- return ret;
-}
-
-int
-server3_3_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;
-
- ret = xdr_to_generic (req->msg[0], &args,
- (xdrproc_t)xdr_gfs3_readdir_req);
- if (ret < 0) {
- //failed to decode msg;
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
-
- frame = get_frame_from_request (req);
- if (!frame) {
- // something wrong, mostly insufficient memory
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
- frame->root->op = GF_FOP_READDIR;
-
- state = CALL_STATE (frame);
- if (!frame->root->client->bound_xl) {
- /* auth failure, request on subvolume without setvolume */
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
-
- /* FIXME: this should go away when variable sized iobufs are introduced
- * and transport layer can send msgs bigger than current page-size.
- */
- headers_size = sizeof (struct rpc_msg) + sizeof (gfs3_readdir_rsp);
- if ((frame->this->ctx->page_size < args.size)
- || ((frame->this->ctx->page_size - args.size) < headers_size)) {
- state->size = frame->this->ctx->page_size - headers_size;
- } else {
- state->size = args.size;
- }
-
- 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 (frame->root->client->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)
- SERVER_REQ_SET_ERROR (req, ret);
-
- return ret;
-}
-
-int
-server3_3_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;
-
- ret = xdr_to_generic (req->msg[0], &args,
- (xdrproc_t)xdr_gfs3_fsyncdir_req);
- if (ret < 0) {
- //failed to decode msg;
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
-
- frame = get_frame_from_request (req);
- if (!frame) {
- // something wrong, mostly insufficient memory
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
- frame->root->op = GF_FOP_FSYNCDIR;
-
- state = CALL_STATE (frame);
- if (!frame->root->client->bound_xl) {
- /* auth failure, request on subvolume without setvolume */
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
-
- 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 (frame->root->client->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)
- SERVER_REQ_SET_ERROR (req, ret);
-
- return ret;
-}
-
-
-
-int
-server3_3_mknod (rpcsvc_request_t *req)
-{
- server_state_t *state = NULL;
- call_frame_t *frame = NULL;
- gfs3_mknod_req args = {{0,},};
- int ret = -1;
- int op_errno = 0;
-
- if (!req)
- return ret;
-
- args.bname = alloca (req->msg[0].iov_len);
-
- ret = xdr_to_generic (req->msg[0], &args,
- (xdrproc_t)xdr_gfs3_mknod_req);
- if (ret < 0) {
- //failed to decode msg;
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
-
- frame = get_frame_from_request (req);
- if (!frame) {
- // something wrong, mostly insufficient memory
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
- frame->root->op = GF_FOP_MKNOD;
-
- state = CALL_STATE (frame);
- if (!frame->root->client->bound_xl) {
- /* auth failure, request on subvolume without setvolume */
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
-
- state->resolve.type = RESOLVE_NOT;
- memcpy (state->resolve.pargfid, args.pargfid, 16);
- state->resolve.bname = gf_strdup (args.bname);
-
- state->mode = args.mode;
- state->dev = args.dev;
- state->umask = args.umask;
-
- GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl,
- state->xdata,
- args.xdata.xdata_val,
- args.xdata.xdata_len, ret,
- op_errno, out);
-
- ret = 0;
- resolve_and_resume (frame, server_mknod_resume);
-
-out:
- if (op_errno)
- SERVER_REQ_SET_ERROR (req, ret);
-
- /* memory allocated by libc, don't use GF_FREE */
- free (args.xdata.xdata_val);
-
- return ret;
-
-}
-
-
-int
-server3_3_mkdir (rpcsvc_request_t *req)
-{
- server_state_t *state = NULL;
- call_frame_t *frame = NULL;
- gfs3_mkdir_req args = {{0,},};
- int ret = -1;
- int op_errno = 0;
-
- if (!req)
- return ret;
-
- args.bname = alloca (req->msg[0].iov_len);
-
- ret = xdr_to_generic (req->msg[0], &args,
- (xdrproc_t)xdr_gfs3_mkdir_req);
- if (ret < 0) {
- //failed to decode msg;
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
-
- frame = get_frame_from_request (req);
- if (!frame) {
- // something wrong, mostly insufficient memory
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
- frame->root->op = GF_FOP_MKDIR;
-
- state = CALL_STATE (frame);
- if (!frame->root->client->bound_xl) {
- /* auth failure, request on subvolume without setvolume */
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
-
- state->resolve.type = RESOLVE_NOT;
- memcpy (state->resolve.pargfid, args.pargfid, 16);
- 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 (frame->root->client->bound_xl,
- state->xdata,
- args.xdata.xdata_val,
- args.xdata.xdata_len, ret,
- op_errno, out);
-
- ret = 0;
- resolve_and_resume (frame, server_mkdir_resume);
-
-out:
- if (op_errno)
- SERVER_REQ_SET_ERROR (req, ret);
-
- free (args.xdata.xdata_val);
-
- return ret;
-}
-
-
-int
-server3_3_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.bname = alloca (req->msg[0].iov_len);
-
- ret = xdr_to_generic (req->msg[0], &args,
- (xdrproc_t)xdr_gfs3_rmdir_req);
- if (ret < 0) {
- //failed to decode msg;
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
-
- frame = get_frame_from_request (req);
- if (!frame) {
- // something wrong, mostly insufficient memory
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
- frame->root->op = GF_FOP_RMDIR;
-
- state = CALL_STATE (frame);
- if (!frame->root->client->bound_xl) {
- /* auth failure, request on subvolume without setvolume */
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
-
- state->resolve.type = RESOLVE_MUST;
- memcpy (state->resolve.pargfid, args.pargfid, 16);
- state->resolve.bname = gf_strdup (args.bname);
-
- state->flags = args.xflags;
-
- GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl,
- state->xdata,
- args.xdata.xdata_val,
- args.xdata.xdata_len, ret,
- op_errno, out);
-
- ret = 0;
- resolve_and_resume (frame, server_rmdir_resume);
-out:
- free (args.xdata.xdata_val);
-
- if (op_errno)
- SERVER_REQ_SET_ERROR (req, ret);
-
- return ret;
-}
-
-
-
-int
-server3_3_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);
-
- ret = xdr_to_generic (req->msg[0], &args,
- (xdrproc_t)xdr_gfs3_inodelk_req);
- if (ret < 0) {
- //failed to decode msg;
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
-
- frame = get_frame_from_request (req);
- if (!frame) {
- // something wrong, mostly insufficient memory
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
- frame->root->op = GF_FOP_INODELK;
-
- state = CALL_STATE (frame);
- if (!frame->root->client->bound_xl) {
- /* auth failure, request on subvolume without setvolume */
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
-
- state->resolve.type = RESOLVE_EXACT;
- memcpy (state->resolve.gfid, args.gfid, 16);
-
- cmd = args.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 = args.type;
- state->volume = gf_strdup (args.volume);
-
- gf_proto_flock_to_flock (&args.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_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->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)
- SERVER_REQ_SET_ERROR (req, ret);
-
- return ret;
-}
-
-int
-server3_3_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);
- ret = xdr_to_generic (req->msg[0], &args,
- (xdrproc_t)xdr_gfs3_finodelk_req);
- if (ret < 0) {
- //failed to decode msg;
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
-
- frame = get_frame_from_request (req);
- if (!frame) {
- // something wrong, mostly insufficient memory
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
- frame->root->op = GF_FOP_FINODELK;
-
- state = CALL_STATE (frame);
- if (!frame->root->client->bound_xl) {
- /* auth failure, request on subvolume without setvolume */
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
-
- state->resolve.type = RESOLVE_EXACT;
- 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:
- 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 = args.type;
-
- gf_proto_flock_to_flock (&args.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_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->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)
- SERVER_REQ_SET_ERROR (req, ret);
-
- return ret;
-}
-
-
-int
-server3_3_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);
-
- ret = xdr_to_generic (req->msg[0], &args,
- (xdrproc_t)xdr_gfs3_entrylk_req);
- if (ret < 0) {
- //failed to decode msg;
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
-
- frame = get_frame_from_request (req);
- if (!frame) {
- // something wrong, mostly insufficient memory
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
- frame->root->op = GF_FOP_ENTRYLK;
-
- state = CALL_STATE (frame);
- if (!frame->root->client->bound_xl) {
- /* auth failure, request on subvolume without setvolume */
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
-
- state->resolve.type = RESOLVE_EXACT;
- memcpy (state->resolve.gfid, args.gfid, 16);
-
- if (args.namelen)
- state->name = gf_strdup (args.name);
- state->volume = gf_strdup (args.volume);
-
- state->cmd = args.cmd;
- state->type = args.type;
-
- GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->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)
- SERVER_REQ_SET_ERROR (req, ret);
-
- return ret;
-}
-
-int
-server3_3_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);
-
- ret = xdr_to_generic (req->msg[0], &args,
- (xdrproc_t)xdr_gfs3_fentrylk_req);
- if (ret < 0) {
- //failed to decode msg;
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
-
- frame = get_frame_from_request (req);
- if (!frame) {
- // something wrong, mostly insufficient memory
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
- frame->root->op = GF_FOP_FENTRYLK;
-
- state = CALL_STATE (frame);
- if (!frame->root->client->bound_xl) {
- /* auth failure, request on subvolume without setvolume */
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
-
- state->resolve.type = RESOLVE_EXACT;
- 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 (frame->root->client->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)
- SERVER_REQ_SET_ERROR (req, ret);
-
- return ret;
-}
-
-int
-server3_3_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;
-
- ret = xdr_to_generic (req->msg[0], &args,
- (xdrproc_t)xdr_gfs3_access_req);
- if (ret < 0) {
- //failed to decode msg;
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
-
- frame = get_frame_from_request (req);
- if (!frame) {
- // something wrong, mostly insufficient memory
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
- frame->root->op = GF_FOP_ACCESS;
-
- state = CALL_STATE (frame);
- if (!frame->root->client->bound_xl) {
- /* auth failure, request on subvolume without setvolume */
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
-
- state->resolve.type = RESOLVE_MUST;
- memcpy (state->resolve.gfid, args.gfid, 16);
- state->mask = args.mask;
-
- GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->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)
- SERVER_REQ_SET_ERROR (req, ret);
-
- return ret;
-}
-
-
-
-int
-server3_3_symlink (rpcsvc_request_t *req)
-{
- server_state_t *state = NULL;
- call_frame_t *frame = NULL;
- gfs3_symlink_req args = {{0,},};
- int ret = -1;
- int op_errno = 0;
-
- if (!req)
- return ret;
-
- args.bname = alloca (req->msg[0].iov_len);
- args.linkname = alloca (4096);
-
- ret = xdr_to_generic (req->msg[0], &args,
- (xdrproc_t)xdr_gfs3_symlink_req);
- if (ret < 0) {
- //failed to decode msg;
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
-
- frame = get_frame_from_request (req);
- if (!frame) {
- // something wrong, mostly insufficient memory
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
- frame->root->op = GF_FOP_SYMLINK;
-
- state = CALL_STATE (frame);
- if (!frame->root->client->bound_xl) {
- /* auth failure, request on subvolume without setvolume */
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
-
- state->resolve.type = RESOLVE_NOT;
- memcpy (state->resolve.pargfid, args.pargfid, 16);
- state->resolve.bname = gf_strdup (args.bname);
- state->name = gf_strdup (args.linkname);
- state->umask = args.umask;
-
- GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->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);
-
-out:
- if (op_errno)
- SERVER_REQ_SET_ERROR (req, ret);
-
- /* memory allocated by libc, don't use GF_FREE */
- free (args.xdata.xdata_val);
-
- return ret;
-}
-
-
-
-int
-server3_3_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.newbname = alloca (req->msg[0].iov_len);
-
- ret = xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_link_req);
- if (ret < 0) {
- //failed to decode msg;
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
-
- frame = get_frame_from_request (req);
- if (!frame) {
- // something wrong, mostly insufficient memory
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
- frame->root->op = GF_FOP_LINK;
-
- state = CALL_STATE (frame);
- if (!frame->root->client->bound_xl) {
- /* auth failure, request on subvolume without setvolume */
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
-
- state->resolve.type = RESOLVE_MUST;
- memcpy (state->resolve.gfid, args.oldgfid, 16);
-
- state->resolve2.type = RESOLVE_NOT;
- state->resolve2.bname = gf_strdup (args.newbname);
- memcpy (state->resolve2.pargfid, args.newgfid, 16);
-
- GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->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)
- SERVER_REQ_SET_ERROR (req, ret);
-
- return ret;
-}
-
-
-int
-server3_3_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.oldbname = alloca (req->msg[0].iov_len);
- args.newbname = alloca (req->msg[0].iov_len);
-
- ret = xdr_to_generic (req->msg[0], &args,
- (xdrproc_t)xdr_gfs3_rename_req);
- if (ret < 0) {
- //failed to decode msg;
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
-
- frame = get_frame_from_request (req);
- if (!frame) {
- // something wrong, mostly insufficient memory
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
- frame->root->op = GF_FOP_RENAME;
-
- state = CALL_STATE (frame);
- if (!frame->root->client->bound_xl) {
- /* auth failure, request on subvolume without setvolume */
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
-
- state->resolve.type = RESOLVE_MUST;
- state->resolve.bname = gf_strdup (args.oldbname);
- memcpy (state->resolve.pargfid, args.oldgfid, 16);
-
- state->resolve2.type = RESOLVE_MAY;
- state->resolve2.bname = gf_strdup (args.newbname);
- memcpy (state->resolve2.pargfid, args.newgfid, 16);
-
- GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->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)
- SERVER_REQ_SET_ERROR (req, ret);
-
- return ret;
-}
-
-int
-server3_3_lk (rpcsvc_request_t *req)
-{
- server_state_t *state = NULL;
- call_frame_t *frame = NULL;
- gfs3_lk_req args = {{0,},};
- int ret = -1;
- int op_errno = 0;
-
- if (!req)
- return ret;
-
- ret = xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_lk_req);
- if (ret < 0) {
- //failed to decode msg;
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
-
- frame = get_frame_from_request (req);
- if (!frame) {
- // something wrong, mostly insufficient memory
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
- frame->root->op = GF_FOP_LK;
-
- state = CALL_STATE (frame);
- if (!frame->root->client->bound_xl) {
- /* auth failure, request on subvolume without setvolume */
- SERVER_REQ_SET_ERROR (req, ret);
- goto out;
- }
-
- 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:
- state->cmd = F_GETLK;
- break;
- case GF_LK_SETLK:
- state->cmd = F_SETLK;
- break;
- case GF_LK_SETLKW:
- state->cmd = F_SETLKW;
- break;
- case GF_LK_RESLK_LCK:
- state->cmd = F_RESLK_LCK;
- break;
- case GF_LK_RESLK_LCKW:
- state->cmd = F_RESLK_LCKW;
- break;
- case GF_LK_RESLK_UNLCK:
- state->cmd = F_RESLK_UNLCK;
- break;
- case GF_LK_GETLK_FD:
- state->cmd = F_GETLK_FD;
- break;
-
- }
-
-
- gf_proto_flock_to_flock (&args.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 (frame->root->client->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);
- break;
- }
-
-
- GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->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)
- SERVER_REQ_SET_